Reputation: 51
I have also asked this question on the Mirth forum.
We are currently trying to connect to a WCF service using the open source health care integration engine Mirth . Mirth is Java-based, uses Mule internally which uses JAX-WS. The WCF server is returning HTTP status code "400: Bad Request". We don’t have easy access to the WCF server.
Communication with the client works well in C#. In Visual Studio, add Service Reference, and then in main():
PatientRegistryQueryFulfiller.GetDemographicsClient svc = new PatientRegistryQueryFulfiller.GetDemographicsClient();
doc.Load(@"C:\MirthTesting\PRPA_EX201307NO_10_PatientReg_GetDemographics.xml");
PatientRegistryQueryFulfiller.PRPA_IN201307NO patientRegistryRequest = (PatientRegistryQueryFulfiller.PRPA_IN201307NO)ObjectSerializer.DeserializeObject(doc, typeof(PatientRegistryQueryFulfiller.PRPA_IN201307NO));
PatientRegistryQueryFulfiller.PRPA_IN201307NOResponse patientRegistryResponse = svc.GetDemographics(patientRegistryRequest);
doc = ObjectSerializer.SerializeObject(patientRegistryResponse.Item);
The autogenerated WCF client (from the WSDL) has an app.config with an endpoint, and this binding:
<bindings>
<basicHttpBinding>
<binding name="PatientRegistryQueryFulfiller_Binding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="655360"
maxBytesPerRead="4096" maxNameTableCharCount="655360" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
The only thing done differently in the WCF-solution is extending the maxNameTableCharCount and maxArrayLength in the readerQuotas tag for the binding in question, the rest is left with default values. However, I have not found a way to set these in Mirth, should this indeed be the reason for the error.
We’re running Mirth v 2.2.1 (most recent checkout), and the Mirth Channel is set to both read and send a HL7v3 document. The problem arises only when trying to communicate with the WCF-service. The destination is a Web Service Sender, with both service and port read from the WSDL. There is no authenthication, and the envelope is generated from the only available operation. We’re not using MTOM.
We’re fairly certain that this is related to JAX-WS and WCF interoperability. Any general hints?
We’ve tried setting properties on JAX-WS connection. Deep in the bowels of mirth, we’ve tried setting the http chunk size: dispatch.getRequestContext().put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192) (WebServiceMessageDispatcher.Java line 140)
The stack trace is as follows:
ERROR-410: Web Service Connector error
ERROR MESSAGE: Error connecting to web service.
com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 400: Bad Request
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.checkStatusCode(Unknown Source)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(Unknown Source)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(Unknown Source)
at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source)
at com.sun.xml.internal.ws.client.Stub.process(Unknown Source)
at com.sun.xml.internal.ws.client.dispatch.DispatchImpl.doInvoke(Unknown Source)
at com.sun.xml.internal.ws.client.dispatch.DispatchImpl.invoke(Unknown Source)
at com.mirth.connect.connectors.ws.WebServiceMessageDispatcher.processMessage(WebServiceMessageDispatcher.java:176)
at com.mirth.connect.connectors.ws.WebServiceMessageDispatcher.doDispatch(WebServiceMessageDispatcher.java:106)
at com.mirth.connect.connectors.ws.WebServiceMessageDispatcher.doSend(WebServiceMessageDispatcher.java:204)
at org.mule.providers.AbstractMessageDispatcher.send(AbstractMessageDispatcher.java:164)
at org.mule.impl.MuleSession.sendEvent(MuleSession.java:191)
at org.mule.impl.MuleSession.sendEvent(MuleSession.java:130)
at org.mule.routing.outbound.AbstractOutboundRouter.send(AbstractOutboundRouter.java:85)
at org.mule.routing.outbound.FilteringMulticastingRouter.route(FilteringMulticastingRouter.java:54)
at org.mule.routing.outbound.OutboundMessageRouter$1.doInTransaction(OutboundMessageRouter.java:78)
at org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:48)
at org.mule.routing.outbound.OutboundMessageRouter.route(OutboundMessageRouter.java:82)
at org.mule.impl.model.DefaultMuleProxy.onCall(DefaultMuleProxy.java:247)
at org.mule.impl.model.seda.SedaComponent.doSend(SedaComponent.java:209)
at org.mule.impl.model.AbstractComponent.sendEvent(AbstractComponent.java:277)
at org.mule.impl.MuleSession.sendEvent(MuleSession.java:201)
at org.mule.routing.inbound.InboundMessageRouter.send(InboundMessageRouter.java:176)
at org.mule.routing.inbound.InboundMessageRouter.route(InboundMessageRouter.java:143)
at org.mule.providers.AbstractMessageReceiver$DefaultInternalMessageListener.onMessage(AbstractMessageReceiver.java:487)
at org.mule.providers.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:266)
at org.mule.providers.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:225)
at com.mirth.connect.connectors.vm.VMMessageReceiver.getMessages(VMMessageReceiver.java:223)
at org.mule.providers.TransactedPollingMessageReceiver.poll(TransactedPollingMessageReceiver.java:108)
at org.mule.providers.PollingMessageReceiver.run(PollingMessageReceiver.java:97)
at org.mule.impl.work.WorkerContext.run(WorkerContext.java:290)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Unknown Source)
Upvotes: 5
Views: 7792
Reputation: 31
We found a solution. Long description of the solution on the Mirth forum.
The problem was that the web services gave us a "400: bad request" when we tried to send it a request that we thought was meaningful. "400 bad request" is a very generic and not so informative error.
This solution creates a debuggable file-based testing harness that you can use to understand what Mirth does. It is not a production-quality solution. YMMV.
soap:address location="http://your-server/HL7Connector/GetDemographicsService30/"/
Turning on HTTP dumping (in Eclipse). Enter under "Run config", VM arguments. This lets you see exactly what Mirth (or your Java client) sends to the web service: -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true
Add a pre-processing script to your sender channel to see what Mirth actually does:
FileUtil.write('C:/MirthTesting/read/sender_preprocessmessage_in.txt', false, message);return message;
Add a post-procesing script to your sender channel to see what Mirth does:
FileUtil.write('C:/MirthTesting/read/dipssender_postprocessmessage.txt', false, message);
return;
To actually make this work, we had to make one change to the Mirth source code. With JDK1.7 that we used, Mirth didn't actually send the SOAP action. In Server/.../WebServiceMessageDispatcher.Java line 137, we had to add:
dispatch.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
(taken from this blog post)
Upvotes: 3