La versatilidad y flexibilidad de Mirth Connect como herramienta motor de integración no tiene límites si nos planteamos en alguna ocasión descargar el código fuente. Al ser código abierto, está disponible en el repositorio, tanto para hacer contribuciones como para una adaptación concreta que no esté contemplada. Puede parecer que, para crear un Custom Web Service en Mirth Connect puede ser necesario recurrir al código, pero no es así.
Si tenemos que cambiar el interfaz del contrato de integración, Mirth Connect tiene prevista la posibilidad de importar clases externas para adaptarlo.
Caso Práctico: Migración de un WebService ya existente en BizTalk a Mirth manteniendo el wsdl
En el Hospital X tienen una plataforma de integración de procesos de negocio en Microsoft BizTalk, con una serie de WebServices funcionando con proveedores.
Esta plataforma está obsoleta y están migrando todos las integraciones a una mas moderna y eficiente, como Mirth Connect.
En la mayoría de los casos se trata de desarrollar nuevos canales que implementen la lógica de negocio que ya estaba diseñada en BizTalk. Sin embargo, nos encontramos con un caso en que, el proveedor que consume un WebService expuesto por la plataforma, tiene compilada su integración contra el wsdl con un precompilador de modelo. Por tanto, cualquier variación en el contrato, el wsdl, hará que deje de funcionar.
El proveedor ya no existe, discontinuó su producto, y solo ofrece mantenimiento pero no va a cambiar su desarrollo. Esto significa que tendremos que adaptar el contrato wsdl al que exponía el servicio de BizTalk, idéntico.
En concreto, el contrato del antiguo servicio web expone un método Operacion_QueryPacientes, que recibe un parámetro denominadopart de tipo String. En el parámetro se envía un mensaje HL7 v2 tipo QRY en xml, encapsulado con la directiva CDATA.
Una descarga del wsdl del servicio actual es como sigue:
<definitions targetNamespace="http://tempuri.org/" name="Operacion_QueryPacientesService" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <xsd:schema> <xsd:import namespace="http://tempuri.org/" schemaLocation="http://localhost:8082/services/QueryPacientes?xsd=1"/> </xsd:schema> </types> <message name="Operacion_QueryPacientes"> <part name="parameters" element="tns:Operacion_QueryPacientes"/> </message> <message name="Operacion_QueryPacientesResponse"> <part name="parameters" element="tns:Operacion_QueryPacientesResponse"/> </message> <portType name="ConsultaPacientesSoap"> <operation name="Operacion_QueryPacientes"> <input wsam:Action="Operacion_QueryPacientes" message="tns:Operacion_QueryPacientes"/> <output wsam:Action="http://tempuri.org/ConsultaPacientesSoap/Operacion_QueryPacientesResponse" message="tns:Operacion_QueryPacientesResponse"/> </operation> </portType> <binding name="ConsultaPacientesSoapPortBinding" type="tns:ConsultaPacientesSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="Operacion_QueryPacientes"> <soap:operation soapAction="Operacion_QueryPacientes"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="Operacion_QueryPacientesService"> <port name="ConsultaPacientesSoapPort" binding="tns:ConsultaPacientesSoapPortBinding"> <soap:address location="http://localhost:8082/services/QueryPacientes"/> </port> </service> </definitions>
Nota: Fijémonos en que el namespace es «http://tempuri.org/» para comparar luego con el esquema del Web Service de Mirth.
1. Problema: acceptMessage vs
Operacion_QueryPacientes
Mirth Connect expone por defecto un interfaz en el que tenemos un método acceptMessage que recibe un parámetro de tipo String llamado arg0.
La personalización de Mirth Connect en cuanto al interfaz del servicio web no ofrece demasiadas opciones. Lo tenemos todo en esta pantalla.

Básicamente podemos cambiar el nombre del servicio de «Mirth» a «QueryPacientes«, que será lo que indique en el path http://localhost:8081/services/QueryPacientes?wsdl.
En esta misma pantalla podemos observar que, al mantener la configuración Default service no permite especificar un clase del servicio. Además en el último campo, en Method, nos está exponiendo un solo método por defecto llamado acceptMessage con un parámetro message.
Veamos de donde viene esto.
AcceptMessage
Si nos descargamos el código fuente de Mirth Connect veremos que utiliza la clase AcceptMessage para los servicios web.
package com.mirth.connect.connectors.ws;
public abstract class AcceptMessage {
protected WebServiceReceiver webServiceReceiver;
public AcceptMessage(WebServiceReceiver webServiceReceiver) {
this.webServiceReceiver = webServiceReceiver;
}
}
Existe una clase por defecto que hereda de la misma AcceptMessage y que configura el interfaz por defecto de servicios web de tipo soap en Mirth. Esta clase es DefaultAcceptMessage. Si prestamos atención de nuevo a la pantalla de configuración del Web Service Mirth veremos que esta clase estaba por defecto con el selector Default Service:

Esto es lo que configura los servicios web en Mirth. Por lo tanto, cualquier cambio que queramos hacer deberemos crearnos una clase que haga lo mismo: heredar de Accept Message con los cambios que necesitemos.
Veamos ahora el interfaz que expone el Web Service por defecto de Mirth Connect:
<definitions targetNamespace="http://ws.connectors.connect.mirth.com/" name="DefaultAcceptMessageService" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.connectors.connect.mirth.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <xsd:schema> <xsd:import namespace="http://ws.connectors.connect.mirth.com/" schemaLocation="http://localhost:8081/services/QueryPacientes?xsd=1"/> </xsd:schema> </types> <message name="acceptMessage"> <part name="parameters" element="tns:acceptMessage"/> </message> <message name="acceptMessageResponse"> <part name="parameters" element="tns:acceptMessageResponse"/> </message> <portType name="DefaultAcceptMessage"> <operation name="acceptMessage"> <input wsam:Action="http://ws.connectors.connect.mirth.com/DefaultAcceptMessage/acceptMessageRequest" message="tns:acceptMessage"/> <output wsam:Action="http://ws.connectors.connect.mirth.com/DefaultAcceptMessage/acceptMessageResponse" message="tns:acceptMessageResponse"/> </operation> </portType> <binding name="DefaultAcceptMessagePortBinding" type="tns:DefaultAcceptMessage"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="acceptMessage"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="DefaultAcceptMessageService"> <port name="DefaultAcceptMessagePort" binding="tns:DefaultAcceptMessagePortBinding"> <soap:address location="http://localhost:8081/services/QueryPacientes"/> </port> </service> </definitions>
Como podemos ver, tendremos que hacer varias adaptaciones en el interfaz para que sean idénticos. El namespace, nombre del servicio, método, parámetros, etc.
Para ello deberemos crear un Custom Web Service en Mirth con un poco de desarrollo en Java.
2. Clases Java para adaptar nuestro interfaz
Para cambiar el interfaz tendremos que desarrollar nuestra clase
Operacion_QueryPacientes que herede de la clase Accept Message.
Tanto AcceptMessage como DefaultAcceptMessage se encuentran en el paquete com.mirth.connect.connectors.ws del jar ubicado en
/Mirth Connect/extensions/ws/ws-server.jar
En nuestro proyecto tendremos que incluir al menos las siguientes clases:
com.mirth.connect.connectors.ws.AcceptMessage.class
com.mirth.connect.connectors.ws.DefaultAcceptMessage.class
com.mirth.connect.connectors.ws.LoggingSOAPHandler.class
com.mirth.connect.connectors.ws.WebServiceConnectorService.class
com.mirth.connect.connectors.ws.WebServiceDispatcher.class
com.mirth.connect.connectors.ws.WebServiceReceiver.class
Y tendremos las siguientes dependencias, donde <ruta> será la ruta de instalación de nuestro Mirth Connect:
<classpathentry kind="lib" path="<ruta>/Mirth Connect/extensions/ws/ws-server.jar"/>
<classpathentry kind="lib" path="<ruta>/Mirth Connect/server-lib/donkey/donkey-model.jar"/>
<classpathentry kind="lib" path="<ruta>/Mirth Connect/server-lib/donkey/donkey-server.jar"/>
<classpathentry kind="lib" path="<ruta>/Mirth Connect/server-lib/donkey/slf4j-api-1.6.6.jar"/>
<classpathentry kind="lib" path="<ruta>/Mirth Connect/server-lib/log4j-1.2.16.jar"/>
Crearemos un package org.tempuri donde tendremos que incluir nuestra clase Operacion_QueryPacientes que heredará de AcceptMessage. En ella cambiaremos el cambio de namespace con:
@WebService(targetNamespace = "http://tempuri.org/", name = "ConsultaPacientesSoap")
Así como el nombre del método y parámetro de entrada:
public String Operacion_QueryPacientes(@WebParam(name = "part", targetNamespace = "http://tempuri.org/") String param) {
...
Operacion_QueryPacientes
package org.tempuri; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import com.mirth.connect.connectors.ws.AcceptMessage; import com.mirth.connect.connectors.ws.DefaultAcceptMessage; import com.mirth.connect.connectors.ws.LoggingSOAPHandler; import com.mirth.connect.connectors.ws.WebServiceDispatcher; import com.mirth.connect.connectors.ws.WebServiceReceiver; @WebService(targetNamespace = "http://tempuri.org/", name = "ConsultaPacientesSoap") public class Operacion_QueryPacientes extends AcceptMessage { public Operacion_QueryPacientes(WebServiceReceiver webServiceReceiver) { super(webServiceReceiver); } @WebMethod(action = "Operacion_QueryPacientes") public String Operacion_QueryPacientes(@WebParam(name = "part", targetNamespace = "http://tempuri.org/") String param) { String response = webServiceReceiver.processData(param); if (response != null) { return response; } return null; } }

Exportamos a un jar este proyecto, que llamaremos OperConsultaPacientes.jar
3. Desplegar nuestro Custom Web Service en Mirth
Una vez tenemos empaquetado nuestro jar, solo hay que seguir los mismos pasos que como utilizar una librería externa en Mirth Connect.
Ahora nos vamos a Channels, y en el interfaz del servicio web tendremos que modificar la opción Web Service a Custom service.
El marcar Custom service, nos permitirá escribir en el siguiente campo Service Class Name, donde pondremos la clase que queremos utilizar como interfaz. En este caso, la que hemos creado como org.tempuri.Operacion_QueryPacientes.
Por último, y al igual que vimos en el Web Service por defecto, el nombre del servicio será QueryPacientes:

4. Comprobar cambios en el interfaz
En la herramienta SoapUI importaremos dos proyectos, uno para cada canal y comprobaremos los cambios en el interfaz de ambos canales:

Con este simple desarrollo hemos conseguido crear un custom Web Service en Mirth Connect adaptando el contrato de integración al que tenía el antiguo Web Service en BizTalk.

11 ideas sobre “Custom Web Service en Mirth Connect”
Excelente trabajo amigo.
Podrias por favor ayudarme con un dilema de mirth connect?
quiero consumir un wsdl de un HIS, este trae la informacion del paciente y los examenes de laboratorio,….. quiero capturarlos en Mirth Connect …. para luego enviarlos a travez de WSDL a un LIS que acepta WSDL.
De antemano gracias por su respuesta de ayuda
Gracias Johan,
Lo bueno de Mirth Connect es que una vez que entiendes el concepto de Canal, es fácil diseñar un proceso para cualquier cosa qu e necesites.
Para lo que comentas haría falta, en primer lugar, tener el evento disparador que activaría el proceso, en el Source Connector del canal. Luego, en el Destination1 consumiría el WS del HIS con un WebService Sender, y en el Response procesaría la respuesta, donde como dices capturarías los datos que necesites. Con estos datos, un nuevo Destination2 que consumiría el WS del LIS para el envío del mensaje, supongo que HL7, correspondiente.
No sé si lo que necesitas es esta orientación sobre el proceso, o algo mas detallado técnicamente.
Un saludo,
El mensaje de la transacción llego al canal de mirth?
Si, claro, fíjate que sólo estamos cambiando el interfaz del WebService, pero esta clase sigue llamando a los métodos webServiceReceiver de la clase padre AcceptMessage, en Mirth Connect el canal funciona exactamente igual que el WebService por defecto, recogiendo un string como parámetro param.
Hola José … Después de 7 meses revise tu respuesta… Y parece que el tiempo no hubiese pasado…. Muchísimas gracias …. Esta vez retome Mirth con wsdl… Logré hacer algo … Pero me detuve en el envío al LIS por que el recibe datos por wsdl y por ejemplo el puede recibir varios estudios con el mismo TAG
1
2
3
Cuando trato de enviar esos datos el mirth solo me envía el primero, el resto los convierte en caracteres extraños…. He leído que debo transformarlos después de leídos. Para que mirth no los confunda pero no lo he logrado….
Quizás me puedas hechar una manito… Saludos estimado amigo…
Gracias por compartir
Sr José una consulta. es posible crear un método y que allí puedan enviar un xml .
ejemplo:
johan
sanchez
M
15
Muchas gracias de nuevo por su respuesta
Hola Johan
Es posible, claro. El tipo del parámetro que devuelven los métodos en Mirth por defecto es String, por lo que, generalmente con este interfaz se recoge un string con un XML con el correspondiente org.w3c.dom
Un saludo.
Hola sr José
Gracias de antemano por su pronta respuesta.
Lo intente con el método standard de mirth, pero se bloquea solo recibe un string ….apenas le envío una etiqueta del XML se bloquea
Sr José tiene por favor alguna forma de contactarlo
Un correo o número telefónico
Gracias
Hola Jose, gracias por compartir tus experiencias y conocimientos. Queria preguntarte sobre algo que quiero hacer con mirth. En mi caso tengo un HIS que usa una base de datos firebird 2.5, y no cuento con los fuentes del HIS para poder lanzar algun proceso a un webservice que este escuchando. En general lo que quiero hacer es tener un servicio web desde mith que reciba el idpatient, idvisita, idordenMedica, con estos datos me puedo conectar a firebird desde mirth para crear los mensajes HL7 y enviarlos via MLLP. No tengo claro es como hacer para que el mirh pueda recibir estos parametros. Me estoy guiando por tu entrada Custom Web Sevices, lo que indica que debo crear un jar con los 3 parametros que requiero y luego desplegarlo en Mith, no se si me puedes dar una idea un poco mas dirigida a lo que te comento. Muchas gracias y felicitaciones.
Está muy bueno el tutorial, la página tiene un problema que al bajar para leer hacer scroll automático al final de la página lo que dificulta leer, debe haber un problema con el JS