View Javadoc
1   package com.atlassian.plugin.spring.scanner.runtime.impl;
2   
3   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PrivateService;
4   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PublicDevService;
5   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PublicDevServiceProxy;
6   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PublicNonInterfaceService;
7   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PublicNonInterfaceServiceProxy;
8   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PublicService;
9   import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.PublicServiceProxy;
10  import com.atlassian.plugin.spring.scanner.runtime.impl.testservices.Service;
11  import org.apache.commons.collections.keyvalue.DefaultMapEntry;
12  import org.hamcrest.CoreMatchers;
13  import org.hamcrest.Matcher;
14  import org.junit.Assert;
15  import org.junit.Before;
16  import org.junit.Test;
17  import org.junit.runner.RunWith;
18  import org.mockito.Mock;
19  import org.mockito.runners.MockitoJUnitRunner;
20  import org.osgi.framework.Bundle;
21  import org.osgi.framework.BundleContext;
22  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
23  import org.springframework.context.ApplicationContext;
24  import org.springframework.context.support.ClassPathXmlApplicationContext;
25  
26  import java.util.Map;
27  
28  import static com.atlassian.plugin.spring.scanner.runtime.impl.IsAopProxy.aopProxy;
29  import static org.hamcrest.CoreMatchers.equalTo;
30  import static org.hamcrest.CoreMatchers.not;
31  import static org.mockito.Matchers.any;
32  import static org.mockito.Matchers.anyMap;
33  import static org.mockito.Matchers.eq;
34  import static org.mockito.Mockito.argThat;
35  import static org.mockito.Mockito.never;
36  import static org.mockito.Mockito.times;
37  import static org.mockito.Mockito.verify;
38  import static org.mockito.Mockito.when;
39  
40  @RunWith(MockitoJUnitRunner.class)
41  public class ServiceExporterBeanPostProcessorTest {
42      @Mock
43      private Bundle bundle;
44      @Mock
45      private BundleContext bundleContext;
46      @Mock
47      private ConfigurableListableBeanFactory beanFactory;
48      @Mock
49      private ExportedSeviceManager exportedSeviceManager;
50  
51      private ServiceExporterBeanPostProcessor exporterPostProcessor;
52      private ApplicationContext applicationContext;
53  
54      @Before
55      public void setUp() throws Exception {
56          when(bundle.getBundleContext()).thenReturn(bundleContext);
57          when(bundleContext.getBundle()).thenReturn(bundle);
58  
59          System.setProperty(ServiceExporterBeanPostProcessor.ATLASSIAN_DEV_MODE_PROP, Boolean.TRUE.toString());
60          this.exporterPostProcessor = new ServiceExporterBeanPostProcessor(bundleContext, beanFactory, exportedSeviceManager);
61          this.exporterPostProcessor.afterPropertiesSet();
62  
63          this.applicationContext = new ClassPathXmlApplicationContext("classpath:/com/atlassian/plugin/spring/scanner/runtime/impl/testservices/testservicesContext.xml");
64      }
65  
66      @Test
67      public void testNonProxyExportAsService() throws Exception {
68          testNonProxyBeanIsExported(PublicService.class, Service.class);
69      }
70  
71      @Test
72      public void testNonProxyExportAsDevService() throws Exception {
73          testNonProxyBeanIsExported(PublicDevService.class, Service.class);
74      }
75  
76      @Test
77      public void testNonProxyNonInterfaceExportAsService() throws Exception {
78          testNonProxyBeanIsExported(PublicNonInterfaceService.class, PublicNonInterfaceService.class);
79      }
80  
81      @Test
82      public void testProxyExportAsService() throws Exception {
83          testProxyBeanIsExported(PublicServiceProxy.class, Service.class);
84      }
85  
86      @Test
87      public void testProxyExportAsDevService() throws Exception {
88          testProxyBeanIsExported(PublicDevServiceProxy.class, Service.class);
89      }
90  
91      @Test
92      public void testProxyNonInterfaceExportAsService() throws Exception {
93          testProxyBeanIsExported(PublicNonInterfaceServiceProxy.class, PublicNonInterfaceServiceProxy.class);
94      }
95  
96      @Test
97      public void testPrivateServiceNotExported() throws Exception {
98          testBeanIsExported(PrivateService.class, CoreMatchers.any(Object.class), CoreMatchers.any(Class.class), false);
99      }
100 
101     private void testBeanIsExported(Class<?> beanImplClass, Matcher<Object> beanMatcher, Matcher<Class> interfaceMatcher, boolean expectExported) throws Exception {
102         Map.Entry<String, ?> nameBeanEntry = getBeanByImplClass(beanImplClass);
103         Assert.assertThat(nameBeanEntry.getValue(), beanMatcher);
104         exporterPostProcessor.postProcessAfterInitialization(nameBeanEntry.getValue(), nameBeanEntry.getKey());
105 
106         verify(exportedSeviceManager, expectExported ? times(1) : never()).registerService(
107                 any(BundleContext.class),
108                 eq(nameBeanEntry.getValue()),
109                 eq(nameBeanEntry.getKey()),
110                 anyMap(),
111                 argThat(interfaceMatcher));
112     }
113 
114     private void testNonProxyBeanIsExported(Class<?> beanImplClass, Class expectInstanceOf) throws Exception {
115         testBeanIsExported(beanImplClass, not(aopProxy()), equalTo(expectInstanceOf), true);
116     }
117 
118     private void testProxyBeanIsExported(Class<?> beanImplClass, Class expectInstanceOf) throws Exception {
119         testBeanIsExported(beanImplClass, aopProxy(), equalTo(expectInstanceOf), true);
120     }
121 
122     protected Map.Entry<String, Object> getBeanByImplClass(Class<?> beanImplClass) {
123         final String beanName = getBeanDefaultName(beanImplClass);
124         final Object bean = applicationContext.getBean(beanName);
125         Assert.assertThat(bean, CoreMatchers.notNullValue());
126         return new DefaultMapEntry(beanName, bean);
127     }
128 
129     private String getBeanDefaultName(Class<?> type) {
130         String name = type.getSimpleName();
131         return name.substring(0, 1).toLowerCase() + name.substring(1);
132     }
133 
134 }