Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Seeking Help for IHE Evaluation Preparation, implementing XDS、PIX、EUA

119 views
Skip to first unread message

文波

unread,
Jan 22, 2024, 9:59:07 PM1/22/24
to ipf-user
Dear everyone
I am currently preparing for the 2024 IHE evaluation, and I am getting ready to implement three profiles in IHE: XDS, PIX, and EUA. However, I am facing some strategic and learning issues. The problems are as follows:
Problem 1, Can I effectively implement IHE profile-defined transactions using the IPF framework?
Problem 2, I have never used Groovy language before. I downloaded the source code of IPF and encountered many difficulties while learning from the source code. Can I use a pure Java language Spring Boot project and the IPF framework to implement XDS, PIX, and EUA transactions? Are there any reference materials available?
Problem 3, as IHE evaluation requires playing various roles, such as in XDS, the ITI-18 transaction, where I need to act as both Document Consumer and Document Registry. For the Document Consumer role, I need to accept query parameters from the front end, assemble them into RegistryStoredQueryRequest_SOAP_XML, and then send it to another Document Registry. Since the ipf-tutorials-xds example provided by the IPF framework is written in Groovy language, I am currently unable to migrate it to a Spring Boot project. Therefore, I am currently manually assembling the RegistryStoredQueryRequest_SOAP.xml message and then sending the message to the Document Registry via HTTP. However, the message I manually assembled is incorrect, as it does not include the lcm, rim, and rs namespaces within the <s:Body> tag, causing errors. How should I solve this?
I hope you can help me answer the above three questions or provide a feasible new approach to prepare for the implementation of the XDS, PIX, and EUA profiles required for the IHE evaluation. I am a complete novice in IHE evaluation and the IPF framework. Please help me develop a feasible strategy. Thank you again for your help.
Best Reagrds
BoVane

Dmytro Rud

unread,
Jan 23, 2024, 1:29:25 AM1/23/24
to ipf-...@googlegroups.com
Hi BoVane

1. Yes for XDS and PIX, but IPF does not support the EUA profile yet.
2. Yes, you can use Java instead of Groovy for everything.
3. If you create the SOAP envelope manually as discussed yesterday, you can manually add XML namespace declarations to the SOAP Body or SOAP Envelope element.

Best regards
Dmytro


--
You received this message because you are subscribed to the Google Groups "ipf-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ipf-user+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ipf-user/1ad11e84-696f-409e-9607-6395d0519a7an%40googlegroups.com.

文波

unread,
Jan 23, 2024, 2:31:46 AM1/23/24
to ipf-user
Hi Dmytro
If I want to manually add namespaces to the tags within the body, how do I know which type of tag belongs to which namespace? For example, in the RegistryStoredQueryRequest_SOAP.xml example, the <s:Body> tag only involves the rim namespace, while in the ProvideAndRegisterDocumentSet-bRequest_SOAP.xml example, the <s:Body> tag involves both the lcm and rim namespaces. Additionally, is it appropriate to use string replacement with the replaceAll() method to manually add namespaces to the tags within the body? Example links are as follows.
ProvideAndRegisterDocumentSet-bRequest_SOAP.xml
RegistryStoredQueryRequest_SOAP.xml

Best regards
BoVane

Dmytro Rud

unread,
Jan 23, 2024, 2:50:58 AM1/23/24
to ipf-...@googlegroups.com
Hi BoVane

Each XML namepspace shall be defined at latest in the XML element where it is used.  For example, if the SOAP body contains an element <ns1:Payload>, then the namespace corresponding to the prefix "ns1" shall be defined either in <ns1:Payload> or in <soap:Body> or in <soap:Envelope> (presumed that "soap" is the namespace prefix defined for SOAP):

Variant 1:

<soap:Envelope xmlns:soap="..." xmlns:ns1="...">
    <soap:Body>
        <ns1:Payload>...</ns1:Payload>
    </soap:Body>
</soap:Envelope>

Variant 2:

<soap:Envelope xmlns:soap="...">
    <soap:Body xmlns:ns1="...">
        <ns1:Payload>...</ns1:Payload>
    </soap:Body>
</soap:Envelope>

Variant 3:

<soap:Envelope xmlns:soap="...">
    <soap:Body>
        <ns1:Payload xmlns:ns1="...">...</ns1:Payload>
    </soap:Body>
</soap:Envelope>

Usage of replaceAll() can be dangerous.  But why do you need this method?

Best regards
Dmytro



文波

unread,
Jan 23, 2024, 3:12:49 AM1/23/24
to ipf-user
Hi Dmytro
I'm sorry, I don't understand anything. I feel like I'm very wrong. This is my code and output for generating ITI-18 QueryRequest. I want to add a namespace to my output so that it matches the standard example provided by IHE. The link to the standard example is as follows: [Link to Standard Example]
RegistryStoredQueryRequest_SOAP.xml

Best regards

@Slf4j
public class ITI18RequestResponse {
protected static CamelContext camelContext;
@SneakyThrows
public static void generateITI18QueryRequest(ITI18QueryDTO iti18QueryDTO) {
camelContext = new DefaultCamelContext();
camelContext.start();
FindDocumentsQuery query = new FindDocumentsQuery();
// setup patientId
query.setPatientId(new Identifiable(iti18QueryDTO.getPatientId()));
log.info(query.getPatientId().getId());
// setup status
List<AvailabilityStatus> statuses = CollUtil.newArrayList();
statuses.add(AvailabilityStatus.APPROVED);
query.setStatus(statuses);
QueryRegistry queryRegistry = new QueryRegistry(query);
queryRegistry.setReturnType(QueryReturnType.LEAF_CLASS);

DefaultExchange exchange = new DefaultExchange(camelContext);
Message message = new DefaultMessage(camelContext);
message.setBody(queryRegistry);
exchange.setIn(message);
log.info(XdsRenderingUtils.render(exchange));
String soap = convertObjectToXml(exchange);
log.warn(soap);


}

public static void main(String[] args) {
ITI18QueryDTO iti18QueryDTO = new ITI18QueryDTO();
iti18QueryDTO.setPatientId("st3498702^^^&amp;1.3.6.1.4.1.21367.2005.3.7&amp;ISO");
generateITI18QueryRequest(iti18QueryDTO);
}

public static String convertObjectToXml(Exchange exchange) {
String iti18RequestXmlString = XdsRenderingUtils.render(exchange).replaceAll("<\\?xml(.+?)\\?>", "");
String wsaMessageId = UUID.randomUUID().toString();
String targetEndpointUri = "https://example.com/iti18Endpoint";

String soapEnvelope = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:wsa=\"http://www.w3.org/2005/08/addressing/\"><soap:Header>" +
"<wsa:MessageID>" + wsaMessageId + "</wsa:MessageID>" +
"<wsa:ReplyTo><wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address></wsa:ReplyTo>" +
"<wsa:To>" +targetEndpointUri+ "</wsa:To>" +
"<wsa:Action>urn:ihe:iti:2007:RegistryStoredQuery</wsa:Action>" +
"</soap:Header><soap:Body>" + iti18RequestXmlString + "</soap:Body></soap:Envelope>";
return soapEnvelope;
}

}
The soap XML I generated
<soap:Envelope
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:wsa="http://www.w3.org/2005/08/addressing/">
    <soap:Header>
        <wsa:MessageID>f0307a8c-9a5c-4467-9626-ab629e523985</wsa:MessageID>
        <wsa:ReplyTo>
            <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
        </wsa:ReplyTo>
        <wsa:To>https://example.com/iti18Endpoint</wsa:To>
        <wsa:Action>urn:ihe:iti:2007:RegistryStoredQuery</wsa:Action>
    </soap:Header>
    <soap:Body>
        <query:AdhocQueryRequest
            xmlns="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0"
            xmlns:rs="urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0"
            xmlns:xds="urn:ihe:iti:xds-b:2007"
            xmlns:query="urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0"
            xmlns:lcm="urn:oasis:names:tc:ebxml-regrep:xsd:lcm:3.0"
            xmlns:rmd="urn:ihe:iti:rmd:2017"
            xmlns:xdsi="urn:ihe:rad:xdsi-b:2009">
            <query:ResponseOption returnType="LeafClass" returnComposedObjects="true"/>
            <AdhocQuery id="urn:uuid:14d4debf-8f97-4251-9a74-a90016b0af0d">
                <Slot name="$XDSDocumentEntryPatientId">
                    <ValueList>
                        <Value>'st3498702\S\\S\\S\\T\amp;1.3.6.1.4.1.21367.2005.3.7\T\amp;ISO'</Value>
                    </ValueList>
                </Slot>
                <Slot name="$XDSDocumentEntryStatus">
                    <ValueList>
                        <Value>('urn:oasis:names:tc:ebxml-regrep:StatusType:Approved')</Value>
                    </ValueList>
                </Slot>
            </AdhocQuery>
        </query:AdhocQueryRequest>
    </soap:Body>
</soap:Envelope>
The soap Example IHE provided contains namespace in body tags

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <!--The following header applies for a Synchronous Web Services Exchange Request
        Please note that a soap message can only have one header section. -->
  <s:Header>
<a:Action s:mustUnderstand="1">urn:ihe:iti:2007:RegistryStoredQuery</a:Action>
<a:MessageID>urn:uuid:a02ca8cd-86fa-4afc-a27c-616c183b2055</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://localhost:2647/XdsService/IHEXDSRegistry.svc</a:To>
</s:Header>
  <s:Body>
<query:AdhocQueryRequest xsi:schemaLocation="urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0 ../../schema/ebRS/query.xsd" xmlns:query="urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:rs="urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0">
<query:ResponseOption returnComposedObjects="true" returnType="LeafClass"/>
<rim:AdhocQuery id=" urn:uuid:14d4debf-8f97-4251-9a74-a90016b0af0d ">
<rim:Slot name="$XDSDocumentEntryPatientId">
<rim:ValueList>
<rim:Value>st3498702^^^&amp;1.3.6.1.4.1.21367.2005.3.7&amp;ISO</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Slot name="$XDSDocumentEntryStatus">
<rim:ValueList>
<rim:Value>('urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Approved')</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Slot name="$XDSDocumentEntryCreationTimeFrom">
<rim:ValueList>
<rim:Value>200412252300</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Slot name="$XDSDocumentEntryCreationTimeTo">
<rim:ValueList>
<rim:Value>200501010800</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Slot name="$XDSDocumentEntryHealthcareFacilityTypeCode">
<rim:ValueList>
<rim:Value>(‘Emergency Department’)</rim:Value>
</rim:ValueList>
</rim:Slot>
</rim:AdhocQuery>
</query:AdhocQueryRequest>
</s:Body>
</s:Envelope>

Dmytro Rud

unread,
Jan 23, 2024, 3:21:03 AM1/23/24
to ipf-...@googlegroups.com
The SOAP XML you generated is correct and does not require any changes.  Simply use it as it is.


Dmytro Rud

unread,
Jan 23, 2024, 3:24:19 AM1/23/24
to ipf-...@googlegroups.com
The only wrong thing is this:

                        <Value>'st3498702\S\\S\\S\\T\amp;1.3.6.1.4.1.21367.2005.3.7\T\amp;ISO'</Value>

Seems that your ITI18QueryDTO does not set the patient ID correctly behind the scenes.

文波

unread,
Jan 23, 2024, 3:40:47 AM1/23/24
to ipf-user
Thank you very much for your help.Then how should fix it? When I set the PatientId and call the method to generate the string, the system automatically escapes the special characters inside. In the ipf-tutorials-xds test, you use UUID as the patient ID, so can I also use UUID as the patient ID? AdditionallyI am currently studying ipf-tutorials-xds. If I have any questions along the way, I will come to ask you.

Dmytro Rud

unread,
Jan 23, 2024, 3:45:12 AM1/23/24
to ipf-...@googlegroups.com
How does ITI18QueryDTO set the patient ID in the IPF class?  Can you show the code?


文波

unread,
Jan 23, 2024, 3:50:01 AM1/23/24
to ipf-user
I use soap ui for test

But when I generate UUID as patientId, the error occur

Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId              ProcessorId          Processor                                                                        Elapsed (ms)
[route2            ] [route2            ] [xds-iti18://xds-iti18                                                         ] [         0]
[route2            ] [log2              ] [log                                                                           ] [         0]
[route2            ] [process4          ] [Processor@0x42421133                                                          ] [         0]

Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
org.openehealth.ipf.commons.ihe.xds.core.validate.XDSMetaDataException: The universal ID type of an assigning authority must be ISO: urn:uuid:14d4debf-8f97-4251-9a74-a90016b0af0d

The ITI-18 processor are as follows
@Component
public class Iti18Processor implements Processor {
protected Logger log = LoggerFactory.getLogger(getClass());

@Override
public void process(Exchange exchange) throws Exception {
Message message = exchange.getIn();
log.info(XdsRenderingUtils.render(exchange));
QueryRegistry request = message.getBody(QueryRegistry.class); //ITI-18 type of request class
log.debug("QueryRegistry: " + request);
Query query = request.getQuery();
QueryType queryType = query.getType();
QueryResponse queryResponse = new QueryResponse(Status.SUCCESS);
switch(queryType) {
case FIND_DOCUMENTS:
FindDocumentsQuery findQuery = (FindDocumentsQuery)query;

// Create a fake document reference
DocumentEntry documentEntry = new DocumentEntry();
// set attributes
documentEntry.setCreationTime(new Timestamp(new DateTime(), Precision.SECOND));
documentEntry.getConfidentialityCodes().add(new Code("N", new LocalizedString("Normal", "en_EN", "utf-8"), "2.16.840.1.113883.5.25"));
documentEntry.setFormatCode(new Code("urn:ihe:iti:xds:2017:mimeTypeSufficient", new LocalizedString("mimeType Sufficient", "en_EN", "utf-8"),"1.3.6.1.4.1.19376.1.2.7.1")); // http://hl7.org/fhir/ValueSet-formatcodes.html
documentEntry.setPatientId(new Identifiable("121212", new AssigningAuthority("1.3.4.5")));
documentEntry.setSourcePatientId(new Identifiable("121212", new AssigningAuthority("1.3.4.5")));
documentEntry.setRepositoryUniqueId("1.2.3.4");
documentEntry.setAvailabilityStatus(AvailabilityStatus.APPROVED);
documentEntry.setMimeType("text/xml");
documentEntry.setLanguageCode("en-US");

// we can't return actual document in response, this is defined here to show how to set some attributes
String textXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Document></Document>";
documentEntry.setHash(DigestUtils.sha1Hex( textXml ));
documentEntry.setSize((long) textXml.length());

documentEntry.setEntryUuid("urn:uuid:" + UUID.randomUUID().toString());
documentEntry.setClassCode(new Code("HnP", new LocalizedString("History and Physical", "en_EN", "utf-8"), "L"));
documentEntry.setTypeCode(new Code("O", new LocalizedString("Outpatient", "en_EN", "utf-8"), "L"));
documentEntry.setType(DocumentEntryType.STABLE);
documentEntry.setPracticeSettingCode(new Code("GM", new LocalizedString("General Medicine", "en_EN", "utf-8"), "L"));
documentEntry.setHealthcareFacilityTypeCode(new Code("HnP", new LocalizedString("History and Physical", "en_EN", "utf-8"), "L"));

queryResponse.getDocumentEntries().add(documentEntry);
exchange.getOut().setBody(queryResponse);
log.info(XdsRenderingUtils.render(exchange));
break;
default:
queryResponse.setStatus(Status.FAILURE);
queryResponse.getErrors().add(new ErrorInfo(ErrorCode._USER_DEFINED,"", Severity.ERROR,"","This query is not supported yet."));
break;
}
exchange.getOut().setBody(queryResponse);
log.info(XdsRenderingUtils.render(exchange));
}

}

The xds Router are as follows

@Component
public class XdsRouteBuilder extends RouteBuilder {

@Override
public void configure() {

// Entry point for Provide and Register Document Set
from("xds-iti41:xds-iti41")
.log("received iti41: " + bodyAs(ProvideAndRegisterDocumentSet.class))
// Validate and convert the request
.process(iti41RequestValidator())
.process(new Iti41Processor())
// Validate response
.process(iti41ResponseValidator())
;

// Entry point for Stored Query
from("xds-iti18:xds-iti18")
.log("received iti18: " + bodyAs(QueryRegistry.class))
.process(iti18RequestValidator())
.process(new Iti18Processor())
.process(iti18ResponseValidator())
;

// Entry point for iti43 Retrieve Document Set
from("xds-iti43:xds-iti43")
.log("received iti43: " + bodyAs(RetrieveDocumentSet.class))
.process(iti43RequestValidator())
.process(new Iti43Processor())
.process(iti43ResponseValidator())
;
}

}

Dmytro Rud

unread,
Jan 23, 2024, 3:58:16 AM1/23/24
to ipf-...@googlegroups.com
This is not what I meant.  In the previous mail you posted this code:
iti18QueryDTO.setPatientId("st3498702^^^&amp;1.3.6.1.4.1.21367.2005.3.7&amp;ISO");
My question is: How does iti18QueryDTO use this patient ID?


文波

unread,
Jan 23, 2024, 4:04:39 AM1/23/24
to ipf-user
I use parentID in  iti18QueryDTO  to setup Identifiable

FindDocumentsQuery query = new FindDocumentsQuery();
// setup patientId
query.setPatientId(new Identifiable(iti18QueryDTO.getPatientId()));
log.info(query.getPatientId().getId());

Dmytro Rud

unread,
Jan 23, 2024, 4:08:30 AM1/23/24
to ipf-...@googlegroups.com
he first parameter of "new Identifiable(...)" shall be only "st3498702", because "1.3.6.1.4.1.21367.2005.3.7" is the assigning aithority OID (the second parameter of "new Identifiable(...)".


文波

unread,
Jan 23, 2024, 4:13:20 AM1/23/24
to ipf-user
Dear Dmytro
Thank you very much for your help. I am currently studying ipf-tutorials-xds. If I have any questions along the way, I will come to ask you.😊😊😊
Best regards
BoVane

文波

unread,
Jan 26, 2024, 3:43:59 AM1/26/24
to ipf-user
Hi Dmytro 
If I want to implement an ITI-18 transaction using the IPF framework, and I have already constructed an object of type QueryRegistry, can I use the IPF framework to generate a SOAP message for the QueryRegistry object? I want the corresponding XML to automatically include namespaces within the tags when generating the XML. For example, if I send an ITI-18 query request (a SOAP-formatted string) in SoapUI, and then define an Iti18Processor implementing Processor in a Spring Boot project, and define a XdsRouteBuilder extending RouteBuilder, will it directly respond with a SOAP-structured return in SoapUI? In this process, is the SOAP XML structure of the response body generated by the IPF framework? Please forgive me once again for being a novice, and thank you very much for your help.
Best regards
BoVane

Dmytro Rud

unread,
Jan 26, 2024, 4:06:07 AM1/26/24
to ipf-...@googlegroups.com
Hi BoVane

Again: 
1. The generated XML already includes all XML namespace definitions etc., and does not need to be modified.  Even more, you as application developer do not need to work with XML at all, you need to create a POJO, either using ebXML JAXB classes or in the simplified data model provided by IPF, and IPF will do the rest.
2. Same for SOAP envelope: it is automatically created when you send a message, and automatically parsed when you receive a message.  This is done by the Apache CXF framework which is used in IPF.  

Best regards
Dmytro





bovane.ch

unread,
Jan 26, 2024, 4:18:20 AM1/26/24
to ipf-user
Thank you very much for your explanation. I will take the time to
understand the logic behind it. By the way, are the XDS-related
transactions implemented in IPF WebService services? Can I directly
test them in SOAP UI software? I don't quite understand the entire
interaction process. Let me use the example of the ITI-18 transaction.

The first question is, for instance, if I have a web application where
I enter some data on a webpage and then fill this data into the model
provided by the IPF framework (QueryRegistry), can I simply use the
send() method?

The second question is about the recipient of the ITI-18 transaction.
Do I need to respond to the relevant requests and then return?

The third question is, after studying the XDS tutorial you provided, I
noticed that you store registration information and document
information in memory. Is it possible to modify this to persist in a
database? Do you have any reference materials?

On 1970年1月1日星期四 08:00, wrote:

> Hi BoVane Again: 1. The generated XML already includes all XML namespace definitions etc., and does not need to be modified. Even more, you as application developer do not need to work with XML at all, you need to create a POJO, either using ebXML JAXB classes or in the simplified data model provided by IPF, and IPF will do the rest. 2. Same for SOAP envelope: it is automatically created when you send a message, and automatically parsed when you receive a message. This is done by the Apache CXF framework which is used in IPF. Best regards Dmytro To view this discussion on the web visit https://groups.google.com/d/msgid/ipf-user/CAHh9K-nz%2BdMD-qiiADpK%3DNeoJpfR32RRwTmFcj5und9UAFQTTQ%40mail.gmail.com.

Dmytro Rud

unread,
Jan 26, 2024, 5:17:36 AM1/26/24
to ipf-...@googlegroups.com
Please see my responses inline.

Best regards
Dmytro


On Fri, Jan 26, 2024 at 10:18 AM bovane.ch <bova...@gmail.com> wrote:
Thank you very much for your explanation. I will take the time to
understand the logic behind it. By the way, are the XDS-related
transactions implemented in IPF WebService services?

Yes.  According to IHE specifications, all XDS.b transacions shall use Web Services (SOAP 1.2 with WS-Addressing), and IPF implements this.
 
Can I directly test them in SOAP UI software?

Yes.
 
I don't quite understand the entire
interaction process. Let me use the example of the ITI-18 transaction.

The first question is, for instance, if I have a web application where
I enter some data on a webpage and then fill this data into the model
provided by the IPF framework (QueryRegistry), can I simply use the
send() method?

send() method of which class?
 
The second question is about the recipient of the ITI-18 transaction.
Do I need to respond to the relevant requests and then return?

Yes, as Document Registry (the server of ITI-18 transactions), you have to create and return a proper response message.
 
The third question is, after studying the XDS tutorial you provided, I
noticed that you store registration information and document
information in memory. Is it possible to modify this to persist in a
database?

Yes.
 
Do you have any reference materials?

Unfortunately not.
 
On 1970年1月1日星期四 08:00,  wrote:

> Hi BoVane Again: 1. The generated XML already includes all XML namespace definitions etc., and does not need to be modified. Even more, you as application developer do not need to work with XML at all, you need to create a POJO, either using ebXML JAXB classes or in the simplified data model provided by IPF, and IPF will do the rest. 2. Same for SOAP envelope: it is automatically created when you send a message, and automatically parsed when you receive a message. This is done by the Apache CXF framework which is used in IPF. Best regards Dmytro To view this discussion on the web visit https://groups.google.com/d/msgid/ipf-user/CAHh9K-nz%2BdMD-qiiADpK%3DNeoJpfR32RRwTmFcj5und9UAFQTTQ%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "ipf-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ipf-user+u...@googlegroups.com.

文波

unread,
Jan 31, 2024, 4:15:21 AM1/31/24
to ipf-user
Hi Dmytro
I have now constructed a QueryRegistry object for the ITI-18 transaction. I want to send it to my server, but I don't know how to call the send method. I can't find the send method. I am using IPF framework version 3.6.5. Should I implement send() in pure Java? Is my IPF framework version incorrect? My Maven dependencies are as follows. And my codes are as follows

<!-- Camel BOM version=3.6.5 -->
<dependency>
<groupId>org.openehealth.ipf</groupId>
<artifactId>ipf-dependencies</artifactId>
<version>${ipf.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<dependency>
<groupId>org.openehealth.ipf.boot</groupId>
<artifactId>ipf-xds-spring-boot-starter</artifactId>
<version>${ipf.version}</version>
</dependency>

<dependency>
<groupId>org.openehealth.ipf.platform-camel</groupId>
<artifactId>ipf-platform-camel-ihe-mllp</artifactId>
<version>${ipf.version}</version>
</dependency>

<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.8</version>
</dependency>

public static void generateITI18QueryRequest(ITI18QueryDTO iti18QueryDTO) {
camelContext = new DefaultCamelContext();
camelContext.start();
FindDocumentsQuery query = new FindDocumentsQuery();
// setup patientId
query.setPatientId(new Identifiable(iti18QueryDTO.getPatientId(), new AssigningAuthority(iti18QueryDTO.getAuthorityOID())));
log.info(query.getPatientId().getId());
// setup status
List<AvailabilityStatus> statuses = CollUtil.newArrayList();
statuses.add(AvailabilityStatus.APPROVED);
query.setStatus(statuses);
QueryRegistry queryRegistry = new QueryRegistry(query);
queryRegistry.setReturnType(QueryReturnType.LEAF_CLASS)
;
// the send method error  ———— 
Cannot resolve method 'send' 
Response response = send(ITI18,queryRegistry, QueryResponse.class);


}

Dmytro Rud

unread,
Jan 31, 2024, 4:22:31 AM1/31/24
to ipf-...@googlegroups.com
Hi BoVane

It seems that what you need is to use the Camel producer template.  You may take a look at the method send() in the class org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer.  It is written in Groovy, but you can use Java instead.

Best regards
Dmytro


文波

unread,
Jan 31, 2024, 4:28:57 AM1/31/24
to ipf-user
Hi Dmytro
Can I directly call the send method defined in the class org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer in Java, instead of re-implementing the send method in Java language? In addition to the send method, are there any other ways in the IPF framework to send my QueryRegistry object to the server for the ITI-18 transaction?
Best regards
BoVane

Dmytro Rud

unread,
Jan 31, 2024, 4:32:38 AM1/31/24
to ipf-...@googlegroups.com
Yes, you can use the method send() as-is, but you will have to instantiate the StandardTestContainer for that.
Other way would be to write a Camel route and use the .to() statement there.

文波

unread,
Jan 31, 2024, 4:39:31 AM1/31/24
to ipf-user
In IPF version 3.6.5, does it support the StandardTestContainer class? My current JDK version is 1.8, but I can't find the StandardTestContainer class. Should I modify the IPF framework version, or should I modify the JDK version? Also, do you have a complete example of writing a Camel route and using the .to() statement there? Thank you very much for your help.

Dmytro Rud

unread,
Jan 31, 2024, 4:51:01 AM1/31/24
to ipf-...@googlegroups.com
StandardTestContainer is a very old IPF class, you will find it in the Maven artifact 

<groupId>org.openehealth.ipf.platform-camel</groupId>
<artifactId>ipf-platform-camel-ihe-ws</artifactId>
<type>test-jar</type>

And yes, there is a lot of sample Camel routes in IPF tutorials and unit tests.  For general Camel documentation, please visit https://camel.apache.org/manual/.


文波

unread,
Jan 31, 2024, 4:53:05 AM1/31/24
to ipf-user
I have a question now, which is how to instantiate the StandardTestContainer? When I directly use StandardTestContainer standardTestContainer = new StandardTestContainer();, it will throw an error Caused by: java.lang.ClassNotFoundException: org.openehealth.ipf.commons.ihe.ws.server.ServletServer. First, I start my spring boot project, including the routing and transaction processing. It's just this simple xds-springboot project at https://github.com/tjudycki/xds-example. Then I write the query request QueryRegistry for the ITI-18 transaction, and I want to send this QueryRegistry object to the endpoint provided in my xds-springboot project. But now, when I try to instantiate StandardTestContainer, it throws an error. In my situation, how should I correctly instantiate StandardTestContainer? Thanks again for your help.

文波

unread,
Jan 31, 2024, 4:58:16 AM1/31/24
to ipf-user
my codes are as follows
StandardTestContainer standardTestContainer = new StandardTestContainer();
Response response = (Response) standardTestContainer.send(ITI18,queryRegistry, QueryResponse.class);

Dmytro Rud

unread,
Jan 31, 2024, 5:00:55 AM1/31/24
to ipf-...@googlegroups.com
ServletServer is in the artifact 

<groupId>org.openehealth.ipf.commons</groupId>
<artifactId>ipf-commons-ihe-ws</artifactId>
<type>test-jar</type>

If the compiler will be unable to find some other classes, please look in IPF sources where they are.


文波

unread,
Jan 31, 2024, 5:11:08 AM1/31/24
to ipf-user
Hi Dmytro
I'm really sorry, I'm so unfamiliar with the code, could you help me take a look at my code? My code is as follows, and my error message is as follows, once again, thank you sincerely for your help.
Best Regards
BoVane

=====================codes as follows =====================
private static String ITI18 = "xds-iti18://localhost:8367/api/xds-iti18";
@SneakyThrows
public static void generateITI18QueryRequest(ITI18QueryDTO iti18QueryDTO) {
FindDocumentsQuery query = new FindDocumentsQuery();
// setup patientId
query.setPatientId(new Identifiable(iti18QueryDTO.getPatientId(), new AssigningAuthority(iti18QueryDTO.getAuthorityOID())));
log.info(query.getPatientId().getId());
// setup status
List<AvailabilityStatus> statuses = CollUtil.newArrayList();
statuses.add(AvailabilityStatus.APPROVED);
query.setStatus(statuses);
QueryRegistry queryRegistry = new QueryRegistry(query);
queryRegistry.setReturnType(QueryReturnType.LEAF_CLASS)
;
// How to fix it ?
StandardTestContainer standardTestContainer = new StandardTestContainer();
Response response = (Response) standardTestContainer.send(ITI18,queryRegistry, QueryResponse.class);
log.warn(response.toString());
}

================ the errors are as follows ====================

Exception in thread "main" groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method org.apache.camel.impl.DefaultExchange#<init>.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[interface org.apache.camel.Endpoint]
[interface org.apache.camel.CamelContext]
[interface org.apache.camel.Exchange]
at groovy.lang.MetaClassImpl.doChooseMostSpecificParams(MetaClassImpl.java:3385)
at groovy.lang.MetaClassImpl.chooseMostSpecificParams(MetaClassImpl.java:3361)
at groovy.lang.MetaClassImpl.chooseMethodInternal(MetaClassImpl.java:3351)
at groovy.lang.MetaClassImpl.chooseMethod(MetaClassImpl.java:3295)
at groovy.lang.MetaClassImpl.createConstructorSite(MetaClassImpl.java:3597)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallConstructorSite(CallSiteArray.java:85)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:277)
at org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer.send(StandardTestContainer.groovy:147)
at org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer$send.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:203)
at org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer.send(StandardTestContainer.groovy:132)
at org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer.send(StandardTestContainer.groovy)

at com.mediway.aggregation.ihe.xds.client.ITI18RequestResponse.generateITI18QueryRequest(ITI18RequestResponse.java:39)
at com.mediway.aggregation.ihe.xds.client.ITI18RequestResponse.main(ITI18RequestResponse.java:49)

Process finished with exit code 1

Dmytro Rud

unread,
Feb 1, 2024, 1:42:17 AM2/1/24
to ipf-...@googlegroups.com
Take a look at org.openehealth.ipf.tutorials.iheclient.IHEWebServiceClient.

Best regards
Dmytro

文波

unread,
Feb 1, 2024, 3:41:53 AM2/1/24
to ipf-user
Hi Dmytro
I have reviewed the code inside org.openehealth.ipf.tutorials.iheclient.IHEWebServiceClient, and now I want to do some testing work. My project is using Java version 11, and the IPF framework version is 4.8-m5. I have copied the Java file IHEWebServiceClient into my project, and then directly written a main test method inside the class. The code is provided at the end of this email. Next, I will describe my issue scenario. I have used two methods as an IHE client. The first method is using SOAP UI software to send a SOAP-formatted query string directly to the port http://localhost:8367/api/services/xds-iti18 for the ITI-18 transaction, and I can correctly retrieve the response in SOAP UI software. The second method as an IHE client is using the methods from org.openehealth.ipf.tutorials.iheclient.IHEWebServiceClient. However, I encountered an error as shown below. How should I modify my code? Thank you very much for your help.
Best regards
Bo

===================      my codes and errors are as follows    ======================================
public QueryResponse iti18StoredQuery(StoredQuery query, String host, int port, String pathAndParameters) throws Exception {
QueryRegistry storedQuery = new QueryRegistry(query);
// String endpoint = String.format("http://%s:%d/%s", host, port, pathAndParameters);
String endpoint = String.format("xds-iti18://%s:%d/%s", host, port, pathAndParameters);
log.warn(endpoint);
return send(endpoint, storedQuery, QueryResponse.class);
}


public static void
main(String[] args) throws Exception {
IHEWebServiceClient iheWebServiceClient = new IHEWebServiceClient();
// I don't know whether should I set the DefaultCamelContext
iheWebServiceClient.setCamelContext(new DefaultCamelContext());
// set up a query
FindDocumentsQuery query = new FindDocumentsQuery();
query.setPatientId(new Identifiable("st3498702", new AssigningAuthority("1.3.6.1.4.1.21367.2005.3.7")));
log.info(query.getPatientId().getId());
// setup status
List<AvailabilityStatus> statuses = CollUtil.newArrayList();
statuses.add(AvailabilityStatus.APPROVED);
query.setStatus(statuses);
// send the query to endpoints
QueryResponse queryResponse = iheWebServiceClient.iti18StoredQuery(query,"localhost",8367,"api/services/xds-iti18");
log.warn(queryResponse.toString());
}



16:21:34.110 [main] DEBUG org.apache.camel.support.DefaultComponent - Creating endpoint uri=[xds-iti18://localhost:8367/api/services/xds-iti18], path=[localhost:8367/api/services/xds-iti18]
Exception in thread "main" org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: xds-iti18://localhost:8367/api/services/xds-iti18 due to: Registry instance has not been set. Call ContextFacade.setRegistry or initialize a Spring Registry
at org.apache.camel.impl.engine.AbstractCamelContext.doGetEndpoint(AbstractCamelContext.java:1020)
at org.apache.camel.impl.engine.AbstractCamelContext.getEndpoint(AbstractCamelContext.java:902)
at org.apache.camel.impl.engine.DefaultProducerTemplate.resolveMandatoryEndpoint(DefaultProducerTemplate.java:573)
at org.apache.camel.impl.engine.DefaultProducerTemplate.send(DefaultProducerTemplate.java:130)
at com.mediway.aggregation.ihe.xds.client.IHEWebServiceClient.send(IHEWebServiceClient.java:149)
at com.mediway.aggregation.ihe.xds.client.IHEWebServiceClient.send(IHEWebServiceClient.java:136)
at com.mediway.aggregation.ihe.xds.client.IHEWebServiceClient.iti18StoredQuery(IHEWebServiceClient.java:75)
at com.mediway.aggregation.ihe.xds.client.IHEWebServiceClient.main(IHEWebServiceClient.java:168)
Caused by: java.lang.IllegalStateException: Registry instance has not been set. Call ContextFacade.setRegistry or initialize a Spring Registry
at org.openehealth.ipf.commons.core.config.ContextFacade.getInstance(ContextFacade.java:82)
at org.openehealth.ipf.commons.core.config.ContextFacade.getBeans(ContextFacade.java:61)
at org.openehealth.ipf.platform.camel.ihe.atna.util.AuditConfiguration.obtainAuditContext(AuditConfiguration.java:38)
at org.openehealth.ipf.platform.camel.ihe.ws.AbstractWsComponent.getAuditContext(AbstractWsComponent.java:74)
at org.openehealth.ipf.platform.camel.ihe.ws.AbstractWsEndpoint.<init>(AbstractWsEndpoint.java:138)
at org.openehealth.ipf.platform.camel.ihe.xds.XdsEndpoint.<init>(XdsEndpoint.java:40)
at org.openehealth.ipf.platform.camel.ihe.xds.iti18.Iti18Component$1.<init>(Iti18Component.java:47)
at org.openehealth.ipf.platform.camel.ihe.xds.iti18.Iti18Component.createEndpoint(Iti18Component.java:47)
at org.apache.camel.support.DefaultComponent.createEndpoint(DefaultComponent.java:171)
at org.apache.camel.impl.engine.AbstractCamelContext.doGetEndpoint(AbstractCamelContext.java:986)
... 7 more

Process finished with exit code 1

=================  Another client using SOAP UI  ===================

截屏2024-02-01 16.27.39.png截屏2024-02-01 16.36.19.png

Dmytro Rud

unread,
Feb 1, 2024, 3:48:02 AM2/1/24
to ipf-...@googlegroups.com
The hint is in the error message: Call ContextFacade.setRegistry or initialize a Spring Registry

文波

unread,
Feb 1, 2024, 3:53:48 AM2/1/24
to ipf-user
I know the error hints but I don't know how to fix it, I'm sorry for knowing little about it 😭 Is there any reference ?

文波

unread,
Feb 1, 2024, 8:58:50 PM2/1/24
to ipf-user
Hi Dmytro
I would like to ask some questions about ipf-tutorials-iheclient in the IPF framework. I have reviewed the code in the IPF framework and conducted tests. Now I want to send requests such as ITI-18, ITI-41, etc. through the ihe-client. However, during this process, I encountered an error: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: xds-iti18://localhost:8367/api/services/xds-iti18 due to: Registry instance has not been set. Call ContextFacade.setRegistry or initialize a Spring Registry. I don't have much knowledge about Spring Registry and ContextFacade, so how should I modify my client code? I don't know where to start, and I hope you can help me. Additionally, I'm not sure whether I should learn Groovy in order to understand the code inside ipf-tutorials-xds in the IPF framework, or if I should rewrite the Groovy code in ipf-tutorials-xds to pure Java code. I'm not sure which approach would be more costly. Which approach do you think is better? I'm very confused,Thank you very much for your help.
Best regards
Bo

Dmytro Rud

unread,
Feb 1, 2024, 11:53:47 PM2/1/24
to ipf-...@googlegroups.com
Hello Bo

1. On the initialization of Spring stuff etc.: Try the following code (untested):

        // initialization of the application -- should be executed only once
        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("context.xml");
        CamelContext camelContext = appContext.getBean(CamelContext.class);
        ProducerTemplate producerTemplate = appContext.getBean(ProducerTemplate.class);

        // for each call 
        Exchange exchange = new DefaultExchange(camelContext);
        exchange.setPattern(ExchangePattern.InOut);
        exchange.getIn().setBody(request);   // "request" is what you created
        exchange = producerTemplate.send(endpointUrl, exchange);    
        Exception exception = Exchanges.extractException(exchange);
        if (exception != null) {
            throw exception;
        }
        ${ResponseClassName} response = exchange.getMessage().getMandatoryBody(${ResponseClassName}.class);    

I attach the file "context.xml" to this message -- hope Google Groups will not cut it.

2. You would need to learn Groovy in the both cases -- both to understand the present code and to rewrite it.

Best regards
Dmytro


context.xml

文波

unread,
Feb 2, 2024, 1:49:03 AM2/2/24
to ipf-user
Hello Dmytro
I am very excited that your code is running. Without your help, I would have been at a loss. I can now send ITI-18 transaction query messages normally. Does this code template comply with all the requirements for sending messages as an IHE client? Additionally, for roles like Document Registry and Document Repository, can I integrate them with the server and database, for example, storing original data and document content in the database? When there is a query request, I can retrieve the corresponding information from the database and return it. Furthermore, I will follow your advice and learn the relevant Groovy language to understand the tutorial code in IPF. I'm really grateful for your help. If I have more questions, I will come back to you. I wish you good health and all the best.
Best regards
Bo

Dmytro Rud

unread,
Feb 2, 2024, 3:08:20 AM2/2/24
to ipf-...@googlegroups.com
1. Yes, the code will send IHE-compliant SOAP calls.  For compliance with the IHE ATNA profile (audit trail), you have to add Audit Record Repository parameters to the bean "auditContext" in context.xml.
2. Yes, Document Registries and Repositories are supposed to persist their data.  As already mentioned, there is no universal recipe for that -- some implementers may map ebXML data structures to a relational DB schema, some others may use NoSQL, etc.  But for participation on a Connectathon, an in-memory storage may be sufficient.

Best regards
Dmytro


文波

unread,
Feb 5, 2024, 3:57:56 AM2/5/24
to ipf-user
Hi Dmytro
I encountered some problems while studying the code in ipf-tutorials-xds in the IPF framework. My JDK version is 11, and the IPF framework version is 4.8-m5. First, I started the tomcat server inside Server.groovy without any errors. Next, I ran the test cases inside TestRepositoryAndRegistry.groovy, and all the test cases passed. Then I changed my testing strategy, and I wanted to perform the testing using pure Java as the client. Therefore, I used the IHEWebServiceClient code from the ipf-tutorials-iheclient module and wrote the Provide code for the ITI-41 transaction. I found that I was able to successfully send the data of ProvideAndRegisterDocumentSet to the xds-iti41 route, and I could see the printout in the Server's console, but then I encountered an error. The error occurred after storing document: 4.3.2.1 in DataStore, when it needed to transform to RegisterDocumentSetRequest and send to the ITI-42 endpoint: xds-iti42://localhost:0/xds-iti42. The specific error message was org.apache.cxf.interceptor.Fault: Could not send Message. Caused by: java.net.ConnectException: Can't assign requested address. I suspect that the problem lies in sending RegisterDocumentSetRequest to the ITI-42 endpoint: xds-iti42://localhost:0/xds-iti42 with incorrect port information. How should I modify it? I have already tried changing the xds-iti41:xds-iti41 terminal ${header.port} in Iti4142RouteBuilder to a specific port like 9091, but I still encountered an error. What should I do to modify the code? Thank you very much for your help.
Best regards
Bo
======     The server console error log are as follows       ========

16:05:28.580 [http-nio-9091-exec-7] INFO org.openehealth.ipf.tutorials.xds.Iti4142RouteBuilder - received iti41: ProvideAndRegisterDocumentSet(submissionSet=SubmissionSet(super=XDSMetaClass(availabilityStatus=APPROVED, comments=LocalizedString(lang=en-US, charset=UTF-8, value=comments1), entryUuid=submissionSet01, patientId=Identifiable(id=50f09e9e-095c-4a97-baea-754c8099c410, assigningAuthority=AssigningAuthority(universalId=1.3, universalIdType=ISO)), title=LocalizedString(lang=en-US, charset=UTF-8, value=Submission Set 01), uniqueId=1.123, homeCommunityId=urn:oid:1.2.3.4.5.6.2333.23, logicalUuid=null, version=null, limitedMetadata=false, extraMetadata=null, extraClassifications=null), authors=[Author(authorPerson=Person(id=Identifiable(id=id1, assigningAuthority=AssigningAuthority(universalId=1.1, universalIdType=ISO)), name=XcnName(super=Name(familyName=Otto, givenName=null, secondAndFurtherGivenNames=null, suffix=null, prefix=null, degree=null))), authorInstitution=[], authorRole=[], authorSpecialty=[], authorTelecom=[])], contentTypeCode=Code(code=code1, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code1), schemeName=scheme1), intendedRecipients=[Recipient(person=null, organization=Organization(assigningAuthority=null, organizationName=org, idNumber=null), telecom=null)], sourceId=1.2.3, submissionTime=Timestamp(dateTime=1980-01-01T00:00Z[UTC], precision=YEAR)), folders=[Folder(super=XDSMetaClass(availabilityStatus=APPROVED, comments=LocalizedString(lang=en-US, charset=UTF-8, value=comments3), entryUuid=folder01, patientId=Identifiable(id=50f09e9e-095c-4a97-baea-754c8099c410, assigningAuthority=AssigningAuthority(universalId=1.3, universalIdType=ISO)), title=LocalizedString(lang=en-US, charset=UTF-8, value=Folder 01), uniqueId=1.48574589, homeCommunityId=null, logicalUuid=null, version=null, limitedMetadata=false, extraMetadata=null, extraClassifications=null), codeList=[Code(code=code7, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code7), schemeName=scheme7)], lastUpdateTime=Timestamp(dateTime=1982-09-10T12:13:15Z[UTC], precision=SECOND))], documents=[Document(documentEntry=DocumentEntry(super=XDSMetaClass(availabilityStatus=APPROVED, comments=LocalizedString(lang=en-US, charset=UTF-8, value=comment2), entryUuid=document01, patientId=Identifiable(id=50f09e9e-095c-4a97-baea-754c8099c410, assigningAuthority=AssigningAuthority(universalId=1.3, universalIdType=ISO)), title=LocalizedString(lang=en-US, charset=UTF-8, value=Document 01), uniqueId=4.3.2.1, homeCommunityId=null, logicalUuid=null, version=null, limitedMetadata=false, extraMetadata={urn:abc=[ddd]}, extraClassifications=null), authors=[Author(authorPerson=Person(id=Identifiable(id=id2, assigningAuthority=AssigningAuthority(universalId=1.2, universalIdType=ISO)), name=XcnName(super=Name(familyName=Norbi, givenName=null, secondAndFurtherGivenNames=null, suffix=null, prefix=null, degree=null))), authorInstitution=[Organization(assigningAuthority=null, organizationName=authorOrg, idNumber=null)], authorRole=[Identifiable(id=role1, assigningAuthority=AssigningAuthority(universalId=1.2.3.1, universalIdType=ISO)), Identifiable(id=role2, assigningAuthority=null)], authorSpecialty=[Identifiable(id=spec1, assigningAuthority=AssigningAuthority(universalId=1.2.3.3, universalIdType=ISO)), Identifiable(id=spec2, assigningAuthority=null)], authorTelecom=[Telecom(use=NET, type=Internet, email=aut...@acme.org, countryCode=null, areaCityCode=null, localNumber=null, extension=null, unformattedPhoneNumber=null), Telecom(use=NET, type=Internet, email=aut...@acme.org, countryCode=null, areaCityCode=null, localNumber=null, extension=null, unformattedPhoneNumber=null)])], classCode=Code(code=code2, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code2), schemeName=scheme2), confidentialityCodes=[Code(code=code8, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code8), schemeName=scheme8)], creationTime=Timestamp(dateTime=1981-01-01T00:00Z[UTC], precision=YEAR), eventCodeList=[Code(code=code9, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code9), schemeName=scheme9)], formatCode=Code(code=code3, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code3), schemeName=scheme3), hash=d05bbfd1a09a6637607553041af284817ace6560, healthcareFacilityTypeCode=Code(code=code4, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code4), schemeName=scheme4), languageCode=en-US, legalAuthenticator=Person(id=Identifiable(id=legal, assigningAuthority=AssigningAuthority(universalId=1.7, universalIdType=ISO)), name=XcnName(super=Name(familyName=Gustav, givenName=null, secondAndFurtherGivenNames=null, suffix=null, prefix=null, degree=null))), mimeType=application/octet-stream, practiceSettingCode=Code(code=code5, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code5), schemeName=scheme5), serviceStartTime=Timestamp(dateTime=1980-12-01T00:00Z[UTC], precision=MONTH), serviceStopTime=Timestamp(dateTime=1981-01-01T00:00Z[UTC], precision=MONTH), size=70000, sourcePatientId=Identifiable(id=source, assigningAuthority=AssigningAuthority(universalId=4.1, universalIdType=ISO)), sourcePatientInfo=PatientInfo(ids=[], names=[XpnName(super=Name(familyName=Susi, givenName=null, secondAndFurtherGivenNames=null, suffix=null, prefix=null, degree=null))], birthDate=Timestamp(dateTime=1980-01-01T00:00Z[UTC], precision=YEAR), gender=M, addresses=[Address(streetAddress=hier, otherDesignation=null, city=null, stateOrProvince=null, zipOrPostalCode=null, country=null, countyParishCode=null)]), typeCode=Code(code=code6, displayName=LocalizedString(lang=en-US, charset=UTF-8, value=code6), schemeName=scheme6), uri=http://hierunten.com, repositoryUniqueId=1.2.3.4, type=STABLE, referenceIdList=[ReferenceId(id=ref-id-1, assigningAuthority=CXiAssigningAuthority(super=AssigningAuthority(universalId=1.1.2.3, universalIdType=ISO)namespaceId=ABCD), idTypeCode=urn:ihe:iti:xds:2013:order), ReferenceId(id=ref-id-2, assigningAuthority=CXiAssigningAuthority(super=AssigningAuthority(universalId=2.1.2.3, universalIdType=ISO)namespaceId=DEFG), idTypeCode=vendor-defined)], documentAvailability=null))], associations=[Association(targetUuid=document01, sourceUuid=submissionSet01, associationType=HAS_MEMBER, label=ORIGINAL, entryUuid=docAss, docCode=null, previousVersion=111, originalStatus=null, newStatus=null, associationPropagation=null, availabilityStatus=null, extraMetadata=null), Association(targetUuid=folder01, sourceUuid=submissionSet01, associationType=HAS_MEMBER, label=null, entryUuid=folderAss, docCode=null, previousVersion=110, originalStatus=null, newStatus=null, associationPropagation=null, availabilityStatus=null, extraMetadata=null), Association(targetUuid=document01, sourceUuid=folder01, associationType=HAS_MEMBER, label=null, entryUuid=docFolderAss, docCode=null, previousVersion=null, originalStatus=null, newStatus=null, associationPropagation=null, availabilityStatus=null, extraMetadata=null)], targetHomeCommunityId=urn:oid:1.2.3.4.5.6.2333.23)
16:05:28.584 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendProcessor - >>>> direct://makeDocsReReadable Exchange[]
16:05:28.584 [http-nio-9091-exec-7] DEBUG org.openehealth.ipf.commons.core.ContentMap - Return existing content of type class javax.activation.DataHandler
16:05:28.585 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendProcessor - >>>> direct://checkForAssociationToDeprecatedObject Exchange[928BE8CD423B9C7-0000000000000002]
16:05:28.586 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendProcessor - >>>> direct://checkPatientIds Exchange[928BE8CD423B9C7-0000000000000002]
16:05:28.586 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.FilterProcessor - Filter matches: false for exchange: Exchange[928BE8CD423B9C7-0000000000000002]
16:05:28.587 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendProcessor - >>>> direct://checkHashAndSize Exchange[928BE8CD423B9C7-0000000000000002]
16:05:28.588 [http-nio-9091-exec-7] DEBUG org.openehealth.ipf.commons.core.ContentMap - Return existing content of type class javax.activation.DataHandler
16:05:28.588 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.FilterProcessor - Filter matches: false for exchange: Exchange[]
16:05:28.588 [http-nio-9091-exec-7] DEBUG org.openehealth.ipf.commons.core.ContentMap - Return existing content of type class javax.activation.DataHandler
16:05:28.589 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.FilterProcessor - Filter matches: false for exchange: Exchange[]
16:05:28.589 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendProcessor - >>>> direct://storeDocs Exchange[928BE8CD423B9C7-0000000000000002]
16:05:28.589 [http-nio-9091-exec-7] DEBUG org.openehealth.ipf.commons.core.ContentMap - Return existing content of type class javax.activation.DataHandler
16:05:28.589 [http-nio-9091-exec-7] INFO org.openehealth.ipf.tutorials.xds.DataStore - Stored document: 4.3.2.1
16:05:28.589 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendProcessor - >>>> direct://updateDocEntriesFromProvide Exchange[928BE8CD423B9C7-0000000000000002]
16:05:28.590 [http-nio-9091-exec-7] DEBUG org.openehealth.ipf.commons.core.ContentMap - Return existing content of type class javax.activation.DataHandler
16:05:28.591 [http-nio-9091-exec-7] INFO route1 - Transform to RegisterDocumentSetRequest
16:05:28.591 [http-nio-9091-exec-7] INFO route1 - Send to ITI-42 endpoint: xds-iti42://localhost:0/xds-iti42

16:05:28.592 [http-nio-9091-exec-7] DEBUG org.apache.camel.processor.SendDynamicProcessor - >>>> xds-iti42://localhost:0/xds-iti42 Exchange[928BE8CD423B9C7-0000000000000002]

org.apache.cxf.interceptor.Fault: Could not send Message.
Caused by: java.net.ConnectException: Can't assign requested address

==========  My test codes are as follows ===============
// initialization of the application -- should be executed only once
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("context-xds.xml");
CamelContext camelContext = appContext.getBean(CamelContext.class);

// set up CamelContext
IHEWebServiceClient iheWebServiceClient = new IHEWebServiceClient();
iheWebServiceClient.setCamelContext(camelContext);
// generate documentEntry
ProvideAndRegisterDocumentSet provide = SampleData.createProvideAndRegisterDocumentSet();
DocumentEntry documentEntry = provide.getDocuments().get(0).getDocumentEntry();
Identifiable patientId = documentEntry.getPatientId();
HashMap<StringList<String>extra = new HashMap<>();
extra.put("urn:abc"CollUtil.newArrayList("ddd"));
documentEntry.setExtraMetadata(extra);
patientId.setId(UUID.randomUUID().toString());
documentEntry.setUniqueId("4.3.2.1");
log.info(provide.getDocuments().get(0).getContent(DataHandler.class).toString());
log.info("xxxl");
documentEntry.setHash(String.valueOf(ContentUtils.sha1(provide.getDocuments().get(0).getContent(DataHandler.class))));
documentEntry.setSize(Long.valueOf(String.valueOf(ContentUtils.size(provide.getDocuments().get(0).getContent(DataHandler.class)))));
log.warn(documentEntry.getSize().toString());
provide.getDocuments().get(0).setDocumentEntry(documentEntry);
// Response response = iheWebServiceClient.iti41ProvideAndRegister(provide,"localhost",8367, "api/services/xds-iti18");
Response response = iheWebServiceClient.iti41ProvideAndRegister(provide,"localhost",9091"xds-iti41");
log.warn(response.toString());
截屏2024-02-04 16.43.06.png


I modify getPort()  in Iti4142RouteBuilder  to spectify port 9091,then It works, But appears another problem. I found that simply changing the port does not solve my problem. Even when I modified the getPort() method inside Iti4142RouteBuilder to 9091, it still didn't work. After providing and registering the documents, I couldn't find any document information, and a major reason for this is the incorrect port information. I checked the log printouts in the console, and the port for the terminal services is all 0. How should I modify the code for IHEWebServiceClient? (The code is in my initial question.) When I ran the tests inside TestRepositoryAndRegistry.groovy, I observed the printouts in the console, and I found that the port information is constantly changing, not a fixed value. Please help me, as I really don't know what to do. Thank you very much.🙏🙏
Reply all
Reply to author
Forward
0 new messages