This chapter provides a detailed specification for the Direct Client Protocol and describes how the protocol is implemented on each Transport. It contains these sections:
Protocol Overview
The direct client protocol is designed to expose the base Network Core API to the client. Clients using this protocol are capable of accessing any and all features provided by the underlying Network Services and Resources.
The cost of this flexibility is the increased complexity of client code necessary to implement the protocol. Clients are responsible for managing the binding of Network Services and Resources. Clients are also required to be aware of the API details of each Network Service and Resource they use, as well as the processes around using those APIs.
Core Messages
There are 4 types of core messages: Core Request, Core Response, Core Event, and Core Error. The client initiates an action by sending a Core Request. The Network Core will either generate a Core Response or Error in reply to the request depending on the result. The Network Core may also generate Core Events as a result of processing a Core Request or in response to other events within the HIS container.
The exact format and contents of these messages depends on which transport carries them. However, regardless of transport, each message class will always include certain information:
Core Request
· Request Id – Uniquely identifies this request from all others
· Request Type – Determines the type of request being made
Core Response
· Request Id – Uniquely identifies the original request that produced this response
· Response Type – Matches the original request type
· Result – Indicates success or failure of the original request
· Response Data – Responses which carry data will have a dedicated section to contain it
· Error Information – If the request was unsuccessful, information about the failure will be provided
Core Event
· Event Name – Identifies the type of event that occurred
· Event Data – Events which carry data will have a dedicated section to contain it
Core Error
· Error Type – The type of error that occurred
· Error Information – Any information about the error condition will be provided
Service and Resource Messages
The messages delivered to a service or resource and the messages they produce in response or raise as events follow the same general guidelines as core messages. However, service messages will always carry the unique identifier for the target service and resource messages will always carry the unique identifiers for both the parent service and the target resource.
Message Formats
This section outlines the general format for each type of message used by the direct client protocol. For details on specific messages, including usage and example contents, see appropriate section below.
Base Message Format
All messages sent and received over the socket transport are packaged as JSON structures and delivered in the message content section of the socket transport message frame. The class of message is identified by the "messageType" property of the top-level JSON object:
{
"messageType": "[message-class]"
}There are 12 message classes representing requests, responses, events, and errors for services, resources, and the network core itself.
coreRequest
coreResponse
coreEvent
coreError
serviceRequest
serviceResponse
serviceEvent
serviceError
resourceRequest
resourceResponse
resourceEvent
resourceError
Each message class builds on the base message format adding additional properties to the JSON object. Some properties may be objects themselves with internal properties.
Core Request
All core request messages include the additional properties requestId and command. The request id should be unique among all requests so should be a GUID or UUID. The protocol doesn't require a particular format for the identifier. It is treated as a text value for reference and comparison without further processing.
{
"messageType": "coreRequest",
"requestId": "[request-id]",
"command": "[request-name]"
}Core Response
A core request can generate one of two types of responses: success or failure. A successful response indicates that the request was completed without issue and any data associated with the request is provided in the response message. A failure response indicates that the request could not be completed given the information provided in the request. A failure response differs from an error in that the failure state is normal and recoverable, where as an error is abnormal and is often times unrecoverable. The success or failure of a request is provided in the "result" property of the response message.
Success Response
{
"messageType": "coreResponse",
"requestId": "[original-request-id]",
"command": "[original-request-command]",
"result": "success"
}Failure Response
{
"messageType": "coreResponse",
"requestId": "[original-request-id]",
"command": "[original-request-command]",
"result": "failure",
"failure":
{
"code": "[type-of-failure]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-applicable]"
}
}Core Event
A core event is generated in response to some asynchronous activity within the HIS container. It may be related to the processing of a previously issued request, or may be completely unsolicited. Core events carry the name of the event and information related to the event if available. If no additional information is provided with the event, the "event" property is typically not present. For details of the "event" property's contents see the description for each individual event below.
{
"messageType": "coreEvent",
"name": "[event-name]",
"event":
{
[event-specific-contents]
}
}Core Error
A core error message represents a serious error state that renders the requested activity, the client connection, or even the HIS container unrecoverable. Errors are usually related to malformed requests or other issues encountered while processing messages. If the original request that produced the error can be determined and the request's identifier can be retrieved, it is provided in the "requestId" property of the error message.
{
"messageType": "coreError",
"requestId": "[original-request-id]",
"error":
{
"code": "[type-of-error]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-available]"
}
}Service Request
A service request consists of an outer shell, or envelope, that identifies the destination service and an inner payload with the details of the request in a service specific format. The "serviceId" property defines the target of the request.
{
"messageType": "serviceRequest",
"requestId": "[request-id]",
"serviceId": "[service-id]",
"request":
{
[service-specific-contents]
}
}Service Response
Unlike a core response, a service response message does not define success or failure in the outer envelope. The details of the response, including disposition, are contained within the inner payload.
{
"messageType": "serviceResponse",
"requestId": "[original-request-id]",
"serviceId": "[target-service-id]",
"response":
{
[service-specific-contents]
}
}Service Event
Service events follow the same general structure as core events with the addition of the "serviceId" property to denote the service that generated the event and the event name is moved into the event contents.
{
"messageType": "serviceEvent",
"serviceId": "[source-service-id]",
"event":
{
[service-specific-event-contents]
}
}Service Error
As with a core error message, a service error represents a serious error state that is likely not recoverable and may result in the automatic unbinding of the client from the service.
{
"messageType": "serviceError",
"requestId": "[original-request-id]",
"serviceId": "[source-service-id]",
"error":
{
"code": "[type-of-error]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-available]"
[service-specific-error-information]
}
}Resource Request
Like a service request, a resource request consists of an outer shell, or envelope. The envelope identifies the parent service and destination resource. The inner payload provides the details of the request in a service specific format. The "serviceId" property defines the parent service and the "resourceId" property selects the target resource of the request.
{
"messageType": "resourceRequest",
"requestId": "[request-id]",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]",
"request":
{
[resource-specific-contents]
}
}Resource Response
Unlike a core response, a resource response message does not define success or failure in the outer envelope. The details of the response, including disposition, are contained within the inner payload.
{
"messageType": "resourceResponse",
"requestId": "[original-request-id]",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]",
"response":
{
[resource-specific-contents]
}
}Resource Event
Resource events follow the same structure as service events with the addition of the "resourceId" property to denote the resource that generated the event.
{
"messageType": "resourceEvent",
"serviceId": "[parent-service-id]",
"resourceId": "[source-resource-id]",
"event":
{
[resource-specific-event-contents]
}
}Resource Error
As with a core error message, a resource error represents a serious error state that is likely not recoverable and may result in the automatic unbinding of the client from the resource.
{
"messageType": "resourceError",
"requestId": "[original-request-id]",
"serviceId": "[parent-service-id]",
"resourceId": "[source-resource-id]",
"error":
{
"code": "[type-of-error]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-available]"
[resource-specific-error-information]
}
}Core Requests and Responses
There are XX core commands supported by the direct client protocol. This section provides example content and flows for each request and the possible responses that might be generated.
authenticate (Obsolete)
The client issues an authenticate request to authenticate the current user with HIS.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "authenticate",
"user": "[username]",
"password": "[password]"
}Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "authenticate",
"result": "success"
"response": {}
}Secondary Events
The authenticate request does not generate any secondary events.
getServices (listServices)
The client issues a getServices request to retrieve the current list of Network Services known to this HIS instance. HIS delivers the requested list in its response message.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "getServices" | "listServices"
}Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "getServices" | "listServices",
"result": "success"
"services":
[
{
"id": "[service-id]",
"name": "[service-name]",
"type": "[service-type]",
"info":
{
[service-specific-information]
},
"serviceStatus":
{
"status": "[service-status]",
"acceptingClients": "[true | false]",
"clientCount": "[number-of-bound-clients]"
}
}
…
]
}Secondary Events
The getServices request does not generate any secondary events.
getService
The client issues a getService request to retrieve information about a specific Network Service known to this HIS instance. HIS delivers the requested list in its response message.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "getService",
"serviceId": "[service-id]"
}Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "getService",
"result": "success"
"service":
{
"id": "[service-id]",
"name": "[service-name]",
"type": "[service-type]",
"info":
{
[service-specific-information]
},
"serviceStatus":
{
"status": "[service-status]",
"acceptingClients": "[true | false]",
"clientCount": "[number-of-bound-clients]"
}
}
}Secondary Events
The getService request does not generate any secondary events.
listResources
The client issues a listResources request to retrieve the current list of Network Resources of a Network Service known to this HIS instance. HIS delivers the requested list in its response message.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "listResources"
}Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "listResources",
"result": "success"
"resources":
[
{
"id": "[resource-id]",
"serviceId": "[service-id]"
"name": "[resource-name]",
"type": "[resource-type]",
"info":
{
[resource-specific-information]
},
"resourceStatus":
{
"acceptingClients": "[true | false]",
"clientCount": "[number-of-bound-clients]"
}
}
…
]
}Secondary Events
The listResources request does not generate any secondary events.
getResource
The client issues a getResource request to retrieve information about a specific Network Resource of a Network Service known to this HIS instance. HIS delivers the requested list in its response message.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "getResource",
"serviceId": "[service-id]",
"resourceId": "[resource-id]"
}Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "getResource",
"result": "success"
"resource":
{
"id": "[resource-id]",
"serviceId": "[service-id]",
"name": "[resource-name]",
"type": "[resource-type]",
"info":
{
[resource-specific-information]
},
"serviceStatus":
{
"acceptingClients": "[true | false]",
"clientCount": "[number-of-bound-clients]"
}
}
}Secondary Events
The getResource request does not generate any secondary events.
bindService
Requests that the client be bound to the given service. The target service is identified by the "serviceId" property of the request message. If the client cannot be bound to the service for some reason (it is already bound, the service does not exist, or the service is out of service) a failure response is generated.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "bindService",
"serviceId": "[target-service-id]"
}Success Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "bindService",
"serviceId": "[target-service-id]",
"result": "success"
}Failure Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "bindService",
"serviceId": "[target-service-id]",
"result": "failure",
"failure":
{
"code": "[type-of-failure]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-applicable]"
}
}Secondary Events
Some services will generate an initial event when a new client is bound to it. For example, the Service Monitor service will send the new client an event that contains a full list of available services. That way, the client will have a frame of reference to compare any future add and remove events. See the service definition section for details about what events a given service generates.
unbindService
This command requests that a previously bound service be unbound from the client. The target service is identified by the "serviceId" property of the request message. If the client cannot be unbound from the service (it is not currently bound), a failure response is generated.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "unbindService",
"serviceId": "[target-service-id]"
}Success Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "unbindService",
"serviceId": "[target-service-id]",
"result": "success"
}Failure Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "unbindService",
"serviceId": "[target-service-id]",
"result": "failure",
"failure":
{
"code": "[type-of-failure]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-applicable]"
}
}Secondary Events
The unbound service will most likely not generate any secondary events during the unbinding process. However, services are not barred from doing so.
bindResource
Requests that the client be bound to the given resource. The target resource is identified by the "resourceId" property of the request message. If the client cannot be bound to the resource for some reason (it is already bound, the resource does not exist, or the resource binding limits have been reached) a failure response is generated.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "bindResource",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]"
}Success Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "bindResource",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]",
"result": "success"
}Failure Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "bindResource",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]",
"result": "failure",
"failure":
{
"code": "[type-of-failure]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-applicable]"
}
}Secondary Events
Some resources will generate an initial event when a new client is bound to it. See the parent service definition section for details about what events a given resource generates.
unbindResource
This command requests that a previously bound resource be unbound from the client. The target resource is identified by the "resourceId" property of the request message. If the client cannot be unbound from the resource (it is not currently bound), a failure response is generated.
Request
{
"messageType": "coreRequest",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "unbindResource",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]"
}Success Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "unbindResource",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]",
"result": "success"
}Failure Response
{
"messageType": "coreResponse",
"requestId": "74a24977ca11484293c9e059fdba8061",
"command": "unbindResource",
"serviceId": "[parent-service-id]",
"resourceId": "[target-resource-id]",
"result": "failure",
"failure":
{
"code": "[type-of-failure]",
"message": "[human-readable-message]",
"context": "[stack-trace-if-applicable]"
}
}Secondary Events
The unbound resource will most likely not generate any secondary events during the unbinding process. However, resources are not barred from doing so.
Core Events
There are no specific core events at this time.
Socket Transport (Obsolete)
The real-time and bi-directional nature of the Socket Transport lends itself well to the direct client protocol. After the client completes the transport's handshake phase, it can begin sending core requests and receiving core events and responses. The client can also begin binding the services and resources it requires.
As per the Socket Transport specification, the client session begins with the client opening a socket to HIS and completing the handshake phase. Once the handshake is processed, the client begins to send requests to HIS. Responses, events, and errors will be sent to the client as they are generated by HIS. It is highly recommended that the client leverage a multithreaded processing model; separating the receiving of messages from performing in response to them.
HTTP Transport
The HTTP Transport allows for quick development of client applications, but doesn't offer the flexibility or performance of the Socket Transport.