/atlassian-plugins-osgi/src/test/java/it/com/atlassian/plugin/osgi/TestPluginInstall.java
Java | 987 lines | 840 code | 115 blank | 32 comment | 8 complexity | 95e83e98348de8f46bbf77a460b402ea MD5 | raw file
- package it.com.atlassian.plugin.osgi;
- import com.atlassian.plugin.DefaultModuleDescriptorFactory;
- import com.atlassian.plugin.JarPluginArtifact;
- import com.atlassian.plugin.Plugin;
- import com.atlassian.plugin.PluginState;
- import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
- import com.atlassian.plugin.impl.UnloadablePlugin;
- import com.atlassian.plugin.osgi.AnotherInterface;
- import com.atlassian.plugin.osgi.BasicWaitCondition;
- import com.atlassian.plugin.osgi.BooleanFlag;
- import com.atlassian.plugin.osgi.Callable2;
- import com.atlassian.plugin.osgi.Callable3;
- import com.atlassian.plugin.osgi.DefaultBooleanFlag;
- import com.atlassian.plugin.osgi.DummyModuleDescriptor;
- import com.atlassian.plugin.osgi.HostClassUsingHostComponentConstructor;
- import com.atlassian.plugin.osgi.HostClassUsingHostComponentSetter;
- import com.atlassian.plugin.osgi.ObjectModuleDescriptor;
- import com.atlassian.plugin.osgi.PluginInContainerTestBase;
- import com.atlassian.plugin.osgi.SomeInterface;
- import com.atlassian.plugin.osgi.StubServletModuleDescriptor;
- import com.atlassian.plugin.osgi.external.SingleModuleDescriptorFactory;
- import com.atlassian.plugin.osgi.factory.OsgiPlugin;
- import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
- import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
- import com.atlassian.plugin.servlet.DefaultServletModuleManager;
- import com.atlassian.plugin.servlet.ServletModuleManager;
- import com.atlassian.plugin.servlet.descriptors.ServletModuleDescriptor;
- import com.atlassian.plugin.test.PluginJarBuilder;
- import com.atlassian.plugin.util.PluginUtils;
- import com.atlassian.plugin.util.WaitUntil;
- import com.google.common.collect.ImmutableMap;
- import org.junit.Rule;
- import org.junit.Test;
- import org.junit.contrib.java.lang.system.RestoreSystemProperties;
- import org.osgi.framework.Bundle;
- import org.osgi.framework.Constants;
- import javax.servlet.ServletConfig;
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpServlet;
- import java.io.File;
- import java.util.Collections;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- import static com.atlassian.plugin.PluginState.DISABLED;
- import static com.atlassian.plugin.osgi.container.felix.FelixOsgiContainerManager.ATLASSIAN_BOOTDELEGATION_EXTRA;
- import static org.hamcrest.Matchers.empty;
- import static org.hamcrest.Matchers.instanceOf;
- import static org.hamcrest.Matchers.lessThan;
- import static org.hamcrest.Matchers.notNullValue;
- import static org.hamcrest.core.Is.is;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.assertThat;
- import static org.junit.Assert.assertTrue;
- import static org.junit.Assert.fail;
- import static org.mockito.Mockito.mock;
- import static org.mockito.Mockito.when;
- public final class TestPluginInstall extends PluginInContainerTestBase {
- @Rule
- public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
- private static final String SPRING_CONFIG_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<beans xmlns=\"http://www.springframework.org/schema/beans\"\n"
- + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
- + " xmlns:osgi=\"http://www.eclipse.org/gemini/blueprint/schema/blueprint\"\n"
- + " xsi:schemaLocation=\""
- + " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\n"
- + " http://www.eclipse.org/gemini/blueprint/schema/blueprint http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd\"\n"
- + ">\n";
- private static final String SPRING_CONFIG_FOOTER = "</beans>\n";
- private static void assertExists(File f) {
- assertTrue("File should exist: " + f, f.exists());
- }
- private static void assertDoesNotExist(File f) {
- assertFalse("File should not exist: " + f, f.exists());
- }
- @Test
- public void testUpgradeOfBundledPlugin() throws Exception {
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(hostContainer);
- factory.addModuleDescriptor("object", ObjectModuleDescriptor.class);
- final File pluginJar = new PluginJarBuilder("testUpgradeOfBundledPlugin")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.bundled.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <object key='obj' class='my.Foo'/>",
- "</atlassian-plugin>")
- .addFormattedJava("my.Foo",
- "package my;",
- "public class Foo {}")
- .build();
- initBundlingPluginManager(factory, pluginJar);
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("test.bundled.plugin").getName());
- assertEquals("my.Foo", pluginAccessor.getPlugin("test.bundled.plugin").getModuleDescriptor("obj").getModule().getClass().getName());
- final File pluginJar2 = new PluginJarBuilder("testUpgradeOfBundledPlugin")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.bundled.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <object key='obj' class='my.Bar'/>",
- "</atlassian-plugin>")
- .addFormattedJava("my.Bar",
- "package my;",
- "public class Bar {}")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar2));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("test.bundled.plugin").getName());
- assertEquals("my.Bar", pluginAccessor.getPlugin("test.bundled.plugin").getModuleDescriptor("obj").getModule().getClass().getName());
- }
- @Test
- public void testUpgradeOfBadPlugin() throws Exception {
- new PluginJarBuilder("testUpgradeOfBundledPlugin-old")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.bundled.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component key='obj' class='my.Foo'/>",
- "</atlassian-plugin>")
- .addFormattedJava("my.Foo",
- "package my;",
- "public class Foo {",
- " public Foo() { throw new RuntimeException('bad plugin');}",
- "}")
- .build(pluginsDir);
- new PluginJarBuilder("testUpgradeOfBundledPlugin-new")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.bundled.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>2.0</version>",
- " </plugin-info>",
- " <component key='obj' class='my.Foo'/>",
- "</atlassian-plugin>")
- .addFormattedJava("my.Foo",
- "package my;",
- "public class Foo {",
- " public Foo() {}",
- "}")
- .build(pluginsDir);
- initPluginManager();
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("test.bundled.plugin").getName());
- assertEquals("2.0", pluginAccessor.getPlugin("test.bundled.plugin").getPluginInformation().getVersion());
- }
- @Test
- public void testUpgradeWithNewComponentImports() throws Exception {
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
- factory.addModuleDescriptor("dummy", DummyModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface() {
- });
- registrar.register(AnotherInterface.class).forInstance(new AnotherInterface() {
- });
- }
- }, factory);
- final File pluginJar = new PluginJarBuilder("first")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component-import key='comp1' interface='com.atlassian.plugin.osgi.SomeInterface' />",
- " <dummy key='dum1'/>", "</atlassian-plugin>")
- .build();
- final File pluginJar2 = new PluginJarBuilder("second")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component-import key='comp1' interface='com.atlassian.plugin.osgi.SomeInterface' />",
- " <component-import key='comp2' interface='com.atlassian.plugin.osgi.AnotherInterface' />",
- " <dummy key='dum1'/>",
- " <dummy key='dum2'/>",
- "</atlassian-plugin>")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("test.plugin").getName());
- assertEquals(2, pluginAccessor.getPlugin("test.plugin").getModuleDescriptors().size());
- pluginController.installPlugins(new JarPluginArtifact(pluginJar2));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals(4, pluginAccessor.getPlugin("test.plugin").getModuleDescriptors().size());
- assertEquals("Test 2", pluginAccessor.getPlugin("test.plugin").getName());
- }
- @Test
- public void testInstallWithClassConstructorReferencingHostClassWithHostComponent() throws Exception {
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(hostContainer);
- factory.addModuleDescriptor("object", ObjectModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface() {
- });
- }
- }, factory);
- final File pluginJar = new PluginJarBuilder("testUpgradeOfBundledPlugin")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='hostClass' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <object key='hostClass' class='com.atlassian.plugin.osgi.HostClassUsingHostComponentConstructor'/>",
- "</atlassian-plugin>")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("hostClass").getName());
- assertEquals(1, pluginAccessor.getPlugin("hostClass").getModuleDescriptors().size());
- HostClassUsingHostComponentConstructor module = (HostClassUsingHostComponentConstructor) pluginAccessor.getPlugin("hostClass").getModuleDescriptor("hostClass").getModule();
- assertNotNull(module);
- }
- @Test
- public void testInstallWithClassSetterReferencingHostClassWithHostComponent() throws Exception {
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(hostContainer);
- factory.addModuleDescriptor("object", ObjectModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface() {
- });
- }
- }, factory);
- final File pluginJar = new PluginJarBuilder("testUpgradeOfBundledPlugin")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='hostClass' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <object key='hostClass' class='com.atlassian.plugin.osgi.HostClassUsingHostComponentSetter'/>",
- "</atlassian-plugin>")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("hostClass").getName());
- assertEquals(1, pluginAccessor.getPlugin("hostClass").getModuleDescriptors().size());
- HostClassUsingHostComponentSetter module = (HostClassUsingHostComponentSetter) pluginAccessor.getPlugin("hostClass").getModuleDescriptor("hostClass").getModule();
- assertNotNull(module);
- assertNotNull(module.getSomeInterface());
- }
- /* Enable for manual memory leak profiling
- @Test
- public void testNoMemoryLeak() throws Exception
- {
- DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
- factory.addModuleDescriptor("dummy", DummyModuleDescriptor.class);
- for (int x=0; x<100; x++)
- {
- pluginEventManager = new DefaultPluginEventManager();
- initPluginManager(new HostComponentProvider(){
- public void provide(ComponentRegistrar registrar)
- {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface(){});
- registrar.register(AnotherInterface.class).forInstance(new AnotherInterface(){});
- }
- }, factory);
- pluginSystemLifecycle.shutdown();
- }
- System.out.println("Gentlement, start your profilers!");
- System.in.read();
- }
- */
- @Test
- public void testUpgradeWithNoAutoDisable() throws Exception {
- DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
- factory.addModuleDescriptor("dummy", DummyModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(ComponentRegistrar registrar) {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface() {
- });
- registrar.register(AnotherInterface.class).forInstance(new AnotherInterface() {
- });
- }
- }, factory);
- File pluginJar = new PluginJarBuilder("first")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component-import key='comp1' interface='com.atlassian.plugin.osgi.SomeInterface' />",
- " <dummy key='dum1'/>",
- "</atlassian-plugin>")
- .build();
- final File pluginJar2 = new PluginJarBuilder("second")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component-import key='comp1' interface='com.atlassian.plugin.osgi.SomeInterface' />",
- " <dummy key='dum1'/>",
- " <dummy key='dum2'/>",
- "</atlassian-plugin>")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar));
- assertTrue(pluginAccessor.isPluginEnabled("test.plugin"));
- final Lock lock = new ReentrantLock();
- Thread upgradeThread = new Thread() {
- public void run() {
- lock.lock();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar2));
- lock.unlock();
- }
- };
- Thread isEnabledThread = new Thread() {
- public void run() {
- try {
- while (!lock.tryLock(10, TimeUnit.SECONDS))
- pluginAccessor.isPluginEnabled("test.plugin");
- } catch (InterruptedException e) {
- fail();
- }
- }
- };
- upgradeThread.start();
- isEnabledThread.start();
- upgradeThread.join(10000);
- assertTrue(pluginAccessor.isPluginEnabled("test.plugin"));
- }
- @Test
- public void testUpgradeTestingForCachedXml() throws Exception {
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
- factory.addModuleDescriptor("dummy", DummyModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface() {
- });
- registrar.register(AnotherInterface.class).forInstance(new AnotherInterface() {
- });
- }
- }, factory);
- final File pluginJar = new PluginJarBuilder("first").addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>", " <plugin-info>", " <version>1.0</version>",
- " </plugin-info>", " <component key='comp1' interface='com.atlassian.plugin.osgi.SomeInterface' class='my.ServiceImpl' />",
- "</atlassian-plugin>").addFormattedJava("my.ServiceImpl", "package my;",
- "public class ServiceImpl implements com.atlassian.plugin.osgi.SomeInterface {}").build();
- final File pluginJar2 = new PluginJarBuilder("second").addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>", " <plugin-info>", " <version>1.0</version>",
- " </plugin-info>", "</atlassian-plugin>").build();
- pluginController.installPlugins(new JarPluginArtifact(pluginJar));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test", pluginAccessor.getPlugin("test.plugin").getName());
- pluginController.installPlugins(new JarPluginArtifact(pluginJar2));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertEquals("Test 2", pluginAccessor.getPlugin("test.plugin").getName());
- }
- @Test
- public void testPluginDependentOnPackageImport() throws Exception {
- HostComponentProvider prov = new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- registrar.register(ServletConfig.class).forInstance(new HttpServlet() {
- });
- }
- };
- File servletJar = new PluginJarBuilder("first")
- .addFormattedResource("META-INF/MANIFEST.MF",
- "Export-Package: javax.servlet.http;version='4.0.0',javax.servlet;version='4.0.0'",
- "Import-Package: javax.servlet.http;version='4.0.0',javax.servlet;version='4.0.0'",
- "Bundle-SymbolicName: first",
- "Bundle-Version: 4.0.0",
- "Manifest-Version: 1.0",
- "")
- .addFormattedJava("javax.servlet.Servlet",
- "package javax.servlet;",
- "public interface Servlet {}")
- .addFormattedJava("javax.servlet.http.HttpServlet",
- "package javax.servlet.http;",
- "public abstract class HttpServlet implements javax.servlet.Servlet{}")
- .build();
- File pluginJar = new PluginJarBuilder("asecond")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='second' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " <bundle-instructions><Import-Package>javax.servlet.http;version='3.0',javax.servlet;version='3.0',*</Import-Package></bundle-instructions>",
- " </plugin-info>",
- "</atlassian-plugin>")
- .addFormattedJava("second.MyImpl",
- "package second;",
- "public class MyImpl {",
- " public MyImpl(javax.servlet.ServletConfig config) {",
- " }",
- "}")
- .build();
- initPluginManager(prov);
- pluginController.installPlugins(new JarPluginArtifact(servletJar));
- pluginController.installPlugins(new JarPluginArtifact(pluginJar));
- WaitUntil.invoke(new BasicWaitCondition() {
- public boolean isFinished() {
- return pluginAccessor.getEnabledPlugins().size() == 2;
- }
- });
- assertEquals(2, pluginAccessor.getEnabledPlugins().size());
- assertNotNull(pluginAccessor.getPlugin("first-4.0.0"));
- assertNotNull(pluginAccessor.getPlugin("second"));
- }
- @Test
- public void testPluginWithHostComponentUsingOldPackageImport() throws Exception {
- final PluginJarBuilder firstBuilder = new PluginJarBuilder("oldpkgfirst");
- firstBuilder
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='first' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " <bundle-instructions>",
- " <Export-Package>first</Export-Package>",
- " </bundle-instructions>",
- " </plugin-info>",
- " <servlet key='foo' class='second.MyServlet'>",
- " <url-pattern>/foo</url-pattern>",
- " </servlet>",
- "</atlassian-plugin>")
- .addFormattedJava("first.MyInterface",
- "package first;",
- "public interface MyInterface {}")
- .build(pluginsDir);
- new PluginJarBuilder("oldpkgsecond", firstBuilder.getClassLoader())
- .addPluginInformation("second", "Some name", "1.0")
- .addFormattedJava("second.MyImpl",
- "package second;",
- "public class MyImpl implements first.MyInterface {}")
- .build(pluginsDir);
- initPluginManager();
- assertEquals(2, pluginAccessor.getEnabledPlugins().size());
- assertNotNull(pluginAccessor.getPlugin("first"));
- assertNotNull(pluginAccessor.getPlugin("second"));
- }
- @Test
- public void testPluginWithServletDependentOnPackageImport() throws Exception {
- final PluginJarBuilder firstBuilder = new PluginJarBuilder("first");
- firstBuilder
- .addPluginInformation("first", "Some name", "1.0")
- .addFormattedJava("first.MyInterface",
- "package first;",
- "public interface MyInterface {}")
- .addFormattedResource("META-INF/MANIFEST.MF",
- "Manifest-Version: 1.0",
- "Bundle-SymbolicName: first",
- "Bundle-Version: 1.0",
- "Export-Package: first",
- "")
- .build(pluginsDir);
- new PluginJarBuilder("asecond", firstBuilder.getClassLoader())
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='asecond' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <servlet key='foo' class='second.MyServlet'>",
- " <url-pattern>/foo</url-pattern>",
- " </servlet>",
- "</atlassian-plugin>")
- .addFormattedJava("second.MyServlet",
- "package second;",
- "public class MyServlet extends javax.servlet.http.HttpServlet implements first.MyInterface {}")
- .build(pluginsDir);
- initPluginManager(null, new SingleModuleDescriptorFactory(new DefaultHostContainer(), "servlet", StubServletModuleDescriptor.class));
- assertEquals(2, pluginAccessor.getEnabledPlugins().size());
- assertTrue(pluginAccessor.getPlugin("first").getPluginState() == PluginState.ENABLED);
- assertNotNull(pluginAccessor.getPlugin("asecond").getPluginState() == PluginState.ENABLED);
- }
- @Test
- public void testPluginWithServletRefreshedAfterOtherPluginUpgraded() throws Exception {
- final PluginJarBuilder firstBuilder = new PluginJarBuilder("first");
- firstBuilder
- .addPluginInformation("first", "Some name", "1.0")
- .addFormattedJava("first.MyInterface",
- "package first;",
- "public interface MyInterface {}")
- .addFormattedResource("META-INF/MANIFEST.MF",
- "Manifest-Version: 1.0",
- "Bundle-SymbolicName: first",
- "Bundle-Version: 1.0",
- "Export-Package: first",
- "")
- .build(pluginsDir);
- new PluginJarBuilder("asecond", firstBuilder.getClassLoader())
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='asecond' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <servlet key='foo' class='second.MyServlet'>",
- " <url-pattern>/foo</url-pattern>",
- " </servlet>",
- "</atlassian-plugin>")
- .addFormattedJava("second.MyServlet",
- "package second;",
- "import com.atlassian.plugin.osgi.Callable2;",
- "public class MyServlet extends javax.servlet.http.HttpServlet implements first.MyInterface {",
- " private Callable2 callable;",
- " public MyServlet(Callable2 cal) { this.callable = cal; }",
- " public String getServletInfo() {",
- " try {return callable.call() + ' bob';} catch (Exception ex) { throw new RuntimeException(ex);}",
- " }",
- "}")
- .build(pluginsDir);
- HostComponentProvider prov = new HostComponentProvider() {
- public void provide(ComponentRegistrar registrar) {
- registrar.register(Callable2.class).forInstance(new Callable2() {
- public String call() {
- return "hi";
- }
- });
- }
- };
- ServletContext ctx = mock(ServletContext.class);
- when(ctx.getInitParameterNames()).thenReturn(Collections.<String>enumeration(Collections.<String>emptyList()));
- ServletConfig servletConfig = mock(ServletConfig.class);
- when(servletConfig.getServletContext()).thenReturn(ctx);
- ServletModuleManager mgr = new DefaultServletModuleManager(pluginEventManager);
- hostContainer = createHostContainer(Collections.<Class<?>, Object>singletonMap(ServletModuleManager.class, mgr));
- initPluginManager(prov, new SingleModuleDescriptorFactory(
- hostContainer,
- "servlet",
- ServletModuleDescriptor.class));
- assertEquals(2, pluginAccessor.getEnabledPlugins().size());
- assertTrue(pluginAccessor.getPlugin("first").getPluginState() == PluginState.ENABLED);
- assertNotNull(pluginAccessor.getPlugin("asecond").getPluginState() == PluginState.ENABLED);
- assertEquals("hi bob", mgr.getServlet("/foo", servletConfig).getServletInfo());
- final File updatedJar = new PluginJarBuilder("first-updated")
- .addPluginInformation("foo", "Some name", "1.0")
- .addFormattedJava("first.MyInterface",
- "package first;",
- "public interface MyInterface {}")
- .addFormattedResource("META-INF/MANIFEST.MF",
- "Manifest-Version: 1.0",
- "Bundle-SymbolicName: foo",
- "Bundle-Version: 1.0",
- "Export-Package: first",
- "")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(updatedJar));
- WaitUntil.invoke(new BasicWaitCondition() {
- public boolean isFinished() {
- return pluginAccessor.isPluginEnabled("asecond");
- }
- });
- assertEquals("hi bob", mgr.getServlet("/foo", servletConfig).getServletInfo());
- }
- // PLUG-760
- @Test
- public void testModuleDescriptorWithNamespace() throws Exception {
- new PluginJarBuilder("asecond")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='asecond' pluginsVersion='2'",
- " xmlns='http://www.atlassian.com/schema/plugins'",
- " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'",
- " xsi:schemaLocation='http://www.atlassian.com/schema/plugins http://schema.atlassian.com/refapp/refapp-2.9.xsd'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <servlet key='foo' class='second.MyServlet'>",
- " <url-pattern>/foo</url-pattern>",
- " </servlet>",
- "</atlassian-plugin>")
- .addFormattedJava("second.MyServlet",
- "package second;",
- "public class MyServlet extends javax.servlet.http.HttpServlet {}")
- .build(pluginsDir);
- ServletContext ctx = mock(ServletContext.class);
- when(ctx.getInitParameterNames()).thenReturn(Collections.<String>enumeration(Collections.<String>emptyList()));
- ServletConfig servletConfig = mock(ServletConfig.class);
- when(servletConfig.getServletContext()).thenReturn(ctx);
- ServletModuleManager mgr = new DefaultServletModuleManager(pluginEventManager);
- hostContainer = createHostContainer(Collections.<Class<?>, Object>singletonMap(ServletModuleManager.class, mgr));
- initPluginManager(null, new SingleModuleDescriptorFactory(
- hostContainer,
- "servlet",
- ServletModuleDescriptor.class));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertNotNull(pluginAccessor.getPlugin("asecond").getPluginState() == PluginState.ENABLED);
- }
- @Test
- public void testLotsOfHostComponents() throws Exception {
- new PluginJarBuilder("first")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <dummy key='dum1'/>",
- "</atlassian-plugin>")
- .build(pluginsDir);
- new PluginJarBuilder("second")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test 2' key='test.plugin2' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <dummy key='dum1'/>",
- " <dummy key='dum2'/>",
- "</atlassian-plugin>")
- .build(pluginsDir);
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
- factory.addModuleDescriptor("dummy", DummyModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- for (int x = 0; x < 100; x++) {
- registrar.register(SomeInterface.class).forInstance(new SomeInterface() {
- }).withName("some" + x);
- registrar.register(AnotherInterface.class).forInstance(new AnotherInterface() {
- }).withName("another" + x);
- }
- }
- }, factory);
- assertEquals(2, pluginAccessor.getEnabledPlugins().size());
- }
- @Test
- public void testInstallWithManifestNoSpringContextAndComponents() throws Exception {
- final BooleanFlag flag = new DefaultBooleanFlag(false);
- new PluginJarBuilder("first")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='first' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component key='foo' class='first.MyClass' interface='first.MyInterface' public='true'/>",
- "</atlassian-plugin>")
- .addFormattedJava("first.MyInterface",
- "package first;",
- "public interface MyInterface {}")
- .addFormattedJava("first.MyClass",
- "package first;",
- "public class MyClass implements MyInterface{",
- " public MyClass(com.atlassian.plugin.osgi.BooleanFlag bool) { bool.set(true); }",
- "}")
- .addFormattedResource("META-INF/MANIFEST.MF",
- "Manifest-Version: 1.0",
- "Bundle-SymbolicName: foo",
- "Bundle-Version: 1.0",
- "Export-Package: first",
- "")
- .build(pluginsDir);
- initPluginManager(registrar -> registrar.register(BooleanFlag.class)
- .forInstance(flag)
- .withName("bob"));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertNotNull(pluginAccessor.getPlugin("first"));
- assertTrue(flag.get());
- }
- @Test
- public void testInstallWithManifestNoDescriptorWithSpringXml() throws Exception {
- new PluginJarBuilder("nodesc")
- .manifest(new ImmutableMap.Builder<String, String>()
- .put(OsgiPlugin.ATLASSIAN_PLUGIN_KEY, "nodesc")
- .put(Constants.BUNDLE_VERSION, "1.0")
- .build())
- .addResource("META-INF/spring/foo.xml", SPRING_CONFIG_HEADER + SPRING_CONFIG_FOOTER)
- .build(pluginsDir);
- initPluginManager();
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- Plugin plugin = pluginAccessor.getPlugin("nodesc");
- assertNotNull(plugin);
- assertEquals("1.0", plugin.getPluginInformation().getVersion());
- assertEquals("nodesc", plugin.getKey());
- assertEquals(0, plugin.getModuleDescriptors().size());
- }
- @Test
- public void testInstallWithManifestNoDescriptorWithSpringHeader() throws Exception {
- new PluginJarBuilder("nodesc")
- .manifest(new ImmutableMap.Builder<String, String>()
- .put(OsgiPlugin.ATLASSIAN_PLUGIN_KEY, "nodesc")
- .put(Constants.BUNDLE_VERSION, "1.0")
- .put("Spring-Context", "*;timeout:=60")
- .build())
- .build(pluginsDir);
- initPluginManager();
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- Plugin plugin = pluginAccessor.getPlugin("nodesc");
- assertNotNull(plugin);
- assertEquals("1.0", plugin.getPluginInformation().getVersion());
- assertEquals("nodesc", plugin.getKey());
- assertEquals(0, plugin.getModuleDescriptors().size());
- }
- @Test
- public void testInstallWithSpringContainerFail() throws Exception {
- System.setProperty(PluginUtils.ATLASSIAN_PLUGINS_ENABLE_WAIT, "10");
- new PluginJarBuilder("fail-spring-container")
- .manifest(new ImmutableMap.Builder<String, String>()
- .put(OsgiPlugin.ATLASSIAN_PLUGIN_KEY, "fail-spring-container")
- .put(Constants.BUNDLE_VERSION, "1.0")
- .put("Spring-Context", "*")
- .build())
- .addResource("META-INF/spring/fail.xml",
- SPRING_CONFIG_HEADER + "<osgi:reference id=\"notFound\" interface=\"some.class.NotFound\"/>" + SPRING_CONFIG_FOOTER)
- .build(pluginsDir);
- final long beforeStarting = System.currentTimeMillis();
- initPluginManager();
- final long startupDuration = System.currentTimeMillis() - beforeStarting;
- assertThat(pluginAccessor.getEnabledPlugins(), empty());
- final Plugin plugin = pluginAccessor.getPlugin("fail-spring-container");
- assertThat(plugin, notNullValue());
- assertThat(plugin, instanceOf(OsgiPlugin.class));
- final OsgiPlugin osgiPlugin = (OsgiPlugin) plugin;
- assertThat(osgiPlugin.getPluginState(), is(DISABLED));
- assertThat(osgiPlugin.getBundle().getState(), is(Bundle.RESOLVED));
- assertThat("fail-spring-container failed due to plugin system timeout rather than immediately via PluginContainerFailedEvent", startupDuration, lessThan(10000L));
- }
- // TODO: turn this back on PLUG-682
- // @Test
- public void testInstallWithComponentBeanNameConflictedWithHostComponent() throws Exception {
- new PluginJarBuilder("first")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='first' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component key='host_component1' class='first.MyClass' interface='first.MyInterface'/>",
- "</atlassian-plugin>")
- .addFormattedJava("com.atlassian.plugin.osgi.SomeInterface",
- "package com.atlassian.plugin.osgi;",
- "public interface SomeInterface {}")
- .addFormattedJava("first.MyClass",
- "package first;",
- "import com.atlassian.plugin.osgi.SomeInterface;",
- "public class MyClass implements SomeInterface{",
- "}")
- .build(pluginsDir);
- initPluginManager(registrar -> registrar.register(SomeInterface.class)
- .forInstance(new SomeInterface() {})
- .withName("host_component1"));
- // there is a name conflict therefore this plugin should not have been enabled.
- assertEquals(0, pluginAccessor.getEnabledPlugins().size());
- assertTrue(pluginAccessor.getPlugins().toArray()[0] instanceof UnloadablePlugin);
- // the error message has to mention the problematic component name otherwise users won't be able to figure out.
- assertTrue(pluginAccessor.getPlugins().toArray(new UnloadablePlugin[1])[0].getErrorText().contains("host_component1"));
- }
- @Test
- public void testInstallWithStrangePath() throws Exception {
- File strangeDir = new File(tmpDir, "20%time");
- strangeDir.mkdir();
- File oldTmp = tmpDir;
- try {
- tmpDir = strangeDir;
- cacheDir = new File(tmpDir, "felix-cache");
- cacheDir.mkdir();
- pluginsDir = new File(tmpDir, "plugins");
- pluginsDir.mkdir();
- new PluginJarBuilder("strangePath")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- "</atlassian-plugin>")
- .build(pluginsDir);
- final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
- factory.addModuleDescriptor("dummy", DummyModuleDescriptor.class);
- initPluginManager(new HostComponentProvider() {
- public void provide(final ComponentRegistrar registrar) {
- }
- }, factory);
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- } finally {
- tmpDir = oldTmp;
- }
- }
- @Test
- public void testInstallWithUnsatisifedDependency() throws Exception {
- File plugin = new PluginJarBuilder("unsatisifiedDependency")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component-import key='foo' interface='java.util.concurrent.Callable' />",
- "</atlassian-plugin>")
- .build(pluginsDir);
- long start = System.currentTimeMillis();
- // Set dev mode temporarily
- System.setProperty("atlassian.dev.mode", "true");
- System.setProperty(PluginUtils.ATLASSIAN_PLUGINS_ENABLE_WAIT, "7");
- initPluginManager();
- assertTrue(start + (60 * 1000) > System.currentTimeMillis());
- }
- @Test
- public void testInstallSimplePluginNoSpring() throws Exception {
- File jar = new PluginJarBuilder("strangePath")
- .addPluginInformation("no-spring", "foo", "1.0")
- .build();
- initPluginManager();
- pluginController.installPlugins(new JarPluginArtifact(jar));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- }
- @Test
- public void testInstallSimplePluginWithNoManifest() throws Exception {
- File jar = new PluginJarBuilder("strangePath")
- .addPluginInformation("no-spring", "foo", "1.0")
- .buildWithNoManifest();
- initPluginManager();
- pluginController.installPlugins(new JarPluginArtifact(jar));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- }
- @Test
- public void testInstallPluginTakesTooLong() throws Exception {
- System.setProperty(PluginUtils.ATLASSIAN_PLUGINS_ENABLE_WAIT, "3");
- final PluginJarBuilder builder = new PluginJarBuilder("first")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " </plugin-info>",
- " <component key='svc' class='my.ServiceImpl' public='true'>",
- " <interface>my.Service</interface>",
- " </component>",
- "</atlassian-plugin>")
- .addFormattedJava("my.Service",
- "package my;",
- "public interface Service {",
- " public Object call() throws Exception;",
- "}")
- .addFormattedJava("my.ServiceImpl",
- "package my;",
- "public class ServiceImpl implements Service {",
- "public ServiceImpl(){",
- "try{",
- "Thread.sleep(10000);",
- "}catch(Exception e){}",
- "}",
- " public Object call() throws Exception { ",
- " return 'hi';}",
- "}");
- final File jar = builder.build();
- initPluginManager();
- pluginController.installPlugins(new JarPluginArtifact(jar));
- assertEquals(0, pluginAccessor.getEnabledPlugins().size());
- }
- @Test
- public void testInstallPluginVersion3() throws Exception {
- initPluginManager();
- final File v3plugin = new PluginJarBuilder("v3-plugin")
- .addFormattedResource("atlassian-plugin.xml",
- "<atlassian-plugin name='V3 Plugin' key='v3-plugin' pluginsVersion='3'>",
- " <plugin-info>",
- " <version>1.0</version>",
- " <permissions>",
- " <permission>execute_java</permission>",
- " </permissions>",
- " </plugin-info>",
- "</atlassian-plugin>")
- .addFormattedResource("META-INF/MANIFEST.MF",
- "Bundle-SymbolicName: v3-plugin",
- // need the key because of com.atlassian.plugin.osgi.factory.OsgiPluginUninstalledHelper#install,
- // and the comparison of keys, using com.atlassian.plugin.osgi.util.OsgiHeaderUtil#getPluginKey !
- OsgiPlugin.ATLASSIAN_PLUGIN_KEY + ": v3-plugin",
- "Bundle-Version: 1.0.0",
- "Manifest-Version: 1.0",
- "Spring-Context: *;timeout:=60", // we still need a container, add this to trigger spring.
- "")
- .build();
- pluginController.installPlugins(new JarPluginArtifact(v3plugin));
- assertEquals(1, pluginAccessor.getEnabledPlugins().size());
- assertNotNull(pluginAccessor.getEnabledPlugin("v3-plugin"));
- }
- public static class Callable3Aware {
- private final Callable3 callable;
- public Callable3Aware(Callable3 callable) {
- this.callable = callable;
- }
- public String call() throws Exception {
- return callable.call();
- }
- }
- }