Dealing with JavaGateway output

Primary tabs

Hi everyone, 

I have just started to use JavaGateway and I didn''t encountered so much difficulties since I've got the output of the Java class I have called. 

This is the class I have implemented: 

Method OnRequest(pRequest As EnsLib.HL7.Message, Output pResponse As EnsLib.HL7.Message) As %Status
{
set MDMarchiv=pRequest.OutputToString()
$$$TRACE(MDMarchiv)
#dim RPConverter = ##class(training.hl7.HL7toRP).%New()
set output=RPConverter.hl7toRp(MDMarchiv)
$$$LOGINFO("after transformation: "_output)
set RPStream = ##class(%FileCharacterStream).%New(output)     #dim finalResponse As %FileCharacterStream=##class(%FileCharacterStream).%New()
set sc = ..Transform(output, "xdata://" _ $classname() _ ":" _ "addSOAP", .finalResponse)
#dim RPArchiv As HS.Message.XMLMessage = ##class(HS.Message.XMLMessage).%New()
    set RPArchiv.ContentStream=RPStream
    set sc=..SendRequestAsync("lombardia.bus.DCEProcess",RPArchiv)
    if $$$ISERR(sc) {quit sc}
    quit $$$OK
}

Basically, I want want to translate an HL7 message into an XML message through the java class called by the JavaGateway in this way: 

Parameter JAVAGATEWAYPORT = 55555; Method hl7toRp(hl7 As %String) As %String
{
#dim jgw As %Net.Remote.Gateway = "" //#dim ret As %String="" try
{
$$$LOGINFO("START: JAVAGTW "_..#JAVAGATEWAYPORT)
//w "START: JAVAGTW"_..#JAVAGATEWAYPORT_"\n"
set jgw = ##class(%Net.Remote.Java.JavaGateway).%New() set sc = jgw.%Connect("localhost", ..#JAVAGATEWAYPORT)
$$$LOGINFO("Status after connect: "_sc)
if $$$ISERR(sc) quit w "HL7 "_ hl7,!
$$$TRACE(hl7)
#dim ret As %String = ##class(com.santer.siss.mapping.v25.fse.tester.HL7toXML).hl7ToRP(.jgw, .hl7)
$$$LOGINFO($$$CLASSNAME(ret))
if $isObject(jgw) try { do jgw.%Disconnect() } catch ignore { $$$LOGSTATUS(ignore.AsStatus()) }  
}
catch ex
{
w "Exception"_ex ,!
set sc = $get(%objlasterror)
if (sc = "") set sc = ex.AsStatus()
set ret = sc }
w ret,! return ret
}

Everithing seems to work fine, indeed, when I log the output with the $$$LOGINFO i get the xml message that I was expecting. The quite strange thing is that when I try to log the class type I have obtained as output of the java class, I didn't get %String or some other ObjectScript class but, instead, I get the xml message itself. It seem to be that the result don't have a proper class type. 

The final issue arise when I try to put the result into a stream; the xml message results empty and, moreover, If I try to send just the RPStream, I get this error: OID is null. 

How can I cast the output as a string or better as a stream in order to deal with it normally?

 

Thanks in advance for your collaboration. 

Answers

The quite strange thing is that when I try to log the class type I have obtained as output of the java class, I didn't get %String or some other
ObjectScript class but, instead, I get the xml message itself. It seem to be that the result don't have a proper class type.

That is correct, the ret variable seems to be a string, so it's not a class, therefore it cannot have a class name.

In Object Script there are objects and primitives (strings). Only objects have classes.

 

The final issue arise when I try to put the result into a stream; the xml message results empty and, moreover, If I try to send just the RPStream, I get this error: OID is null. 

How are you doing it?

Ok this make sense, thank you. This if what I get from the $CLASSNAME log: 

this: <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<rootNode>
<nodeOne>
<NodeTwo>
<auxNode>20180920</auxNode>
<helpNode>E</helpNode>
</NodeTwo>
</nodeOne>
</rootNode>

This, instead, is the java class: 

Class com.santer.siss.mapping.v25.fse.tester.HL7toXML Extends java.lang.Object [ ProcedureBlock ]
{ 
Parameter IMPORTTIMESTAMP As STRING = "2019-10-17 10:06:14.0";
Method %OnNew(ByRef p0 As %ObjectHandle) As %Status
{
Quit:'$D(p0) $$$OK
Quit ..%Constructor(p0,"com.santer.siss.mapping.v25.fse.tester.HL7toXML",0)
} 
ClassMethod hl7ToRP(ByRef p0 As %ObjectHandle, ByRef p1 As %ObjectHandle) As %ObjectHandle
{
Quit ..%SR(p0,"hl7ToRP","com.santer.siss.mapping.v25.fse.tester.HL7toXML",.p1)
} }

I have tried to put it into a stream in two ways: 

1. set RPStream = ##class(%FileCharacterStream).%New(output)

2. With an XSLT in order to add the SOAP envelope: #dim finalResponse As %FileCharacterStream=##class(%FileCharacterStream).%New()
set sc = ..Transform(output, "xdata://" _ $classname() _ ":" _ "addSOAP", .finalResponse)

Thanks to trace operation, I was seeing the the tranform was working but I was getting an error before the asysnc request. I'm posing everithig below:

Transform

XData addSOAP
{
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv='http://www.w3.org/2003/05/soap-envelope' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema' xmlns:wsa='http://www.w3.org/2005/08/addressing'>
            <soapenv:Header/>
            <soapenv:Body> 
              <xsl:copy-of select="*"/>
            </soapenv:Body>
           </soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
}

Trasform Output: 

<?xml version="1.0" ?>

<!-- type: HS.Util.Trace.Request id: 149506 -->

<Request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.w3.org/2001/XMLSchema"><HSCoreVersion>

16

</HSCoreVersion><CurrentClass>

lombardia.bus.HL7DCEPreProcess

</CurrentClass><CurrentMethod>

Transform

</CurrentMethod><Comment>

After Transform xdata://lombardia.bus.HL7DCEPreProcess:addSOAP

</Comment><Items><Item><ItemName>

tSC

</ItemName><ItemValue>

1

</ItemValue></Item><Item><ItemName>

pOutput

</ItemName><ItemValue>

<![CDATA[<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header/>
<soapenv:Body>
<rootNode>
<nodeOne>
<NodeTwo>
<auxNode>20180920</auxNode>
<helpNode>E</helpNode>
</NodeTwo>
</nodeOne>
</rootNode>
</soapenv:Body></soapenv:Envelope>]]>
</ItemValue></Item></Items>
</Request>

In this case I get this Error: 

ERRORE #5002: Errore di Caché: <SUBSCRIPT>%SaveData+29^Ens.MessageHeader.1 ^Ens.MessageHeaderI("MessageBodyId","<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap

but it seems to be truncated. 

Thanks a lot for your answer and collaboration

Streams work like this:

set stream = ##class(<stream class>).%New()
do stream.Write(string)
set sc = stream.Save()

In your case I'd recommend using %Stream.GlobalCharacter as stream class. FileStream also works better if you supply a filename. Check this doc.

add SOAP envelope

Not sure what are you trying to do. SOAP Operation should add all relevant headers and additional ones can be passed as objects. Docs.

UPD.

  • I meant java code for com.santer.siss.mapping.v25.fse.tester.HL7toXML:hl7ToRP method.
  • For $$$CLASSNAME you can click RMB on it and then LMB on "Go To $$$CLASSNAME", in there you can see a macro definition(#define CLASSNAME <definition>). Please post it.  

Comments

Please consider posting com.santer.siss.mapping.v25.fse.tester.HL7toXML:hl7ToRP method.

And also $$$CLASSNAME definition.