View Javadoc
1   package com.atlassian.plugin.osgi.spring;
2   
3   import com.atlassian.plugin.JarPluginArtifact;
4   import com.atlassian.plugin.osgi.PluginInContainerTestBase;
5   import com.atlassian.plugin.test.PluginJarBuilder;
6   import org.junit.Test;
7   
8   import static org.junit.Assert.assertEquals;
9   
10  /**
11   * When an optional OSGi service is unavailable at runtime, Spring DM's proxy class will throw a specific exception.
12   * The exception is different in OSGi Blueprint. This test is to demonstrate a plugin that relies on the Spring DM
13   * behaviour so we can consider other approaches.
14   * <ul>
15   * <li>Catch <code>RuntimeException</code> and check for both class names
16   * <li>Fail; don't try to cope with missing services
17   * <li>Rewrite the bytecode for the catch at runtime
18   * </li>
19   */
20  public class TestServiceUnavailable extends PluginInContainerTestBase {
21      /* Spring definition of a bean that takes an optional reference to an OSGi service */
22      static final String beans = "<beans xmlns=\"http://www.springframework.org/schema/beans\"\n" +
23              "             xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
24              "             xmlns:osgi=\"http://www.eclipse.org/gemini/blueprint/schema/blueprint\"\n" +
25              "             xsi:schemaLocation=\"" +
26              "                 http://www.eclipse.org/gemini/blueprint/schema/blueprint http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd\n" +
27              "                 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\">\n" +
28              "\n" +
29              " <osgi:reference id='a' interface='test.X' cardinality='0..1' timeout='1'/>" +
30              " <bean class='test.FooConsumer'>" +
31              "  <constructor-arg ref='a' />" +
32              " </bean>" +
33  
34              "</beans>\n";
35  
36      /* Communicate with the plugin through a static field */
37      public static String mutable = null;
38  
39      @Test
40      public void testUnavailableServicesCanBeDetected() throws Exception {
41          TestServiceUnavailable.mutable = null;
42  
43          initPluginManager();
44  
45          PluginJarBuilder plugin = new PluginJarBuilder("testServiceUnavailable")
46                  .addFormattedResource("atlassian-plugin.xml",
47                          "<atlassian-plugin name='Test' key='test.serviceunavailable.plugin' pluginsVersion='2'>",
48                          "    <plugin-info>",
49                          "        <version>1.0</version>",
50                          "    </plugin-info>",
51                          "</atlassian-plugin>")
52  
53                  .addFormattedJava("test.X",
54                          "package test;",
55                          "public interface X {}"
56                  )
57  
58                  .addFormattedJava("test.FooConsumer",
59                          "package test;",
60                          "import com.atlassian.plugin.osgi.spring.TestServiceUnavailable;",
61                          /* A constructor that tries to use an OSGi service stub and cope with it being unavailable */
62                          "public class FooConsumer {",
63                          "    FooConsumer (Object foo)",
64                          "    {",
65                          "        TestServiceUnavailable.mutable = \"invoked\";",
66                          "        try",
67                          "        {",
68                          "            foo.toString();",
69                          "            TestServiceUnavailable.mutable = \"succeeded\";",
70                          "        }",
71                          "        catch (RuntimeException e)",
72                          "        {",
73                          "            if (e.getClass().getSimpleName().equals(\"ServiceUnavailableException\"))",
74                          "            {",
75                          "                TestServiceUnavailable.mutable = \"caught\";",
76                          "            }",
77                          "            else",
78                          "            {",
79                          "                throw e;",
80                          "            }",
81                          "        }",
82                          "        catch (Exception e)",
83                          "        {",
84                          "            TestServiceUnavailable.mutable = \"unexpected - \" + e.getClass().getName();",
85                          "        }",
86                          "    }",
87                          "}"
88                  )
89  
90                  .addFormattedResource("META-INF/spring/beans.xml", beans);
91  
92          plugin.build(pluginsDir);
93  
94          pluginController.installPlugins(new JarPluginArtifact(plugin.build()));
95  
96          osgiContainerManager.stop();
97  
98          assertEquals("The specific ServiceUnavailableException should be caught",
99                  "caught", mutable);
100     }
101 }