Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve mapping between XDS XON and FHIR Organization #166

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Unreleased

- Fixed an NPE in the assertion route
- Improved mapping between XDS XON and FHIR Organization [165](https://github.com/i4mi/MobileAccessGateway/issues/165)

## 2024/05/15 v070
- support for multiple IDP's [128](https://github.com/i4mi/MobileAccessGateway/issues/128)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
import ch.bfh.ti.i4mi.mag.Config;
import ch.bfh.ti.i4mi.mag.pmir.PatientReferenceCreator;

import static ch.bfh.ti.i4mi.mag.mhd.Utils.isUnprefixedOid;
import static ch.bfh.ti.i4mi.mag.mhd.Utils.isUnprefixedUuid;

/**
* base query response converter XDS to MHD
* @author alexander kreutz
Expand Down Expand Up @@ -236,21 +239,35 @@ public Patient transformPatient(Person person) {
}

/**
* XDS Organization -> FHIR Organization
* IPF Organization (XDS XON) -> FHIR Organization
* @param org
* @return
*/
public Organization transform(org.openehealth.ipf.commons.ihe.xds.core.metadata.Organization org) {
if (org == null) return null;
Organization result = new Organization();
if (org == null) {
return null;
}
final var result = new Organization();
result.setName(org.getOrganizationName());
String id = org.getIdNumber();
// TODO handle system not given
String id = org.getIdNumber();
if (isUnprefixedOid(id)) {
id = "urn:oid:" + id;
} else if (isUnprefixedUuid(id)) {
id = "urn:uuid:" + id;
}

if (org.getAssigningAuthority()!=null) {
String system = org.getAssigningAuthority().getUniversalId();
result.addIdentifier().setSystem("urn:oid:"+system).setValue(id);
} else result.addIdentifier().setValue(id);
if (org.getAssigningAuthority() != null) {
String system = org.getAssigningAuthority().getUniversalId();
if (isUnprefixedOid(system)) {
system = "urn:oid:" + system;
}
result.addIdentifier().setSystem(system).setValue(id);
} else {
final var identifier = result.addIdentifier().setValue(id);
if (id.startsWith("urn:")) {
identifier.setSystem("urn:ietf:rfc:3986");
}
}
return result;
}

Expand Down
48 changes: 13 additions & 35 deletions src/main/java/ch/bfh/ti/i4mi/mag/mhd/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,15 @@
* limitations under the License.
*/

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.camel.Body;
import org.apache.camel.Headers;
import org.apache.camel.Processor;
import org.apache.camel.http.common.HttpMessage;
import org.hl7.fhir.r4.model.Patient;
import org.openehealth.ipf.commons.ihe.fhir.Constants;
import org.openehealth.ipf.commons.ihe.fhir.FhirSearchParameters;
import org.openehealth.ipf.commons.ihe.fhir.iti66.Iti66SearchParameters;
import org.openehealth.ipf.commons.ihe.fhir.iti67.Iti67SearchParameters;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.RetrieveDocumentSetResponseType;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.RetrieveDocumentSetResponseType.DocumentResponse;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.AssigningAuthority;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.AvailabilityStatus;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.Code;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.DocumentEntry;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.Identifiable;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.ReferenceId;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.Timestamp;
import org.openehealth.ipf.commons.ihe.xds.core.requests.QueryRegistry;
import org.openehealth.ipf.commons.ihe.xds.core.requests.RetrieveDocumentSet;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindDocumentsByReferenceIdQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindDocumentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindSubmissionSetsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.QueryList;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.QueryReturnType;
import org.openehealth.ipf.commons.ihe.xds.core.responses.RetrievedDocumentSet;

import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ch.bfh.ti.i4mi.mag.Config;

/**
* utility classes for Mobile Access Gateway
Expand All @@ -65,7 +32,10 @@
*/
public class Utils {

public static final String KEPT_BODY = "KeptBody";
public static final String KEPT_BODY = "KeptBody";

public static final Pattern UNPREFIXED_OID_PATTERN = Pattern.compile("\\d+(\\.\\d+)+");
public static final Pattern UNPREFIXED_UUID_PATTERN = Pattern.compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}");

public static FhirSearchParameters searchParameterToBody(@Headers Map<String, Object> parameters) {
FhirSearchParameters searchParameter = (FhirSearchParameters) parameters
Expand Down Expand Up @@ -141,4 +111,12 @@ public static Processor retrievedDocumentSetToHttResponse() {
};
}
*/

public static boolean isUnprefixedOid(final String oid) {
return oid != null && UNPREFIXED_OID_PATTERN.matcher(oid).matches();
}

public static boolean isUnprefixedUuid(final String uuid) {
return uuid != null && UNPREFIXED_UUID_PATTERN.matcher(uuid).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1000,20 +1000,30 @@ public Telecom transform(ContactPoint contactPoint) {
}

/**
* FHIR Organization -> XDS Organization
* FHIR Organization -> IPF Organization (XDS XON)
* @param org
* @return
*/
public org.openehealth.ipf.commons.ihe.xds.core.metadata.Organization transform(Organization org) {
org.openehealth.ipf.commons.ihe.xds.core.metadata.Organization result = new org.openehealth.ipf.commons.ihe.xds.core.metadata.Organization();
final var result = new org.openehealth.ipf.commons.ihe.xds.core.metadata.Organization();
result.setOrganizationName(org.getName());
Identifier identifier = org.getIdentifierFirstRep();
if (identifier != null) {
result.setIdNumber(identifier.getValue());
result.setAssigningAuthority(new AssigningAuthority(noPrefix(identifier.getSystem())));
}
return result;
}
final Identifier identifier = org.getIdentifierFirstRep();
if (identifier != null && identifier.hasValue()) {
if (identifier.hasSystem()) {
Copy link
Contributor

@unixoid unixoid Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proposal: change line 1011 to if ((identifier != null) && identifier.hasValue()) {, change line 1021 to simply } else {.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

if (identifier.getSystem().equals("urn:ietf:rfc:3986")) {
// The value is a URI, remove the prefix and ignore the system
result.setIdNumber(noPrefix(identifier.getValue()));
} else {
// The value is an identifier, use the system as assigning authority
result.setIdNumber(identifier.getValue());
result.setAssigningAuthority(new AssigningAuthority(noPrefix(identifier.getSystem())));
}
} else {
result.setIdNumber(identifier.getValue());
}
}
return result;
}

/**
* FHIR Reference to Author -> XDS Author
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ch.bfh.ti.i4mi.mag.mhd;

import ch.bfh.ti.i4mi.mag.Config;
import ch.bfh.ti.i4mi.mag.mhd.iti67.Iti67ResponseConverter;
import org.junit.jupiter.api.Test;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.Hl7v2Based;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.Organization;

import static org.junit.jupiter.api.Assertions.*;

/**
* Tests for {@link BaseQueryResponseConverter}.
*
* @author Quentin Ligier
**/
class BaseQueryResponseConverterTest {

@Test
void testTransformOrganization() {
final var converter = new Iti67ResponseConverter(new Config());

var fhirOrg = converter.transform(Hl7v2Based.parse("Test^^^^^^^^^1234", Organization.class));
assertEquals("Test", fhirOrg.getName());
assertEquals(1, fhirOrg.getIdentifier().size());
assertEquals("1234", fhirOrg.getIdentifierFirstRep().getValue());
assertFalse(fhirOrg.getIdentifierFirstRep().hasSystem());

fhirOrg = converter.transform(Hl7v2Based.parse("Test^^^^^&1.2.3&ISO^^^^1234", Organization.class));
assertEquals("Test", fhirOrg.getName());
assertEquals(1, fhirOrg.getIdentifier().size());
assertEquals("1234", fhirOrg.getIdentifierFirstRep().getValue());
assertEquals("urn:oid:1.2.3", fhirOrg.getIdentifierFirstRep().getSystem());

fhirOrg = converter.transform(Hl7v2Based.parse("Test^^^^^^^^^1.2.3", Organization.class));
assertEquals("Test", fhirOrg.getName());
assertEquals(1, fhirOrg.getIdentifier().size());
assertEquals("urn:oid:1.2.3", fhirOrg.getIdentifierFirstRep().getValue());
assertEquals("urn:ietf:rfc:3986", fhirOrg.getIdentifierFirstRep().getSystem());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ch.bfh.ti.i4mi.mag.mhd.iti65;

import org.hl7.fhir.r4.model.Organization;
import org.junit.jupiter.api.Test;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.Hl7v2Based;

import static org.junit.jupiter.api.Assertions.*;

/**
* Tests for {@link Iti65RequestConverter}.
*
* @author Quentin Ligier
**/
class Iti65RequestConverterTest {

@Test
void testTransformOrganization() {
final var iti65RequestConverter = new Iti65RequestConverter();

final var org = new Organization();
org.setName("Test");
org.addIdentifier().setValue("1234");

var xon = iti65RequestConverter.transform(org);
assertEquals("Test^^^^^^^^^1234", Hl7v2Based.render(xon));

org.getIdentifierFirstRep().setSystem("urn:oid:1.2.3");
xon = iti65RequestConverter.transform(org);
assertEquals("Test^^^^^&1.2.3&ISO^^^^1234", Hl7v2Based.render(xon));

org.getIdentifierFirstRep().setValue("urn:oid:1.2.3").setSystem("urn:ietf:rfc:3986");
xon = iti65RequestConverter.transform(org);
assertEquals("Test^^^^^^^^^1.2.3", Hl7v2Based.render(xon));
}
}
Loading