go to post David Loveluck · Jun 28, 2016 Laurayour 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 documetnationdave
go to post David Loveluck · Jun 22, 2016 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.
go to post David Loveluck · Jun 21, 2016 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
go to post David Loveluck · Jun 13, 2016 thanks for correcting me Steve. As well as selecting, you have to enable.
go to post David Loveluck · Jun 13, 2016 thanks for correcting me Steve. As well as selecting, you have to enable.
go to post David Loveluck · Jun 10, 2016 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.
go to post David Loveluck · Jun 2, 2016 I looked at the code and StatsStarted returns 1 if InitStats has been called within the current business service. So it is more than statistics being enabled for that config item. I will get someone to look at the sample code.
go to post David Loveluck · Jun 1, 2016 Hi Jamesi 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 widgetsIf 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
go to post David Loveluck · May 19, 2016 It doesn't change this discussion but for many years we have documented that a proper web server such as IIS or Apache and CSP should be used instead of the http inbound adapter in any operational setting.That provides a level of operational robustness (security, recovery etc.) that the inbound adapter will not provide.dave
go to post David Loveluck · May 13, 2016 I think you might be getting local times and UTC times mixed up.TimeCreated is stored in UTC and now() gives you local time so your arithmetic could be giving a negative numberDave
go to post David Loveluck · Apr 27, 2016 Thanks Clayton. Overriding OnConstructReply like this is very useful for constructing non standard ACKs in the HL7 world as well.
go to post David Loveluck · Apr 22, 2016 Richardwelcome 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 athttp://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.Enjoydave
go to post David Loveluck · Apr 21, 2016 Jeffseveral 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.pdfdetailed documentation:http://docs.intersystems.com/ens20152/csp/docbook/DocBook.UI.Page.cls?KE...
go to post David Loveluck · Apr 21, 2016 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.
go to post David Loveluck · Apr 14, 2016 Stevedo you just mean that the recipient is responsible for opening the TCP/IP connection? You can make that happen by putting ! in front of the TCP/IP address of the targetDave
go to post David Loveluck · Mar 29, 2016 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.
go to post David Loveluck · Mar 14, 2016 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 eithera)you do not use the ProcedureBlock class keyword,orb) you put process in the public list for you methodthen 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
go to post David Loveluck · Mar 14, 2016 if you are using a routing rule I think you can use the context property Source. So your condition for testing if it came from your "fromLab" busienss service would be Source="fromLab"
go to post David Loveluck · Mar 3, 2016 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.
go to post David Loveluck · Feb 29, 2016 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.