-
Notifications
You must be signed in to change notification settings - Fork 14
Tutorial 04 05 Add Dispatcher Classes

For each traditional Synergy routine, you must add a dispatcher, which is a class that inherits from the RoutineStub class which is defined in the Traditional Bridge library code, and which has helper methods for serializing and deserializing, exception handling, and logging (see RoutineDispatcher.dbl for more information).
Each method dispatcher class does these things:
- De-serializes any
inorinoutparameters from a JSON-RPC request message into suitable variables, and prepares variables for anyoutparameters and functionreturn values. - Calls the underlying subroutine or function, passing the parameter variables.
- Serializes any
inoutparameters,outparameters or functionreturn valuesinto a JSON-RPC response message.
This is what the generic code for each dispatcher class looks like:
;;*****************************************************************************
;;
;; Title: <ROUTINE>Dispatcher.dbl
;;
;; Description: Dispatcher class for calls to <ROUTINE>
;;
;;*****************************************************************************
import Harmony.TraditionalBridge
import Json
import System
import System.Collections
.ifdef DBLV11
import System.Text.Json
.define JSON_ELEMENT @JsonElement
.else
.define JSON_ELEMENT @JsonValue
.endc
namespace TraditionalBridge.Dispatchers
;;; <summary>
;;; Dispatcher for <ROUTINE>
;;; </summary>
public class <ROUTINE>Dispatcher extends RoutineStub
;;; <summary>
;;; Dispatch to <ROUTINE>
;;; </summary>
;;; <param name="name">Name of routine to call.</param>
;;; <param name="callFrame">Current JSON-RPC request.</param>
;;; <param name="serializer">Outbound data serializer.</param>
;;; <param name="dispatcher">Inbound routine dispatcher.</param>
protected override method DispatchInternal, void
required in name, string
required in callFrame, JSON_ELEMENT
required in serializer, @DispatchSerializer
required in dispatcher, @RoutineDispatcher
;;Declare data for any parameters and/or return value
record
arguments, JSON_ELEMENT
endrecord
proc
;;------------------------------------------------------------
;;Process inbound arguments
arguments = callFrame.GetProperty("params")
;TODO: Add code for to de-serialize inbound parameters here
;;------------------------------------------------------------
;; Call the underlying routine
;TODO: Call the underlying routine here
;;------------------------------------------------------------
;;Process any outbound return value and/or parameters
;TODO: Serialize any outbound return value and/or parameters here
endmethod
endclass
endnamespace
We recommend organizing all dispatcher classes in a project folder and namespace path.
- In
Solution Explorer, right-click on theTraditionalBridge, selectAdd > Folder, and name the folderDispatchers.
Your next task is to create a dispatcher class for each of the three routines being exposed. First, you will create a dispatcher for the GetEnvironment function.
-
Right-click on the
Dispatchersfolder, selectAdd > Class, and name the new fileGetEnvironmentDispatcher.dbl. -
Replace the current code in the file with the sample scaffolding code shown above.
-
Replace all instances of the token
<ROUTINE>with the wordGetEnvironment.TIP: The Visual Studio shortcut key for "Find and Replace" is
Ctrl+H.
The routine being called has no parameters, but it is a function that returns an alpha value. This means we need to do the following:
- Declare an appropriate variable to store the return value from the function.
- Call the function and assign the return value to the variable.
- Serialize the return value into the JSON-RPC response to the caller.
-
In the data division of the
DispatchInternalmethod, add a newstringvariable namedreturnValueto the existing record, like this:;;Declare data for any parameters and/or return value record arguments, JSON_ELEMENT returnValue, string endrecord -
As we have no inbound parameters, remove the
TODOcommentAdd code for to de-serialize inbound parameters here. -
Locate the
TODOcommentCall the underlying routine hereand replace it with a call to the synergy function:returnValue = %GetEnvironment -
Locate the
TODOcommentSerialize any outbound return value and/or parameters hereand replace it with the following code:;;Argument 0 is the return value serializer.ArgumentData(0, returnValue,FieldDataType.AlphaField,returnValue.Length,0,true)This code essentially adds the return value to the JSON-RPC response that will be returned to the caller. The parameters to the ArgumentData method are:
- The argument number, 0 representing the return value of a function.
- The actual value to be returned.
- The data type of the value being returned, using the ENUM FieldDataType. Possible values are:
- AlphaField
- DecimalField
- ImpliedDecimal
- ImpliedDecimalField
- IntegerField
- DataObjectField
- DataObjectCollectionField
- EnumField
- HandleField
- BinaryHandleField
- StringField
- AlphaArrayField
- DecimalArrayField
- ImpliedDecimalArrayField
- IntegerArrayField
- StringArrayField
- The length of the data being returned.
- The number of decimal places (for implied decimal fields).
- A boolean value indicating whether the value contains any binary data.
-
Save the file.
Your dispatcher should now look like this:
;;*****************************************************************************
;;
;; Title: GetEnvironmentDispatcher.dbl
;;
;; Description: Dispatcher class for calls to GetEnvironment
;;
;;*****************************************************************************
import Harmony.TraditionalBridge
import Json
import System
import System.Collections
.ifdef DBLV11
import System.Text.Json
.define JSON_ELEMENT @JsonElement
.else
.define JSON_ELEMENT @JsonValue
.endc
namespace TraditionalBridge.Dispatchers
;;; <summary>
;;; Dispatcher for GetEnvironment
;;; </summary>
public class GetEnvironmentDispatcher extends RoutineStub
;;; <summary>
;;; Dispatch to GetEnvironment
;;; </summary>
;;; <param name="name">Name of routine to call.</param>
;;; <param name="callFrame">Current JSON-RPC request.</param>
;;; <param name="serializer">Outbound data serializer.</param>
;;; <param name="dispatcher">Inbound routine dispatcher.</param>
protected override method DispatchInternal, void
required in name, string
required in callFrame, JSON_ELEMENT
required in serializer, @DispatchSerializer
required in dispatcher, @RoutineDispatcher
;;Declare data for any parameters and/or return value
record
arguments, JSON_ELEMENT
returnValue, string
endrecord
proc
;;------------------------------------------------------------
;;Process inbound arguments
arguments = callFrame.GetProperty("params")
;;------------------------------------------------------------
;; Call the underlying routine
returnValue = %GetEnvironment
;;------------------------------------------------------------
;;Process any outbound return value and/or parameters
;;Argument 0 is the return value
serializer.ArgumentData(0, returnValue,FieldDataType.AlphaField,returnValue.Length,0,true)
endmethod
endclass
endnamespace
The dispatcher for the GetEnvironment function is now complete.
Your next task is to develop a dispatcher for the GetLogicalName function.
-
Right-click on the
Dispatchersfolder, selectAdd > Class, and name the new fileGetLogicalNameDispatcher.dbl. -
Replace the current code in the file with the sample scaffolding code shown above.
-
Replace all instances of the token
<ROUTINE>with the wordGetLogicalName.
TIP: The Visual Studio shortcut key for "Find and Replace" is Ctrl+H.
The routine being called has one inbound parameter and is a function that returns an alpha value. This means we need to do the following:
- Declare appropriate variables to store the logical name to pass to the function and the return value from the function.
- Call the function, passing the parameter variable, and assign the return value to the return value variable.
- Serialize the return value into the JSON-RPC response to the caller.
- In the data division of the
DispatchInternalmethod, add analphavariable namedlogicalNameand astringvariable namedreturnValueto the existing record, like this:
;;Declare data for any parameters and/or return value
record
arguments, JSON_ELEMENT
logicalName, a256
returnValue, string
endrecord
Next you need extract the value of the inbound parameter from the received JSON-RPC message and store the value in the new logicalName field that you just created.
-
Locate and remove the
TODOcommentAdd code for to de-serialize inbound parameters here, and replace it with this code:;;Argument 1 is the inbound logical name logicalName = dispatcher.GetText(arguments[1]) -
Now locate the
TODOcommentCall the underlying routine hereand replace it with a call to the synergy function:returnValue = %GetLogicalName(logicalName) -
Finally, locate the
TODOcommentSerialize any outbound return value and/or parameters hereand replace it with the following code:;;Argument 0 is the return value serializer.ArgumentData(0, returnValue,FieldDataType.AlphaField,returnValue.Length,0,true) -
Save the file.
Your dispatcher should now look like this:
;;*****************************************************************************
;;
;; Title: GetLogicalNameDispatcher.dbl
;;
;; Description: Dispatcher class for calls to GetLogicalName
;;
;;*****************************************************************************
import Harmony.TraditionalBridge
import Json
import System
import System.Collections
.ifdef DBLV11
import System.Text.Json
.define JSON_ELEMENT @JsonElement
.else
.define JSON_ELEMENT @JsonValue
.endc
namespace TraditionalBridge.Dispatchers
;;; <summary>
;;; Dispatcher for GetLogicalName
;;; </summary>
public class GetLogicalNameDispatcher extends RoutineStub
;;; <summary>
;;; Dispatch to GetLogicalName
;;; </summary>
;;; <param name="name">Name of routine to call.</param>
;;; <param name="callFrame">Current JSON-RPC request.</param>
;;; <param name="serializer">Outbound data serializer.</param>
;;; <param name="dispatcher">Inbound routine dispatcher.</param>
protected override method DispatchInternal, void
required in name, string
required in callFrame, JSON_ELEMENT
required in serializer, @DispatchSerializer
required in dispatcher, @RoutineDispatcher
;;Declare data for any parameters and/or return value
record
arguments, JSON_ELEMENT
logicalName, a256
returnValue, string
endrecord
proc
;;------------------------------------------------------------
;;Process inbound arguments
arguments = callFrame.GetProperty("params")
;;Argument 1 is the inbound logical name
logicalName = dispatcher.GetText(arguments[1])
;;------------------------------------------------------------
;; Call the underlying routine
returnValue = %GetLogicalName(logicalName)
;;------------------------------------------------------------
;;Process any outbound return value and/or parameters
;;Argument 0 is the return value
serializer.ArgumentData(0, returnValue,FieldDataType.AlphaField,returnValue.Length,0,true)
endmethod
endclass
endnamespace
Your dispatcher for the GetLogicalName routine is now complete.
Your final task is to create a dispatcher class for the AddTwoNumbers function.
-
Right-click on the
Dispatchersfolder, selectAdd > Class, and name the new fileAddTwoNumbersDispatcher.dbl. -
Replace the current code in the file with the sample scaffolding code shown above.
-
Replace all instances of the token
<ROUTINE>with the wordAddTwoNumbers.
TIP: The Visual Studio shortcut key for "Find and Replace" is Ctrl+H.
The routine being called is a subroutine with three parameters, all defined as numeric. There are two in parameters, and one out parameter. This means we need to do the following:
- Declare appropriate variables represent the three parameter values.
- Call the subroutine, passing the appropriate parameters.
- Serialize the
outparameter into the JSON-RPC response to the caller.
- In the data division of the
DispatchInternalmethod, add three newdecimalvariables namedarg1,arg2andarg3to the existing record, like this:
;;Declare data for any parameters and/or return value
record
arguments, JSON_ELEMENT
arg1, decimal
arg2, decimal
arg3, decimal
endrecord
Now extract the value of the inbound parameters from the received JSON-RPC message and store the value in the new arg1 and arg2 variables.
-
Locate and remove the
TODOcommentAdd code for to de-serialize inbound parameters here, and replace it with this code:;;Arguments 1 and 2 are passed in to the underlying routine arg1 = dispatcher.GetImplied(arguments[1]) arg2 = dispatcher.GetImplied(arguments[2]) -
Locate the
TODOcommentCall the underlying routine hereand replace it with a call to the underlying subroutine:xcall AddTwoNumbers(arg1,arg2,arg3) -
Finally, locate the
TODOcommentSerialize any outbound return value and/or parameters hereand replace it with the following code:;;Argument 3 is the returned value serializer.ArgumentData(3,arg3,FieldDataType.ImpliedDecimal,28,10,false) -
Save the file.
Your dispatcher should now look like this:
;;*****************************************************************************
;;
;; Title: GetEnvironmentDispatcher.dbl
;;
;; Description: Dispatcher class for calls to GetEnvironment
;;
;;*****************************************************************************
import Harmony.TraditionalBridge
import Json
import System
import System.Collections
.ifdef DBLV11
import System.Text.Json
.define JSON_ELEMENT @JsonElement
.else
.define JSON_ELEMENT @JsonValue
.endc
namespace TraditionalBridge.Dispatchers
;;; <summary>
;;; Dispatcher for GetEnvironment
;;; </summary>
public class GetEnvironmentDispatcher extends RoutineStub
;;; <summary>
;;; Dispatch to GetEnvironment
;;; </summary>
;;; <param name="name">Name of routine to call.</param>
;;; <param name="callFrame">Current JSON-RPC request.</param>
;;; <param name="serializer">Outbound data serializer.</param>
;;; <param name="dispatcher">Inbound routine dispatcher.</param>
protected override method DispatchInternal, void
required in name, string
required in callFrame, JSON_ELEMENT
required in serializer, @DispatchSerializer
required in dispatcher, @RoutineDispatcher
;;Declare data for any parameters and/or return value
record
arguments, JSON_ELEMENT
returnValue, string
endrecord
proc
;;------------------------------------------------------------
;;Process inbound arguments
arguments = callFrame.GetProperty("params")
;;------------------------------------------------------------
;; Call the underlying routine
returnValue = %GetEnvironment
;;------------------------------------------------------------
;;Process any outbound return value and/or parameters
;;Argument 0 is the return value
serializer.ArgumentData(0, returnValue,FieldDataType.AlphaField,returnValue.Length,0,true)
endmethod
endclass
endnamespace
The dispatcher for the AddTwoNumbers function is now complete.
Next topic: Add Main Dispatcher Class
-
Tutorial 2: Building a Service from Scratch
- Creating a Basic Solution
- Enabling OData Support
- Configuring Self Hosting
- Entity Collection Endpoints
- API Documentation
- Single Entity Endpoints
- OData Query Support
- Alternate Key Endpoints
- Expanding Relations
- Postman Tests
- Supporting CRUD Operations
- Adding a Primary Key Factory
- Adding Create Endpoints
- Adding Upsert Endpoints
- Adding Patch Endpoints
- Adding Delete Endpoints
-
Harmony Core CLI Tool
-
OData Aware Tools
-
Advanced Topics
- CLI Tool Customization
- Adapters
- API Versioning
- Authentication
- Authorization
- Collection Counts
- Customization File
- Custom Field Types
- Custom File Specs
- Custom Properties
- Customizing Generated Code
- Deploying to Linux
- Dynamic Call Protocol
- Environment Variables
- Field Security
- File I/O
- Improving AppSettings Processing
- Logging
- Optimistic Concurrency
- Multi-Tenancy
- Publishing in IIS
- Repeatable Unit Tests
- Stored Procedure Routing
- Suppressing OData Metadata
- Traditional Bridge
- Unit Testing
- EF Core Optimization
- Updating a Harmony Core Solution
- Updating to 3.1.90
- Creating a new Release
-
Background Information