diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java b/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java index da3e989..aba299b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java @@ -11,6 +11,7 @@ import ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor; import ca.uhn.fhir.jpa.bulk.provider.BulkDataExportProvider; import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor; import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc; +import ca.uhn.fhir.jpa.packages.PackageInstallOutcomeJson; import ca.uhn.fhir.jpa.packages.PackageInstallationSpec; import ca.uhn.fhir.jpa.partition.PartitionManagementProvider; import ca.uhn.fhir.jpa.provider.*; @@ -96,6 +97,9 @@ public class BaseJpaRestfulServer extends RestfulServer { @Autowired ApplicationContext myApplicationContext; + @Autowired(required = false) + RepositoryValidationInterceptorFactoryR4 factory; + public BaseJpaRestfulServer() { } @@ -350,14 +354,20 @@ public class BaseJpaRestfulServer extends RestfulServer { if (appProperties.getImplementationGuides() != null) { Map guides = appProperties.getImplementationGuides(); for (Map.Entry guide : guides.entrySet()) { - packageInstallerSvc.install(new PackageInstallationSpec() - .setPackageUrl(guide.getValue().getUrl()) - .setName(guide.getValue().getName()) - .setVersion(guide.getValue().getVersion()) - .setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL)); + PackageInstallOutcomeJson outcome = packageInstallerSvc.install(new PackageInstallationSpec() + .setPackageUrl(guide.getValue().getUrl()) + .setName(guide.getValue().getName()) + .setVersion(guide.getValue().getVersion()) + .setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL)); + } } + if(factory != null) + interceptorService.registerInterceptor(factory.buildUsingStoredStructureDefinitions()); + + + if (appProperties.getLastn_enabled()) { daoConfig.setLastNEnabled(true); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactory.java b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactory.java deleted file mode 100644 index 577c412..0000000 --- a/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -package ca.uhn.fhir.jpa.starter; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.interceptor.api.IInterceptorService; -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.interceptor.validation.IRepositoryValidatingRule; -import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor; -import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Configuration; - -import java.util.List; - -/** - * This class can be customized to enable the {@link ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor} - * on this server. - *

- * The enable_repository_validating_interceptor property must be enabled in application.yaml - * in order to use this class. - */ -@ConditionalOnProperty(prefix = "hapi.fhir", name = "enable_repository_validating_interceptor", havingValue = "true") -@Configuration -public class RepositoryValidationInterceptorFactory { - - private final FhirContext fhirContext; - private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; - - public RepositoryValidationInterceptorFactory(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry, IInterceptorService interceptorService) { - this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; - this.fhirContext = daoRegistry.getSystemDao().getContext(); - interceptorService.registerInterceptor(build()); - } - - public RepositoryValidatingInterceptor build() { - - // Customize the ruleBuilder here to have the rules you want! We will give a simple example - // of enabling validation for all Patient resources - repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireValidationToDeclaredProfiles(); - - // Do not customize below this line - List rules = repositoryValidatingRuleBuilder.build(); - return new RepositoryValidatingInterceptor(fhirContext, rules); - } - -} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryDstu3.java b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryDstu3.java new file mode 100644 index 0000000..79ed691 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryDstu3.java @@ -0,0 +1,74 @@ +package ca.uhn.fhir.jpa.starter; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; +import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; +import ca.uhn.fhir.jpa.interceptor.validation.IRepositoryValidatingRule; +import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor; +import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder; +import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.starter.annotations.OnDSTU3Condition; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.TokenParam; +import org.hl7.fhir.dstu3.model.StructureDefinition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This class can be customized to enable the {@link RepositoryValidatingInterceptor} + * on this server. + *

+ * The enable_repository_validating_interceptor property must be enabled in application.yaml + * in order to use this class. + */ +@ConditionalOnProperty(prefix = "hapi.fhir", name = "enable_repository_validating_interceptor", havingValue = "true") +@Configuration +@Conditional(OnDSTU3Condition.class) +public class RepositoryValidationInterceptorFactoryDstu3 { + + private final FhirContext fhirContext; + private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; + private final IFhirResourceDao structureDefinitionResourceProvider; + + public RepositoryValidationInterceptorFactoryDstu3(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; + this.fhirContext = daoRegistry.getSystemDao().getContext(); + structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); + + } + + public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { + + IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefintions = results.getResources(0, results.size()) + .stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); + + structureDefintions.entrySet().forEach(structureDefinitionListEntry -> + { + String[] urls = structureDefinitionListEntry.getValue().stream().map(StructureDefinition::getUrl).toArray(String[]::new); + repositoryValidatingRuleBuilder.forResourcesOfType(structureDefinitionListEntry.getKey()).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + }); + + List rules = repositoryValidatingRuleBuilder.build(); + return new RepositoryValidatingInterceptor(fhirContext, rules); + } + + public RepositoryValidatingInterceptor build() { + + // Customize the ruleBuilder here to have the rules you want! We will give a simple example + // of enabling validation for all Patient resources + repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + + // Do not customize below this line + List rules = repositoryValidatingRuleBuilder.build(); + return new RepositoryValidatingInterceptor(fhirContext, rules); + } + +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryR4.java b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryR4.java new file mode 100644 index 0000000..2a053dc --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryR4.java @@ -0,0 +1,74 @@ +package ca.uhn.fhir.jpa.starter; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; +import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; +import ca.uhn.fhir.jpa.interceptor.validation.IRepositoryValidatingRule; +import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor; +import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder; +import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.TokenParam; +import org.hl7.fhir.r4.model.StructureDefinition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This class can be customized to enable the {@link ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor} + * on this server. + *

+ * The enable_repository_validating_interceptor property must be enabled in application.yaml + * in order to use this class. + */ +@ConditionalOnProperty(prefix = "hapi.fhir", name = "enable_repository_validating_interceptor", havingValue = "true") +@Configuration +@Conditional(OnR4Condition.class) +public class RepositoryValidationInterceptorFactoryR4 { + + private final FhirContext fhirContext; + private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; + private final IFhirResourceDao structureDefinitionResourceProvider; + + public RepositoryValidationInterceptorFactoryR4(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; + this.fhirContext = daoRegistry.getSystemDao().getContext(); + structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); + + } + + public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { + + IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefintions = results.getResources(0, results.size()) + .stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); + + structureDefintions.entrySet().forEach(structureDefinitionListEntry -> + { + String[] urls = structureDefinitionListEntry.getValue().stream().map(StructureDefinition::getUrl).toArray(String[]::new); + repositoryValidatingRuleBuilder.forResourcesOfType(structureDefinitionListEntry.getKey()).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + }); + + List rules = repositoryValidatingRuleBuilder.build(); + return new RepositoryValidatingInterceptor(fhirContext, rules); + } + + public RepositoryValidatingInterceptor build() { + + // Customize the ruleBuilder here to have the rules you want! We will give a simple example + // of enabling validation for all Patient resources + repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + + // Do not customize below this line + List rules = repositoryValidatingRuleBuilder.build(); + return new RepositoryValidatingInterceptor(fhirContext, rules); + } + +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryR5.java b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryR5.java new file mode 100644 index 0000000..0ddcc96 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/RepositoryValidationInterceptorFactoryR5.java @@ -0,0 +1,74 @@ +package ca.uhn.fhir.jpa.starter; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; +import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; +import ca.uhn.fhir.jpa.interceptor.validation.IRepositoryValidatingRule; +import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor; +import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder; +import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.starter.annotations.OnR5Condition; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.TokenParam; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This class can be customized to enable the {@link RepositoryValidatingInterceptor} + * on this server. + *

+ * The enable_repository_validating_interceptor property must be enabled in application.yaml + * in order to use this class. + */ +@ConditionalOnProperty(prefix = "hapi.fhir", name = "enable_repository_validating_interceptor", havingValue = "true") +@Configuration +@Conditional(OnR5Condition.class) +public class RepositoryValidationInterceptorFactoryR5 { + + private final FhirContext fhirContext; + private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; + private final IFhirResourceDao structureDefinitionResourceProvider; + + public RepositoryValidationInterceptorFactoryR5(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; + this.fhirContext = daoRegistry.getSystemDao().getContext(); + structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); + + } + + public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { + + IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefintions = results.getResources(0, results.size()) + .stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); + + structureDefintions.entrySet().forEach(structureDefinitionListEntry -> + { + String[] urls = structureDefinitionListEntry.getValue().stream().map(StructureDefinition::getUrl).toArray(String[]::new); + repositoryValidatingRuleBuilder.forResourcesOfType(structureDefinitionListEntry.getKey()).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + }); + + List rules = repositoryValidatingRuleBuilder.build(); + return new RepositoryValidatingInterceptor(fhirContext, rules); + } + + public RepositoryValidatingInterceptor build() { + + // Customize the ruleBuilder here to have the rules you want! We will give a simple example + // of enabling validation for all Patient resources + repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + + // Do not customize below this line + List rules = repositoryValidatingRuleBuilder.build(); + return new RepositoryValidatingInterceptor(fhirContext, rules); + } + +}