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/05/26 22:45:09 UTC
[4/5] git commit: [KARAF-3003] Allow deployment based on generic
requirements, bundles and bundle dependencies
[KARAF-3003] Allow deployment based on generic requirements, bundles and bundle dependencies
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/98123912
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/98123912
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/98123912
Branch: refs/heads/master
Commit: 981239128f69f31dbd89cb6ddabf8a416d1606e1
Parents: 714da5e
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 26 22:44:36 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 26 22:44:36 2014 +0200
----------------------------------------------------------------------
.../karaf/features/command/RequirementAdd.java | 85 ++++++++++++
.../karaf/features/command/RequirementList.java | 59 +++++++++
.../features/command/RequirementRemove.java | 85 ++++++++++++
.../apache/karaf/features/FeaturesService.java | 6 +
.../features/internal/region/Subsystem.java | 130 ++++++++++++++-----
.../internal/region/SubsystemResolver.java | 19 +--
.../internal/resolver/ResourceUtils.java | 26 ++++
.../features/internal/service/Deployer.java | 16 +--
.../internal/service/FeaturesServiceImpl.java | 84 ++++++++----
.../karaf/features/internal/service/State.java | 6 +-
.../features/internal/service/StateStorage.java | 6 +-
.../features/internal/region/SubsystemTest.java | 24 ++++
.../features/internal/service/DeployerTest.java | 21 ++-
.../internal/service/StateStorageTest.java | 4 +-
14 files changed, 472 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/command/src/main/java/org/apache/karaf/features/command/RequirementAdd.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RequirementAdd.java b/features/command/src/main/java/org/apache/karaf/features/command/RequirementAdd.java
new file mode 100644
index 0000000..c8491b3
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RequirementAdd.java
@@ -0,0 +1,85 @@
+/*
+ * 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.command;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "requirement-add", description = "Add provisioning requirements.")
+@Service
+public class RequirementAdd implements Action {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ @Argument(required = true, multiValued = true)
+ List<String> requirements;
+
+ @Option(name = "-r", aliases = "--no-auto-refresh", description = "Do not automatically refresh bundles", required = false, multiValued = false)
+ boolean noRefresh;
+
+ @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")
+ boolean verbose;
+
+ @Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only")
+ boolean simulate;
+
+ @Option(name = "-g", aliases = "--region", description = "Region to install to")
+ String region;
+
+ @Override
+ public Object execute() throws Exception {
+ EnumSet<FeaturesService.Option> options = EnumSet.noneOf(FeaturesService.Option.class);
+ if (simulate) {
+ options.add(FeaturesService.Option.Simulate);
+ }
+ if (noStart) {
+ options.add(FeaturesService.Option.NoAutoStartBundles);
+ }
+ if (noRefresh) {
+ options.add(FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ if (noManage) {
+ options.add(FeaturesService.Option.NoAutoManageBundles);
+ }
+ if (verbose) {
+ options.add(FeaturesService.Option.Verbose);
+ }
+ Map<String, Set<String>> reqs = new HashMap<>();
+ reqs.put(region == null ? FeaturesService.ROOT_REGION : region, new HashSet<>(requirements));
+ featuresService.addRequirements(reqs, options);
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/command/src/main/java/org/apache/karaf/features/command/RequirementList.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RequirementList.java b/features/command/src/main/java/org/apache/karaf/features/command/RequirementList.java
new file mode 100644
index 0000000..195b385
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RequirementList.java
@@ -0,0 +1,59 @@
+/*
+ * 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.command;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "feature", name = "requirement-list", description = "List provisioning requirements.")
+@Service
+public class RequirementList implements Action {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ @Option(name = "--no-format", description = "Disable table rendered output")
+ boolean noFormat;
+
+ @Override
+ public Object execute() throws Exception {
+ Map<String, Set<String>> requirements = featuresService.listRequirements();
+
+ ShellTable table = new ShellTable();
+ table.column("Region");
+ table.column("Requirement");
+ table.emptyTableText("No requirements defined");
+
+ for (Map.Entry<String, Set<String>> entry : requirements.entrySet()) {
+ for (String requirement : entry.getValue()) {
+ table.addRow().addContent(entry.getKey(), requirement);
+ }
+ }
+
+ table.print(System.out, !noFormat);
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/command/src/main/java/org/apache/karaf/features/command/RequirementRemove.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RequirementRemove.java b/features/command/src/main/java/org/apache/karaf/features/command/RequirementRemove.java
new file mode 100644
index 0000000..a2385e9
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RequirementRemove.java
@@ -0,0 +1,85 @@
+/*
+ * 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.command;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "requirement-remove", description = "Remove provisioning requirements.")
+@Service
+public class RequirementRemove implements Action {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ @Argument(required = true, multiValued = true)
+ List<String> requirements;
+
+ @Option(name = "-r", aliases = "--no-auto-refresh", description = "Do not automatically refresh bundles", required = false, multiValued = false)
+ boolean noRefresh;
+
+ @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")
+ boolean verbose;
+
+ @Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only")
+ boolean simulate;
+
+ @Option(name = "-g", aliases = "--region", description = "Region to install to")
+ String region;
+
+ @Override
+ public Object execute() throws Exception {
+ EnumSet<FeaturesService.Option> options = EnumSet.noneOf(FeaturesService.Option.class);
+ if (simulate) {
+ options.add(FeaturesService.Option.Simulate);
+ }
+ if (noStart) {
+ options.add(FeaturesService.Option.NoAutoStartBundles);
+ }
+ if (noRefresh) {
+ options.add(FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ if (noManage) {
+ options.add(FeaturesService.Option.NoAutoManageBundles);
+ }
+ if (verbose) {
+ options.add(FeaturesService.Option.Verbose);
+ }
+ Map<String, Set<String>> reqs = new HashMap<>();
+ reqs.put(region == null ? FeaturesService.ROOT_REGION : region, new HashSet<>(requirements));
+ featuresService.removeRequirements(reqs, options);
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/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 e266402..8f40a6d 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
@@ -93,6 +93,8 @@ public interface FeaturesService {
void installFeatures(Set<String> features, String region, EnumSet<Option> options) throws Exception;
+ void addRequirements(Map<String, Set<String>> requirements, EnumSet<Option> options) throws Exception;
+
void uninstallFeature(String name, EnumSet<Option> options) throws Exception;
void uninstallFeature(String name) throws Exception;
@@ -105,6 +107,8 @@ public interface FeaturesService {
void uninstallFeatures(Set<String> features, String region, EnumSet<Option> options) throws Exception;
+ void removeRequirements(Map<String, Set<String>> requirements, EnumSet<Option> options) throws Exception;
+
void updateFeaturesState(Map<String, Map<String, RequestedState>> stateChanges, EnumSet<Option> options) throws Exception;
Feature[] listFeatures() throws Exception;
@@ -113,6 +117,8 @@ public interface FeaturesService {
Feature[] listInstalledFeatures() throws Exception;
+ Map<String, Set<String>> listRequirements();
+
boolean isRequired(Feature f);
boolean isInstalled(Feature f);
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
index f64bc0f..30a789a 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
@@ -27,6 +27,8 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.resolver.Util;
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
import org.apache.felix.utils.version.VersionRange;
import org.apache.felix.utils.version.VersionTable;
import org.apache.karaf.features.BundleInfo;
@@ -46,7 +48,6 @@ import org.apache.karaf.features.internal.resolver.ResourceUtils;
import org.apache.karaf.features.internal.service.Overrides;
import org.osgi.framework.BundleException;
import org.osgi.framework.Version;
-import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
@@ -54,6 +55,7 @@ import static org.apache.karaf.features.internal.resolver.ResourceUtils.TYPE_FEA
import static org.apache.karaf.features.internal.resolver.ResourceUtils.TYPE_SUBSYSTEM;
import static org.apache.karaf.features.internal.resolver.ResourceUtils.addIdentityRequirement;
import static org.apache.karaf.features.internal.resolver.ResourceUtils.getUri;
+import static org.apache.karaf.features.internal.resolver.ResourceUtils.toFeatureRequirement;
import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet;
import static org.eclipse.equinox.region.RegionFilter.VISIBLE_ALL_NAMESPACE;
import static org.osgi.framework.namespace.IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE;
@@ -92,6 +94,8 @@ public class Subsystem extends ResourceImpl {
private final List<Resource> installable = new ArrayList<>();
private final Map<String, DependencyInfo> dependencies = new HashMap<>();
+ private final List<String> bundles = new ArrayList<>();
+
public Subsystem(String name) {
super(name, TYPE_SUBSYSTEM, Version.emptyVersion);
this.name = name;
@@ -183,14 +187,16 @@ public class Subsystem extends ResourceImpl {
throw new UnsupportedOperationException("Can not create application subsystems inside a feature subsystem");
}
// Create subsystem
- Subsystem as = new Subsystem(getName() + "/" + name, this, acceptDependencies);
+ String childName = getName() + "/" + name;
+ Subsystem as = new Subsystem(childName, this, acceptDependencies);
children.add(as);
// Add a requirement to force its resolution
- Capability identity = as.getCapabilities(IDENTITY_NAMESPACE).iterator().next();
- Object bsn = identity.getAttributes().get(IDENTITY_NAMESPACE);
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put(IDENTITY_NAMESPACE, childName);
+ attrs.put(CAPABILITY_TYPE_ATTRIBUTE, TYPE_SUBSYSTEM);
Requirement requirement = new RequirementImpl(this, IDENTITY_NAMESPACE,
Collections.<String, String>emptyMap(),
- Collections.singletonMap(IDENTITY_NAMESPACE, bsn));
+ attrs);
addRequirement(requirement);
// Add it to repo
installable.add(as);
@@ -205,6 +211,39 @@ public class Subsystem extends ResourceImpl {
ResourceUtils.addIdentityRequirement(this, name, TYPE_FEATURE, range);
}
+ public void require(String requirement) throws BundleException {
+ int idx = requirement.indexOf(":");
+ String type, req;
+ if (idx >= 0) {
+ type = requirement.substring(0, idx);
+ req = requirement.substring(idx + 1);
+ } else {
+ type = "feature";
+ req = requirement;
+ }
+ switch (type) {
+ case "feature":
+ addRequirement(toFeatureRequirement(req));
+ break;
+ case "requirement":
+ addRequirement(req);
+ break;
+ case "bundle":
+ bundles.add(req);
+ break;
+ }
+ }
+
+ protected void addRequirement(String requirement) throws BundleException {
+ for (Requirement req : ResourceBuilder.parseRequirement(this, requirement)) {
+ Object range = req.getAttributes().get(CAPABILITY_VERSION_ATTRIBUTE);
+ if (range instanceof String) {
+ req.getAttributes().put(CAPABILITY_VERSION_ATTRIBUTE, new VersionRange((String) range));
+ }
+ addRequirement(req);
+ }
+ }
+
public Map<String, BundleInfo> getBundleInfos() {
Map<String, BundleInfo> infos = new HashMap<>();
for (DependencyInfo di : dependencies.values()) {
@@ -286,10 +325,10 @@ public class Subsystem extends ResourceImpl {
for (Subsystem child : children) {
child.downloadBundles(manager, overrides, featureResolutionRange);
}
+ final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<>();
+ final Downloader downloader = manager.createDownloader();
+ final Map<BundleInfo, Conditional> infos = new HashMap<>();
if (feature != null) {
- final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<>();
- final Downloader downloader = manager.createDownloader();
- final Map<BundleInfo, Conditional> infos = new HashMap<>();
for (Conditional cond : feature.getConditional()) {
for (final BundleInfo bi : cond.getBundles()) {
infos.put(bi, cond);
@@ -298,29 +337,41 @@ public class Subsystem extends ResourceImpl {
for (BundleInfo bi : feature.getBundles()) {
infos.put(bi, null);
}
- for (Map.Entry<BundleInfo, Conditional> entry : infos.entrySet()) {
- final BundleInfo bi = entry.getKey();
- final String loc = bi.getLocation();
- downloader.download(loc, new DownloadCallback() {
- @Override
- public void downloaded(StreamProvider provider) throws Exception {
- ResourceImpl res = createResource(loc, provider.getMetadata());
- bundles.put(loc, res);
- }
- });
- }
- for (String override : overrides) {
- final String loc = Overrides.extractUrl(override);
- downloader.download(loc, new DownloadCallback() {
- @Override
- public void downloaded(StreamProvider provider) throws Exception {
- ResourceImpl res = createResource(loc, provider.getMetadata());
- bundles.put(loc, res);
- }
- });
- }
- downloader.await();
- Overrides.override(bundles, overrides);
+ }
+ for (Map.Entry<BundleInfo, Conditional> entry : infos.entrySet()) {
+ final BundleInfo bi = entry.getKey();
+ final String loc = bi.getLocation();
+ downloader.download(loc, new DownloadCallback() {
+ @Override
+ public void downloaded(StreamProvider provider) throws Exception {
+ ResourceImpl res = createResource(loc, provider.getMetadata());
+ bundles.put(loc, res);
+ }
+ });
+ }
+ for (Clause bundle : Parser.parseClauses(this.bundles.toArray(new String[this.bundles.size()]))) {
+ final String loc = bundle.getName();
+ downloader.download(loc, new DownloadCallback() {
+ @Override
+ public void downloaded(StreamProvider provider) throws Exception {
+ ResourceImpl res = createResource(loc, provider.getMetadata());
+ bundles.put(loc, res);
+ }
+ });
+ }
+ for (String override : overrides) {
+ final String loc = Overrides.extractUrl(override);
+ downloader.download(loc, new DownloadCallback() {
+ @Override
+ public void downloaded(StreamProvider provider) throws Exception {
+ ResourceImpl res = createResource(loc, provider.getMetadata());
+ bundles.put(loc, res);
+ }
+ });
+ }
+ downloader.await();
+ Overrides.override(bundles, overrides);
+ if (feature != null) {
// Add conditionals
Map<Conditional, Resource> resConds = new HashMap<>();
for (Conditional cond : feature.getConditional()) {
@@ -350,6 +401,23 @@ public class Subsystem extends ResourceImpl {
}
}
}
+ for (Clause bundle : Parser.parseClauses(this.bundles.toArray(new String[this.bundles.size()]))) {
+ final String loc = bundle.getName();
+ boolean dependency = Boolean.parseBoolean(bundle.getAttribute("dependency"));
+ boolean start = bundle.getAttribute("start") == null || Boolean.parseBoolean(bundle.getAttribute("start"));
+ int startLevel = 0;
+ try {
+ startLevel = Integer.parseInt(bundle.getAttribute("start-level"));
+ } catch (NumberFormatException e) {
+ // Ignore
+ }
+ if (dependency) {
+ addDependency(bundles.get(loc), false, start, startLevel);
+ } else {
+ doAddDependency(bundles.get(loc), true, start, startLevel);
+ addIdentityRequirement(this, bundles.get(loc));
+ }
+ }
// Compute dependencies
for (DependencyInfo info : dependencies.values()) {
installable.add(info.resource);
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/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 f8f7bca..5a92494 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
@@ -84,18 +84,17 @@ public class SubsystemResolver {
private RegionDigraph flatDigraph;
private Map<String, Map<String, BundleInfo>> bundleInfos;
-
public SubsystemResolver(DownloadManager manager) {
this.manager = manager;
}
public void prepare(
Collection<Feature> allFeatures,
- Map<String, Set<String>> features,
+ Map<String, Set<String>> requirements,
Map<String, Set<BundleRevision>> system
) throws Exception {
// Build subsystems on the fly
- for (Map.Entry<String, Set<String>> entry : features.entrySet()) {
+ for (Map.Entry<String, Set<String>> entry : requirements.entrySet()) {
String[] parts = entry.getKey().split("/");
if (root == null) {
root = new Subsystem(parts[0]);
@@ -106,18 +105,8 @@ public class SubsystemResolver {
for (int i = 1; i < parts.length; i++) {
ss = getOrCreateChild(ss, parts[i]);
}
- for (String feature : entry.getValue()) {
- String name;
- String range;
- int idx = feature.indexOf('/');
- if (idx >= 0) {
- name = feature.substring(0, idx);
- range = feature.substring(idx + 1);
- } else {
- name = feature;
- range = null;
- }
- ss.requireFeature(name, range);
+ for (String requirement : entry.getValue()) {
+ ss.require(requirement);
}
}
if (root == null) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/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 d3f5527..210c375 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
@@ -21,6 +21,8 @@ import java.util.List;
import java.util.Map;
import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.resource.Capability;
import org.osgi.resource.Resource;
@@ -115,4 +117,28 @@ public final class ResourceUtils {
}
}
+ public static String toFeatureRequirement(String feature) {
+ String[] parts = feature.split("/");
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put(IDENTITY_NAMESPACE, parts[0]);
+ attrs.put(CAPABILITY_TYPE_ATTRIBUTE, TYPE_FEATURE);
+ if (parts.length > 1) {
+ attrs.put(CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(parts[1]));
+ }
+ Map<String, String> dirs = new HashMap<>();
+ dirs.put(Constants.FILTER_DIRECTIVE, SimpleFilter.convert(attrs).toString());
+ return new RequirementImpl(null, IDENTITY_NAMESPACE, dirs, attrs).toString();
+ }
+
+ public static String toFeatureCapability(String feature) {
+ String[] parts = feature.split("/");
+ Map<String, String> dirs = new HashMap<>();
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put(IDENTITY_NAMESPACE, parts[0]);
+ attrs.put(CAPABILITY_TYPE_ATTRIBUTE, TYPE_FEATURE);
+ if (parts.length > 1) {
+ attrs.put(CAPABILITY_VERSION_ATTRIBUTE, VersionTable.getVersion(parts[1]));
+ }
+ return new CapabilityImpl(null, IDENTITY_NAMESPACE, dirs, attrs).toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/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 d80fe3d..4d289cb 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
@@ -148,7 +148,7 @@ public class Deployer {
String updateSnaphots;
Repository globalRepository;
- Map<String, Set<String>> requestedFeatures;
+ Map<String, Set<String>> requirements;
Map<String, Map<String, FeaturesService.RequestedState>> stateChanges;
EnumSet<FeaturesService.Option> options;
}
@@ -199,13 +199,10 @@ public class Deployer {
map(dstate.bundles));
// Resolve
- // TODO: requirements
- // TODO: bundles
-
SubsystemResolver resolver = new SubsystemResolver(manager);
resolver.prepare(
dstate.features.values(),
- request.requestedFeatures,
+ request.requirements,
apply(unmanagedBundles, adapt(BundleRevision.class))
);
Set<String> prereqs = resolver.collectPrerequisites();
@@ -242,9 +239,9 @@ public class Deployer {
newRequest.globalRepository = request.globalRepository;
newRequest.options = request.options;
newRequest.overrides = request.overrides;
- newRequest.requestedFeatures = copy(dstate.state.requestedFeatures);
+ newRequest.requirements = copy(dstate.state.requirements);
for (String prereq : prereqs) {
- addToMapSet(newRequest.requestedFeatures, ROOT_REGION, prereq);
+ addToMapSet(newRequest.requirements, ROOT_REGION, prereq);
}
newRequest.stateChanges = Collections.emptyMap();
newRequest.updateSnaphots = request.updateSnaphots;
@@ -671,6 +668,9 @@ public class Deployer {
callback.setBundleStartLevel(bundle, startLevel);
}
FeaturesService.RequestedState reqState = states.get(resource);
+ if (reqState == null) {
+ reqState = FeaturesService.RequestedState.Started;
+ }
switch (reqState) {
case Started:
toResolve.add(bundle);
@@ -689,7 +689,7 @@ public class Deployer {
//
State newState = new State();
newState.bundleChecksums.putAll(deployment.bundleChecksums);
- newState.requestedFeatures.putAll(request.requestedFeatures);
+ newState.requirements.putAll(request.requirements);
newState.installedFeatures.putAll(installedFeatures);
newState.stateFeatures.putAll(stateFeatures);
newState.managedBundles.putAll(managedBundles);
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/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 03686aa..ce01342 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
@@ -69,8 +69,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.karaf.features.internal.service.StateStorage.toStringStringSetMap;
+import static org.apache.karaf.features.internal.util.MapUtils.add;
import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet;
import static org.apache.karaf.features.internal.util.MapUtils.copy;
+import static org.apache.karaf.features.internal.util.MapUtils.remove;
/**
*
@@ -164,6 +166,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
}
+ @SuppressWarnings("unchecked")
private void checkResolve() {
if (bundle == null) {
return; // Most certainly in unit tests
@@ -190,7 +193,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
// Resolve
try {
Map<String, Map<String, RequestedState>> stateChanges = Collections.emptyMap();
- doInstallFeaturesInThread(requestedFeatures, stateChanges, copyState(), options);
+ doProvisionInThread(requestedFeatures, stateChanges, copyState(), options);
} catch (Exception e) {
LOGGER.warn("Error updating state", e);
}
@@ -206,7 +209,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
request.put("features", requestedFeatures);
request.put("options", opts);
try (
- FileOutputStream fos = new FileOutputStream(resolveFile);
+ FileOutputStream fos = new FileOutputStream(resolveFile)
) {
JsonWriter.write(fos, request);
}
@@ -599,9 +602,9 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
@Override
public boolean isRequired(Feature f) {
- String id = f.getName() + "/" + new VersionRange(f.getVersion(), true);
+ String id = "feature:" + f.getName() + "/" + new VersionRange(f.getVersion(), true);
synchronized (lock) {
- Set<String> features = state.requestedFeatures.get(ROOT_REGION);
+ Set<String> features = state.requirements.get(ROOT_REGION);
return features != null && features.contains(id);
}
}
@@ -678,7 +681,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
@Override
public void installFeatures(Set<String> features, String region, EnumSet<Option> options) throws Exception {
State state = copyState();
- Map<String, Set<String>> required = copy(state.requestedFeatures);
+ Map<String, Set<String>> required = copy(state.requirements);
if (region == null || region.isEmpty()) {
region = ROOT_REGION;
}
@@ -713,14 +716,16 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
fl = new HashSet<>();
required.put(region, fl);
}
- fl.addAll(featuresToAdd);
+ for (String feature : featuresToAdd) {
+ fl.add("feature:" + feature);
+ }
Map<String, Map<String, RequestedState>> stateChanges = Collections.emptyMap();
- doInstallFeaturesInThread(required, stateChanges, state, options);
+ doProvisionInThread(required, stateChanges, state, options);
}
public void uninstallFeatures(Set<String> features, String region, EnumSet<Option> options) throws Exception {
State state = copyState();
- Map<String, Set<String>> required = copy(state.requestedFeatures);
+ Map<String, Set<String>> required = copy(state.requirements);
if (region == null || region.isEmpty()) {
region = ROOT_REGION;
}
@@ -734,7 +739,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
List<String> toRemove = new ArrayList<>();
feature = normalize(feature);
if (feature.endsWith("/0.0.0")) {
- String nameSep = feature.substring(0, feature.indexOf("/") + 1);
+ String nameSep = "feature:" + feature.substring(0, feature.indexOf("/") + 1);
for (String f : fl) {
if (normalize(f).startsWith(nameSep)) {
toRemove.add(f);
@@ -743,7 +748,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
} else {
String name = feature.substring(0, feature.indexOf("/"));
String version = feature.substring(feature.indexOf("/") + 1);
- String req = name + "/" + new VersionRange(version, true);
+ String req = "feature:" + name + "/" + new VersionRange(version, true);
toRemove.add(req);
}
toRemove.retainAll(fl);
@@ -757,7 +762,9 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
if (i > 0) {
sb.append(", ");
}
- sb.append(toRemove.get(i));
+ String f = toRemove.get(i);
+ String version = f.substring(f.indexOf("/") + 1);
+ sb.append(version);
}
sb.append("). Please specify the version to uninstall.");
throw new IllegalArgumentException(sb.toString());
@@ -779,13 +786,38 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
required.remove(region);
}
Map<String, Map<String, RequestedState>> stateChanges = Collections.emptyMap();
- doInstallFeaturesInThread(required, stateChanges, state, options);
+ doProvisionInThread(required, stateChanges, state, options);
}
@Override
public void updateFeaturesState(Map<String, Map<String, RequestedState>> stateChanges, EnumSet<Option> options) throws Exception {
State state = copyState();
- doInstallFeaturesInThread(copy(state.requestedFeatures), stateChanges, state, options);
+ doProvisionInThread(copy(state.requirements), stateChanges, state, options);
+ }
+
+ @Override
+ public void addRequirements(Map<String, Set<String>> requirements, EnumSet<Option> options) throws Exception {
+ State state = copyState();
+ Map<String, Set<String>> required = copy(state.requirements);
+ add(required, requirements);
+ Map<String, Map<String, RequestedState>> stateChanges = Collections.emptyMap();
+ doProvisionInThread(required, stateChanges, state, options);
+ }
+
+ @Override
+ public void removeRequirements(Map<String, Set<String>> requirements, EnumSet<Option> options) throws Exception {
+ State state = copyState();
+ Map<String, Set<String>> required = copy(state.requirements);
+ remove(required, requirements);
+ Map<String, Map<String, RequestedState>> stateChanges = Collections.emptyMap();
+ doProvisionInThread(required, stateChanges, state, options);
+ }
+
+ @Override
+ public Map<String, Set<String>> listRequirements() {
+ synchronized (lock) {
+ return copy(this.state.requirements);
+ }
}
private State copyState() {
@@ -810,16 +842,16 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
* the command may be interrupted while waiting for the refresh to be done, leading
* to bundles not being started after the refresh.
*/
- public void doInstallFeaturesInThread(final Map<String, Set<String>> features,
- final Map<String, Map<String, RequestedState>> stateChanges,
- final State state,
- final EnumSet<Option> options) throws Exception {
+ public void doProvisionInThread(final Map<String, Set<String>> requirements,
+ final Map<String, Map<String, RequestedState>> stateChanges,
+ final State state,
+ final EnumSet<Option> options) throws Exception {
ExecutorService executor = Executors.newCachedThreadPool();
try {
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
- doInstallFeatures(features, stateChanges, state, options);
+ doProvision(requirements, stateChanges, state, options);
return null;
}
}).get();
@@ -888,13 +920,13 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
return dstate;
}
- private Deployer.DeploymentRequest getDeploymentRequest(Map<String, Set<String>> requestedFeatures, Map<String, Map<String, RequestedState>> stateChanges, EnumSet<Option> options) {
+ private Deployer.DeploymentRequest getDeploymentRequest(Map<String, Set<String>> requirements, Map<String, Map<String, RequestedState>> stateChanges, EnumSet<Option> options) {
Deployer.DeploymentRequest request = new Deployer.DeploymentRequest();
request.bundleUpdateRange = bundleUpdateRange;
request.featureResolutionRange = featureResolutionRange;
request.globalRepository = globalRepository;
request.overrides = Overrides.loadOverrides(overrides);
- request.requestedFeatures = requestedFeatures;
+ request.requirements = requirements;
request.stateChanges = stateChanges;
request.options = options;
return request;
@@ -902,17 +934,17 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
- public void doInstallFeatures(Map<String, Set<String>> requestedFeatures, // all request features
- Map<String, Map<String, RequestedState>> stateChanges, // features state changes
- State state, // current state
- EnumSet<Option> options // installation options
+ public void doProvision(Map<String, Set<String>> requirements, // all requirements
+ Map<String, Map<String, RequestedState>> stateChanges, // features state changes
+ State state, // current state
+ EnumSet<Option> options // installation options
) throws Exception {
Set<String> prereqs = new HashSet<>();
while (true) {
try {
Deployer.DeploymentState dstate = getDeploymentState(state);
- Deployer.DeploymentRequest request = getDeploymentRequest(requestedFeatures, stateChanges, options);
+ Deployer.DeploymentRequest request = getDeploymentRequest(requirements, stateChanges, options);
new Deployer(new SimpleDownloader(), this).deploy(dstate, request);
break;
} catch (Deployer.PartialDeploymentException e) {
@@ -961,7 +993,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
@Override
public void persistResolveRequest(Deployer.DeploymentRequest request) throws IOException {
- writeResolve(request.requestedFeatures, request.options);
+ writeResolve(request.requirements, request.options);
}
@Override
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
index b1a3ccd..a059b0b 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
@@ -28,7 +28,7 @@ public class State {
public final AtomicBoolean bootDone = new AtomicBoolean();
public final Set<String> repositories = new TreeSet<>();
- public final Map<String, Set<String>> requestedFeatures = new HashMap<>();
+ public final Map<String, Set<String>> requirements = new HashMap<>();
public final Map<String, Set<String>> installedFeatures = new HashMap<>();
public final Map<String, Map<String, String>> stateFeatures = new HashMap<>();
public final Map<String, Set<Long>> managedBundles = new HashMap<>();
@@ -47,7 +47,7 @@ public class State {
private static void copy(State from, State to, boolean clear) {
if (clear) {
to.repositories.clear();
- to.requestedFeatures.clear();
+ to.requirements.clear();
to.installedFeatures.clear();
to.stateFeatures.clear();
to.managedBundles.clear();
@@ -55,7 +55,7 @@ public class State {
}
to.bootDone.set(from.bootDone.get());
MapUtils.copy(from.repositories, to.repositories);
- MapUtils.copy(from.requestedFeatures, to.requestedFeatures);
+ MapUtils.copy(from.requirements, to.requirements);
MapUtils.copy(from.installedFeatures, to.installedFeatures);
MapUtils.copy(from.stateFeatures, to.stateFeatures);
MapUtils.copy(from.managedBundles, to.managedBundles);
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
index e085b65..20e0fcd 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
@@ -32,7 +32,7 @@ public abstract class StateStorage {
public void load(State state) throws IOException {
state.repositories.clear();
- state.requestedFeatures.clear();
+ state.requirements.clear();
state.installedFeatures.clear();
state.managedBundles.clear();
try (
@@ -42,7 +42,7 @@ public abstract class StateStorage {
Map json = (Map) JsonReader.read(is);
state.bootDone.set((Boolean) json.get("bootDone"));
state.repositories.addAll(toStringSet((Collection) json.get("repositories")));
- state.requestedFeatures.putAll(toStringStringSetMap((Map) json.get("features")));
+ state.requirements.putAll(toStringStringSetMap((Map) json.get("features")));
state.installedFeatures.putAll(toStringStringSetMap((Map) json.get("installed")));
state.stateFeatures.putAll(toStringStringStringMapMap((Map) json.get("state")));
state.managedBundles.putAll(toStringLongSetMap((Map) json.get("managed")));
@@ -59,7 +59,7 @@ public abstract class StateStorage {
Map<String, Object> json = new HashMap<>();
json.put("bootDone", state.bootDone.get());
json.put("repositories", state.repositories);
- json.put("features", state.requestedFeatures);
+ json.put("features", state.requirements);
json.put("installed", state.installedFeatures);
json.put("state", state.stateFeatures);
json.put("managed", state.managedBundles);
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
index e6b5b8f..11f9b0a 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
@@ -35,6 +35,8 @@ import org.osgi.resource.Capability;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
+import static org.apache.karaf.features.internal.resolver.ResourceUtils.toFeatureCapability;
+import static org.apache.karaf.features.internal.resolver.ResourceUtils.toFeatureRequirement;
import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet;
import static org.junit.Assert.assertEquals;
@@ -158,6 +160,28 @@ public class SubsystemTest {
verify(resolver, expected);
}
+ @Test
+ public void testBundle() throws Exception {
+ RepositoryImpl repo = new RepositoryImpl(getClass().getResource("data1/features.xml").toURI());
+
+ Map<String, Set<String>> features = new HashMap<String, Set<String>>();
+ addToMapSet(features, "root/apps1", "bundle:a");
+ addToMapSet(features, "root/apps1", "bundle:c;dependency=true");
+ Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
+ addToMapSet(expected, "root/apps1", "a/1.0.0");
+ addToMapSet(expected, "root/apps1", "c/1.0.0");
+
+ SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager(getClass(), "data1"));
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
+ features,
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.<String>emptySet(),
+ FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
+ null);
+
+ verify(resolver, expected);
+ }
+
private void verify(SubsystemResolver resolver, Map<String, Set<String>> expected) {
Map<String, Set<String>> mapping = getBundleNamesPerRegions(resolver);
if (!expected.equals(mapping)) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
index 723df3b..9478b67 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
@@ -22,7 +22,6 @@ import java.net.URL;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
@@ -101,8 +100,8 @@ public class DeployerTest {
request.overrides = Collections.emptySet();
request.stateChanges = Collections.emptyMap();
request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
- request.requestedFeatures = new HashMap<>();
- addToMapSet(request.requestedFeatures, ROOT_REGION, f100.getName() + "/" + new VersionRange(f100.getVersion(), true));
+ request.requirements = new HashMap<>();
+ addToMapSet(request.requirements, ROOT_REGION, f100.getName() + "/" + new VersionRange(f100.getVersion(), true));
deployer.deploy(dstate, request);
@@ -194,8 +193,8 @@ public class DeployerTest {
request.overrides = Collections.emptySet();
request.stateChanges = Collections.emptyMap();
request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
- request.requestedFeatures = new HashMap<>();
- addToMapSet(request.requestedFeatures, ROOT_REGION, f101.getName() + "/" + new VersionRange(f101.getVersion(), true));
+ request.requirements = new HashMap<>();
+ addToMapSet(request.requirements, ROOT_REGION, f101.getName() + "/" + new VersionRange(f101.getVersion(), true));
deployer.deploy(dstate, request);
@@ -252,8 +251,8 @@ public class DeployerTest {
request.overrides = Collections.emptySet();
request.stateChanges = Collections.emptyMap();
request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
- request.requestedFeatures = new HashMap<>();
- addToMapSet(request.requestedFeatures, ROOT_REGION, f1.getName());
+ request.requirements = new HashMap<>();
+ addToMapSet(request.requirements, ROOT_REGION, f1.getName());
deployer.deploy(dstate, request);
@@ -314,8 +313,8 @@ public class DeployerTest {
request.overrides = Collections.emptySet();
request.stateChanges = Collections.emptyMap();
request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
- request.requestedFeatures = new HashMap<>();
- addToMapSet(request.requestedFeatures, ROOT_REGION, f2.getName());
+ request.requirements = new HashMap<>();
+ addToMapSet(request.requirements, ROOT_REGION, f2.getName());
try {
deployer.deploy(dstate, request);
@@ -369,8 +368,8 @@ public class DeployerTest {
request.overrides = Collections.emptySet();
request.stateChanges = Collections.emptyMap();
request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
- request.requestedFeatures = new HashMap<>();
- addToMapSet(request.requestedFeatures, ROOT_REGION, f2.getName());
+ request.requirements = new HashMap<>();
+ addToMapSet(request.requirements, ROOT_REGION, f2.getName());
deployer.deploy(dstate, request);
http://git-wip-us.apache.org/repos/asf/karaf/blob/98123912/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
index 857936c..fbd819f 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
@@ -37,7 +37,7 @@ public class StateStorageTest {
State oldState = new State();
oldState.bootDone.set(true);
oldState.bundleChecksums.put(4l, 32794l);
- oldState.requestedFeatures.put("bar", Collections.singleton("f1"));
+ oldState.requirements.put("bar", Collections.singleton("f1"));
oldState.managedBundles.put("reg", Collections.singleton(32l));
oldState.managedBundles.put("reg2", new HashSet<Long>(Arrays.asList(24l, 43l)));
oldState.repositories.add("repo");
@@ -53,7 +53,7 @@ public class StateStorageTest {
assertEquals(oldState.bootDone.get(), newState.bootDone.get());
assertEquals(oldState.bundleChecksums, newState.bundleChecksums);
- assertEquals(oldState.requestedFeatures, newState.requestedFeatures);
+ assertEquals(oldState.requirements, newState.requirements);
assertEquals(oldState.managedBundles, newState.managedBundles);
assertEquals(oldState.repositories, newState.repositories);
}