View Javadoc
1   package ca.uhn.fhir.jpa.config;
2   
3   import ca.uhn.fhir.context.FhirContext;
4   import ca.uhn.fhir.i18n.HapiLocalizer;
5   import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
6   import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
7   import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
8   import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl;
9   import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
10  import ca.uhn.fhir.jpa.search.reindex.ResourceReindexingSvcImpl;
11  import ca.uhn.fhir.jpa.subscription.dbmatcher.CompositeInMemoryDaoSubscriptionMatcher;
12  import ca.uhn.fhir.jpa.subscription.dbmatcher.DaoSubscriptionMatcher;
13  import ca.uhn.fhir.jpa.subscription.module.cache.ISubscribableChannelFactory;
14  import ca.uhn.fhir.jpa.subscription.module.cache.LinkedBlockingQueueSubscribableChannelFactory;
15  import ca.uhn.fhir.jpa.subscription.module.matcher.ISubscriptionMatcher;
16  import ca.uhn.fhir.jpa.subscription.module.matcher.InMemorySubscriptionMatcher;
17  import org.hibernate.jpa.HibernatePersistenceProvider;
18  import org.springframework.beans.factory.annotation.Autowire;
19  import org.springframework.beans.factory.annotation.Autowired;
20  import org.springframework.context.annotation.*;
21  import org.springframework.core.env.Environment;
22  import org.springframework.core.task.AsyncTaskExecutor;
23  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
24  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
25  import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
26  import org.springframework.scheduling.TaskScheduler;
27  import org.springframework.scheduling.annotation.EnableScheduling;
28  import org.springframework.scheduling.annotation.SchedulingConfigurer;
29  import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
30  import org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean;
31  import org.springframework.scheduling.config.ScheduledTaskRegistrar;
32  import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
33  
34  import javax.annotation.Nonnull;
35  
36  /*
37   * #%L
38   * HAPI FHIR JPA Server
39   * %%
40   * Copyright (C) 2014 - 2019 University Health Network
41   * %%
42   * Licensed under the Apache License, Version 2.0 (the "License");
43   * you may not use this file except in compliance with the License.
44   * You may obtain a copy of the License at
45   * 
46   *      http://www.apache.org/licenses/LICENSE-2.0
47   * 
48   * Unless required by applicable law or agreed to in writing, software
49   * distributed under the License is distributed on an "AS IS" BASIS,
50   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51   * See the License for the specific language governing permissions and
52   * limitations under the License.
53   * #L%
54   */
55  
56  
57  @Configuration
58  @EnableScheduling
59  @EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data")
60  @ComponentScan(basePackages = "ca.uhn.fhir.jpa", excludeFilters = {
61  	@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = BaseConfig.class),
62  	@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = WebSocketConfigurer.class),
63  	@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*\\.test\\..*"),
64  	@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test.*"),
65  	@ComponentScan.Filter(type = FilterType.REGEX, pattern = "ca.uhn.fhir.jpa.subscription.module.standalone.*")})
66  
67  public abstract class BaseConfig implements SchedulingConfigurer {
68  
69  	public static final String TASK_EXECUTOR_NAME = "hapiJpaTaskExecutor";
70  
71  	@Autowired
72  	protected Environment myEnv;
73  
74  	@Override
75  	public void configureTasks(@Nonnull ScheduledTaskRegistrar theTaskRegistrar) {
76  		theTaskRegistrar.setTaskScheduler(taskScheduler());
77  	}
78  
79  	@Bean(autowire = Autowire.BY_TYPE)
80  	public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
81  		return new DatabaseBackedPagingProvider();
82  	}
83  
84  	/**
85  	 * This method should be overridden to provide an actual completed
86  	 * bean, but it provides a partially completed entity manager
87  	 * factory with HAPI FHIR customizations
88  	 */
89  	protected LocalContainerEntityManagerFactoryBean entityManagerFactory() {
90  		LocalContainerEntityManagerFactoryBean retVal = new HapiFhirLocalContainerEntityManagerFactoryBean();
91  		configureEntityManagerFactory(retVal, fhirContext());
92  		return retVal;
93  	}
94  
95  	public abstract FhirContext fhirContext();
96  
97  	@Bean
98  	public ScheduledExecutorFactoryBean scheduledExecutorService() {
99  		ScheduledExecutorFactoryBean b = new ScheduledExecutorFactoryBean();
100 		b.setPoolSize(5);
101 		b.afterPropertiesSet();
102 		return b;
103 	}
104 
105 	@Bean(name = "mySubscriptionTriggeringProvider")
106 	@Lazy
107 	public SubscriptionTriggeringProvider subscriptionTriggeringProvider() {
108 		return new SubscriptionTriggeringProvider();
109 	}
110 
111 	@Bean
112 	public TaskScheduler taskScheduler() {
113 		ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler();
114 		retVal.setConcurrentExecutor(scheduledExecutorService().getObject());
115 		retVal.setScheduledExecutor(scheduledExecutorService().getObject());
116 		return retVal;
117 	}
118 
119 	@Bean(name = TASK_EXECUTOR_NAME)
120 	public AsyncTaskExecutor taskExecutor() {
121 		ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler();
122 		retVal.setConcurrentExecutor(scheduledExecutorService().getObject());
123 		retVal.setScheduledExecutor(scheduledExecutorService().getObject());
124 		return retVal;
125 	}
126 
127 	@Bean
128 	public IResourceReindexingSvc resourceReindexingSvc() {
129 		return new ResourceReindexingSvcImpl();
130 	}
131 
132 	@Bean
133 	public IStaleSearchDeletingSvc staleSearchDeletingSvc() {
134 		return new StaleSearchDeletingSvcImpl();
135 	}
136 
137 	@Bean
138 	public InMemorySubscriptionMatcher inMemorySubscriptionMatcher() {
139 		return new InMemorySubscriptionMatcher();
140 	}
141 
142 	@Bean
143 	public DaoSubscriptionMatcher daoSubscriptionMatcher() {
144 		return new DaoSubscriptionMatcher();
145 	}
146 
147 	/**
148 	 * Create a @Primary @Bean if you need a different implementation
149 	 */
150 	@Bean
151 	public ISubscribableChannelFactory linkedBlockingQueueSubscribableChannelFactory() {
152 		return new LinkedBlockingQueueSubscribableChannelFactory();
153 	}
154 
155 	@Bean
156 	@Primary
157 	public ISubscriptionMatcher subscriptionMatcherCompositeInMemoryDatabase() {
158 		return new CompositeInMemoryDaoSubscriptionMatcher(daoSubscriptionMatcher(), inMemorySubscriptionMatcher());
159 	}
160 
161 	public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) {
162 		theFactory.setJpaDialect(hibernateJpaDialect(theCtx.getLocalizer()));
163 		theFactory.setPackagesToScan("ca.uhn.fhir.jpa.model.entity", "ca.uhn.fhir.jpa.entity");
164 		theFactory.setPersistenceProvider(new HibernatePersistenceProvider());
165 	}
166 
167 	private static HibernateJpaDialect hibernateJpaDialect(HapiLocalizer theLocalizer) {
168 		return new HapiFhirHibernateJpaDialect(theLocalizer);
169 	}
170 }