View Javadoc

1   package com.atlassian.plugin.osgi;
2   
3   import com.atlassian.plugin.Application;
4   import com.atlassian.plugin.DefaultModuleDescriptorFactory;
5   import com.atlassian.plugin.ModuleDescriptorFactory;
6   import com.atlassian.plugin.PluginAccessor;
7   import com.atlassian.plugin.event.PluginEventManager;
8   import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
9   import com.atlassian.plugin.factories.LegacyDynamicPluginFactory;
10  import com.atlassian.plugin.factories.PluginFactory;
11  import com.atlassian.plugin.hostcontainer.SimpleConstructorHostContainer;
12  import com.atlassian.plugin.loaders.BundledPluginLoader;
13  import com.atlassian.plugin.loaders.DirectoryPluginLoader;
14  import com.atlassian.plugin.loaders.PluginLoader;
15  import com.atlassian.plugin.manager.DefaultPluginManager;
16  import com.atlassian.plugin.manager.store.MemoryPluginPersistentStateStore;
17  import com.atlassian.plugin.module.ClassPrefixModuleFactory;
18  import com.atlassian.plugin.module.ModuleFactory;
19  import com.atlassian.plugin.module.PrefixDelegatingModuleFactory;
20  import com.atlassian.plugin.module.PrefixModuleFactory;
21  import com.atlassian.plugin.osgi.container.OsgiPersistentCache;
22  import com.atlassian.plugin.osgi.container.PackageScannerConfiguration;
23  import com.atlassian.plugin.osgi.container.felix.FelixOsgiContainerManager;
24  import com.atlassian.plugin.osgi.container.impl.DefaultOsgiPersistentCache;
25  import com.atlassian.plugin.osgi.container.impl.DefaultPackageScannerConfiguration;
26  import com.atlassian.plugin.osgi.factory.OsgiBundleFactory;
27  import com.atlassian.plugin.osgi.factory.OsgiPluginFactory;
28  import com.atlassian.plugin.osgi.factory.RemotablePluginFactory;
29  import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
30  import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
31  import com.atlassian.plugin.osgi.hostcomponents.InstanceBuilder;
32  import com.atlassian.plugin.osgi.module.BeanPrefixModuleFactory;
33  import com.atlassian.plugin.repositories.FilePluginInstaller;
34  import com.atlassian.plugin.test.PluginTestUtils;
35  import com.google.common.collect.ImmutableList;
36  import com.google.common.collect.ImmutableSet;
37  import junit.framework.TestCase;
38  import org.apache.commons.io.FileUtils;
39  import org.apache.commons.io.IOUtils;
40  
41  import java.io.File;
42  import java.io.FileInputStream;
43  import java.io.FileOutputStream;
44  import java.io.IOException;
45  import java.io.InputStream;
46  import java.util.Arrays;
47  import java.util.Collections;
48  import java.util.HashMap;
49  import java.util.Map;
50  import java.util.zip.ZipEntry;
51  import java.util.zip.ZipOutputStream;
52  
53  /**
54   * Base for in-container unit tests
55   */
56  public abstract class PluginInContainerTestBase extends TestCase
57  {
58      protected FelixOsgiContainerManager osgiContainerManager;
59      protected File tmpDir;
60      protected File cacheDir;
61      protected File pluginsDir;
62      protected ModuleDescriptorFactory moduleDescriptorFactory;
63      protected DefaultPluginManager pluginManager;
64      protected PluginEventManager pluginEventManager;
65      protected ModuleFactory moduleFactory;
66      protected SimpleConstructorHostContainer hostContainer;
67  
68      @Override
69      public void setUp() throws Exception
70      {
71          tmpDir = PluginTestUtils.createTempDirectory(PluginInContainerTestBase.class);
72          cacheDir = new File(tmpDir, "cache");
73          cacheDir.mkdir();
74          pluginsDir = new File(tmpDir, "plugins");
75          pluginsDir.mkdir();
76          this.pluginEventManager = new DefaultPluginEventManager();
77          moduleFactory = new PrefixDelegatingModuleFactory(ImmutableSet.<PrefixModuleFactory>of(
78              new ClassPrefixModuleFactory(hostContainer),
79              new BeanPrefixModuleFactory()));
80          hostContainer = createHostContainer(new HashMap<Class<?>, Object>());
81      }
82  
83      protected SimpleConstructorHostContainer createHostContainer(Map<Class<?>, Object> originalContext)
84      {
85          Map<Class<?>, Object> context = new HashMap<Class<?>, Object>(originalContext);
86          context.put(ModuleFactory.class, moduleFactory);
87          return new SimpleConstructorHostContainer(context);
88      }
89  
90      @Override
91      public void tearDown() throws Exception
92      {
93          if (osgiContainerManager != null)
94          {
95              osgiContainerManager.stop();
96              osgiContainerManager.clearExportCache(); // prevent export cache from being reused across tests
97          }
98          FileUtils.deleteDirectory(tmpDir);
99          osgiContainerManager = null;
100         tmpDir = null;
101         pluginsDir = null;
102         moduleDescriptorFactory = null;
103         pluginManager = null;
104         pluginEventManager = null;
105         moduleFactory = null;
106         hostContainer = null;
107     }
108 
109     protected void initPluginManager() throws Exception
110     {
111         initPluginManager(null, new DefaultModuleDescriptorFactory(hostContainer));
112     }
113 
114     protected void initPluginManager(final HostComponentProvider hostComponentProvider) throws Exception
115     {
116         initPluginManager(hostComponentProvider, new DefaultModuleDescriptorFactory(hostContainer));
117     }
118 
119     protected void initPluginManager(final HostComponentProvider hostComponentProvider, final ModuleDescriptorFactory moduleDescriptorFactory, final String version)
120             throws Exception
121     {
122         final PackageScannerConfiguration scannerConfig = buildScannerConfiguration(version);
123         HostComponentProvider requiredWrappingProvider = getWrappingHostComponentProvider(hostComponentProvider);
124         OsgiPersistentCache cache = new DefaultOsgiPersistentCache(cacheDir);
125         osgiContainerManager = new FelixOsgiContainerManager(cache, scannerConfig, requiredWrappingProvider, pluginEventManager);
126 
127         final LegacyDynamicPluginFactory legacyFactory = new LegacyDynamicPluginFactory(PluginAccessor.Descriptor.FILENAME, tmpDir);
128         final OsgiPluginFactory osgiPluginDeployer = new OsgiPluginFactory(PluginAccessor.Descriptor.FILENAME, Collections.<Application>emptySet(), cache, osgiContainerManager, pluginEventManager);
129         final OsgiBundleFactory osgiBundleFactory = new OsgiBundleFactory(osgiContainerManager, pluginEventManager);
130         final RemotablePluginFactory remotablePluginFactory = new RemotablePluginFactory(PluginAccessor.Descriptor.FILENAME, Collections.<Application>emptySet(), osgiContainerManager, pluginEventManager);
131 
132         final DirectoryPluginLoader loader = new DirectoryPluginLoader(pluginsDir,
133                 ImmutableList.<PluginFactory>of(legacyFactory, osgiPluginDeployer, osgiBundleFactory, remotablePluginFactory),
134                 new DefaultPluginEventManager());
135 
136         initPluginManager(moduleDescriptorFactory, loader);
137     }
138 
139     protected void initPluginManager(final HostComponentProvider hostComponentProvider, final ModuleDescriptorFactory moduleDescriptorFactory)
140             throws Exception
141     {
142         initPluginManager(hostComponentProvider, moduleDescriptorFactory, (String) null);
143     }
144 
145     protected void initPluginManager(final ModuleDescriptorFactory moduleDescriptorFactory, PluginLoader loader)
146             throws Exception
147     {
148         this.moduleDescriptorFactory = moduleDescriptorFactory;
149         pluginManager = new DefaultPluginManager(new MemoryPluginPersistentStateStore(), Arrays.<PluginLoader>asList(loader), moduleDescriptorFactory,
150                 pluginEventManager);
151         pluginManager.setPluginInstaller(new FilePluginInstaller(pluginsDir));
152         pluginManager.init();
153     }
154 
155     protected void initBundlingPluginManager(final ModuleDescriptorFactory moduleDescriptorFactory, File... bundledPluginJars) throws Exception
156     {
157         this.moduleDescriptorFactory = moduleDescriptorFactory;
158         final PackageScannerConfiguration scannerConfig = buildScannerConfiguration("1.0");
159         HostComponentProvider requiredWrappingProvider = getWrappingHostComponentProvider(null);
160         OsgiPersistentCache cache = new DefaultOsgiPersistentCache(cacheDir);
161         osgiContainerManager = new FelixOsgiContainerManager(cache, scannerConfig, requiredWrappingProvider, pluginEventManager);
162 
163         final OsgiPluginFactory osgiPluginDeployer = new OsgiPluginFactory(PluginAccessor.Descriptor.FILENAME, Collections.<Application>emptySet(), cache, osgiContainerManager, pluginEventManager);
164 
165         final DirectoryPluginLoader loader = new DirectoryPluginLoader(pluginsDir, Arrays.<PluginFactory>asList(osgiPluginDeployer),
166             new DefaultPluginEventManager());
167 
168         File zip = new File(bundledPluginJars[0].getParentFile(), "bundled-plugins.zip");
169         for (File bundledPluginJar : bundledPluginJars)
170         {
171             ZipOutputStream stream = null;
172             InputStream in = null;
173             try
174             {
175                 stream = new ZipOutputStream(new FileOutputStream(zip));
176                 in = new FileInputStream(bundledPluginJar);
177                 stream.putNextEntry(new ZipEntry(bundledPluginJar.getName()));
178                 IOUtils.copy(in, stream);
179                 stream.closeEntry();
180             }
181             catch (IOException ex)
182             {
183                 IOUtils.closeQuietly(in);
184                 IOUtils.closeQuietly(stream);
185             }
186         }
187         File bundledDir = new File(bundledPluginJars[0].getParentFile(), "bundled-plugins");
188         final BundledPluginLoader bundledLoader = new BundledPluginLoader(zip.toURL(), bundledDir, Arrays.<PluginFactory>asList(osgiPluginDeployer),
189             new DefaultPluginEventManager());
190 
191         pluginManager = new DefaultPluginManager(new MemoryPluginPersistentStateStore(), Arrays.<PluginLoader> asList(bundledLoader, loader), moduleDescriptorFactory,
192             pluginEventManager);
193         pluginManager.setPluginInstaller(new FilePluginInstaller(pluginsDir));
194         pluginManager.init();
195     }
196 
197     private HostComponentProvider getWrappingHostComponentProvider(final HostComponentProvider hostComponentProvider)
198     {
199         HostComponentProvider requiredWrappingProvider = new HostComponentProvider()
200         {
201             public void provide(final ComponentRegistrar registrar)
202             {
203 
204                 if (hostComponentProvider != null)
205                 {
206                     hostComponentProvider.provide(new ComponentRegistrar()
207                     {
208                         public InstanceBuilder register(Class<?>... mainInterfaces)
209                         {
210                             if (!Arrays.asList(mainInterfaces).contains(PluginEventManager.class))
211                             {
212                                 return registrar.register(mainInterfaces);
213                             }
214                             return null;
215                         }
216                     });
217                 }
218                 registrar.register(ModuleFactory.class).forInstance(moduleFactory);
219                 registrar.register(PluginEventManager.class).forInstance(pluginEventManager);
220                 registrar.register(PluginAccessor.class).forInstance(pluginManager);
221             }
222         };
223         return requiredWrappingProvider;
224     }
225 
226     private PackageScannerConfiguration buildScannerConfiguration(String version)
227     {
228         final PackageScannerConfiguration scannerConfig = new DefaultPackageScannerConfiguration(version);
229         scannerConfig.getPackageIncludes().add("com.atlassian.plugin*");
230         scannerConfig.getPackageIncludes().add("javax.servlet*");
231         scannerConfig.getPackageIncludes().add("com_cenqua_clover");
232         scannerConfig.getPackageExcludes().add("com.atlassian.plugin.osgi.bridge*");
233         scannerConfig.getPackageExcludes().add("com.atlassian.plugin.osgi.bridge.external");
234         scannerConfig.getPackageExcludes().add("com.atlassian.plugin.osgi.spring.external");
235         scannerConfig.getPackageVersions().put("org.apache.commons.logging", "1.1.1");
236         return scannerConfig;
237     }
238 }