Using TCP Adapters with Ensemble
Using the Inbound TCP Adapters
|
|
Overview of Inbound TCP Adapter
Each TCP inbound adapter checks for data on a specified port, reads the input, and sends the input as a stream to the associated business service. The business service, which you create and configure, uses this stream and communicates with the rest of the production. The following figure shows the overall flow:
-
Each time the adapter encounters input from its configured data source, it calls the internal
ProcessInput() method of the business service class, passing the stream as an input argument.
-
The internal
ProcessInput() method of the business service class executes. This method performs basic Ensemble tasks such as maintaining internal information as needed by all business services. You do not customize or override this method, which your business service class inherits.
-
The
ProcessInput() method then calls your custom
OnProcessInput() method, passing the input object. The requirements for this method are described later in this chapter.
The response message follows the same path, in reverse.
Creating a Business Service to Use a TCP Inbound Adapter
The following list describes the basic requirements of the business service class:
-
-
-
-
Your class can implement the
OnConnect() callback method. This method is called each time the TCP inbound adapter establishes a new connection to or from a remote system.
If you implement this method, it must have the following signature:
Method OnConnect(pTimeout As %Numeric) As %Status
If
OnConnect() returns an error status, the new connection fails and the adapter is disconnected. If an untrapped exception occurs within
OnConnect(), the adapter catches it and continues as if
OnConnect() were not implemented.
-
Note:
Studio provides a wizard that you can use to create a business service stub. To access this wizard, click
File > New and then click the
Production tab. Then click
Business Service and click
OK. Note that the wizard provides a generic input argument. If you use the wizard, InterSystems recommends that you edit the method signature to use the specific arguments needed with the adapter you chose; see the next section.
Implementing the OnProcessInput() Method
This section describes the method signature for
OnProcessInput(), which depends upon the adapter, and describes how to
implement this method.
Signature for OnProcessInput() for EnsLib.TCP.CountedInboundAdapter
Method OnProcessInput(pInput As %Library.GlobalCharacterStream,
Output pOutput As %Library.AbstractStream) As %Status
-
pInput contains the incoming data stream that the TCP client has directed to the adapter.
-
pOutput contains any response that the business service might provide to the TCP client.
Signature for OnProcessInput() for EnsLib.TCP.CountedXMLInboundAdapter
Method OnProcessInput(pInput As %RegisteredObject,
Output pOutput As %RegisteredObject) As %Status
-
-
pOutput contains any response that you might need to return to the XTE server.
Signature for OnProcessInput() for EnsLib.TCP.TextLineInboundAdapter
Method OnProcessInput(pInput As Ens.StringContainer,
Output pOutput As Ens.StringContainer) As %Status
-
pInput contains the incoming line of text.
-
pOutput contains the outgoing response string (if any).
Implementing OnProcessInput()
In all cases, the
OnProcessInput() method should do some or all of the following:
-
Examine the input object (
pInput) and decide how to use it.
-
Create an instance of the request message, which will be the message that your business service sends.
-
For the request message, set its properties as appropriate, using values in the input.
-
Each of these methods returns a status (specifically, an instance of
%Status).
-
Make sure that you set the output argument (
pOutput). Typically you set this equal to the response message that you have received. This step is required.
-
If the data source expects an acknowledgment or response to its input,
OnProcessInput() must create this response and relay it to the data source, via the adapter.
-
Return an appropriate status. This step is required.
Example for EnsLib.TCP.CountedInboundAdapter
Class Test.HL7v3.InterfaceEngine.Service.HL7TCPIn Extends Ens.BusinessService
{
Parameter ADAPTER = "EnsLib.TCP.CountedInboundAdapter";
Parameter SINGLEPOOLJOB = 1;
Parameter SETTINGS = "TargetConfigNames";
/// Configuration item to which to send messages
Property TargetConfigNames As %String;
Method OnProcessInput(pInput As %GlobalCharacterStream,
pOutput As %RegisteredObject) As %Status
{
Set $ZTrap = "OnProcessInputET"
Set tRequest =
##class(Test.HL7v3.InterfaceEngine.Request.Message).%New()
Set tRequest.Stream = pInput
Set tRequest.DocType = $Case(pInput.Size < 10000, 1:"MCOA", :"CDAR2")
If (..TargetConfigNames '= "") {
For tCount = 1:1:$Length(..TargetConfigNames, ",") {
Set tTarget =
$ZStrip($Piece(..TargetConfigNames, ",", tCount), "<>W")
Set tStatus = ..SendRequestAsync(tTarget, tRequest)
}
}
Quit $$$OK
OnProcessInputET
Set $ZTrap = ""
Quit $$$ERROR($$$GeneralError,"Error in OnProcessInput: "_$ZError)
}
/// Return an array of connections for
/// drawing lines on the config diagram
ClassMethod OnGetConnections(Output pArray As %String,
item As Ens.Config.Item)
{
Set (tValue,tIndex)=""
For {
Set tIndex = item.Settings.Next(tIndex) Quit:tIndex=""
Set tSetting = item.Settings.GetAt(tIndex)
If tSetting.Name="TargetConfigNames" Set tValue=tSetting.Value
}
For i=1:1:$L(tValue,",") {
Set tOne=$P(tValue,",",i)
Continue:""=tOne
Set pArray(tOne)=""
}
Quit
}
}
Example for EnsLib.TCP.TextLineInboundAdapter
Class TestTCPTextLine.AuthorizationTCPService Extends Ens.BusinessService
{
/// Name of the adapter class
Parameter ADAPTER = "EnsLib.TCP.TextLineInboundAdapter";
Method OnProcessInput(pInput As Ens.StringContainer,
pOutput As Ens.StringContainer) As %Status
{
set $ZT = "EXCEPTION"
set st = $$$OK
do {
if ('$isobject($get(pInput))) { quit }
// Input must have the following format: 'PatientCode:ProcedureCode'
set tSubject = pInput.StringValue
$$$TRACE("received line "_tSubject)
set req = ##class(TestTCPTextLine.AuthorizationRequest).%New()
set req.PatientCode = $piece(tSubject,":",1)
set req.ProcedureCode = $piece(tSubject,":",2)
set st = ..SendRequestSync("AuthorizationProcess", req, .resp)
quit:$$$ISERR(st)
set pOutput=
##class(Ens.StringContainer).%New(resp.AuthorizationFlag_
":"_resp.AuthorizationCode)
} while (0)
EXIT
//do ..Adapter.Disconnect()
quit st
EXCEPTION
set $ZT = ""
set st = $$$EnsSystemError
goto EXIT
}
}
Adding and Configuring the Business Service
To add your business service to an Ensemble production, use the Management Portal to do the following:
-
Add an instance of your business service class to the Ensemble production.
-
When you configure the business service, you specify a value for the
Allowed IP Addresses settings, along other settings. Note that
Allowed IP Addresses provides a way to enable the adapter to initiate the connection.
-
Enable the business service.
-