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 2020/06/29 13:51:00 UTC
[karaf-cellar] branch master updated: Synchronizer map (#67)
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-cellar.git
The following commit(s) were added to refs/heads/master by this push:
new 3396c2a Synchronizer map (#67)
3396c2a is described below
commit 3396c2aa20e2227de7c21ed01bae81c488dd22b2
Author: Thomas Draier <td...@jahia.com>
AuthorDate: Mon Jun 29 15:50:55 2020 +0200
Synchronizer map (#67)
Synchronize access to map
---
.../karaf/cellar/bundle/BundleSynchronizer.java | 5 +-
.../cellar/config/ConfigurationSynchronizer.java | 4 +-
.../apache/karaf/cellar/core/CellarSupport.java | 4 ++
.../karaf/cellar/core/utils/CellarUtils.java | 57 ++++++++++++++++++++++
.../cellar/features/FeaturesSynchronizer.java | 11 ++++-
5 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
index 6e18cfd..51a7bb2 100644
--- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
+++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
@@ -19,6 +19,7 @@ import org.apache.karaf.cellar.core.Synchronizer;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventProducer;
import org.apache.karaf.cellar.core.event.EventType;
+import org.apache.karaf.cellar.core.utils.CellarUtils;
import org.apache.karaf.features.BootFinished;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -198,12 +199,13 @@ public class BundleSynchronizer extends BundleSupport implements Synchronizer {
}
// cleanup the local bundles not present on the cluster if the node is not the first one in the cluster group
- if (clusterManager.listNodesByGroup(group).size() > 1) {
+ if (CellarUtils.doCleanupResourcesNotPresentInCluster(configurationAdmin) && getSynchronizerMap().containsKey(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName)) {
for (Bundle bundle : bundleContext.getBundles()) {
String id = getId(bundle);
if (!clusterBundles.containsKey(id) && isAllowed(group, Constants.CATEGORY, bundle.getLocation(), EventType.INBOUND)) {
// the bundle is not present on the cluster, so it has to be uninstalled locally
try {
+ LOGGER.debug("CELLAR BUNDLE: uninstalling local bundle {} which is not present in cluster", id);
bundle.uninstall();
} catch (Exception e) {
LOGGER.warn("Can't uninstall {}", id, e);
@@ -315,6 +317,7 @@ public class BundleSynchronizer extends BundleSupport implements Synchronizer {
}
}
}
+ getSynchronizerMap().putIfAbsent(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName, true);
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
diff --git a/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java b/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java
index e02040c..613ce4c 100644
--- a/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java
+++ b/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSynchronizer.java
@@ -19,6 +19,7 @@ import org.apache.karaf.cellar.core.Synchronizer;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventProducer;
import org.apache.karaf.cellar.core.event.EventType;
+import org.apache.karaf.cellar.core.utils.CellarUtils;
import org.apache.karaf.features.BootFinished;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
@@ -148,7 +149,7 @@ public class ConfigurationSynchronizer extends ConfigurationSupport implements S
} else LOGGER.trace("CELLAR CONFIG: configuration with PID {} is marked BLOCKED INBOUND for cluster group {}", pid, groupName);
}
// cleanup the local configurations not present on the cluster if the node is not the first one in the cluster
- if (clusterManager.listNodesByGroup(group).size() > 1) {
+ if (CellarUtils.doCleanupResourcesNotPresentInCluster(configurationAdmin) && getSynchronizerMap().containsKey(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName)) {
try {
Set<String> filenames = new HashSet();
for (Properties configuration : clusterConfigurations.values()) {
@@ -241,6 +242,7 @@ public class ConfigurationSynchronizer extends ConfigurationSupport implements S
}
}
}
+ getSynchronizerMap().putIfAbsent(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName, true);
} catch (IOException ex) {
LOGGER.error("CELLAR CONFIG: failed to read configuration (IO error)", ex);
} catch (InvalidSyntaxException ex) {
diff --git a/core/src/main/java/org/apache/karaf/cellar/core/CellarSupport.java b/core/src/main/java/org/apache/karaf/cellar/core/CellarSupport.java
index 8904cea..a1d0f3c 100644
--- a/core/src/main/java/org/apache/karaf/cellar/core/CellarSupport.java
+++ b/core/src/main/java/org/apache/karaf/cellar/core/CellarSupport.java
@@ -248,4 +248,8 @@ public class CellarSupport {
this.groupManager = groupManager;
}
+ @SuppressWarnings("unchecked")
+ protected Map<String, Boolean> getSynchronizerMap() {
+ return clusterManager.getMap("org.apache.karaf.cellar.synchronizers");
+ }
}
diff --git a/core/src/main/java/org/apache/karaf/cellar/core/utils/CellarUtils.java b/core/src/main/java/org/apache/karaf/cellar/core/utils/CellarUtils.java
index 28e57d7..8ba5973 100644
--- a/core/src/main/java/org/apache/karaf/cellar/core/utils/CellarUtils.java
+++ b/core/src/main/java/org/apache/karaf/cellar/core/utils/CellarUtils.java
@@ -13,13 +13,21 @@
*/
package org.apache.karaf.cellar.core.utils;
+import java.io.IOException;
import java.util.Collection;
+import java.util.Dictionary;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.karaf.cellar.core.Configurations;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Generic Cellar utils class.
*/
@@ -29,6 +37,8 @@ public class CellarUtils {
MERGA
}
+ private static final transient Logger LOGGER = LoggerFactory.getLogger(CellarUtils.class);
+
public static final String MERGABLE = "MERGABLE[%s]";
public static final String MERGABLE_REGEX = "MERGABLE\\[([^\\s]+[\\,]*[\\s]*)*\\]";
@@ -129,4 +139,51 @@ public class CellarUtils {
return true;
}
}
+
+ /**
+ * Retrieves the value of the configuration property from the specified configuration. If the property is not found or there is an error
+ * retrieving it, return the provided default value.
+ *
+ * @param configurationAdmin
+ * the config admin service instance
+ * @param configurationId
+ * the configuration PID to be retrieved
+ * @param propertyKey
+ * the key of the property entry to look up
+ * @param defaultValue
+ * a value to be returned, if the property is not present in the configuration or there is an error retrieving it
+ * @return the value of the configuration property from the specified configuration. If the property is not found or there is an error
+ * retrieving it, return the provided default value
+ */
+ public static String getConfigurationProperty(ConfigurationAdmin configurationAdmin, String configurationId,
+ String propertyKey, String defaultValue) {
+ String propertyValue = null;
+ try {
+ Configuration configuration = configurationAdmin.getConfiguration(configurationId, null);
+ Dictionary<String, Object> properties = configuration.getProperties();
+ if (properties != null) {
+ propertyValue = (String) properties.get(propertyKey);
+ }
+ } catch (IOException e) {
+ LOGGER.warn("Error while retrieving the " + propertyKey + " entry from coonfiguration " + configurationId,
+ e);
+ }
+
+ return propertyValue != null ? propertyValue : defaultValue;
+ }
+
+ /**
+ * Returns the flag value, indicating if the resources (bundles, configuration, features), not present on cluster, should be uninstalled
+ * on cluster sync by corresponding synchronizers.
+ *
+ * @param configurationAdmin
+ * the config admin service instance
+ * @return the flag value, indicating if the resources (bundles, configuration, features), not present on cluster, should be uninstalled
+ * on cluster sync by corresponding synchronizers
+ */
+ public static boolean doCleanupResourcesNotPresentInCluster(ConfigurationAdmin configurationAdmin) {
+ return Boolean.parseBoolean(getConfigurationProperty(configurationAdmin, Configurations.NODE,
+ "org.apache.karaf.cellar.cleanupResourcesNotPresentInCluster", "true"));
+ }
+
}
diff --git a/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSynchronizer.java b/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSynchronizer.java
index 487b780..daf8961 100644
--- a/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSynchronizer.java
+++ b/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSynchronizer.java
@@ -19,6 +19,7 @@ import org.apache.karaf.cellar.core.Synchronizer;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventProducer;
import org.apache.karaf.cellar.core.event.EventType;
+import org.apache.karaf.cellar.core.utils.CellarUtils;
import org.apache.karaf.features.*;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.Configuration;
@@ -122,6 +123,7 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
Map<String, String> clusterRepositories = clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + groupName);
Map<String, FeatureState> clusterFeatures = clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName);
+ Map<String, Boolean> synchronizers = getSynchronizerMap();
if (clusterRepositories != null && !clusterRepositories.isEmpty()) {
// get the features repositories from the cluster to update locally
@@ -138,7 +140,8 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
}
}
// cleanup the local features repositories not present on the cluster if the node is not the first one in the cluster group
- if (clusterManager.listNodesByGroup(group).size() > 1) {
+
+ if (synchronizers.containsKey(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + groupName)) {
try {
for (Repository repository : featuresService.listRepositories()) {
URI uri = repository.getURI();
@@ -161,6 +164,7 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
}
if (clusterFeatures != null && !clusterFeatures.isEmpty()) {
+ boolean doUninstallFeaturesNotPresentInCluster = CellarUtils.doCleanupResourcesNotPresentInCluster(configurationAdmin) && synchronizers.containsKey(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName);
// get the features from the cluster group and update locally
for (FeatureState state : clusterFeatures.values()) {
String name = state.getName();
@@ -187,7 +191,7 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
}
}
// if feature has to be uninstalled locally (and node is not the first one in the cluster group)
- if (clusterManager.listNodesByGroup(group).size() > 1 && !clusterInstalled && locallyInstalled) {
+ if (doUninstallFeaturesNotPresentInCluster && !clusterInstalled && locallyInstalled) {
try {
LOGGER.debug("CELLAR FEATURE: uninstalling feature {}/{}", state.getName(), state.getVersion());
featuresService.uninstallFeature(state.getName(), state.getVersion());
@@ -227,6 +231,7 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
Map<String, String> clusterRepositories = clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + groupName);
Map<String, FeatureState> clusterFeatures = clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName);
+ Map<String, Boolean> synchronizers = getSynchronizerMap();
Repository[] repositoryList = new Repository[0];
Feature[] featuresList = new Feature[0];
@@ -260,6 +265,7 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
}
}
}
+ synchronizers.put(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + groupName, true);
// push features to the cluster group
if (featuresList != null && featuresList.length > 0) {
@@ -312,6 +318,7 @@ public class FeaturesSynchronizer extends FeaturesSupport implements Synchronize
}
}
}
+ synchronizers.put(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName, true);
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}