You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2017/02/16 10:43:39 UTC
svn commit: r1783196 - in /sling/trunk/installer:
core/src/main/java/org/apache/sling/installer/core/impl/
it/src/test/java/org/apache/sling/installer/it/
Author: kwin
Date: Thu Feb 16 10:43:39 2017
New Revision: 1783196
URL: http://svn.apache.org/viewvc?rev=1783196&view=rev
Log:
SLING-6392 support entity id changes for the same url (by uninstalling stale resources)
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/BundleInstallUpgradeDowngradeTest.java
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/MockInstallableResource.java
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java?rev=1783196&r1=1783195&r2=1783196&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java Thu Feb 16 10:43:39 2017
@@ -31,6 +31,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -224,8 +225,20 @@ public class PersistentResourceList {
t = new EntityResourceList(input.getEntityId(), this.listener);
this.data.put(input.getEntityId(), t);
}
-
t.addOrUpdate(input);
+
+ // find stale resources (other entity ids with the same URL)
+ Collection<RegisteredResource> staleResources = getResourcesWithUrl(input.getURL(), input.getEntityId());
+ for (RegisteredResource staleResource : staleResources) {
+ // get according group
+ EntityResourceList group = this.data.get(staleResource.getEntityId());
+ if (group == null) {
+ logger.error("Could not get group of stale resource {}", staleResource);
+ } else {
+ group.remove(input.getURL());
+ logger.warn("Removing stale resource {}, overwritten by {}", staleResource, input);
+ }
+ }
} else {
// check if there is an old resource and remove it first
if ( this.untransformedResources.contains(input) ) {
@@ -241,6 +254,7 @@ public class PersistentResourceList {
public List<RegisteredResource> getUntransformedResources() {
return this.untransformedResources;
}
+
/**
* Remove a resource by url.
@@ -283,6 +297,27 @@ public class PersistentResourceList {
}
/**
+ *
+ * @param url the url of the resource to look for
+ * @param entityIdToSkip all resources having this entity id should in no case be returned
+ * @return the list of all registered resources with the given url, not having the entityId which should be skipped.
+ */
+ private Collection<RegisteredResource> getResourcesWithUrl(String url, String entityIdToSkip) {
+ Collection<RegisteredResource> foundResources = new LinkedList<>();
+ for(final EntityResourceList group : this.data.values()) {
+ if (group.getResourceId().equals(entityIdToSkip)) {
+ continue;
+ }
+ for (RegisteredResource resource : group.listResources()) {
+ if (resource.getURL().equals(url)) {
+ foundResources.add(resource);
+ }
+ }
+ }
+ return foundResources;
+ }
+
+ /**
* Compact the internal state and remove empty groups.
* @return <code>true</code> if another cycle should be started.
*/
Modified: sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/BundleInstallUpgradeDowngradeTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/BundleInstallUpgradeDowngradeTest.java?rev=1783196&r1=1783195&r2=1783196&view=diff
==============================================================================
--- sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/BundleInstallUpgradeDowngradeTest.java (original)
+++ sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/BundleInstallUpgradeDowngradeTest.java Thu Feb 16 10:43:39 2017
@@ -19,6 +19,8 @@ package org.apache.sling.installer.it;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.it.OsgiInstallerTestBase.BundleEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -207,4 +209,44 @@ public class BundleInstallUpgradeDowngra
}
}
+
+ /**
+ * This test class assures that whenever a new bundle is
+ * provided with the same url as an already installed bundle,
+ * the already installed bundle is uninstalled and the new one installed.
+ * @see <a href="https://issues.apache.org/jira/browse/SLING-6392">SLING-6392</a>
+ */
+ @Test
+ public void testReplaceBundleWithSameUrlButDifferentSymbolicName() throws Exception {
+ final String symbolicName = "osgi-installer-testbundle";
+ final String symbolicName2 = "osgi-installer-testA";
+ final String installableResourceId = "stable-id";
+
+ assertNull("Test bundle must not be present before test", findBundle(symbolicName));
+ assertNull("Test A bundle must not be present before test", findBundle(symbolicName2));
+ {
+ //assertNull("Test bundle must be absent before installing", findBundle(symbolicName));
+ final Object listener = this.startObservingBundleEvents();
+ installer.updateResources(URL_SCHEME, getInstallableResource(
+ getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.0.jar"), installableResourceId, "1", InstallableResource.DEFAULT_PRIORITY), null);
+ this.waitForBundleEvents(symbolicName + " must be installed", listener,
+ new BundleEvent(symbolicName, "1.0", org.osgi.framework.BundleEvent.INSTALLED),
+ new BundleEvent(symbolicName, "1.0", org.osgi.framework.BundleEvent.STARTED));
+ assertBundle("After installing", symbolicName, "1.0", Bundle.ACTIVE);
+ }
+
+ // now modify the bundle (having the same url but a different symbolic name and different digest)
+ {
+ final Object listener = this.startObservingBundleEvents();
+ installer.updateResources(URL_SCHEME, getInstallableResource(
+ getTestBundle(BUNDLE_BASE_NAME + "-testA-1.0.jar"), installableResourceId, "2", InstallableResource.DEFAULT_PRIORITY), null);
+ this.waitForBundleEvents(symbolicName2 + " must be installed and " + symbolicName + " uninstalled", listener,
+ new BundleEvent(symbolicName, "1.0", org.osgi.framework.BundleEvent.STOPPED),
+ new BundleEvent(symbolicName, "1.0", org.osgi.framework.BundleEvent.UNINSTALLED),
+ new BundleEvent(symbolicName2, "1.0", org.osgi.framework.BundleEvent.INSTALLED),
+ new BundleEvent(symbolicName2, "1.0", org.osgi.framework.BundleEvent.STARTED));
+ assertBundle("After installing a different bundle with same id " + installableResourceId, symbolicName2, "1.0", Bundle.ACTIVE);
+ assertNull("Test bundle must not be present after removing it", findBundle(symbolicName));
+ }
+ }
}
\ No newline at end of file
Modified: sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/MockInstallableResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/MockInstallableResource.java?rev=1783196&r1=1783195&r2=1783196&view=diff
==============================================================================
--- sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/MockInstallableResource.java (original)
+++ sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/MockInstallableResource.java Thu Feb 16 10:43:39 2017
@@ -45,8 +45,8 @@ public class MockInstallableResource ext
InstallableResource.TYPE_BUNDLE, null);
}
- public MockInstallableResource(String uri, InputStream is, String digest, String type, Integer priority) {
- super(uri, is,
+ public MockInstallableResource(String id, InputStream is, String digest, String type, Integer priority) {
+ super(id, is,
null, digest,
type != null ? type : InstallableResource.TYPE_BUNDLE, priority);
}
Modified: sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java?rev=1783196&r1=1783195&r2=1783196&view=diff
==============================================================================
--- sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java (original)
+++ sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java Thu Feb 16 10:43:39 2017
@@ -408,14 +408,17 @@ public class OsgiInstallerTestBase imple
}
protected InstallableResource[] getInstallableResource(File testBundle, String digest, int priority) throws IOException {
- final String url = testBundle.getAbsolutePath();
+ return getInstallableResource(testBundle, testBundle.getAbsolutePath(), digest, priority);
+ }
+
+ protected InstallableResource[] getInstallableResource(File testBundle, String id, String digest, int priority) throws IOException {
if (digest == null) {
digest = String.valueOf(testBundle.lastModified());
}
- final InstallableResource result = new MockInstallableResource(url, new FileInputStream(testBundle), digest, null, priority);
+ final InstallableResource result = new MockInstallableResource(id, new FileInputStream(testBundle), digest, null, priority);
return new InstallableResource[] {result};
}
-
+
protected InstallableResource[] getInstallableResource(String configPid, Dictionary<String, Object> data) {
return getInstallableResource(configPid, copy(data), InstallableResource.DEFAULT_PRIORITY);
}