You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2019/05/23 09:29:20 UTC
[karaf] branch master updated: [KARAF-2894] Add option to delete
configurations/configuration files while uninstalling feature
This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/master by this push:
new 2d3c15e [KARAF-2894] Add option to delete configurations/configuration files while uninstalling feature
new 54505d8 Merge pull request #849 from jbonofre/KARAF-2894
2d3c15e is described below
commit 2d3c15ea30222776d092edf138ac540e4115a55a
Author: Jean-Baptiste Onofré <jb...@apache.org>
AuthorDate: Tue May 21 14:53:12 2019 +0200
[KARAF-2894] Add option to delete configurations/configuration files while uninstalling feature
---
.../apache/karaf/config/command/ExistsCommand.java | 42 ++++++++++++++
.../org/apache/karaf/config/core/ConfigMBean.java | 9 +++
.../apache/karaf/config/core/ConfigRepository.java | 2 +
.../karaf/config/core/impl/ConfigMBeanImpl.java | 9 +++
.../config/core/impl/ConfigRepositoryImpl.java | 9 +++
.../features/command/UninstallFeatureCommand.java | 4 ++
.../org/apache/karaf/features/FeaturesService.java | 3 +-
.../management/FeaturesServiceMBeanImpl.java | 41 +++++++++++--
.../internal/service/BundleInstallSupport.java | 2 +
.../internal/service/BundleInstallSupportImpl.java | 7 +++
.../karaf/features/internal/service/Deployer.java | 42 ++++++++++++++
.../internal/service/FeatureConfigInstaller.java | 30 ++++++++++
.../internal/service/FeaturesServiceImpl.java | 5 ++
.../features/management/FeaturesServiceMBean.java | 4 ++
.../features/internal/service/DeployerTest.java | 5 ++
.../java/org/apache/karaf/itests/FeatureTest.java | 67 ++++++++++++++++++++++
.../profile/assembly/AssemblyDeployCallback.java | 6 ++
.../java/org/apache/karaf/tooling/VerifyMojo.java | 7 ++-
18 files changed, 286 insertions(+), 8 deletions(-)
diff --git a/config/src/main/java/org/apache/karaf/config/command/ExistsCommand.java b/config/src/main/java/org/apache/karaf/config/command/ExistsCommand.java
new file mode 100644
index 0000000..a1032da
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/ExistsCommand.java
@@ -0,0 +1,42 @@
+/*
+ * 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.config.command;
+
+import org.apache.karaf.config.command.completers.ConfigurationCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "config", name = "exists", description = "Check if a configuration exists.")
+@Service
+public class ExistsCommand extends ConfigCommandSupport {
+
+ @Argument(index = 0, name = "pid", description = "PID of the configuration", required = true, multiValued = false)
+ @Completion(ConfigurationCompleter.class)
+ String pid;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ if (configRepository.exists(pid)) {
+ return Boolean.TRUE;
+ } else {
+ return Boolean.FALSE;
+ }
+ }
+
+}
diff --git a/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java b/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
index 283f677..6ae174b 100644
--- a/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
+++ b/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
@@ -57,6 +57,15 @@ public interface ConfigMBean {
void delete(String pid) throws MBeanException;
/**
+ * Check if a configuration identified by the given PID exists.
+ *
+ * @param pid The configuration PID to check.
+ * @return true if the configuration exists, false else.
+ * @throws MBeanException in case of MBean failure.
+ */
+ boolean exists(String pid) throws MBeanException;
+
+ /**
* Get the list of properties for a configuration PID.
*
* @param pid the configuration PID.
diff --git a/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java b/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
index 556cc17..36dd59a 100644
--- a/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
+++ b/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
@@ -31,6 +31,8 @@ public interface ConfigRepository {
void delete(String pid) throws Exception;
+ boolean exists(String pid) throws Exception;
+
void update(String pid, Map<String, Object> properties) throws IOException;
String createFactoryConfiguration(String factoryPid, Map<String, Object> properties) throws IOException;
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
index cdd2f3c..ec37598 100644
--- a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
@@ -125,6 +125,15 @@ public class ConfigMBeanImpl extends StandardMBean implements ConfigMBean {
}
@Override
+ public boolean exists(String pid) throws MBeanException {
+ try {
+ return this.configRepo.exists(pid);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.toString());
+ }
+ }
+
+ @Override
@SuppressWarnings("rawtypes")
public Map<String, String> listProperties(String pid) throws MBeanException {
try {
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
index 04757bb..1643daf 100644
--- a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
@@ -92,6 +92,15 @@ public class ConfigRepositoryImpl implements ConfigRepository {
configuration.delete();
}
+ @Override
+ public boolean exists(String pid) throws Exception {
+ Configuration[] configurations = configAdmin.listConfigurations("(service.pid=" + pid + ")");
+ if (configurations == null || configurations.length == 0) {
+ return false;
+ }
+ return true;
+ }
+
private File getCfgFileFromProperties(Dictionary<String, Object> properties) throws URISyntaxException, MalformedURLException {
if (properties != null) {
Object val = properties.get(FILEINSTALL_FILE_NAME);
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 5ce3a03..2cbcd48 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
@@ -47,10 +47,14 @@ public class UninstallFeatureCommand extends FeaturesCommandSupport {
@Option(name = "-g", aliases = "--region", description = "Region to install to")
String region;
+ @Option(name = "-c", aliases = "--delete-configurations", description = "Delete configurations", required = false, multiValued = false)
+ boolean deleteConfigurations;
+
protected void doExecute(FeaturesService admin) throws Exception {
addOption(FeaturesService.Option.Simulate, simulate);
addOption(FeaturesService.Option.Verbose, verbose);
addOption(FeaturesService.Option.NoAutoRefreshBundles, noRefresh);
+ addOption(FeaturesService.Option.DeleteConfigurations, deleteConfigurations);
admin.uninstallFeatures(new HashSet<>(features), region, options);
}
}
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 2594dab..6c2b4e1 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
@@ -57,7 +57,8 @@ public interface FeaturesService {
Verbose,
Upgrade,
DisplayFeaturesWiring,
- DisplayAllWiring
+ DisplayAllWiring,
+ DeleteConfigurations
}
/**
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
index 47b369b..6882b7f 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
@@ -83,9 +83,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
public void postDeregister() {
}
- /**
- * {@inheritDoc}
- */
+ @Override
public TabularData getFeatures() throws Exception {
try {
List<Feature> allFeatures = Arrays.asList(featuresService.listFeatures());
@@ -105,9 +103,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
}
}
- /**
- * {@inheritDoc}
- */
+ @Override
public TabularData getRepositories() throws Exception {
try {
List<Repository> allRepositories = Arrays.asList(featuresService.listRepositories());
@@ -131,6 +127,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
return infoFeature(featuresService.repositoryProvidedFeatures(new URI(uri)));
}
+ @Override
public void addRepository(String uri) throws Exception {
URI repoUri = new URI(uri);
if (featuresService.isRepositoryUriBlacklisted(repoUri)) {
@@ -139,6 +136,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
featuresService.addRepository(repoUri);
}
+ @Override
public void addRepository(String uri, boolean install) throws Exception {
URI repoUri = new URI(uri);
if (featuresService.isRepositoryUriBlacklisted(repoUri)) {
@@ -147,10 +145,12 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
featuresService.addRepository(repoUri, install);
}
+ @Override
public void removeRepository(String uri) throws Exception {
removeRepository(uri, false);
}
+ @Override
public void removeRepository(String uri, boolean uninstall) throws Exception {
List<URI> uris = new ArrayList<>();
Pattern pattern = Pattern.compile(uri);
@@ -180,6 +180,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
}
}
+ @Override
public void refreshRepository(String uri) throws Exception {
if (uri == null || uri.isEmpty()) {
for (Repository repository : featuresService.listRepositories()) {
@@ -202,10 +203,12 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
}
}
+ @Override
public void installFeature(String name) throws Exception {
featuresService.installFeature(name);
}
+ @Override
public void installFeature(String name, boolean noRefresh) throws Exception {
EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
if (noRefresh) {
@@ -214,6 +217,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
featuresService.installFeature(name, options);
}
+ @Override
public void installFeature(String name, boolean noRefresh, boolean noStart) throws Exception {
EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
if (noRefresh) {
@@ -225,10 +229,12 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
featuresService.installFeature(name, options);
}
+ @Override
public void installFeature(String name, String version) throws Exception {
featuresService.installFeature(name, version);
}
+ @Override
public void installFeature(String name, String version, boolean noRefresh) throws Exception {
EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
if (noRefresh) {
@@ -237,6 +243,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
featuresService.installFeature(name, version, options);
}
+ @Override
public void installFeature(String name, String version, boolean noRefresh, boolean noStart) throws Exception {
EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
if (noRefresh) {
@@ -248,6 +255,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
featuresService.installFeature(name, version, options);
}
+ @Override
public TabularData infoFeature(String name) throws Exception {
try {
Feature[] features = featuresService.getFeatures(name);
@@ -258,6 +266,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
}
}
+ @Override
public TabularData infoFeature(String name, String version) throws Exception {
try {
Feature[] features = featuresService.getFeatures(name, version);
@@ -279,27 +288,47 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
return JmxFeature.tableFrom(features);
}
+ @Override
public void uninstallFeature(String name) throws Exception {
featuresService.uninstallFeature(name);
}
+ @Override
public void uninstallFeature(String name, boolean noRefresh) throws Exception {
+ uninstallFeature(name, noRefresh, false);
+ }
+
+ @Override
+ public void uninstallFeature(String name, boolean noRefresh, boolean deleteConfigurations) throws Exception {
EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
if (noRefresh) {
options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
}
+ if (deleteConfigurations) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.DeleteConfigurations);
+ }
featuresService.uninstallFeature(name, options);
}
+ @Override
public void uninstallFeature(String name, String version) throws Exception {
featuresService.uninstallFeature(name, version);
}
+ @Override
public void uninstallFeature(String name, String version, boolean noRefresh) throws Exception {
+ uninstallFeature(name, version, noRefresh, false);
+ }
+
+ @Override
+ public void uninstallFeature(String name, String version, boolean noRefresh, boolean deleteConfigurations) throws Exception {
EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
if (noRefresh) {
options.add(FeaturesService.Option.NoAutoRefreshBundles);
}
+ if (deleteConfigurations) {
+ options.add(FeaturesService.Option.DeleteConfigurations);
+ }
featuresService.uninstallFeature(name, version, options);
}
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupport.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupport.java
index 9dc06a4..b37f689 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupport.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupport.java
@@ -68,6 +68,8 @@ public interface BundleInstallSupport {
RegionDigraph getDiGraphCopy() throws BundleException;
void installConfigs(Feature feature) throws IOException, InvalidSyntaxException;
+
+ void deleteConfigs(Feature feature) throws IOException, InvalidSyntaxException;
void installLibraries(Feature feature) throws IOException;
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupportImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupportImpl.java
index b05425c..ca893df 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupportImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/BundleInstallSupportImpl.java
@@ -303,6 +303,13 @@ public class BundleInstallSupportImpl implements BundleInstallSupport {
}
@Override
+ public void deleteConfigs(Feature feature) throws IOException, InvalidSyntaxException {
+ if (configInstaller != null) {
+ configInstaller.uninstallFeatureConfigs(feature);
+ }
+ }
+
+ @Override
public void installLibraries(Feature feature) {
// TODO: install libraries
}
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 c7c077c..51b1d45 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
@@ -42,6 +42,8 @@ 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.ConfigFileInfo;
+import org.apache.karaf.features.ConfigInfo;
import org.apache.karaf.features.DeploymentEvent;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeatureEvent;
@@ -49,6 +51,7 @@ import org.apache.karaf.features.FeatureState;
import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.features.internal.download.DownloadManager;
import org.apache.karaf.features.internal.download.StreamProvider;
+import org.apache.karaf.features.internal.model.ConfigFile;
import org.apache.karaf.features.internal.region.SubsystemResolver;
import org.apache.karaf.features.internal.region.SubsystemResolverCallback;
import org.apache.karaf.features.internal.resolver.FeatureResource;
@@ -60,6 +63,7 @@ import org.apache.karaf.features.internal.util.MapUtils;
import org.apache.karaf.features.internal.util.MultiException;
import org.eclipse.equinox.region.Region;
import org.eclipse.equinox.region.RegionDigraph;
+import org.omg.CORBA.DynAnyPackage.Invalid;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
@@ -133,6 +137,7 @@ public class Deployer {
void replaceDigraph(Map<String, Map<String, Map<String, Set<String>>>> policies,
Map<String, Set<Long>> bundles) throws BundleException, InvalidSyntaxException;
void installConfigs(Feature feature) throws IOException, InvalidSyntaxException;
+ void deleteConfigs(Feature feature) throws IOException, InvalidSyntaxException;
void installLibraries(Feature feature) throws IOException;
}
@@ -359,6 +364,7 @@ public class Deployer {
|| request.options.contains(FeaturesService.Option.DisplayAllWiring);
boolean showFeaturesWiringOnly = request.options.contains(FeaturesService.Option.DisplayFeaturesWiring)
&& !request.options.contains(FeaturesService.Option.DisplayAllWiring);
+ boolean deleteConfigurations = request.options.contains(FeaturesService.Option.DeleteConfigurations);
// TODO: add an option to unmanage bundles instead of uninstalling those
@@ -647,6 +653,30 @@ public class Deployer {
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion(), verbose);
}
}
+ if (deleteConfigurations) {
+ print(" Configurations to delete:", verbose);
+ for (Map.Entry<String, Set<String>> entry : delFeatures.entrySet()) {
+ for (String name : entry.getValue()) {
+ Feature feature = dstate.featuresById.get(name);
+ if (feature != null) {
+ for (ConfigInfo configInfo : feature.getConfigurations()) {
+ print(" " + configInfo.getName(), verbose);
+ }
+ }
+ }
+ }
+ print(" Configuration Files to delete:", verbose);
+ for (Map.Entry<String, Set<String>> entry : delFeatures.entrySet()) {
+ for (String name : entry.getValue()) {
+ Feature feature = dstate.featuresById.get(name);
+ if (feature != null) {
+ for (ConfigFileInfo configFileInfo : feature.getConfigurationFiles()) {
+ print(" " + configFileInfo.getFinalname(), verbose);
+ }
+ }
+ }
+ }
+ }
return;
}
@@ -936,6 +966,16 @@ public class Deployer {
}
}
+ // Delete configurations
+ if (deleteConfigurations) {
+ for (Map.Entry<String, Set<String>> entry : delFeatures.entrySet()) {
+ for (String name : entry.getValue()) {
+ Feature feature = dstate.featuresById.get(name);
+ callback.deleteConfigs(feature);
+ }
+ }
+ }
+
if (!noRefresh) {
if (toRefresh.containsKey(dstate.bundles.get(0l))) {
print("The system bundle needs to be refreshed, restarting Karaf...", verbose);
@@ -1005,6 +1045,8 @@ public class Deployer {
}
}
+ // If uninstall and delete configurations, actually delete configurations and configuration files
+
// Call listeners
for (Map.Entry<String, Set<String>> entry : delFeatures.entrySet()) {
for (String name : entry.getValue()) {
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
index 66ec66d..e401a69 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
@@ -157,6 +157,36 @@ public class FeatureConfigInstaller {
}
}
+ public void uninstallFeatureConfigs(Feature feature) throws IOException, InvalidSyntaxException {
+ if (feature != null) {
+ if (feature.getConfigurations() != null) {
+ for (ConfigInfo configInfo : feature.getConfigurations()) {
+ ConfigId configId = parsePid(configInfo.getName());
+ Configuration configuration = findExistingConfiguration(configAdmin, configId);
+ if (configuration != null) {
+ configuration.delete();
+ }
+ File cfgFile = null;
+ if (storage != null) {
+ cfgFile = new File(storage, configId.fullPid + ".cfg");
+ }
+ if (cfgFile.exists()) {
+ cfgFile.delete();
+ }
+ }
+ }
+ if (feature.getConfigurationFiles() != null) {
+ for (ConfigFileInfo configFileInfo : feature.getConfigurationFiles()) {
+ String finalname = substFinalName(configFileInfo.getFinalname());
+ File cfgFile = new File(finalname);
+ if (cfgFile.exists()) {
+ cfgFile.delete();
+ }
+ }
+ }
+ }
+ }
+
private Dictionary<String, Object> convertToDict(Map<String, Object> props) {
Dictionary<String, Object> cfgProps = new Hashtable<>();
for (Map.Entry<String, Object> e : props.entrySet()) {
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 d6e9e40..e6c54c4c 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
@@ -1179,6 +1179,11 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
}
@Override
+ public void deleteConfigs(Feature feature) throws IOException, InvalidSyntaxException {
+ installSupport.deleteConfigs(feature);
+ }
+
+ @Override
public void installLibraries(Feature feature) throws IOException {
installSupport.installLibraries(feature);
}
diff --git a/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java b/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
index 70fe8a6..c0a3a30 100644
--- a/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
+++ b/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
@@ -149,8 +149,12 @@ public interface FeaturesServiceMBean {
void uninstallFeature(String name, boolean noRefresh) throws Exception;
+ void uninstallFeature(String name, boolean noRefresh, boolean deleteConfigurations) throws Exception;
+
void uninstallFeature(String name, String version) throws Exception;
void uninstallFeature(String name, String version, boolean noRefresh) throws Exception;
+ void uninstallFeature(String name, String version, boolean noRefresh, boolean deleteConfigurations) throws Exception;
+
}
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 a124e8d..6b437eb 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
@@ -629,6 +629,11 @@ public class DeployerTest {
}
@Override
+ public void deleteConfigs(Feature feature) throws IOException, InvalidSyntaxException {
+
+ }
+
+ @Override
public void installLibraries(Feature feature) throws IOException {
}
diff --git a/itests/test/src/test/java/org/apache/karaf/itests/FeatureTest.java b/itests/test/src/test/java/org/apache/karaf/itests/FeatureTest.java
index 9f58b75..dff4a20 100644
--- a/itests/test/src/test/java/org/apache/karaf/itests/FeatureTest.java
+++ b/itests/test/src/test/java/org/apache/karaf/itests/FeatureTest.java
@@ -33,6 +33,7 @@ import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
+import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.LinkedList;
@@ -157,4 +158,70 @@ public class FeatureTest extends KarafTestSupport {
mbeanServer.invoke(name, "refreshRepository", new Object[] { ".*pax-web.*" }, new String[]{ "java.lang.String" });
}
+ @Test
+ public void configRegularLifecycle() throws Exception {
+ System.out.println(executeCommand("feature:install http", new RolePrincipal("admin")));
+ String output = executeCommand("config:exists org.ops4j.pax.web");
+ assertContains("true", output);
+ File jetty = new File(System.getProperty("karaf.etc"), "jetty.xml");
+ assertTrue("jetty.xml should exist", jetty.exists());
+
+ System.out.println(executeCommand("feature:uninstall http", new RolePrincipal("admin")));
+ output = executeCommand("config:exists org.ops4j.pax.web");
+ assertContains("true", output);
+ jetty = new File(System.getProperty("karaf.etc"), "jetty.xml");
+ assertTrue("jetty.xml should still exist", jetty.exists());
+ }
+
+ @Test
+ public void configDelete() throws Exception {
+ System.out.println(executeCommand("feature:install http", new RolePrincipal("admin")));
+ String output = executeCommand("config:exists org.ops4j.pax.web");
+ assertContains("true", output);
+ File jetty = new File(System.getProperty("karaf.etc"), "jetty.xml");
+ assertTrue("etc/jetty.xml should exist", jetty.exists());
+
+ System.out.println(executeCommand("feature:uninstall -c http", new RolePrincipal("admin")));
+ output = executeCommand("config:exists org.ops4j.pax.web");
+ assertContains("false", output);
+ jetty = new File(System.getProperty("karaf.etc"), "jetty.xml");
+ assertFalse("jetty.xml should not still exist", jetty.exists());
+ }
+
+ @Test
+ public void configRegularLifecycleViaMBean() throws Exception {
+ MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+ ObjectName featureMBean = new ObjectName("org.apache.karaf:type=feature,name=root");
+ ObjectName configMBean = new ObjectName("org.apache.karaf:type=config,name=root");
+ mbeanServer.invoke(featureMBean, "installFeature", new Object[]{ "http" }, new String[]{ "java.lang.String" });
+
+ boolean exist = (boolean) mbeanServer.invoke(configMBean, "exists", new Object[]{ "org.ops4j.pax.web" }, new String[]{ "java.lang.String" });
+ assertTrue("true", exist);
+ File jetty = new File(System.getProperty("karaf.etc", "jetty.xml"));
+ assertTrue("jetty.xml should exist", jetty.exists());
+
+ mbeanServer.invoke(featureMBean, "uninstallFeature", new Object[]{ "http" }, new String[]{ "java.lang.String" });
+ exist = (boolean) mbeanServer.invoke(configMBean, "exists", new Object[]{ "org.ops4j.pax.web" }, new String[]{ "java.lang.String" });
+ assertTrue("true", exist);
+ jetty = new File(System.getProperty("karaf.etc", "jetty.xml"));
+ assertTrue("jetty.xml should exist", jetty.exists());
+ }
+
+ @Test
+ public void configDeleteViaMBean() throws Exception {
+ MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+ ObjectName featureMBean = new ObjectName("org.apache.karaf:type=feature,name=root");
+ ObjectName configMBean = new ObjectName("org.apache.karaf:type=config,name=root");
+ mbeanServer.invoke(featureMBean, "installFeature", new Object[]{ "http" }, new String[]{ "java.lang.String" });
+
+ boolean exist = (boolean) mbeanServer.invoke(configMBean, "exists", new Object[]{ "org.ops4j.pax.web" }, new String[]{ "java.lang.String" });
+ assertTrue("true", exist);
+ File jetty = new File(System.getProperty("karaf.etc", "jetty.xml"));
+ assertTrue("jetty.xml should exist", jetty.exists());
+
+ mbeanServer.invoke(featureMBean, "uninstallFeature", new Object[]{ "http", false, true }, new String[]{ "java.lang.String", "boolean", "boolean" });
+ exist = (boolean) mbeanServer.invoke(configMBean, "exists", new Object[]{ "org.ops4j.pax.web" }, new String[]{ "java.lang.String" });
+ assertFalse("false", exist);
+ }
+
}
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/AssemblyDeployCallback.java b/profile/src/main/java/org/apache/karaf/profile/assembly/AssemblyDeployCallback.java
index f478f33..6160c13 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/AssemblyDeployCallback.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/AssemblyDeployCallback.java
@@ -53,6 +53,7 @@ import org.apache.karaf.features.internal.util.MapUtils;
import org.apache.karaf.util.maven.Parser;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.wiring.BundleRevision;
import org.slf4j.Logger;
@@ -205,6 +206,11 @@ public class AssemblyDeployCallback extends StaticInstallSupport implements Depl
}
@Override
+ public void deleteConfigs(org.apache.karaf.features.Feature feature) throws IOException, InvalidSyntaxException {
+ // nothing to do
+ }
+
+ @Override
public void installLibraries(org.apache.karaf.features.Feature feature) throws IOException {
assertNotBlacklisted(feature);
Downloader downloader = manager.createDownloader();
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java
index 32ac5ef..f13e0cb 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java
@@ -102,6 +102,7 @@ import org.ops4j.pax.url.mvn.MavenResolvers;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.startlevel.BundleStartLevel;
@@ -822,7 +823,11 @@ public class VerifyMojo extends MojoSupport {
@Override
public void installConfigs(org.apache.karaf.features.Feature feature) {
}
-
+
+ @Override
+ public void deleteConfigs(org.apache.karaf.features.Feature feature) throws IOException, InvalidSyntaxException {
+ }
+
@Override
public void installLibraries(org.apache.karaf.features.Feature feature) {
}