http://git-wip-us.apache.org/repos/asf/karaf/blob/ca651c8e/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleServiceImpl.java ---------------------------------------------------------------------- diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleServiceImpl.java b/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleServiceImpl.java index 69861e1..f2e7012 100644 --- a/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleServiceImpl.java +++ b/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleServiceImpl.java @@ -32,9 +32,11 @@ import org.apache.karaf.bundle.core.BundleInfo; import org.apache.karaf.bundle.core.BundleService; import org.apache.karaf.bundle.core.BundleState; import org.apache.karaf.bundle.core.BundleStateService; +import org.apache.karaf.jaas.modules.JaasHelper; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; +import org.osgi.framework.startlevel.BundleStartLevel; import org.osgi.framework.wiring.BundleCapability; import org.osgi.framework.wiring.BundleRequirement; import org.osgi.framework.wiring.BundleRevision; @@ -55,7 +57,7 @@ public class BundleServiceImpl implements BundleService { private static final String ORIGINAL_WIRES = "Original-Wires"; private final BundleContext bundleContext; - private final List<BundleStateService> stateServices = new CopyOnWriteArrayList<BundleStateService>(); + private final List<BundleStateService> stateServices = new CopyOnWriteArrayList<>(); public BundleServiceImpl(BundleContext bundleContext) { this.bundleContext = bundleContext; @@ -71,19 +73,22 @@ public class BundleServiceImpl implements BundleService { @Override public List<Bundle> selectBundles(List<String> ids, boolean defaultAllBundles) { - return new BundleSelectorImpl(bundleContext).selectBundles(ids, defaultAllBundles); + return selectBundles(null, ids, defaultAllBundles); } @Override - public Bundle getBundle(String id, boolean defaultAllBundles) { - List<String> ids = new ArrayList<String>(1); - ids.add(id); - List<Bundle> bundles = selectBundles(ids, defaultAllBundles); - if (bundles.isEmpty()) { - return null; - } else { - return bundles.get(0); - } + public List<Bundle> selectBundles(String context, List<String> ids, boolean defaultAllBundles) { + return doSelectBundles(doGetBundleContext(context), ids, defaultAllBundles); + } + + @Override + public Bundle getBundle(String id) { + return getBundle(null, id); + } + + @Override + public Bundle getBundle(String context, String id) { + return doGetBundle(doGetBundleContext(context), id); } @Override @@ -104,13 +109,14 @@ public class BundleServiceImpl implements BundleService { for (BundleStateService bundleStateService : stateServices) { String part = bundleStateService.getDiag(bundle); if (part != null) { - message.append(bundleStateService.getName() + "\n"); + message.append(bundleStateService.getName()); + message.append("\n"); message.append(part); } } if (bundle.getState() == Bundle.INSTALLED) { System.out.println("Unsatisfied Requirements:"); - List<BundleRequirement> reqs = getUnsatisfiedRquirements(bundle, null); + List<BundleRequirement> reqs = getUnsatisfiedRequirements(bundle, null); for (BundleRequirement req : reqs) { System.out.println(req); } @@ -119,8 +125,8 @@ public class BundleServiceImpl implements BundleService { } @Override - public List<BundleRequirement> getUnsatisfiedRquirements(Bundle bundle, String namespace) { - List<BundleRequirement> result = new ArrayList<BundleRequirement>(); + public List<BundleRequirement> getUnsatisfiedRequirements(Bundle bundle, String namespace) { + List<BundleRequirement> result = new ArrayList<>(); BundleRevision rev = bundle.adapt(BundleRevision.class); if (rev != null) { List<BundleRequirement> reqs = rev.getDeclaredRequirements(namespace); @@ -132,6 +138,72 @@ public class BundleServiceImpl implements BundleService { } return result; } + + @Override + public int getSystemBundleThreshold() { + int sbsl = 50; + try { + final String sbslProp = bundleContext.getProperty("karaf.systemBundlesStartLevel"); + if (sbslProp != null) { + sbsl = Integer.valueOf(sbslProp); + } + } catch (Exception ignore) { + // ignore + } + return sbsl; + } + + private BundleContext doGetBundleContext(String context) { + if (context == null || context.trim().isEmpty()) { + return bundleContext; + } else { + List<Bundle> bundles = doSelectBundles(bundleContext, Collections.singletonList(context), false); + if (bundles.isEmpty()) { + throw new IllegalArgumentException("Context " + context + " does not evaluate to a bundle"); + } else if (bundles.size() > 1) { + throw new IllegalArgumentException("Context " + context + " is ambiguous"); + } + BundleContext bundleContext = bundles.get(0).getBundleContext(); + if (bundleContext == null) { + throw new IllegalArgumentException("Context " + context + " is not resolved"); + } + return bundleContext; + } + } + + private Bundle doGetBundle(BundleContext bundleContext, String id) { + List<Bundle> bundles = doSelectBundles(bundleContext, Collections.singletonList(id), false); + if (bundles.isEmpty()) { + throw new IllegalArgumentException("Bundle " + id + " does not match any bundle"); + } else { + List<Bundle> filtered = filter(bundles); + if (filtered.isEmpty()) { + throw new IllegalArgumentException("Access to bundle " + id + " is forbidden"); + } else if (filtered.size() > 1) { + throw new IllegalArgumentException("Multiple bundles matching " + id); + } + return filtered.get(0); + } + } + + private List<Bundle> doSelectBundles(BundleContext bundleContext, List<String> ids, boolean defaultAllBundles) { + return filter(new BundleSelectorImpl(bundleContext).selectBundles(ids, defaultAllBundles)); + } + + private List<Bundle> filter(List<Bundle> bundles) { + if (JaasHelper.currentUserHasRole(BundleService.SYSTEM_BUNDLES_ROLE)) { + return bundles; + } + int sbsl = getSystemBundleThreshold(); + List<Bundle> filtered = new ArrayList<>(); + for (Bundle bundle : bundles) { + int level = bundle.adapt(BundleStartLevel.class).getStartLevel(); + if (level >= sbsl) { + filtered.add(bundle); + } + } + return filtered; + } private boolean canBeSatisfied(BundleRequirement req) { Bundle[] bundles = bundleContext.getBundles(); @@ -149,11 +221,6 @@ public class BundleServiceImpl implements BundleService { return false; } - @Override - public List<Bundle> getBundlesByURL(String urlFilter) { - return new BundleSelectorImpl(bundleContext).getBundlesByURL(urlFilter); - } - /* * Enable DynamicImport=* on the bundle */ @@ -187,7 +254,7 @@ public class BundleServiceImpl implements BundleService { */ public void disableDynamicImports(Bundle bundle) { Set<String> current = getWiredBundles(bundle).keySet(); - for (String original : bundle.getHeaders().get(ORIGINAL_WIRES).toString().split(",")) { + for (String original : bundle.getHeaders().get(ORIGINAL_WIRES).split(",")) { current.remove(original); } @@ -211,7 +278,7 @@ public class BundleServiceImpl implements BundleService { * Explode a set of string values in to a ,-delimited string */ private String explode(Set<String> set) { - StringBuffer result = new StringBuffer(); + StringBuilder result = new StringBuilder(); Iterator<String> it = set.iterator(); while (it.hasNext()) { result.append(it.next()); @@ -230,7 +297,7 @@ public class BundleServiceImpl implements BundleService { */ public Map<String, Bundle> getWiredBundles(Bundle bundle) { // the set of bundles from which the bundle imports packages - Map<String, Bundle> exporters = new HashMap<String, Bundle>(); + Map<String, Bundle> exporters = new HashMap<>(); for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions()) { BundleWiring wiring = revision.getWiring();
http://git-wip-us.apache.org/repos/asf/karaf/blob/ca651c8e/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java ---------------------------------------------------------------------- diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java b/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java index 665dc1b..cb52567 100644 --- a/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java +++ b/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -91,8 +92,12 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche oldCounter = counter.get(); watchedBundles.clear(); for (String bundleURL : watchURLs) { - for (Bundle bundle : bundleService.getBundlesByURL(bundleURL)) { - watchedBundles.add(bundle); + // Transform into regexp + bundleURL = bundleURL.replaceAll("\\*", ".*"); + for (Bundle bundle : bundleService.selectBundles(Collections.singletonList(bundleURL), false)) { + if (isMavenSnapshotUrl(bundle.getLocation())) { + watchedBundles.add(bundle); + } } } } @@ -141,6 +146,10 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche } } + private boolean isMavenSnapshotUrl(String url) { + return url.startsWith("mvn:") && url.contains("SNAPSHOT"); + } + private void updateBundleIfNecessary(File localRepository, List<Bundle> updated, Bundle bundle) throws FileNotFoundException, BundleException, IOException { File location = getBundleExternalLocation(localRepository, bundle); @@ -248,7 +257,8 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche @Override public List<Bundle> getBundlesByURL(String urlFilter) { - return bundleService.getBundlesByURL(urlFilter); + urlFilter = urlFilter.replaceAll("\\*", ".*"); + return bundleService.selectBundles(Collections.singletonList(urlFilter), false); } } http://git-wip-us.apache.org/repos/asf/karaf/blob/ca651c8e/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java ---------------------------------------------------------------------- diff --git a/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java b/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java index 876f605..c4413b9 100644 --- a/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java +++ b/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java @@ -17,7 +17,6 @@ package org.apache.karaf.bundle.command; import java.util.Arrays; -import java.util.Collections; import org.apache.karaf.bundle.core.internal.BundleServiceImpl; import org.junit.Test; @@ -25,12 +24,14 @@ import org.osgi.framework.BundleContext; public class ListServicesTest { - private ListBundleServices listServices; + private BundleContext bundleContext; + private Services listServices; @SuppressWarnings("unchecked") public ListServicesTest() { - listServices = new ListBundleServices(); - BundleContext bundleContext = new TestBundleFactory().createBundleContext(); + listServices = new Services(); + bundleContext = new TestBundleFactory().createBundleContext(); + listServices.context = null; listServices.setBundleContext(bundleContext); listServices.setBundleService(new BundleServiceImpl(bundleContext)); } http://git-wip-us.apache.org/repos/asf/karaf/blob/ca651c8e/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java ---------------------------------------------------------------------- diff --git a/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java b/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java index 27e4a63..6912c41 100644 --- a/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java +++ b/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java @@ -28,6 +28,7 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; +import org.osgi.framework.startlevel.BundleStartLevel; public class TestBundleFactory { ServiceReference<?> createServiceRef(Object ... keyProp) { @@ -61,6 +62,8 @@ public class TestBundleFactory { Bundle bundle2 = createBundle(2, "Bundle B"); Bundle bundle3 = createBundle(3, "Bundle C"); + BundleStartLevel bsl = createMock(BundleStartLevel.class); + ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.MyService"}, "key1", "value1"); ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.OtherService"}, "key2", 1); @@ -76,7 +79,13 @@ public class TestBundleFactory { expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, bundle3}).anyTimes(); expect(ref2.getUsingBundles()).andReturn(new Bundle[]{bundle3}).anyTimes(); - replay(bundle1, bundle2, bundle3, ref1, ref2); + expect(bundle1.adapt(BundleStartLevel.class)).andReturn(bsl).anyTimes(); + expect(bundle2.adapt(BundleStartLevel.class)).andReturn(bsl).anyTimes(); + expect(bundle3.adapt(BundleStartLevel.class)).andReturn(bsl).anyTimes(); + + expect(bsl.getStartLevel()).andReturn(80).anyTimes(); + + replay(bundle1, bundle2, bundle3, ref1, ref2, bsl); return new Bundle[] { bundle1, bundle2, bundle3 }; } @@ -94,6 +103,7 @@ public class TestBundleFactory { public BundleContext createBundleContext() { BundleContext bundleContext = createMock(BundleContext.class); Bundle[] bundles = createBundles(); + expect(bundleContext.getProperty("karaf.systemBundlesStartLevel")).andReturn(Integer.toString(50)).anyTimes(); expect(bundleContext.getBundles()).andReturn(bundles).anyTimes(); expect(bundleContext.getBundle(0)).andReturn(null).anyTimes(); expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes(); http://git-wip-us.apache.org/repos/asf/karaf/blob/ca651c8e/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java ---------------------------------------------------------------------- diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java index 111df95..05489ed 100644 --- a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java +++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java @@ -25,8 +25,37 @@ import java.security.ProtectionDomain; import javax.security.auth.Subject; import javax.security.auth.SubjectDomainCombiner; +import org.apache.karaf.jaas.boot.principal.RolePrincipal; + public class JaasHelper { + public static boolean currentUserHasRole(String requestedRole) { + String clazz; + String role; + int index = requestedRole.indexOf(':'); + if (index > 0) { + clazz = requestedRole.substring(0, index); + role = requestedRole.substring(index + 1); + } else { + clazz = RolePrincipal.class.getName(); + role = requestedRole; + } + AccessControlContext acc = AccessController.getContext(); + if (acc == null) { + return false; + } + Subject subject = Subject.getSubject(acc); + if (subject == null) { + return false; + } + for (Principal p : subject.getPrincipals()) { + if (clazz.equals(p.getClass().getName()) && role.equals(p.getName())) { + return true; + } + } + return false; + } + public static <T> T doAs(final Subject subject, final PrivilegedAction<T> action) { if (action == null) {