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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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 }