aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jwr...@apache.org
Subject svn commit: r1382116 - in /aries/trunk/subsystem: subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ subsystem-itests/src/test/java/org/apache/aries/subsystem/ite...
Date Fri, 07 Sep 2012 18:34:15 GMT
Author: jwross
Date: Fri Sep  7 18:34:15 2012
New Revision: 1382116

URL: http://svn.apache.org/viewvc?rev=1382116&view=rev
Log:
ARIES-922: If a bundle is uninstalled from the root region while the bundle event hook is
not registered but remains in persistent memory, root initialization will no longer fail with
an NPE. The missing bundle is simply removed from memory.

A failure will still occur if the same thing happens for a non-root subsystem. I left it that
way for now for fail-fast purposes since it would be very bad for someone to muck around with
the deployed content of a non-root subsystem outside of the subsystems API. It might be reasonable
in the future to make this more intelligent by checking to see if the missing resource is
optional or trying to re-deploy it from a repository.

Also added a new test.

Modified:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeployedContentHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeployedContentHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeployedContentHeader.java?rev=1382116&r1=1382115&r2=1382116&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeployedContentHeader.java
(original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeployedContentHeader.java
Fri Sep  7 18:34:15 2012
@@ -85,6 +85,27 @@ public class DeployedContentHeader imple
 		}
 		
 		@Override
+		public boolean equals(Object o) {
+			if (o == this)
+				return true;
+			if (!(o instanceof Clause))
+				return false;
+			Clause that = (Clause)o;
+			return getSymbolicName().equals(that.getSymbolicName())
+					&& getDeployedVersion().equals(that.getDeployedVersion())
+					&& getType().equals(that.getType());
+		}
+		
+		@Override
+		public int hashCode() {
+			int result = 17;
+			result = 31 * result + getSymbolicName().hashCode();
+			result = 31 * result + getDeployedVersion().hashCode();
+			result = 31 * result + getType().hashCode();
+			return result;
+		}
+		
+		@Override
 		public Attribute getAttribute(String name) {
 			Parameter result = parameters.get(name);
 			if (result instanceof Attribute)

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java?rev=1382116&r1=1382115&r2=1382116&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
(original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
Fri Sep  7 18:34:15 2012
@@ -358,6 +358,20 @@ public class AriesSubsystem implements R
 			catch (Exception e) {
 				throw new SubsystemException(e);
 			}
+			Collection<DeployedContentHeader.Clause> missingResources = resource.getMissingResources();
+			if (!missingResources.isEmpty()) {
+				if (isRoot())
+					// We don't care if the root subsystem has missing resources
+					// because they are either (1) extraneous bundles outside of
+					// the subsystems API or (2) provisioned dependencies of
+					// other subsystems. Those that fall in the latter category
+					// will be detected by the dependent subsystems.
+					removedContent(missingResources);
+				else
+					// If a non-root subsystem has missing dependencies, let's
+					// fail fast for now.
+					throw new SubsystemException("Missing resources: " + missingResources);
+			}
 		}
 		return resource;
 	}
@@ -427,9 +441,17 @@ public class AriesSubsystem implements R
 		DeployedContentHeader.Clause clause = header.getClause(resource);
 		if (clause == null)
 			return;
+		removedContent(Collections.singleton(clause));
+	}
+	
+	void removedContent(Collection<DeployedContentHeader.Clause> content) {
+		DeploymentManifest manifest = getDeploymentManifest();
+		DeployedContentHeader header = manifest.getDeployedContentHeader();
+		if (header == null)
+			return;
 		Collection<DeployedContentHeader.Clause> clauses = new ArrayList<DeployedContentHeader.Clause>(header.getClauses());
 		for (Iterator<DeployedContentHeader.Clause> i = clauses.iterator(); i.hasNext();)
-			if (clause.equals(i.next())) {
+			if (content.contains(i.next())) {
 				i.remove();
 				break;
 			}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java?rev=1382116&r1=1382115&r2=1382116&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
(original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
Fri Sep  7 18:34:15 2012
@@ -46,6 +46,7 @@ import org.eclipse.equinox.region.Region
 import org.eclipse.equinox.region.RegionDigraph;
 import org.eclipse.equinox.region.RegionFilter;
 import org.eclipse.equinox.region.RegionFilterBuilder;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.InvalidSyntaxException;
@@ -76,6 +77,7 @@ public class SubsystemResource implement
 	private final Collection<Resource> installableContent = new HashSet<Resource>();
 	private final Collection<Resource> installableDependencies = new HashSet<Resource>();
 	private final Collection<Resource> mandatoryResources = new HashSet<Resource>();
+	private final Collection<DeployedContentHeader.Clause> missingResources = new HashSet<DeployedContentHeader.Clause>();
 	private final Collection<Resource> optionalResources = new HashSet<Resource>();
 	private final AriesSubsystem parent;
 	private final Repository preferredProviderRepository;
@@ -159,6 +161,10 @@ public class SubsystemResource implement
 		return resource.getLocation().getValue();
 	}
 	
+	public Collection<DeployedContentHeader.Clause> getMissingResources() {
+		return missingResources;
+	}
+	
 	public Collection<AriesSubsystem> getParents() {
 		if (parent == null) {
 			Header<?> header = getDeploymentManifest().getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_PARENTS);
@@ -290,6 +296,10 @@ public class SubsystemResource implement
 			sharedDependencies.add(resource);
 	}
 	
+	private void addMissingResource(DeployedContentHeader.Clause resource) {
+		missingResources.add(resource);
+	}
+	
 	private void addValidCapabilities(Collection<Capability> from, Collection<Capability>
to) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		for (Capability c : from)
 			if (isValid(c))
@@ -332,8 +342,9 @@ public class SubsystemResource implement
 			for (DeployedContentHeader.Clause clause : header.getClauses()) {
 				Resource resource = findContent(clause);
 				if (resource == null)
-					throw new SubsystemException("Resource does not exist: " + clause);
-				addContentResource(resource);
+					addMissingResource(clause);
+				else
+					addContentResource(resource);
 			}
 		}
 	}
@@ -531,7 +542,10 @@ public class SubsystemResource implement
 		if (resourceId != -1) {
 			String type = clause.getType();
 			if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type))
{
-				return Activator.getInstance().getBundleContext().getBundle(0).getBundleContext().getBundle(resourceId).adapt(BundleRevision.class);
+				Bundle resource = Activator.getInstance().getBundleContext().getBundle(0).getBundleContext().getBundle(resourceId);
+				if (resource == null)
+					return null;
+				return resource.adapt(BundleRevision.class);
 			}
 			else
 				return Activator.getInstance().getSubsystems().getSubsystemById(resourceId);

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java?rev=1382116&r1=1382115&r2=1382116&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
(original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
Fri Sep  7 18:34:15 2012
@@ -14,6 +14,7 @@
 package org.apache.aries.subsystem.itests;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.IOException;
@@ -103,6 +104,34 @@ public class RootSubsystemTest extends S
 	}
 	
 	@Test
+	public void testUninstallRootRegionBundleWithNoBundleEventHook() throws Exception {
+		// Install an extraneous bundle into the root region. The bundle will
+		// be recorded in the root subsystem's persistent memory.
+		Bundle bundleA = bundleContext.installBundle(new File(BUNDLE_A).toURI().toURL().toString());
+		try {
+			Bundle core = getSubsystemCoreBundle();
+			// Stop the subsystems bundle in order to unregister the bundle
+			// event hook.
+			core.stop();
+			// Uninstall the bundle so it won't be there on restart.
+			bundleA.uninstall();
+			try {
+				// Start the subsystems bundle and ensure the root subsystem
+				// recovers from the uninstalled bundle being in persistent
+				// memory.
+				core.start();
+			}
+			catch (BundleException e) {
+				fail("Could not start subsystems bundle after uninstalling a root region bundle with
no bundle event hook registered");
+			}
+		}
+		finally {
+			if (Bundle.UNINSTALLED != bundleA.getState())
+				bundleA.uninstall();
+		}
+	}
+	
+	@Test
 	public void testVersion() {
 		assertEquals("Wrong root version", getRootSubsystem().getVersion(), Version.parseVersion("1.0.0"));
 	}



Mime
View raw message