View Javadoc

1   package it.com.atlassian.plugin.osgi;
2   
3   import com.atlassian.plugin.DefaultModuleDescriptorFactory;
4   import com.atlassian.plugin.JarPluginArtifact;
5   import com.atlassian.plugin.Plugin;
6   import com.atlassian.plugin.PluginRestartState;
7   import com.atlassian.plugin.PluginState;
8   import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
9   import com.atlassian.plugin.descriptors.RequiresRestart;
10  import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
11  import com.atlassian.plugin.module.ContainerManagedPlugin;
12  import com.atlassian.plugin.module.ModuleFactory;
13  import com.atlassian.plugin.osgi.Callable2;
14  import com.atlassian.plugin.osgi.Callable3;
15  import com.atlassian.plugin.osgi.PluginInContainerTestBase;
16  import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
17  import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
18  import com.atlassian.plugin.test.PluginJarBuilder;
19  import org.osgi.framework.Bundle;
20  import org.osgi.util.tracker.ServiceTracker;
21  
22  import java.io.File;
23  
24  public class TestEnableDisablePlugin extends PluginInContainerTestBase
25  {
26      public void testEnableDisableEnable() throws Exception
27      {
28          File pluginJar = new PluginJarBuilder("enabledisabletest")
29                  .addPluginInformation("enabledisable", "foo", "1.0")
30                  .addJava("my.Foo", "package my;" +
31                          "public class Foo {}")
32                  .build();
33          initPluginManager(null);
34          pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
35          Plugin plugin = pluginManager.getPlugin("enabledisable");
36          assertNotNull(((ContainerManagedPlugin)plugin).getContainerAccessor().createBean(plugin.loadClass("my.Foo", this.getClass())));
37          pluginManager.disablePlugin("enabledisable");
38          pluginManager.enablePlugin("enabledisable");
39  
40          plugin = pluginManager.getPlugin("enabledisable");
41  
42          assertNotNull(((ContainerManagedPlugin)plugin).getContainerAccessor().createBean(plugin.loadClass("my.Foo", this.getClass())));
43      }
44  
45      public void testEnableDisableEnableWithPublicComponent() throws Exception
46      {
47          File pluginJar = new PluginJarBuilder("enabledisabletest")
48                  .addFormattedResource("atlassian-plugin.xml",
49                      "<atlassian-plugin name='Test 2' key='enabledisablewithcomponent' pluginsVersion='2'>",
50                      "    <plugin-info>",
51                      "        <version>1.0</version>",
52                      "    </plugin-info>",
53                      "    <component key='foo' class='my.Foo' public='true' interface='my.Fooable'/>",
54                      "</atlassian-plugin>")
55                  .addJava("my.Fooable", "package my;" +
56                          "public interface Fooable {}")
57                  .addFormattedJava("my.Foo", "package my;",
58                          "public class Foo implements Fooable, org.springframework.beans.factory.DisposableBean {",
59                          "  public void destroy() throws Exception { Thread.sleep(500); }",
60                          "}")
61                  .build();
62          initPluginManager(null);
63          pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
64          Plugin plugin = pluginManager.getPlugin("enabledisablewithcomponent");
65          assertEquals(PluginState.ENABLED, plugin.getPluginState());
66          assertNotNull(((ContainerManagedPlugin)plugin).getContainerAccessor().createBean(plugin.loadClass("my.Foo", this.getClass())));
67          pluginManager.disablePlugin("enabledisablewithcomponent");
68          pluginManager.enablePlugin("enabledisablewithcomponent");
69  
70          plugin = pluginManager.getPlugin("enabledisablewithcomponent");
71          assertEquals(PluginState.ENABLED, plugin.getPluginState());
72  
73          assertNotNull(((ContainerManagedPlugin)plugin).getContainerAccessor().createBean(plugin.loadClass("my.Foo", this.getClass())));
74      }
75      
76      public void testDisableEnableOfPluginThatRequiresRestart() throws Exception
77      {
78          final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
79          factory.addModuleDescriptor("requiresRestart", RequiresRestartModuleDescriptor.class);
80          new PluginJarBuilder()
81                  .addFormattedResource("atlassian-plugin.xml",
82                      "<atlassian-plugin name='Test 2' key='test.restartrequired' pluginsVersion='2'>",
83                      "    <plugin-info>",
84                      "        <version>1.0</version>",
85                      "    </plugin-info>",
86                      "    <requiresRestart key='foo' />",
87                      "</atlassian-plugin>")
88                  .build(pluginsDir);
89  
90          initPluginManager(null, factory);
91  
92          assertEquals(1, pluginManager.getPlugins().size());
93          assertNotNull(pluginManager.getPlugin("test.restartrequired"));
94          assertTrue(pluginManager.isPluginEnabled("test.restartrequired"));
95          assertEquals(1, pluginManager.getEnabledModuleDescriptorsByClass(RequiresRestartModuleDescriptor.class).size());
96          assertEquals(PluginRestartState.NONE, pluginManager.getPluginRestartState("test.restartrequired"));
97  
98          pluginManager.disablePlugin("test.restartrequired");
99          assertFalse(pluginManager.isPluginEnabled("test.restartrequired"));
100         pluginManager.enablePlugin("test.restartrequired");
101 
102         assertEquals(1, pluginManager.getPlugins().size());
103         assertNotNull(pluginManager.getPlugin("test.restartrequired"));
104         assertTrue(pluginManager.isPluginEnabled("test.restartrequired"));
105         assertEquals(PluginRestartState.NONE, pluginManager.getPluginRestartState("test.restartrequired"));
106         assertEquals(1, pluginManager.getEnabledModuleDescriptorsByClass(RequiresRestartModuleDescriptor.class).size());
107     }
108 
109     public void testEnableEnablesDependentPlugins() throws Exception
110     {
111         PluginJarBuilder builderProvider = new PluginJarBuilder("enabledisable-prov")
112                 .addFormattedResource("atlassian-plugin.xml",
113                     "<atlassian-plugin name='Test' key='provider' pluginsVersion='2'>",
114                     "    <plugin-info>",
115                     "        <version>1.0</version>",
116                     "        <bundle-instructions><Export-Package>my</Export-Package></bundle-instructions>",
117                     "    </plugin-info>",
118                     "</atlassian-plugin>")
119                 .addJava("my.Foo", "package my;" +
120                         "public interface Foo {}");
121 
122         PluginJarBuilder builderConsumer = new PluginJarBuilder("enabledisable-con", builderProvider.getClassLoader())
123                 .addFormattedResource("atlassian-plugin.xml",
124                     "<atlassian-plugin name='Test' key='consumer' pluginsVersion='2'>",
125                     "    <plugin-info>",
126                     "        <version>1.0</version>",
127                     "        <bundle-instructions><Import-Package>my</Import-Package></bundle-instructions>",
128                     "    </plugin-info>",
129                     "</atlassian-plugin>")
130                 .addJava("my2.Bar", "package my2;" +
131                         "public class Bar implements my.Foo {}");
132 
133         initPluginManager(null);
134         pluginManager.installPlugin(new JarPluginArtifact(builderProvider.build()));
135         pluginManager.installPlugin(new JarPluginArtifact(builderConsumer.build()));
136 
137         Plugin provider = pluginManager.getPlugin("provider");
138         Plugin consumer = pluginManager.getPlugin("consumer");
139         assertEquals(PluginState.ENABLED, provider.getPluginState());
140         assertEquals(PluginState.ENABLED, consumer.getPluginState());
141 
142         pluginManager.disablePlugin("provider");
143         pluginManager.disablePlugin("consumer");
144 
145         assertEquals(PluginState.DISABLED, provider.getPluginState());
146         assertEquals(PluginState.DISABLED, consumer.getPluginState());
147 
148         pluginManager.enablePlugin("consumer");
149         assertEquals(PluginState.ENABLED, consumer.getPluginState());
150         assertEquals(PluginState.ENABLED, provider.getPluginState());
151     }
152 
153     public void testStoppedOsgiBundleDetected() throws Exception
154     {
155         new PluginJarBuilder("osgi")
156                 .addFormattedResource("META-INF/MANIFEST.MF",
157                     "Manifest-Version: 1.0",
158                     "Bundle-SymbolicName: my",
159                     "Bundle-Version: 1.0",
160                     "")
161                 .build(pluginsDir);
162         initPluginManager();
163         Plugin plugin = pluginManager.getPlugin("my-1.0");
164         assertTrue(pluginManager.isPluginEnabled("my-1.0"));
165         assertTrue(plugin.getPluginState() == PluginState.ENABLED);
166 
167         for (Bundle bundle : osgiContainerManager.getBundles())
168         {
169             if (bundle.getSymbolicName().equals("my"))
170             {
171                 bundle.stop();
172             }
173         }
174 
175         assertFalse(pluginManager.isPluginEnabled("my-1.0"));
176         assertTrue(plugin.getPluginState() == PluginState.DISABLED);
177 
178     }
179 
180 //    public void testStartedOsgiBundleDetected() throws Exception
181 //    {
182 //        new PluginJarBuilder("osgi")
183 //                .addFormattedResource("META-INF/MANIFEST.MF",
184 //                    "Manifest-Version: 1.0",
185 //                    "Bundle-SymbolicName: my",
186 //                    "Bundle-Version: 1.0",
187 //                    "")
188 //                .build(pluginsDir);
189 //        initPluginManager();
190 //        Plugin plugin = pluginManager.getPlugin("my-1.0");
191 //        assertTrue(pluginManager.isPluginEnabled("my-1.0"));
192 //        assertTrue(plugin.getPluginState() == PluginState.ENABLED);
193 //
194 //        for (Bundle bundle : osgiContainerManager.getBundles())
195 //        {
196 //            if (bundle.getSymbolicName().equals("my"))
197 //            {
198 //                bundle.stop();
199 //                bundle.start();
200 //            }
201 //        }
202 //
203 //        assertTrue(WaitUntil.invoke(new WaitUntil.WaitCondition()
204 //        {
205 //            public boolean isFinished()
206 //            {
207 //                return pluginManager.isPluginEnabled("my-1.0");
208 //            }
209 //
210 //            public String getWaitMessage()
211 //            {
212 //                return null;
213 //            }
214 //        }));
215 //        assertTrue(pluginManager.isPluginEnabled("my-1.0"));
216 //        assertTrue(plugin.getPluginState() == PluginState.ENABLED);
217 //    }
218 
219 
220     public void testStoppedOsgiPluginDetected() throws Exception
221     {
222         new PluginJarBuilder("osgi")
223                 .addPluginInformation("my", "foo", "1.0")
224                 .build(pluginsDir);
225         initPluginManager();
226         Plugin plugin = pluginManager.getPlugin("my");
227         assertTrue(pluginManager.isPluginEnabled("my"));
228         assertTrue(plugin.getPluginState() == PluginState.ENABLED);
229 
230         for (Bundle bundle : osgiContainerManager.getBundles())
231         {
232             if (bundle.getSymbolicName().equals("my"))
233             {
234                 bundle.stop();
235             }
236         }
237 
238         assertFalse(pluginManager.isPluginEnabled("my"));
239         assertTrue(plugin.getPluginState() == PluginState.DISABLED);
240 
241     }
242 
243 
244     public void testEnableEnablesDependentPluginsWithBundles() throws Exception
245     {
246         PluginJarBuilder builderProvider = new PluginJarBuilder("enabledisable-prov")
247                 .addFormattedResource("META-INF/MANIFEST.MF",
248                     "Manifest-Version: 1.0",
249                     "Bundle-SymbolicName: my",
250                     "Atlassian-Plugin-Key: provider",
251                     "Export-Package: my",
252                     "")
253                 .addJava("my.Foo", "package my;" +
254                         "public interface Foo {}");
255 
256 
257 
258         PluginJarBuilder builderConsumer = new PluginJarBuilder("enabledisable-con", builderProvider.getClassLoader())
259                 .addFormattedResource("atlassian-plugin.xml",
260                     "<atlassian-plugin name='Test' key='consumer' pluginsVersion='2'>",
261                     "    <plugin-info>",
262                     "        <version>1.0</version>",
263                     "        <bundle-instructions><Import-Package>my</Import-Package></bundle-instructions>",
264                     "    </plugin-info>",
265                     "</atlassian-plugin>")
266                 .addJava("my2.Bar", "package my2;" +
267                         "public class Bar implements my.Foo {}");
268 
269         initPluginManager(null);
270         pluginManager.installPlugin(new JarPluginArtifact(builderProvider.build()));
271         pluginManager.installPlugin(new JarPluginArtifact(builderConsumer.build()));
272 
273         Plugin provider = pluginManager.getPlugin("provider");
274         Plugin consumer = pluginManager.getPlugin("consumer");
275         assertEquals(PluginState.ENABLED, provider.getPluginState());
276         assertEquals(PluginState.ENABLED, consumer.getPluginState());
277 
278         pluginManager.disablePlugin("provider");
279         pluginManager.disablePlugin("consumer");
280 
281         assertEquals(PluginState.DISABLED, provider.getPluginState());
282         assertEquals(PluginState.DISABLED, consumer.getPluginState());
283 
284         pluginManager.enablePlugin("consumer");
285         assertEquals(PluginState.ENABLED, consumer.getPluginState());
286         assertEquals(PluginState.ENABLED, provider.getPluginState());
287     }
288 
289     public void testDisableDoesNotKillLongRunningOperation() throws Exception
290     {
291         File pluginJar = new PluginJarBuilder("longrunning")
292                 .addFormattedResource("atlassian-plugin.xml",
293                         "<atlassian-plugin name='Test' key='longrunning' pluginsVersion='2'>",
294                         "    <plugin-info>",
295                         "        <version>1.0</version>",
296                         "    </plugin-info>",
297                         "    <component key='comp' class='my.Foo' public='true'>",
298                         "       <interface>com.atlassian.plugin.osgi.Callable3</interface>",
299                         "    </component>",
300                         "</atlassian-plugin>")
301                 .addFormattedJava("my.Foo",
302                         "package my;",
303                         "import com.atlassian.plugin.osgi.*;",
304                         "public class Foo implements Callable3{",
305                         "  private Callable2 callable;",
306                         "  public Foo(Callable2 callable) {",
307                         "    this.callable = callable;",
308                         "  }",
309                         "  public String call() throws Exception {",
310                         "    Thread.sleep(2000);",
311                         "    return callable.call();",
312                         "  }",
313                         "}")
314                 .build();
315         initPluginManager(new HostComponentProvider()
316         {
317             public void provide(ComponentRegistrar registrar)
318             {
319                 registrar.register(Callable2.class).forInstance(new Callable2()
320                 {
321 
322                     public String call()
323                     {
324                         return "called";
325                     }
326                 }).withName("foobar");
327             }
328         });
329 
330         pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
331         assertTrue(pluginManager.getPlugin("longrunning").getPluginState() == PluginState.ENABLED);
332         final ServiceTracker tracker = osgiContainerManager.getServiceTracker("com.atlassian.plugin.osgi.Callable3");
333         final Callable3 service = (Callable3) tracker.getService();
334         final StringBuilder sb = new StringBuilder();
335         Thread t = new Thread()
336         {
337             public void run()
338             {
339                 try
340                 {
341                     sb.append(service.call());
342                 }
343                 catch (Exception e)
344                 {
345                     throw new RuntimeException(e);
346                 }
347             }
348         };
349         t.start();
350         pluginManager.disablePlugin("longrunning");
351         t.join();
352         assertEquals("called", sb.toString());
353     }
354     
355     @RequiresRestart
356     public static class RequiresRestartModuleDescriptor extends AbstractModuleDescriptor<Void>
357     {
358         public RequiresRestartModuleDescriptor()
359         {
360             super(ModuleFactory.LEGACY_MODULE_FACTORY);
361         }
362 
363         @Override
364         public Void getModule()
365         {
366             throw new UnsupportedOperationException("You should never be getting a module from this descriptor " + this.getClass().getName());
367         }
368     }
369 }