1   package com.atlassian.plugin.osgi;
2   
3   import com.atlassian.plugin.JarPluginArtifact;
4   import com.atlassian.plugin.AutowireCapablePlugin;
5   import com.atlassian.plugin.Plugin;
6   import com.atlassian.plugin.PluginState;
7   import com.atlassian.plugin.PluginParseException;
8   import com.atlassian.plugin.PluginRestartState;
9   import com.atlassian.plugin.DefaultModuleDescriptorFactory;
10  import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
11  import com.atlassian.plugin.descriptors.RequiresRestart;
12  import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
13  import com.atlassian.plugin.manager.DefaultPluginManager;
14  import com.atlassian.plugin.util.WaitUntil;
15  import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
16  import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
17  import com.atlassian.plugin.test.PluginJarBuilder;
18  
19  import java.io.File;
20  import java.io.IOException;
21  
22  import org.osgi.util.tracker.ServiceTracker;
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(((AutowireCapablePlugin)plugin).autowire(plugin.loadClass("my.Foo", this.getClass())));
37          pluginManager.disablePlugin("enabledisable");
38          pluginManager.enablePlugin("enabledisable");
39  
40          plugin = pluginManager.getPlugin("enabledisable");
41  
42          assertNotNull(((AutowireCapablePlugin)plugin).autowire(plugin.loadClass("my.Foo", this.getClass())));
43      }
44      
45      public void testDisableEnableOfPluginThatRequiresRestart() throws Exception, IOException
46      {
47          final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
48          factory.addModuleDescriptor("requiresRestart", RequiresRestartModuleDescriptor.class);
49          new PluginJarBuilder()
50                  .addFormattedResource("atlassian-plugin.xml",
51                      "<atlassian-plugin name='Test 2' key='test.restartrequired' pluginsVersion='2'>",
52                      "    <plugin-info>",
53                      "        <version>1.0</version>",
54                      "    </plugin-info>",
55                      "    <requiresRestart key='foo' />",
56                      "</atlassian-plugin>")
57                  .build(pluginsDir);
58  
59          initPluginManager(null, factory);
60  
61          assertEquals(1, pluginManager.getPlugins().size());
62          assertNotNull(pluginManager.getPlugin("test.restartrequired"));
63          assertTrue(pluginManager.isPluginEnabled("test.restartrequired"));
64          assertEquals(1, pluginManager.getEnabledModuleDescriptorsByClass(RequiresRestartModuleDescriptor.class).size());
65          assertEquals(PluginRestartState.NONE, pluginManager.getPluginRestartState("test.restartrequired"));
66  
67          pluginManager.disablePlugin("test.restartrequired");
68          assertFalse(pluginManager.isPluginEnabled("test.restartrequired"));
69          pluginManager.enablePlugin("test.restartrequired");
70  
71          assertEquals(1, pluginManager.getPlugins().size());
72          assertNotNull(pluginManager.getPlugin("test.restartrequired"));
73          assertTrue(pluginManager.isPluginEnabled("test.restartrequired"));
74          assertEquals(PluginRestartState.NONE, pluginManager.getPluginRestartState("test.restartrequired"));
75          assertEquals(1, pluginManager.getEnabledModuleDescriptorsByClass(RequiresRestartModuleDescriptor.class).size());
76      }
77  
78      public void testEnableEnablesDependentPlugins() throws Exception
79      {
80          PluginJarBuilder builderProvider = new PluginJarBuilder("enabledisable-prov")
81                  .addFormattedResource("atlassian-plugin.xml",
82                      "<atlassian-plugin name='Test' key='provider' pluginsVersion='2'>",
83                      "    <plugin-info>",
84                      "        <version>1.0</version>",
85                      "        <bundle-instructions><Export-Package>my</Export-Package></bundle-instructions>",
86                      "    </plugin-info>",
87                      "</atlassian-plugin>")
88                  .addJava("my.Foo", "package my;" +
89                          "public interface Foo {}");
90  
91          PluginJarBuilder builderConsumer = new PluginJarBuilder("enabledisable-con", builderProvider.getClassLoader())
92                  .addFormattedResource("atlassian-plugin.xml",
93                      "<atlassian-plugin name='Test' key='consumer' pluginsVersion='2'>",
94                      "    <plugin-info>",
95                      "        <version>1.0</version>",
96                      "        <bundle-instructions><Import-Package>my</Import-Package></bundle-instructions>",
97                      "    </plugin-info>",
98                      "</atlassian-plugin>")
99                  .addJava("my2.Bar", "package my2;" +
100                         "public class Bar implements my.Foo {}");
101 
102         initPluginManager(null);
103         pluginManager.installPlugin(new JarPluginArtifact(builderProvider.build()));
104         pluginManager.installPlugin(new JarPluginArtifact(builderConsumer.build()));
105 
106         Plugin provider = pluginManager.getPlugin("provider");
107         Plugin consumer = pluginManager.getPlugin("consumer");
108         assertEquals(PluginState.ENABLED, provider.getPluginState());
109         assertEquals(PluginState.ENABLED, consumer.getPluginState());
110 
111         pluginManager.disablePlugin("provider");
112         pluginManager.disablePlugin("consumer");
113 
114         assertEquals(PluginState.DISABLED, provider.getPluginState());
115         assertEquals(PluginState.DISABLED, consumer.getPluginState());
116 
117         pluginManager.enablePlugin("consumer");
118         assertEquals(PluginState.ENABLED, consumer.getPluginState());
119         assertEquals(PluginState.ENABLED, provider.getPluginState());
120     }
121 
122     public void testEnableEnablesDependentPluginsWithBundles() throws Exception
123     {
124         PluginJarBuilder builderProvider = new PluginJarBuilder("enabledisable-prov")
125                 .addFormattedResource("META-INF/MANIFEST.MF",
126                     "Manifest-Version: 1.0",
127                     "Bundle-SymbolicName: my",
128                     "Atlassian-Plugin-Key: provider",
129                     "Export-Package: my",
130                     "")
131                 .addJava("my.Foo", "package my;" +
132                         "public interface Foo {}");
133 
134 
135 
136         PluginJarBuilder builderConsumer = new PluginJarBuilder("enabledisable-con", builderProvider.getClassLoader())
137                 .addFormattedResource("atlassian-plugin.xml",
138                     "<atlassian-plugin name='Test' key='consumer' pluginsVersion='2'>",
139                     "    <plugin-info>",
140                     "        <version>1.0</version>",
141                     "        <bundle-instructions><Import-Package>my</Import-Package></bundle-instructions>",
142                     "    </plugin-info>",
143                     "</atlassian-plugin>")
144                 .addJava("my2.Bar", "package my2;" +
145                         "public class Bar implements my.Foo {}");
146 
147         initPluginManager(null);
148         pluginManager.installPlugin(new JarPluginArtifact(builderProvider.build()));
149         pluginManager.installPlugin(new JarPluginArtifact(builderConsumer.build()));
150 
151         Plugin provider = pluginManager.getPlugin("provider");
152         Plugin consumer = pluginManager.getPlugin("consumer");
153         assertEquals(PluginState.ENABLED, provider.getPluginState());
154         assertEquals(PluginState.ENABLED, consumer.getPluginState());
155 
156         pluginManager.disablePlugin("provider");
157         pluginManager.disablePlugin("consumer");
158 
159         assertEquals(PluginState.DISABLED, provider.getPluginState());
160         assertEquals(PluginState.DISABLED, consumer.getPluginState());
161 
162         pluginManager.enablePlugin("consumer");
163         assertEquals(PluginState.ENABLED, consumer.getPluginState());
164         assertEquals(PluginState.ENABLED, provider.getPluginState());
165     }
166 
167     public void testDisableDoesNotKillLongRunningOperation() throws Exception
168     {
169         File pluginJar = new PluginJarBuilder("longrunning")
170                 .addFormattedResource("atlassian-plugin.xml",
171                         "<atlassian-plugin name='Test' key='longrunning' pluginsVersion='2'>",
172                         "    <plugin-info>",
173                         "        <version>1.0</version>",
174                         "    </plugin-info>",
175                         "    <component key='comp' class='my.Foo' public='true'>",
176                         "       <interface>com.atlassian.plugin.osgi.Callable3</interface>",
177                         "    </component>",
178                         "</atlassian-plugin>")
179                 .addFormattedJava("my.Foo",
180                         "package my;",
181                         "import com.atlassian.plugin.osgi.*;",
182                         "public class Foo implements Callable3{",
183                         "  private Callable2 callable;",
184                         "  public Foo(Callable2 callable) {",
185                         "    this.callable = callable;",
186                         "  }",
187                         "  public String call() throws Exception {",
188                         "    Thread.sleep(2000);",
189                         "    return callable.call();",
190                         "  }",
191                         "}")
192                 .build();
193         initPluginManager(new HostComponentProvider()
194         {
195             public void provide(ComponentRegistrar registrar)
196             {
197                 registrar.register(Callable2.class).forInstance(new Callable2()
198                 {
199 
200                     public String call()
201                     {
202                         return "called";
203                     }
204                 }).withName("foobar");
205             }
206         });
207 
208         pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
209         assertTrue(pluginManager.getPlugin("longrunning").getPluginState() == PluginState.ENABLED);
210         final ServiceTracker tracker = osgiContainerManager.getServiceTracker("com.atlassian.plugin.osgi.Callable3");
211         final Callable3 service = (Callable3) tracker.getService();
212         final StringBuilder sb = new StringBuilder();
213         Thread t = new Thread()
214         {
215             public void run()
216             {
217                 try
218                 {
219                     sb.append(service.call());
220                 }
221                 catch (Exception e)
222                 {
223                     throw new RuntimeException(e);
224                 }
225             }
226         };
227         t.start();
228         pluginManager.disablePlugin("longrunning");
229         t.join();
230         assertEquals("called", sb.toString());
231     }
232     
233     @RequiresRestart
234     public static class RequiresRestartModuleDescriptor extends AbstractModuleDescriptor
235     {
236         @Override
237         public Void getModule()
238         {
239             throw new UnsupportedOperationException("You should never be getting a module from this descriptor " + this.getClass().getName());
240         }
241     }
242 }