Search in sources :

Example 1 with ReadOnlyInterceptor

use of ca.uhn.fhir.jpa.starter.ReadOnlyInterceptor in project drug-formulary-ri by HL7-DaVinci.

the class JpaRestfulServer method initialize.

@SuppressWarnings("unchecked")
@Override
protected void initialize() throws ServletException {
    super.initialize();
    /*
     * Create a FhirContext object that uses the version of FHIR
     * specified in the properties file.
     */
    ApplicationContext appCtx = (ApplicationContext) getServletContext().getAttribute("org.springframework.web.context.WebApplicationContext.ROOT");
    // Customize supported resource types
    Set<String> supportedResourceTypes = HapiProperties.getSupportedResourceTypes();
    if (!supportedResourceTypes.isEmpty() && !supportedResourceTypes.contains("SearchParameter")) {
        supportedResourceTypes.add("SearchParameter");
    }
    if (!supportedResourceTypes.isEmpty()) {
        DaoRegistry daoRegistry = appCtx.getBean(DaoRegistry.class);
        daoRegistry.setSupportedResourceTypes(supportedResourceTypes);
    }
    /*
     * ResourceProviders are fetched from the Spring context
     */
    FhirVersionEnum fhirVersion = HapiProperties.getFhirVersion();
    ResourceProviderFactory resourceProviders;
    Object systemProvider;
    if (fhirVersion == FhirVersionEnum.DSTU2) {
        resourceProviders = appCtx.getBean("myResourceProvidersDstu2", ResourceProviderFactory.class);
        systemProvider = appCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class);
    } else if (fhirVersion == FhirVersionEnum.DSTU3) {
        resourceProviders = appCtx.getBean("myResourceProvidersDstu3", ResourceProviderFactory.class);
        systemProvider = appCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class);
    } else if (fhirVersion == FhirVersionEnum.R4) {
        resourceProviders = appCtx.getBean("myResourceProvidersR4", ResourceProviderFactory.class);
        systemProvider = appCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class);
    } else if (fhirVersion == FhirVersionEnum.R5) {
        resourceProviders = appCtx.getBean("myResourceProvidersR5", ResourceProviderFactory.class);
        systemProvider = appCtx.getBean("mySystemProviderR5", JpaSystemProviderR5.class);
    } else {
        throw new IllegalStateException();
    }
    setFhirContext(appCtx.getBean(FhirContext.class));
    registerProviders(resourceProviders.createProviders());
    registerProvider(systemProvider);
    /*
     * The conformance provider exports the supported resources, search parameters,
     * etc for
     * this server. The JPA version adds resourceProviders counts to the exported
     * statement, so it
     * is a nice addition.
     *
     * You can also create your own subclass of the conformance provider if you need
     * to
     * provide further customization of your server's CapabilityStatement
     */
    IFhirSystemDao<org.hl7.fhir.r4.model.Bundle, org.hl7.fhir.r4.model.Meta> systemDao = appCtx.getBean("mySystemDaoR4", IFhirSystemDao.class);
    MetadataProvider metadata = new MetadataProvider(this, systemDao, appCtx.getBean(DaoConfig.class));
    // JpaConformanceProviderR4 confProvider = new JpaConformanceProviderR4(this,
    // systemDao,
    // appCtx.getBean(DaoConfig.class));
    metadata.setImplementationDescription("Da Vinci Drug Formulary Reference Server");
    setServerConformanceProvider(metadata);
    /*
     * ETag Support
     */
    setETagSupport(HapiProperties.getEtagSupport());
    /*
     * This server tries to dynamically generate narratives
     */
    FhirContext ctx = getFhirContext();
    ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
    /*
     * Default to JSON and pretty printing
     */
    setDefaultPrettyPrint(HapiProperties.getDefaultPrettyPrint());
    /*
     * Default encoding
     */
    setDefaultResponseEncoding(HapiProperties.getDefaultEncoding());
    /*
     * This configures the server to page search results to and from
     * the database, instead of only paging them to memory. This may mean
     * a performance hit when performing searches that return lots of results,
     * but makes the server much more scalable.
     */
    setPagingProvider(appCtx.getBean(DatabaseBackedPagingProvider.class));
    /*
     * This interceptor formats the output using nice colourful
     * HTML output when the request is detected to come from a
     * browser.
     */
    ResponseHighlighterInterceptor responseHighlighterInterceptor = new ResponseHighlighterInterceptor();
    this.registerInterceptor(responseHighlighterInterceptor);
    /*
     * Add Read Only Interceptor
     */
    ReadOnlyInterceptor readOnlyInterceptor = new ReadOnlyInterceptor();
    this.registerInterceptor(readOnlyInterceptor);
    /*
     * This interceptor handles the $export operation
     */
    ExportInterceptor exportInterceptor = new ExportInterceptor();
    this.registerInterceptor(exportInterceptor);
    /*
     * Add some logging for each request
     */
    LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
    loggingInterceptor.setLoggerName(HapiProperties.getLoggerName());
    loggingInterceptor.setMessageFormat(HapiProperties.getLoggerFormat());
    loggingInterceptor.setErrorMessageFormat(HapiProperties.getLoggerErrorFormat());
    loggingInterceptor.setLogExceptions(HapiProperties.getLoggerLogExceptions());
    this.registerInterceptor(loggingInterceptor);
    /*
     * Add Authorization interceptor
     */
    PatientAuthorizationInterceptor authorizationInterceptor = new PatientAuthorizationInterceptor();
    this.registerInterceptor(authorizationInterceptor);
    /*
     * If you are hosting this server at a specific DNS name, the server will try to
     * figure out the FHIR base URL based on what the web container tells it, but
     * this doesn't always work. If you are setting links in your search bundles
     * that
     * just refer to "localhost", you might want to use a server address strategy:
     */
    String serverAddress = HapiProperties.getServerAddress();
    if (serverAddress != null && serverAddress.length() > 0) {
        setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress));
    }
    /*
     * If you are using DSTU3+, you may want to add a terminology uploader, which
     * allows
     * uploading of external terminologies such as Snomed CT. Note that this
     * uploader
     * does not have any security attached (any anonymous user may use it by
     * default)
     * so it is a potential security vulnerability. Consider using an
     * AuthorizationInterceptor
     * with this feature.
     */
    if (false) {
        // <-- DISABLED RIGHT NOW
        registerProvider(appCtx.getBean(TerminologyUploaderProvider.class));
    }
    // manual triggering of a subscription delivery, enable this provider
    if (false) {
        // <-- DISABLED RIGHT NOW
        SubscriptionTriggeringProvider retriggeringProvider = appCtx.getBean(SubscriptionTriggeringProvider.class);
        registerProvider(retriggeringProvider);
    }
    // to your specific needs
    if (HapiProperties.getCorsEnabled()) {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedHeader(HttpHeaders.ORIGIN);
        config.addAllowedHeader(HttpHeaders.ACCEPT);
        config.addAllowedHeader(HttpHeaders.CONTENT_TYPE);
        config.addAllowedHeader(HttpHeaders.AUTHORIZATION);
        config.addAllowedHeader(HttpHeaders.CACHE_CONTROL);
        config.addAllowedHeader("x-fhir-starter");
        config.addAllowedHeader("X-Requested-With");
        config.addAllowedHeader("Prefer");
        String allAllowedCORSOrigins = HapiProperties.getCorsAllowedOrigin();
        Arrays.stream(allAllowedCORSOrigins.split(",")).forEach(o -> {
            config.addAllowedOrigin(o);
        });
        config.addAllowedOrigin(HapiProperties.getCorsAllowedOrigin());
        config.addExposedHeader("Location");
        config.addExposedHeader("Content-Location");
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD"));
        config.setAllowCredentials(HapiProperties.getCorsAllowedCredentials());
        // Create the interceptor and register it
        CorsInterceptor interceptor = new CorsInterceptor(config);
        registerInterceptor(interceptor);
    }
    // will activate them and match results against them
    if (HapiProperties.getSubscriptionWebsocketEnabled() || HapiProperties.getSubscriptionEmailEnabled() || HapiProperties.getSubscriptionRestHookEnabled()) {
        // Loads subscription interceptors (SubscriptionActivatingInterceptor,
        // SubscriptionMatcherInterceptor)
        // with activation of scheduled subscription
        SubscriptionInterceptorLoader subscriptionInterceptorLoader = appCtx.getBean(SubscriptionInterceptorLoader.class);
        subscriptionInterceptorLoader.registerInterceptors();
        // Subscription debug logging
        IInterceptorService interceptorService = appCtx.getBean(IInterceptorService.class);
        interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor());
    }
    // Cascading deletes
    DaoRegistry daoRegistry = appCtx.getBean(DaoRegistry.class);
    IInterceptorBroadcaster interceptorBroadcaster = appCtx.getBean(IInterceptorBroadcaster.class);
    if (HapiProperties.getAllowCascadingDeletes()) {
        CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor(daoRegistry, interceptorBroadcaster);
        getInterceptorService().registerInterceptor(cascadingDeleteInterceptor);
    }
    // Binary Storage
    if (HapiProperties.isBinaryStorageEnabled()) {
        BinaryStorageInterceptor binaryStorageInterceptor = appCtx.getBean(BinaryStorageInterceptor.class);
        getInterceptorService().registerInterceptor(binaryStorageInterceptor);
    }
    // Validation
    IValidatorModule validatorModule;
    switch(fhirVersion) {
        case DSTU2:
            validatorModule = appCtx.getBean("myInstanceValidatorDstu2", IValidatorModule.class);
            break;
        case DSTU3:
            validatorModule = appCtx.getBean("myInstanceValidatorDstu3", IValidatorModule.class);
            break;
        case R4:
            validatorModule = appCtx.getBean("myInstanceValidatorR4", IValidatorModule.class);
            break;
        case R5:
            validatorModule = appCtx.getBean("myInstanceValidatorR5", IValidatorModule.class);
            break;
        // These versions are not supported by HAPI FHIR JPA
        case DSTU2_HL7ORG:
        case DSTU2_1:
        default:
            validatorModule = null;
            break;
    }
    if (validatorModule != null) {
        if (HapiProperties.getValidateRequestsEnabled()) {
            RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
            interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
            interceptor.setValidatorModules(Collections.singletonList(validatorModule));
            registerInterceptor(interceptor);
        }
        if (HapiProperties.getValidateResponsesEnabled()) {
            ResponseValidatingInterceptor interceptor = new ResponseValidatingInterceptor();
            interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
            interceptor.setValidatorModules(Collections.singletonList(validatorModule));
            registerInterceptor(interceptor);
        }
    }
    // GraphQL
    if (HapiProperties.getGraphqlEnabled()) {
        if (fhirVersion.isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
            registerProvider(appCtx.getBean(GraphQLProvider.class));
        }
    }
    if (!HapiProperties.getAllowedBundleTypes().isEmpty()) {
        String allowedBundleTypesString = HapiProperties.getAllowedBundleTypes();
        Set<String> allowedBundleTypes = new HashSet<>();
        Arrays.stream(allowedBundleTypesString.split(",")).forEach(o -> {
            BundleType type = BundleType.valueOf(o);
            allowedBundleTypes.add(type.toCode());
        });
        DaoConfig config = appCtx.getBean(DaoConfig.class);
        config.setBundleTypesAllowedForStorage(Collections.unmodifiableSet(new TreeSet<>(allowedBundleTypes)));
    }
    // Bulk Export
    if (HapiProperties.getBulkExportEnabled()) {
        registerProvider(appCtx.getBean(BulkDataExportProvider.class));
    }
}
Also used : Meta(org.hl7.fhir.dstu3.model.Meta) FhirContext(ca.uhn.fhir.context.FhirContext) ResourceProviderFactory(ca.uhn.fhir.jpa.util.ResourceProviderFactory) SubscriptionDebugLogInterceptor(ca.uhn.fhir.jpa.subscription.module.interceptor.SubscriptionDebugLogInterceptor) BinaryStorageInterceptor(ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor) FhirVersionEnum(ca.uhn.fhir.context.FhirVersionEnum) SubscriptionTriggeringProvider(ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider) IInterceptorBroadcaster(ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster) JpaSystemProviderR4(ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4) CorsInterceptor(ca.uhn.fhir.rest.server.interceptor.CorsInterceptor) ReadOnlyInterceptor(ca.uhn.fhir.jpa.starter.ReadOnlyInterceptor) ApplicationContext(org.springframework.context.ApplicationContext) BundleType(org.hl7.fhir.r4.model.Bundle.BundleType) ResponseHighlighterInterceptor(ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor) IValidatorModule(ca.uhn.fhir.validation.IValidatorModule) TreeSet(java.util.TreeSet) DefaultThymeleafNarrativeGenerator(ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator) TerminologyUploaderProvider(ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider) RequestValidatingInterceptor(ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor) HashSet(java.util.HashSet) BulkDataExportProvider(ca.uhn.fhir.jpa.bulk.BulkDataExportProvider) DaoConfig(ca.uhn.fhir.jpa.dao.DaoConfig) LoggingInterceptor(ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor) Bundle(org.hl7.fhir.dstu3.model.Bundle) IInterceptorService(ca.uhn.fhir.interceptor.api.IInterceptorService) DatabaseBackedPagingProvider(ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider) CascadingDeleteInterceptor(ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor) GraphQLProvider(ca.uhn.fhir.jpa.provider.GraphQLProvider) JpaSystemProviderDstu2(ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2) ResponseValidatingInterceptor(ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor) SubscriptionInterceptorLoader(ca.uhn.fhir.jpa.subscription.SubscriptionInterceptorLoader) CorsConfiguration(org.springframework.web.cors.CorsConfiguration) MetadataProvider(ca.uhn.fhir.jpa.starter.MetadataProvider) DaoRegistry(ca.uhn.fhir.jpa.dao.DaoRegistry) HardcodedServerAddressStrategy(ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy)

Aggregations

FhirContext (ca.uhn.fhir.context.FhirContext)1 FhirVersionEnum (ca.uhn.fhir.context.FhirVersionEnum)1 IInterceptorBroadcaster (ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster)1 IInterceptorService (ca.uhn.fhir.interceptor.api.IInterceptorService)1 BinaryStorageInterceptor (ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor)1 BulkDataExportProvider (ca.uhn.fhir.jpa.bulk.BulkDataExportProvider)1 DaoConfig (ca.uhn.fhir.jpa.dao.DaoConfig)1 DaoRegistry (ca.uhn.fhir.jpa.dao.DaoRegistry)1 CascadingDeleteInterceptor (ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor)1 GraphQLProvider (ca.uhn.fhir.jpa.provider.GraphQLProvider)1 JpaSystemProviderDstu2 (ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2)1 SubscriptionTriggeringProvider (ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider)1 TerminologyUploaderProvider (ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider)1 JpaSystemProviderR4 (ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4)1 DatabaseBackedPagingProvider (ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider)1 MetadataProvider (ca.uhn.fhir.jpa.starter.MetadataProvider)1 ReadOnlyInterceptor (ca.uhn.fhir.jpa.starter.ReadOnlyInterceptor)1 SubscriptionInterceptorLoader (ca.uhn.fhir.jpa.subscription.SubscriptionInterceptorLoader)1 SubscriptionDebugLogInterceptor (ca.uhn.fhir.jpa.subscription.module.interceptor.SubscriptionDebugLogInterceptor)1 ResourceProviderFactory (ca.uhn.fhir.jpa.util.ResourceProviderFactory)1