如何使用 apache camel hl7 生成自定义 ack
How to generate a custom ack with apache camel hl7
我正在尝试使用 camel 为 hl7v2.x 消息设置一个 mllp 侦听器。
我的环境
- apache camel 和组件版本 2.18.3
我还想避免使用 HAPI 库,因为我更喜欢为接收和生成的消息使用自定义解析器。由于我的每个客户都使用不同版本的标准和真正不同的字段 usage.That 这就是为什么在以下路由中没有对 hl7 数据类型进行解组,只是对字符串进行解组。我会自己做解析器。
还有我的路由(所有的bean和变量都定义在代码的其他地方,我认为它们不相关)
from("netty4:tcp://0.0.0.0:3333?
encoder=#encoderHl7&decoder=#decoderHl7&sync=true")
.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
.unmarshal().string()
.to("file://" + rutaSalidaFichero)
;
首先,作为概念证明,我只是试图将收到的所有消息复制到一个文件系统目录中。消息被正确接收并写入目录。但是我不知道如何生成和发送ACK,自动生成和发送一个错误的。
如果我从 outer/sending 系统发送 hl7 消息,camel 组件发送与 ack 相同的消息,因此发送系统在 return 中发送错误,因为它不是 ack预期的。我正在使用 mirth、dcm4chee、hapi 发送 hl7 消息......所有这些都得到相同的结果。
例如,如果我从 outer/sender 系统发送以下消息
MSH|^~\&|LIS|LIS|HIS|HIS|20170412131105||OML^O21|0000000001|P|2.5|||AL|||8859/1|||1.0
PID|1||123456||APELLIDO1&APELLIDO2^NOMBRE|19200101
兽人|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
兽人|RP|009509452919|317018426||||||20170412000000
OBR|1|317018426|317018426|CULT^CULTIVO
我没有在 camel 文档中找到对 ack 生成的引用,或者我是否可以使用自定义 "something" 来生成它。我想更改此默认行为。
正如 camel hl7 组件文档所说 (http://camel.apache.org/hl7.html, "HL7 Acknowledgement expression") 你可以通过使用
生成默认 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()))
这是我在项目中所做的:
<bean id="hl7Processor" class="com.mediresource.MessageRouting.HL7.HL7Processor" />
<route>
<from uri="mina2:tcp://10.68.124.140:2575?sync=true&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>
在 class 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;
}
我正在尝试使用 camel 为 hl7v2.x 消息设置一个 mllp 侦听器。
我的环境
- apache camel 和组件版本 2.18.3
我还想避免使用 HAPI 库,因为我更喜欢为接收和生成的消息使用自定义解析器。由于我的每个客户都使用不同版本的标准和真正不同的字段 usage.That 这就是为什么在以下路由中没有对 hl7 数据类型进行解组,只是对字符串进行解组。我会自己做解析器。
还有我的路由(所有的bean和变量都定义在代码的其他地方,我认为它们不相关)
from("netty4:tcp://0.0.0.0:3333?
encoder=#encoderHl7&decoder=#decoderHl7&sync=true")
.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
.unmarshal().string()
.to("file://" + rutaSalidaFichero)
;
首先,作为概念证明,我只是试图将收到的所有消息复制到一个文件系统目录中。消息被正确接收并写入目录。但是我不知道如何生成和发送ACK,自动生成和发送一个错误的。
如果我从 outer/sending 系统发送 hl7 消息,camel 组件发送与 ack 相同的消息,因此发送系统在 return 中发送错误,因为它不是 ack预期的。我正在使用 mirth、dcm4chee、hapi 发送 hl7 消息......所有这些都得到相同的结果。
例如,如果我从 outer/sender 系统发送以下消息 MSH|^~\&|LIS|LIS|HIS|HIS|20170412131105||OML^O21|0000000001|P|2.5|||AL|||8859/1|||1.0 PID|1||123456||APELLIDO1&APELLIDO2^NOMBRE|19200101 兽人|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 兽人|RP|009509452919|317018426||||||20170412000000 OBR|1|317018426|317018426|CULT^CULTIVO
我没有在 camel 文档中找到对 ack 生成的引用,或者我是否可以使用自定义 "something" 来生成它。我想更改此默认行为。
正如 camel hl7 组件文档所说 (http://camel.apache.org/hl7.html, "HL7 Acknowledgement expression") 你可以通过使用
生成默认 ackimport 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()))
这是我在项目中所做的:
<bean id="hl7Processor" class="com.mediresource.MessageRouting.HL7.HL7Processor" />
<route>
<from uri="mina2:tcp://10.68.124.140:2575?sync=true&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>
在 class 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;
}