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