View Javadoc
1   package ca.uhn.fhir.jpa.config;
2   
3   /*
4    * #%L
5    * HAPI FHIR JPA Server
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import ca.uhn.fhir.context.FhirContext;
24  import ca.uhn.fhir.i18n.HapiLocalizer;
25  import ca.uhn.fhir.jpa.dao.DaoRegistry;
26  import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
27  import ca.uhn.fhir.jpa.search.*;
28  import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
29  import ca.uhn.fhir.jpa.search.reindex.ResourceReindexingSvcImpl;
30  import ca.uhn.fhir.jpa.search.warm.CacheWarmingSvcImpl;
31  import ca.uhn.fhir.jpa.search.warm.ICacheWarmingSvc;
32  import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
33  import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
34  import ca.uhn.fhir.jpa.subscription.email.SubscriptionEmailInterceptor;
35  import ca.uhn.fhir.jpa.subscription.resthook.SubscriptionRestHookInterceptor;
36  import ca.uhn.fhir.jpa.subscription.websocket.SubscriptionWebsocketInterceptor;
37  import org.hibernate.jpa.HibernatePersistenceProvider;
38  import org.springframework.beans.factory.annotation.Autowire;
39  import org.springframework.beans.factory.annotation.Autowired;
40  import org.springframework.context.annotation.Bean;
41  import org.springframework.context.annotation.Configuration;
42  import org.springframework.context.annotation.Lazy;
43  import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
44  import org.springframework.core.env.Environment;
45  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
46  import org.springframework.orm.hibernate5.HibernateExceptionTranslator;
47  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
48  import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
49  import org.springframework.scheduling.TaskScheduler;
50  import org.springframework.scheduling.annotation.EnableScheduling;
51  import org.springframework.scheduling.annotation.SchedulingConfigurer;
52  import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
53  import org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean;
54  import org.springframework.scheduling.config.ScheduledTaskRegistrar;
55  
56  import javax.annotation.Nonnull;
57  import java.util.concurrent.ScheduledExecutorService;
58  
59  
60  @Configuration
61  @EnableScheduling
62  @EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data")
63  public abstract class BaseConfig implements SchedulingConfigurer {
64  
65  	public static final String TASK_EXECUTOR_NAME = "hapiJpaTaskExecutor";
66  
67  	@Autowired
68  	protected Environment myEnv;
69  
70  	@Bean(name = "myDaoRegistry")
71  	public DaoRegistry daoRegistry() {
72  		return new DaoRegistry();
73  	}
74  
75  	@Override
76  	public void configureTasks(@Nonnull ScheduledTaskRegistrar theTaskRegistrar) {
77  		theTaskRegistrar.setTaskScheduler(taskScheduler());
78  	}
79  
80  	@Bean(autowire = Autowire.BY_TYPE)
81  	public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
82  		return new DatabaseBackedPagingProvider();
83  	}
84  
85  	/**
86  	 * This method should be overridden to provide an actual completed
87  	 * bean, but it provides a partially completed entity manager
88  	 * factory with HAPI FHIR customizations
89  	 */
90  	protected LocalContainerEntityManagerFactoryBean entityManagerFactory() {
91  		LocalContainerEntityManagerFactoryBean retVal = new HapiFhirLocalContainerEntityManagerFactoryBean();
92  		configureEntityManagerFactory(retVal, fhirContext());
93  		return retVal;
94  	}
95  
96  	public abstract FhirContext fhirContext();
97  
98  	@Bean
99  	public ICacheWarmingSvc cacheWarmingSvc() {
100 		return new CacheWarmingSvcImpl();
101 	}
102 
103 	@Bean
104 	public HibernateExceptionTranslator hibernateExceptionTranslator() {
105 		return new HibernateExceptionTranslator();
106 	}
107 
108 	@Bean
109 	public HibernateJpaDialect hibernateJpaDialectInstance() {
110 		return new HibernateJpaDialect();
111 	}
112 
113 	@Bean()
114 	public ScheduledExecutorService scheduledExecutorService() {
115 		ScheduledExecutorFactoryBean b = new ScheduledExecutorFactoryBean();
116 		b.setPoolSize(5);
117 		b.afterPropertiesSet();
118 		return b.getObject();
119 	}
120 
121 	@Bean(name = "mySubscriptionTriggeringProvider")
122 	@Lazy
123 	public SubscriptionTriggeringProvider subscriptionTriggeringProvider() {
124 		return new SubscriptionTriggeringProvider();
125 	}
126 
127 	@Bean(autowire = Autowire.BY_TYPE, name = "mySearchCoordinatorSvc")
128 	public ISearchCoordinatorSvc searchCoordinatorSvc() {
129 		return new SearchCoordinatorSvcImpl();
130 	}
131 
132 	@Bean
133 	public ISearchParamPresenceSvc searchParamPresenceSvc() {
134 		return new SearchParamPresenceSvcImpl();
135 	}
136 
137 	@Bean(autowire = Autowire.BY_TYPE)
138 	public IStaleSearchDeletingSvc staleSearchDeletingSvc() {
139 		return new StaleSearchDeletingSvcImpl();
140 	}
141 
142 	/**
143 	 * Note: If you're going to use this, you need to provide a bean
144 	 * of type {@link ca.uhn.fhir.jpa.subscription.email.IEmailSender}
145 	 * in your own Spring config
146 	 */
147 	@Bean
148 	@Lazy
149 	public SubscriptionEmailInterceptor subscriptionEmailInterceptor() {
150 		return new SubscriptionEmailInterceptor();
151 	}
152 
153 	@Bean
154 	@Lazy
155 	public SubscriptionRestHookInterceptor subscriptionRestHookInterceptor() {
156 		return new SubscriptionRestHookInterceptor();
157 	}
158 
159 	@Bean
160 	@Lazy
161 	public SubscriptionWebsocketInterceptor subscriptionWebsocketInterceptor() {
162 		return new SubscriptionWebsocketInterceptor();
163 	}
164 
165 	@Bean(name = TASK_EXECUTOR_NAME)
166 	public TaskScheduler taskScheduler() {
167 		ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler();
168 		retVal.setConcurrentExecutor(scheduledExecutorService());
169 		retVal.setScheduledExecutor(scheduledExecutorService());
170 		return retVal;
171 	}
172 
173 	@Bean
174 	public IResourceReindexingSvc resourceReindexingSvc() {
175 		return new ResourceReindexingSvcImpl();
176 	}
177 
178 	public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) {
179 		theFactory.setJpaDialect(hibernateJpaDialect(theCtx.getLocalizer()));
180 		theFactory.setPackagesToScan("ca.uhn.fhir.jpa.entity");
181 		theFactory.setPersistenceProvider(new HibernatePersistenceProvider());
182 	}
183 
184 	private static HibernateJpaDialect hibernateJpaDialect(HapiLocalizer theLocalizer) {
185 		return new HapiFhirHibernateJpaDialect(theLocalizer);
186 	}
187 
188 	/**
189 	 * This lets the "@Value" fields reference properties from the properties file
190 	 */
191 	@Bean
192 	public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
193 		return new PropertySourcesPlaceholderConfigurer();
194 	}
195 
196 }