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 }