Include profile URL in generated IPS (#5938)
* Include profile URL in generated IPS * Add changelog * Documentation tweak
This commit is contained in:
parent
446869b524
commit
14c364dffd
|
@ -626,6 +626,16 @@ public class BundleBuilder {
|
|||
terser.setElement(myBundle, "Bundle.timestamp", theTimestamp.getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a profile URL to <code>Bundle.meta.profile</code>
|
||||
*
|
||||
* @since 7.4.0
|
||||
*/
|
||||
public void addProfile(String theProfile) {
|
||||
FhirTerser terser = myContext.newTerser();
|
||||
terser.addElement(myBundle, "Bundle.meta.profile", theProfile);
|
||||
}
|
||||
|
||||
public class DeleteBuilder extends BaseOperationBuilder {
|
||||
|
||||
// nothing yet
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
type: add
|
||||
issue: 5938
|
||||
title: "Generated IPS documents will now include a bundle profile declaration."
|
|
@ -42,7 +42,10 @@ public interface IIpsGenerationStrategy {
|
|||
|
||||
/**
|
||||
* This method returns the profile associated with the IPS document
|
||||
* generated by this strategy.
|
||||
* generated by this strategy. This URL will be added to generated
|
||||
* IPS Bundles in <code>Bundle.meta.profile</code>, and can also
|
||||
* be used to support the <code>profile</code> parameter on the
|
||||
* <code>$summary</code> operation.
|
||||
*/
|
||||
String getBundleProfile();
|
||||
|
||||
|
|
|
@ -146,6 +146,7 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc {
|
|||
bundleBuilder.setType(Bundle.BundleType.DOCUMENT.toCode());
|
||||
bundleBuilder.setIdentifier("urn:ietf:rfc:4122", UUID.randomUUID().toString());
|
||||
bundleBuilder.setTimestamp(InstantType.now());
|
||||
bundleBuilder.addProfile(theStrategy.getBundleProfile());
|
||||
|
||||
// Add composition to document
|
||||
bundleBuilder.addDocumentEntry(composition);
|
||||
|
|
|
@ -5,7 +5,6 @@ import ca.uhn.fhir.context.support.ConceptValidationOptions;
|
|||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy;
|
||||
import ca.uhn.fhir.jpa.ips.jpa.DefaultJpaIpsGenerationStrategy;
|
||||
import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider;
|
||||
|
@ -18,6 +17,7 @@ import ca.uhn.fhir.validation.SingleValidationMessage;
|
|||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import org.hl7.fhir.common.hapi.validation.support.NpmPackageValidationSupport;
|
||||
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
|
||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -31,6 +31,7 @@ import org.hl7.fhir.r4.model.Immunization;
|
|||
import org.hl7.fhir.r4.model.MedicationStatement;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.PrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
@ -41,6 +42,7 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -48,10 +50,10 @@ import java.util.stream.Collectors;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.hibernate.validator.internal.util.Contracts.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* This test uses a complete R4 JPA server as a backend and wires the
|
||||
|
@ -77,7 +79,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
|
||||
@Test
|
||||
public void testGenerateLargePatientSummary() {
|
||||
public void testGenerateLargePatientSummary() throws IOException {
|
||||
Bundle sourceData = ClasspathUtil.loadCompressedResource(myFhirContext, Bundle.class, "/large-patient-everything.json.gz");
|
||||
sourceData.setType(Bundle.BundleType.TRANSACTION);
|
||||
for (Bundle.BundleEntryComponent nextEntry : sourceData.getEntry()) {
|
||||
|
@ -97,6 +99,9 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output));
|
||||
|
||||
// Verify
|
||||
assertThat(output.getMeta().getProfile().stream().map(PrimitiveType::getValue).toList(), contains(
|
||||
"http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips"
|
||||
));
|
||||
validateDocument(output);
|
||||
assertEquals(117, output.getEntry().size());
|
||||
String patientId = findFirstEntryResource(output, Patient.class, 1).getIdElement().toUnqualifiedVersionless().getValue();
|
||||
|
@ -162,7 +167,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateTinyPatientSummary() {
|
||||
public void testGenerateTinyPatientSummary() throws IOException {
|
||||
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||
|
||||
Bundle sourceData = ClasspathUtil.loadCompressedResource(myFhirContext, Bundle.class, "/tiny-patient-everything.json.gz");
|
||||
|
@ -251,7 +256,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
|
||||
@Nonnull
|
||||
private static Composition findCompositionSectionByDisplay(Bundle output, String theDisplay) {
|
||||
private static Composition findCompositionSectionByDisplay(Bundle output, @SuppressWarnings("SameParameterValue") String theDisplay) {
|
||||
Composition composition = (Composition) output.getEntry().get(0).getResource();
|
||||
Composition.SectionComponent section = composition
|
||||
.getSection()
|
||||
|
@ -259,6 +264,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
.filter(t -> t.getCode().getCoding().get(0).getDisplay().equals(theDisplay))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
assertNotNull(section);
|
||||
return composition;
|
||||
}
|
||||
|
||||
|
@ -266,23 +272,26 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
@Nonnull
|
||||
private static List<String> extractSectionTitles(Bundle outcome) {
|
||||
Composition composition = (Composition) outcome.getEntry().get(0).getResource();
|
||||
List<String> sectionTitles = composition
|
||||
return composition
|
||||
.getSection()
|
||||
.stream()
|
||||
.map(Composition.SectionComponent::getTitle)
|
||||
.toList();
|
||||
return sectionTitles;
|
||||
}
|
||||
|
||||
private void validateDocument(Bundle theOutcome) {
|
||||
private void validateDocument(Bundle theOutcome) throws IOException {
|
||||
FhirValidator validator = myFhirContext.newValidator();
|
||||
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myFhirContext);
|
||||
instanceValidator.setValidationSupport(new ValidationSupportChain(new IpsTerminologySvc(), myFhirContext.getValidationSupport()));
|
||||
|
||||
NpmPackageValidationSupport npmSupport = new NpmPackageValidationSupport(myFhirContext);
|
||||
npmSupport.loadPackageFromClasspath("/ips-package-1.1.0.tgz");
|
||||
|
||||
instanceValidator.setValidationSupport(new ValidationSupportChain(npmSupport, new IpsTerminologySvc(), myFhirContext.getValidationSupport()));
|
||||
validator.registerValidatorModule(instanceValidator);
|
||||
ValidationResult validation = validator.validateWithResult(theOutcome);
|
||||
|
||||
Optional<SingleValidationMessage> failure = validation.getMessages().stream().filter(t -> t.getSeverity().ordinal() >= ResultSeverityEnum.ERROR.ordinal()).findFirst();
|
||||
assertFalse(failure.isPresent(), () -> failure.get().toString());
|
||||
assertFalse(failure.isPresent(), () -> failure.orElseThrow().toString());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
@ -294,7 +303,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public IIpsGeneratorSvc ipsGeneratorSvc(FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy, DaoRegistry theDaoRegistry) {
|
||||
public IIpsGeneratorSvc ipsGeneratorSvc(FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy) {
|
||||
return new IpsGeneratorSvcImpl(theFhirContext, theGenerationStrategy);
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue