From d82cf687f78865bc9a0f309d7e40f53c948c20ba Mon Sep 17 00:00:00 2001 From: Thomas Papke Date: Mon, 18 Oct 2021 20:56:53 +0200 Subject: [PATCH] #365 XDS ExtraMetadata slots might get duplicated if SubmitObjectsRequest's are unmarshalled and marshalled on the same instance * Fix extra metadata slot duplication --- .../ihe/xds/core/XdsJaxbDataBinding.java | 2 + .../transform/ebxml/Ebrs30MarshalingTest.java | 60 +++-- ...mitObjectsRequest_ebrs3_extra_metadata.xml | 244 ++++++++++++++++++ 3 files changed, 286 insertions(+), 20 deletions(-) create mode 100644 commons/ihe/xds/src/test/resources/SubmitObjectsRequest_ebrs3_extra_metadata.xml diff --git a/commons/ihe/xds/src/main/java/org/openehealth/ipf/commons/ihe/xds/core/XdsJaxbDataBinding.java b/commons/ihe/xds/src/main/java/org/openehealth/ipf/commons/ihe/xds/core/XdsJaxbDataBinding.java index 14df8e3513..d168ffbadf 100644 --- a/commons/ihe/xds/src/main/java/org/openehealth/ipf/commons/ihe/xds/core/XdsJaxbDataBinding.java +++ b/commons/ihe/xds/src/main/java/org/openehealth/ipf/commons/ihe/xds/core/XdsJaxbDataBinding.java @@ -122,6 +122,8 @@ public void beforeMarshal(Object source) { private static void injectExtraMetadata(List slots, ExtraMetadataHolder holder) { if (holder.getExtraMetadata() != null) { + slots.removeIf(slot -> isExtraMetadataSlotName(slot.getName()) + && holder.getExtraMetadata().containsKey(slot.getName())); holder.getExtraMetadata().entrySet().stream() .filter(entry -> isExtraMetadataSlotName(entry.getKey())) .forEach(entry -> { diff --git a/commons/ihe/xds/src/test/java/org/openehealth/ipf/commons/ihe/xds/core/transform/ebxml/Ebrs30MarshalingTest.java b/commons/ihe/xds/src/test/java/org/openehealth/ipf/commons/ihe/xds/core/transform/ebxml/Ebrs30MarshalingTest.java index 8a1fcda49d..c114475dde 100644 --- a/commons/ihe/xds/src/test/java/org/openehealth/ipf/commons/ihe/xds/core/transform/ebxml/Ebrs30MarshalingTest.java +++ b/commons/ihe/xds/src/test/java/org/openehealth/ipf/commons/ihe/xds/core/transform/ebxml/Ebrs30MarshalingTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.openehealth.ipf.commons.ihe.xds.core.XdsJaxbDataBinding; import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLExtrinsicObject; import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLObjectLibrary; import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.EbXMLAdhocQueryRequest30; @@ -29,21 +30,26 @@ import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.lcm.SubmitObjectsRequest; import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.query.AdhocQueryRequest; import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rim.ExtrinsicObjectType; -import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rim.IdentifiableType; +import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rim.ObjectFactory; import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rim.RegistryObjectListType; import org.openehealth.ipf.commons.ihe.xds.core.transform.requests.QueryParameter; import org.openehealth.ipf.commons.ihe.xds.core.transform.requests.RegisterDocumentSetTransformer; import org.openehealth.ipf.commons.ihe.xds.core.transform.requests.query.QuerySlotHelper; import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; -import javax.xml.namespace.QName; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.StringReader; +import java.io.StringWriter; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * Tests for marshaling objects created with our ebxml 2.1 classes. @@ -54,14 +60,13 @@ public class Ebrs30MarshalingTest { private EbXMLExtrinsicObject docEntry; private EbXMLFactory30 factory; private EbXMLObjectLibrary objectLibrary; - - private static final QName EXTRINSIC_OBJECT_QNAME = - new QName("urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0", "ExtrinsicObject", "rim"); + private JAXBContext context; @BeforeEach - public void setUp() { + public void setUp() throws JAXBException { factory = new EbXMLFactory30(); objectLibrary = factory.createObjectLibrary(); + context = JAXBContext.newInstance("org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs"); request = new SubmitObjectsRequest(); var objListElement = new RegistryObjectListType(); @@ -70,12 +75,7 @@ public void setUp() { docEntry = factory.createExtrinsic("Document01", objectLibrary); docEntry.setObjectType(DocumentEntryType.STABLE.getUuid()); - objList.add(getJaxbElement(EXTRINSIC_OBJECT_QNAME, ((EbXMLExtrinsicObject30)docEntry).getInternal())); - } - - @SuppressWarnings("unchecked") - private static JAXBElement getJaxbElement(QName qname, IdentifiableType object) { - return new JAXBElement<>(qname, (Class)object.getClass(), object); + objList.add(new ObjectFactory().createExtrinsicObject(((EbXMLExtrinsicObject30)docEntry).getInternal())); } @Test @@ -131,8 +131,7 @@ public void testAddSlot() throws Exception { @Test public void testFromRealEbXML() throws Exception { var file = new File(getClass().getClassLoader().getResource("SubmitObjectsRequest_ebrs30.xml").toURI()); - - var context = JAXBContext.newInstance("org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs"); + var unmarshaller = context.createUnmarshaller(); var unmarshalled = unmarshaller.unmarshal(file); @@ -158,8 +157,6 @@ public void testFromRealEbXML() throws Exception { @Test public void testPatientIdSlotRegexp() throws Exception { var file = new File(getClass().getClassLoader().getResource("iti18request.xml").toURI()); - - var context = JAXBContext.newInstance("org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs"); var unmarshaller = context.createUnmarshaller(); var unmarshalled = unmarshaller.unmarshal(file); @@ -174,7 +171,6 @@ public void testPatientIdSlotRegexp() throws Exception { public void testPatientIdMPQSlotRegexp() throws Exception { var file = new File(getClass().getClassLoader().getResource("iti51request.xml").toURI()); - var context = JAXBContext.newInstance("org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs"); var unmarshaller = context.createUnmarshaller(); var unmarshalled = unmarshaller.unmarshal(file); @@ -184,9 +180,33 @@ public void testPatientIdMPQSlotRegexp() throws Exception { var patientIdList = slotHelper.toStringList(QueryParameter.DOC_ENTRY_PATIENT_ID); assertEquals(2, patientIdList.size()); } + + @Test + public void verifyExtraMetadataWithJaxbBinding() throws Exception { + var file = new File( + getClass().getClassLoader().getResource("SubmitObjectsRequest_ebrs3_extra_metadata.xml").toURI()); + var unmarshaller = context.createUnmarshaller(); + unmarshaller.setListener(new XdsJaxbDataBinding().getUnmarshallerListener()); + + var unmarshalled = unmarshaller.unmarshal(file); + var original = (SubmitObjectsRequest) unmarshalled; + int numberOfSlotsInFirstDoc = new EbXMLSubmitObjectsRequest30(original).getExtrinsicObjects().get(0).getSlots() + .size(); + + var marshaller = context.createMarshaller(); + marshaller.setListener(new XdsJaxbDataBinding().getMarshallerListener()); + StringWriter writer = new StringWriter(); + marshaller.marshal(original, writer); + + var unmarshalledSecond = (SubmitObjectsRequest) unmarshaller.unmarshal(new StringReader(writer.toString())); + int numberOfSlotsInSecondDoc = new EbXMLSubmitObjectsRequest30(unmarshalledSecond).getExtrinsicObjects().get(0) + .getSlots().size(); + + assertEquals(numberOfSlotsInFirstDoc, numberOfSlotsInSecondDoc, + "Number of slots after Marshalling and Unmarsshalling does not match"); + } private SubmitObjectsRequest send() throws JAXBException { - var context = JAXBContext.newInstance("org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs"); var marshaller = context.createMarshaller(); var unmarshaller = context.createUnmarshaller(); var outputStream = new ByteArrayOutputStream(); diff --git a/commons/ihe/xds/src/test/resources/SubmitObjectsRequest_ebrs3_extra_metadata.xml b/commons/ihe/xds/src/test/resources/SubmitObjectsRequest_ebrs3_extra_metadata.xml new file mode 100644 index 0000000000..8e8dbd46a1 --- /dev/null +++ b/commons/ihe/xds/src/test/resources/SubmitObjectsRequest_ebrs3_extra_metadata.xml @@ -0,0 +1,244 @@ + + + + + + 20051224 + + + + + en-us + + + + + 200412230800 + + + + + 200412230801 + + + + + ST-1000^^^&1.3.6.1.4.1.21367.2003.3.9&ISO + + + + + PID-3|ST-1000^^^&1.3.6.1.4.1.21367.2003.3.9&ISO + PID-5|Doe^John^^^ + PID-7|19560527 + PID-8|M + PID-11|100 Main St^^Metropolis^Il^44130^USA + + + + + somevalue + + + + + + + + + + Gerald Smitty + + + + + Cleveland Clinic + Parma Community + + + + + Attending + + + + + Orthopedic + + + + + + + Connect-a-thon classCodes + + + + + + + + + + Connect-a-thon confidentialityCodes + + + + + + + + + + Connect-a-thon formatCodes + + + + + + + + + + Connect-a-thon healthcareFacilityTypeCodes + + + + + + + + + + Connect-a-thon practiceSettingCodes + + + + + + + + + + LOINC + + + + + + + + + + + + + + + + + + + + + 20041225235050 + + + + + + + + + + + + Sherry Dopplemeyer + + + + + Cleveland Clinic + Berea Community + + + + + Primary Surgon + + + + + Orthopedic + + + + + + + Connect-a-thon contentTypeCodes + + + + + + + + + + + + + + + + + + + + + + + + + + + Original + + + + + +