如何使用apache camel hl7

时间:2017-04-12 12:20:13

标签: apache-camel netty hl7 mllp

我正在尝试使用camel为hl7v2.x消息设置一个mllp监听器。

我的环境

  • apache camel and components version 2.18.3

另外,我想避免使用HAPI库,因为我更喜欢收到和生成的消息的自定义解析器。因为我的客户每个人都使用不同版本的标准和非常不同的字段用法。这就是为什么在以下路由中没有对hl7数据类型进行解组,只是为了字符串。我自己会做解析器。

我的路线(所有的bean和变量都在代码的其他地方定义,我认为它们不相关)

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

首先,作为概念的证明,我只是试图将收到的所有消息复制到文件系统目录中。消息被正确接收并写入目录。但我不知道如何生成和发送ACK,自动生成和发送不正确的ACK。

如果我从外部/发送系统发送hl7消息,则camel组件发送与ack相同的消息,因此发送系统发送错误,因为它不是预期的ack。我正在使用mirth,dcm4chee,hapi发送hl7消息...所有这些都有相同的结果。

例如,如果我从外部/发件人系统发送以下消息   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 |||||| 201704.12亿     OBR | 1 | 317018426 | 317018426 | CULT ^ CULTIVO

我收到了与发送系统中的确认相同的内容。这是生成ack作为接收消息的骆驼 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 |||||| 201704.12亿     OBR | 1 | 317018426 | 317018426 | CULT ^ CULTIVO

我没有在camel docs中找到ack的生成,或者如果我可以使用自定义的“something”来生成它。我想更改此默认行为。

2 个答案:

答案 0 :(得分:0)

正如camel hl7组件文档所说(http://camel.apache.org/hl7.html," HL7确认表达式"),您只需使用

生成默认确认
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#evaluate"看起来像

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

答案 1 :(得分:0)

这就是我在项目中所做的:

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