· Jul 18

Custom Business Process Required Methods

I am hoping someone can let me know if I've gone down a dark path or not:

  • I'm using the record mapper to create a business service that waits for a .txt file and sets pipe delimited data to the mapper's record class
  • That record (essentially the raw data) is sent to a business process 
    • OnRequest() is implemented where it opens or creates an instance of the target object and validates and transforms and sets the data to the target object as needed; the response is that target object.
    • OnResponse() is implement as a shell and simply returns $$$OK
  • The goal is simply to update or create the target object from the data in the file where it will sit and wait for another process to pick it up and send it off to where it needs to go (i.e. I don't need to send it to a business operation after the business process is done.


  • Am I just totally misusing Ensemble by not using a DTL or BPL here?  It's a small enough file that it's easier for me to code the transformations in the OnRequest() method (or I guess I can create a instance method to call and put that logic there), but I don't see the need to send an async request because at that point I'm not requesting anything else.
  • I am not clear where the response output (from the method signature) is going and what it's used for in the OnRequest() method; I think the answer is that this would get sent back to the business service is send sync was true, is that correct?
  • I am not clear what I should be doing with the OnResponse() method - I feel like I would only need to implement that if I was sending a new request from OnRequest() to another service and was expecting a response from that service.

I don't want to over-complicate the ingestion of a simple file but I want to make sure I'm not doing something silly.  Ideally it would be:

  • File in and mapped to record with record mapper
  • Record is used to add to or create an instance of the target class
  • Error if something goes wrong, otherwise we don't need acks or confirmations or anything beyond what's in the message header
Product version: IRIS 2023.1
Discussion (3)2
Log in or sign up to continue

Well, I'll answer you from my experience, maybe I'm wrong.

About your first question, you are totally free to use a encoded BP or BPL and DTL, as you prefer. I usually prefer to use BP by code for custom objects and DTL and BPL when I work with HL7 messages...why? because I'm too lazy to write code foreach transformation of field in an HL7 message.

The Business Service used by the RecordMapper has a property called Synchronous Send:


When you check it the Business Service is going to send the record mapped in a sync call to your BP, so it's not going to read a new line of the file until a response is received from the destination.

About the OnRespone, you can check the official documentation:

I usually implement the OnResponse to receive Async responses from Business Operations called by my BP, in your case I think that it's unnecessary, but this is a personal opinion.

Thanks @Luis Angel Pérez Ramos!

Yes, agreed on DTLs for HL7 - it's built for that!  In my case, yes, it's a custom object.  Also, I think for my use I will keep the request from the service to the process (the mapped record to the processing) as async.  

So I'm still a little unclear and, yes I have read and reread that page of documentation but I'm left with questions.  Let me stub out some code to see if I can narrow down my thoughts (sorry I'm really clumsey with this editor)

Class BusinessProcess extends Ens.BusinessProcess {

Method OnRequest(request as Record.From.Mapper, response as MyCustomObject) as %Status {

  // does it make sense that my response is here the custom object 
  // I'm transforming my record to?  i don't see a need to create a 
  // whole new response class just to say the record was completed . . . 
  // either the response is "" or an instance of MyCustomObject

  s response=##class(MyCustomObject).%New()
  s response.rawData1=$e(request.PropertyToExtractFrom)
  s response.RawData2=$zstrip($p(request.DelimitedProperty,""|",2),"<>W")
  d response.%Save()

  // this is where i'm sacrificing the dtl and bpl for just simple code - 
  // sounds like you say you do this for custom objects, so i think i'm good

  q $$$OK

  // does the response even matter here?  i'm not sending it to a business 
  // operation, however we do have a kind of dummy business operation we can 
  // use to send the response to and nothing happens, just kind of an ending 
  // point to say "we're done and there was no issues".

  // so i could implement something like:
  // ..SendRequestAsync("DummyOperationToSayWe'reDone",0) q 1


Method OnResponse(request As %Library.Persistent, ByRef response As %Library.Persistent, callrequest As %Library.Persistent, callresponse As %Library.Persistent, pCompletionKey As %String) As %Status


  // the documentation says i must implement this but i was able to compile without . . . 
  // you also seem to indicate it's optional.  since i'm not handling any responses 
  // from any of the business hosts this isn't necessary to implement i think.  
  // if i were to implement request would be an instance of Record.From.Mapper and 
  // response would be the response defined in the business process or operation, yes?

  q $$$OK


I think I answered my own question after working more on it today.  

My OnRequest() method processed the record with ObjectScript code.  I just was careful to return a proper %Status if there was an error so Ensemble knew what to do.  I used the Ens.StringContainer response class to set the response (which isn't used as far as I can see because it's async from the business service) and used that same response object as the request to a business operation just to finish things up.  That wasn't really necessary either, but while viewing the messages I can see a processing message that has the file name and resulting object ID so we can troubleshoot if needed.