Hi

What are your settings for charset, content type and content encoding?

I would expect to see something like this:

  1. ContentEncoding = "HL7-ER7"
  2. ContentCharset = "UTF-8"
  3. ContentType = "application/hl7-v2"

The most common type of framing is MLLP. If you are acting as an HL7 server tand you don't know what the client framin is then set framing to flexible. that way ensemble will try and detect the framing based on the properties listed above and by looking for tell tale characters (segment terminators) such as LF $c(10) or CR,LF $c(13,10).  Depending on the properties listed above you may see the terminator represented as "/r". 

If you are the HL7 client then you can get away with framing = none provided both you and the 3rd party server are consistent on the content type, charset and encoding.

I hope that gives you some ideas of what to look out for and the questions you need to ask the 3rd party application you are trying to communicate with.

Yours

Nigel

Hi Carl

Ok, thank you for the additional information. Unfortunately I don' have an answer for the issue you are facing. I suggest you open an issue with the WRC.

Yours

Nigel

Hi

I am wondering if this is a user security level issue. As you know you need Windows/Unix Administrator rights to install Cache/Ensemble/IRIS. The same is true if you want to run any of the executables in the 'bin' directory such as cstart cachesystray and so on. I am not a UNIX expert and so I can  only speak from my Windows experience but assuming this is windows close the Cache/Ensemble/IRIS systeray icon and then from the 'bin' directory fine th csystray.exe, right click and slect 'run as administrator', then see if you can start or shut down your instance.

If that fails and all other suggestions from the Developer community uninstall C/E/IRIS and reinstall it making sure you run the installation as 'Administrator'

The final suggection is check your cache.key or iris.key and make sure your license is still valid.

Yours

Nigel

sorry, let me correct the parameter declaration as

method ABC(myContext as %RegisteredObject) as %Status

...

Nigel

Hi

Can you upload the class definition of the table that contains the data as well as the routines that were generated by the sql compiler i.e. the classes and routines for *.SMTKTUAT.*.* (.cls, *.int)

Have you tried accessing the data through the Management Portal->Stystem Explorer->SQL->Execute Query?

Have you tried setting up an ODBC DSN and then accessing the table from within say Excel?

If you set up a Windows ODBC DSN you can turn on logging for the DSN

To resolve this issue you need to isolate whether the issue lies within the code generated by IRIS for the sql statement, or whether it is the ODBC/JDBC connection functionality.

Have you written a simple class method using %Library.ResultSet as in

classmethod TestQuery() as %Status

{

      set tSC=$$$OK

      try {

              set rs=##class(%ResultSet)).%New("%DynamicQuery:SQL")

              set tSC=rs.Prepare("select col1, col2, ...., colN from Table where ....") if 'tSC quit

             set tSC=rs.Execute() if 'tSC quit

             while rs.Next(.tSC) {

                     if 'tSC quit

                     write !,rs.Data("Col1")," ",rs.Data("Col2")," ", ...., rs.Data("ColN")

           }

         }

         catch ex {set tSC=ex.AsStatus()}

        if 'tSC write !,$system.Status.GetErrorText(tsc)

        quit tSC

}

Nigel

Hi

Bear in mind that when you are working with DTL's when you invoke the Transform() method there is a third parameter called aux. The aux object can be an instance of any class you design and can contain any properties you desire. These are typically values that you want to use in the DTL that are not part of your request object.

When you call the DTL you create a new instance of your aux class and then when you invoke the DTL Transform you can write the following code:

set tSC=##class({Your DTL}).Transform(request,.response, .aux) where aux is an instance of your custom aux class.

This is true also of DTL's called from a BPL with one exception. If the DTL is invoked from a Business Rule then the Business rule creates an instance of a system defined aux object that contains information about which rule invoked the DTL and so on. 

I am busy trying to convert a Custom Code Business Process that will invoke a DTL and am still trying to get my head around what variables/objects are available in the BPL (Context) and the DTL.

If you resolve how to create a BPL using the context object and then invoke a DTL into which you can pass data other than the request and response message I would be interested to know how if you have success and how you managed to get it to work.

Yours

Nigel

Hi

Here is an example of a HTTP Operation POSTing HL7 messages. this HTTP request uses HTTPS and a Proxy Server. The lines I have highlighted in Yellow will be different in your case as you are sending JSON. Not clear if you are using FHIR. However your ContentType will most likely be application/json or application/json+fhir

    set tSC=$$$OK,pResponse=""
    try {
        set message=pRequest.OutputToString(,,.tSC) if 'tSC quit
        set tResponse = ##class(%Net.HttpResponse).%New(),tResponse.ContentType="application/hl7-v2"
        if '$IsObject(..HTTPRequest) {
            set pHttpRequest=##class(%Net.HttpRequest).%New()
            set pHttpRequest.Server=..Adapter.HTTPServer
            set pHttpRequest.Port=..Adapter.HTTPPort
            set pHttpRequest.ProxyServer=..Adapter.ProxyServer
            set pHttpRequest.ProxyPort=..Adapter.ProxyPort
            set pHttpRequest.ProxyTunnel=..Adapter.ProxyHttpTunnel
            set pHttpRequest.ProxyHTTPS=1
            set pHttpRequest.SSLConfiguration=..Adapter.SSLConfig
            set pHttpRequest.UserAgent="curl/7.29.0"
            set pHttpRequest.ContentEncoding="HL7-ER7"
            set pHttpRequest.ContentCharset="UTF-8"
            set pHttpRequest.ContentType="application/hl7-v2"
            set pHttpRequest.AcceptGzip=0
            set pHttpRequest.WriteRawMode=0
            set pHttpRequest.ReadRawMode=0
            set pHttpRequest.OpenTimeout=..Adapter.ConnectTimeout
            set pHttpRequest.Timeout=..Adapter.ResponseTimeout
            set pHttpRequest.WriteTimeout=..Adapter.WriteTimeout
            set pHttpRequest.SocketTimeout=115
            set ..HTTPRequest=pHttpRequest
        }
        set ..HTTPRequest.HttpResponse=tResponse
        do ..HTTPRequest.EntityBody.Write(message)
        set tSC=..HTTPRequest.Post(..Adapter.URL,0,1) if 'tSC {
            set sc=$$$DebugLog("HTTP Write","Error: "_$$$GetErrorText(tSC))
        }
        else {do $$$DebugLog("HTTP Write","Post Sucessful)}
        set response=..HTTPRequest.HttpResponse
        $$$TRACE("HTTP Response Status: "_response.StatusCode)
        if response.StatusCode=200 {
            if $IsObject(response.Data) {
                set message="" while 'response.Data.AtEnd {set message=message_response.Data.Read(,.tSC) if 'tSC quit}
                set pResponse=##class(EnsLib.HL7.Message).ImportFromString(message,.tSC) if 'tSC $$$TRACE("An error occurred creating Respnse Message: "_$system.Status.GetErrorText(tSC))
            }
        }
        else {
            set message="" if $IsObject(response.Data) {set message="" while 'response.Data.AtEnd {set message=message_response.Data.Read(,.tSC) if 'tSC quit}}
            set tSC=$$$ERROR(5001,"HTTP Response Status is "_response.StatusCode_" with Error Text: "_response.ReasonPhrase_" with Content: "_message) quit
        }
    }
    catch ex {
        set tSC=ex.AsStatus()
    }
    if 'tSC,'$IsObject(pResponse) {

  // Here I create a NACK HL7 message if I didn't get a valid response from the remote server. Possibly because the server is down or the 

 //server has crashed. I have a DTL that takes the inbound HL7 request message and transforms it into an HL7 ACK message. I force the ACK 

// Code to "AE" and use the contents of tSC (error status) as the Error Message. Note I make use of the 3rd parameter in the Transform()

// method that allows you to pass in an object containing any properties you want. This is a useful way of getting data into the DTL that

// doesn't exist in either your sourse or target objects.

        set pResponse=##class(EnsLib.HL7.Message).%New(),aux=##class(HPRS.Transformations.CreateNACKDTL.AUX).%New()
        set aux.ACKCode="AE",aux.ACKMessage=$system.Status.GetErrorText(tSC)
        set sc=##class(HPRS.Transformations.CreateNACKDTL).Transform(pRequest,.pResponse,.aux) if 'sc $$$TRACE("Unable to Create NACK Response HL7 Message")
    }
    $$$TRACE("Outcome of HTTP Operation: "_$s(tSC:"Ok",1:"Error: "_$$$GetErrorText(tSC)))
    quit $$$OK

Yours

Nigel Salm
 

Hi

The short answer is yes, you are constrained by the 3.6Mb string size limit and bear in mind that if you are exposing that property to SQL and ODBC you are further constrained by the limitations within ODBC itself. 

I have been giving this whole concept a lot of thought recently. My context is slightly different as I am working in the context of FHIR and JSON and for example you can send in a patient's photo which in JSON has to be represented as a string of Base64Encoded Binary . In principal that photo could be of any size but when the JSON string is converted into a FHIR Patient Object the underlying datatype of the photo.data.value is ultimately derived from a class called %xsd.Base64Binary which is esentially a string and therefore has the size limitation. It doesn't really matter what my underlying persisted datatype is i.e. %GlobalBinaryStream because I am working with the IRIS FHIR Classes as intemediary object classes between my JSON and my underlying persisted classes I have to work with the constraint that the JSON Base64Binary content will fail if it's length exceeds the 3.6Mb (something I wish to address with ISC/WRC at some point).

The alternative of course, to persisting larger data content of something link an image, is to have a url that points to the image location and can be retrieved from the image server for presentation purposes.

So where I know that my images are not going to be that large I read in or write out the base64binary from/to my JSON message but where I know the image is larger such as an x-ray or histo image then that content lives on the appropriate image server as is retirieved  when required for presentation purposes.

Nigel Salm

Hi

Remember that not only messages contribute to the volume of ensemble generated data. If you are using $$$TRACE in your production then this will generate a lot of data in the Ensemble namespace . If you have lots of TRACE statements then this can generate a lot of data.

There is a class method

do ##class(Ens.Purge).PurgeEventLogsByDate({NumberOfDaysToRetainTraceData},.count) There are other methods in this class to purge other management data such as messages

Trace information is stored in the global ^Ens.Util.LogD and ^Ens.Util.LogI

Nige;

My guess is that you need to specify Exception as a Status i.e.:

Exceptuion.AsStatus()

and then your code should read

set pOutput=##class(MyResponse).%New()

set sc=Exception.AsStatus()

set pOutput.errorString=$system.GetErrorText(sc)

but another thought:

If your method quits with tSC (as a %Status) then presumably your method quits with

quit tSC

in which case instead of trowing tSC just quit your Try {} with quit tSC

and in your catch write it as follows:

catch Exception {

   set tSC=Exception .As Status()

}

set pOutput=##class(MyResponse).%New()

set pOutput.errorString=$s(tSC:"",1:$system.Status.GetErrorText(tSC))

quit tSC