Developing Ensemble Productions
Defining Business Operations
[Home] [Back] [Next]
InterSystems: The power behind what matters   
Class Reference   

This chapter describes how to define business operation classes. It contains the following sections:

Ensemble provides specialized business operation classes that use specific outbound adapters, and one of those might be suitable for your needs. If so, no programming would be needed. For a partial list, see Connectivity Options in Introducing Ensemble.
A business operation is responsible for sending requests from Ensemble to an external application or system. The following figure shows how it works:
Note that this figure shows only the input flow of data, not the optional response.
A business operation is responsible for the following activities:
Each business operation contains a message map that specifies which external operation to perform, depending on the type of request message that it received. The message map contains one or more entries, each of which corresponds to one invocation of the associated outbound adapter.
Key Principles
First, be sure to read the chapter Programming in Ensemble.”
By convention, a business operation is an extremely specific operation that contains very little logic and does what is requested of it without calling further operations or branching in any way. When the design of the production demands logic, this is contained in a business process.
Many productions provide a large set of extremely simple business operations. In these cases, business processes contain the logic that determines when each operation should be called.
Also see Key Principles in the chapter Defining Business Services.”
Defining a Business Operation Class
To create a business operation class, define a class as follows:
The following example shows the general structure that you need:
Class MyProduction.NewOperation Extends Ens.BusinessOperation 
Parameter ADAPTER = "MyProduction.MyOutboundAdapter";

Parameter INVOCATION = "Queue";

Method SampleCall(pRequest As Ens.Request, Output pResponse As Ens.Response) As %Status
  Quit $$$ERROR($$$NotImplemented)

XData MessageMap
  <MapItem MessageType="Ens.Request">
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.
For examples of business operation classes, see the adapter guides.
Defining a Message Map
A message map is an XML document, contained within an XData MessageMap block in the business operation host class. For example:
Class MyProduction.Operation Extends Ens.BusinessOperation

XData MessageMap
  <MapItem MessageType="MyProduction.MyRequest">
  <MapItem MessageType="Ens.StringRequest">

The operation of the message map is straightforward. When the business operation receives an incoming request, it searches, starting at the top of the message map, through each MapItem until it finds the first one whose MessageType attribute matches the type of the incoming message. It then invokes the operation method associated with this MapItem.
Some things to keep in mind about message maps:
Defining Message Handler Methods
When you create a business operation class, typically the biggest task is writing message handlers for use with this adapter, that is, methods that receive Ensemble messages and then invoke methods of the adapter in order to communicate with targets outside the production.
Each message handler method should have the following signature:
Method Sample(pReq As RequestClass, Output pResp As ResponseClass) As %Status
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 some or all of the following:
  1. Optionally set properties of the business operation class (at any appropriate time). See Business Operation Properties.”
  2. Examine the input object.
  3. Create an instance of the response class.
  4. Call the applicable method or methods of the adapter. These methods are available via the Adapter property of your business operation. For example:
        Set tSc=..Adapter.SendMail(email,.pf)
    This method is discussed after these steps.
    Or, to send messages to a target within the production, see Sending Messages to a Target within the Production.”
  5. Examine the response.
  6. Use information in the response to create an Ensemble response message (an instance of Ens.Response or a subclass), which the method returns as output.
    For information on defining message classes, see the chapter Defining Ensemble Messages.”
  7. Make sure that you set the output argument (pOutput). Typically you set this equal to the response message. This step is required.
  8. Return an appropriate status. This step is required.
Business Operation Properties
Within an operation method, the following properties of the business operation class are available:
Property Description
%ConfigName The configuration name for this business operation.
%SessionId The session ID of the current message being processed.
Adapter The associated outbound adapter for this business operation.
DeferResponse To defer the response from this business operation for later delivery, set the DeferResponse property to the integer value 1 (true) and obtain a deferred response delivery token before exiting the business operation.
FailureTimeout The length of time (in seconds) during which to continue retry attempts. After this number of seconds has elapsed, give up and return an error code. See Retry and RetryInterval.
Retry Set this property to the integer value 1 (true) if you want to retry the current message. Typically, the retry feature is used when the external application is not responding and you wish to retry without generating an error. See RetryInterval and FailureTimeout.
RetryInterval How frequently (in seconds) to retry access to the output system if this message is marked for retry. See Retry and FailureTimeout.
SuspendMessage Set this property to the integer value 1 (true) if you want the business operation to mark its current in-progress message as having Suspended status. See the section Suspending Messages.”
Sending Requests to Targets within the Production
Although a business operation is primarily responsible for delivering a request to the specific external application, it can also send messages to other business operations or to business processes, as needed. To send messages to a target within the production, call SendRequestSync(), SendRequestAsync(), or SendDeferredResponse().
For information on these methods, see Sending Request Messages in the chapter Defining Business Services.”
Ens.BusinessOperation defines an additional method that you can use: DeferResponse().
The DeferResponse() Method
This method returns a %Status value indicating success or failure. It provides one by-reference argument, token, which returns the deferred response delivery token required for a later call to SendDeferredResponse(). For example:
   Set sc=..DeferResponse(.token)
   // Send the token out somewhere...
   Quit $$$O
For an overview of deferred sending, see Using Deferred Sending in the chapter Programming in Ensemble.”
Suspending Messages
If you want the business operation to mark its current in-progress message as having Suspended status, set the business operation property SuspendMessage to the integer value 1 (true). Typically a business operation will do this for messages that have been rejected by the external system for some reason.
Ensemble places a Suspended message on a special queue so that a system administrator can diagnose the problem, fix the problem, and then resend the message. The system administrator can perform a simple resend (to the original target) or can send it to a new destination. For information, see Monitoring Ensemble.
The following sample method is from a business operation that sends a document to an external system. The method sets the SuspendMessage property to 1 if an error returns from the call to Validate() the document that is about to be sent:
Method validateAndIndex(pDoc As MyX12.Document) As %Status
  If ""=..Validation||'$method($this,"OnValidate",pDoc,..Validation,.tSC) {
    Set tSC=##class(MyX12.Validator).Validate(pDoc,..Validation)
  Set:'$D(tSC) tSC=$$$OK
  If $$$ISERR(tSC) {
    Set ..SuspendMessage=1
    Do ..SendAlert(##class(Ens.AlertRequest).%New($LB(
        ..%ConfigName,"Suspended document "_pDoc.%Id()_
        " because it failed validation using spec '"
        _..Validation_"' with error "_
    Quit tSC
  If ""'=..SearchTableClass {
    TRY {
      Set tSCStore=$classmethod(..SearchTableClass,"IndexDoc",pDoc)
      If $$$ISERR(tSCStore)
        $$$LOGWARNING("Failed to create SearchTable entries")
    CATCH errobj {
      $$$LOGWARNING("Failed to invoke SearchTable class")
  Quit $$$OK