You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/07/05 13:21:38 UTC
[sling-whiteboard] branch master updated: Initial implementation of
the whitelist service and resolver hook
This is an automated email from the ASF dual-hosted git repository.
davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
The following commit(s) were added to refs/heads/master by this push:
new 6ef377b Initial implementation of the whitelist service and resolver hook
6ef377b is described below
commit 6ef377b8a6e6794d4a5dfad93ae9c66cb6d3bbf3
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Thu Jul 5 14:20:50 2018 +0100
Initial implementation of the whitelist service and resolver hook
---
featuremodel/feature-whitelist/pom.xml | 7 +-
.../feature/whitelist/impl/ResolverHookImpl.java | 6 +-
.../whitelist/impl/WhitelistServiceImpl.java | 25 +++-
.../whitelist/impl/ResolverHookImplTest.java | 163 +++++++++++++++++++++
4 files changed, 190 insertions(+), 11 deletions(-)
diff --git a/featuremodel/feature-whitelist/pom.xml b/featuremodel/feature-whitelist/pom.xml
index 6e5fc2d..0aa23b9 100644
--- a/featuremodel/feature-whitelist/pom.xml
+++ b/featuremodel/feature-whitelist/pom.xml
@@ -96,6 +96,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
-
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>2.8.9</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/ResolverHookImpl.java b/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/ResolverHookImpl.java
index 4926593..46ce493 100644
--- a/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/ResolverHookImpl.java
+++ b/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/ResolverHookImpl.java
@@ -88,7 +88,7 @@ class ResolverHookImpl implements ResolverHook {
Feature capFeat = fs.getFeatureForBundle(capBundleID);
// Within a single feature everything can wire to everything else
- if (capFeat.equals(reqFeat))
+ if (reqFeat.equals(capFeat))
continue nextCapability;
@@ -96,7 +96,7 @@ class ResolverHookImpl implements ResolverHook {
if (pkg instanceof String) {
String packageName = (String) pkg;
// If the export is in the global region.
- if (whitelistService.regionWhitelistsPackage(WhitelistService.GLOBAL_REGION, packageName))
+ if (Boolean.TRUE.equals(whitelistService.regionWhitelistsPackage(WhitelistService.GLOBAL_REGION, packageName)))
continue nextCapability;
// If the export is in a region that the feature is also in, then allow
@@ -105,7 +105,7 @@ class ResolverHookImpl implements ResolverHook {
if (WhitelistService.GLOBAL_REGION.equals(region))
continue;
- if (whitelistService.regionWhitelistsPackage(region, packageName))
+ if (!Boolean.FALSE.equals(whitelistService.regionWhitelistsPackage(region, packageName)))
continue nextCapability;
}
diff --git a/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/WhitelistServiceImpl.java b/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/WhitelistServiceImpl.java
index 2243f7e..9877c0e 100644
--- a/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/WhitelistServiceImpl.java
+++ b/featuremodel/feature-whitelist/src/main/java/org/apache/sling/feature/whitelist/impl/WhitelistServiceImpl.java
@@ -32,19 +32,30 @@ class WhitelistServiceImpl implements WhitelistService {
WhitelistServiceImpl(Map<String, Set<String>> regionPackages,
Map<String, Set<String>> featureRegions) {
+ Set<String> allRegions = new HashSet<>();
+
+ Map<String, Set<String>> frm = new HashMap<>();
+ for (Map.Entry<String, Set<String>> entry : featureRegions.entrySet()) {
+ Set<String> regions = Collections.unmodifiableSet(new HashSet<>(entry.getValue()));
+ allRegions.addAll(regions);
+ frm.put(entry.getKey(), regions);
+ }
+ featureRegionMapping = Collections.unmodifiableMap(frm);
+
Map<String, Set<String>> rpm = new HashMap<>();
for (Map.Entry<String, Set<String>> entry : regionPackages.entrySet()) {
- rpm.put(entry.getKey(),
+ String region = entry.getKey();
+ rpm.put(region,
Collections.unmodifiableSet(new HashSet<>(entry.getValue())));
+ allRegions.remove(region);
}
- regionPackageMapping = Collections.unmodifiableMap(rpm);
- Map<String, Set<String>> frm = new HashMap<>();
- for (Map.Entry<String, Set<String>> entry : featureRegions.entrySet()) {
- frm.put(entry.getKey(),
- Collections.unmodifiableSet(new HashSet<>(entry.getValue())));
+ // If there are more regions mentioned but these don't have any package
+ // mappings, give them an empty mapping
+ for (String region : allRegions) {
+ rpm.put(region, Collections.emptySet());
}
- featureRegionMapping = Collections.unmodifiableMap(frm);
+ regionPackageMapping = Collections.unmodifiableMap(rpm);
}
@Override
diff --git a/featuremodel/feature-whitelist/src/test/java/org/apache/sling/feature/whitelist/impl/ResolverHookImplTest.java b/featuremodel/feature-whitelist/src/test/java/org/apache/sling/feature/whitelist/impl/ResolverHookImplTest.java
new file mode 100644
index 0000000..fbfbbe0
--- /dev/null
+++ b/featuremodel/feature-whitelist/src/test/java/org/apache/sling/feature/whitelist/impl/ResolverHookImplTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.sling.feature.whitelist.impl;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.service.FeatureService;
+import org.apache.sling.feature.whitelist.WhitelistService;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.util.tracker.ServiceTracker;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+public class ResolverHookImplTest {
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Test
+ public void testFilterMatches() throws Exception {
+ ArtifactId fid = new ArtifactId("gid", "aid", "0.0.9", null, null);
+ Feature f = new Feature(fid);
+
+ ArtifactId fid2 = new ArtifactId("gid2", "aid2", "1.0.0-SNAPSHOT", null, null);
+ Feature f2 = new Feature(fid2);
+
+ FeatureService fs = Mockito.mock(FeatureService.class);
+ Mockito.when(fs.getFeatureForBundle(7)).thenReturn(f);
+ Mockito.when(fs.getFeatureForBundle(9)).thenReturn(f2);
+ Mockito.when(fs.getFeatureForBundle(10)).thenReturn(f2);
+
+ ServiceTracker st = Mockito.mock(ServiceTracker.class);
+ Mockito.when(st.waitForService(Mockito.anyLong())).thenReturn(fs);
+
+ Map<String, Set<String>> rpm = new HashMap<>();
+ rpm.put("r0", Collections.singleton("org.bar"));
+ rpm.put("r1", new HashSet<>(Arrays.asList("org.blah", "org.foo")));
+ rpm.put(WhitelistService.GLOBAL_REGION, Collections.singleton("org.bar.tar"));
+
+ Map<String, Set<String>> frm = new HashMap<>();
+ frm.put("gid:aid:0.0.9",
+ new HashSet<>(Arrays.asList("r1", "r2", WhitelistService.GLOBAL_REGION)));
+ frm.put("gid2:aid2:1.0.0-SNAPSHOT", Collections.singleton("r2"));
+
+ WhitelistService wls = new WhitelistServiceImpl(rpm, frm);
+ ResolverHookImpl rh = new ResolverHookImpl(st, wls);
+
+ // Check that we can get the capability from another bundle in the same region
+ // Bundle 7 is in feature f with regions r1, r2
+ BundleRequirement req = mockRequirement(7);
+ BundleCapability bc1 = mockCapability("org.foo", 19);
+ List<BundleCapability> candidates = new ArrayList<>(Arrays.asList(bc1));
+ rh.filterMatches(req, candidates);
+ assertEquals(Collections.singletonList(bc1), candidates);
+
+ // Check that we cannot get the capability from another bundle in a different region
+ // Bundle 9 is in feature f2 with region r2
+ BundleRequirement req2 = mockRequirement(9);
+ BundleCapability bc2 = mockCapability("org.bar", 17);
+ Collection<BundleCapability> c2 = new ArrayList<>(Arrays.asList(bc2));
+ rh.filterMatches(req2, c2);
+ assertEquals(0, c2.size());
+
+ // Check that we can get the capability from the same bundle
+ BundleRequirement req3 = mockRequirement(9);
+ BundleCapability bc3 = mockCapability("org.bar", 9);
+ Collection<BundleCapability> c3 = new ArrayList<>(Arrays.asList(bc3));
+ rh.filterMatches(req3, c3);
+ assertEquals(Collections.singletonList(bc3), c3);
+
+ // Check that we can get the capability from the another bundle in the same feature
+ BundleRequirement req4 = mockRequirement(9);
+ BundleCapability bc4 = mockCapability("org.bar", 10);
+ Collection<BundleCapability> c4 = new ArrayList<>(Arrays.asList(bc4));
+ rh.filterMatches(req4, c4);
+ assertEquals(Collections.singletonList(bc4), c4);
+
+ // Check that we cannot get the capability from another bundle where the capability
+ // is globally visible (from bundle 9, f2)
+ BundleRequirement req5 = mockRequirement(9);
+ BundleCapability bc5 = mockCapability("org.bar.tar", 17);
+ Collection<BundleCapability> c5 = new ArrayList<>(Arrays.asList(bc5));
+ rh.filterMatches(req5, c5);
+ assertEquals(Collections.singletonList(bc5), c5);
+
+ // Check that we cannot get the capability from another bundle where the capability
+ // is globally visible (from bundle 7, f)
+ BundleRequirement req6 = mockRequirement(7);
+ BundleCapability bc6 = mockCapability("org.bar.tar", 17);
+ Collection<BundleCapability> c6 = new ArrayList<>(Arrays.asList(bc6));
+ rh.filterMatches(req6, c6);
+ assertEquals(Collections.singletonList(bc6), c6);
+
+ // Check that capabilities in non-package namespaces are ignored
+ BundleRequirement req7 = Mockito.mock(BundleRequirement.class);
+ Mockito.when(req7.getNamespace()).thenReturn("some.other.namespace");
+ BundleCapability bc7 = mockCapability("org.bar", 17);
+ Collection<BundleCapability> c7 = new ArrayList<>(Arrays.asList(bc7));
+ rh.filterMatches(req7, c7);
+ assertEquals(Collections.singletonList(bc7), c7);
+ }
+
+ private BundleCapability mockCapability(String pkg, long bundleID) {
+ Map<String, Object> attrs =
+ Collections.singletonMap(PackageNamespace.PACKAGE_NAMESPACE, pkg);
+
+ Bundle bundle = Mockito.mock(Bundle.class);
+ Mockito.when(bundle.getBundleId()).thenReturn(bundleID);
+
+ BundleRevision br = Mockito.mock(BundleRevision.class);
+ Mockito.when(br.getBundle()).thenReturn(bundle);
+
+
+ BundleCapability cap = Mockito.mock(BundleCapability.class);
+ Mockito.when(cap.getAttributes()).thenReturn(attrs);
+ Mockito.when(cap.getRevision()).thenReturn(br);
+ return cap;
+ }
+
+ private BundleRequirement mockRequirement(long bundleID) {
+ Bundle bundle = Mockito.mock(Bundle.class);
+ Mockito.when(bundle.getBundleId()).thenReturn(bundleID);
+
+ BundleRevision br = Mockito.mock(BundleRevision.class);
+ Mockito.when(br.getBundle()).thenReturn(bundle);
+
+ BundleRequirement req = Mockito.mock(BundleRequirement.class);
+ Mockito.when(req.getNamespace()).thenReturn(PackageNamespace.PACKAGE_NAMESPACE);
+ Mockito.when(req.getRevision()).thenReturn(br);
+
+ return req;
+ }
+}