2012-02-24 29 views
5

También hice esta pregunta en el Mirth forum.JAX-WS cliente de Java, interoperabilidad del servicio WCF: "400: Solicitud incorrecta"

Actualmente estamos tratando de conectarnos a un servicio WCF utilizando el motor de integración de atención médica de código abierto Mirth. Mirth está basado en Java, usa Mule internamente que usa JAX-WS. El servidor WCF está devolviendo el código de estado HTTP "400: Solicitud incorrecta". No tenemos fácil acceso al servidor WCF.

La comunicación con el cliente funciona bien en C#. En Visual Studio, agregue Servicio de Referencia, y luego en 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); 

El cliente autogenerado WCF (desde el WSDL) tiene un app.config con un punto final, y esta unión:

<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> 

Lo único que se hace de manera diferente en la solución WCF es extender el maxNameTableCharCount y maxArrayLength en la etiqueta readerQuotas para el enlace en cuestión, el resto queda con los valores predeterminados. Sin embargo, no he encontrado una manera de establecer estos en Mirth, si este es el motivo del error.

Estamos ejecutando Mirth v 2.2.1 (último pago), y Mirth Channel está configurado para leer y enviar un documento HL7v3. El problema surge solo cuando se trata de comunicarse con el servicio WCF. El destino es un remitente del servicio web, con servicio y lectura de puerto del WSDL. No hay autentificación, y el sobre se genera a partir de la única operación disponible. No estamos usando MTOM.

Estamos bastante seguros de que esto está relacionado con la interoperabilidad JAX-WS y WCF. ¿Algún consejo general?

Hemos intentado configurar propiedades en la conexión JAX-WS. En lo profundo de las entrañas de la alegría, hemos tratado de establecer el tamaño http trozo:. dispatch.getRequestContext() poner (JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192) (línea WebServiceMessageDispatcher.Java 140)

El seguimiento de pila es el siguiente:

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) 
+0

¿No hay manera que usted puede obtener una copia de la configuración del servicio? –

+0

Otra idea es deshacerse de todos los bits de configuración innecesarios y simplemente configurar las cosas que SABE que necesita. Los archivos de configuración generados automáticamente son innecesariamente detallados. Probablemente no resuelva el problema, pero puede ayudar de todos modos. –

Respuesta

3

Hemos encontrado una solución. Descripción larga de la solución en the Mirth forum.

El problema fue que los servicios web nos dieron una "400: mala solicitud" cuando intentamos enviar una solicitud que pensamos que era significativa. "400 mala solicitud" es un error muy genérico y no tan informativo.

Una solución para las pruebas

Esta solución crea una basada en archivos arnés prueba depurable que se puede utilizar para entender lo que hace la alegría. No es una solución de calidad de producción. YMMV.

  • Instalar la alegría
  • descargar los archivos WSDL del servicio web (por ejemplo EncounterManager) y ponerlos bajo la alegría Server \ public_html \ EncounterManager modo que la alegría puede alojarlas.
  • En el archivo WSDL encima del local, modificarlo y asegurarse de que la acción de SOAP en los puntos finales para el servicio web real:

jabón: la dirección de ubicación = "http: // su -server/HL7Connector/GetDemographicsService30/"/

  • Reiniciar la alegría si ya se ha iniciado.
  • En la alegría Connect, crear un nuevo canal, por ejemplo remitente
  • sólo para las pruebas, hacen que el Fuente de este canal un lector de archivos que lee algo en (por ejemplo, un identificador del paciente desde un archivo de texto ) Por ejemplo, hazlo C: \ MirthTesting \ unread. Indique a Mirth para mover el archivo después de que haya terminado en C: \ MirthTesting \ read
  • En la página de resumen del nuevo transformador, haga clic en "Establecer tipos de datos".
  • tipos de datos Conjunto de conector Fuente de entrada = de texto delimitado, conector de salida Fuente = HL7, Destino de salida = 1 de texto delimitado. Esto es solo para probar, puedes hacer cosas sofisticadas HL7 más tarde. En el origen, haga clic en Editar transformador.
  • Haga clic en "Agregar nuevo paso", ingrese el nuevo nombre de variable "patientIdWanted" e ingrese para la asignación, "messageObject.getRawData()". Esto hace que Mirth lea el contenido de cualquier archivo de texto que ponga en el directorio "No leído" y lo coloque en una variable que puede usar más adelante (en el mapa del canal)
  • Haga Destino de su nuevo canal en un Web service sender. Ingrese la URL del WSDL local (por ejemplo, http: // localhost: 8080/EncounterManager/EncounterManagerQueryFulfiller.wsdl)
  • Haga clic en Obtener operaciones, luego Generar envolvente.
  • El sobre SOAP es muy grande y está lleno de HL7 sin sentido (para mí). Reemplácelo con un ejemplo simple que funcione, y elimine todo el HL7 innecesario. Su proveedor debe darle un ejemplo de trabajo.
  • Ahora debe colocar las variables que lee desde el paso del lector de archivos en el sobre SOAP. Su sobre de SOAP debe contener una "carga útil", p. el identificador del paciente en alguna parte Para la consulta GetDemographics, se veía así (parte de ella). Tenga en cuenta que el $ {patientIdWanted} es donde Mirth reemplaza el valor en la plantilla, de lo que ponemos en el mapa del canal del archivo de texto anterior.
  • Ahora guarde este canal.
  • Crea un nuevo canal para recibir lo que el servicio web en el paso anterior te envió. Llámelo Receptor
  • En el nuevo canal, configure los tipos de datos como "Texto delimitado". De nuevo, solo para probar.
  • Establecer la fuente del canal "receptor" a "lector de canales"
  • Establecer el destino del nuevo canal al escritor archivo. Ingrese un directorio y un nombre de archivo, p. C: \ MirthTesting \ read \ webservice-response.txt. En la plantilla, ingrese $ {message.rawData} para ver todo lo que tiene Mirth.
  • Volver al Remitente canal, seleccione el destino, ingrese el Receptor canal como el destino de la respuesta.
  • Guarde los cambios, valide el conector, vuelva a desplegar todos los canales.
  • Ahora cree un archivo de texto con un identificador del paciente en él, y lo puso en C: \ MirthTesting \ sin leer
  • la alegría leerá este archivo (a continuación, pasar al directorio de "leer"). Su primer canal recibirá el archivo de texto, mueva el contenido al mapa del canal $ {patientIdWanted}. Su servicio web recibirá el sobre SOAP con este identificador de paciente. La respuesta se enviará al canal Receptor , y se descargará como texto sin formato.

cosas que era útil

  • darse cuenta de que la alegría es un submarino nuclear: potente y misteriosa. ¡Sin manual!
  • Siendo un poco competentes en C# y Java
  • Tener ejemplos de mensajes HL7 que tengan sentido
  • mediante Visual Studio para generar un cliente C# puro para verificar que se podía leer desde el servicio web con sencillo en C#. (Usamos Mirth para alojar los archivos WSDL, pero usted podría usar IIS)
  • Usando Eclipse para generar un cliente Java para verificar que podemos leer desde el servicio web con Java. Usamos el SOAPUI (el mismo que utiliza Mirth) con Eclipse Indigo EE edition (desde la línea de comandos usando wsimport.bat)
  • Descargando Mirth del código fuente y ejecutándolo desde Eclipse.
  • Activación de descarga de HTTP (en Eclipse). Ingrese debajo de "Ejecutar configuración", argumentos de VM. Esto le permite ver exactamente lo que la alegría (o su cliente Java) envía al servicio web: -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true

  • Añadir un pre -Procesamiento script a su canal emisor para ver lo que realmente hace la alegría:

    FileUtil.write('C:/MirthTesting/read/sender_preprocessmessage_in.txt', false, message);return message; 
    
  • Agregar un script de post-procese a su canal emisor para ver lo que hace la alegría:

    FileUtil.write('C:/MirthTesting/read/dipssender_postprocessmessage.txt', false, message); 
    return; 
    

Un cambio de código

Para hacer esto realmente, tuvimos que hacer un cambio en el código fuente de Mirth. Con JDK1.7 que utilizamos, Mirth en realidad no envió la acción SOAP. En Servidor /.../ WebServiceMessageDispatcher.java línea 137, que había que añadir:

dispatch.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true); 

(tomado de this blog post)

Cuestiones relacionadas