You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2012/10/23 21:15:55 UTC

svn commit: r1401402 - in /aries/trunk/subsystem: subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/

Author: jwross
Date: Tue Oct 23 19:15:54 2012
New Revision: 1401402

URL: http://svn.apache.org/viewvc?rev=1401402&view=rev
Log:
Updates for preexisting regions.

The root region constant has been removed since the root region is now determined by the region in which the subsystem.core bundle
was installed.

Root subsystem initialization and capability validation now take preexisting regions into account.

New test to insure resources within preexisting regions can be capability providers if the sharing policy allows.

The specification takes the point of view that subsystems is the only isolation engine existing in the framework. These changes
provide leniency for the Virgo use case where there are two preexisting regions, kernel and user, and subsystems is installed into
the user region. Although the changes were made in the spirit of generality, no attempt was made to introduce a compatibility
mechanism for multiple isolation engines in the same framework. However, it might make sense to direct some future work towards
providing a more robust compability with extraneous Region Digraph regions, since this is the isolation engine used by the
implementation. For example, a "regions as subsystems" approach could be taken where a subsystem is created for each preexisting
region. This could be problematic and potentially complex, however, since the subsystem graph can only handle a subset of
graphs that are possible when using Digraph directly.

One other thing to note about these changes is that they implement the spec wording literally, which states that any bundles
installed out of band (i.e. outside of the subsystems API) become constituents of the root subsystem. This means that all
bundles that are part of preexisting regions will become constituents of the root subsystem, even if they are not actually in
the root subsystem region. This results in a potential disparity between the bundles returned by getConstituents() and
getBundleContext().getBundles(). We may wish to address this disparity at both the specification and implementation level in
the future.

Modified:
    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/RawSubsystemResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.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/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=1401402&r1=1401401&r2=1401402&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 Tue Oct 23 19:15:54 2012
@@ -55,7 +55,6 @@ import org.osgi.service.subsystem.Subsys
 import org.osgi.service.subsystem.SubsystemException;
 
 public class AriesSubsystem implements Resource, Subsystem {
-	public static final String ROOT_REGION = "org.eclipse.equinox.region.kernel";
 	public static final String ROOT_SYMBOLIC_NAME = "org.osgi.service.subsystem.root";
 	public static final Version ROOT_VERSION = Version.parseVersion("1.0.0");
 	public static final String ROOT_LOCATION = "subsystem://?"

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java?rev=1401402&r1=1401401&r2=1401402&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java Tue Oct 23 19:15:54 2012
@@ -398,7 +398,7 @@ public class RawSubsystemResource implem
 					.manifest(getSubsystemManifest())
 					.location(AriesSubsystem.ROOT_LOCATION).autostart(true).id(0)
 					.lastId(SubsystemIdentifier.getLastId())
-					.region(AriesSubsystem.ROOT_REGION).state(State.INSTALLING)
+					.state(State.INSTALLING)
 					.build();
 	}
 	

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=1401402&r1=1401401&r2=1401402&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 Tue Oct 23 19:15:54 2012
@@ -42,6 +42,7 @@ import org.apache.aries.subsystem.core.a
 import org.apache.aries.subsystem.core.archive.SubsystemImportServiceHeader;
 import org.apache.aries.subsystem.core.archive.SubsystemImportServiceRequirement;
 import org.apache.aries.subsystem.core.archive.SubsystemManifest;
+import org.apache.aries.subsystem.core.internal.BundleResourceInstaller.BundleConstituent;
 import org.apache.aries.util.filesystem.FileSystem;
 import org.apache.aries.util.filesystem.IDirectory;
 import org.apache.aries.util.manifest.ManifestHeaderProcessor;
@@ -57,6 +58,7 @@ import org.osgi.framework.ServiceReferen
 import org.osgi.framework.hooks.weaving.WeavingHook;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
@@ -346,10 +348,11 @@ public class SubsystemResource implement
 	
 	private void addSubsystemServiceImportToSharingPolicy(RegionFilterBuilder builder, Region to)
 			throws InvalidSyntaxException, BundleException, IOException, URISyntaxException {
-		if (to.getName().equals(AriesSubsystem.ROOT_REGION))
+		Region root = Activator.getInstance().getSubsystems().getRootSubsystem().getRegion();
+		if (to.getName().equals(root.getName()))
 			addSubsystemServiceImportToSharingPolicy(builder);
 		else {
-			to = Activator.getInstance().getSubsystems().getRootSubsystem().getRegion();
+			to = root;
 			builder = to.getRegionDigraph().createRegionFilterBuilder();
 			addSubsystemServiceImportToSharingPolicy(builder);
 			RegionFilter regionFilter = builder.build();
@@ -480,13 +483,21 @@ public class SubsystemResource implement
 				Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>();
 				for (AriesSubsystem subsystem : Activator.getInstance().getSubsystems().getSubsystems())
 					for (Resource constituent : subsystem.getConstituents())
-						if (constituent instanceof BundleRevision) {
-							BundleRevision revision = (BundleRevision)constituent;
-							wirings.put(revision, revision.getWiring());
-						}
+						addWiring(constituent, wirings);
 				return Collections.unmodifiableMap(wirings);
 			}
 			
+			private void addWiring(Resource resource, Map<Resource, Wiring> wirings) {
+				if (resource instanceof BundleConstituent) {
+					BundleConstituent bc = (BundleConstituent)resource;
+					wirings.put(bc.getBundle().adapt(BundleRevision.class), bc.getWiring());
+				}
+				else if (resource instanceof BundleRevision) {
+					BundleRevision br = (BundleRevision)resource;
+					wirings.put(br, br.getWiring());
+				}
+			}
+			
 			@Override
 			public List<Capability> findProviders(Requirement requirement) {
 				List<Capability> result = new ArrayList<Capability>();
@@ -662,15 +673,26 @@ public class SubsystemResource implement
 	private boolean isValid(Capability capability) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getNamespace()))
 			return true;
+		Resource resource = capability.getResource();
 		Region region;
-		if (isInstallable(capability.getResource())) {
-			if (isContent(capability.getResource()))
+		if (isInstallable(resource)) {
+			if (isContent(resource))
 				region = getRegion();
 			else
 				region = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(parent).getRegion();
 		}
-		else
-			region = Activator.getInstance().getSubsystems().getSubsystemsReferencing(capability.getResource()).iterator().next().getRegion();
+		else {
+			// This is an already installed resource from the system repository.
+			if (Utils.isBundle(resource))
+				// If it's a bundle, use region digraph to get the region in order
+				// to account for bundles in isolated regions outside of the
+				// subsystems API.
+				region = Activator.getInstance().getRegionDigraph().getRegion(((BundleRevision)resource).getBundle());
+			else
+				// If it's anything else, get the region from one of the
+				// subsystems referencing it.
+				region = Activator.getInstance().getSubsystems().getSubsystemsReferencing(capability.getResource()).iterator().next().getRegion();
+		}
 		return new SharingPolicyValidator(region, getRegion()).isValid(capability);
 	}
 	

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java?rev=1401402&r1=1401401&r2=1401402&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java Tue Oct 23 19:15:54 2012
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.resource.Resource;
@@ -131,11 +132,9 @@ public class Subsystems {
 					// that already existed in its region. Not sure this will be the final resting place. Plus, there are issues
 					// since this does not take into account the possibility of already existing bundles going away or new bundles
 					// being installed out of band while this initialization is taking place. Need a bundle event hook for that.
-					BundleContext context = Activator.getInstance().getBundleContext().getBundle(0).getBundleContext();
-					for (long id : root.getRegion().getBundleIds()) {
-						BundleRevision br = context.getBundle(id).adapt(BundleRevision.class);
-						ResourceInstaller.newInstance(coordination, br, root).install();
-					}
+					BundleContext context = Activator.getInstance().getBundleContext().getBundle(org.osgi.framework.Constants.SYSTEM_BUNDLE_LOCATION).getBundleContext();
+					for (Bundle b : context.getBundles())
+						ResourceInstaller.newInstance(coordination, b.adapt(BundleRevision.class), root).install();
 					// TODO End proof of concept.
 				} catch (Exception e) {
 					coordination.fail(e);

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=1401402&r1=1401401&r2=1401402&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 Tue Oct 23 19:15:54 2012
@@ -18,6 +18,8 @@ import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.eclipse.equinox.region.Region;
 import org.eclipse.equinox.region.RegionDigraph;
@@ -28,13 +30,24 @@ import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.MavenConfiguredJUnit4TestRunner;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.Version;
 import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
 
 @RunWith(MavenConfiguredJUnit4TestRunner.class)
 public class RootSubsystemTest extends SubsystemTest {
-	private static final String BUNDLE_A = "bundle.a";
+	/*
+	 * Subsystem-SymbolicName: application.a.esa
+	 * Subsystem-Content: bundle.a.jar
+	 */
+	private static final String APPLICATION_A = "application.a.esa";
+	/*
+	 * Bundle-SymbolicName: bundle.a.jar
+	 * Import-Package: org.osgi.framework
+	 */
+	private static final String BUNDLE_A = "bundle.a.jar";
 	
 	private static boolean createdTestFiles;
 	@Before
@@ -42,11 +55,25 @@ public class RootSubsystemTest extends S
 		if (createdTestFiles)
 			return;
 		createBundleA();
+		createApplicationA();
 		createdTestFiles = true;
 	}
 	
+	private static void createApplicationA() throws IOException {
+		createApplicationAManifest();
+		createSubsystem(APPLICATION_A, BUNDLE_A);
+	}
+	
+	private static void createApplicationAManifest() throws IOException {
+		Map<String, String> attributes = new HashMap<String, String>();
+		attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, APPLICATION_A);
+		createManifest(APPLICATION_A + ".mf", attributes);
+	}
+	
 	private static void createBundleA() throws IOException {
-		createBundle(BUNDLE_A);
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+		createBundle(BUNDLE_A, headers);
 	}
 	
 	// TODO Test root subsystem headers.
@@ -183,5 +210,17 @@ public class RootSubsystemTest extends S
 		region = digraph.getRegion(root.getBundleContext().getBundle());
 		// The root subsystem should now be in the new region.
 		assertEquals("Wrong region", user, region);
+		// Extra test. Install application A into the root region (user) and 
+		// make sure it resolves. Although the system bundle is in the kernel 
+		// region and not a constituent of the root subsystem, the capability 
+		// should still be found and used.
+		try {
+			Subsystem applicationA = installSubsystemFromFile(root, APPLICATION_A);
+			uninstallSubsystemSilently(applicationA);
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+			fail("Subsystem should have installed");
+		}
 	}
 }