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/09 15:25:34 UTC
[1/3] git commit: [KARAF-2888] Use single resolution to compute
feature conditionals, modelled with optional resources
Repository: karaf
Updated Branches:
refs/heads/master 678919692 -> 2b13959ee
[KARAF-2888] Use single resolution to compute feature conditionals, modelled with optional resources
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/de72fa9d
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/de72fa9d
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/de72fa9d
Branch: refs/heads/master
Commit: de72fa9dabfdcaf0df5e4b1715179df42f4ec6c8
Parents: 6789196
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 08:16:59 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Apr 9 12:12:15 2014 +0200
----------------------------------------------------------------------
.../internal/deployment/DeploymentBuilder.java | 15 ++++--
.../internal/resolver/FeatureResource.java | 48 ++++++++++++++------
.../internal/service/FeaturesServiceImpl.java | 42 -----------------
3 files changed, 44 insertions(+), 61 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/de72fa9d/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java b/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
index 022e56f..00a91c4 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
@@ -81,6 +81,7 @@ public class DeploymentBuilder {
Downloader downloader;
ResourceImpl requirements;
Map<String, Resource> resources;
+ Set<Resource> optionals;
Map<String, StreamProvider> providers;
Set<Feature> featuresToRegister = new HashSet<Feature>();
@@ -112,6 +113,7 @@ public class DeploymentBuilder {
Set<String> optionals)
throws IOException, MultiException, InterruptedException, ResolutionException, BundleException {
this.resources = new ConcurrentHashMap<String, Resource>();
+ this.optionals = new HashSet<Resource>();
this.providers = new ConcurrentHashMap<String, StreamProvider>();
this.requirements = new ResourceImpl("dummy", "dummy", Version.emptyVersion);
// First, gather all bundle resources
@@ -139,10 +141,13 @@ public class DeploymentBuilder {
for (Feature feature : featuresToRegister) {
Resource resource = FeatureResource.build(feature, featureRange, resources);
resources.put("feature:" + feature.getName() + "/" + feature.getVersion(), resource);
+ for (Conditional cond : feature.getConditional()) {
+ this.optionals.add(FeatureResource.build(feature, cond, featureRange, resources));
+ }
}
// Build requirements
for (String feature : features) {
- requireFeature(feature, requirements);
+ requireFeature(feature);
}
for (String bundle : bundles) {
requireResource(bundle);
@@ -167,14 +172,14 @@ public class DeploymentBuilder {
ResolverImpl resolver = new ResolverImpl(new Slf4jResolverLog(LOGGER));
ResolveContext context = new ResolveContextImpl(
Collections.<Resource>singleton(requirements),
- Collections.<Resource>emptySet(),
+ this.optionals,
new AggregateRepository(repos),
resolveOptionalImports);
return resolver.resolve(context);
}
- public void requireFeature(String feature, ResourceImpl resource) throws IOException {
+ public void requireFeature(String feature) throws IOException {
// Find name and version range
String[] split = feature.split("/");
String name = split[0].trim();
@@ -188,8 +193,8 @@ public class DeploymentBuilder {
attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, FeatureNamespace.TYPE_FEATURE);
attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, range);
- resource.addRequirement(
- new RequirementImpl(resource, IdentityNamespace.IDENTITY_NAMESPACE,
+ requirements.addRequirement(
+ new RequirementImpl(requirements, IdentityNamespace.IDENTITY_NAMESPACE,
Collections.<String, String>emptyMap(), attrs)
);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/de72fa9d/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 7d1671c..88f08ae 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
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.felix.utils.version.VersionRange;
import org.apache.felix.utils.version.VersionTable;
import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Conditional;
import org.apache.karaf.features.Dependency;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.internal.util.Macro;
@@ -40,6 +41,19 @@ public class FeatureResource extends ResourceImpl {
private final Feature feature;
+ public static Resource build(Feature feature, Conditional conditional, String featureRange, Map<String, Resource> locToRes) throws BundleException {
+ Feature fcond = conditional.asFeature(feature.getName(), feature.getVersion());
+ FeatureResource resource = (FeatureResource) build(fcond, featureRange, locToRes);
+ for (Dependency dep : conditional.getCondition()) {
+ addDependency(resource, dep, featureRange);
+ }
+ 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);
+ return resource;
+ }
+
public static Resource build(Feature feature, String featureRange, Map<String, Resource> locToRes) throws BundleException {
FeatureResource resource = new FeatureResource(feature);
Map<String, String> dirs = new HashMap<String, String>();
@@ -66,20 +80,7 @@ public class FeatureResource extends ResourceImpl {
}
}
for (Dependency dep : feature.getDependencies()) {
- String name = dep.getName();
- String version = dep.getVersion();
- if (version.equals("0.0.0")) {
- version = null;
- } else if (!version.startsWith("[") && !version.startsWith("(")) {
- version = Macro.transform(featureRange, version);
- }
- dirs = new HashMap<String, String>();
- attrs = new HashMap<String, Object>();
- attrs.put(FeatureNamespace.FEATURE_NAMESPACE, name);
- if (version != null) {
- attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(version));
- }
- resource.addRequirement(new RequirementImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs));
+ addDependency(resource, dep, featureRange);
}
for (org.apache.karaf.features.Capability cap : feature.getCapabilities()) {
resource.addCapabilities(ResourceBuilder.parseCapability(resource, cap.getValue()));
@@ -90,6 +91,25 @@ public class FeatureResource extends ResourceImpl {
return resource;
}
+ protected static void addDependency(FeatureResource resource, Dependency dep, String featureRange) {
+ Map<String, String> dirs;
+ Map<String, Object> attrs;
+ String name = dep.getName();
+ String version = dep.getVersion();
+ if (version.equals("0.0.0")) {
+ version = null;
+ } else if (!version.startsWith("[") && !version.startsWith("(")) {
+ version = Macro.transform(featureRange, version);
+ }
+ dirs = new HashMap<String, String>();
+ attrs = new HashMap<String, Object>();
+ attrs.put(FeatureNamespace.FEATURE_NAMESPACE, name);
+ if (version != null) {
+ attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(version));
+ }
+ resource.addRequirement(new RequirementImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs));
+ }
+
public FeatureResource(Feature feature) {
super(feature.getName(), FeatureNamespace.TYPE_FEATURE, VersionTable.getVersion(feature.getVersion()));
this.feature = feature;
http://git-wip-us.apache.org/repos/asf/karaf/blob/de72fa9d/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 a42e133..8766c91 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
@@ -737,48 +737,6 @@ public class FeaturesServiceImpl implements FeaturesService {
List<String> installedFeatureIds = getFeatureIds(allResources);
List<Feature> installedFeatures = getFeatures(repositories, installedFeatureIds);
- // TODO: is there are a way to use fragments or on-demand resources
- // TODO: in the resolver to use a single resolution ?
- boolean resolveAgain = false;
- Set<String> featuresAndConditionals = new TreeSet<String>(features);
- for (Feature feature : installedFeatures) {
- for (Conditional cond : feature.getConditional()) {
- boolean condSatisfied = true;
- for (Dependency dep : cond.getCondition()) {
- boolean depSatisfied = false;
- String name = dep.getName();
- VersionRange range = new VersionRange(dep.getVersion(), false, true);
- for (Feature f : installedFeatures) {
- if (f.getName().equals(name)) {
- if (range.contains(VersionTable.getVersion(f.getVersion()))) {
- depSatisfied = true;
- break;
- }
- }
- }
- if (!depSatisfied) {
- condSatisfied = false;
- break;
- }
- }
- if (condSatisfied) {
- featuresAndConditionals.add(cond.asFeature(feature.getName(), feature.getVersion()).getId());
- resolveAgain = true;
- }
- }
- }
- if (resolveAgain) {
- builder.download(featuresAndConditionals,
- Collections.<String>emptySet(),
- Collections.<String>emptySet(),
- overrides,
- Collections.<String>emptySet());
- resolution = builder.resolve(systemBundles, false);
- allResources = resolution.keySet();
- providers = builder.getProviders();
- }
-
-
//
// Compute list of installable resources (those with uris)
//
[3/3] git commit: [KARAF-2888] Add a simulation option
Posted by gn...@apache.org.
[KARAF-2888] Add a simulation option
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/2b13959e
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/2b13959e
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/2b13959e
Branch: refs/heads/master
Commit: 2b13959eeae1512dd5de8b4e083239130c89df39
Parents: b348022
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 15:23:05 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Apr 9 15:23:29 2014 +0200
----------------------------------------------------------------------
.../features/command/InstallFeatureCommand.java | 5 +++++
.../command/UninstallFeatureCommand.java | 6 ++++++
.../apache/karaf/features/FeaturesService.java | 1 +
.../internal/service/FeaturesServiceImpl.java | 22 ++++++++++++--------
4 files changed, 25 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b13959e/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 b73dd3f..675d0fe 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,8 @@ public class InstallFeatureCommand extends FeaturesCommandSupport {
boolean noStart;
@Option(name = "-v", aliases = "--verbose", description = "Explain what is being done", required = false, multiValued = false)
boolean verbose;
+ @Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only", required = false, multiValued = false)
+ boolean simulate;
protected void doExecute(FeaturesService admin) throws Exception {
for (String feature : features) {
@@ -57,6 +59,9 @@ public class InstallFeatureCommand extends FeaturesCommandSupport {
version = DEFAULT_VERSION;
}
EnumSet<FeaturesService.Option> options = EnumSet.of(FeaturesService.Option.PrintBundlesToRefresh);
+ if (simulate) {
+ options.add(FeaturesService.Option.Simulate);
+ }
if (noStart) {
options.add(FeaturesService.Option.NoAutoStartBundles);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b13959e/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
index b56eac6..14d6be2 100644
--- a/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
+++ b/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
@@ -41,9 +41,15 @@ public class UninstallFeatureCommand extends FeaturesCommandSupport {
@Option(name = "-v", aliases = "--verbose", description = "Explain what is being done", required = false, multiValued = false)
boolean verbose;
+ @Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only", required = false, multiValued = false)
+ boolean simulate;
+
protected void doExecute(FeaturesService admin) throws Exception {
// iterate in the provided feature
EnumSet<FeaturesService.Option> options = EnumSet.noneOf(FeaturesService.Option.class);
+ if (simulate) {
+ options.add(FeaturesService.Option.Simulate);
+ }
if (noRefresh) {
options.add(FeaturesService.Option.NoAutoRefreshBundles);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b13959e/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 289303c..7855ca4 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
@@ -33,6 +33,7 @@ public interface FeaturesService {
NoAutoRefreshBundles,
NoAutoStartBundles,
ContinueBatchOnFailure,
+ Simulate,
Verbose
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b13959e/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 85a25dd..add1034 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
@@ -735,6 +735,7 @@ public class FeaturesServiceImpl implements FeaturesService {
boolean noRefresh = options.contains(Option.NoAutoRefreshBundles);
boolean noStart = options.contains(Option.NoAutoStartBundles);
boolean verbose = options.contains(Option.Verbose);
+ boolean simulate = options.contains(Option.Simulate);
// Get a list of resolved and unmanaged bundles to use as capabilities during resolution
List<Resource> systemBundles = new ArrayList<Resource>();
@@ -818,8 +819,11 @@ public class FeaturesServiceImpl implements FeaturesService {
//
// Log deployment
//
- logDeployment(deployment);
+ logDeployment(deployment, verbose);
+ if (simulate) {
+ return;
+ }
Set<Bundle> toRefresh = new HashSet<Bundle>();
Set<Bundle> toStart = new HashSet<Bundle>();
@@ -1054,24 +1058,24 @@ public class FeaturesServiceImpl implements FeaturesService {
}
}
- protected void logDeployment(Deployment deployment) {
- LOGGER.info("Changes to perform:");
+ protected void logDeployment(Deployment deployment, boolean verbose) {
+ print("Changes to perform:", verbose);
if (!deployment.toDelete.isEmpty()) {
- LOGGER.info(" Bundles to uninstall:");
+ print(" Bundles to uninstall:", verbose);
for (Bundle bundle : deployment.toDelete) {
- LOGGER.info(" " + bundle.getSymbolicName() + " / " + bundle.getVersion());
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
}
}
if (!deployment.toUpdate.isEmpty()) {
- LOGGER.info(" Bundles to update:");
+ print(" Bundles to update:", verbose);
for (Map.Entry<Bundle, Resource> entry : deployment.toUpdate.entrySet()) {
- LOGGER.info(" " + entry.getKey().getSymbolicName() + " / " + entry.getKey().getVersion() + " with " + UriNamespace.getUri(entry.getValue()));
+ print(" " + entry.getKey().getSymbolicName() + " / " + entry.getKey().getVersion() + " with " + UriNamespace.getUri(entry.getValue()), verbose);
}
}
if (!deployment.toInstall.isEmpty()) {
- LOGGER.info(" Bundles to install:");
+ print(" Bundles to install:", verbose);
for (Resource resource : deployment.toInstall) {
- LOGGER.info(" " + UriNamespace.getUri(resource));
+ print(" " + UriNamespace.getUri(resource), verbose);
}
}
}
[2/3] git commit: [KARAF-2888] Fix configuration options to actually
make them configurable
Posted by gn...@apache.org.
[KARAF-2888] Fix configuration options to actually make them configurable
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b3480226
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b3480226
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b3480226
Branch: refs/heads/master
Commit: b3480226941deeaf89eb7df1c392f9f0ad21e10c
Parents: de72fa9
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 14:20:16 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Apr 9 14:20:16 2014 +0200
----------------------------------------------------------------------
.../apache/karaf/features/FeaturesService.java | 2 +
.../karaf/features/internal/osgi/Activator.java | 17 ++-
.../internal/service/FeaturesServiceImpl.java | 131 ++++++++++++-------
.../karaf/features/FeaturesServiceTest.java | 8 +-
.../service/FeaturesServiceImplTest.java | 8 +-
.../karaf/itests/ConditionalFeaturesTest.java | 17 ++-
.../apache/karaf/itests/KarafTestSupport.java | 10 +-
7 files changed, 123 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/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 a62c684..289303c 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
@@ -28,6 +28,8 @@ public interface FeaturesService {
enum Option {
NoCleanIfFailure,
PrintBundlesToRefresh,
+ NoAutoRefreshManagedBundles,
+ NoAutoRefreshUnmanagedBundles,
NoAutoRefreshBundles,
NoAutoStartBundles,
ContinueBatchOnFailure,
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
index d51e5d5..be0da05 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
@@ -49,6 +49,9 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
public class Activator extends BaseActivator {
+ public static final String FEATURES_REPOS_PID = "org.apache.karaf.features.repos";
+ public static final String FEATURES_SERVICE_CONFIG_FILE = "org.apache.karaf.features.cfg";
+
private ServiceTracker<FeaturesListener, FeaturesListener> featuresListenerTracker;
private FeaturesServiceImpl featuresService;
private SingleServiceTracker<RegionsPersistence> regionsTracker;
@@ -65,7 +68,7 @@ public class Activator extends BaseActivator {
trackService(ConfigurationAdmin.class);
Properties configuration = new Properties();
- File configFile = new File(System.getProperty("karaf.etc"), "org.apache.karaf.features.cfg");
+ File configFile = new File(System.getProperty("karaf.etc"), FEATURES_SERVICE_CONFIG_FILE);
if (configFile.isFile() && configFile.canRead()) {
try {
configuration.load(new FileReader(configFile));
@@ -86,7 +89,7 @@ public class Activator extends BaseActivator {
FeatureFinder featureFinder = new FeatureFinder();
Hashtable<String, Object> props = new Hashtable<String, Object>();
- props.put(Constants.SERVICE_PID, "org.apache.karaf.features.repos");
+ props.put(Constants.SERVICE_PID, FEATURES_REPOS_PID);
register(ManagedService.class, featureFinder, props);
// TODO: region support
@@ -113,7 +116,10 @@ public class Activator extends BaseActivator {
// TODO: honor respectStartLvlDuringFeatureStartup and respectStartLvlDuringFeatureUninstall
// boolean respectStartLvlDuringFeatureStartup = getBoolean("respectStartLvlDuringFeatureStartup", true);
// boolean respectStartLvlDuringFeatureUninstall = getBoolean("respectStartLvlDuringFeatureUninstall", true);
- String overrides = getString("overrides", new File(System.getProperty("karaf.etc"), "overrides.properties").toString());
+ String overrides = getString("overrides", new File(System.getProperty("karaf.etc"), "overrides.properties").toURI().toString());
+ String featureResolutionRange = getString("featureResolutionRange", FeaturesServiceImpl.DEFAULT_FEATURE_RESOLUTION_RANGE);
+ String bundleUpdateRange = getString("bundleUpdateRange", FeaturesServiceImpl.DEFAULT_BUNDLE_UPDATE_RANGE);
+ String updateSnapshots = getString("updateSnapshots", FeaturesServiceImpl.DEFAULT_UPDATE_SNAPSHOTS);
StateStorage stateStorage = new StateStorage() {
@Override
protected InputStream getInputStream() throws IOException {
@@ -144,7 +150,10 @@ public class Activator extends BaseActivator {
featureFinder,
eventAdminListener,
configInstaller,
- overrides);
+ overrides,
+ featureResolutionRange,
+ bundleUpdateRange,
+ updateSnapshots);
register(FeaturesService.class, featuresService);
featuresListenerTracker = new ServiceTracker<FeaturesListener, FeaturesListener>(
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/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 8766c91..85a25dd 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
@@ -42,8 +42,6 @@ import java.util.concurrent.Executors;
import org.apache.felix.utils.version.VersionRange;
import org.apache.felix.utils.version.VersionTable;
import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.Conditional;
-import org.apache.karaf.features.Dependency;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeatureEvent;
import org.apache.karaf.features.FeaturesListener;
@@ -85,17 +83,57 @@ import static org.apache.felix.resolver.Util.getVersion;
*/
public class FeaturesServiceImpl implements FeaturesService {
+ public static final String UPDATE_SNAPSHOTS_NONE = "none";
+ public static final String UPDATE_SNAPSHOTS_CRC = "crc";
+ public static final String UPDATE_SNAPSHOTS_ALWAYS = "always";
+ public static final String DEFAULT_UPDATE_SNAPSHOTS = UPDATE_SNAPSHOTS_CRC;
+
private static final Logger LOGGER = LoggerFactory.getLogger(FeaturesServiceImpl.class);
private static final String SNAPSHOT = "SNAPSHOT";
private static final String MAVEN = "mvn:";
+ /**
+ * Our bundle.
+ * We use it to check bundle operations affecting our own bundle.
+ */
private final Bundle bundle;
+
+ /**
+ * The system bundle context.
+ * For all bundles related operations, we use the system bundle context
+ * to allow this bundle to be stopped and still allow the deployment to
+ * take place.
+ */
private final BundleContext systemBundleContext;
+ /**
+ * Used to load and save the {@link State} of this service.
+ */
private final StateStorage storage;
private final FeatureFinder featureFinder;
private final EventAdminListener eventAdminListener;
private final FeatureConfigInstaller configInstaller;
private final String overrides;
+ public static final String DEFAULT_FEATURE_RESOLUTION_RANGE = "${range;[====,====]}";
+ /**
+ * Range to use when a version is specified on a feature dependency.
+ * The default is {@link FeaturesServiceImpl#DEFAULT_FEATURE_RESOLUTION_RANGE}
+ */
+ private final String featureResolutionRange;
+ public static final String DEFAULT_BUNDLE_UPDATE_RANGE = "${range;[==,=+)}";
+ /**
+ * Range to use when verifying if a bundle should be updated or
+ * new bundle installed.
+ * The default is {@link FeaturesServiceImpl#DEFAULT_BUNDLE_UPDATE_RANGE}
+ */
+ private final String bundleUpdateRange;
+ /**
+ * Use CRC to check snapshot bundles and update them if changed.
+ * Either:
+ * - none : never update snapshots
+ * - always : always update snapshots
+ * - crc : use CRC to detect changes
+ */
+ private final String updateSnaphots;
private final List<FeaturesListener> listeners = new CopyOnWriteArrayIdentityList<FeaturesListener>();
@@ -106,14 +144,16 @@ public class FeaturesServiceImpl implements FeaturesService {
private Map<String, Map<String, Feature>> featureCache;
-
public FeaturesServiceImpl(Bundle bundle,
BundleContext systemBundleContext,
StateStorage storage,
FeatureFinder featureFinder,
EventAdminListener eventAdminListener,
FeatureConfigInstaller configInstaller,
- String overrides) {
+ String overrides,
+ String featureResolutionRange,
+ String bundleUpdateRange,
+ String updateSnaphots) {
this.bundle = bundle;
this.systemBundleContext = systemBundleContext;
this.storage = storage;
@@ -121,6 +161,9 @@ public class FeaturesServiceImpl implements FeaturesService {
this.eventAdminListener = eventAdminListener;
this.configInstaller = configInstaller;
this.overrides = overrides;
+ this.featureResolutionRange = featureResolutionRange;
+ this.bundleUpdateRange = bundleUpdateRange;
+ this.updateSnaphots = updateSnaphots;
loadState();
}
@@ -141,6 +184,12 @@ public class FeaturesServiceImpl implements FeaturesService {
protected void saveState() {
try {
synchronized (lock) {
+ // Make sure we don't store bundle checksums if
+ // it has been disabled through configadmin
+ // so that we don't keep out-of-date checksums.
+ if (!UPDATE_SNAPSHOTS_CRC.equalsIgnoreCase(updateSnaphots)) {
+ state.bundleChecksums.clear();
+ }
storage.save(state);
}
} catch (IOException e) {
@@ -680,31 +729,11 @@ public class FeaturesServiceImpl implements FeaturesService {
Set<Long> managed, // currently managed bundles
EnumSet<Option> options // installation options
) throws Exception {
- // TODO: make this configurable through ConfigAdmin
- // TODO: this needs to be tested a bit
- // TODO: note that this only applies to managed and updateable bundles
- boolean updateSnaphots = true;
-
- // TODO: make this configurable at runtime
- // TODO: note that integration tests will fail if set to false
- // TODO: but I think it should be the default anyway
- boolean noRefreshUnmanaged = true;
-
- // TODO: make this configurable at runtime
- boolean noRefreshManaged = true;
-
- // TODO: make this configurable at runtime
- boolean noRefresh = false;
+ boolean noRefreshUnmanaged = options.contains(Option.NoAutoRefreshUnmanagedBundles);
+ boolean noRefreshManaged = options.contains(Option.NoAutoRefreshManagedBundles);
+ boolean noRefresh = options.contains(Option.NoAutoRefreshBundles);
boolean noStart = options.contains(Option.NoAutoStartBundles);
-
- // TODO: make this configurable through ConfigAdmin
- // TODO: though opening it as some important effects
- String featureResolutionRange = "${range;[====,====]}";
-
- // TODO: make this configurable through ConfigAdmin
- String bundleUpdateRange = "${range;[==,=+)}";
-
boolean verbose = options.contains(Option.Verbose);
// Get a list of resolved and unmanaged bundles to use as capabilities during resolution
@@ -778,7 +807,7 @@ public class FeaturesServiceImpl implements FeaturesService {
synchronized (lock) {
bundleChecksums.putAll(state.bundleChecksums);
}
- Deployment deployment = computeDeployment(managed, updateSnaphots, bundles, providers, resources, bundleChecksums, bundleUpdateRange);
+ Deployment deployment = computeDeployment(managed, bundles, providers, resources, bundleChecksums);
if (deployment.toDelete.isEmpty() &&
deployment.toUpdate.isEmpty() &&
@@ -869,7 +898,8 @@ public class FeaturesServiceImpl implements FeaturesService {
}
deployment.resToBnd.put(resource, bundle);
// save a checksum of installed snapshot bundle
- if (isUpdateable(resource) && !deployment.newCheckums.containsKey(bundle.getLocation())) {
+ if (UPDATE_SNAPSHOTS_CRC.equals(updateSnaphots)
+ && isUpdateable(resource) && !deployment.newCheckums.containsKey(bundle.getLocation())) {
deployment.newCheckums.put(bundle.getLocation(), ChecksumUtils.checksum(getBundleInputStream(resource, providers)));
}
BundleInfo bi = bundleInfos.get(uri);
@@ -989,6 +1019,8 @@ public class FeaturesServiceImpl implements FeaturesService {
}
}
+ // TODO: call listeners for features added and removed
+
print("Done.", verbose);
}
@@ -1046,12 +1078,10 @@ public class FeaturesServiceImpl implements FeaturesService {
protected Deployment computeDeployment(
Set<Long> managed,
- boolean updateSnaphots,
Bundle[] bundles,
Map<String, StreamProvider> providers,
List<Resource> resources,
- Map<String, Long> bundleChecksums,
- String bundleUpdateRange) throws IOException {
+ Map<String, Long> bundleChecksums) throws IOException {
Deployment deployment = new Deployment();
// TODO: regions
@@ -1074,21 +1104,28 @@ public class FeaturesServiceImpl implements FeaturesService {
if (resource != null) {
// In case of snapshots, check if the snapshot is out of date
// and flag it as to update
- if (updateSnaphots && managed.contains(bundle.getBundleId()) && isUpdateable(resource)) {
- // if the checksum are different
- InputStream is = null;
- try {
- is = getBundleInputStream(resource, providers);
- long newCrc = ChecksumUtils.checksum(is);
- long oldCrc = bundleChecksums.containsKey(bundle.getLocation()) ? bundleChecksums.get(bundle.getLocation()) : 0l;
- if (newCrc != oldCrc) {
- LOGGER.debug("New snapshot available for " + bundle.getLocation());
- deployment.toUpdate.put(bundle, resource);
- deployment.newCheckums.put(bundle.getLocation(), newCrc);
- }
- } finally {
- if (is != null) {
- is.close();
+ if (managed.contains(bundle.getBundleId()) && isUpdateable(resource)) {
+ // Always update snapshots
+ if (UPDATE_SNAPSHOTS_ALWAYS.equalsIgnoreCase(updateSnaphots)) {
+ LOGGER.debug("Update snapshot for " + bundle.getLocation());
+ deployment.toUpdate.put(bundle, resource);
+ }
+ else if (UPDATE_SNAPSHOTS_CRC.equalsIgnoreCase(updateSnaphots)) {
+ // if the checksum are different
+ InputStream is = null;
+ try {
+ is = getBundleInputStream(resource, providers);
+ long newCrc = ChecksumUtils.checksum(is);
+ long oldCrc = bundleChecksums.containsKey(bundle.getLocation()) ? bundleChecksums.get(bundle.getLocation()) : 0l;
+ if (newCrc != oldCrc) {
+ LOGGER.debug("New snapshot available for " + bundle.getLocation());
+ deployment.toUpdate.put(bundle, resource);
+ deployment.newCheckums.put(bundle.getLocation(), newCrc);
+ }
+ } finally {
+ if (is != null) {
+ is.close();
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
index db7a4fc..8a7c9b9 100644
--- a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
@@ -345,7 +345,7 @@ public class FeaturesServiceTest extends TestBase {
+ " <feature name='f2' version='0.2'><bundle>bundle2</bundle></feature>"
+ "</features>");
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
svc.addRepository(uri);
assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "[0.1,0.3)"));
@@ -365,7 +365,7 @@ public class FeaturesServiceTest extends TestBase {
expect(bundleContext.getBundles()).andReturn(new Bundle[0]);
replay(bundleContext);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, bundleContext, new Storage(), null, null, null, null);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, bundleContext, new Storage(), null, null, null, null, null, null, null);
svc.addRepository(uri);
try {
List<Feature> features = Arrays.asList(svc.listFeatures());
@@ -386,7 +386,7 @@ public class FeaturesServiceTest extends TestBase {
URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ " <featur><bundle>somebundle</bundle></featur></features>");
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
try {
svc.addRepository(uri);
fail("exception expected");
@@ -404,7 +404,7 @@ public class FeaturesServiceTest extends TestBase {
+ " <feature name='f1'><bundle>file:bundle1</bundle><bundle>file:bundle2</bundle></feature>"
+ "</features>");
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
svc.addRepository(uri);
Feature feature = svc.getFeature("f1");
Assert.assertNotNull("No feature named fi found", feature);
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
index 8339151..b8b5fc0 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
@@ -49,7 +49,7 @@ public class FeaturesServiceImplTest extends TestBase {
public void testGetFeature() throws Exception {
Feature transactionFeature = feature("transaction", "1.0.0");
final Map<String, Map<String, Feature>> features = features(transactionFeature);
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "") {
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
return features;
}
@@ -60,7 +60,7 @@ public class FeaturesServiceImplTest extends TestBase {
@Test
public void testGetFeatureStripVersion() throws Exception {
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "") {
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
return features(feature("transaction", "1.0.0"));
}
@@ -72,7 +72,7 @@ public class FeaturesServiceImplTest extends TestBase {
@Test
public void testGetFeatureNotAvailable() throws Exception {
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "") {
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
return features(feature("transaction", "1.0.0"));
}
@@ -86,7 +86,7 @@ public class FeaturesServiceImplTest extends TestBase {
feature("transaction", "1.0.0"),
feature("transaction", "2.0.0")
);
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "") {
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
return features;
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java b/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
index 9045b82..1d353bd 100644
--- a/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
+++ b/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
@@ -17,6 +17,9 @@
package org.apache.karaf.itests;
+import java.util.EnumSet;
+
+import org.apache.karaf.features.FeaturesService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.PaxExam;
@@ -58,22 +61,22 @@ public class ConditionalFeaturesTest extends KarafTestSupport {
@Test
public void testScr() throws Exception {
//Remove management and install scr
- featureService.uninstallFeature("management");
- featureService.installFeature("scr");
+ featureService.uninstallFeature("management", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
+ featureService.installFeature("scr", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertBundleNotInstalled("org.apache.karaf.scr.management");
//Add management back
- featureService.installFeature("management");
+ featureService.installFeature("management", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertBundleInstalled("org.apache.karaf.scr.management");
}
@Test
public void testWebconsole() throws Exception {
try {
- featureService.uninstallFeature("scr");
+ featureService.uninstallFeature("scr", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
} catch (Exception e) {
}
- featureService.installFeature("webconsole");
+ featureService.installFeature("webconsole", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertBundleInstalled("org.apache.karaf.webconsole.features");
assertBundleInstalled("org.apache.karaf.webconsole.instance");
@@ -84,14 +87,14 @@ public class ConditionalFeaturesTest extends KarafTestSupport {
//Add eventadmin
try {
- featureService.installFeature("eventadmin");
+ featureService.installFeature("eventadmin", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
} catch (Exception ex) {
//ignore as the eventadmin activator might throw an error.
}
assertBundleInstalled("org.apache.felix.webconsole.plugins.event");
//Remove eventadmin
- featureService.uninstallFeature("eventadmin");
+ featureService.uninstallFeature("eventadmin", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertBundleNotInstalled("org.apache.felix.webconsole.plugins.event");
}
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b3480226/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java b/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
index 207d75a..c06c043 100644
--- a/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
+++ b/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
@@ -34,6 +34,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
+import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
@@ -411,7 +412,7 @@ public class KarafTestSupport {
}
protected void installAndAssertFeature(String feature) throws Exception {
- featureService.installFeature(feature);
+ featureService.installFeature(feature, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertFeatureInstalled(feature);
}
@@ -423,7 +424,7 @@ public class KarafTestSupport {
boolean success = false;
try {
for (String curFeature : feature) {
- featureService.installFeature(curFeature);
+ featureService.installFeature(curFeature, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertFeatureInstalled(curFeature);
}
success = true;
@@ -431,7 +432,7 @@ public class KarafTestSupport {
for (String curFeature : feature) {
System.out.println("Uninstalling " + curFeature);
try {
- featureService.uninstallFeature(curFeature);
+ featureService.uninstallFeature(curFeature, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
} catch (Exception e) {
if (success) {
throw e;
@@ -455,7 +456,8 @@ public class KarafTestSupport {
if (!featuresBefore.contains(curFeature)) {
try {
System.out.println("Uninstalling " + curFeature.getName());
- featureService.uninstallFeature(curFeature.getName(), curFeature.getVersion());
+ featureService.uninstallFeature(curFeature.getName(), curFeature.getVersion(),
+ EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}