diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_0/5925-resole-unsupportedoperationexception-validating-mhd.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_0/5925-resole-unsupportedoperationexception-validating-mhd.yaml new file mode 100644 index 00000000000..f19fba74278 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_4_0/5925-resole-unsupportedoperationexception-validating-mhd.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 5925 +title: "An UnsupportedOperationException occurred when validating R5 MHD bundles using + the HAPI FHIR validator. Thanks to Renaud Subiger for contributing a fix!" diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java index 340dcfc775c..0dc166c0c8e 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java @@ -322,7 +322,8 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent binding, boolean cacheOk, boolean Hierarchical) { - throw new UnsupportedOperationException(Msg.code(663)); + ValueSet valueSet = fetchResource(ValueSet.class, binding.getValueSet(), src); + return expandVS(valueSet, cacheOk, Hierarchical); } @Override diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/NpmPackageValidationSupportTest.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/NpmPackageValidationSupportTest.java index 9549e2ad2ad..0afad0fee73 100644 --- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/NpmPackageValidationSupportTest.java +++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/NpmPackageValidationSupportTest.java @@ -24,6 +24,7 @@ import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class NpmPackageValidationSupportTest extends BaseValidationTestWithInlineMocks { @@ -89,4 +90,32 @@ public class NpmPackageValidationSupportTest extends BaseValidationTestWithInlin assertArrayEquals(expectedBytes, actualBytes); } } + + @Test + public void testValidateIheMhdPackage() throws IOException { + ValidationSupportChain validationSupportChain = new ValidationSupportChain(); + validationSupportChain.addValidationSupport(getNpmPackageValidationSupport("classpath:package/ihe.iti.mhd.tgz")); + validationSupportChain.addValidationSupport(new DefaultProfileValidationSupport(myFhirContext)); + validationSupportChain.addValidationSupport(new CommonCodeSystemsTerminologyService(myFhirContext)); + validationSupportChain.addValidationSupport(new InMemoryTerminologyServerValidationSupport(myFhirContext)); + validationSupportChain.addValidationSupport(new SnapshotGeneratingValidationSupport(myFhirContext)); + + CachingValidationSupport validationSupport = new CachingValidationSupport(validationSupportChain); + + FhirValidator validator = myFhirContext.newValidator(); + FhirInstanceValidator instanceValidator = new FhirInstanceValidator(validationSupport); + validator.registerValidatorModule(instanceValidator); + + String bundle = loadResource("/r4/mhd_minimal_provide_document_bundle.json"); + ValidationResult validationResult = validator.validateWithResult(bundle); + + assertEquals(1, validationResult.getMessages().size()); + + String outcomeSerialized = myFhirContext.newJsonParser() + .setPrettyPrint(true) + .encodeResourceToString(validationResult.toOperationOutcome()); + ourLog.info(outcomeSerialized); + + assertThat(outcomeSerialized, containsString("Terminology_TX_ValueSet_NotFound")); + } } diff --git a/hapi-fhir-validation/src/test/resources/package/ihe.iti.mhd.tgz b/hapi-fhir-validation/src/test/resources/package/ihe.iti.mhd.tgz new file mode 100644 index 00000000000..5e3d6cc6b61 Binary files /dev/null and b/hapi-fhir-validation/src/test/resources/package/ihe.iti.mhd.tgz differ diff --git a/hapi-fhir-validation/src/test/resources/r4/mhd_minimal_provide_document_bundle.json b/hapi-fhir-validation/src/test/resources/r4/mhd_minimal_provide_document_bundle.json new file mode 100644 index 00000000000..0663757c515 --- /dev/null +++ b/hapi-fhir-validation/src/test/resources/r4/mhd_minimal_provide_document_bundle.json @@ -0,0 +1,190 @@ +{ + "resourceType": "Bundle", + "meta": { + "profile": [ + "https://profiles.ihe.net/ITI/MHD/StructureDefinition/IHE.MHD.Minimal.ProvideBundle" + ], + "security": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", + "code": "HTEST" + } + ] + }, + "type": "transaction", + "timestamp": "2024-05-11T14:16:19.224Z", + "entry": [ + { + "fullUrl": "urn:uuid:9649cc3d-eb0b-407b-b1ba-61c4eef4dba3", + "resource": { + "resourceType": "List", + "id": "9649cc3d-eb0b-407b-b1ba-61c4eef4dba3", + "meta": { + "profile": [ + "https://profiles.ihe.net/ITI/MHD/StructureDefinition/IHE.MHD.Minimal.SubmissionSet" + ], + "security": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", + "code": "HTEST" + } + ] + }, + "text": { + "status": "extensions", + "div": "
SubmissionSet with Patient
" + }, + "contained": [ + { + "resourceType": "Practitioner", + "id": "622209e6-32ad-4283-b4eb-e2bea2aea856", + "telecom": [ + { + "system": "email", + "value": "john.doe@localhost" + } + ] + } + ], + "extension": [ + { + "url": "https://profiles.ihe.net/ITI/MHD/StructureDefinition/ihe-sourceId", + "valueIdentifier": { + "value": "urn:oid:1.2.3.4" + } + }, + { + "url": "https://profiles.ihe.net/ITI/MHD/StructureDefinition/ihe-intendedRecipient", + "valueReference": { + "reference": "#622209e6-32ad-4283-b4eb-e2bea2aea856" + } + } + ], + "identifier": [ + { + "use": "usual", + "system": "urn:ietf:rfc:3986", + "value": "urn:oid:1.2.840.113556.1.8000.2554.58783.21864.3474.19410.44358.58254.41281.46343" + } + ], + "status": "current", + "mode": "working", + "code": { + "coding": [ + { + "system": "https://profiles.ihe.net/ITI/MHD/CodeSystem/MHDlistTypes", + "code": "submissionset" + } + ] + }, + "subject": { + "reference": "urn:uuid:51eb4fab-9d1a-4314-ad7c-363fc430f52c" + }, + "date": "2004-10-25T23:50:50-05:00", + "entry": [ + { + "item": { + "reference": "urn:uuid:f494ac72-be69-4910-baf4-0cce4a45e7c1" + } + } + ] + }, + "request": { + "method": "POST", + "url": "List" + } + }, + { + "fullUrl": "urn:uuid:f494ac72-be69-4910-baf4-0cce4a45e7c1", + "resource": { + "resourceType": "DocumentReference", + "id": "f494ac72-be69-4910-baf4-0cce4a45e7c1", + "meta": { + "profile": [ + "https://profiles.ihe.net/ITI/MHD/StructureDefinition/IHE.MHD.Minimal.DocumentReference" + ], + "security": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", + "code": "HTEST" + } + ] + }, + "masterIdentifier": { + "system": "urn:ietf:rfc:3986", + "value": "urn:oid:1.2.840.113556.1.8000.2554.53432.348.12973.17740.34205.4355.50220.62012" + }, + "status": "current", + "subject": { + "reference": "urn:uuid:51eb4fab-9d1a-4314-ad7c-363fc430f52c" + }, + "content": [ + { + "attachment": { + "contentType": "text/plain", + "url": "urn:uuid:4d14267b-19ff-4237-a301-4cdcfd67d4f9", + "size": 11, + "hash": "MGE0ZDU1YThkNzc4ZTUwMjJmYWI3MDE5NzdjNWQ4NDBiYmM0ODZkMA==" + }, + "format": { + "system": "http://ihe.net/fhir/ihe.formatcode.fhir/CodeSystem/formatcode", + "code": "urn:ihe:iti:xds-sd:text:2008" + } + } + ] + }, + "request": { + "method": "POST", + "url": "DocumentReference" + } + }, + { + "fullUrl": "urn:uuid:4d14267b-19ff-4237-a301-4cdcfd67d4f9", + "resource": { + "resourceType": "Binary", + "id": "4d14267b-19ff-4237-a301-4cdcfd67d4f9", + "meta": { + "security": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", + "code": "HTEST" + } + ] + }, + "contentType": "text/plain", + "data": "SGVsbG8gV29ybGQ=" + }, + "request": { + "method": "POST", + "url": "Binary" + } + }, + { + "fullUrl": "urn:uuid:51eb4fab-9d1a-4314-ad7c-363fc430f52c", + "resource": { + "resourceType": "Patient", + "id": "51eb4fab-9d1a-4314-ad7c-363fc430f52c", + "meta": { + "security": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", + "code": "HTEST" + } + ] + }, + "name": [ + { + "family": "Schmidt", + "given": [ + "Dee" + ] + } + ] + }, + "request": { + "method": "POST", + "url": "Patient" + } + } + ] +} diff --git a/pom.xml b/pom.xml index 3b6244971d5..08b3a1c9d6a 100644 --- a/pom.xml +++ b/pom.xml @@ -913,6 +913,10 @@ thetrueoneshots Gijs Groenewegen + + subigre + Renaud Subiger +