001/*
002 * #%L
003 * HAPI FHIR JPA 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.config;
021
022import ca.uhn.fhir.batch2.api.IJobCoordinator;
023import ca.uhn.fhir.batch2.api.IJobPersistence;
024import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider;
025import ca.uhn.fhir.batch2.jobs.expunge.DeleteExpungeJobSubmitterImpl;
026import ca.uhn.fhir.batch2.util.Batch2TaskHelper;
027import ca.uhn.fhir.context.FhirContext;
028import ca.uhn.fhir.context.FhirVersionEnum;
029import ca.uhn.fhir.context.support.IValidationSupport;
030import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
031import ca.uhn.fhir.interceptor.api.IInterceptorService;
032import ca.uhn.fhir.interceptor.executor.InterceptorService;
033import ca.uhn.fhir.interceptor.model.RequestPartitionId;
034import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
035import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
036import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
037import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
038import ca.uhn.fhir.jpa.api.svc.ISearchUrlJobMaintenanceSvc;
039import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
040import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
041import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
042import ca.uhn.fhir.jpa.bulk.export.svc.BulkDataExportJobSchedulingHelperImpl;
043import ca.uhn.fhir.jpa.bulk.export.svc.BulkExportHelperService;
044import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc;
045import ca.uhn.fhir.jpa.bulk.imprt.svc.BulkDataImportSvcImpl;
046import ca.uhn.fhir.jpa.cache.IResourceTypeCacheSvc;
047import ca.uhn.fhir.jpa.cache.IResourceVersionSvc;
048import ca.uhn.fhir.jpa.cache.ISearchParamIdentityCacheSvc;
049import ca.uhn.fhir.jpa.cache.ResourceTypeCacheSvcImpl;
050import ca.uhn.fhir.jpa.cache.ResourceVersionSvcDaoImpl;
051import ca.uhn.fhir.jpa.dao.CacheTagDefinitionDao;
052import ca.uhn.fhir.jpa.dao.DaoSearchParamProvider;
053import ca.uhn.fhir.jpa.dao.HistoryBuilder;
054import ca.uhn.fhir.jpa.dao.HistoryBuilderFactory;
055import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
056import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
057import ca.uhn.fhir.jpa.dao.ISearchBuilder;
058import ca.uhn.fhir.jpa.dao.JpaStorageResourceParser;
059import ca.uhn.fhir.jpa.dao.MatchResourceUrlService;
060import ca.uhn.fhir.jpa.dao.ResourceHistoryCalculator;
061import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
062import ca.uhn.fhir.jpa.dao.TransactionProcessor;
063import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamIdentityDao;
064import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
065import ca.uhn.fhir.jpa.dao.data.IResourceModifiedDao;
066import ca.uhn.fhir.jpa.dao.data.IResourceSearchUrlDao;
067import ca.uhn.fhir.jpa.dao.data.IResourceTypeDao;
068import ca.uhn.fhir.jpa.dao.data.ITagDefinitionDao;
069import ca.uhn.fhir.jpa.dao.expunge.ExpungeEverythingService;
070import ca.uhn.fhir.jpa.dao.expunge.ExpungeOperation;
071import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
072import ca.uhn.fhir.jpa.dao.expunge.IExpungeEverythingService;
073import ca.uhn.fhir.jpa.dao.expunge.IResourceExpungeService;
074import ca.uhn.fhir.jpa.dao.expunge.JpaResourceExpungeService;
075import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider;
076import ca.uhn.fhir.jpa.dao.index.DaoResourceLinkResolver;
077import ca.uhn.fhir.jpa.dao.index.DaoSearchParamSynchronizer;
078import ca.uhn.fhir.jpa.dao.index.IdHelperService;
079import ca.uhn.fhir.jpa.dao.index.SearchParamWithInlineReferencesExtractor;
080import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
081import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
082import ca.uhn.fhir.jpa.dao.validation.SearchParameterDaoValidator;
083import ca.uhn.fhir.jpa.delete.DeleteConflictFinderService;
084import ca.uhn.fhir.jpa.delete.DeleteConflictService;
085import ca.uhn.fhir.jpa.delete.ThreadSafeResourceDeleterSvc;
086import ca.uhn.fhir.jpa.entity.Search;
087import ca.uhn.fhir.jpa.entity.TermValueSet;
088import ca.uhn.fhir.jpa.esr.ExternallyStoredResourceServiceRegistry;
089import ca.uhn.fhir.jpa.graphql.DaoRegistryGraphQLStorageServices;
090import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
091import ca.uhn.fhir.jpa.interceptor.JpaConsentContextServices;
092import ca.uhn.fhir.jpa.interceptor.OverridePathBasedReferentialIntegrityForDeletesInterceptor;
093import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder;
094import ca.uhn.fhir.jpa.model.config.PartitionSettings;
095import ca.uhn.fhir.jpa.model.dao.JpaPid;
096import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
097import ca.uhn.fhir.jpa.packages.IHapiPackageCacheManager;
098import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
099import ca.uhn.fhir.jpa.packages.JpaPackageCache;
100import ca.uhn.fhir.jpa.packages.NpmJpaValidationSupport;
101import ca.uhn.fhir.jpa.packages.PackageInstallerSvcImpl;
102import ca.uhn.fhir.jpa.packages.util.PackageUtils;
103import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
104import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
105import ca.uhn.fhir.jpa.partition.PartitionLookupSvcImpl;
106import ca.uhn.fhir.jpa.partition.PartitionManagementProvider;
107import ca.uhn.fhir.jpa.partition.RequestPartitionHelperSvc;
108import ca.uhn.fhir.jpa.provider.DiffProvider;
109import ca.uhn.fhir.jpa.provider.IReplaceReferencesSvc;
110import ca.uhn.fhir.jpa.provider.InstanceReindexProvider;
111import ca.uhn.fhir.jpa.provider.ProcessMessageProvider;
112import ca.uhn.fhir.jpa.provider.ReplaceReferencesSvcImpl;
113import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
114import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
115import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
116import ca.uhn.fhir.jpa.provider.ValueSetOperationProviderDstu2;
117import ca.uhn.fhir.jpa.sched.AutowiringSpringBeanJobFactory;
118import ca.uhn.fhir.jpa.sched.HapiSchedulerServiceImpl;
119import ca.uhn.fhir.jpa.search.ISynchronousSearchSvc;
120import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
121import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory;
122import ca.uhn.fhir.jpa.search.PersistedJpaSearchFirstPageBundleProvider;
123import ca.uhn.fhir.jpa.search.ResourceSearchUrlSvc;
124import ca.uhn.fhir.jpa.search.SearchStrategyFactory;
125import ca.uhn.fhir.jpa.search.SearchUrlJobMaintenanceSvcImpl;
126import ca.uhn.fhir.jpa.search.SynchronousSearchSvcImpl;
127import ca.uhn.fhir.jpa.search.builder.QueryStack;
128import ca.uhn.fhir.jpa.search.builder.predicate.ComboNonUniqueSearchParameterPredicateBuilder;
129import ca.uhn.fhir.jpa.search.builder.predicate.ComboUniqueSearchParameterPredicateBuilder;
130import ca.uhn.fhir.jpa.search.builder.predicate.CoordsPredicateBuilder;
131import ca.uhn.fhir.jpa.search.builder.predicate.DatePredicateBuilder;
132import ca.uhn.fhir.jpa.search.builder.predicate.NumberPredicateBuilder;
133import ca.uhn.fhir.jpa.search.builder.predicate.QuantityNormalizedPredicateBuilder;
134import ca.uhn.fhir.jpa.search.builder.predicate.QuantityPredicateBuilder;
135import ca.uhn.fhir.jpa.search.builder.predicate.ResourceHistoryPredicateBuilder;
136import ca.uhn.fhir.jpa.search.builder.predicate.ResourceHistoryProvenancePredicateBuilder;
137import ca.uhn.fhir.jpa.search.builder.predicate.ResourceIdPredicateBuilder;
138import ca.uhn.fhir.jpa.search.builder.predicate.ResourceLinkPredicateBuilder;
139import ca.uhn.fhir.jpa.search.builder.predicate.ResourceTablePredicateBuilder;
140import ca.uhn.fhir.jpa.search.builder.predicate.SearchParamPresentPredicateBuilder;
141import ca.uhn.fhir.jpa.search.builder.predicate.StringPredicateBuilder;
142import ca.uhn.fhir.jpa.search.builder.predicate.TagPredicateBuilder;
143import ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder;
144import ca.uhn.fhir.jpa.search.builder.predicate.UriPredicateBuilder;
145import ca.uhn.fhir.jpa.search.builder.sql.GeneratedSql;
146import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
147import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryExecutor;
148import ca.uhn.fhir.jpa.search.builder.sql.SqlObjectFactory;
149import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask;
150import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl;
151import ca.uhn.fhir.jpa.search.cache.DatabaseSearchResultCacheSvcImpl;
152import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
153import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
154import ca.uhn.fhir.jpa.search.elastic.IndexNamePrefixLayoutStrategy;
155import ca.uhn.fhir.jpa.search.reindex.IInstanceReindexService;
156import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
157import ca.uhn.fhir.jpa.search.reindex.InstanceReindexServiceImpl;
158import ca.uhn.fhir.jpa.search.reindex.ResourceReindexer;
159import ca.uhn.fhir.jpa.search.reindex.ResourceReindexingSvcImpl;
160import ca.uhn.fhir.jpa.search.warm.CacheWarmingSvcImpl;
161import ca.uhn.fhir.jpa.search.warm.ICacheWarmingSvc;
162import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
163import ca.uhn.fhir.jpa.searchparam.config.SearchParamConfig;
164import ca.uhn.fhir.jpa.searchparam.extractor.IResourceLinkResolver;
165import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
166import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
167import ca.uhn.fhir.jpa.sp.SearchParamIdentityCacheSvcImpl;
168import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
169import ca.uhn.fhir.jpa.subscription.ResourceModifiedMessagePersistenceSvcImpl;
170import ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl;
171import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
172import ca.uhn.fhir.jpa.term.TermReadSvcImpl;
173import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
174import ca.uhn.fhir.jpa.term.ValueSetConceptAccumulator;
175import ca.uhn.fhir.jpa.term.ValueSetConceptAccumulatorFactory;
176import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
177import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
178import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
179import ca.uhn.fhir.jpa.term.api.ITermReindexingSvc;
180import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
181import ca.uhn.fhir.jpa.util.JpaHapiTransactionService;
182import ca.uhn.fhir.jpa.util.MemoryCacheService;
183import ca.uhn.fhir.jpa.util.PartitionedIdModeVerificationSvc;
184import ca.uhn.fhir.jpa.util.PersistenceContextProvider;
185import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain;
186import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl;
187import ca.uhn.fhir.jpa.validation.ValidationSettings;
188import ca.uhn.fhir.model.api.IPrimitiveDatatype;
189import ca.uhn.fhir.replacereferences.ReplaceReferencesPatchBundleSvc;
190import ca.uhn.fhir.rest.api.server.RequestDetails;
191import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter;
192import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
193import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationInterceptor;
194import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationSvc;
195import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
196import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
197import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
198import ca.uhn.fhir.subscription.api.IResourceModifiedMessagePersistenceSvc;
199import ca.uhn.fhir.util.IMetaTagSorter;
200import ca.uhn.fhir.util.MetaTagSorterAlphabetical;
201import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
202import jakarta.annotation.Nullable;
203import org.hl7.fhir.common.hapi.validation.support.UnknownCodeSystemWarningValidationSupport;
204import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
205import org.hl7.fhir.common.hapi.validation.validator.WorkerContextValidationSupportAdapter;
206import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
207import org.springframework.beans.factory.annotation.Autowired;
208import org.springframework.context.annotation.Bean;
209import org.springframework.context.annotation.Configuration;
210import org.springframework.context.annotation.Import;
211import org.springframework.context.annotation.Lazy;
212import org.springframework.context.annotation.Primary;
213import org.springframework.context.annotation.Scope;
214import org.springframework.core.task.AsyncTaskExecutor;
215import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean;
216import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
217import org.springframework.scheduling.TaskScheduler;
218import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
219import org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean;
220import org.springframework.transaction.PlatformTransactionManager;
221
222import java.util.Date;
223
224@Configuration
225// repositoryFactoryBeanClass: EnversRevisionRepositoryFactoryBean is needed primarily for unit testing
226@EnableJpaRepositories(
227                basePackages = "ca.uhn.fhir.jpa.dao.data",
228                repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
229@Import({
230        BeanPostProcessorConfig.class,
231        TermCodeSystemConfig.class,
232        SearchParamConfig.class,
233        ValidationSupportConfig.class,
234        Batch2SupportConfig.class,
235        JpaBulkExportConfig.class,
236        SearchConfig.class,
237        PackageLoaderConfig.class,
238        EnversAuditConfig.class,
239        MdmJpaConfig.class
240})
241public class JpaConfig {
242        public static final String JPA_VALIDATION_SUPPORT_CHAIN = "myJpaValidationSupportChain";
243        public static final String JPA_VALIDATION_SUPPORT = "myJpaValidationSupport";
244        public static final String TASK_EXECUTOR_NAME = "hapiJpaTaskExecutor";
245        public static final String GRAPHQL_PROVIDER_NAME = "myGraphQLProvider";
246        public static final String PERSISTED_JPA_BUNDLE_PROVIDER = "PersistedJpaBundleProvider";
247        public static final String PERSISTED_JPA_BUNDLE_PROVIDER_BY_SEARCH = "PersistedJpaBundleProvider_BySearch";
248        public static final String PERSISTED_JPA_SEARCH_FIRST_PAGE_BUNDLE_PROVIDER =
249                        "PersistedJpaSearchFirstPageBundleProvider";
250        public static final String HISTORY_BUILDER = "HistoryBuilder";
251        public static final String DEFAULT_PROFILE_VALIDATION_SUPPORT = "myDefaultProfileValidationSupport";
252        private static final String HAPI_DEFAULT_SCHEDULER_GROUP = "HAPI";
253
254        @Autowired
255        public JpaStorageSettings myStorageSettings;
256
257        @Autowired
258        private PartitionSettings myPartitionSettings;
259
260        @Autowired
261        private FhirContext myFhirContext;
262
263        @Bean
264        public ValidationSupportChain.CacheConfiguration validationSupportChainCacheConfiguration() {
265                return ValidationSupportChain.CacheConfiguration.defaultValues();
266        }
267
268        /**
269         * Note, there is a circular dependency between {@link WorkerContextValidationSupportAdapter}
270         * and {@link JpaValidationSupportChain}. The WorkerContextValidationSupportAdapter wraps
271         * an instance of {@link IValidationSupport} (which is what JpaValidationSupportChain is)
272         * but we also need to pass in the WorkerContextValidationSupportAdapter instance to the
273         * snapshot generator which is created within the {@literal @PostConstruct} method within
274         * JpaValidationSupportChain.
275         * <p>
276         * In order to allow the circular dependency to be created (since Spring doesn't like
277         * these), JpaValidationSupportChain calls {@link WorkerContextValidationSupportAdapter#setValidationSupport(IValidationSupport)}
278         * to pass itself in.
279         * </p>
280         * <p>
281         * This is obviously not ideal, but is the best we can do since the corelib
282         * tools all use {@link org.hl7.fhir.r5.context.IWorkerContext} interface as their
283         * input. See {@link WorkerContextValidationSupportAdapter} for more info.
284         * </p>
285         */
286        @Bean
287        public WorkerContextValidationSupportAdapter workerContextValidationSupportAdapter() {
288                return new WorkerContextValidationSupportAdapter();
289        }
290
291        @Bean(name = JpaConfig.JPA_VALIDATION_SUPPORT_CHAIN)
292        @Primary
293        public IValidationSupport jpaValidationSupportChain() {
294                return new JpaValidationSupportChain(
295                                myFhirContext, validationSupportChainCacheConfiguration(), workerContextValidationSupportAdapter());
296        }
297
298        @Bean("myDaoRegistry")
299        public DaoRegistry daoRegistry() {
300                return new DaoRegistry();
301        }
302
303        @Lazy
304        @Bean
305        public CascadingDeleteInterceptor cascadingDeleteInterceptor(
306                        FhirContext theFhirContext,
307                        DaoRegistry theDaoRegistry,
308                        IInterceptorBroadcaster theInterceptorBroadcaster,
309                        ThreadSafeResourceDeleterSvc threadSafeResourceDeleterSvc) {
310                return new CascadingDeleteInterceptor(
311                                theFhirContext, theDaoRegistry, theInterceptorBroadcaster, threadSafeResourceDeleterSvc);
312        }
313
314        @Bean
315        public ExternallyStoredResourceServiceRegistry ExternallyStoredResourceServiceRegistry() {
316                return new ExternallyStoredResourceServiceRegistry();
317        }
318
319        @Lazy
320        @Bean
321        public ThreadSafeResourceDeleterSvc safeDeleter(
322                        DaoRegistry theDaoRegistry,
323                        IInterceptorBroadcaster theInterceptorBroadcaster,
324                        HapiTransactionService hapiTransactionService) {
325                return new ThreadSafeResourceDeleterSvc(theDaoRegistry, theInterceptorBroadcaster, hapiTransactionService);
326        }
327
328        @Lazy
329        @Bean
330        public ResponseTerminologyTranslationInterceptor responseTerminologyTranslationInterceptor(
331                        IValidationSupport theValidationSupport,
332                        ResponseTerminologyTranslationSvc theResponseTerminologyTranslationSvc) {
333                return new ResponseTerminologyTranslationInterceptor(
334                                theValidationSupport, theResponseTerminologyTranslationSvc);
335        }
336
337        @Bean
338        public ResponseTerminologyTranslationSvc responseTerminologyTranslationSvc(
339                        IValidationSupport theValidationSupport) {
340                return new ResponseTerminologyTranslationSvc(theValidationSupport);
341        }
342
343        @Bean
344        @Lazy
345        public IGraphQLStorageServices graphqlStorageServices() {
346                return new DaoRegistryGraphQLStorageServices();
347        }
348
349        @Bean
350        public ScheduledExecutorFactoryBean scheduledExecutorService() {
351                ScheduledExecutorFactoryBean b = new ScheduledExecutorFactoryBean();
352                b.setPoolSize(5);
353                b.afterPropertiesSet();
354                return b;
355        }
356
357        @Bean(name = "mySubscriptionTriggeringProvider")
358        @Lazy
359        public SubscriptionTriggeringProvider subscriptionTriggeringProvider() {
360                return new SubscriptionTriggeringProvider();
361        }
362
363        @Bean
364        @Lazy
365        public ValueSetOperationProvider valueSetOperationProvider(FhirContext theFhirContext) {
366                if (theFhirContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) {
367                        return new ValueSetOperationProviderDstu2();
368                }
369                return new ValueSetOperationProvider();
370        }
371
372        @Bean
373        public IJpaStorageResourceParser jpaStorageResourceParser() {
374                return new JpaStorageResourceParser();
375        }
376
377        @Bean
378        public TransactionProcessor transactionProcessor() {
379                return new TransactionProcessor();
380        }
381
382        @Bean(name = "myAttachmentBinaryAccessProvider")
383        @Lazy
384        public BinaryAccessProvider binaryAccessProvider() {
385                return new BinaryAccessProvider();
386        }
387
388        @Bean(name = "myBinaryStorageInterceptor")
389        @Lazy
390        public BinaryStorageInterceptor<? extends IPrimitiveDatatype<byte[]>> binaryStorageInterceptor(
391                        JpaStorageSettings theStorageSettings, FhirContext theCtx) {
392                BinaryStorageInterceptor<? extends IPrimitiveDatatype<byte[]>> interceptor =
393                                new BinaryStorageInterceptor<>(theCtx);
394                interceptor.setAllowAutoInflateBinaries(theStorageSettings.isAllowAutoInflateBinaries());
395                interceptor.setAutoInflateBinariesMaximumSize(theStorageSettings.getAutoInflateBinariesMaximumBytes());
396                return interceptor;
397        }
398
399        @Bean
400        public MemoryCacheService memoryCacheService(JpaStorageSettings theStorageSettings) {
401                return new MemoryCacheService(theStorageSettings);
402        }
403
404        @Bean
405        @Primary
406        public IResourceLinkResolver daoResourceLinkResolver() {
407                return new DaoResourceLinkResolver<JpaPid>();
408        }
409
410        @Bean(name = PackageUtils.LOADER_WITH_CACHE)
411        public IHapiPackageCacheManager packageCacheManager() {
412                return new JpaPackageCache();
413        }
414
415        @Bean
416        public NpmJpaValidationSupport npmJpaValidationSupport() {
417                return new NpmJpaValidationSupport();
418        }
419
420        @Bean
421        public ValidationSettings validationSettings() {
422                return new ValidationSettings();
423        }
424
425        @Bean
426        public ISearchCacheSvc searchCacheSvc() {
427                return new DatabaseSearchCacheSvcImpl();
428        }
429
430        @Bean
431        public ISearchResultCacheSvc searchResultCacheSvc() {
432                return new DatabaseSearchResultCacheSvcImpl();
433        }
434
435        @Bean
436        public ITermConceptMappingSvc termConceptMappingSvc() {
437                return new TermConceptMappingSvcImpl();
438        }
439
440        @Bean
441        public TaskScheduler taskScheduler() {
442                ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler(
443                                scheduledExecutorService().getObject(),
444                                scheduledExecutorService().getObject());
445                return retVal;
446        }
447
448        @Bean(name = TASK_EXECUTOR_NAME)
449        public AsyncTaskExecutor taskExecutor() {
450                ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler(
451                                scheduledExecutorService().getObject(),
452                                scheduledExecutorService().getObject());
453                return retVal;
454        }
455
456        @Bean
457        public IResourceReindexingSvc resourceReindexingSvc() {
458                return new ResourceReindexingSvcImpl();
459        }
460
461        @Bean
462        @Lazy
463        public IInstanceReindexService instanceReindexService() {
464                return new InstanceReindexServiceImpl();
465        }
466
467        @Bean
468        @Lazy
469        public InstanceReindexProvider instanceReindexProvider(IInstanceReindexService theInstanceReindexService) {
470                return new InstanceReindexProvider(theInstanceReindexService);
471        }
472
473        @Bean
474        public ResourceReindexer resourceReindexer(FhirContext theFhirContext) {
475                return new ResourceReindexer(theFhirContext);
476        }
477
478        @Bean
479        public HapiFhirHibernateJpaDialect hibernateJpaDialect(FhirContext theFhirContext) {
480                return new HapiFhirHibernateJpaDialect(theFhirContext.getLocalizer());
481        }
482
483        @Bean
484        @Lazy
485        public OverridePathBasedReferentialIntegrityForDeletesInterceptor
486                        overridePathBasedReferentialIntegrityForDeletesInterceptor() {
487                return new OverridePathBasedReferentialIntegrityForDeletesInterceptor();
488        }
489
490        @Bean
491        public IRequestPartitionHelperSvc requestPartitionHelperService() {
492                return new RequestPartitionHelperSvc();
493        }
494
495        @Bean
496        public HapiTransactionService hapiTransactionService() {
497                return new JpaHapiTransactionService();
498        }
499
500        @Bean
501        public IInterceptorService jpaInterceptorService() {
502                return new InterceptorService();
503        }
504
505        @Bean
506        public IPackageInstallerSvc npmInstallerSvc() {
507                return new PackageInstallerSvcImpl();
508        }
509
510        @Bean
511        public IConsentContextServices consentContextServices() {
512                return new JpaConsentContextServices();
513        }
514
515        @Bean
516        @Lazy
517        public DiffProvider diffProvider() {
518                return new DiffProvider();
519        }
520
521        @Bean
522        @Lazy
523        public IPartitionLookupSvc partitionConfigSvc() {
524                return new PartitionLookupSvcImpl();
525        }
526
527        @Bean
528        @Lazy
529        public PartitionManagementProvider partitionManagementProvider() {
530                return new PartitionManagementProvider();
531        }
532
533        @Bean
534        @Lazy
535        public RequestTenantPartitionInterceptor requestTenantPartitionInterceptor() {
536                return new RequestTenantPartitionInterceptor();
537        }
538
539        @Bean
540        @Lazy
541        public TerminologyUploaderProvider terminologyUploaderProvider() {
542                return new TerminologyUploaderProvider();
543        }
544
545        @Bean
546        @Lazy
547        public ProcessMessageProvider processMessageProvider() {
548                return new ProcessMessageProvider();
549        }
550
551        @Bean
552        public ISchedulerService schedulerService() {
553                return new HapiSchedulerServiceImpl().setDefaultGroup(HAPI_DEFAULT_SCHEDULER_GROUP);
554        }
555
556        @Bean
557        public AutowiringSpringBeanJobFactory schedulerJobFactory() {
558                return new AutowiringSpringBeanJobFactory();
559        }
560
561        @Bean
562        public IBulkDataExportJobSchedulingHelper bulkDataExportJobSchedulingHelper(
563                        DaoRegistry theDaoRegistry,
564                        PlatformTransactionManager theTxManager,
565                        JpaStorageSettings theStorageSettings,
566                        BulkExportHelperService theBulkExportHelperSvc,
567                        IJobPersistence theJpaJobPersistence) {
568                return new BulkDataExportJobSchedulingHelperImpl(
569                                theDaoRegistry, theTxManager, theStorageSettings, theBulkExportHelperSvc, theJpaJobPersistence, null);
570        }
571
572        @Bean
573        @Lazy
574        public BulkDataExportProvider bulkDataExportProvider() {
575                return new BulkDataExportProvider();
576        }
577
578        @Bean
579        @Lazy
580        public IDeleteExpungeJobSubmitter deleteExpungeJobSubmitter() {
581                return new DeleteExpungeJobSubmitterImpl();
582        }
583
584        @Bean
585        @Lazy
586        public IBulkDataImportSvc bulkDataImportSvc() {
587                return new BulkDataImportSvcImpl();
588        }
589
590        @Bean
591        public PersistedJpaBundleProviderFactory persistedJpaBundleProviderFactory() {
592                return new PersistedJpaBundleProviderFactory();
593        }
594
595        @Bean
596        public SearchBuilderFactory searchBuilderFactory() {
597                return new SearchBuilderFactory();
598        }
599
600        @Bean
601        public SqlObjectFactory sqlBuilderFactory() {
602                return new SqlObjectFactory();
603        }
604
605        @Bean
606        public HibernatePropertiesProvider HibernatePropertiesProvider() {
607                return new HibernatePropertiesProvider();
608        }
609
610        @Bean
611        public HistoryBuilderFactory historyBuilderFactory() {
612                return new HistoryBuilderFactory();
613        }
614
615        @Bean
616        public IResourceVersionSvc resourceVersionSvc() {
617                return new ResourceVersionSvcDaoImpl();
618        }
619
620        @Bean
621        public ISearchParamIdentityCacheSvc searchParamIdentityCacheSvc(
622                        @Autowired IResourceIndexedSearchParamIdentityDao theResourceIndexedSearchParamIdentityDao,
623                        @Autowired PlatformTransactionManager theTxManager,
624                        @Autowired MemoryCacheService theMemoryCacheService) {
625                return new SearchParamIdentityCacheSvcImpl(
626                                myStorageSettings, theResourceIndexedSearchParamIdentityDao, theTxManager, theMemoryCacheService);
627        }
628
629        @Bean
630        public IResourceTypeCacheSvc resourceTypeCacheSvc(
631                        @Autowired IHapiTransactionService theHapiTransactionService,
632                        @Autowired IResourceTypeDao theResourceTypeDao,
633                        @Autowired MemoryCacheService theMemoryCacheService) {
634                return new ResourceTypeCacheSvcImpl(theHapiTransactionService, theResourceTypeDao, theMemoryCacheService);
635        }
636
637        /* **************************************************************** *
638         * Prototype Beans Below                                            *
639         * **************************************************************** */
640
641        @Bean(name = PERSISTED_JPA_BUNDLE_PROVIDER)
642        @Scope("prototype")
643        public PersistedJpaBundleProvider newPersistedJpaBundleProvider(RequestDetails theRequest, String theUuid) {
644                return new PersistedJpaBundleProvider(theRequest, theUuid);
645        }
646
647        @Bean(name = PERSISTED_JPA_BUNDLE_PROVIDER_BY_SEARCH)
648        @Scope("prototype")
649        public PersistedJpaBundleProvider newPersistedJpaBundleProviderBySearch(
650                        RequestDetails theRequest, Search theSearch) {
651                return new PersistedJpaBundleProvider(theRequest, theSearch);
652        }
653
654        @Bean(name = PERSISTED_JPA_SEARCH_FIRST_PAGE_BUNDLE_PROVIDER)
655        @Scope("prototype")
656        public PersistedJpaSearchFirstPageBundleProvider newPersistedJpaSearchFirstPageBundleProvider(
657                        RequestDetails theRequest,
658                        SearchTask theSearchTask,
659                        ISearchBuilder theSearchBuilder,
660                        RequestPartitionId theRequestPartitionId) {
661                return new PersistedJpaSearchFirstPageBundleProvider(
662                                theSearchTask, theSearchBuilder, theRequest, theRequestPartitionId);
663        }
664
665        @Bean(name = RepositoryValidatingRuleBuilder.REPOSITORY_VALIDATING_RULE_BUILDER)
666        @Scope("prototype")
667        public RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder(IValidationSupport theValidationSupport) {
668                return new RepositoryValidatingRuleBuilder(theValidationSupport);
669        }
670
671        @Bean
672        @Scope("prototype")
673        public ComboUniqueSearchParameterPredicateBuilder newComboUniqueSearchParameterPredicateBuilder(
674                        SearchQueryBuilder theSearchSqlBuilder) {
675                return new ComboUniqueSearchParameterPredicateBuilder(theSearchSqlBuilder);
676        }
677
678        @Bean
679        @Scope("prototype")
680        public ComboNonUniqueSearchParameterPredicateBuilder newComboNonUniqueSearchParameterPredicateBuilder(
681                        SearchQueryBuilder theSearchSqlBuilder) {
682                return new ComboNonUniqueSearchParameterPredicateBuilder(theSearchSqlBuilder);
683        }
684
685        @Bean
686        @Scope("prototype")
687        public CoordsPredicateBuilder newCoordsPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
688                return new CoordsPredicateBuilder(theSearchBuilder);
689        }
690
691        @Bean
692        @Scope("prototype")
693        public DatePredicateBuilder newDatePredicateBuilder(SearchQueryBuilder theSearchBuilder) {
694                return new DatePredicateBuilder(theSearchBuilder);
695        }
696
697        @Bean
698        @Scope("prototype")
699        public NumberPredicateBuilder newNumberPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
700                return new NumberPredicateBuilder(theSearchBuilder);
701        }
702
703        @Bean
704        @Scope("prototype")
705        public QuantityPredicateBuilder newQuantityPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
706                return new QuantityPredicateBuilder(theSearchBuilder);
707        }
708
709        @Bean
710        @Scope("prototype")
711        public QuantityNormalizedPredicateBuilder newQuantityNormalizedPredicateBuilder(
712                        SearchQueryBuilder theSearchBuilder) {
713                return new QuantityNormalizedPredicateBuilder(theSearchBuilder);
714        }
715
716        @Bean
717        @Scope("prototype")
718        public ResourceLinkPredicateBuilder newResourceLinkPredicateBuilder(
719                        QueryStack theQueryStack, SearchQueryBuilder theSearchBuilder, boolean theReversed) {
720                return new ResourceLinkPredicateBuilder(theQueryStack, theSearchBuilder, theReversed);
721        }
722
723        @Bean
724        @Scope("prototype")
725        public ResourceTablePredicateBuilder newResourceTablePredicateBuilder(SearchQueryBuilder theSearchBuilder) {
726                return new ResourceTablePredicateBuilder(theSearchBuilder);
727        }
728
729        @Bean
730        @Scope("prototype")
731        public TagPredicateBuilder newTagPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
732                return new TagPredicateBuilder(theSearchBuilder);
733        }
734
735        @Bean
736        @Scope("prototype")
737        public ResourceIdPredicateBuilder newResourceIdPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
738                return new ResourceIdPredicateBuilder(theSearchBuilder);
739        }
740
741        @Bean
742        @Scope("prototype")
743        public SearchParamPresentPredicateBuilder newSearchParamPresentPredicateBuilder(
744                        SearchQueryBuilder theSearchBuilder) {
745                return new SearchParamPresentPredicateBuilder(theSearchBuilder);
746        }
747
748        @Bean
749        @Scope("prototype")
750        public StringPredicateBuilder newStringPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
751                return new StringPredicateBuilder(theSearchBuilder);
752        }
753
754        @Bean
755        @Scope("prototype")
756        public TokenPredicateBuilder newTokenPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
757                return new TokenPredicateBuilder(theSearchBuilder);
758        }
759
760        @Bean
761        @Scope("prototype")
762        public ResourceHistoryPredicateBuilder newResourceHistoryPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
763                return new ResourceHistoryPredicateBuilder(theSearchBuilder);
764        }
765
766        @Bean
767        @Scope("prototype")
768        public ResourceHistoryProvenancePredicateBuilder newResourceHistoryProvenancePredicateBuilder(
769                        SearchQueryBuilder theSearchBuilder) {
770                return new ResourceHistoryProvenancePredicateBuilder(theSearchBuilder);
771        }
772
773        @Bean
774        @Scope("prototype")
775        public UriPredicateBuilder newUriPredicateBuilder(SearchQueryBuilder theSearchBuilder) {
776                return new UriPredicateBuilder(theSearchBuilder);
777        }
778
779        @Bean
780        @Scope("prototype")
781        public SearchQueryExecutor newSearchQueryExecutor(GeneratedSql theGeneratedSql, Integer theMaxResultsToFetch) {
782                return new SearchQueryExecutor(theGeneratedSql, theMaxResultsToFetch);
783        }
784
785        @Bean(name = HISTORY_BUILDER)
786        @Scope("prototype")
787        public HistoryBuilder newHistoryBuilder(
788                        @Nullable String theResourceType,
789                        @Nullable JpaPid theResourceId,
790                        @Nullable Date theRangeStartInclusive,
791                        @Nullable Date theRangeEndInclusive) {
792                return new HistoryBuilder(theResourceType, theResourceId, theRangeStartInclusive, theRangeEndInclusive);
793        }
794
795        @Bean
796        @Primary
797        public ISearchParamProvider searchParamProvider() {
798                return new DaoSearchParamProvider();
799        }
800
801        @Bean
802        public IIdHelperService idHelperService() {
803                return new IdHelperService();
804        }
805
806        @Bean
807        public SearchStrategyFactory searchStrategyFactory(@Autowired(required = false) IFulltextSearchSvc theFulltextSvc) {
808                return new SearchStrategyFactory(myStorageSettings, theFulltextSvc);
809        }
810
811        @Bean
812        public DeleteConflictService deleteConflictService() {
813                return new DeleteConflictService();
814        }
815
816        @Bean
817        public DeleteConflictFinderService deleteConflictFinderService() {
818                return new DeleteConflictFinderService();
819        }
820
821        @Bean
822        public ExpungeService expungeService() {
823                return new ExpungeService();
824        }
825
826        @Bean
827        @Scope("prototype")
828        public ExpungeOperation expungeOperation(
829                        String theResourceName,
830                        IResourcePersistentId theResourceId,
831                        ExpungeOptions theExpungeOptions,
832                        RequestDetails theRequestDetails) {
833                return new ExpungeOperation(theResourceName, theResourceId, theExpungeOptions, theRequestDetails);
834        }
835
836        @Bean
837        public IExpungeEverythingService expungeEverythingService() {
838                return new ExpungeEverythingService();
839        }
840
841        @Bean
842        public IResourceExpungeService resourceExpungeService() {
843                return new JpaResourceExpungeService();
844        }
845
846        @Bean
847        public ISearchParamPresenceSvc searchParamPresenceService() {
848                return new SearchParamPresenceSvcImpl();
849        }
850
851        @Bean
852        public SearchParamWithInlineReferencesExtractor searchParamWithInlineReferencesExtractor() {
853                return new SearchParamWithInlineReferencesExtractor();
854        }
855
856        @Bean
857        public MatchResourceUrlService matchResourceUrlService() {
858                return new MatchResourceUrlService();
859        }
860
861        @Bean
862        public DaoSearchParamSynchronizer daoSearchParamSynchronizer() {
863                return new DaoSearchParamSynchronizer();
864        }
865
866        @Bean
867        public ResourceTableFKProvider resourceTableFKProvider() {
868                return new ResourceTableFKProvider();
869        }
870
871        @Bean
872        public ICacheWarmingSvc cacheWarmingSvc() {
873                return new CacheWarmingSvcImpl();
874        }
875
876        @Bean
877        public IndexNamePrefixLayoutStrategy indexLayoutStrategy() {
878                return new IndexNamePrefixLayoutStrategy();
879        }
880
881        @Bean
882        public ResourceLoaderImpl jpaResourceLoader() {
883                return new ResourceLoaderImpl();
884        }
885
886        @Bean
887        public UnknownCodeSystemWarningValidationSupport unknownCodeSystemWarningValidationSupport(
888                        FhirContext theFhirContext) {
889                return new UnknownCodeSystemWarningValidationSupport(theFhirContext);
890        }
891
892        @Bean
893        public ISynchronousSearchSvc synchronousSearchSvc() {
894                return new SynchronousSearchSvcImpl();
895        }
896
897        @Bean
898        public VersionCanonicalizer versionCanonicalizer(FhirContext theFhirContext) {
899                return new VersionCanonicalizer(theFhirContext);
900        }
901
902        @Bean
903        public SearchParameterDaoValidator searchParameterDaoValidator(
904                        FhirContext theFhirContext,
905                        JpaStorageSettings theStorageSettings,
906                        ISearchParamRegistry theSearchParamRegistry) {
907                return new SearchParameterDaoValidator(theFhirContext, theStorageSettings, theSearchParamRegistry);
908        }
909
910        @Bean
911        public ITermReadSvc terminologyService() {
912                return new TermReadSvcImpl();
913        }
914
915        @Bean
916        public ValueSetConceptAccumulatorFactory valueSetConceptAccumulatorFactory() {
917                return new ValueSetConceptAccumulatorFactory();
918        }
919
920        @Bean
921        @Scope("prototype")
922        public ValueSetConceptAccumulator valueSetConceptAccumulator(TermValueSet theTermValueSet) {
923                return valueSetConceptAccumulatorFactory().create(theTermValueSet);
924        }
925
926        @Bean
927        public ITermCodeSystemStorageSvc termCodeSystemStorageSvc() {
928                return new TermCodeSystemStorageSvcImpl();
929        }
930
931        @Bean
932        public ITermReindexingSvc termReindexingSvc() {
933                return new TermReindexingSvcImpl();
934        }
935
936        @Bean
937        @Scope("prototype")
938        public PersistenceContextProvider persistenceContextProvider() {
939                return new PersistenceContextProvider();
940        }
941
942        @Bean
943        public ResourceSearchUrlSvc resourceSearchUrlSvc(
944                        PersistenceContextProvider thePersistenceContextProvider,
945                        IResourceSearchUrlDao theResourceSearchUrlDao,
946                        MatchUrlService theMatchUrlService,
947                        FhirContext theFhirContext,
948                        PartitionSettings thePartitionSettings) {
949                return new ResourceSearchUrlSvc(
950                                thePersistenceContextProvider.getEntityManager(),
951                                theResourceSearchUrlDao,
952                                theMatchUrlService,
953                                theFhirContext,
954                                thePartitionSettings);
955        }
956
957        @Bean
958        public ISearchUrlJobMaintenanceSvc searchUrlJobMaintenanceSvc(ResourceSearchUrlSvc theResourceSearchUrlSvc) {
959                return new SearchUrlJobMaintenanceSvcImpl(theResourceSearchUrlSvc);
960        }
961
962        @Bean
963        public IResourceModifiedMessagePersistenceSvc subscriptionMessagePersistence(
964                        FhirContext theFhirContext,
965                        IResourceModifiedDao theIResourceModifiedDao,
966                        DaoRegistry theDaoRegistry,
967                        HapiTransactionService theHapiTransactionService) {
968                return new ResourceModifiedMessagePersistenceSvcImpl(
969                                theFhirContext, theIResourceModifiedDao, theDaoRegistry, theHapiTransactionService);
970        }
971
972        @Bean
973        public IMetaTagSorter metaTagSorter() {
974                return new MetaTagSorterAlphabetical();
975        }
976
977        @Bean
978        public ResourceHistoryCalculator resourceHistoryCalculator(
979                        FhirContext theFhirContext, HibernatePropertiesProvider theHibernatePropertiesProvider) {
980                return new ResourceHistoryCalculator(theFhirContext, theHibernatePropertiesProvider.isOracleDialect());
981        }
982
983        @Bean
984        public CacheTagDefinitionDao tagDefinitionDao(
985                        ITagDefinitionDao tagDefinitionDao, MemoryCacheService memoryCacheService) {
986                return new CacheTagDefinitionDao(tagDefinitionDao, memoryCacheService);
987        }
988
989        @Bean
990        public Batch2TaskHelper batch2TaskHelper() {
991                return new Batch2TaskHelper();
992        }
993
994        @Bean
995        public IReplaceReferencesSvc replaceReferencesSvc(
996                        DaoRegistry theDaoRegistry,
997                        HapiTransactionService theHapiTransactionService,
998                        IResourceLinkDao theResourceLinkDao,
999                        IJobCoordinator theJobCoordinator,
1000                        ReplaceReferencesPatchBundleSvc theReplaceReferencesPatchBundle,
1001                        Batch2TaskHelper theBatch2TaskHelper,
1002                        JpaStorageSettings theStorageSettings) {
1003                return new ReplaceReferencesSvcImpl(
1004                                theDaoRegistry,
1005                                theHapiTransactionService,
1006                                theResourceLinkDao,
1007                                theJobCoordinator,
1008                                theReplaceReferencesPatchBundle,
1009                                theBatch2TaskHelper,
1010                                theStorageSettings);
1011        }
1012
1013        @Bean
1014        public ReplaceReferencesPatchBundleSvc replaceReferencesPatchBundleSvc(DaoRegistry theDaoRegistry) {
1015                return new ReplaceReferencesPatchBundleSvc(theDaoRegistry);
1016        }
1017
1018        @Bean
1019        public PartitionedIdModeVerificationSvc partitionedIdModeVerificationSvc(
1020                        PartitionSettings thePartitionSettings,
1021                        HibernatePropertiesProvider theHibernatePropertiesProvider,
1022                        PlatformTransactionManager theTxManager) {
1023                return new PartitionedIdModeVerificationSvc(thePartitionSettings, theHibernatePropertiesProvider, theTxManager);
1024        }
1025}