Laura

your sample file is a an interchange (look for the ISA and IEA segments) that include one group (see the GS and GE segments) that in turn contains one 835 message (look for the ST and SE segments).

An interchange can contain multiple groups which typically contain many individual transactions.

You should just copy the ST and SE segments and all in between and use that to test your 835 transformation.

You can then create transformations on the interchange and the group and loop through all the individual transactions calling your DTL as subtransformations. I think this is documented but it has got easier in the last few years so hopefully you are on a modern release.

Alternatively, because people want the same simple changes to the interchange and group segments for all X12 transactions people often just write than bit in object script.

Ask again if you don't find the documetnation

dave

it is intended for constant collection of statistics from a live system.

To minimize the overhead, the counts are accumulated in memory and written to disk at intervals. Benchmarks showed no significant increase in resources consumed with statistic gathering turned on.

This means the package avoids anything that would be relatively expensive to collect. For example several people have asked for the average size of a message to be collected but this would have needed an extra method call to get the information.

It also means that the statistics are not guaranteed to be correct if the system crashes.

With 2015.1 and later you have the option to increase the rule logging. This will tell you exactly what is going on when executing a routing rule. 

There is a setting in the Development & Debugging section of the configuration settings of a routing engine. That is described as ...

This set of flags controls the logging performed by the rule engine whenever a routing rule is executed. The following flags are available:

  • 'e' - log errors only. All errors will be logged irrespective of other flags, so setting the value to 'e' or leaving the value empty will only log errors.
  • 'r' - log return values. This is the default value for the setting, and is also automatic whenever the 'd' or 'c' flags are specified.
  • 'd' - log user-defined debug actions in the rule. This will also include 'r'.
  • 'c' - log details of the conditions that are evaluated in the rule. This will also include 'r'.
  • 'a' - log all available information. This is equivalent to 'rcd'.

Dave

As Liz says this feature has been in Ensemble for about ten years. One very obvious use case in development is to have a file based BO as a duplicate of a TCP BO so you can cut out all the complexity of testing with a real target system.

To add a duplicate you just add another config item to your production with the same name.

Whichever one is selected from the pull down will start up with the production.

To remove a duplicate you select the one you want to delete from the pull down and delete the config item from the production. The other one will be left behind. Or you could edit the XML to remove it.

Hi James

i don't know exactly what you are doing so i'll give some background and you can ask more questions.

 

InitStats initializes the local counters. Like resetting and starting the stopwatch.

RecordStats takes the values since InitStats and adds them to the temporary array.

The framework call these two for you. For example Ens.BusinessService.ProcessInput() of a business service calls them to capture the activity of a single invocation of a business service.

 

If you want to capture stats in your own code you can call them yourself.

If you have called SetStatsUserDimension between the two then that value is put in the userdimension field. For example, if my application has a business service that is accepting orders for widgets then in OnProcessInput I might have the line

     do ##class(Ens.Util.Statistics).SetStatsUserDimension(..%ConfigName,pInput.Color)

and I would be able to get a breakdown of statistics for black, blue or green widgets

If you want to use your own statistics instead of out elapsed time and count, you can use RecordStats to write whatever values you like to the temporary array.

StatsStarted() is supposed to be used to check that statistics gathering has been turned on for the production or config item. For now, just don’t use it and assume the stats are turned on. I will find out more.

I don’t remember what StatsActive() means you probably don’t need to call it. I have never used it.

 

 

Dave

Richard

welcome to the community. I think you are misunderstanding a few things and making life hard for yourself. If you are just processing HL7 messages you probably don't need to do any coding until you get to more advanced topics. The graphical editors will do nearly everything you need.

I suggest you watch the  getting started videos at

http://video.intersystems.com/video/Video.Pages.VideoLibrary.cls?video=1...

below the first video there is a playlist of  topics including one on transformations. Notice that there is an odd shaped arrow to the right of the three playlist items visible on the screen so you can scroll across and see the others,

You can probably watch all seven videos in about an hour and you will be ready to start.

Enjoy

dave

Jeff

several points:

1) Extending EnsLib.SOAP.Service is absolutely fine as long as you  make sure it uses CSP and not the HTTP Inbound Adapter. We are trying to remove all references to that adapter from our examples but it is taking a longer than i had hoped.

2) In general,for creating a SOAP service that is not just a pass through (or close to pass through)  i normally prefer to just extend %SOAP.Service and keep the  business service definition separate. It means you have to do a small amount of extra work, but you also get more control. It is a matter of personal preference.

3) For pass through you should probably use the EnsLib.xxxx.GenericService where xxxx is one of REST, HTTP or SOAP. These bundle up additional information such as the http headers so the  outbound request faithfully reproduces the inbound request.

4) And finally if you want to gain efficiency by reducing the overhead of persistent messages within Ensemble you should look at the new features included in 2015.2. For these pass through cases you can now user real inproc calls and suppress all the message storage and journal creation. This makes it more efficient but you lose the message trace.

release notes:

http://docs.intersystems.com/documentation/ensemble/20152/pdfs/EGRN.pdf

detailed documentation:

http://docs.intersystems.com/ens20152/csp/docbook/DocBook.UI.Page.cls?KE...

This is a very good question but there are some subtleties that need to be considered.

On a production server, compilation should be part of a managed deployment process so this isn’t an issue, but in development it is easy to forget to restart a BS or BO.

This situation only applies to Business Services and Business Operations. Typically in a BS or BO the class that implements the service remains instantiated until the BS is disabled or the production is restarted and so the old code runs. The Business process class is instantiated for each request so it doesn’t apply there.

It can be more complicated. For example if a BS is instantiated by application code using CreateBusinessService() from (for example) a web page the BS class will be instantiated for each request so you will see the new code picked up immediately. On the other hand if one job in a pool dies and is restarted, or if the pool size is increased, then you can have a mixture of BS jobs, some running the old code and some running the new code. This is probably rare in development but I do know someone was confused by that situation a few years back.

The configuration page that shows connections can’t know what code is instantiated in running Business Services and the connection lines have to be derived from the current code in the class definition. The only thing that could be done with that is to disable the functionality if the class has been compiled; but that would be unhelpful in the cases when the change had nothing to do with routing.

If a BS or BO continues to run older code after the class is compiled, then we log a message in the event log. We might be able to set a flag in the Job Status global and have an indication in the production monitor based on that, but this situation exists on a job basis, not on a configuration item basis so the UI would be a compromise in the special circumstances described above. I have recorded the enhancement request but nothing is currently planned so for now, I would always advise restarting a BS or BO as soon as you compile the class.

this is data captured as a result of setting 'archive IO' on a BS or BO.

There is no UI to view the IO log but if you search the documentation for IOLog it will tell you the SQL query to use.

For adapters this is intended to capture information close as close to being the information sent over the wore as possible. However, for many technologies (e.g. CSP or xDBC) that is not very close and there are better ways to capture the information sent over the wire, so this is not as widely used as it once was.

I don't know why it wouldn't be purged if the time created is old enough for you to expect it to be purged.

i thought a routing engine was the harder case :-)

If you are in COS called from BPL then you can access the current BP as 'process' as long as either

a)you do not use the ProcedureBlock class keyword,

or

b) you put process in the public list for you method

then you can access properties of the process such as %PrimaryRequestHeader

ClassMethod MyMethod(vale As %String) As %String [ PublicList = process]

{

   ...

  set src=process.%PrimaryRequestHeader.SourceConfigName

   ...

}

If you are calling a COS funciton from a routing rule, you can get similar information form the variable 'context' which is a reference to an object of type EnsLib.HL7.MsgRouter.RoutingEngine 

Without a FIFO requirement, you could simpley increase the pool size on the BO; but if you want to maintain FIFO  for messages referring to the same patient, i don't see a simple alternative to your suggestion.

I have seen solutions that put messages for a patient on a hold-queue until they can be processed, but this seems overkill for your situation. It is complicated to get right.

It looks as if  you are receiving a patient query (QRY_A19) so the approach depends on where the information for the reply is going to come from. 

If the BS has all that information in Ensemble then you can just do as you suggest. If it has to come from a downstream system then you might have to use business service setting 'AckMode=Application'. This means the business service will wait for an ACK  to be sent to it from downstream. If that response is exactly what you want, you can use it. Otherwise you will still have to override OnConstructReply to use the ACK to build exactly what you need.