001/*-
002 * #%L
003 * HAPI FHIR Subscription Server
004 * %%
005 * Copyright (C) 2014 - 2025 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.match.config;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
024import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
025import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
026import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher;
027import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory;
028import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelRegistry;
029import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryChannelNamer;
030import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory;
031import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
032import ca.uhn.fhir.jpa.subscription.match.deliver.email.SubscriptionDeliveringEmailSubscriber;
033import ca.uhn.fhir.jpa.subscription.match.deliver.message.SubscriptionDeliveringMessageSubscriber;
034import ca.uhn.fhir.jpa.subscription.match.deliver.resthook.SubscriptionDeliveringRestHookSubscriber;
035import ca.uhn.fhir.jpa.subscription.match.matcher.matching.CompositeInMemoryDaoSubscriptionMatcher;
036import ca.uhn.fhir.jpa.subscription.match.matcher.matching.DaoSubscriptionMatcher;
037import ca.uhn.fhir.jpa.subscription.match.matcher.matching.ISubscriptionMatcher;
038import ca.uhn.fhir.jpa.subscription.match.matcher.matching.InMemorySubscriptionMatcher;
039import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.MatchingQueueSubscriberLoader;
040import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionActivatingSubscriber;
041import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionMatchDeliverer;
042import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionMatchingSubscriber;
043import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionRegisteringSubscriber;
044import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader;
045import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
046import ca.uhn.fhir.jpa.subscription.model.config.SubscriptionModelConfig;
047import ca.uhn.fhir.jpa.topic.SubscriptionTopicDispatcher;
048import ca.uhn.fhir.jpa.topic.SubscriptionTopicPayloadBuilder;
049import ca.uhn.fhir.jpa.topic.SubscriptionTopicRegistry;
050import ca.uhn.fhir.jpa.topic.filter.InMemoryTopicFilterMatcher;
051import org.springframework.context.ApplicationContext;
052import org.springframework.context.annotation.Bean;
053import org.springframework.context.annotation.Import;
054import org.springframework.context.annotation.Lazy;
055import org.springframework.context.annotation.Primary;
056import org.springframework.context.annotation.Scope;
057
058/**
059 * This Spring config should be imported by a system that pulls messages off of the
060 * matching queue for processing, and handles delivery
061 */
062@Import(SubscriptionModelConfig.class)
063public class SubscriptionProcessorConfig {
064
065        @Bean
066        public SubscriptionMatchingSubscriber subscriptionMatchingSubscriber() {
067                return new SubscriptionMatchingSubscriber();
068        }
069
070        @Bean
071        public SubscriptionActivatingSubscriber subscriptionActivatingSubscriber() {
072                return new SubscriptionActivatingSubscriber();
073        }
074
075        @Bean
076        public MatchingQueueSubscriberLoader subscriptionMatchingSubscriberLoader() {
077                return new MatchingQueueSubscriberLoader();
078        }
079
080        @Bean
081        public SubscriptionRegisteringSubscriber subscriptionRegisteringSubscriber() {
082                return new SubscriptionRegisteringSubscriber();
083        }
084
085        @Bean
086        public SubscriptionRegistry subscriptionRegistry() {
087                return new SubscriptionRegistry();
088        }
089
090        @Bean
091        public SubscriptionDeliveryChannelNamer subscriptionDeliveryChannelNamer() {
092                return new SubscriptionDeliveryChannelNamer();
093        }
094
095        @Bean
096        public SubscriptionLoader subscriptionLoader() {
097                return new SubscriptionLoader();
098        }
099
100        @Bean
101        public SubscriptionChannelRegistry subscriptionChannelRegistry() {
102                return new SubscriptionChannelRegistry();
103        }
104
105        @Bean
106        public SubscriptionDeliveryHandlerFactory subscriptionDeliveryHandlerFactory(
107                        ApplicationContext theApplicationContext, IEmailSender theEmailSender) {
108                return new SubscriptionDeliveryHandlerFactory(theApplicationContext, theEmailSender);
109        }
110
111        @Bean
112        public SubscriptionMatchDeliverer subscriptionMatchDeliverer(
113                        FhirContext theFhirContext,
114                        IInterceptorBroadcaster theInterceptorBroadcaster,
115                        SubscriptionChannelRegistry theSubscriptionChannelRegistry) {
116                return new SubscriptionMatchDeliverer(
117                                theFhirContext, theInterceptorBroadcaster, theSubscriptionChannelRegistry);
118        }
119
120        @Bean
121        @Scope("prototype")
122        public SubscriptionDeliveringRestHookSubscriber subscriptionDeliveringRestHookSubscriber() {
123                return new SubscriptionDeliveringRestHookSubscriber();
124        }
125
126        @Bean
127        @Scope("prototype")
128        public SubscriptionDeliveringMessageSubscriber subscriptionDeliveringMessageSubscriber(
129                        IChannelFactory theChannelFactory) {
130                return new SubscriptionDeliveringMessageSubscriber(theChannelFactory);
131        }
132
133        @Bean
134        @Scope("prototype")
135        public SubscriptionDeliveringEmailSubscriber subscriptionDeliveringEmailSubscriber(IEmailSender theEmailSender) {
136                return new SubscriptionDeliveringEmailSubscriber(theEmailSender);
137        }
138
139        @Bean
140        public InMemorySubscriptionMatcher inMemorySubscriptionMatcher() {
141                return new InMemorySubscriptionMatcher();
142        }
143
144        @Bean
145        public DaoSubscriptionMatcher daoSubscriptionMatcher() {
146                return new DaoSubscriptionMatcher();
147        }
148
149        @Bean
150        @Primary
151        public ISubscriptionMatcher subscriptionMatcher(
152                        DaoSubscriptionMatcher theDaoSubscriptionMatcher,
153                        InMemorySubscriptionMatcher theInMemorySubscriptionMatcher) {
154                return new CompositeInMemoryDaoSubscriptionMatcher(theDaoSubscriptionMatcher, theInMemorySubscriptionMatcher);
155        }
156
157        @Lazy
158        @Bean
159        SubscriptionTopicPayloadBuilder subscriptionTopicPayloadBuilder(
160                        FhirContext theFhirContext,
161                        DaoRegistry theDaoRegistry,
162                        SubscriptionTopicRegistry theSubscriptionTopicRegistry,
163                        MatchUrlService theMatchUrlService) {
164                switch (theFhirContext.getVersion().getVersion()) {
165                        case R4:
166                        case R4B:
167                        case R5:
168                                return new SubscriptionTopicPayloadBuilder(
169                                                theFhirContext, theDaoRegistry, theSubscriptionTopicRegistry, theMatchUrlService);
170                        default:
171                                return null;
172                }
173        }
174
175        @Lazy
176        @Bean
177        SubscriptionTopicDispatcher subscriptionTopicDispatcher(
178                        FhirContext theFhirContext,
179                        SubscriptionRegistry theSubscriptionRegistry,
180                        SubscriptionMatchDeliverer theSubscriptionMatchDeliverer,
181                        SubscriptionTopicPayloadBuilder theSubscriptionTopicPayloadBuilder) {
182                return new SubscriptionTopicDispatcher(
183                                theFhirContext,
184                                theSubscriptionRegistry,
185                                theSubscriptionMatchDeliverer,
186                                theSubscriptionTopicPayloadBuilder);
187        }
188
189        @Bean
190        InMemoryTopicFilterMatcher inMemoryTopicFilterMatcher(SearchParamMatcher theSearchParamMatcher) {
191                return new InMemoryTopicFilterMatcher(theSearchParamMatcher);
192        }
193}