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