001/*- 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2024 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.context.ConfigurationException; 023import ca.uhn.fhir.context.FhirContext; 024import ca.uhn.fhir.i18n.Msg; 025import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; 026import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; 027import ca.uhn.fhir.jpa.api.dao.DaoRegistry; 028import ca.uhn.fhir.jpa.api.svc.IIdHelperService; 029import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc; 030import ca.uhn.fhir.jpa.dao.ISearchBuilder; 031import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; 032import ca.uhn.fhir.jpa.dao.data.IResourceTagDao; 033import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; 034import ca.uhn.fhir.jpa.model.config.PartitionSettings; 035import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; 036import ca.uhn.fhir.jpa.search.ExceptionService; 037import ca.uhn.fhir.jpa.search.ISynchronousSearchSvc; 038import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory; 039import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; 040import ca.uhn.fhir.jpa.search.SearchStrategyFactory; 041import ca.uhn.fhir.jpa.search.builder.SearchBuilder; 042import ca.uhn.fhir.jpa.search.builder.sql.SqlObjectFactory; 043import ca.uhn.fhir.jpa.search.builder.tasks.SearchContinuationTask; 044import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask; 045import ca.uhn.fhir.jpa.search.builder.tasks.SearchTaskParameters; 046import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc; 047import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc; 048import ca.uhn.fhir.rest.server.IPagingProvider; 049import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; 050import jakarta.annotation.PostConstruct; 051import org.hl7.fhir.instance.model.api.IBaseResource; 052import org.springframework.beans.factory.BeanFactory; 053import org.springframework.beans.factory.annotation.Autowired; 054import org.springframework.context.annotation.Bean; 055import org.springframework.context.annotation.Configuration; 056import org.springframework.context.annotation.Scope; 057import org.springframework.transaction.PlatformTransactionManager; 058 059@Configuration 060public class SearchConfig { 061 public static final String SEARCH_TASK = "searchTask"; 062 public static final String CONTINUE_TASK = "continueTask"; 063 064 @Autowired 065 private JpaStorageSettings myStorageSettings; 066 067 @Autowired 068 private HapiFhirLocalContainerEntityManagerFactoryBean myEntityManagerFactory; 069 070 @Autowired 071 private SqlObjectFactory mySqlBuilderFactory; 072 073 @Autowired 074 private HibernatePropertiesProvider myDialectProvider; 075 076 @Autowired 077 private ISearchParamRegistry mySearchParamRegistry; 078 079 @Autowired 080 private PartitionSettings myPartitionSettings; 081 082 @Autowired 083 protected IInterceptorBroadcaster myInterceptorBroadcaster; 084 085 @Autowired 086 protected IResourceTagDao myResourceTagDao; 087 088 @Autowired 089 private DaoRegistry myDaoRegistry; 090 091 @Autowired 092 private FhirContext myContext; 093 094 @Autowired 095 private IIdHelperService myIdHelperService; 096 097 @Autowired 098 private PlatformTransactionManager myManagedTxManager; 099 100 @Autowired 101 private SearchStrategyFactory mySearchStrategyFactory; 102 103 @Autowired 104 private SearchBuilderFactory mySearchBuilderFactory; 105 106 @Autowired 107 private ISearchResultCacheSvc mySearchResultCacheSvc; 108 109 @Autowired 110 private ISearchCacheSvc mySearchCacheSvc; 111 112 @Autowired 113 private IPagingProvider myPagingProvider; 114 115 @Autowired 116 private BeanFactory myBeanFactory; 117 118 @Autowired 119 private ISynchronousSearchSvc mySynchronousSearchSvc; 120 121 @Autowired 122 private PersistedJpaBundleProviderFactory myPersistedJpaBundleProviderFactory; 123 124 @Autowired 125 private IRequestPartitionHelperSvc myRequestPartitionHelperService; 126 127 @Autowired 128 private HapiTransactionService myHapiTransactionService; 129 130 @Bean 131 public ISearchCoordinatorSvc searchCoordinatorSvc() { 132 return new SearchCoordinatorSvcImpl( 133 myContext, 134 myStorageSettings, 135 myInterceptorBroadcaster, 136 myHapiTransactionService, 137 mySearchCacheSvc, 138 mySearchResultCacheSvc, 139 myDaoRegistry, 140 mySearchBuilderFactory, 141 mySynchronousSearchSvc, 142 myPersistedJpaBundleProviderFactory, 143 mySearchParamRegistry, 144 mySearchStrategyFactory, 145 exceptionService(), 146 myBeanFactory); 147 } 148 149 @Bean 150 public ExceptionService exceptionService() { 151 return new ExceptionService(myContext); 152 } 153 154 @Bean(name = ISearchBuilder.SEARCH_BUILDER_BEAN_NAME) 155 @Scope("prototype") 156 public ISearchBuilder newSearchBuilder(String theResourceName, Class<? extends IBaseResource> theResourceType) { 157 return new SearchBuilder( 158 theResourceName, 159 myStorageSettings, 160 myEntityManagerFactory, 161 mySqlBuilderFactory, 162 myDialectProvider, 163 mySearchParamRegistry, 164 myPartitionSettings, 165 myInterceptorBroadcaster, 166 myResourceTagDao, 167 myDaoRegistry, 168 myContext, 169 myIdHelperService, 170 theResourceType); 171 } 172 173 @Bean(name = SEARCH_TASK) 174 @Scope("prototype") 175 public SearchTask createSearchTask(SearchTaskParameters theParams) { 176 return new SearchTask( 177 theParams, 178 myHapiTransactionService, 179 myContext, 180 myInterceptorBroadcaster, 181 mySearchBuilderFactory, 182 mySearchResultCacheSvc, 183 myStorageSettings, 184 mySearchCacheSvc, 185 myPagingProvider); 186 } 187 188 @Bean(name = CONTINUE_TASK) 189 @Scope("prototype") 190 public SearchContinuationTask createSearchContinuationTask(SearchTaskParameters theParams) { 191 return new SearchContinuationTask( 192 theParams, 193 myHapiTransactionService, 194 myContext, 195 myInterceptorBroadcaster, 196 mySearchBuilderFactory, 197 mySearchResultCacheSvc, 198 myStorageSettings, 199 mySearchCacheSvc, 200 myPagingProvider, 201 exceptionService() // singleton 202 ); 203 } 204 205 @PostConstruct 206 public void validateConfiguration() { 207 if (myStorageSettings.isIndexStorageOptimized() 208 && myPartitionSettings.isPartitioningEnabled() 209 && myPartitionSettings.isIncludePartitionInSearchHashes()) { 210 throw new ConfigurationException(Msg.code(2525) + "Incorrect configuration. " 211 + "StorageSettings#isIndexStorageOptimized and PartitionSettings.isIncludePartitionInSearchHashes " 212 + "cannot be enabled at the same time."); 213 } 214 } 215}