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