You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/04/25 00:49:29 UTC
[1/3] git commit: [KARAF-2888] Fix messages printed by the
FeaturesService
Repository: karaf
Updated Branches:
refs/heads/master d8e6ae44f -> 2e1dbb7b5
[KARAF-2888] Fix messages printed by the FeaturesService
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b123f9f6
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b123f9f6
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b123f9f6
Branch: refs/heads/master
Commit: b123f9f6e427b2d0f5c05b71f741d6858af485d9
Parents: d8e6ae4
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 24 17:31:10 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 24 17:31:10 2014 +0200
----------------------------------------------------------------------
.../karaf/features/internal/service/FeaturesServiceImpl.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/b123f9f6/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index cbfb15a..7863884 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -951,7 +951,7 @@ public class FeaturesServiceImpl implements FeaturesService {
}
if (simulate) {
- if (!toRefresh.isEmpty()) {
+ if (!noRefresh && !toRefresh.isEmpty()) {
print(" Bundles to refresh:", verbose);
for (Bundle bundle : toRefresh) {
print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
@@ -1250,7 +1250,7 @@ public class FeaturesServiceImpl implements FeaturesService {
while (!toStart.isEmpty()) {
List<Bundle> bs = getBundlesToStart(toStart);
for (Bundle bundle : bs) {
- LOGGER.info(" " + bundle.getSymbolicName() + " / " + bundle.getVersion());
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
try {
bundle.start();
} catch (BundleException e) {
[3/3] git commit: [KARAF-2888] Allow non-managed bundles to
automatically become managed if they are required by a feature and only used
by managed bundles Allow updates to bundle information,
such as start and start-level
Posted by gn...@apache.org.
[KARAF-2888] Allow non-managed bundles to automatically become managed if they are required by a feature and only used by managed bundles
Allow updates to bundle information, such as start and start-level
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/2e1dbb7b
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/2e1dbb7b
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/2e1dbb7b
Branch: refs/heads/master
Commit: 2e1dbb7b59139ee6e8d6ebce21fbfe6bc5593489
Parents: 6e36051
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 24 23:31:31 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Fri Apr 25 00:02:00 2014 +0200
----------------------------------------------------------------------
.../features/command/InstallFeatureCommand.java | 6 +
.../apache/karaf/features/FeaturesService.java | 1 +
.../internal/region/ResourceComparator.java | 43 ------
.../internal/region/SubsystemResolver.java | 132 +++++++++---------
.../internal/service/BundleComparator.java | 44 ++++++
.../internal/service/FeaturesServiceImpl.java | 134 ++++++++++++++++---
.../internal/service/ResourceComparator.java | 43 ++++++
.../karaf/features/internal/util/MapUtils.java | 5 +
8 files changed, 290 insertions(+), 118 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
index ccd869a..1f45aa0 100644
--- a/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
+++ b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
@@ -44,6 +44,9 @@ public class InstallFeatureCommand extends FeaturesCommandSupport {
@Option(name = "-s", aliases = "--no-auto-start", description = "Do not start the bundles", required = false, multiValued = false)
boolean noStart;
+ @Option(name = "-m", aliases = "--no-auto-manage", description = "Do not automatically manage bundles", required = false, multiValued = false)
+ boolean noManage;
+
@Option(name = "-v", aliases = "--verbose", description = "Explain what is being done", required = false, multiValued = false)
boolean verbose;
@@ -64,6 +67,9 @@ public class InstallFeatureCommand extends FeaturesCommandSupport {
if (noRefresh) {
options.add(FeaturesService.Option.NoAutoRefreshBundles);
}
+ if (noManage) {
+ options.add(FeaturesService.Option.NoAutoManageBundles);
+ }
if (verbose) {
options.add(FeaturesService.Option.Verbose);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
index 7bb3cf8..178f404 100644
--- a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
+++ b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
@@ -31,6 +31,7 @@ public interface FeaturesService {
NoAutoRefreshUnmanagedBundles,
NoAutoRefreshBundles,
NoAutoStartBundles,
+ NoAutoManageBundles,
Simulate,
Verbose
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/internal/region/ResourceComparator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/ResourceComparator.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/ResourceComparator.java
deleted file mode 100644
index 19ba529..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/ResourceComparator.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.karaf.features.internal.region;
-
-import java.util.Comparator;
-
-import org.apache.felix.resolver.Util;
-import org.osgi.framework.Version;
-import org.osgi.resource.Resource;
-
-public class ResourceComparator implements Comparator<Resource> {
-
- @Override
- public int compare(Resource o1, Resource o2) {
- String bsn1 = Util.getSymbolicName(o1);
- String bsn2 = Util.getSymbolicName(o2);
- int c = bsn1.compareTo(bsn2);
- if (c == 0) {
- Version v1 = Util.getVersion(o1);
- Version v2 = Util.getVersion(o2);
- c = v1.compareTo(v2);
- if (c == 0) {
- c = o1.hashCode() - o2.hashCode();
- }
- }
- return c;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
index 86d8e1b..a6355d2 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
@@ -16,8 +16,6 @@
*/
package org.apache.karaf.features.internal.region;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -29,7 +27,6 @@ import org.apache.felix.resolver.ResolverImpl;
import org.apache.felix.resolver.Util;
import org.apache.karaf.features.BundleInfo;
import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.Repository;
import org.apache.karaf.features.internal.download.DownloadManager;
import org.apache.karaf.features.internal.download.Downloader;
import org.apache.karaf.features.internal.download.StreamProvider;
@@ -69,6 +66,16 @@ public class SubsystemResolver {
private Subsystem root;
private Map<Resource, List<Wire>> wiring;
+ // Cached computed results
+ private Map<String, String> flatSubsystemsMap;
+ private Map<String, Set<Resource>> bundlesPerRegions;
+ private Map<Resource, String> bundles;
+ private Map<String, Set<Resource>> featuresPerRegions;
+ private Map<Resource, String> features;
+ private RegionDigraph flatDigraph;
+ private Map<String, Map<String, BundleInfo>> bundleInfos;
+
+
public SubsystemResolver() {
this(new SimpleDownloader());
}
@@ -152,22 +159,23 @@ public class SubsystemResolver {
}
public Map<String, Map<String, BundleInfo>> getBundleInfos() {
- Map<String, Map<String, BundleInfo>> infos = new HashMap<String, Map<String, BundleInfo>>();
- Map<String, String> flats = getFlatSubsystemsMap();
- addBundleInfos(infos, root, flats);
- return infos;
+ if (bundleInfos == null) {
+ bundleInfos = new HashMap<String, Map<String, BundleInfo>>();
+ addBundleInfos(root);
+ }
+ return bundleInfos;
}
- private void addBundleInfos(Map<String, Map<String, BundleInfo>> infos, Subsystem subsystem, Map<String, String> flats) {
- String region = flats.get(subsystem.getName());
- Map<String, BundleInfo> bis = infos.get(region);
+ private void addBundleInfos(Subsystem subsystem) {
+ String region = getFlatSubsystemsMap().get(subsystem.getName());
+ Map<String, BundleInfo> bis = bundleInfos.get(region);
if (bis == null) {
bis = new HashMap<String, BundleInfo>();
- infos.put(region, bis);
+ bundleInfos.put(region, bis);
}
bis.putAll(subsystem.getBundleInfos());
for (Subsystem child : subsystem.getChildren()) {
- addBundleInfos(infos, child, flats);
+ addBundleInfos(child);
}
}
@@ -175,83 +183,87 @@ public class SubsystemResolver {
return manager.getProviders();
}
- public RegionDigraph getDigraph() {
- return digraph;
- }
-
public Map<Resource, List<Wire>> getWiring() {
return wiring;
}
public RegionDigraph getFlatDigraph() throws BundleException, InvalidSyntaxException {
- RegionDigraph clone = this.digraph.copy();
- RegionDigraph computedDigraph = digraph;
- for (Region r : clone.getRegions()) {
- clone.removeRegion(r);
- }
- Map<String, String> flats = getFlatSubsystemsMap();
- for (Region r : computedDigraph.getRegions()) {
- if (r.getName().equals(flats.get(r.getName()))) {
- clone.createRegion(r.getName());
+ if (flatDigraph == null) {
+ flatDigraph = new StandardRegionDigraph(null, null);
+ Map<String, String> flats = getFlatSubsystemsMap();
+ for (Region r : digraph.getRegions()) {
+ if (r.getName().equals(flats.get(r.getName()))) {
+ flatDigraph.createRegion(r.getName());
+ }
}
- }
- for (Region r : computedDigraph.getRegions()) {
- for (RegionDigraph.FilteredRegion fr : computedDigraph.getEdges(r)) {
- String rt = flats.get(r.getName());
- String rh = flats.get(fr.getRegion().getName());
- if (!rh.equals(rt)) {
- Region tail = clone.getRegion(rt);
- Region head = clone.getRegion(rh);
- RegionFilterBuilder rfb = clone.createRegionFilterBuilder();
- for (Map.Entry<String, Collection<String>> entry : fr.getFilter().getSharingPolicy().entrySet()) {
- // Discard osgi.identity namespace
- if (!IDENTITY_NAMESPACE.equals(entry.getKey())) {
- for (String f : entry.getValue()) {
- rfb.allow(entry.getKey(), f);
+ for (Region r : digraph.getRegions()) {
+ for (RegionDigraph.FilteredRegion fr : digraph.getEdges(r)) {
+ String rt = flats.get(r.getName());
+ String rh = flats.get(fr.getRegion().getName());
+ if (!rh.equals(rt)) {
+ Region tail = flatDigraph.getRegion(rt);
+ Region head = flatDigraph.getRegion(rh);
+ RegionFilterBuilder rfb = flatDigraph.createRegionFilterBuilder();
+ for (Map.Entry<String, Collection<String>> entry : fr.getFilter().getSharingPolicy().entrySet()) {
+ // Discard osgi.identity namespace
+ if (!IDENTITY_NAMESPACE.equals(entry.getKey())) {
+ for (String f : entry.getValue()) {
+ rfb.allow(entry.getKey(), f);
+ }
}
}
+ flatDigraph.connect(tail, rfb.build(), head);
}
- clone.connect(tail, rfb.build(), head);
}
}
}
- return clone;
+ return flatDigraph;
}
public Map<String, String> getFlatSubsystemsMap() {
- Map<String, String> toFlatten = new HashMap<String, String>();
- findSubsystemsToFlatten(root, toFlatten);
- return toFlatten;
+ if (flatSubsystemsMap == null) {
+ flatSubsystemsMap = new HashMap<String, String>();
+ findSubsystemsToFlatten(root, flatSubsystemsMap);
+ }
+ return flatSubsystemsMap;
}
public Map<String, Set<Resource>> getBundlesPerRegions() {
- return invert(getBundles());
+ if (bundlesPerRegions == null) {
+ bundlesPerRegions = invert(getBundles());
+ }
+ return bundlesPerRegions;
}
public Map<Resource, String> getBundles() {
- String filter = String.format("(&(%s=*)(|(%s=%s)(%s=%s)))",
- IDENTITY_NAMESPACE,
- CAPABILITY_TYPE_ATTRIBUTE, TYPE_BUNDLE,
- CAPABILITY_TYPE_ATTRIBUTE, TYPE_FRAGMENT);
- SimpleFilter sf = SimpleFilter.parse(filter);
- return getResourceMapping(sf);
+ if (bundles == null) {
+ String filter = String.format("(&(%s=*)(|(%s=%s)(%s=%s)))",
+ IDENTITY_NAMESPACE,
+ CAPABILITY_TYPE_ATTRIBUTE, TYPE_BUNDLE,
+ CAPABILITY_TYPE_ATTRIBUTE, TYPE_FRAGMENT);
+ SimpleFilter sf = SimpleFilter.parse(filter);
+ bundles = getResourceMapping(sf);
+ }
+ return bundles;
}
public Map<String, Set<Resource>> getFeaturesPerRegions() {
- return invert(getFeatures());
+ if (featuresPerRegions == null) {
+ featuresPerRegions = invert(getFeatures());
+ }
+ return featuresPerRegions;
}
public Map<Resource, String> getFeatures() {
- SimpleFilter sf = createFilter(IDENTITY_NAMESPACE, "*",
- CAPABILITY_TYPE_ATTRIBUTE, TYPE_FEATURE);
- return getResourceMapping(sf);
- }
-
- public Map<String, Set<Resource>> getResourcesPerRegion(SimpleFilter resourceFilter) {
- return invert(getResourceMapping(resourceFilter));
+ if (features == null) {
+ SimpleFilter sf = createFilter(IDENTITY_NAMESPACE, "*",
+ CAPABILITY_TYPE_ATTRIBUTE, TYPE_FEATURE);
+ features = getResourceMapping(sf);
+ }
+ return features;
}
- public Map<Resource, String> getResourceMapping(SimpleFilter resourceFilter) {
+ private Map<Resource, String> getResourceMapping(SimpleFilter resourceFilter) {
Map<String, String> flats = getFlatSubsystemsMap();
Map<Resource, List<Wire>> wiring = getWiring();
Map<Resource, String> resources = new HashMap<Resource, String>();
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleComparator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleComparator.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleComparator.java
new file mode 100644
index 0000000..d6bd3e1
--- /dev/null
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleComparator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.karaf.features.internal.service;
+
+import java.util.Comparator;
+
+import org.apache.felix.resolver.Util;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.resource.Resource;
+
+public class BundleComparator implements Comparator<Bundle> {
+
+ @Override
+ public int compare(Bundle o1, Bundle o2) {
+ String bsn1 = o1.getSymbolicName();
+ String bsn2 = o2.getSymbolicName();
+ int c = bsn1.compareTo(bsn2);
+ if (c == 0) {
+ Version v1 = o1.getVersion();
+ Version v2 = o2.getVersion();
+ c = v1.compareTo(v2);
+ if (c == 0) {
+ c = o1.hashCode() - o2.hashCode();
+ }
+ }
+ return c;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index 7863884..eafd08e 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -50,7 +50,6 @@ import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.features.Repository;
import org.apache.karaf.features.RepositoryEvent;
import org.apache.karaf.features.internal.download.StreamProvider;
-import org.apache.karaf.features.internal.region.ResourceComparator;
import org.apache.karaf.features.internal.region.SubsystemResolver;
import org.apache.karaf.features.internal.util.ChecksumUtils;
import org.apache.karaf.features.internal.util.Macro;
@@ -69,6 +68,7 @@ import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
@@ -84,6 +84,7 @@ import static org.apache.karaf.features.internal.resolver.ResourceUtils.getFeatu
import static org.apache.karaf.features.internal.resolver.ResourceUtils.getUri;
import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet;
import static org.apache.karaf.features.internal.util.MapUtils.apply;
+import static org.apache.karaf.features.internal.util.MapUtils.contains;
import static org.apache.karaf.features.internal.util.MapUtils.copy;
import static org.apache.karaf.features.internal.util.MapUtils.diff;
import static org.apache.karaf.features.internal.util.MapUtils.flatten;
@@ -875,6 +876,7 @@ public class FeaturesServiceImpl implements FeaturesService {
boolean noStart = options.contains(Option.NoAutoStartBundles);
boolean verbose = options.contains(Option.Verbose);
boolean simulate = options.contains(Option.Simulate);
+ boolean noManageBundles = options.contains(Option.NoAutoManageBundles);
DeploymentState dstate = getDeploymentState();
@@ -911,10 +913,10 @@ public class FeaturesServiceImpl implements FeaturesService {
Set<Resource> resourceLinkedToOldFeatures = new HashSet<Resource>();
if (noStart) {
for (Map.Entry<String, Set<Resource>> entry : featuresPerRegion.entrySet()) {
+ String region = entry.getKey();
for (Resource resource : entry.getValue()) {
String id = getFeatureId(resource);
- if (state.installedFeatures.containsKey(entry.getKey())
- && state.installedFeatures.get(entry.getKey()).contains(id)) {
+ if (contains(state.installedFeatures, region, id)) {
addTransitive(resource, resourceLinkedToOldFeatures, resolver.getWiring());
}
}
@@ -926,19 +928,10 @@ public class FeaturesServiceImpl implements FeaturesService {
//
Deployment deployment = computeDeployment(dstate, resolver, state);
- if (deployment.regions.isEmpty()) {
- print("No deployment change.", verbose);
- return;
- }
- //
- // Log deployment
- //
- logDeployment(deployment, verbose);
-
//
// Compute the set of bundles to refresh
//
- Set<Bundle> toRefresh = new HashSet<Bundle>();
+ Set<Bundle> toRefresh = new TreeSet<Bundle>(new BundleComparator()); // sort is only used for display
for (RegionDeployment regionDeployment : deployment.regions.values()) {
toRefresh.addAll(regionDeployment.toDelete);
toRefresh.addAll(regionDeployment.toUpdate.keySet());
@@ -950,6 +943,53 @@ public class FeaturesServiceImpl implements FeaturesService {
toRefresh.removeAll(flatten(unmanagedBundles));
}
+ // Automatically turn unmanaged bundles into managed bundles
+ // if they are required by a feature and no other unmanaged
+ // bundles have a requirement on it
+ Set<Bundle> toManage = new TreeSet<Bundle>(new BundleComparator()); // sort is only used for display
+ if (!noManageBundles) {
+ Set<Resource> features = resolver.getFeatures().keySet();
+ Set<? extends Resource> unmanaged = apply(flatten(unmanagedBundles), adapt(BundleRevision.class));
+ Set<Resource> requested = new HashSet<Resource>();
+ // Gather bundles required by a feature
+ for (List<Wire> wires : resolver.getWiring().values()) {
+ for (Wire wire : wires) {
+ if (features.contains(wire.getRequirer()) && unmanaged.contains(wire.getProvider())) {
+ requested.add(wire.getProvider());
+ }
+ }
+ }
+ // Now, we know which bundles are completely unmanaged
+ unmanaged.removeAll(requested);
+ // Check if bundles have wires from really unmanaged bundles
+ for (List<Wire> wires : resolver.getWiring().values()) {
+ for (Wire wire : wires) {
+ if (requested.contains(wire.getProvider()) && unmanaged.contains(wire.getRequirer())) {
+ requested.remove(wire.getProvider());
+ }
+ }
+ }
+ if (!requested.isEmpty()) {
+ Map<Long, String> bundleToRegion = new HashMap<Long, String>();
+ for (Map.Entry<String, Set<Long>> entry : dstate.bundlesPerRegion.entrySet()) {
+ for (long id : entry.getValue()) {
+ bundleToRegion.put(id, entry.getKey());
+ }
+ }
+ for (Resource rev : requested) {
+ Bundle bundle = ((BundleRevision) rev).getBundle();
+ long id = bundle.getBundleId();
+ addToMapSet(managedBundles, bundleToRegion.get(id), id);
+ toManage.add(bundle);
+ }
+ }
+ }
+
+ //
+ // Log deployment
+ //
+ logDeployment(deployment, verbose);
+
if (simulate) {
if (!noRefresh && !toRefresh.isEmpty()) {
print(" Bundles to refresh:", verbose);
@@ -957,10 +997,18 @@ public class FeaturesServiceImpl implements FeaturesService {
print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
}
}
+ if (!toManage.isEmpty()) {
+ print(" Managing bundle:", verbose);
+ for (Bundle bundle : toManage) {
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
+ }
+ }
return;
}
Set<Bundle> toStart = new HashSet<Bundle>();
+ Set<Bundle> toResolve = new HashSet<Bundle>();
+ Set<Bundle> toStop = new HashSet<Bundle>();
//
// Execute deployment
@@ -994,9 +1042,42 @@ public class FeaturesServiceImpl implements FeaturesService {
//
//
+ // Find start levels to update
+ //
+ Map<Bundle, Integer> toUpdateStartLevel = new HashMap<Bundle, Integer>();
+ {
+ FrameworkStartLevel fsl = systemBundleContext.getBundle().adapt(FrameworkStartLevel.class);
+ for (Map.Entry<Resource, String> entry : resolver.getBundles().entrySet()) {
+ Resource resource = entry.getKey();
+ Bundle bundle = deployment.resToBnd.get(resource);
+ String region = entry.getValue();
+ BundleInfo bi = bundleInfos.get(region).get(getUri(resource));
+ if (bundle != null && bi != null) {
+ int sl;
+ if (bi.getStartLevel() > 0) {
+ sl = bi.getStartLevel();
+ } else {
+ sl = fsl.getInitialBundleStartLevel();
+ }
+ BundleStartLevel bundleStartLevel = bundle.adapt(BundleStartLevel.class);
+ if (bundleStartLevel.getStartLevel() != sl) {
+ toUpdateStartLevel.put(bundle, sl);
+ if (sl > fsl.getStartLevel()) {
+ toStop.add(bundle);
+ }
+ }
+ if (bi.isStart()) {
+ toStart.add(bundle);
+ } else {
+ toStop.add(bundle);
+ }
+ }
+ }
+ }
+
+ //
// Stop bundles by chunks
//
- Set<Bundle> toStop = new HashSet<Bundle>();
for (RegionDeployment regionDeployment : deployment.regions.values()) {
toStop.addAll(regionDeployment.toUpdate.keySet());
toStop.addAll(regionDeployment.toDelete);
@@ -1008,7 +1089,9 @@ public class FeaturesServiceImpl implements FeaturesService {
List<Bundle> bs = getBundlesToStop(toStop);
for (Bundle bundle : bs) {
print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
- bundle.stop(STOP_TRANSIENT);
+ // If the bundle start level will be changed, stop it persistently to
+ // avoid a restart when the start level is actually changed
+ bundle.stop(toUpdateStartLevel.containsKey(bundle) ? 0 : STOP_TRANSIENT);
toStop.remove(bundle);
}
}
@@ -1132,12 +1215,22 @@ public class FeaturesServiceImpl implements FeaturesService {
toStart.add(bundle);
BundleInfo bi = bundleInfos.get(rde.getKey()).get(uri);
if (bi != null && bi.getStartLevel() > 0) {
+ // TODO: this is wrong, as it will certainly start the bundle asynchronously
+ // TODO:
bundle.adapt(BundleStartLevel.class).setStartLevel(bi.getStartLevel());
}
}
}
}
//
+ // Update start levels
+ //
+ for (Map.Entry<Bundle, Integer> entry : toUpdateStartLevel.entrySet()) {
+ Bundle bundle = entry.getKey();
+ int sl = entry.getValue();
+ bundle.adapt(BundleStartLevel.class).setStartLevel(sl);
+ }
+ //
// Install bundles
//
boolean hasToInstall = false;
@@ -1173,6 +1266,7 @@ public class FeaturesServiceImpl implements FeaturesService {
if (bi != null && bi.getStartLevel() > 0) {
bundle.adapt(BundleStartLevel.class).setStartLevel(bi.getStartLevel());
}
+ toResolve.add(bundle);
if (resourceLinkedToOldFeatures.contains(resource)) {
toStart.add(bundle);
} else if (!noStart) {
@@ -1241,6 +1335,12 @@ public class FeaturesServiceImpl implements FeaturesService {
}
}
+ // Resolve bundles
+ toResolve.addAll(toStart);
+ toResolve.addAll(toRefresh);
+ removeFragmentsAndBundlesInState(toResolve, UNINSTALLED);
+ systemBundleContext.getBundle().adapt(FrameworkWiring.class).resolveBundles(toResolve);
+
// Compute bundles to start
removeFragmentsAndBundlesInState(toStart, UNINSTALLED | ACTIVE | STARTING);
if (!toStart.isEmpty()) {
@@ -1345,6 +1445,10 @@ public class FeaturesServiceImpl implements FeaturesService {
}
protected void logDeployment(Deployment overallDeployment, boolean verbose) {
+ if (overallDeployment.regions.isEmpty()) {
+ print("No deployment change.", verbose);
+ return;
+ }
print("Changes to perform:", verbose);
for (Map.Entry<String, RegionDeployment> region : overallDeployment.regions.entrySet()) {
RegionDeployment deployment = region.getValue();
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/internal/service/ResourceComparator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/ResourceComparator.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/ResourceComparator.java
new file mode 100644
index 0000000..bdf3458
--- /dev/null
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/ResourceComparator.java
@@ -0,0 +1,43 @@
+/*
+ * 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.karaf.features.internal.service;
+
+import java.util.Comparator;
+
+import org.apache.felix.resolver.Util;
+import org.osgi.framework.Version;
+import org.osgi.resource.Resource;
+
+public class ResourceComparator implements Comparator<Resource> {
+
+ @Override
+ public int compare(Resource o1, Resource o2) {
+ String bsn1 = Util.getSymbolicName(o1);
+ String bsn2 = Util.getSymbolicName(o2);
+ int c = bsn1.compareTo(bsn2);
+ if (c == 0) {
+ Version v1 = Util.getVersion(o1);
+ Version v2 = Util.getVersion(o2);
+ c = v1.compareTo(v2);
+ if (c == 0) {
+ c = o1.hashCode() - o2.hashCode();
+ }
+ }
+ return c;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2e1dbb7b/features/core/src/main/java/org/apache/karaf/features/internal/util/MapUtils.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/MapUtils.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/MapUtils.java
index 0a21e29..d844c22 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/MapUtils.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/util/MapUtils.java
@@ -81,6 +81,11 @@ public class MapUtils {
};
}
+ public static <S, T> boolean contains(Map<S, Set<T>> mapset, S key, T val) {
+ Set<T> set = mapset.get(key);
+ return set != null && set.contains(val);
+ }
+
public static <S, T> Set<T> flatten(Map<S, Set<T>> mapset) {
Set<T> set = new HashSet<T>();
for (Set<T> s : mapset.values()) {
[2/3] git commit: [KARAF-2923] Resolve optional dependencies to
gather bundles to refresh correctly,
but do not go to the user-defined repositories for optional requirements
Posted by gn...@apache.org.
[KARAF-2923] Resolve optional dependencies to gather bundles to refresh correctly, but do not go to the user-defined repositories for optional requirements
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/6e36051b
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/6e36051b
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/6e36051b
Branch: refs/heads/master
Commit: 6e36051bc3ebe128d31cb14ce7ff9686cfd4fc0e
Parents: b123f9f
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 24 17:34:13 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 24 17:34:13 2014 +0200
----------------------------------------------------------------------
.../internal/region/SubsystemResolveContext.java | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/6e36051b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
index ef9c420..10be228 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
@@ -100,10 +100,13 @@ public class SubsystemResolveContext extends ResolveContext {
if (res != null && !res.isEmpty()) {
caps.addAll(res);
} else if (globalRepository != null) {
- resMap = globalRepository.findProviders(Collections.singleton(requirement));
- res = resMap != null ? resMap.get(requirement) : null;
- if (res != null && !res.isEmpty()) {
- caps.addAll(res);
+ // Only bring in external resources for non optional requirements
+ if (!RESOLUTION_OPTIONAL.equals(requirement.getDirectives().get(RESOLUTION_DIRECTIVE))) {
+ resMap = globalRepository.findProviders(Collections.singleton(requirement));
+ res = resMap != null ? resMap.get(requirement) : null;
+ if (res != null && !res.isEmpty()) {
+ caps.addAll(res);
+ }
}
}
@@ -168,9 +171,7 @@ public class SubsystemResolveContext extends ResolveContext {
@Override
public boolean isEffective(Requirement requirement) {
- String resolution = requirement.getDirectives().get(RESOLUTION_DIRECTIVE);
- return requirement.getNamespace().equals(IDENTITY_NAMESPACE)
- || !RESOLUTION_OPTIONAL.equals(resolution);
+ return true;
}
@Override