
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}