Browse files

Fixed issue in capability validation when both the capability and req…

…uirement resources are not in the installing

subsystem's region. Also added new test.

git-svn-id: https://svn.apache.org/repos/asf/aries/trunk@1419805 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent 6740c72 commit bfcd1909e0ffa221b53dcb549766149c3effe3a3 John Ross committed Dec 10, 2012
View
26 ...system-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
@@ -279,7 +279,7 @@ private boolean addDependencies(Repository repository, Requirement requirement,
if (m.containsKey(requirement)) {
Collection<Capability> cc = m.get(requirement);
// TODO The following check only needs to be done on capabilities from the system repository.
- addValidCapabilities(cc, capabilities);
+ addValidCapabilities(cc, capabilities, requirement);
}
return !capabilities.isEmpty();
}
@@ -322,9 +322,9 @@ private void addMissingResource(DeployedContentHeader.Clause resource) {
missingResources.add(resource);
}
- private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
+ private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to, Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
for (Capability c : from)
- if (isValid(c))
+ if (isValid(c, requirement))
to.add(c);
}
@@ -665,30 +665,32 @@ private boolean isUnscoped() {
return !isScoped();
}
- private boolean isValid(Capability capability) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
+ private boolean isValid(Capability capability, Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
if (IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getNamespace()))
return true;
- Resource resource = capability.getResource();
- Region region;
+ Region from = findRegionForCapabilityValidation(capability.getResource());
+ Region to = findRegionForCapabilityValidation(requirement.getResource());
+ return new SharingPolicyValidator(from, to).isValid(capability);
+ }
+
+ private Region findRegionForCapabilityValidation(Resource resource) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
if (isInstallable(resource)) {
if (isContent(resource))
- region = getRegion();
- else
- region = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(parent).getRegion();
+ return getRegion();
+ return Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(parent).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());
+ return 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 Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource).iterator().next().getRegion();
}
- return new SharingPolicyValidator(region, getRegion()).isValid(capability);
}
private void setImportIsolationPolicy() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
View
154 ...stem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ResolutionTest.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.subsystem.itests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.MavenConfiguredJUnit4TestRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.service.subsystem.SubsystemException;
+
+/*
+ * Contains a series of tests related to resolution.
+ */
+@RunWith(MavenConfiguredJUnit4TestRunner.class)
+public class ResolutionTest extends SubsystemTest {
+ /*
+ * Subsystem-SymbolicName: application.a.esa
+ * Subsystem-Content: bundle.a.jar
+ */
+ private static final String APPLICATION_A = "application.a.esa";
+ /*
+ * Bundle-SymbolicName: bundle.a.jar
+ * Require-Capability: a
+ */
+ private static final String BUNDLE_A = "bundle.a.jar";
+ /*
+ * Bundle-SymbolicName: bundle.b.jar
+ * Provide-Capability: a
+ * Require-Capability: b
+ */
+ private static final String BUNDLE_B = "bundle.b.jar";
+ /*
+ * Bundle-SymbolicName: bundle.c.jar
+ * Provide-Capability: b
+ */
+ private static final String BUNDLE_C = "bundle.c.jar";
+
+ @Before
+ public static void createApplications() throws Exception {
+ if (createdApplications) {
+ return;
+ };
+ createBundleA();
+ createBundleB();
+ createBundleC();
+ createApplicationA();
+ createdApplications = 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 {
+ Map<String, String> headers = new HashMap<String, String>();
+ headers.put(Constants.REQUIRE_CAPABILITY, "a");
+ createBundle(BUNDLE_A, headers);
+ }
+
+ private static void createBundleB() throws IOException {
+ Map<String, String> headers = new HashMap<String, String>();
+ headers.put(Constants.PROVIDE_CAPABILITY, "a");
+ headers.put(Constants.REQUIRE_CAPABILITY, "b");
+ createBundle(BUNDLE_B, headers);
+ }
+
+ private static void createBundleC() throws IOException {
+ Map<String, String> headers = new HashMap<String, String>();
+ headers.put(Constants.PROVIDE_CAPABILITY, "b");
+ createBundle(BUNDLE_C, headers);
+ }
+
+ /*
+ * Test that the right regions are used when validating capabilities.
+ *
+ * Application A contains a content bundle requiring capability A. Bundle B
+ * provides capability A and is available as an installable resource from a
+ * repository service. Bundle B also requires capability B. Bundle C is an
+ * already installed resource in the root subsystem providing capability B.
+ * When validating capability A, the subsystem should use the root region as
+ * the from region, and its own region as the to region. When validating
+ * capability B, the subsystem should use the root region as the from region
+ * as well as for the to region.
+ */
+ @Test
+ public void testContentWithNonConstituentDependencyWithNonConstituentDependency() throws Exception {
+ // Register a repository service containing bundle B requiring
+ // capability B and providing capability A.
+ registerRepositoryService(BUNDLE_B);
+ Subsystem root = getRootSubsystem();
+ // Install unmanaged bundle C providing capability B as a constituent
+ // of the root subsystem.
+ Bundle bundleC = installBundleFromFile(BUNDLE_C, root);
+ try {
+ // Install application A with content bundle A requiring
+ // capability A.
+ Subsystem applicationA = installSubsystemFromFile(APPLICATION_A);
+ // Make sure the Require-Capability exists for capability a...
+ assertHeaderExists(applicationA, Constants.REQUIRE_CAPABILITY);
+ // ...but not for capability b.
+ assertEquals("Wrong Require-Capability header", "a;resolution:=mandatory;effective:=resolve", applicationA.getSubsystemHeaders(null).get(Constants.REQUIRE_CAPABILITY));
+ try {
+ // Make sure the runtime resolution works as well.
+ applicationA.start();
+ }
+ catch (SubsystemException e) {
+ fail("Application A should have started");
+ }
+ finally {
+ stopAndUninstallSubsystemSilently(applicationA);
+ }
+ }
+ catch (SubsystemException e) {
+ fail("Application A should have installed");
+ }
+ finally {
+ uninstallSilently(bundleC);
+ }
+ }
+}

0 comments on commit bfcd190

Please sign in to comment.