here is a sample ITI-21 request message:
=====
MSH|^~\&|@1.2.840.114350.1.13.99998.8735||@1.2.840.114350.1.13.99999.4567||20070428150301||QBP^Q22^QBP_Q21|1.2.840.114350.1.13.0.1.7.1.1|P^T|2.5
QPD|IHE PDQ Query|18...@1.2.840.114350.1.13.28.1.18.5.999|@PID.5.1^Heidi~@PID.5.2^MARY~@PID.7^19400101~@PID.8^F~@PID.11.1^3443 North Arctic Avenue~@PID.11.3^Some City|||||^^^&1.3.6.1.4.1.21367.2005.1.2&ISO
RCP|I
=====
Its format and contents are described in the specification of HL7 v2.5 as well as in the IHE IT Infrastructure Technical Framework, Vol. 2a, Section 3.21.
@Rajesh: the ITI-21 transaction does not belong to the XDS profile and is not based on ebML.
Regards
Dmytro
> 1) As a first step we would like to read a sample request from a
> variable(or a file), send it to the MPI and write the result(s) in
> another variable (file). We are not sure whether we have to unmarshal/
> marshall the testmessage as in the HL7 tutorial before sending it?
You haven't. Read under http://repo.openehealth.org/confluence/display/ipf2/mllp-common-datatypes about data types that can be used by HL7v2-based IPF components. In other words: an unparsed String or even a File would be ok.
> It would be nice if you could help us with a short code snippet.
See below.
> 2) Another question concerning that problem is whether we have to
> configure one or more rules to send the request to the MPI and receive
> the result to store it to a file? Is it possible to make a rule that
> "gets the request" -> "sends the request" -> "receives the result" ->
> "stores/processes the result"?
What do you mean under "rule"? A Camel/IPF route? Yes, it's possible to write a route that performs the steps you listed -- something like
from('file://myRequest.txt')
.onException(MllpAcceptanceException)
.maximumRedeliveries(0)
.process { println 'Not a PDQ message' }
.end()
.onException(ValidationException)
.maximumRedeliveries(0)
.process { println 'Invalid PDQ message' }
.end()
.onException(Exception.class)
.maximumRedeliveries(10)
.process { println 'MPI unreachable' }
.end()
.process(PixPdqCamelValidators.iti21RequestValidator())
.to('pix-iti21://mpi.uni-heilbronn.de:8888')
.process(PixPdqCamelValidators.iti21ResponseValidator())
.process {
assert it.in.body instanceof MessageAdapter
println it.in.body
it.in.body = it.in.body.toString()
}
.to('file://myResponse.txt')
(this is untested Groovy code)
> 3) A further question that occurred is whether we have to authenticate
> ourself to the MPI before asking for information (and then of course
> the question: how?)? We successfully sendedd a testmessage with the
> HL7 Client to our MPI and received a result. For this action we did
> not have to type in any username and password.
> It would be very nice if you could help us with some code snippets or
> point us to some example files for our problem. Thanks a lot for your
> help.
As far as I understood, your experiment has shown that the MPI does not require any client authentication ;)
MLLP protocol per se does not provide any authentication mechanisms. When you still want to have them, all you can do is to use SSL and analyse SSL certificates -- for example, by means of an user-defined MLLP interceptor. Such interceptors can be deployed at an IPF MLLP endpoint as described in the last section of http://repo.openehealth.org/confluence/display/ipf2/mllp-common-parameters .
Regards
Dmytro
the following statement is missing in your Groovy file:
import org.openehealth.ipf.platform.camel.ihe.mllp.core.MllpAcceptanceException
(I suppose that other classes mentioned in the snippet will require import statements as well.)
Regards,
Dmytro
have you defined a HL7v2 codec bean? Read here about it:
http://repo.openehealth.org/confluence/display/ipf2/mllp-common-parameters
Best Regards,
I'm not sure whether the Camel file component (http://camel.apache.org/file.html) respects the classpath when searchig for files. Probably it doesn't. Try to specify absolute path in from(file://...).
renaming of the context file was not neccessary.
MockedSender is here:
<dependency>
<groupId>org.openehealth.ipf.commons</groupId>
<artifactId>commons-ihe-atna</artifactId>
<version>${ipf-version}</version>
<!--scope>test</scope-->
<type>test-jar</type>
</dependency>
Regards,
IPF 2.2.1 comes with Spring 3.0.4, while your pom.xml references
2.5.6. So you have incompatible set of JARs in the classpath. I
suppose this is the error cause.
In order to avoid such problems, you can automatically inherit
dependency configuration from IPF. Add the following item to the
<dependenciesManagement> section of your pom.xml:
<dependencyManagement>
<dependencies>
.....
<dependency>
<groupId>org.openehealth.ipf</groupId>
<artifactId>ipf</artifactId>
<version>${ipf-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
.....
</dependencies>
</dependencyManagement>
After that, <version> elements of third-party dependencies can be
omitted, because Maven will use versions configured in IPF.
Regards,
Dmytro
2011/4/29 slowessam <wessa...@googlemail.com>:
IPF 2.2.1 comes with Spring 3.0.4, while your pom.xml references
2.5.6. So you have incompatible set of JARs in the classpath. I
suppose this is the error cause.
In order to avoid such problems, you can automatically inherit
dependency configuration from IPF. Add the following item to the
<dependenciesManagement> section of your pom.xml:
<dependencyManagement>
<dependencies>
.....
<dependency>
<groupId>org.openehealth.ipf</groupId>
<artifactId>ipf</artifactId>
<version>${ipf-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
.....
</dependencies>
</dependencyManagement>
After that, <version> elements of third-party dependencies can be
omitted, because Maven will use versions configured in IPF.
Regards,
Dmytro
2011/4/29 slowessam <wessa...@googlemail.com>:
so, you have a route and want to execute this route from a plain
Java application --- right? The approach applied in unit tests
(ProducerTemplate & Co.) is suitable in this case as well.
(But then, probably, arises the question about why the business
logic to be triggered has been implemented as a Camel route).
Regards,
Dmytro
2011/5/3 Sven Siekmann <sven.s...@web.de>:
> ok. Now I am really a little bit confused. So you say we can just use
> this ProducerTemplate like in the unit test - right? In the unit test
> we inherited the relevant methods from "MllpTestContainer" - is there
> a class we can inherit from to get these methods for our application
> code? Or do we need to write these methods on our own? Or should we
> use the MllpTestContainer?
you can keep using MllpTestContainer, or you can write something like
===============
// build Camel infrastructure
CamelContext camelContext = new DefaultCamelContext();
camelContext.start();
// prepare request
String request = "MSH|...|blabla|...";
Exchange requestExchange = new DefaultExchange(camelContext);
requestExchange.getIn().setBody(request);
// send request
ProducerTemplate producerTemplate = new DefaultProducerTemplate(camelContext);
producerTemplate.start();
Exchange responseExchange = producerTemplate.send("direct:start",
requestExchange);
// get response
String response = responseExchange.getOut().getBody(String.class);
===============
This example assumes that your route starts with from("direct:start")
instead of from("file...") and does not contain to("file...") at the
end.
> Concerning your remark in parentheses: Do you suggest not to use the
> implementation via Camel route in our case (maybe even for the whole
> application?)? And what do we have to do to use Camel routes? Could
> you give us some code snippets or point us to some example files so
> that we maybe get an idea how it works. Thank you for your help.
I see at least two possible scenarios here:
1. As in the sample code above: a Java application uses
ProducerTemplate to send a request to a Camel route via direct
endpont, the route performs message validation and communicates with
MPI using IPF components.
2. A Java application performs message validation and uses
ProducerTemplate to communicate with MPI using IPF components. No
route definitions, no DSL extensions and no context descriptors are
required in this case.
The implementation of the second scenario could look like
===============
// build Camel infrastructure
CamelContext camelContext = new DefaultCamelContext();
camelContext.start();
// prepare request
String request = "MSH|...|blabla|...";
Exchange requestExchange = new DefaultExchange(camelContext);
requestExchange.getIn().setBody(request);
// validate request
try {
PixPdqCamelValidators.iti21RequestValidator().process(requestExchange);
} catch (ValidationException e) {
System.out.println("Request validation failed");
System.exit(1);
}
// send request
ProducerTemplate producerTemplate = new DefaultProducerTemplate(camelContext);
producerTemplate.start();
try {
Exchange responseExchange =
producerTemplate.send("pdq-iti21://...", requestExchange);
if (responseExchange.getException() != null) {
throw responseExchange.getException();
}
} catch (Exception e) {
System.out.println("Request failed");
responseExchange.getException().printStackTrace();
System.exit(1);
}
// validate response
responseExchange.getIn().setBody(responseExchange.getOut().getBody());
try {
PixPdqCamelValidators.iti21ResponseValidator().process(responseExchange);
} catch (ValidationException e) {
System.out.println("Response validation failed");
System.exit(1);
}
// process response
MessageAdapter response =
responseExchange.getIn().getBody(MessageAdapter.class);
Terser terser = new Terser((Message) response.getTarget());
.......
===============
Kind Regards,
Dmytro
1. Does your route definition begin with from("direct:start") ?
2a. Does your pom.xml contain platform-camel-ihe-pixpdq as dependency?
2b. Did you define a HL7v2 codec as described early in this mailing list?
Regards,
Dmytro
2011/5/9 slowessam <wessa...@googlemail.com>:
Regards,
Dmytro.
2011/5/9 slowessam <wessa...@googlemail.com>:
> Hi Dmytro,
>
> this is our route definition:
> =========
> from('direct:start')
> .onException(MllpAcceptanceException)
> .maximumRedeliveries(0)
> .process { println 'Not a PDQ message' }
> .end()
> .onException(ValidationException)
> .maximumRedeliveries(0)
> .process { println 'Invalid PDQ message' }
> .end()
> .onException(Exception.class)
> .maximumRedeliveries(10)
> .process { println 'MPI unreachable' }
> .end()
> .process(PixPdqCamelValidators.iti21RequestValidator())
> .process(PixPdqCamelValidators.iti21ResponseValidator())
> .process {
> assert it.in.body instanceof MessageAdapter
> println it.in.body
> it.in.body = it.in.body.toString()
> }
> ==========
>
> this is our cntext.xml
>
> ==========
> <beans xmlns="http://www.springframework.org/schema/beans"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:lang="http://www.springframework.org/schema/lang"
> xmlns:camel="http://camel.apache.org/schema/spring"
> xsi:schemaLocation="
> http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
> http://www.springframework.org/schema/lang
> http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
> http://camel.apache.org/schema/spring
> http://camel.apache.org/schema/spring/camel-spring.xsd">
>
> <camel:camelContext id="camelContext">
> <camel:routeBuilder ref="routeBuilder" />
> </camel:camelContext>
>
> <bean id="routeBuilder" depends-on="routeModelExtender"
> class="de.hhn.mi.coala.PDQRouteBuilder">
> </bean>
>
> <bean id="pdqModelExtension"
> class="de.hhn.mi.coala.PDQModelExtension">
> </bean>
>
> <bean id="hl7codec"
> class="org.apache.camel.component.hl7.HL7MLLPCodec">
> <property name="charset" value="iso-8859-1" />
> </bean>
>
> <!-- HAPI extensions -->
> <bean id="hapiModelExtension"
> class="org.openehealth.ipf.modules.hl7.extend.HapiModelExtension">
> <!-- <property name="mappingService" ref="..." /> -->
> </bean>
>
> <!-- General Mapping extensions <bean id="mappingExtension"
> class="org.openehealth.ipf.commons.map.extend.MappingExtension">
> <property name="mappingService" ref="..." /> </bean> -->
>
> <!-- Camel DSL extensions -->
> <bean id="hl7ModelExtension"
>
> class="org.openehealth.ipf.platform.camel.hl7.extend.Hl7ModelExtension">
> </bean>
>
> <bean id="coreModelExtension"
>
> class="org.openehealth.ipf.platform.camel.core.extend.CoreModelExtension">
> </bean>
>
> <bean id="routeModelExtender"
>
> class="org.openehealth.ipf.platform.camel.core.extend.DefaultModelExtender">
> <property name="routeModelExtensions">
> <list>
> <ref bean="coreModelExtension" />
> <ref bean="coreModelExtension" />
> <ref bean="pdqModelExtension" />
> <ref bean="hl7ModelExtension" />
> <ref bean="hapiModelExtension" />
> <!-- <ref bean="mappingExtension" /> -->
> </list>
> </property>
> </bean>
>
> </beans>
>
> ===========
>
> .
> and our pom.xml
>
> ===========
> <dependencyManagement>
> <dependencies>
> <dependency>
> <groupId>org.openehealth.ipf</groupId>
> <artifactId>ipf</artifactId>
> <version>${ipf-version}</version>
> <type>pom</type>
> <scope>import</scope>
> </dependency>
> </dependencies>
> </dependencyManagement>
> <dependencies>
> <dependency>
> <groupId>org.openehealth.ipf.platform-camel</groupId>
> <artifactId>platform-camel-ihe-pixpdq</artifactId>
> <version>${ipf-version}</version>
> </dependency>
> <!-- USE with Camel -->
> <dependency>
> <groupId>org.openehealth.ipf.platform-camel</groupId>
> <artifactId>platform-camel-hl7</artifactId>
> <version>${ipf-version}</version>
> </dependency>
> <!-- HAPI version? -->
> <!-- Dependency for HL7 v2.5 -->
> <dependency>
> <groupId>ca.uhn.hapi</groupId>
> <artifactId>hapi-structures-v25</artifactId>
> <!-- <version>0.6</version> -->
> </dependency>
> <dependency>
> <groupId>net.sf.saxon</groupId>
> <artifactId>saxon</artifactId>
> <!-- <version>9.1.0.8</version> -->
> </dependency>
> <dependency>
> <groupId>org.springframework</groupId>
> <artifactId>spring-core</artifactId>
> <!-- <version>2.5.6</version> -->
> </dependency>
> <dependency>
> <groupId>org.openehealth.ipf.platform-camel</groupId>
> <artifactId>platform-camel-ihe-mllp</artifactId>
> <version>${ipf-version}</version>
> <!--scope>test</scope -->
> <type>test-jar</type>
> </dependency>
> <dependency>
> <groupId>org.openehealth.ipf.commons</groupId>
> <artifactId>commons-ihe-atna</artifactId>
> <version>${ipf-version}</version>
> <!--scope>test</scope -->
> <type>test-jar</type>
> =============
>
> and at least this is the hl7v2 codec that we defined:
>
> "MSH|^~\\&|OHFConsumer|OHFFacility|OTHER_KIOSK|HIMSSSANDIEGO|
> 20070108145322-0800||"
> + "QBP^Q22|9416994431147258002|P|2.5|\nQPD|Q22^Find
> Candidates|"
> + "7891956360974608557281601076319|@PID.5.1^M*|\nRCP|I|
> 2^RD"
>
> Regards,
>
> Wessam
>
>
> On 9 Mai, 11:27, Dmytro Rud <dmytro....@googlemail.com> wrote:
>> Hi,
>>
>> 1. Does your route definition begin with from("direct:start") ?
>> 2a. Does your pom.xml contain platform-camel-ihe-pixpdq as dependency?
>> 2b. Did you define a HL7v2 codec as described early in this mailing list?
>>
>> Regards,
>> Dmytro
>>
>> 2011/5/9 slowessam <wessamk...@googlemail.com>:
>>
>> > Hi Dmytro,
>>
>> > we still have an error in our reasoning. We used the first sample code
>> > above with the endpoint: "direct:start"
>> > but we get:
>>
>> > ===========
>> > 2011-05-09T11:14:10,806 [main] WARN - component.direct.DirectProducer
>> > | No consumers available on endpoint: Endpoint[direct://start] to
>> > process: Exchange[Message: MSH|^~\&|OHFConsumer|OHFFacility|
>> > OTHER_KIOSK|HIMSSSANDIEGO|20070108145322-0800||QBP^Q22|
>> > 9416994431147258002|P|2.5|
>> > QPD|Q22^Find Candidates|78919563609746085572816010763...@PID.5.1^M*|
>> ...
>>
>> Erfahren Sie mehr »
Regards,
Dmytro
2011/5/9 slowessam <wessa...@googlemail.com>:
Regards,
Dmytro
2011/5/9 Sven Siekmann <sven.s...@web.de>:
Regards,
Dmytro
2011/5/9 Sven Siekmann <sven.s...@web.de>:
Dmytro.
Sven Siekmann writes:
>> Erfahren Sie mehr �
(Definitely not an IPF issue.)
Best Regards,
Dmytro
Sven Siekmann writes:
>> Erfahren Sie mehr �