Как сгенерировать кастомный апк с apache camel hl7

Я пытаюсь настроить слушатель mllp для сообщений hl7v2.x, используя верблюда.

Моя среда

  • верблюд и компоненты apache версии 2.18.3

Также я хотел бы избежать использования библиотеки HAPI, так как я предпочитаю настраиваемый парсер для полученных и сгенерированных сообщений. Так как каждый из моих клиентов использует разные версии стандартного и действительно разные поля использования, поэтому нет никакого демаршаллинга к типу данных hl7 на следующем маршруте, только к строке. Я сделаю парсер сам.

И мой маршрут (все компоненты и переменные определены в другом месте кода, я думаю, что они не имеют отношения)

from("netty4:tcp://0.0.0.0:3333?
encoder=#encoderHl7&decoder=#decoderHl7&sync=true")
.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") 
.unmarshal().string()
.to("file://" + rutaSalidaFichero)
;

Во-первых, как подтверждение концепции, я просто пытаюсь скопировать все полученные сообщения в каталог файловой системы. Сообщения правильно принимаются и записываются в каталог. Но я не знаю, как генерировать и отправлять ACK, автоматически генерируется и отправляется неверный.

Если я отправляю сообщение hl7 из внешней / отправляющей системы, верблюжий компонент отправляет то же сообщение, что и подтверждение, поэтому отправляющая система отправляет в ответ сообщение об ошибке, поскольку подтверждение не ожидается. Я отправляю сообщение hl7, используя mirth, dcm4chee, hapi... все с тем же результатом.

Например, если я отправлю следующее сообщение из внешней / отправляющей системы MSH|^~\&|LIS|LIS|HIS|HIS|20170412131105||OML^O21|0000000001|P|2.5|||AL|||8859/1|||1.0 PID|1||123456||APELLIDO1&APELLIDO2^NOMBRE|19200101 ORC|RP|009509452919|317018426||||||20170412000000 OBR|1|317018426|317018426|CULT^CULTIVO

Я получил так же, как подтверждение в системе отправки. Это верблюд, генерирующий подтверждение в виде принимающего сообщения MSH | ^ ~ \ & | LIS | LIS | HIS | HIS | 20170412131105 || OML ^ O21 | 0000000001 | P | 2.5 ||| AL ||| 8859/1 || | 1.0 PID | 1 || 123456 || APELLIDO1 & APELLIDO2 ^ NOMBRE | 19200101 ORC | RP | 009509452919 | 317018426 |||||| 20170412000000 OBR | 1 | 317018426 | 317018426 | CULT ^ CULTIVO

Я не нашел в документах верблюда ссылки на генерацию ack, или если я могу использовать пользовательское "что-то" для его генерации. Я хотел бы изменить это поведение по умолчанию.

2 ответа

Решение

Как сказано в документации по верблюжьему компоненту hl7 ( http://camel.apache.org/hl7.html, "выражение подтверждения HL7"), вы можете сгенерировать ack по умолчанию, просто используя

import static org.apache.camel.component.hl7.HL7.ack;
...

   from("direct:test1")
      // acknowledgement
      .transform(ack())

Здесь "ack()" является вызовом для "org.apache.camel.component.hl7.HL7#ack()". Но вы можете проверить, что "org.apache.camel.component.hl7.HL7" содержит некоторые другие полезные методы, такие как

org.apache.camel.component.hl7.HL7#ack(ca.uhn.hl7v2.AcknowledgmentCode code)

или же

org.apache.camel.component.hl7.HL7#ack(ca.uhn.hl7v2.AcknowledgmentCode code, java.lang.String errorMessage, ca.uhn.hl7v2.ErrorCode )

Вы можете использовать их для настройки фактического ответа ACK. Если мы пойдем глубже, то вы увидите, что "org.apache.camel.component.hl7.HL7#ack" являются просто обертками для

new ValueBuilder(new AckExpression(...))

и большинство параметров из методов "ack" направляются непосредственно в org.apache.camel.component.hl7.AckExpression. Фактическая генерация ACK выполняется в "org.apache.camel.component.hl7.AckExpression#valu" и выглядит как

public Object evaluate(Exchange exchange) {
        Throwable t = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
        Message msg = exchange.getIn().getBody(Message.class);
        try {
            HL7Exception hl7e = generateHL7Exception(t);
            AcknowledgmentCode code = acknowledgementCode;
            if (t != null && code == null) {
                code = AcknowledgmentCode.AE;
            }
            return msg.generateACK(code == null ? AcknowledgmentCode.AA : code, hl7e);
        } catch (Exception e) {
            throw ObjectHelper.wrapRuntimeCamelException(e);
        }
    }

Если вам нужна более глубокая настройка, вы можете просто написать свое собственное выражение MyCustomAckExpression, которое расширит org.apache.camel.component.hl7.AckExpression и реализует требуемую логику вместо

return msg.generateACK(code == null ? AcknowledgmentCode.AA : code, hl7e);

и использовать его как

...

   from("direct:test1")
      // acknowledgement
      .transform(new ValueBuilder(new MyCustomAckExpression()))

Вот что я сделал на своем проекте:

<bean id="hl7Processor" class="com.mediresource.MessageRouting.HL7.HL7Processor" />

<route>
    <from uri="mina2:tcp://10.68.124.140:2575?sync=true&amp;codec=#hl7codec" />
    <onException>
        <exception>org.apache.camel.RuntimeCamelException</exception>
        <exception>ca.uhn.hl7v2.HL7Exception</exception>
        <redeliveryPolicy maximumRedeliveries="0" />
        <handled>
            <constant>true</constant>
        </handled>        
        <bean ref="hl7Processor" method="sendACKError" />
    </onException>    
    <bean ref="hl7Processor" method="sendACK" />
</route>

На классе HL7Processor у меня есть это:

public Message sendACK(Message message, Exchange exchange ) throws HL7Exception, IOException {

    logger.debug("Entering");       
    Message ack = message.generateACK();
    logger.info("(10-4), End - ACK sent for " + exchange.getExchangeId());
    return ack;

} 

public Message sendACKError(Message message, Exception ex) throws HL7Exception, IOException {

    try {
        logger.warn("Internal Error:" + ex);
        Message ack = message.generateACK(AcknowledgmentCode.AE, new HL7Exception("Internal Error") );
        logger.warn("(10-4), End - NACK");
        return ack;
    } catch (Exception ex1) {
        logger.error("Fatal error on processError! ", ex1);
    }
    return null;
}
Другие вопросы по тегам