Skip to content

Commit f0f3b91

Browse files
authored
FM2-665 Adjust auto-proxy to work with 2.8.x, see TRUNK-6382 (#572)
1 parent 37767da commit f0f3b91

File tree

5 files changed

+110
-138
lines changed

5 files changed

+110
-138
lines changed

api/src/main/java/org/openmrs/module/fhir2/api/translators/impl/ImmunizationTranslatorImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
public class ImmunizationTranslatorImpl implements ImmunizationTranslator {
6262

6363
public static final String IMMUNIZATION_GROUPING_CONCEPT = "CIEL:1421";
64-
64+
6565
public static final String IMMUNIZATION_FREE_TEXT_COMMENT_CONCEPT = "CIEL:161011";
6666

6767
public static final Set<String> IMMUNIZATION_CONCEPTS = ImmutableSet.of("CIEL:984", "CIEL:1410", "CIEL:1418",
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public License,
3+
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
4+
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5+
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6+
*
7+
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8+
* graphic logo is a trademark of OpenMRS Inc.
9+
*/
10+
package org.openmrs.module.fhir2.spring;
11+
12+
import java.lang.reflect.Method;
13+
import java.util.Arrays;
14+
15+
import org.openmrs.aop.AuthorizationAdvice;
16+
import org.openmrs.module.fhir2.api.FhirHelperService;
17+
import org.openmrs.module.fhir2.api.FhirService;
18+
import org.openmrs.module.fhir2.api.dao.FhirDaoAop;
19+
import org.openmrs.module.fhir2.api.translators.FhirTranslator;
20+
import org.springframework.aop.Advisor;
21+
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
22+
import org.springframework.beans.factory.annotation.Autowired;
23+
import org.springframework.cache.annotation.CacheConfig;
24+
import org.springframework.cache.annotation.CacheEvict;
25+
import org.springframework.cache.annotation.CachePut;
26+
import org.springframework.cache.annotation.Cacheable;
27+
import org.springframework.cache.interceptor.CacheInterceptor;
28+
import org.springframework.context.annotation.Bean;
29+
import org.springframework.context.annotation.Configuration;
30+
import org.springframework.context.annotation.EnableAspectJAutoProxy;
31+
import org.springframework.core.annotation.AnnotationUtils;
32+
import org.springframework.transaction.interceptor.TransactionInterceptor;
33+
34+
/**
35+
* This is a Spring AOP configuration that add advices to beans that implement the FhirDao marker
36+
* interface, which is where authorization is checked in the FHIR2 module and sub-implementations.
37+
* This is used to ensure that our custom interceptors are applied to the classes in the FHIR2
38+
* module, even though they do not follow our usual pattern of registering with the service
39+
* container.
40+
*/
41+
@Configuration
42+
@EnableAspectJAutoProxy
43+
public class FhirAopConfiguration {
44+
45+
@Bean
46+
public Advisor createFhirAuthorizationAdvisor(@Autowired AuthorizationAdvice authorizationAdvice) {
47+
return new StaticMethodMatcherPointcutAdvisor(authorizationAdvice) {
48+
49+
@Override
50+
public boolean matches(Method method, Class<?> targetClass) {
51+
return FhirDaoAop.class.isAssignableFrom(targetClass);
52+
}
53+
};
54+
}
55+
56+
@Bean
57+
public Advisor createFhirTransactionAdvisor(@Autowired(required = false) TransactionInterceptor transactionInterceptor) {
58+
if (transactionInterceptor != null) {
59+
// TransactionInterceptor is not available since core 2.8 as it is done via tx:annotation-driven on all beans
60+
return new StaticMethodMatcherPointcutAdvisor(transactionInterceptor) {
61+
62+
@Override
63+
public boolean matches(Method method, Class<?> targetClass) {
64+
return FhirDaoAop.class.isAssignableFrom(targetClass);
65+
}
66+
};
67+
}
68+
return null;
69+
}
70+
71+
/**
72+
* Creates advisors for FHIR beans using Spring caching. It is required before OpenMRS core 2.8.
73+
*
74+
* @param cacheInterceptor the cache interceptor
75+
* @return the cache advisor
76+
*/
77+
@Bean
78+
public Advisor createFhirCacheAdvisor(@Autowired(required = false) CacheInterceptor cacheInterceptor) {
79+
if (cacheInterceptor != null) {
80+
// CacheInterceptor is not available since core 2.8 as it is done via cache:annotation-driven on all beans
81+
return new StaticMethodMatcherPointcutAdvisor(cacheInterceptor) {
82+
83+
@Override
84+
public boolean matches(Method method, Class<?> targetClass) {
85+
return (FhirTranslator.class.isAssignableFrom(targetClass)
86+
|| FhirService.class.isAssignableFrom(targetClass)
87+
|| FhirHelperService.class.isAssignableFrom(targetClass))
88+
&& (AnnotationUtils.findAnnotation(targetClass, CacheConfig.class) != null
89+
|| AnnotationUtils.findAnnotation(targetClass, Cacheable.class) != null
90+
|| AnnotationUtils.findAnnotation(targetClass, CacheEvict.class) != null
91+
|| AnnotationUtils.findAnnotation(targetClass, CachePut.class) != null
92+
|| Arrays.stream(targetClass.getMethods())
93+
.anyMatch((m) -> AnnotationUtils.findAnnotation(m, Cacheable.class) != null
94+
|| AnnotationUtils.findAnnotation(m, CacheEvict.class) != null
95+
|| AnnotationUtils.findAnnotation(m, CachePut.class) != null));
96+
}
97+
};
98+
}
99+
return null;
100+
}
101+
}

api/src/main/java/org/openmrs/module/fhir2/spring/FhirAutoProxyCreator.java

Lines changed: 0 additions & 128 deletions
This file was deleted.

api/src/main/resources/moduleApplicationContext.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,4 @@
4949
<bean id="fhirUcumService" class="org.fhir.ucum.UcumEssenceService">
5050
<constructor-arg name="stream" value="classpath:ucum-fhir-essence.xml" />
5151
</bean>
52-
53-
<bean class="org.openmrs.module.fhir2.spring.FhirAutoProxyCreator" />
5452
</beans>

api/src/test/java/org/openmrs/module/fhir2/api/impl/FhirImmunizationServiceImplTest.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import static org.hl7.fhir.r4.model.Patient.SP_IDENTIFIER;
1717
import static org.junit.Assert.assertNull;
1818
import static org.junit.Assert.assertTrue;
19-
import static org.junit.jupiter.api.Assertions.assertNotNull;
2019
import static org.openmrs.module.fhir2.FhirConstants.ENCOUNTER;
2120
import static org.openmrs.module.fhir2.FhirConstants.PATIENT;
2221
import static org.openmrs.module.fhir2.FhirConstants.PRACTITIONER;
@@ -60,11 +59,11 @@
6059
import org.springframework.beans.factory.annotation.Qualifier;
6160

6261
public class FhirImmunizationServiceImplTest extends BaseFhirContextSensitiveTest {
63-
62+
6463
private static final String FREETEXT_COMMENT_CONCEPT_CODE = "161011";
65-
64+
6665
private static final String FREETEXT_COMMENT_CONCEPT_SOURCE = "CIEL";
67-
66+
6867
private static final String IMMUNIZATIONS_METADATA_XML = "org/openmrs/module/fhir2/Immunization_metadata.xml";
6968

7069
private static final String IMMUNIZATIONS_INITIAL_DATA_XML = "org/openmrs/module/fhir2/api/services/impl/FhirImmunizationService_initial_data.xml";
@@ -179,7 +178,8 @@ public void saveImmunization_shouldSaveImmunizationWithNoteField() throws Except
179178
@Test
180179
public void saveImmunization_shouldNotFailIfNoteConceptIsMissingAndNoteProvided() throws Exception {
181180
// Remove the note concept since @Before loads it
182-
conceptService.purgeConcept(conceptService.getConceptByMapping(FREETEXT_COMMENT_CONCEPT_CODE, FREETEXT_COMMENT_CONCEPT_SOURCE));
181+
conceptService.purgeConcept(
182+
conceptService.getConceptByMapping(FREETEXT_COMMENT_CONCEPT_CODE, FREETEXT_COMMENT_CONCEPT_SOURCE));
183183
assertNull(conceptService.getConceptByMapping(FREETEXT_COMMENT_CONCEPT_CODE, FREETEXT_COMMENT_CONCEPT_SOURCE));
184184

185185
FhirContext ctx = FhirContext.forR4();
@@ -262,9 +262,10 @@ public void updateImmunization_shouldUpdateNoteFieldWhenNoteConceptIsAvailable()
262262
@Test
263263
public void updateImmunization_shouldNotFailIfNoteConceptIsMissingButNoteIsProvided() throws Exception {
264264
// Remove the note concept since @Before loads it
265-
conceptService.purgeConcept(conceptService.getConceptByMapping(FREETEXT_COMMENT_CONCEPT_CODE, FREETEXT_COMMENT_CONCEPT_SOURCE));
265+
conceptService.purgeConcept(
266+
conceptService.getConceptByMapping(FREETEXT_COMMENT_CONCEPT_CODE, FREETEXT_COMMENT_CONCEPT_SOURCE));
266267
assertNull(conceptService.getConceptByMapping(FREETEXT_COMMENT_CONCEPT_CODE, FREETEXT_COMMENT_CONCEPT_SOURCE));
267-
268+
268269
FhirContext ctx = FhirContext.forR4();
269270
IParser parser = ctx.newJsonParser();
270271
String createJson = IOUtils.toString(

0 commit comments

Comments
 (0)