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 2015/04/14 17:39:59 UTC

karaf git commit: [KARAF-3102] Improve bundle state and features state computation

Repository: karaf
Updated Branches:
  refs/heads/master 026843479 -> f8363dec5


[KARAF-3102] Improve bundle state and features state computation


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/f8363dec
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/f8363dec
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/f8363dec

Branch: refs/heads/master
Commit: f8363dec55c18757151df9491067b1cfd1e09946
Parents: 0268434
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Tue Apr 14 17:39:40 2015 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Tue Apr 14 17:39:54 2015 +0200

----------------------------------------------------------------------
 .../internal/resolver/FeatureResource.java      | 15 ++++-
 .../internal/resolver/ResourceUtils.java        | 18 ++---
 .../features/internal/service/Deployer.java     | 70 ++++++++++++++------
 3 files changed, 73 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/f8363dec/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
index 73cb7a1..d7c7cf8 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
@@ -36,6 +36,8 @@ import static org.apache.karaf.features.internal.resolver.ResourceUtils.addIdent
  */
 public final class FeatureResource extends ResourceImpl {
 
+    public static final String REQUIREMENT_CONDITIONAL_DIRECTIVE = "condition";
+    public static final String CONDITIONAL_TRUE = "true";
     private final Feature feature;
 
     private FeatureResource(Feature feature) {
@@ -58,13 +60,13 @@ public final class FeatureResource extends ResourceImpl {
                 if (p.length > 1) {
                     dep.setVersion(p[1]);
                 }
-                addDependency(resource, dep, featureRange);
+                addDependency(resource, dep, featureRange, true);
             }
         }
         org.apache.karaf.features.internal.model.Dependency dep = new org.apache.karaf.features.internal.model.Dependency();
         dep.setName(feature.getName());
         dep.setVersion(feature.getVersion());
-        addDependency(resource, dep, featureRange);
+        addDependency(resource, dep, featureRange, true);
         return resource;
     }
 
@@ -94,6 +96,10 @@ public final class FeatureResource extends ResourceImpl {
     }
 
     protected static void addDependency(FeatureResource resource, Dependency dep, String featureRange) {
+        addDependency(resource, dep, featureRange, false);
+    }
+
+    protected static void addDependency(FeatureResource resource, Dependency dep, String featureRange, boolean condition) {
         String name = dep.getName();
         String version = dep.getVersion();
         if (version.equals("0.0.0")) {
@@ -101,7 +107,10 @@ public final class FeatureResource extends ResourceImpl {
         } else if (!version.startsWith("[") && !version.startsWith("(")) {
             version = Macro.transform(featureRange, version);
         }
-        addIdentityRequirement(resource, name, TYPE_FEATURE, version);
+        RequirementImpl requirement = addIdentityRequirement(resource, name, TYPE_FEATURE, version);
+        if (condition) {
+            requirement.getDirectives().put(REQUIREMENT_CONDITIONAL_DIRECTIVE, CONDITIONAL_TRUE);
+        }
     }
 
     public Feature getFeature() {

http://git-wip-us.apache.org/repos/asf/karaf/blob/f8363dec/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
index 91ea5e1..8c7c406 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
@@ -80,19 +80,19 @@ public final class ResourceUtils {
         return null;
     }
 
-    public static void addIdentityRequirement(ResourceImpl resource, String name, String type, String range) {
-        addIdentityRequirement(resource, name, type, range, true);
+    public static RequirementImpl addIdentityRequirement(ResourceImpl resource, String name, String type, String range) {
+        return addIdentityRequirement(resource, name, type, range, true);
     }
 
-    public static void addIdentityRequirement(ResourceImpl resource, String name, String type, String range, boolean mandatory) {
-        addIdentityRequirement(resource, name, type, range != null ? new VersionRange(range) : null, mandatory);
+    public static RequirementImpl addIdentityRequirement(ResourceImpl resource, String name, String type, String range, boolean mandatory) {
+        return addIdentityRequirement(resource, name, type, range != null ? new VersionRange(range) : null, mandatory);
     }
 
-    public static void addIdentityRequirement(ResourceImpl resource, String name, String type, VersionRange range) {
-        addIdentityRequirement(resource, name, type, range, true);
+    public static RequirementImpl addIdentityRequirement(ResourceImpl resource, String name, String type, VersionRange range) {
+        return addIdentityRequirement(resource, name, type, range, true);
     }
 
-    public static void addIdentityRequirement(ResourceImpl resource, String name, String type, VersionRange range, boolean mandatory) {
+    public static RequirementImpl addIdentityRequirement(ResourceImpl resource, String name, String type, VersionRange range, boolean mandatory) {
         Map<String, String> dirs = new HashMap<>();
         Map<String, Object> attrs = new HashMap<>();
         if (!mandatory) {
@@ -107,7 +107,9 @@ public final class ResourceUtils {
         if (range != null) {
             attrs.put(CAPABILITY_VERSION_ATTRIBUTE, range);
         }
-        resource.addRequirement(new RequirementImpl(resource, IDENTITY_NAMESPACE, dirs, attrs));
+        RequirementImpl requirement = new RequirementImpl(resource, IDENTITY_NAMESPACE, dirs, attrs);
+        resource.addRequirement(requirement);
+        return requirement;
     }
 
     public static void addIdentityRequirement(ResourceImpl resource, Resource required) {

http://git-wip-us.apache.org/repos/asf/karaf/blob/f8363dec/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
index 3a13e8c..e759e56 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
@@ -48,6 +48,7 @@ import org.apache.karaf.features.FeaturesService;
 import org.apache.karaf.features.internal.download.DownloadManager;
 import org.apache.karaf.features.internal.download.StreamProvider;
 import org.apache.karaf.features.internal.region.SubsystemResolver;
+import org.apache.karaf.features.internal.resolver.FeatureResource;
 import org.apache.karaf.features.internal.util.ChecksumUtils;
 import org.apache.karaf.features.internal.util.Macro;
 import org.apache.karaf.features.internal.util.MapUtils;
@@ -383,14 +384,60 @@ public class Deployer {
         // Compute bundle states
         //
         Map<Resource, FeatureState> states = new HashMap<>();
+        // Find all features state
+        Map<Resource, FeatureState> featuresState = new HashMap<>();
+        Map<Resource, Set<Resource>> conditionals = new HashMap<>();
         for (Map.Entry<String, Set<Resource>> entry : resolver.getFeaturesPerRegions().entrySet()) {
             String region = entry.getKey();
             Map<String, String> fss = stateFeatures.get(region);
             for (Resource feature : entry.getValue()) {
-                String fs = fss.get(getFeatureId(feature));
-                propagateState(states, feature, FeatureState.valueOf(fs), resolver);
+                Set<Resource> conditions = new HashSet<>();
+                for (Wire wire : resolver.getWiring().get(feature)) {
+                    if (IDENTITY_NAMESPACE.equals(wire.getRequirement().getNamespace()) &&
+                            FeatureResource.CONDITIONAL_TRUE.equals(wire.getRequirement().getDirectives().get(FeatureResource.REQUIREMENT_CONDITIONAL_DIRECTIVE))) {
+                        conditions.add(wire.getProvider());
+                    }
+                }
+                if (conditions.isEmpty()) {
+                    String fs = fss.get(getFeatureId(feature));
+                    featuresState.put(feature, FeatureState.valueOf(fs));
+                } else {
+                    conditionals.put(feature, conditions);
+                }
             }
         }
+        // Compute conditional features state
+        for (Resource feature : conditionals.keySet()) {
+            FeatureState state = null;
+            for (Resource cond : conditionals.get(feature)) {
+                FeatureState s = featuresState.get(cond);
+                if (state == null) {
+                    state = s;
+                } else if (state == FeatureState.Started && s == FeatureState.Resolved) {
+                    state = FeatureState.Resolved;
+                }
+            }
+            featuresState.put(feature, state);
+        }
+        // Propagate Resolved state
+        for (Resource feature : featuresState.keySet()) {
+            if (featuresState.get(feature) == FeatureState.Resolved) {
+                propagateState(states, feature, FeatureState.Resolved, resolver);
+            }
+        }
+        // Propagate Started state
+        for (Resource feature : featuresState.keySet()) {
+            if (featuresState.get(feature) == FeatureState.Started) {
+                propagateState(states, feature, FeatureState.Started, resolver);
+            }
+        }
+        // Put default Started state for other bundles
+        for (Resource resource : resolver.getBundles().keySet()) {
+            if (!states.containsKey(resource)) {
+                states.put(resource, FeatureState.Started);
+            }
+        }
+        // Only keep bundles resources
         states.keySet().retainAll(resolver.getBundles().keySet());
         //
         // Compute bundles to start, stop and resolve
@@ -829,24 +876,9 @@ public class Deployer {
             if (reqState != states.get(resource)) {
                 states.put(resource, reqState);
                 for (Wire wire : resolver.getWiring().get(resource)) {
-                    Resource provider = wire.getProvider();
-                    FeatureState stateToMerge;
-                    String region = resolver.getBundles().get(provider);
-                    BundleInfo bi = region != null ? resolver.getBundleInfos().get(region).get(getUri(provider)) : null;
-                    if (reqState == FeatureState.Started) {
-                        String effective = wire.getCapability().getDirectives().get(CAPABILITY_EFFECTIVE_DIRECTIVE);
-                        // If there is an active effective capability or a requirement from the feature
-                        // and if the bundle is flagged as to start, start it
-                        if ((EFFECTIVE_ACTIVE.equals(effective) || IDENTITY_NAMESPACE.equals(wire.getCapability().getNamespace()))
-                                && (bi == null || bi.isStart())) {
-                            stateToMerge = FeatureState.Started;
-                        } else {
-                            stateToMerge = FeatureState.Resolved;
-                        }
-                    } else {
-                        stateToMerge = reqState;
+                    if (IDENTITY_NAMESPACE.equals(wire.getCapability().getNamespace())) {
+                        propagateState(states, wire.getProvider(), reqState, resolver);
                     }
-                    propagateState(states, provider, stateToMerge, resolver);
                 }
             }
         }