View Javadoc

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