
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}