aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ross2013-08-09 10:29:15 (EDT)
committerJohn Ross2013-08-12 16:21:34 (EDT)
commit07670433d11dd8ebcca2377523e4e9d176ccdb5a (patch)
treeb6a0ffa444b629a8893bd27e1a35520088057e19
parent55f96a565cf574519f8f98173516a351cc24ac19 (diff)
downloadrt.equinox.bundles-07670433d11dd8ebcca2377523e4e9d176ccdb5a.zip
rt.equinox.bundles-07670433d11dd8ebcca2377523e4e9d176ccdb5a.tar.gz
rt.equinox.bundles-07670433d11dd8ebcca2377523e4e9d176ccdb5a.tar.bz2
[Bug 413053] Test component descriptors are reloaded on bundle update when using wildcards in Service-Component.
-rw-r--r--bundles/org.eclipse.equinox.ds.tests/.classpath1
-rw-r--r--bundles/org.eclipse.equinox.ds.tests/build.properties6
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF8
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml13
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java107
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java13
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java13
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml13
-rwxr-xr-xbundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml13
-rw-r--r--bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java115
10 files changed, 300 insertions, 2 deletions
diff --git a/bundles/org.eclipse.equinox.ds.tests/.classpath b/bundles/org.eclipse.equinox.ds.tests/.classpath
index 932ccfe..d81e9c0 100644
--- a/bundles/org.eclipse.equinox.ds.tests/.classpath
+++ b/bundles/org.eclipse.equinox.ds.tests/.classpath
@@ -30,5 +30,6 @@
<classpathentry kind="src" output="scr_test/tb22" path="bundles_src/tb22"/>
<classpathentry kind="src" output="scr_test/tb23" path="bundles_src/tb23"/>
<classpathentry kind="src" output="scr_test/tb25" path="bundles_src/tb25"/>
+ <classpathentry kind="src" output="scr_test/tb26" path="bundles_src/tb26"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bundles/org.eclipse.equinox.ds.tests/build.properties b/bundles/org.eclipse.equinox.ds.tests/build.properties
index 8b6a057..55429d9 100644
--- a/bundles/org.eclipse.equinox.ds.tests/build.properties
+++ b/bundles/org.eclipse.equinox.ds.tests/build.properties
@@ -39,6 +39,7 @@ bin.includes = META-INF/,\
scr_test/tb23.jar,\
scr_test/tb24.jar,\
scr_test/tb25.jar,\
+ scr_test/tb26.jar,\
test.xml
jars.compile.order = .,\
scr_test/tb1.jar,\
@@ -67,7 +68,8 @@ jars.compile.order = .,\
scr_test/tb22.jar,\
scr_test/tb23.jar,\
scr_test/tb24.jar,\
- scr_test/tb25.jar
+ scr_test/tb25.jar,\
+ scr_test/tb26.jar
source.scr_test/tb1.jar = bundles_src/tb1/
manifest.scr_test/tb1.jar = META-INF/MANIFEST.MF
source.scr_test/tb1a.jar = bundles_src/tb1a/
@@ -122,3 +124,5 @@ source.scr_test/tb24.jar = bundles_src/tb24/
manifest.scr_test/tb24.jar = META-INF/MANIFEST.MF
source.scr_test/tb25.jar = bundles_src/tb25/
manifest.scr_test/tb25.jar = META-INF/MANIFEST.MF
+source.scr_test/tb26.jar = bundles_src/tb26/
+manifest.scr_test/tb26.jar = META-INF/MANIFEST.MF
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..7c62d09
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: org.eclipse.equinox.ds.tests.tb26
+Service-Component: OSGI-INF/*.xml
+Export-Package: org.eclipse.equinox.ds.tests.tb26
+Import-Package: org.osgi.service.component,
+ org.osgi.framework,
+ org.eclipse.osgi.service.urlconversion,
+ org.osgi.util.tracker \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml
new file mode 100755
index 0000000..fc8ec08
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <scr:component
+ name="org.eclipse.equinox.ds.tests.tb26.Component1"
+ enabled="true"
+ immediate="true"
+ xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+ <implementation class="org.eclipse.equinox.ds.tests.tb26.impl.Component1"/>
+ <service>
+ <provide interface="org.eclipse.equinox.ds.tests.tb26.Component"/>
+ </service>
+ </scr:component>
+</root>
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java
new file mode 100755
index 0000000..3a33eaa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java
@@ -0,0 +1,107 @@
+package org.eclipse.equinox.ds.tests.tb26;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
+import org.eclipse.osgi.service.urlconversion.URLConverter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.util.tracker.ServiceTracker;
+
+public abstract class Component {
+ protected ComponentContext context;
+ protected ServiceTracker<URLConverter, URLConverter> tracker;
+
+ public abstract String getName();
+
+ public abstract void update() throws Exception;
+
+ protected void activate(ComponentContext context) throws InvalidSyntaxException {
+ this.context = context;
+ BundleContext bc = context.getBundleContext();
+ Filter f = bc.createFilter("(&(objectClass=" + URLConverter.class.getName() + ")(protocol=bundleentry))");
+ tracker = new ServiceTracker<URLConverter, URLConverter>(bc, f, null);
+ tracker.open();
+ }
+
+ protected void deactivate(ComponentContext context) {
+ tracker.close();
+ }
+
+ protected void replaceCurrentComponentXmlWith(String componentXmlFileName) throws Exception {
+ writeResource("component.xml", readResource(componentXmlFileName));
+ }
+
+ private void closeSilently(Closeable closeable) {
+ try {
+ closeable.close();
+ }
+ catch (IOException e) {}
+ }
+
+ private URL getResource(String name) {
+ Bundle b = context.getBundleContext().getBundle();
+ URL result = b.getResource(name);
+ if (result == null)
+ result = b.findEntries("/", name, true).nextElement();
+ return result;
+ }
+
+ private File getResourceAsFile(String name) throws Exception {
+ return new File(getResourceAsUri(name));
+ }
+
+ private FileInputStream getResourceAsFileInputStream(String name) throws Exception {
+ return new FileInputStream(getResourceAsFile(name));
+ }
+
+ private FileOutputStream getResourceAsFileOutputStream(String name) throws Exception {
+ return new FileOutputStream(getResourceAsFile(name));
+ }
+
+ private URI getResourceAsUri(String name) throws Exception {
+ URL url = getResource(name);
+ URLConverter converter = tracker.getService();
+ url = converter.toFileURL(url);
+ return url.toURI();
+ }
+
+ private byte[] readResource(String name) throws Exception {
+ FileInputStream fis = getResourceAsFileInputStream(name);
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ byte[] bytes = new byte[1024];
+ int read;
+ while((read = fis.read(bytes)) != -1)
+ baos.write(bytes, 0, read);
+ return baos.toByteArray();
+ }
+ finally {
+ closeSilently(baos);
+ }
+ }
+ finally {
+ closeSilently(fis);
+ }
+ }
+
+ private void writeResource(String name, byte[] content) throws Exception {
+ FileOutputStream fos = getResourceAsFileOutputStream(name);
+ try {
+ fos.write(content);
+ }
+ finally {
+ closeSilently(fos);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java
new file mode 100755
index 0000000..80984e3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java
@@ -0,0 +1,13 @@
+package org.eclipse.equinox.ds.tests.tb26.impl;
+
+import org.eclipse.equinox.ds.tests.tb26.Component;
+
+public class Component1 extends Component {
+ public String getName() {
+ return getClass().getName();
+ }
+
+ public void update() throws Exception {
+ replaceCurrentComponentXmlWith("component2.xml");
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java
new file mode 100755
index 0000000..f558d4e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java
@@ -0,0 +1,13 @@
+package org.eclipse.equinox.ds.tests.tb26.impl;
+
+import org.eclipse.equinox.ds.tests.tb26.Component;
+
+public class Component2 extends Component {
+ public String getName() {
+ return getClass().getName();
+ }
+
+ public void update() throws Exception {
+ replaceCurrentComponentXmlWith("component1.xml");
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml
new file mode 100755
index 0000000..fc8ec08
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <scr:component
+ name="org.eclipse.equinox.ds.tests.tb26.Component1"
+ enabled="true"
+ immediate="true"
+ xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+ <implementation class="org.eclipse.equinox.ds.tests.tb26.impl.Component1"/>
+ <service>
+ <provide interface="org.eclipse.equinox.ds.tests.tb26.Component"/>
+ </service>
+ </scr:component>
+</root>
diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml
new file mode 100755
index 0000000..5d2fc1f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <scr:component
+ name="org.eclipse.equinox.ds.tests.tb26.Component2"
+ enabled="true"
+ immediate="true"
+ xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+ <implementation class="org.eclipse.equinox.ds.tests.tb26.impl.Component2"/>
+ <service>
+ <provide interface="org.eclipse.equinox.ds.tests.tb26.Component"/>
+ </service>
+ </scr:component>
+</root>
diff --git a/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java b/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java
index f68b48d..819f0e7 100644
--- a/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java
+++ b/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java
@@ -11,13 +11,18 @@
*******************************************************************************/
package org.eclipse.equinox.ds.tests.tbc;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
import junit.framework.TestCase;
@@ -2935,6 +2940,69 @@ public class DSTest extends TestCase {
Bundle b = installer.installBundle(bundle);
return b;
}
+
+ private Bundle installBundleAsDirectory(String bundle) throws Exception {
+ BundleContext context = getContext();
+ String location = installer.getBundleLocation(bundle);
+ String reference = "reference:";
+ if (location.startsWith(reference))
+ // Remove the "reference" protocol from the URL.
+ // (1) So that when running from a workspace, the test will modify a
+ // copy of the component.xml.
+ // (2) When running from a server, to get a readable input stream when
+ // extracting the JAR into a directory.
+ location = location.substring(location.indexOf(':') + 1);
+ if (!location.endsWith(".jar"))
+ // If the bundle is already a directory, go ahead and install it in
+ // the typical fashion. Leave the "reference" protocol out.
+ return context.installBundle(location);
+ // The bundle is a JAR file and needs to be extracted and copied as a
+ // directory to the data storage area of the test harness bundle.
+ File file = context.getBundle().getDataFile(bundle);
+ ZipInputStream in = new ZipInputStream(new URL(location).openStream());
+ try {
+ for (ZipEntry ze = in.getNextEntry(); ze != null; ze = in.getNextEntry()) {
+ String name = ze.getName();
+ // Is the entry a directory?
+ if (ze.isDirectory())
+ // If so, continue to the next entry. Directories will be
+ // created later.
+ continue;
+ // If not, the contents of the file must be copied.
+ File destination;
+ // Does the file entry contain a directory?
+ int index = name.lastIndexOf('/');
+ if (index == -1)
+ // If not, just create the destination file.
+ destination = new File(file, name);
+ else {
+ // If so, make sure the directory exists.
+ File dir = new File(file, name.substring(0, index));
+ dir.mkdirs();
+ // Then create the destination file.
+ destination = new File(dir, name.substring(index));
+ }
+ // Now copy the contents of the file entry to the destination.
+ byte[] bytes = new byte[1024];
+ int read;
+ FileOutputStream out = new FileOutputStream(destination);
+ try {
+ while ((read = in.read(bytes)) != -1)
+ out.write(bytes, 0, read);
+ }
+ finally {
+ out.close();
+ }
+ in.closeEntry();
+ }
+ }
+ finally {
+ in.close();
+ }
+ // Add the "reference" protocol back when running from a server so the
+ // framework sees the modified component.xml in the bundle data storage.
+ return context.installBundle(reference + file.toURI());
+ }
private void uninstallBundle(Bundle bundle) throws BundleException {
installer.uninstallBundle(bundle);
@@ -2998,5 +3066,50 @@ public class DSTest extends TestCase {
sleep0(2 * timeout);
}
}
-
+
+ /*
+ * This test requires the bundle to be installed as a directory using a
+ * reference URL. Otherwise, necessary file updates will not occur, and the
+ * test will no longer be valid.
+ */
+ public void testComponentDefinitionReloadedOnBundleUpdateInDevModeWhenUsingWildcardInServiceComponentHeader() throws Exception {
+ // Enable component caching in DS.
+ System.setProperty("equinox.ds.dbstore", Boolean.TRUE.toString());
+ // Set dev mode.
+ System.setProperty("osgi.checkConfiguration", Boolean.TRUE.toString());
+
+ String serviceName = "org.eclipse.equinox.ds.tests.tb26.Component";
+ // component.xml = conmponent1.xml initially.
+ Bundle b = installBundleAsDirectory("tb26");
+ try {
+ b.start();
+ waitBundleStart();
+
+ // The component service should be Component1.
+ BundleContext context = getContext();
+ ServiceReference<?> ref = context.getServiceReference(serviceName);
+ assertNotNull(ref);
+ Object service = context.getService(ref);
+ Class clazz = service.getClass();
+ assertEquals("org.eclipse.equinox.ds.tests.tb26.impl.Component1", clazz.getName());
+
+ // Update component.xml with component2.xml.
+ clazz.getMethod("update", (Class[])null).invoke(service, (Object[])null);
+
+ // Force a component update in DS.
+ b.stop();
+ b.start();
+ waitBundleStart();
+
+ // The component service should now be Component2.
+ ref = context.getServiceReference(serviceName);
+ assertNotNull(ref);
+ service = context.getService(ref);
+ clazz = service.getClass();
+ assertEquals("org.eclipse.equinox.ds.tests.tb26.impl.Component2", clazz.getName());
+ }
+ finally {
+ uninstallBundle(b);
+ }
+ }
}