XDSb Provide and Register passthrough payload has no data when forwarding

162 views
Skip to first unread message

Miguel Curi

unread,
Sep 1, 2015, 12:05:56 PM9/1/15
to ipf-user
Hello, I am working on a passthrough route that captures some data from a provide and register transaction and forwards the message as is to an external XDSb Repository.
I can see the XML document in the payload as it goes through the route but it looks like the document has no data when it is recived by the repository.
This is what I have:

Groovy route:

class Iti4142RouteBuilder extends SpringRouteBuilder {
void configure() {
errorHandler(noErrorHandler())
from('xds-iti41:xds-iti41')           
                   .to('iti41Processor')            
   .transform { new Response(Status.SUCCESS) }
}
}


Custom java camel processor 'iti41Processor':

public class CustomProcessorIti41 implements Processor{
    
    ProducerTemplate producer;
    
    public void setProducer(ProducerTemplate producer) {
      this.producer = producer;
    }

    private Map<String, String> endpoints;

    public Map<String, String> getEndpoints(){ return endpoints; }

    public void setEndpoints() Map<String, String> endpoints){ this.endpoints = endpoints; }

    @Override
    public void process(Exchange exchange) throws Exception {

        String docSourceId = documentSourceId(exchange);

        String targetEndpoint = endpoints.get(docSourceOid);

        producer.send(targetEndpoint, exchange);
    }

    private String documentSourceId(Exchange exchange) {
        ProvideAndRegisterDocumentSet pnr = exchange.getIn().getBody(ProvideAndRegisterDocumentSet.class);
        return pnr.getSubmissionSet().getSourceId();
    }

}

I have not tracked the http request responses to the target system but in the target system logs there is a message saying that the document is empty.


2015-08-27 15:18:33,687 ERROR [ajp-bio-8009-exec-6] com.icw.ehf.commons.errorhandling.handler.LogExceptionHandler#error(146) - Ticket: 'ca59ef8c-4cf8-11e5-bdc7-2a6020524153'; Message 'Constraint violation: 
1.2.840.113619.20.2.7:MissingDocument-0002 : 'Computed Size is 0 for Document[Document01]' : Document01 '.
com.icw.ehf.commons.exception.validation.ValidationException: Constraint violation: 
1.2.840.113619.20.2.7:MissingDocument-0002 : 'Computed Size is 0 for Document[Document01]' : Document01 
 at com.gehcit.ehealth.cnf.drr.ipf.xdsbrepository.processor.ProvideRequestProcessor.throwValidationException(ProvideRequestProcessor.java:180)

Any ideas why the document may be getting stripped off when doing producer.send()?

Thanks.

Miguel.


Dmytro Rud

unread,
Sep 1, 2015, 5:52:49 PM9/1/15
to ipf-...@googlegroups.com
Hello Miguel,

I could not reproduce your issue on IPF 3.1 -- the fork endpoint receives the attachment as expected (I can see this in a sniffer tool) and successfully validates the message.

But: please make sure that your "custom processor" is really the one which is called from the route.  The code you sent contains some syntactic errors (a redundant parenthesis in the declaration of detEndpoints; docSourceOid instead of docSourceId), so it could not be actually executed.  The route per se does also not look perfect -- the processor endpoint URI should be prefixed with "bean:".

If the problem remains -- please provide a minimal unit test (Maven project) which reproduces it locally (obviously I have no access to the server you are testing against).

Best regards
Dmytro
--
You received this message because you are subscribed to the Google Groups "ipf-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ipf-user+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Miguel Curi

unread,
Sep 2, 2015, 9:45:50 AM9/2/15
to ipf-user
Thanks Dmytro. I modified the code before posting a little to make it cleaner as some of this code is actually on a base class so I had to change things around just a bit to not have to post all the classes but messed up when typing. The end result should be the same, it just calls the service defined in a database table instead of a HashMap. 

I can see in the logs that the 'iti41Processor' is called and I can see the logs in the target system so I know it is actually going through it. I also have an EventNotifier listener that logs the messages in a database as they go through the camel endpoints and I can see the messages received from the iti41Processor and the message being sent to the target system. When I compare these two I notice that the contents of the <Document> tag in the ProvideAndRegisterDocumentSet are gone by the time it reaches the MessageSentEvent to the target system. I am not manipulating the ProvideAndRegisterDocumentSet object so I don't know why the contents are removed or at which point they get removed, perhaps when calling the xds-iti41 camel endpoint it is stripping the document contents to place them into an mtom attachment but fails to add the attachment? 

Miguel.

Dmytro Rud

unread,
Sep 2, 2015, 10:06:37 AM9/2/15
to ipf-...@googlegroups.com
Can you see (and show us) the HTTP message received by the target system (including all HTTP and SOAP headers)?

Best regards
Dmytro

Dmytro Rud

unread,
Sep 2, 2015, 10:34:29 AM9/2/15
to ipf-...@googlegroups.com
BTW, when you write that you do are not manipulating the request object -- what exactly do you mean?  Can it be that you read in the attachment stream e.g. for logging purposes?

Miguel Curi

unread,
Sep 2, 2015, 4:16:25 PM9/2/15
to ipf-user
I am logging messages using an implementation of org.apache.camel.support.EventNotifierSupport. 
This code logs the IN and OUT messages on the Exchange objects to a database table. I serialize the messages using JAXB into a String before I place them in the database. The actual result is the ProvideAndRegisterDocumentSet xml gets logged to the database and I can see the inline contents of the base64 encoded CCD document in the <Document> tag as it is received by the 'iti41Processor' endpoint. So up to the point at which the MessageSentEvent is triggered, the ProvideAndRegisterDocumentSet object contains the payload of the document. 
I don't have any code that does anything to the object so I can't tell where the content of the document gets cleared but by the time the MessageSentEvent gets triggered for the call to the external endpoint (""xds-iti41://[url]/[webapp]/webservices/rev6/xdsb-provideandregister?secure=true"") the record in the database of this exchange shows no content in the <Document> tag of the PnR.
I am not sure if this is clear, I am trying to explain as much as possible so I may be giving too much detail.

Miguel.

Dmytro Rud

unread,
Sep 2, 2015, 5:13:17 PM9/2/15
to ipf-...@googlegroups.com
This is exactly what I meant.  You use JAXB for rendering XDS requests, and JAXB renders the attachments as well -- in that way, JAXB consumes the attachments' data streams, and there remains no data for further marshallings (e.g. before sending the message out).

Please take a look at the JAXB marshaller configuration in org.openehealth.ipf.platform.camel.ihe.xds.core.converters.XdsRenderingUtils#renderEbxml.

Best regerda
Dmytro

--

Miguel Curi

unread,
Sep 3, 2015, 10:15:55 AM9/3/15
to ipf-user
Excellent!!!! Thanks a lot Dmytro, I really appreciate your help! :)
Problem solved.

Miguel.

Miguel Curi

unread,
Sep 4, 2015, 10:16:27 AM9/4/15
to ipf-user
One more question, if I were to read a PnR message that's in the file system from a camel route using the "file:" endpoint, how would I unmarshall the file into a PnR object? I have this route that should pick up a iti41 message from the file system.

<camel:route id="iti41FileReader">
    <camel:from uri="file:/home/drop/?moveFailed=/home/drop/.error"/>
    <camel:unmarshall>???????</camel:unmarshall>

    <camel:to ref="iti41Processor"/>

</camel:route>

I could use the JaxbDataFormat implementation of camel DataFormat, but wondering if there is a better unmarshaller already available.
Thanks.

Miguel.

Dmytro Rud

unread,
Sep 4, 2015, 10:49:15 AM9/4/15
to ipf-...@googlegroups.com
Hello Miguel,

ebXML documents are in no way special, therefore the standard unmarshaller will be fine.

Best regards
Dmytro

--

Miguel Curi

unread,
Sep 4, 2015, 2:12:18 PM9/4/15
to ipf-user
Great Thanks!!

Miguel.

Miguel Curi

unread,
Sep 8, 2015, 3:15:53 PM9/8/15
to ipf-user
I am doing this:

 

    <camel:camelContext id="camelContext">
       
<camel:dataFormats>
           
<camel:jaxb id="ebxmlJaxb" contextPath="org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30"/>
       
</camel:dataFormats>
   
</camel:camelContext>
   
<routeContext id="myRoutes" xmlns="http://camel.apache.org/schema/spring">
       
<camel:route id="fileConsumerIti41">
         
<camel:from uri="file:/usr/local/drop/?moveFailed=/usr/local/drop/.error"/>
         
<marshal ref="ebxmlJaxb"/>
         
<camel:process ref="iti41Processor"/>
       
</camel:route>
   
</camel:routeContext>



and I am getting this error:

13:59:57.615 [Camel (camelContext) thread #0 - file:///usr/local/drop/] WARN  n.s.i.i.a.InteropAuditingEventNotifier - The exchange contained a failure notification: org.apache.camel.TypeConversionException: Error during type conversion from type: byte[] to the required type: org.openehealth.ipf.commons.ihe.xds.core.requests.ProvideAndRegisterDocumentSet with value [B@272977e8 due null


Caused by: com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 1; unexpected element (uri:"urn:ihe:iti:xds-b:2007", local:"ProvideAndRegisterDocumentSetRequest"). Expected elements are <{http://www.openehealth.org/ipf/xds}association>,<{http://www.openehealth.org/ipf/xds}document>,<{http://www.openehealth.org/ipf/xds}documentEntry>,<{http://www.openehealth.org/ipf/xds}folder>,<{http://www.openehealth.org/ipf/xds}provideAndRegisterDocumentSet>,<{http://www.openehealth.org/ipf/xds}submissionSet>

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:740).........


Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"urn:ihe:iti:xds-b:2007", local:"ProvideAndRegisterDocumentSetRequest"). Expected elements are <{http://www.openehealth.org/ipf/xds}association>,<{http://www.openehealth.org/ipf/xds}document>,<{http://www.openehealth.org/ipf/xds}documentEntry>,<{http://www.openehealth.org/ipf/xds}folder>,<{http://www.openehealth.org/ipf/xds}provideAndRegisterDocumentSet>,<{http://www.openehealth.org/ipf/xds}submissionSet>


What am I doing wrong?


Thanks.


Miguel.

Dmytro Rud

unread,
Sep 8, 2015, 3:54:29 PM9/8/15
to ipf-...@googlegroups.com
Hello Miguel,

Try to specify the full path, i.e.

            <camel:jaxb id="ebxmlJaxb" contextPath="org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.ProvideAndRegisterDocumentSetRequestType.class"/>

(or, maybe, without ".class" at the end)

Best regards
Dmytro


--

Miguel Curi

unread,
Sep 9, 2015, 9:49:50 AM9/9/15
to ipf-user
I have tried both with and without the .class at the end and I get the following in both cases:


test.InteropIntegrationTest: org.apache.camel.RuntimeCamelException: javax.xml.bind.JAXBException: Provider com.sun.xml.bind.v2.ContextFactory could not be instantiated: javax.xml.bind.JAXBException: "org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.ProvideAndRegisterDocumentSetRequestType.class" doesnt contain ObjectFactory.class or jaxb.index

 - with linked exception:

[javax.xml.bind.JAXBException: "org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.ProvideAndRegisterDocumentSetRequestType.class" doesnt contain ObjectFactory.class or jaxb.index]


It is weird because in code I use : 


            JAXBContext contextPnR = JAXBContext.newInstance(org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.ProvideAndRegisterDocumentSetRequestType.class);

            Unmarshaller unmarshallerPnR = contextPnR.createUnmarshaller();

           Object  unmarshalledPnR = unmarshallerPnR.unmarshal(inputPnR.getInputStream());


And that works fine.


Any other ideas? 

Dmytro Rud

unread,
Sep 9, 2015, 10:02:32 AM9/9/15
to ipf-...@googlegroups.com
Use a custom processor with the code that works fine instead of the Camel marshaller.  
Or fix the Camel marshaller and commit your solution to the Camel project.
Of simply send a problem report to Camel and wait till somebody takes a look.

BTW, in the route you call a marshaller, and in the code -- an unmarshaller.
This may also make a difference.

Best regards
Dmytro

Miguel Curi

unread,
Sep 9, 2015, 3:37:12 PM9/9/15
to ipf-user
Great catch!! Changed the route to call unmarshall instead of marshal and it worked :).

   <camel:camelContext id="camelContext">
       
<camel:dataFormats>
           
<camel:jaxb id="ebxmlJaxb" contextPath="org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30"/>
       
</camel:dataFormats>
   
</camel:camelContext>
   
<routeContext id="myRoutes" xmlns="http://camel.apache.org/schema/spring">
       
<camel:route id="fileConsumerIti41">
         
<camel:from uri="file:/usr/local/drop/?moveFailed=/usr/local/drop/.error"/>

         
<unmarshal ref="ebxmlJaxb"/>
         
<camel:process ref="iti41Processor"/>
       
</camel:route>
   
</camel:routeContext>


Thanks!!

Miguel.

Miguel Curi

unread,
Nov 13, 2015, 1:15:40 PM11/13/15
to ipf-user
Hi Dmytro, I have to reopen this question. I am in the need of capturing the actual payload(s) inside a provide and register and a retrieve document set.
Is there a way to serialize the PnR and Retrieve document response including the base64 encoded payload without removing the streams out of the messages?
Thanks in advance.

Miguel.

Dmytro Rud

unread,
Nov 13, 2015, 1:24:29 PM11/13/15
to ipf-...@googlegroups.com
Hi Miguel,

Alternative 2: JAXB with manual re-creation of streams.

Best regards
Dmytro

Miguel Curi

unread,
Nov 13, 2015, 1:42:59 PM11/13/15
to ipf-user
Thanks, I am logging these in the database as xml so option 2 would be prefererred, can you elaborate on manually recreating the streams? Do you mean resetting the provide and register document variable value? Or during marshalling in the AttachmentMarshaller?
Has this been done before?

thanks.
Miguel.

Dmytro Rud

unread,
Nov 13, 2015, 3:34:01 PM11/13/15
to ipf-...@googlegroups.com
I suppose it will be enough to reset the value of
ProvideAndRegisterDocumentSetRequestType.document[i].value.dataSource.inputStream (for ITI-41) or
RetrieveDocumentSetResponseType.documentResponse[i]. document.dataSource.inputStream (for ITI-43).

Best regards
Dmytro
Reply all
Reply to author
Forward
0 new messages