OpenEdge™ Connector
An RPC endpoint for interfacing with OpenEdge™/RAW. The goal is to provide decoupled RPC connectivity with OpenEdge™ regardless of what ecosystem the microservice runs on. This should vastly increase development speed and production resource usage through the use of docker containers.
- Centralized access to OpenEdge™/RAW
- Caching of procedures using in-memory storage via Redis
- Logging to the EK-stack
- Serilog with an Elasticsearch Sink
- Crossplatform access through SignalR
- SignalR - RPC interface
- ASP.NET 5 with SignalR - Interface service
- Compatibility mode - Access to the .NET Framework DLL provided by RAW
- SignalR DLL - .NET applications to interface
- SignalR node package - NodeJS communication with OpenEdge
- ASP.NET 5 with SignalR - Interface service
- MessagePack - Fast and efficient transport, it's JSON but even smaller.
- Redis - Efficient caching for procedure responses
- Windows Server Core on Docker
After the connection is initialized, the client will need to state the microservice it's representing. The server will then communicate back the connection details
/*
Request
*/
{
"application": "{{Microservice App Name}}",
// Allow test access, all access will be blocked unless it is explicitly allowed here first
"test": true
}
/*
Response
*/
{
// Connection identfier, purely for structured logging on the client.
"connectionId": "{{ConnectionId}}"
}
The following structure is expressed in JSON, though through RPC this will be sent in the MessagePack format using our libraries.
{
// (Optional when using in HTTP uri suffix) Name of the procedure to be called in OpenEdge
"proc": "{{Procedure Name}}",
// Parameters to provide with the procedure
"parm": [
{ "pos": 1, "value": "{{Value}}" },
// (Optional) "redact": Redact the input value from any logging.
{ "pos": 2, "value": "{{Value}}", "redact": true },
// (Optional) "out": Optional parameter, specifies the output field.
{ "pos": 3, "out": true },
{
"pos": 4,
// (Optional) Set a label for this result instead of using the position as key.
"label": "test",
// (Optional) Do not remove encapsulating array if the result is an array of length 1
"ar": true,
"out": true
}
],
// (Optional, default = 0) Time in milliseconds the procedure should be cached if not cached already, 0 bypasses caching
// Always bypass caching for confidential information
"cache": 0,
// (Optional, default = no timeout) Timeout in miliseconds for the request to openedge to abort.
// 0 or less = no timeout, timeout window range (1 - 300,000) ->
"tw": 500,
// (Optional) Credentials
"creds": {
// OpenEdge Username
"user": "john",
// OpenEdge user password
"pwd": "VerrySecurePasswordWithSp$cialCh4rs"
}
}
The following structure is expressed in JSON, though through RPC this will be sent in the MessagePack format using our libraries.
{
// Name of the procedure that was called in OpenEdge
"proc": "{{Procedure Name}}",
// Response statuscode, TBD: Whether or not this is required is to be verified when researching SignalR.
"status": 0,
// null if none/at failure
"result": {
// The response will always be a binary array
"3": "{{Pos3Result}}",
"test": "{{Post4Result}}"
},
// Content age timestamp, null if newly requested/not cached
"lastMod": -1,
// Time taken to execute procedure and get result (ms)
"origTime": 135
}
A couple of formats will be specified for structured logging. The provided forats are subject to additional fields but should at least contain their respective following fields
Field | Type | Description |
---|---|---|
ConnectionId | text | Connection identifier for a specific RPC client connection and request |
IP | ip | IP Address off the connecting application |
AppId | text | Application identifier used to authorize the application |
Field | Type | Description |
---|---|---|
Procedure | text | The procedure name executed in the context |
ConnectionId | text | Connection identifier for a specific RPC client connection |
RequestId | long | Request identifier identifying a specific task/request, most likely a procedure execution |
Inputs | text | JSON representation of the input parameters Warning: The inputs specified as redacted should be filtered out at all times! |
Date | date | Time the procedure was executed |
Field | Type | Description |
---|---|---|
Procedure | text | The procedure name executed in the context |
ConnectionId | text | Connection identifier for a specific RPC client connection |
RequestId | long | Request identifier identifying a specific task/request, most likely a procedure execution |
Date | date | Time the procedure was completed |
ElapsedTime | long | Time in milliseconds that elapsed between execution and completion |
Field | Type | Description |
---|---|---|
Procedure | text | The procedure name executed in the context |
ConnectionId | text | Connection identifier for a specific RPC client connection |
RequestId | long | Request identifier identifying a specific task/request, most likely a procedure execution |
Exception | exception | The generic Serilog exception fields containing the error details provided by .NET |