Skip to main content
Previous sectionNext section

Using the File Outbound Adapter

This chapter describes how to use the file outbound adapter (EnsLib.File.OutboundAdapter). It contains the following sections:

Tip:

Ensemble also provides specialized business service classes that use this adapter, and one of those might be suitable for your needs. If so, no programming would be needed. See the section “Connectivity Options” in Introducing Ensemble.

Overall Behavior

Within a production, an outbound adapter is associated with a business operation that you create and configure. The business operation receives a message from within the production, looks up the message type, and executes the appropriate method. This method usually executes methods of the associated adapter.

Creating a Business Operation to Use the Adapter

To create a business operation to use EnsLib.File.OutboundAdapter, you create a new business operation class. Later, add it to your production and configure it.

You must also create appropriate message classes, if none yet exist. See “Defining Ensemble Messages” in Developing Ensemble Productions.

The following list describes the basic requirements of the business operation class:

  • Your business operation class should extend Ens.BusinessOperation.

  • In your class, the ADAPTER parameter should equal EnsLib.File.OutboundAdapter.

  • In your class, the INVOCATION parameter should specify the invocation style you want to use, which must be one of the following.

    • Queue means the message is created within one background job and placed on a queue, at which time the original job is released. Later, when the message is processed, a different background job is allocated for the task. This is the most common setting.

    • InProc means the message will be formulated, sent, and delivered in the same job in which it was created. The job will not be released to the sender’s pool until the message is delivered to the target. This is only suitable for special cases.

  • Your class should define a message map that includes at least one entry. A message map is an XData block entry that has the following structure:

    XData MessageMap
    {
    <MapItems>
      <MapItem MessageType="messageclass">
        <Method>methodname</Method>
      </MapItem>
      ...
    </MapItems>
    }
    
    Copy code to clipboard
  • Your class should define all the methods named in the message map. These methods are known as message handlers. Each message handler should have the following signature:

    Method Sample(pReq As RequestClass, Output pResp As ResponseClass) As %Status
    Copy code to clipboard

    Here Sample is the name of the method, RequestClass is the name of an Ensemble request message class, and ResponseClass is the name of an Ensemble response message class. In general, the method code will refer to properties and methods of the Adapter property of your business operation.

    For information on defining message classes, see “Defining Ensemble Messages” in Developing Ensemble Productions.

    For information on defining the message handler methods, see “Creating Message Handler Methods,” later in this chapter.

  • For other options and general information, see “Defining a Business Operation Class” in Developing Ensemble Productions.

The following example shows the general structure that you need:

Class EHTP.NewOperation1 Extends Ens.BusinessOperation
{
Parameter ADAPTER = "EnsLib.File.OutboundAdapter";

Parameter INVOCATION = "Queue";

Method Sample(pReq As RequestClass, Output pResp As ResponseClass) As %Status
{
  Quit $$$ERROR($$$NotImplemented)
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="RequestClass">
    <Method>Sample</Method>
  </MapItem>
</MapItems>
}
}
Copy code to clipboard
Note:

Studio provides a wizard that you can use to create a business operation stub similar to the preceding. To access this wizard, click File > New, and then click the Production tab. Then click Business Operation and click OK.

Creating Message Handler Methods

When you create a business operation class for use with EnsLib.File.OutboundAdapter, typically your biggest task is writing message handlers for use with this adapter, that is, methods that receive Ensemble messages and then write files.

Each message handler method should have the following signature:

Method Sample(pReq As RequestClass, Output pResp As ResponseClass) As %Status
Copy code to clipboard

Here Sample is the name of the method, RequestClass is the name of an Ensemble request message class, and ResponseClass is the name of an Ensemble response message class.

In general, the method should do the following:

  1. Examine the inbound request message.

  2. Using the information from the inbound request, call a method of the Adapter property of your business operation. The following example calls the EnsLib.File.OutboundAdapter method PutString():

    /// Send an approval to the output file
    Method FileSendReply(pRequest As Demo.Loan.Msg.SendReply,
                         Output pResponse As Ens.Response) As %Status
    {
      $$$TRACE("write to file "_pRequest.Destination)
      Set tSC=..Adapter.PutString(pRequest.Destination, pRequest.Text)
      Quit tSC
    }
    Copy code to clipboard

    You can use similar syntax to call any of the EnsLib.File.OutboundAdapter methods described in “Calling Adapter Methods from the Business Operation.”

  3. Make sure that you set the output argument (pOutput). Typically you set this equal to the response message. This step is required.

  4. Return an appropriate status. This step is required.

Calling Adapter Methods from the Business Operation

Your business operation class can use the following instance methods of EnsLib.File.OutboundAdapter.

CreateTimestamp()
ClassMethod CreateTimestamp(pFilename As %String = "",
                            pSpec As %String = "_%C") As %String
Copy code to clipboard

Using the pFilename string as a starting point, incorporate the time stamp specifier provided in pSpec and return the resulting string. The default time stamp specifier is _%C which provides the full date and time down to the millisecond.

For full details about time stamp conventions, see “Time Stamp Specifications for Filenames” in Configuring Ensemble Productions.

Delete()
Method Delete(pFilename As %String) As %Status
Copy code to clipboard

Deletes the file.

Exists()
Method Exists(pFilename As %String) As %Boolean
Copy code to clipboard

Returns 1 (True) if the file exists, 0 (False) if it does not.

GetStream()
Method GetStream(pFilename As %String,
                 ByRef pStream As %AbstractStream = {$$$NULLOREF})
                 As %Status
Copy code to clipboard

Gets a stream from the file.

NameList()
Method NameList(Output pFileList As %ListOfDataTypes,
                pWildcards As %String = "*",
                pIncludeDirs As %Boolean = 0) As %Status
Copy code to clipboard

Get a list of files in the directory specified by the FilePath setting. The filenames are returned in a %ListOfDataTypes object. Each entry in the list is a semicolon-separated string containing:

Filename;Type;Size;DateCreated;DateModified;FullPathName

PutLine()
Method PutLine(pFilename As %String, pLine As %String) As %Status
Copy code to clipboard

Writes a string to the file and appends to the string the characters specified in the LineTerminator property. By default, the LineTerminator is a carriage return followed by a line feed (ASCII 13, ASCII 10).

If your operating system requires a different value for the LineTerminator property, set the value in the OnInit() method of the business operation. For example:

 Method OnInit() As %Status
  {
      Set ..Adapter.LineTerminator="$C(10)"
      Quit $$$OK
  }
Copy code to clipboard

You can also make the property value to be dependent on the operating system:

 Set ..Adapter.LineTerminator="$Select($$$isUNIX:$C(10),1:$C(13,10))"
Copy code to clipboard
PutString()
Method PutString(pFilename As %String, pData As %String) As %Status
Copy code to clipboard

Writes a string to the file.

PutStream()
Method PutStream(pFilename As %String,
                 pStream As %Stream,
                 ByRef pLen As %Integer = -1) As %Status
Copy code to clipboard

Writes a stream to the file.

Rename()
Method Rename(pFilename As %String,
              pNewFilename As %String,
              pNewPath As %String = "") As %Status
Copy code to clipboard

Renames the file in the current path or moves it to the path specified by pNewPath.

Example Business Operation Class

The following code example shows a business operation class that references the EnsLib.File.OutboundAdapter. This class can perform two operations: If it receives valid patient data, it files patient information based on patient status. If it receives invalid patient data, it logs this information separately.

Class training.healthcare.operation.OpeFilePatient Extends Ens.BusinessOperation
{

Parameter ADAPTER = "EnsLib.File.OutboundAdapter";

Parameter INVOCATION = "Queue";

/* write on log file wrong patient records */
Method writeHL7Message(
       pRequest As EnsLib.HL7.Message,
       Output pResponse As Ens.StringResponse)
       As %Status
{
  $$$LOGINFO("called HL7 Writer")

  set ..Adapter.FilePath="C:\Intersystems\ensemble\test\ftp"

  set st=..Adapter.PutLine("patient.log",message)

  Quit $$$OK
}

/* write on log file wrong patient records */
Method logWrongPatient(
       pRequest As training.healthcare.message.MsgPatient,
       Output pResponse As Ens.StringResponse)
       As %Status
{
  $$$LOGINFO("called OpeFilePatient")

  set ..Adapter.FilePath="C:\Intersystems\ensemble\test\errorparh"
  set message="some information are missing from record: " _
              pRequest.sso _ ", " _
              pRequest.name _ ", " _
              pRequest.surname

  set st=..Adapter.PutLine("patient.log",message)

  Quit $$$OK
}

/* write in xml format the list of active/inactive/requested patients */
Method writeSSOList(
       pRequest As Ens.StringRequest,
       Output pResponse As Ens.StringResponse)
       As %Status
{
  set ..Adapter.FilePath="C:\Intersystems\ensemble\test\ftp"
  set status=pRequest.StringValue

  if status="ACTIVE" set fileName="ActiveSSO.xml"
  if status="INACTIVE" set fileName="InactiveSSO.xml"
  if status="REQUESTED" set fileName="RequestedSSO.xml"

  set st=..Adapter.PutLine(fileName,"<patients>")

  set rs=
  ##class(training.healthcare.data.TabPatient).selectPatients("",status)
  while rs.Next(){
    set st=..Adapter.PutLine(fileName,"<patient>")
    for i=1:1:rs.GetColumnCount() {
      set st=..Adapter.PutLine(fileName,
        "<"_ rs.GetColumnName(i)_">" _
        rs.GetData(i)_"</"_ rs.GetColumnName(i)_">")
    }
    set st=..Adapter.PutLine(fileName,"<patient>")
  }

  set st=..Adapter.PutLine(fileName,"<patients>")

  set pResponse=##class(Ens.StringResponse).%New()
  set pResponse.StringValue="done"

  quit $$$OK
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="training.healthcare.message.MsgPatient">
    <Method>logWrongPatient</Method>
  </MapItem>
   <MapItem MessageType="Ens.StringRequest">
    <Method>writeSSOList</Method>
  </MapItem>
</MapItems>
}

}
Copy code to clipboard

Adding and Configuring the Business Operation

To add your business operation to an Ensemble production, use the Management Portal to do the following:

  1. Add an instance of your business operation class to the Ensemble production.

  2. Configure the business operation. For information on the settings, see “Reference for Settings.”

  3. Enable the business operation.

  4. Run the production.