001/*-
002 * #%L
003 * HAPI FHIR Subscription Server
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.subscription.submit.config;
021
022import ca.uhn.fhir.interceptor.api.IInterceptorService;
023import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
024import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
025import ca.uhn.fhir.jpa.subscription.async.AsyncResourceModifiedProcessingSchedulerSvc;
026import ca.uhn.fhir.jpa.subscription.async.AsyncResourceModifiedSubmitterSvc;
027import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelFactory;
028import ca.uhn.fhir.jpa.subscription.config.SubscriptionConfig;
029import ca.uhn.fhir.jpa.subscription.model.config.SubscriptionModelConfig;
030import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionMatcherInterceptor;
031import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionSubmitInterceptorLoader;
032import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionValidatingInterceptor;
033import ca.uhn.fhir.jpa.subscription.submit.interceptor.validator.IChannelTypeValidator;
034import ca.uhn.fhir.jpa.subscription.submit.interceptor.validator.RegexEndpointUrlValidationStrategy;
035import ca.uhn.fhir.jpa.subscription.submit.interceptor.validator.RestHookChannelValidator;
036import ca.uhn.fhir.jpa.subscription.submit.interceptor.validator.SubscriptionChannelTypeValidatorFactory;
037import ca.uhn.fhir.jpa.subscription.submit.svc.ResourceModifiedSubmitterSvc;
038import ca.uhn.fhir.jpa.subscription.triggering.ISubscriptionTriggeringSvc;
039import ca.uhn.fhir.jpa.subscription.triggering.SubscriptionTriggeringSvcImpl;
040import ca.uhn.fhir.jpa.topic.SubscriptionTopicValidatingInterceptor;
041import ca.uhn.fhir.subscription.api.IResourceModifiedConsumerWithRetries;
042import ca.uhn.fhir.subscription.api.IResourceModifiedMessagePersistenceSvc;
043import jakarta.annotation.Nonnull;
044import jakarta.annotation.Nullable;
045import org.springframework.context.annotation.Bean;
046import org.springframework.context.annotation.Configuration;
047import org.springframework.context.annotation.Import;
048import org.springframework.context.annotation.Lazy;
049
050import java.util.List;
051
052import static ca.uhn.fhir.jpa.subscription.submit.interceptor.validator.RestHookChannelValidator.noOpEndpointUrlValidationStrategy;
053
054/**
055 * This Spring config should be imported by a system that submits resources to the
056 * matching queue for processing
057 */
058@Configuration
059@Import({SubscriptionModelConfig.class, SubscriptionMatcherInterceptorConfig.class, SubscriptionConfig.class})
060public class SubscriptionSubmitterConfig {
061
062        @Bean
063        public SubscriptionValidatingInterceptor subscriptionValidatingInterceptor() {
064                return new SubscriptionValidatingInterceptor();
065        }
066
067        @Bean
068        public SubscriptionSubmitInterceptorLoader subscriptionMatcherInterceptorLoader(
069                        @Nonnull IInterceptorService theInterceptorService,
070                        @Nonnull SubscriptionSettings theSubscriptionSettings,
071                        @Nonnull SubscriptionMatcherInterceptor theSubscriptionMatcherInterceptor,
072                        @Nonnull SubscriptionValidatingInterceptor theSubscriptionValidatingInterceptor,
073                        @Nullable SubscriptionTopicValidatingInterceptor theSubscriptionTopicValidatingInterceptor) {
074                return new SubscriptionSubmitInterceptorLoader(
075                                theInterceptorService,
076                                theSubscriptionSettings,
077                                theSubscriptionMatcherInterceptor,
078                                theSubscriptionValidatingInterceptor,
079                                theSubscriptionTopicValidatingInterceptor);
080        }
081
082        @Bean
083        @Lazy
084        public ISubscriptionTriggeringSvc subscriptionTriggeringSvc() {
085                return new SubscriptionTriggeringSvcImpl();
086        }
087
088        @Bean
089        public ResourceModifiedSubmitterSvc resourceModifiedSvc(
090                        IHapiTransactionService theHapiTransactionService,
091                        IResourceModifiedMessagePersistenceSvc theResourceModifiedMessagePersistenceSvc,
092                        SubscriptionChannelFactory theSubscriptionChannelFactory,
093                        SubscriptionSettings theSubscriptionSettings) {
094
095                return new ResourceModifiedSubmitterSvc(
096                                theSubscriptionSettings,
097                                theSubscriptionChannelFactory,
098                                theResourceModifiedMessagePersistenceSvc,
099                                theHapiTransactionService);
100        }
101
102        @Bean
103        public AsyncResourceModifiedProcessingSchedulerSvc asyncResourceModifiedProcessingSchedulerSvc(
104                        SubscriptionConfig subscriptionConfig, SubscriptionSettings theSubscriptionSettings) {
105                return new AsyncResourceModifiedProcessingSchedulerSvc(theSubscriptionSettings.getSubscriptionIntervalInMs());
106        }
107
108        @Bean
109        public AsyncResourceModifiedSubmitterSvc asyncResourceModifiedSubmitterSvc(
110                        IResourceModifiedMessagePersistenceSvc theIResourceModifiedMessagePersistenceSvc,
111                        IResourceModifiedConsumerWithRetries theResourceModifiedConsumer) {
112                return new AsyncResourceModifiedSubmitterSvc(
113                                theIResourceModifiedMessagePersistenceSvc, theResourceModifiedConsumer);
114        }
115
116        @Bean
117        public IChannelTypeValidator restHookChannelValidator(SubscriptionSettings theSubscriptionSettings) {
118                RestHookChannelValidator.IEndpointUrlValidationStrategy iEndpointUrlValidationStrategy =
119                                noOpEndpointUrlValidationStrategy;
120
121                if (theSubscriptionSettings.hasRestHookEndpointUrlValidationRegex()) {
122                        String endpointUrlValidationRegex = theSubscriptionSettings.getRestHookEndpointUrlValidationRegex();
123                        iEndpointUrlValidationStrategy = new RegexEndpointUrlValidationStrategy(endpointUrlValidationRegex);
124                }
125
126                return new RestHookChannelValidator(iEndpointUrlValidationStrategy);
127        }
128
129        @Bean
130        public SubscriptionChannelTypeValidatorFactory subscriptionChannelTypeValidatorFactory(
131                        List<IChannelTypeValidator> theValidorList) {
132                return new SubscriptionChannelTypeValidatorFactory(theValidorList);
133        }
134}