Repository: karaf-cellar
Updated Branches:
  refs/heads/cellar-3.0.x 952b657a2 -> b68374d8a


[KARAF-3614] Refactore the features distributed map to provide a more reliable 
sync behavior


Project: http://git-wip-us.apache.org/repos/asf/karaf-cellar/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf-cellar/commit/b68374d8
Tree: http://git-wip-us.apache.org/repos/asf/karaf-cellar/tree/b68374d8
Diff: http://git-wip-us.apache.org/repos/asf/karaf-cellar/diff/b68374d8

Branch: refs/heads/cellar-3.0.x
Commit: b68374d8afb09092f98b10040f0d617caa28d889
Parents: 952b657
Author: Jean-Baptiste Onofré <[email protected]>
Authored: Mon Mar 16 14:41:24 2015 +0100
Committer: Jean-Baptiste Onofré <[email protected]>
Committed: Mon Mar 16 14:41:24 2015 +0100

----------------------------------------------------------------------
 assembly/src/main/resources/groups.cfg          |  4 +-
 .../apache/karaf/cellar/features/Constants.java |  4 +-
 .../karaf/cellar/features/FeatureState.java     | 30 +------
 .../cellar/features/FeaturesEventHandler.java   |  4 +-
 .../karaf/cellar/features/FeaturesSupport.java  | 82 --------------------
 .../cellar/features/FeaturesSynchronizer.java   | 67 +++++++++-------
 .../cellar/features/LocalFeaturesListener.java  | 37 +++++----
 .../internal/CellarFeaturesMBeanImpl.java       | 18 +++--
 .../features/shell/InstallFeatureCommand.java   |  1 +
 .../features/shell/ListFeaturesCommand.java     |  4 +-
 .../cellar/features/shell/RepoAddCommand.java   |  7 +-
 .../cellar/features/shell/RepoListCommand.java  |  2 +-
 .../features/shell/RepoRemoveCommand.java       |  2 +-
 13 files changed, 87 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/assembly/src/main/resources/groups.cfg
----------------------------------------------------------------------
diff --git a/assembly/src/main/resources/groups.cfg 
b/assembly/src/main/resources/groups.cfg
index b936f19..62a0cfe 100644
--- a/assembly/src/main/resources/groups.cfg
+++ b/assembly/src/main/resources/groups.cfg
@@ -36,8 +36,8 @@ default.config.blacklist.outbound = 
org.apache.felix.fileinstall*, \
 #
 default.feature.whitelist.inbound = *
 default.feature.whitelist.outbound = *
-default.feature.blacklist.inbound = config,management,hazelcast,cellar*
-default.feature.blacklist.outbound = config,management,hazelcast,cellar*
+default.feature.blacklist.inbound = none
+default.feature.blacklist.outbound = none
 
 #
 # The following properties define the behavior to use when the node joins the 
cluster (the usage of the bootstrap

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/Constants.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/Constants.java 
b/features/src/main/java/org/apache/karaf/cellar/features/Constants.java
index e8e9203..01fcc60 100644
--- a/features/src/main/java/org/apache/karaf/cellar/features/Constants.java
+++ b/features/src/main/java/org/apache/karaf/cellar/features/Constants.java
@@ -18,8 +18,8 @@ package org.apache.karaf.cellar.features;
  */
 public class Constants {
 
-    // hazelcast map name
-    public static final String REPOSITORIES_MAP = 
"org.apache.karaf.cellar.repositories";
+    // hazelcast distributed resources name
+    public static final String REPOSITORIES_LIST = 
"org.apache.karaf.cellar.repositories";
     public static final String FEATURES_MAP = 
"org.apache.karaf.cellar.features";
 
     // configuration category

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/FeatureState.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/FeatureState.java 
b/features/src/main/java/org/apache/karaf/cellar/features/FeatureState.java
index c993191..9895947 100644
--- a/features/src/main/java/org/apache/karaf/cellar/features/FeatureState.java
+++ b/features/src/main/java/org/apache/karaf/cellar/features/FeatureState.java
@@ -22,16 +22,10 @@ public class FeatureState implements Serializable {
 
     private String name;
     private String version;
-    private boolean installed;
+    private Boolean installed;
 
     public FeatureState() { }
 
-    public FeatureState(String name, String version, boolean installed) {
-        this.name = name;
-        this.version = version;
-        this.installed = installed;
-    }
-
     public String getName() {
         return name;
     }
@@ -48,7 +42,7 @@ public class FeatureState implements Serializable {
         this.version = version;
     }
 
-    public boolean isInstalled() {
+    public boolean getInstalled() {
         return installed;
     }
 
@@ -56,24 +50,4 @@ public class FeatureState implements Serializable {
         this.installed = installed;
     }
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        FeatureState info = (FeatureState) o;
-
-        if (name != null ? !name.equals(info.name) : info.name != null) return 
false;
-        if (version != null ? !version.equals(info.version) : info.version != 
null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = name != null ? name.hashCode() : 0;
-        result = 31 * result + (version != null ? version.hashCode() : 0);
-        return result;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/FeaturesEventHandler.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/FeaturesEventHandler.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/FeaturesEventHandler.java
index 0cd1644..40c9db8 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/FeaturesEventHandler.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/FeaturesEventHandler.java
@@ -106,10 +106,10 @@ public class FeaturesEventHandler extends FeaturesSupport 
implements EventHandle
                         
options.add(FeaturesService.Option.NoAutoRefreshBundles);
                     }
                     if (version != null) {
-                        LOGGER.debug("CELLAR FEATURES: un-installing feature 
{}/{}", name, version);
+                        LOGGER.debug("CELLAR FEATURES: uninstalling feature 
{}/{}", name, version);
                         featuresService.uninstallFeature(name, version, 
options);
                     } else {
-                        LOGGER.debug("CELLAR FEATURES: un-installing feature 
{}", name);
+                        LOGGER.debug("CELLAR FEATURES: uninstalling feature 
{}", name);
                         featuresService.uninstallFeature(name, options);
                     }
                 }

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSupport.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSupport.java 
b/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSupport.java
index 042c662..cdb4294 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSupport.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSupport.java
@@ -24,7 +24,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.URI;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -81,87 +80,6 @@ public class FeaturesSupport extends CellarSupport {
         return false;
     }
 
-    /**
-     * Push a {@code Feature} and its status in a cluster group.
-     *
-     * @param feature the feature to push in the cluster group.
-     * @param group the cluster group.
-     */
-    public void pushFeature(Feature feature, Group group) {
-        if (feature != null) {
-            String groupName = group.getName();
-            Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
-
-            if (isAllowed(group, Constants.CATEGORY, feature.getName(), 
EventType.OUTBOUND)) {
-                if (featuresService != null && clusterFeatures != null) {
-                    FeatureState state = new FeatureState(feature.getName(), 
feature.getVersion(), featuresService.isInstalled(feature));
-                    clusterFeatures.put(feature.getName() + "/" + 
feature.getVersion() , state);
-                }
-            } else LOGGER.trace("CELLAR FEATURES: feature {} is marked BLOCKED 
OUTBOUND for cluster group {}", feature.getName(), groupName);
-        } else LOGGER.warn("CELLAR FEATURES: feature is null");
-    }
-
-    /**
-     * Push a {@code Feature} and its status in a cluster group.
-     * This version of the method force the bundle status, without looking the 
features service.
-     *
-     * @param feature the feature to push in the cluster group.
-     * @param group the cluster group.
-     * @param force true to force the bundle status (ignoring the features 
service), false else.
-     */
-    public void pushFeature(Feature feature, Group group, Boolean force) {
-        if (feature != null) {
-            String groupName = group.getName();
-            Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
-
-            if (isAllowed(group, Constants.CATEGORY, feature.getName(), 
EventType.OUTBOUND)) {
-                if (featuresService != null && clusterFeatures != null) {
-                    FeatureState state = new FeatureState(feature.getName(), 
feature.getVersion(), force);
-                    clusterFeatures.put(feature.getName() + "/" + 
feature.getVersion(), state);
-                }
-            } else LOGGER.trace("CELLAR FEATURES: feature {} is marked BLOCKED 
OUTBOUND for cluster group {}", feature.getName(), groupName);
-        } else LOGGER.warn("CELLAR FEATURES: feature is null");
-    }
-
-    /**
-     * Push a features {@code Repository} in a cluster group.
-     *
-     * @param repository the features repository to push in the cluster group.
-     * @param group the cluster group.
-     */
-    public void pushRepository(Repository repository, Group group) {
-        String groupName = group.getName();
-        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
-
-        boolean found = false;
-        for (String clusterRepository : clusterRepositories.keySet()) {
-            if (clusterRepository.equals(repository.getURI().toString())) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) {
-            clusterRepositories.put(repository.getURI().toString(), 
repository.getName());
-        }
-    }
-
-    /**
-     * Remove a features {@code Repository} from a cluster group.
-     *
-     * @param repository the features repository to remove from the cluster 
group.
-     * @param group the cluster group.
-     */
-    public void removeRepository(Repository repository, Group group) {
-        String groupName = group.getName();
-        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
-
-        if (featuresService != null && clusterRepositories != null) {
-            URI uri = repository.getURI();
-            clusterRepositories.remove(uri.toString());
-        }
-    }
-
     public FeaturesService getFeaturesService() {
         return featuresService;
     }

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/FeaturesSynchronizer.java
----------------------------------------------------------------------
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 bdf901b..3996e4a 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
@@ -87,60 +87,53 @@ public class FeaturesSynchronizer extends FeaturesSupport 
implements Synchronize
         if (group != null) {
             String groupName = group.getName();
             LOGGER.debug("CELLAR FEATURES: pulling features repositories and 
features from cluster group {}", groupName);
-            Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
-            Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
-            clusterManager.getList(Constants.FEATURES_MAP + 
Configurations.SEPARATOR + groupName);
             ClassLoader originalClassLoader = 
Thread.currentThread().getContextClassLoader();
             try {
                 
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+
+                List<String> clusterRepositories = 
clusterManager.getList(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
+                Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
+
                 // get the features repositories URLs from the cluster group
                 if (clusterRepositories != null && 
!clusterRepositories.isEmpty()) {
-                    for (String url : clusterRepositories.keySet()) {
+                    for (String url : clusterRepositories) {
                         try {
                             if (!isRepositoryRegisteredLocally(url)) {
-                                LOGGER.debug("CELLAR FEATURES: adding new 
features repository {}", url);
+                                LOGGER.debug("CELLAR FEATURES: adding 
repository {}", url);
                                 featuresService.addRepository(new URI(url));
                             }
                         } catch (MalformedURLException e) {
-                            LOGGER.error("CELLAR FEATURES: failed to add 
features repository URL {} (malformed)", url, e);
+                            LOGGER.error("CELLAR FEATURES: failed to add 
repository URL {} (malformed)", url, e);
                         } catch (Exception e) {
-                            LOGGER.error("CELLAR FEATURES: failed to add 
features repository URL {}", url, e);
+                            LOGGER.error("CELLAR FEATURES: failed to add 
repository URL {}", url, e);
                         }
                     }
                 }
 
                 // get the features from the cluster group
                 if (clusterFeatures != null && !clusterFeatures.isEmpty()) {
-                    for (FeatureState info : clusterFeatures.values()) {
-                        String name = info.getName();
+                    for (FeatureState state : clusterFeatures.values()) {
+                        String name = state.getName();
                         // check if feature is blocked
                         if (isAllowed(group, Constants.CATEGORY, name, 
EventType.INBOUND)) {
-                            Boolean remotelyInstalled = info.isInstalled();
-                            Boolean locallyInstalled = 
isFeatureInstalledLocally(info.getName(), info.getVersion());
+                            Boolean clusterInstalled = state.getInstalled();
+                            Boolean locallyInstalled = 
isFeatureInstalledLocally(state.getName(), state.getVersion());
 
                             // prevent NPE
-                            if (remotelyInstalled == null) {
-                                remotelyInstalled = false;
+                            if (clusterInstalled == null) {
+                                clusterInstalled = false;
                             }
                             if (locallyInstalled == null) {
                                 locallyInstalled = false;
                             }
 
                             // if feature has to be installed locally
-                            if (remotelyInstalled && !locallyInstalled) {
-                                try {
-                                    LOGGER.debug("CELLAR FEATURES: installing 
feature {}/{}", info.getName(), info.getVersion());
-                                    
featuresService.installFeature(info.getName(), info.getVersion());
-                                } catch (Exception e) {
-                                    LOGGER.error("CELLAR FEATURES: failed to 
install feature {}/{} ", new Object[]{info.getName(), info.getVersion()}, e);
-                                }
-                                // if feature has to be uninstalled locally
-                            } else if (!remotelyInstalled && locallyInstalled) 
{
+                            if (clusterInstalled && !locallyInstalled) {
                                 try {
-                                    LOGGER.debug("CELLAR FEATURES: 
un-installing feature {}/{}", info.getName(), info.getVersion());
-                                    
featuresService.uninstallFeature(info.getName(), info.getVersion());
+                                    LOGGER.debug("CELLAR FEATURES: installing 
feature {}/{}", state.getName(), state.getVersion());
+                                    
featuresService.installFeature(state.getName(), state.getVersion());
                                 } catch (Exception e) {
-                                    LOGGER.error("CELLAR FEATURES: failed to 
uninstall feature {}/{} ", new Object[]{info.getName(), info.getVersion()}, e);
+                                    LOGGER.error("CELLAR FEATURES: failed to 
install feature {}/{} ", new Object[]{state.getName(), state.getVersion()}, e);
                                 }
                             }
                         } else LOGGER.trace("CELLAR FEATURES: feature {} is 
marked BLOCKED INBOUND for cluster group {}", name, groupName);
@@ -164,8 +157,12 @@ public class FeaturesSynchronizer extends FeaturesSupport 
implements Synchronize
             LOGGER.debug("CELLAR FEATURES: pushing features repositories and 
features in cluster group {}", groupName);
 
             ClassLoader originalClassLoader = 
Thread.currentThread().getContextClassLoader();
-            
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
             try {
+                
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+
+                List<String> clusterRepositories = 
clusterManager.getList(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
+                Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
+
                 Repository[] repositoryList = new Repository[0];
                 Feature[] featuresList = new Feature[0];
 
@@ -179,14 +176,28 @@ public class FeaturesSynchronizer extends FeaturesSupport 
implements Synchronize
                 // push features repositories to the cluster group
                 if (repositoryList != null && repositoryList.length > 0) {
                     for (Repository repository : repositoryList) {
-                        pushRepository(repository, group);
+                        if 
(!clusterRepositories.contains(repository.getURI().toString())) {
+                            
clusterRepositories.add(repository.getURI().toString());
+                            LOGGER.debug("CELLAR FEATURES: pushing repository 
{} in cluster group {}", repository.getName(), groupName);
+                        } else {
+                            LOGGER.debug("CELLAR FEATURES: repository {} is 
already in cluster group {}", repository.getName(), groupName);
+                        }
                     }
                 }
 
                 // push features to the cluster group
                 if (featuresList != null && featuresList.length > 0) {
                     for (Feature feature : featuresList) {
-                        pushFeature(feature, group);
+                        if (isAllowed(group, Constants.CATEGORY, 
feature.getName(), EventType.OUTBOUND)) {
+                            FeatureState clusterFeatureState = new 
FeatureState();
+                            clusterFeatureState.setName(feature.getName());
+                            
clusterFeatureState.setVersion(feature.getVersion());
+                            
clusterFeatureState.setInstalled(featuresService.isInstalled(feature));
+                            clusterFeatures.put(feature.getName() + "/" + 
feature.getVersion(), clusterFeatureState);
+                            LOGGER.debug("CELLAR FEATURES : pushing feature 
{}/{} to cluster group {}", feature.getName(), feature.getVersion(), groupName);
+                        } else {
+                            LOGGER.debug("CELLAR FEATURES: feature {} is 
marked BLOCKED OUTBOUND for cluster group {}", feature.getName(), groupName);
+                        }
                     }
                 }
             } finally {

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/LocalFeaturesListener.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/LocalFeaturesListener.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/LocalFeaturesListener.java
index 70c938b..dc1d4e9 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/LocalFeaturesListener.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/LocalFeaturesListener.java
@@ -26,6 +26,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Dictionary;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -81,11 +82,16 @@ public class LocalFeaturesListener extends FeaturesSupport 
implements org.apache
                         FeatureEvent.EventType type = event.getType();
 
                         // update the features in the cluster group
+                        Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
group.getName());
+                        FeatureState clusterFeatureState = new FeatureState();
+                        
clusterFeatureState.setName(event.getFeature().getName());
+                        
clusterFeatureState.setVersion(event.getFeature().getVersion());
                         if 
(FeatureEvent.EventType.FeatureInstalled.equals(event.getType())) {
-                            pushFeature(event.getFeature(), group, true);
+                            clusterFeatureState.setInstalled(Boolean.TRUE);
                         } else {
-                            pushFeature(event.getFeature(), group, false);
+                            clusterFeatureState.setInstalled(Boolean.FALSE);
                         }
+                        clusterFeatures.put(event.getFeature().getName() + "/" 
+ event.getFeature().getVersion(), clusterFeatureState);
 
                         // broadcast the event
                         ClusterFeaturesEvent featureEvent = new 
ClusterFeaturesEvent(name, version, type);
@@ -128,37 +134,34 @@ public class LocalFeaturesListener extends 
FeaturesSupport implements org.apache
                         clusterRepositoryEvent.setSourceGroup(group);
                         RepositoryEvent.EventType type = event.getType();
 
+                        List<String> clusterRepositories = 
clusterManager.getList(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
group.getName());
+
                         // update the features repositories in the cluster 
group
                         if 
(RepositoryEvent.EventType.RepositoryAdded.equals(type)) {
-                            pushRepository(event.getRepository(), group);
+                            if 
(!clusterRepositories.contains(event.getRepository().getURI().toString())) {
+                                
clusterRepositories.add(event.getRepository().getURI().toString());
+                            }
                             // update the features in the cluster group
                             Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
group.getName());
                             try {
                                 for (Feature feature : 
event.getRepository().getFeatures()) {
                                     // check the feature in the distributed map
-                                    FeatureState featureState = null;
-                                    for (String k : clusterFeatures.keySet()) {
-                                        FeatureState clusterFeature = 
clusterFeatures.get(k);
-                                        if 
(clusterFeature.getName().equals(feature.getName()) && 
clusterFeature.getVersion().equals(feature.getVersion())) {
-                                            featureState = clusterFeature;
-                                            break;
-                                        }
-                                    }
-                                    if (featureState == null) {
-                                        featureState = new 
FeatureState(feature.getName(), feature.getVersion(), 
featuresService.isInstalled(feature));
-                                        clusterFeatures.put(feature.getName() 
+ "/" + feature.getVersion(), featureState);
-                                    }
+                                    FeatureState clusterFeatureState = new 
FeatureState();
+                                    
clusterFeatureState.setName(feature.getName());
+                                    
clusterFeatureState.setVersion(feature.getVersion());
+                                    
clusterFeatureState.setInstalled(Boolean.FALSE);
+                                    clusterFeatures.put(feature.getName() + 
"/" + feature.getVersion(), clusterFeatureState);
                                 }
                             } catch (Exception e) {
                                 LOGGER.warn("CELLAR FEATURES: failed to update 
the cluster group", e);
                             }
                         } else {
-                            removeRepository(event.getRepository(), group);
+                            // update the repositories in the cluster group
+                            
clusterRepositories.remove(event.getRepository().getURI().toString());
                             // update the features in the cluster group
                             Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
group.getName());
                             try {
                                 for (Feature feature : 
event.getRepository().getFeatures()) {
-                                    FeatureState info = new 
FeatureState(feature.getName(), feature.getVersion(), 
featuresService.isInstalled(feature));
                                     clusterFeatures.remove(feature.getName() + 
"/" + feature.getVersion());
                                 }
                             } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
index 3623238..0ae7bf1 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
@@ -320,7 +320,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
 
                     CompositeData data = new CompositeDataSupport(featuresType,
                             new String[]{"name", "version", "installed", 
"located", "blocked"},
-                            new Object[]{feature.getName(), 
feature.getVersion(), feature.isInstalled(), located, blocked});
+                            new Object[]{feature.getName(), 
feature.getVersion(), feature.getInstalled(), located, blocked});
                     table.put(data);
                 }
             }
@@ -340,7 +340,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
             FeatureState state = clusterFeatures.get(key);
             ExtendedFeatureState extendedState = new ExtendedFeatureState();
             extendedState.setName(state.getName());
-            extendedState.setInstalled(state.isInstalled());
+            extendedState.setInstalled(state.getInstalled());
             extendedState.setVersion(state.getVersion());
             extendedState.setCluster(true);
             extendedState.setLocal(true);
@@ -380,7 +380,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
         }
 
         // get the features repositories in the cluster group
-        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
+        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
 
         List<String> result = new ArrayList<String>();
         for (String clusterRepository : clusterRepositories.keySet()) {
@@ -412,7 +412,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
         
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
         try {
             // get the features repositories in the cluster group
-            Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
+            Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
             // get the features in the cluster group
             Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
 
@@ -458,7 +458,10 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
                 clusterRepositories.put(url, name);
 
                 for (Feature feature : repository.getFeatures()) {
-                    FeatureState state = new FeatureState(feature.getName(), 
feature.getVersion(), featuresService.isInstalled(feature));
+                    FeatureState state = new FeatureState();
+                    state.setName(feature.getName());
+                    state.setVersion(feature.getVersion());
+                    state.setInstalled(featuresService.isInstalled(feature));
                     clusterFeatures.put(feature.getName() + "/" + 
feature.getVersion(), state);
                 }
 
@@ -498,7 +501,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
         }
 
         // get the features repositories in the cluster group
-        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
+        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
         // get the features in the cluster group
         Map<FeatureState, Boolean> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
 
@@ -546,8 +549,7 @@ public class CellarFeaturesMBeanImpl extends StandardMBean 
implements CellarFeat
                 clusterRepositories.remove(url);
 
                 for (Feature feature : repository.getFeatures()) {
-                    FeatureState state = new FeatureState(feature.getName(), 
feature.getVersion(), featuresService.isInstalled(feature));
-                    clusterFeatures.remove(state);
+                    clusterFeatures.remove(feature.getName() + "/" + 
feature.getVersion());
                 }
 
                 // un-register the repository if it's not local registered

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/shell/InstallFeatureCommand.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/InstallFeatureCommand.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/InstallFeatureCommand.java
index e5c7ebf..9c36e7e 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/InstallFeatureCommand.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/InstallFeatureCommand.java
@@ -89,6 +89,7 @@ public class InstallFeatureCommand extends 
CellarCommandSupport {
                     // use the version provided by the user
                     version = split[1];
                 }
+
                 FeatureState found = null;
                 String foundKey = null;
                 for (String k : clusterFeatures.keySet()) {

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/shell/ListFeaturesCommand.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/ListFeaturesCommand.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/ListFeaturesCommand.java
index 073112f..f146360 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/ListFeaturesCommand.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/ListFeaturesCommand.java
@@ -91,7 +91,7 @@ public class ListFeaturesCommand extends CellarCommandSupport 
{
 
                     String name = info.getName();
                     String version = info.getVersion();
-                    boolean isInstalled = info.isInstalled();
+                    boolean isInstalled = info.getInstalled();
 
                     String located = "";
                     boolean cluster = info.isCluster();
@@ -147,7 +147,7 @@ public class ListFeaturesCommand extends 
CellarCommandSupport {
             FeatureState state = clusterFeatures.get(key);
             ExtendedFeatureState extendedState = new ExtendedFeatureState();
             extendedState.setName(state.getName());
-            extendedState.setInstalled(state.isInstalled());
+            extendedState.setInstalled(state.getInstalled());
             extendedState.setVersion(state.getVersion());
             extendedState.setCluster(true);
             extendedState.setLocal(true);

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
index b9ea026..ca57b88 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
@@ -67,7 +67,7 @@ public class RepoAddCommand extends CellarCommandSupport {
         
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
         try {
             // get the features repositories in the cluster group
-            Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
+            Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
             // get the features in the cluster group
             Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
 
@@ -115,7 +115,10 @@ public class RepoAddCommand extends CellarCommandSupport {
 
                     // update the features in the cluster group
                     for (Feature feature : repository.getFeatures()) {
-                        FeatureState featureState = new 
FeatureState(feature.getName(), feature.getVersion(), 
featuresService.isInstalled(feature));
+                        FeatureState featureState = new FeatureState();
+                        featureState.setName(feature.getName());
+                        featureState.setVersion(feature.getVersion());
+                        
featureState.setInstalled(featuresService.isInstalled(feature));
                         clusterFeatures.put(feature.getName() + "/" + 
feature.getVersion(), featureState);
                     }
 

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoListCommand.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoListCommand.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoListCommand.java
index 770919d..ba04061 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoListCommand.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoListCommand.java
@@ -87,7 +87,7 @@ public class RepoListCommand extends CellarCommandSupport {
         Map<String, RepositoryState> repositories = new HashMap<String, 
RepositoryState>();
 
         // get the cluster features repositories
-        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
+        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
         for (String url : clusterRepositories.keySet()) {
             RepositoryState state = new RepositoryState();
             state.setCluster(true);

http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/b68374d8/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
----------------------------------------------------------------------
diff --git 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
index 0d3c582..0e11997 100644
--- 
a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
+++ 
b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
@@ -64,7 +64,7 @@ public class RepoRemoveCommand extends CellarCommandSupport {
         }
 
         // get the features repositories in the cluster group
-        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + 
groupName);
+        Map<String, String> clusterRepositories = 
clusterManager.getMap(Constants.REPOSITORIES_LIST + Configurations.SEPARATOR + 
groupName);
         // get the features in the cluster group
         Map<String, FeatureState> clusterFeatures = 
clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + 
groupName);
 

Reply via email to