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 }