Hi Otto,

This appears to be a typo.  I've modified the marketplace listing and republished, which could take a few days to get approved. 

However, since this is a BYOL instance, once deployed it will just give you a VM which contains the IRIS for Health image, but no running container. The '1971' typo means that port 1971 is open to the VM in the firewall, but IRIS does not (yet) have any SuperServer port defined since it is not running. You could either start IRIS on 1971, or you could add a new firewall rule in GCP to open up port 1972 instead, in the meantime.

Thanks,

Steve

Hi Ignacio,

It looks like the container does not run automatically by the GCP launcher.  I was able to start it manually:

leblanc@intersystems-iris-health-community-editio-2-vm:~$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
leblanc@intersystems-iris-health-community-editio-2-vm:~$ sudo docker images
REPOSITORY                TAG                   IMAGE ID            CREATED             SIZE
intersystems/irishealth   2019.1.0S.111.0-gcp   a39d75e7a42b        9 months ago        1.61GB
leblanc@intersystems-iris-health-community-editio-2-vm:~$ sudo docker run -d -p 52773:52773 --name iris --init intersystems/irishealth:2019.1.0S.111.0-gcp
1932a6736c70d5e5dbd604b040f11907e8cdffa0aaccbbfce14bc37114c1ec46
 

Then I can launch the Management Portal, log in with SuperUser/SYS (then prompted to change my password), and use the instance.

I'll follow up internally to make sure the environment launches as intended, or at least see that the instructions are modified if this is how it is intended to work.

-Steve

Hi James,

Why do you need to convert the HL7 message to a stream at all?  You can use EnsLib.HL7.Operation.HTTPOperation, which expects a message of type EnsLib.HL7.Message, and handle the conversion and HTTP POST for you. Then you can apply HL7 routing rules and transformations in your production, and see the HL7 parsed out with the appropriate schema overlaid in the message trace.

Steve

Does your router apply a data transformation to map the Record Map into an object of type EnsLib.EDI.XML.Document? If you have a schema for the target XML format, you can import that into Ensemble under Interoperate > XML > XML Schema Structures, and then create a Data Transformation to go from your Record Map to an EnsLib.EDI.XML.Document, with your imported schema.  Then send the result to your XML FileOperation, as that should be in the format that the operation expects.

There's no Service/Operation setting to do this automatically.  Warnings are written to the Event Log, so one approach that has been recommended before is to set up a task that mines the Event Log periodically to find new warnings, and handle them that way.

Are there specific warnings that you're concerned about? If it's something that you want to be alerted, perhaps those should be considered errors and not warnings.

Scott,

While there's nothing officially supported in the product, I've pulled some code from a sample that a colleague wrote years ago that should do what you need.  Please note that I have not personally tested this code, and since it is not part of the product, it has not been through any QA testing by InterSystems, so you would need to test and use at your own risk.

/// This method takes in an UUencoded GlobalCharacterStream and 
/// returns an UUdecoded GlobalBinaryStream. 
/// UUencoding is a form of binary-to-text encoding that originated in the Unix program 
/// uuencode, for encoding binary data for transmission over the uucp mail system. 
/// The name "uuencoding" is derived from "Unix-to-Unix encoding". Since uucp converted 
/// characters between various computers' character sets, uuencode was used to convert 
/// the data to fairly common characters that were unlikely to be "translated" and 
/// thereby destroy the file. This method UUDECODE reverses the effect of uuencode, 
/// recreating the original binary file exactly.
/// ref.: http://en.wikipedia.org/wiki/Uuencoding
Method UUDECODE(ByRef sUUE As %GlobalCharacterStream, Output sUUD As %GlobalBinaryStream) As %String
{
 S UUDFilename=""
 D sUUE.Rewind()
 S data=sUUE.ReadLine()
 // A file in uuencoded format starts with a header line of the form:
 // begin (mode) (filename)
 // where (mode) is the file's Unix read/write/execute permissions as three octal digits,
 // and (filename) is the name to be used when recreating the binary data. 
 S data=$e(data,$f(data,"begin"),$l(data))
 F {
	 Q:" 01234567"'[$e(data,1,1)
	 S $e(data,1,1)=$tr($e(data,1,1)," 01234567","") ; ignore (mode)
 }
 S UUDFilename=data
 
 While('sUUE.AtEnd) {
	 S data=sUUE.ReadLine() 
	 // The file ends with two trailer lines:
	 // `
	 // end
	 // (The grave accent indicates a line that encodes zero bytes)
	 Q:data="end"
	 
	 // Each data line starts with a character indicating the number of data bytes 
	 // encoded on the line and ends with a newline character. All data lines,
	 // except perhaps the last, encode 45 bytes of data. The corresponding encoded
	 // length value is 'M' (see uudec() below), so most lines begin with 'M'.
	 S n=$$uudec($e(data,1,1))
	 
	 // Each group of four bytes will be decoded back to a 24-bit value. This
	 // 24-bit value is formed by 4 groups of 6-bit values, each corresponds
	 // to every byte in the encoded group. 
	 F i=2:4:$L(data)
	 {
		 Q:n<=0
		 if n>=1 {
			 ; decode(first 6-bit)<<2 | decode(second 6-bit)>>4
			 ;        first 6-bit: 00XXXXXX --> XXXXXX00
			 ;       second 6-bit: 00YYbbbb --> 000000YY 
			 ; first decoded byte: XXXXXXYY
			 S ch=$zb($zb($$uudec($e(data,i,i))*4,255,1),$$uudec($e(data,i+1,i+1))\16,7) 
			 D sUUD.Write($c(ch))
		 }
		 if n>=2 {
			 ; decode(second 6-bit)<<4 | decode(third 6-bit)>>2
			 ;        second 6-bit: 00bbXXXX --> XXXX0000
			 ;         third 6-bit: 00YYYYbb --> 0000YYYY
			 ; second decoded byte: XXXXYYYY
			 S ch=$zb($zb($$uudec($e(data,i+1,i+1))*16,255,1),$$uudec($e(data,i+2,i+2))\4,7) 
			 D sUUD.Write($c(ch))
		 }
		 if n>=3 {
			 ; decode(third 6-bit)<<6 | decode(fourth 6-bit)
			 ;        third 6-bit: 00bbbbXX --> XX000000
			 ;       fourth 6-bit:              00YYYYYY
			 ; third decoded byte: XXYYYYYY
			 S ch=$zb($zb($$uudec($e(data,i+2,i+2))*64,255,1),$$uudec($e(data,i+3,i+3)),7) 
			 D sUUD.Write($c(ch))
		 }
		 S n=n-3
	 }
 }
 Q UUDFilename
 
 // Each uuencoded byte has a range of values from 0 to 63. When 32 is added, 
 // the ASCII characters will lie in the range 32 (space) to 95 (underscore).
 // ASCII characters greater than 95 may also be used, but only the six 
 // right-most bits are relevant. Since the space character is deemed 
 // problematic for data transmission, so the grave accent (` or ASCII 96) is
 // used to represent the encoded zero value. 
uudec(ch)
	Q $zb($a(ch)-32,63,1) ; 6 bits AND
}

Tom,

I presume by now you've had this answered by the WRC, but the issue is most likely that the private Apache web server that ships with Caché/Ensemble does not currently support SSL.  In order to configure SSL, you would need to configure a full Apache or IIS web server, which is typically recommended for any public-facing, production-level deployment anyway.

-Steve

In your HL7 Service, you can set the 'Ack Mode' to Application, which works as follows:

Application ACK — The Ensemble business service does not send an ACK or NACK to the source application until one returns from the target application by way of the Ensemble business operation. The business service returns the ACK or NACK that it receives from the business operation.

Then in your Business Process, you can construct an ACK (using a DTL with an HL7 ACK as the target) and store whatever data you need there.  You may need to use BPL, rather than a MsgRouter, based on the complexity of what you're trying to do.

Hi Mike,

Would it help to have your service extend EnsLib.HTTP.GenericService?  That would support using the standard CSP port, while also giving you the Ensemble Business Service functionality.  Per the class reference docs:

 

----------------

class EnsLib.HTTP.GenericService extends EnsLib.HTTP.Service

Ensemble Generic HTTP Service based BusinessService class. Can use an HTTP InboundAdapter listener, or the standard CSP Service mechanism, or both. In order for the CSP mechanism to work, HTTP Services using this class must be configured with the invoking URL including ?CfgItem= giving the config item name. (Configured Services exposed using the HTTP Inbound Adapter may also be invoked with this URL parameter but because each configured Inbound Adapter listens on its own TCP/IP port this parameter is just a safety check for them.)

---------------------------

 

Or if you're already doing this, can you elaborate on which logic you would have to recreate here that the InboundAdapter gave you?

 

I am also curious to hear from others who have solved this problem who can offer the best approach.

 

Thanks,

Steve