How to

Custom Web Service en Mirth Connect

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.

WS Mirth por defecto
WS Mirth por defecto

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:

DefaultAcceptMessage
DefaultAcceptMessage es la clase por defecto para Web 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;
    }

}
Estructura Proyecto
En ws-server.jar está la clase AcceptMessage que tendremos que heredar

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:

Mirth Custom WebService
Mirth Custom WebService

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:

Cambios en los wsdl de ambos Web Services
Cambios en los wsdl de ambos Web Services

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.

WSDL adaptado
WSDL adaptado

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

4 ideas sobre “Custom Web Service en Mirth Connect”

Follow by Email
Facebook
Twitter
LinkedIn