Merge pull request #63 from Jahia/configuration-factory-synchronization
Configuration factory synchronization
diff --git a/assembly/src/main/resources/node.cfg b/assembly/src/main/resources/node.cfg
index 38c841e..5a09661 100644
--- a/assembly/src/main/resources/node.cfg
+++ b/assembly/src/main/resources/node.cfg
@@ -44,4 +44,4 @@
# Excluded config properties from the sync
# Some config properties can be considered as local to a node, and should not be sync on the cluster.
#
-config.excluded.properties = service.factoryPid, felix.fileinstall.filename, felix.fileinstall.dir, felix.fileinstall.tmpdir, org.ops4j.pax.url.mvn.defaultRepositories
+config.excluded.properties = felix.fileinstall.filename, felix.fileinstall.dir, felix.fileinstall.tmpdir, org.ops4j.pax.url.mvn.defaultRepositories
diff --git a/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java b/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java
index 910cb7a..b0a1dc2 100644
--- a/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java
+++ b/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationEventHandler.java
@@ -25,7 +25,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
import java.util.Dictionary;
import java.util.Map;
import java.util.Properties;
@@ -76,27 +75,31 @@
String pid = event.getId();
if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, pid, EventType.INBOUND)) {
-
- Properties clusterDictionary = clusterConfigurations.get(pid);
+ Dictionary clusterDictionary = clusterConfigurations.get(pid);
try {
// update the local configuration
- Configuration[] localConfigurations = configurationAdmin.listConfigurations("(service.pid=" + pid + ")");
+ Configuration localConfiguration = findLocalConfiguration(pid, clusterDictionary);
+
if (event.getType() != null && event.getType() == ConfigurationEvent.CM_DELETED) {
// delete the configuration
- if (localConfigurations != null && localConfigurations.length > 0) {
- localConfigurations[0].delete();
- deleteStorage(pid);
+ if (localConfiguration != null) {
+ deleteConfiguration(localConfiguration);
}
} else {
- if (clusterDictionary != null) {
- Configuration localConfiguration = configurationAdmin.getConfiguration(pid, null);
+ if (clusterDictionary != null && shouldReplicateConfig(clusterDictionary)) {
+ if (localConfiguration == null) {
+ // Create new configuration
+ localConfiguration = createLocalConfiguration(pid, clusterDictionary);
+ }
Dictionary localDictionary = localConfiguration.getProperties();
if (localDictionary == null)
localDictionary = new Properties();
localDictionary = filter(localDictionary);
- if (!equals(clusterDictionary, localDictionary)) {
- localConfiguration.update((Dictionary) clusterDictionary);
- persistConfiguration(configurationAdmin, pid, clusterDictionary);
+ if (!equals(clusterDictionary, localDictionary) && canDistributeConfig(localDictionary)) {
+ Dictionary convertedDictionary = convertPropertiesFromCluster(clusterDictionary);
+
+ localConfiguration.update(convertedDictionary);
+ persistConfiguration(localConfiguration, clusterDictionary);
}
}
}
diff --git a/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java b/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java
index 58a4058..83246db 100644
--- a/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java
+++ b/config/src/main/java/org/apache/karaf/cellar/config/ConfigurationSupport.java
@@ -15,11 +15,11 @@
import org.apache.karaf.cellar.core.CellarSupport;
import org.apache.karaf.cellar.core.Configurations;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
import java.net.URI;
import java.net.URL;
import java.util.*;
@@ -29,7 +29,10 @@
*/
public class ConfigurationSupport extends CellarSupport {
- private static final String FELIX_FILEINSTALL_FILENAME = "felix.fileinstall.filename";
+ public static final String FELIX_FILEINSTALL_FILENAME = "felix.fileinstall.filename";
+ public static final String KARAF_CELLAR_FILENAME = "karaf.cellar.filename";
+ public static final String KARAF_CELLAR_CONTENT = "karaf.cellar.content";
+ public static final String KARAF_CELLAR_REMOVED = "karaf.cellar.removed";
protected File storage;
@@ -39,7 +42,7 @@
* @param dictionary the source dictionary.
* @return the corresponding properties.
*/
- public Properties dictionaryToProperties(Dictionary dictionary) {
+ public static Properties dictionaryToProperties(Dictionary dictionary) {
Properties properties = new Properties();
if (dictionary != null) {
Enumeration keys = dictionary.keys();
@@ -76,19 +79,32 @@
Enumeration sourceKeys = source.keys();
while (sourceKeys.hasMoreElements()) {
Object key = sourceKeys.nextElement();
- Object sourceValue = source.get(key);
- Object targetValue = target.get(key);
- if (sourceValue != null && targetValue == null)
- return false;
- if (sourceValue == null && targetValue != null)
- return false;
- if (!sourceValue.equals(targetValue))
- return false;
+ if (!key.equals(org.osgi.framework.Constants.SERVICE_PID)) {
+ Object sourceValue = source.get(key);
+ Object targetValue = target.get(key);
+ if (sourceValue != null && targetValue == null)
+ return false;
+ if (sourceValue == null && targetValue != null)
+ return false;
+ if (!sourceValue.equals(targetValue))
+ return false;
+ }
}
return true;
}
+ public boolean canDistributeConfig(Dictionary dictionary) {
+ if (dictionary.get(ConfigurationAdmin.SERVICE_FACTORYPID) != null) {
+ return dictionary.get(KARAF_CELLAR_FILENAME) != null;
+ }
+ return true;
+ }
+
+ public boolean shouldReplicateConfig(Dictionary clusterDictionary) {
+ return clusterDictionary.get(KARAF_CELLAR_REMOVED) == null;
+ }
+
/**
* Filter a dictionary, and populate a target dictionary.
*
@@ -101,7 +117,70 @@
Enumeration sourceKeys = dictionary.keys();
while (sourceKeys.hasMoreElements()) {
String key = (String) sourceKeys.nextElement();
- if (!isExcludedProperty(key)) {
+ if (key.equals(FELIX_FILEINSTALL_FILENAME)) {
+ String value = dictionary.get(key).toString();
+ value = value.substring(value.lastIndexOf("/") + 1);
+ result.put(KARAF_CELLAR_FILENAME, value);
+ try {
+ result.put(KARAF_CELLAR_CONTENT, readFile(new File(storage, value)));
+ } catch (IOException e) {
+ // Cannot read file
+ }
+ } else if (!isExcludedProperty(key)) {
+ Object value = dictionary.get(key);
+ result.put(key, value);
+ }
+ }
+ }
+ return result;
+ }
+
+ public Properties getDeletedConfigurationMarker(Dictionary dictionary) {
+ Properties result = new Properties();
+ result.put(org.osgi.framework.Constants.SERVICE_PID, dictionary.get(org.osgi.framework.Constants.SERVICE_PID));
+ result.put(KARAF_CELLAR_FILENAME, dictionary.get(KARAF_CELLAR_FILENAME));
+ result.put(KARAF_CELLAR_REMOVED, true);
+ return result;
+ }
+
+ public Configuration findLocalConfiguration(String pid, Dictionary dictionary) throws IOException, InvalidSyntaxException {
+ String filter;
+ Object filename = dictionary != null ? dictionary.get(KARAF_CELLAR_FILENAME) : null;
+ if (filename != null) {
+ String uri = new File(storage, filename.toString()).toURI().toString();
+ filter = "(|(" + FELIX_FILEINSTALL_FILENAME + "=" + uri + ")(" + KARAF_CELLAR_FILENAME + "=" + dictionary.get(KARAF_CELLAR_FILENAME) + ")(" + org.osgi.framework.Constants.SERVICE_PID + "=" + pid + "))";
+ } else {
+ filter = "(" + org.osgi.framework.Constants.SERVICE_PID + "=" + pid + ")";
+ }
+
+ Configuration[] localConfigurations = configurationAdmin.listConfigurations(filter);
+
+ return (localConfigurations != null && localConfigurations.length > 0) ? localConfigurations[0] : null;
+ }
+
+ public Configuration createLocalConfiguration(String pid, Dictionary clusterDictionary) throws IOException {
+ Configuration localConfiguration;
+ Object factoryPid = clusterDictionary.get(ConfigurationAdmin.SERVICE_FACTORYPID);
+ if (factoryPid != null) {
+ localConfiguration = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null);
+ } else {
+ localConfiguration = configurationAdmin.getConfiguration(pid, null);
+ }
+ return localConfiguration;
+ }
+
+ public Dictionary convertPropertiesFromCluster(Dictionary dictionary) {
+ Dictionary result = new Properties();
+ if (dictionary != null) {
+ Enumeration sourceKeys = dictionary.keys();
+ while (sourceKeys.hasMoreElements()) {
+ String key = (String) sourceKeys.nextElement();
+ if (key.equals(KARAF_CELLAR_FILENAME)) {
+ String value = dictionary.get(key).toString();
+ result.put(FELIX_FILEINSTALL_FILENAME, new File(storage, value).toURI().toString());
+ } else if (key.equals(KARAF_CELLAR_CONTENT)) {
+ // skip
+ } else {
Object value = dictionary.get(key);
result.put(key, value);
}
@@ -138,77 +217,96 @@
/**
* Persist a configuration to a storage.
- *
- * @param admin the configuration admin service.
- * @param pid the configuration PID to store.
- * @param props the properties to store, linked to the configuration PID.
+ * @param cfg the configuration to store.
*/
- protected void persistConfiguration(ConfigurationAdmin admin, String pid, Dictionary props) {
+ protected void persistConfiguration(Configuration cfg, Dictionary clusterDictionary) {
try {
- if (pid.matches(".*-.*-.*-.*-.*")) {
- // it's UUID
+ File storageFile = getStorageFile(cfg.getProperties());
+
+ if (storageFile == null && cfg.getProperties().get(ConfigurationAdmin.SERVICE_FACTORYPID) != null) {
+ storageFile = new File(storage, cfg.getPid() + ".cfg");
+ }
+ if (storageFile == null) {
+ // it's a factory configuration without filename specified, cannot save
return;
}
- File storageFile = new File(storage, pid + ".cfg");
- Configuration cfg = admin.getConfiguration(pid, null);
- if (cfg != null && cfg.getProperties() != null) {
- Object val = cfg.getProperties().get(FELIX_FILEINSTALL_FILENAME);
- try {
- if (val instanceof URL) {
- storageFile = new File(((URL) val).toURI());
+
+ String content = clusterDictionary == null ? null : (String) clusterDictionary.get(KARAF_CELLAR_CONTENT);
+
+ if (content == null) {
+ org.apache.felix.utils.properties.Properties p = new org.apache.felix.utils.properties.Properties(storageFile);
+ List<String> propertiesToRemove = new ArrayList<String>();
+ Set<String> set = p.keySet();
+
+ for (String key : set) {
+ if (!org.osgi.framework.Constants.SERVICE_PID.equals(key)
+ && !ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)
+ && !KARAF_CELLAR_FILENAME.equals(key)
+ && !FELIX_FILEINSTALL_FILENAME.equals(key)) {
+ propertiesToRemove.add(key);
}
- if (val instanceof URI) {
- storageFile = new File((URI) val);
+ }
+
+ for (String key : propertiesToRemove) {
+ p.remove(key);
+ }
+ Dictionary props = cfg.getProperties();
+ for (Enumeration<String> keys = props.keys(); keys.hasMoreElements(); ) {
+ String key = keys.nextElement();
+ if (!org.osgi.framework.Constants.SERVICE_PID.equals(key)
+ && !ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)
+ && !KARAF_CELLAR_FILENAME.equals(key)
+ && !FELIX_FILEINSTALL_FILENAME.equals(key)) {
+ p.put(key, (String) props.get(key));
}
- if (val instanceof String) {
- storageFile = new File(new URL((String) val).toURI());
- }
- } catch (Exception e) {
- throw new IOException(e.getMessage(), e);
}
+
+ // save the cfg file
+ storage.mkdirs();
+ p.save();
+ } else {
+ writeFile(storageFile, content);
}
-
- org.apache.felix.utils.properties.Properties p = new org.apache.felix.utils.properties.Properties(storageFile);
- List<String> propertiesToRemove = new ArrayList<String>();
- Set<String> set = p.keySet();
-
- for (String key : set) {
- if (!org.osgi.framework.Constants.SERVICE_PID.equals(key)
- && !ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)
- && !FELIX_FILEINSTALL_FILENAME.equals(key)) {
- propertiesToRemove.add(key);
- }
- }
-
- for (String key : propertiesToRemove) {
- p.remove(key);
- }
-
- for (Enumeration<String> keys = props.keys(); keys.hasMoreElements(); ) {
- String key = keys.nextElement();
- if (!org.osgi.framework.Constants.SERVICE_PID.equals(key)
- && !ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)
- && !FELIX_FILEINSTALL_FILENAME.equals(key)) {
- p.put(key, (String) props.get(key));
- }
- }
-
- // save the cfg file
- storage.mkdirs();
- p.save();
} catch (Exception e) {
- // nothing to do
+ LOGGER.error("CELLAR CONFIG: Issue when trying to persist configuration file", e);
}
}
+ private File getStorageFile(Dictionary properties) throws IOException {
+ File storageFile = null;
+ Object val = properties.get(FELIX_FILEINSTALL_FILENAME);
+ try {
+ if (val instanceof URL) {
+ storageFile = new File(((URL) val).toURI());
+ }
+ if (val instanceof URI) {
+ storageFile = new File((URI) val);
+ }
+ if (val instanceof String) {
+ storageFile = new File(new URL((String) val).toURI());
+ }
+ } catch (Exception e) {
+ throw new IOException(e.getMessage(), e);
+ }
+ return storageFile;
+ }
+
+ public String getKarafFilename(Dictionary dictionary) {
+ return (String) filter(dictionary).get(KARAF_CELLAR_FILENAME);
+ }
+
/**
- * Delete the storage of a configuration.
+ * Delete the configuration.
*
- * @param pid the configuration PID to delete.
+ * @param localConfiguration the configuration PID to delete.
*/
- protected void deleteStorage(String pid) {
- File cfgFile = new File(storage, pid + ".cfg");
- cfgFile.delete();
+ protected void deleteConfiguration(Configuration localConfiguration) throws IOException {
+ String filename = getKarafFilename(localConfiguration.getProperties());
+ localConfiguration.delete();
+ File cfgFile = new File(storage, filename == null ? (localConfiguration.getPid() + ".cfg") : filename);
+ if (cfgFile.exists()) {
+ cfgFile.delete();
+ }
}
public File getStorage() {
@@ -219,4 +317,29 @@
this.storage = storage;
}
+ private String readFile(File file) throws IOException {
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+
+ try {
+ String line = reader.readLine();
+ StringBuilder sb = new StringBuilder();
+
+ while(line != null){
+ sb.append(line).append("\n");
+ line = reader.readLine();
+ }
+ return sb.toString();
+ } finally {
+ reader.close();
+ }
+ }
+ private void writeFile(File file, String content) throws IOException {
+ BufferedWriter writer = new BufferedWriter(new FileWriter(file));
+ try {
+ writer.write(content);
+ } finally {
+ writer.close();
+ }
+ }
+
}
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 b171bff..e02040c 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
@@ -28,10 +28,7 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.util.Dictionary;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
/**
* The ConfigurationSynchronizer is called when Cellar starts or when a node joins a cluster group.
@@ -125,20 +122,25 @@
// get configurations on the cluster to update local configurations
for (String pid : clusterConfigurations.keySet()) {
- if (isAllowed(group, Constants.CATEGORY, pid, EventType.INBOUND)) {
+ if (isAllowed(group, Constants.CATEGORY, pid, EventType.INBOUND) && shouldReplicateConfig(clusterConfigurations.get(pid))) {
Dictionary clusterDictionary = clusterConfigurations.get(pid);
try {
// update the local configuration if needed
- Configuration localConfiguration = configurationAdmin.getConfiguration(pid, null);
+ Configuration localConfiguration = findLocalConfiguration(pid, clusterDictionary);
+ if (localConfiguration == null) {
+ // Create new configuration
+ localConfiguration = createLocalConfiguration(pid, clusterDictionary);
+ }
Dictionary localDictionary = localConfiguration.getProperties();
if (localDictionary == null)
localDictionary = new Properties();
localDictionary = filter(localDictionary);
- if (!equals(clusterDictionary, localDictionary)) {
+ if (!equals(clusterDictionary, localDictionary) && canDistributeConfig(localDictionary) && shouldReplicateConfig(clusterDictionary)) {
LOGGER.debug("CELLAR CONFIG: updating configration {} on node", pid);
+ clusterDictionary = convertPropertiesFromCluster(clusterDictionary);
localConfiguration.update((Dictionary) clusterDictionary);
- persistConfiguration(configurationAdmin, pid, clusterDictionary);
+ persistConfiguration(localConfiguration, clusterDictionary);
}
} catch (IOException ex) {
LOGGER.error("CELLAR CONFIG: failed to read local configuration", ex);
@@ -148,16 +150,26 @@
// 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) {
try {
+ Set<String> filenames = new HashSet();
+ for (Properties configuration : clusterConfigurations.values()) {
+ if (shouldReplicateConfig(configuration)) {
+ filenames.add(getKarafFilename(configuration));
+ }
+ }
+ filenames.remove(null);
for (Configuration configuration : configurationAdmin.listConfigurations(null)) {
String pid = configuration.getPid();
- if (!clusterConfigurations.containsKey(pid) && isAllowed(group, Constants.CATEGORY, pid, EventType.INBOUND)) {
- configuration.delete();
+ if ((!clusterConfigurations.containsKey(pid) || !shouldReplicateConfig(clusterConfigurations.get(pid))) && !filenames.contains(getKarafFilename(configuration.getProperties())) && isAllowed(group, Constants.CATEGORY, pid, EventType.INBOUND)) {
+ LOGGER.debug("CELLAR CONFIG: deleting local configuration {} which is not present in cluster", pid);
+ deleteConfiguration(configuration);
}
}
} catch (Exception e) {
LOGGER.warn("Can't get local configurations", e);
}
}
+ } catch (Exception ex) {
+ LOGGER.error("CELLAR CONFIG: failed to read cluster configuration", ex);
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
@@ -206,7 +218,7 @@
eventProducer.produce(event);
} else {
Dictionary clusterDictionary = clusterConfigurations.get(pid);
- if (!equals(clusterDictionary, localDictionary)) {
+ if (!equals(clusterDictionary, localDictionary) && canDistributeConfig(localDictionary)) {
LOGGER.debug("CELLAR CONFIG: updating configuration pid {} on the cluster", pid);
// update cluster configurations
clusterConfigurations.put(pid, dictionaryToProperties(localDictionary));
@@ -224,14 +236,7 @@
// clean configurations on the cluster not present locally
for (String pid : clusterConfigurations.keySet()) {
if (isAllowed(group, Constants.CATEGORY, pid, EventType.OUTBOUND)) {
- boolean found = false;
- for (Configuration configuration : configurationAdmin.listConfigurations(null)) {
- if (configuration.getPid().equals(pid)) {
- found = true;
- break;
- }
- }
- if (!found) {
+ if (findLocalConfiguration(pid,clusterConfigurations.get(pid)) == null) {
clusterConfigurations.remove(pid);
}
}
diff --git a/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java b/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java
index 20ce8c5..2e319d8 100644
--- a/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java
+++ b/config/src/main/java/org/apache/karaf/cellar/config/LocalConfigurationListener.java
@@ -70,8 +70,17 @@
if (event.getType() == ConfigurationEvent.CM_DELETED) {
if (clusterConfigurations.containsKey(pid)) {
- // update the configurations in the cluster group
- clusterConfigurations.remove(pid);
+ String filename = (String) clusterConfigurations.get(pid).get(KARAF_CELLAR_FILENAME);
+ List<String> matchingPids = new ArrayList<String>();
+ for (Map.Entry<String, Properties> entry : clusterConfigurations.entrySet()) {
+ if (filename.equals(entry.getValue().get(KARAF_CELLAR_FILENAME))) {
+ matchingPids.add(entry.getKey());
+ }
+ }
+ for (String matchingPid : matchingPids) {
+ // update the configurations in the cluster group
+ clusterConfigurations.put(matchingPid, getDeletedConfigurationMarker(clusterConfigurations.get(matchingPid)));
+ }
// send the cluster event
ClusterConfigurationEvent clusterConfigurationEvent = new ClusterConfigurationEvent(pid);
clusterConfigurationEvent.setType(event.getType());
@@ -80,7 +89,6 @@
clusterConfigurationEvent.setLocal(clusterManager.getNode());
eventProducer.produce(clusterConfigurationEvent);
}
-
} else {
Configuration conf = configurationAdmin.getConfiguration(pid, null);
@@ -89,7 +97,7 @@
Properties distributedDictionary = clusterConfigurations.get(pid);
- if (!equals(localDictionary, distributedDictionary)) {
+ if (!equals(localDictionary, distributedDictionary) && canDistributeConfig(localDictionary)) {
// update the configurations in the cluster group
clusterConfigurations.put(pid, dictionaryToProperties(localDictionary));
// send the cluster event
diff --git a/config/src/main/java/org/apache/karaf/cellar/config/internal/osgi/Activator.java b/config/src/main/java/org/apache/karaf/cellar/config/internal/osgi/Activator.java
index e601a92..5dea8c6 100644
--- a/config/src/main/java/org/apache/karaf/cellar/config/internal/osgi/Activator.java
+++ b/config/src/main/java/org/apache/karaf/cellar/config/internal/osgi/Activator.java
@@ -97,6 +97,7 @@
localConfigurationListener.setGroupManager(groupManager);
localConfigurationListener.setConfigurationAdmin(configurationAdmin);
localConfigurationListener.setEventProducer(eventProducer);
+ localConfigurationListener.setStorage(storage);
localConfigurationListener.init();
register(ConfigurationListener.class, localConfigurationListener);
diff --git a/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java b/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java
index 11740cb..567d5da 100644
--- a/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java
+++ b/config/src/main/java/org/apache/karaf/cellar/config/shell/ListCommand.java
@@ -26,10 +26,7 @@
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.osgi.service.cm.Configuration;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
@Command(scope = "cluster", name = "config-list", description = "List the configurations in a cluster group")
@Service
@@ -90,6 +87,9 @@
if (onlyCluster)
continue;
}
+ if (state.getClusterPids() != null && !state.getClusterPids().isEmpty()) {
+ located += " (cluster = " + state.getClusterPids() + ")";
+ }
String blocked = "";
boolean inbound = support.isAllowed(group, Constants.CATEGORY, pid, EventType.INBOUND);
@@ -126,32 +126,51 @@
private Map<String, ConfigurationState> gatherConfigurations() throws Exception {
Map<String, ConfigurationState> configurations = new HashMap<String, ConfigurationState>();
+ Map<String, List<ConfigurationState>> configurationsByFileName = new HashMap<String, List<ConfigurationState>>();
// retrieve cluster configurations
Map<String, Properties> clusterConfigurations = clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
for (String key : clusterConfigurations.keySet()) {
Properties properties = clusterConfigurations.get(key);
ConfigurationState state = new ConfigurationState();
+ state.setPid(key);
state.setProperties(properties);
state.setCluster(true);
state.setLocal(false);
configurations.put(key, state);
+ String filename = properties.getProperty(ConfigurationSupport.KARAF_CELLAR_FILENAME);
+ if (filename != null) {
+ configurationsByFileName.putIfAbsent(filename, new ArrayList<ConfigurationState>());
+ configurationsByFileName.get(filename).add(state);
+ }
}
// retrieve local configurations
for (Configuration configuration : configurationAdmin.listConfigurations(null)) {
String key = configuration.getPid();
- if (configurations.containsKey(key)) {
- ConfigurationState state = configurations.get(key);
- state.setLocal(true);
- } else {
- ConfigurationState state = new ConfigurationState();
- state.setLocal(true);
+
+ String filename = (String) configuration.getProperties().get(ConfigurationSupport.KARAF_CELLAR_FILENAME);
+
+ ConfigurationState state = configurations.get(key);
+ if (state == null) {
+ state = new ConfigurationState();
state.setCluster(false);
- ConfigurationSupport support = new ConfigurationSupport();
- state.setProperties(support.dictionaryToProperties(configuration.getProperties()));
+ state.setProperties(ConfigurationSupport.dictionaryToProperties(configuration.getProperties()));
configurations.put(key, state);
}
+ state.setLocal(true);
+
+ if (filename != null && configurationsByFileName.containsKey(filename)) {
+ state.setCluster(true);
+ state.setClusterPids(new ArrayList<String>());
+ List<ConfigurationState> states = configurationsByFileName.get(filename);
+ for (ConfigurationState otherState : states) {
+ if (!otherState.getPid().equals(key)) {
+ configurations.remove(otherState.getPid());
+ state.getClusterPids().add(otherState.getPid());
+ }
+ }
+ }
}
return configurations;
@@ -162,6 +181,8 @@
private Properties properties;
private boolean cluster;
private boolean local;
+ private String pid;
+ private List<String> clusterPids;
public Properties getProperties() {
return properties;
@@ -186,6 +207,22 @@
public void setLocal(boolean local) {
this.local = local;
}
+
+ public String getPid() {
+ return pid;
+ }
+
+ public void setPid(String pid) {
+ this.pid = pid;
+ }
+
+ public List<String> getClusterPids() {
+ return clusterPids;
+ }
+
+ public void setClusterPids(List<String> clusterPids) {
+ this.clusterPids = clusterPids;
+ }
}
}