【问题标题】:How to generate a custom ack with apache camel hl7如何使用 apache camel hl7 生成自定义 ack
【发布时间】:2017-09-08 05:22:44
【问题描述】:

我正在尝试使用骆驼为 hl7v2.x 消息设置 mllp 侦听器。

我的环境

  • apache 骆驼和组件版本 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||||||20170412000000 OBR|1|317018426|317018426|CULT^CULTIVO

我收到了与发送系统中的 ack 相同的信息。这是生成 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||||||20170412000000 OBR|1|317018426|317018426|CULT^CULTIVO

我没有在骆驼文档中找到对 ack 生成的引用,或者我是否可以使用自定义“某物”来生成它。我想更改此默认行为。

【问题讨论】:

    标签: apache-camel netty hl7


    【解决方案1】:

    正如骆驼 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#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()))
    

    【讨论】:

    • 我已经重写了路线,现在看起来像这样。 from("netty4:tcp://0.0.0.0:3333?encoder=#encoderHl7&decoder=#decoderHl7&sync=true") .unmarshal().string() .onCompletion().modeBeforeConsumer() .transform(ack(AckCode.AA )) .end() .to("file://" + rutaSalidaFichero);如果我不使用 onCompletion().modeBeforeConsumer(),我会丢失路由其余部分的原始消息,并且将 ack 写入文件系统而不是原始消息。欢迎提出意见和建议。
    【解决方案2】:

    这是我在项目中所做的:

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

    【讨论】:

      猜你喜欢
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多