You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by cc...@apache.org on 2009/02/11 05:59:36 UTC

svn commit: r743226 - in /servicemix/smx4/kernel/trunk/gshell/gshell-features/src: main/java/org/apache/servicemix/kernel/gshell/features/ main/java/org/apache/servicemix/kernel/gshell/features/internal/ main/java/org/apache/servicemix/kernel/gshell/fe...

Author: ccustine
Date: Wed Feb 11 04:59:33 2009
New Revision: 743226

URL: http://svn.apache.org/viewvc?rev=743226&view=rev
Log:
SMX4KNL-94 Provide a JMX frontend on top of the features service

Added:
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesRegistry.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/DefaultNamingStrategy.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeature.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeaturesRegistry.java
      - copied, changed from r742215, servicemix/smx4/nmr/trunk/nmr/management/src/main/java/org/apache/servicemix/nmr/management/ManagementEndpointRegistry.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedRepository.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagementAgent.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/NamingStrategy.java
Modified:
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/Feature.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesService.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeatureImpl.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeaturesServiceImpl.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/RepositoryImpl.java
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/resources/META-INF/spring/gshell-features.xml
    servicemix/smx4/kernel/trunk/gshell/gshell-features/src/test/java/org/apache/servicemix/kernel/gshell/features/FeaturesServiceTest.java

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/Feature.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/Feature.java?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/Feature.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/Feature.java Wed Feb 11 04:59:33 2009
@@ -24,6 +24,8 @@
  */
 public interface Feature {
 
+    String getId();
+
     String getName();
 
     String getVersion();

Added: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesRegistry.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesRegistry.java?rev=743226&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesRegistry.java (added)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesRegistry.java Wed Feb 11 04:59:33 2009
@@ -0,0 +1,35 @@
+/*
+ * 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.servicemix.kernel.gshell.features;
+
+/**
+ * Main interface for a Feature Registry which tracks available and installed features.
+ * Tracks features and repositories.
+ */
+public interface FeaturesRegistry {
+    void register(Feature feature);
+
+    void unregister(Feature feature);
+
+    void registerInstalled(Feature feature);
+
+    void unregisterInstalled(Feature feature);
+
+    void register(Repository repository);
+
+    void unregister(Repository repository);
+}

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesService.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesService.java?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesService.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/FeaturesService.java Wed Feb 11 04:59:33 2009
@@ -16,7 +16,6 @@
  */
 package org.apache.servicemix.kernel.gshell.features;
 
-import java.net.URL;
 import java.net.URI;
 
 /**

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeatureImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeatureImpl.java?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeatureImpl.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeatureImpl.java Wed Feb 11 04:59:33 2009
@@ -22,12 +22,16 @@
 import java.util.Map;
 
 import org.apache.servicemix.kernel.gshell.features.Feature;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.jmx.export.annotation.ManagedAttribute;
 
 /**
  * A feature
  */
+@ManagedResource(description = "Managed Feature", currencyTimeLimit = 15)
 public class FeatureImpl implements Feature {
 
+    private String id;
     private String name;
     private String version;
     private List<Feature> dependencies = new ArrayList<Feature>();
@@ -43,12 +47,20 @@
     public FeatureImpl(String name, String version) {
     	this.name = name;
     	this.version = version;
+        this.id = name + "-" + version;
     }
 
+    @ManagedAttribute(description = "Feature Unique ID")
+    public String getId() {
+        return id;
+    }
+
+    @ManagedAttribute(description = "Feature Name")
     public String getName() {
         return name;
     }
 
+    @ManagedAttribute(description = "Feature Version")
     public String getVersion() {
 		return version;
 	}
@@ -57,6 +69,7 @@
 		this.version = version;
 	}
 
+    @ManagedAttribute(description = "List of Dependencies")
     public List<Feature> getDependencies() {
         return dependencies;
     }

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeaturesServiceImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeaturesServiceImpl.java?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeaturesServiceImpl.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/FeaturesServiceImpl.java Wed Feb 11 04:59:33 2009
@@ -41,6 +41,7 @@
 import org.apache.servicemix.kernel.gshell.features.Feature;
 import org.apache.servicemix.kernel.gshell.features.FeaturesService;
 import org.apache.servicemix.kernel.gshell.features.Repository;
+import org.apache.servicemix.kernel.gshell.features.FeaturesRegistry;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -76,6 +77,7 @@
     private Map<Feature, Set<Long>> installed = new HashMap<Feature, Set<Long>>();
     private String boot;
     private boolean bootFeaturesInstalled;
+    private FeaturesRegistry featuresRegistry;
 
     public BundleContext getBundleContext() {
         return bundleContext;
@@ -101,6 +103,10 @@
         this.preferences = preferences;
     }
 
+    public void setFeaturesServiceRegistry(FeaturesRegistry featuresRegistry) {
+        this.featuresRegistry = featuresRegistry;
+    }
+
     public void setUrls(String uris) throws URISyntaxException {
         String[] s = uris.split(",");
         this.uris = new HashSet<URI>();
@@ -123,6 +129,7 @@
     protected void internalAddRepository(URI uri) throws Exception {
         RepositoryImpl repo = new RepositoryImpl(uri);
         repositories.put(uri, repo);
+        featuresRegistry.register(repo);
         features = null;
     }
 
@@ -134,6 +141,7 @@
     }
 
     public void internalRemoveRepository(URI uri) {
+        featuresRegistry.unregister(repositories.get(uri));
         repositories.remove(uri);
         features = null;
     }
@@ -184,7 +192,8 @@
             b.start();
             bundles.add(b.getBundleId());
         }
-        
+
+        featuresRegistry.registerInstalled(f);
         installed.put(f, bundles);
         saveState();
     }
@@ -241,6 +250,7 @@
         for (long bundleId : bundles) {
             getBundleContext().getBundle(bundleId).uninstall();
         }
+        featuresRegistry.unregisterInstalled(feature);
         saveState();
     }
 

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/RepositoryImpl.java?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/RepositoryImpl.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/internal/RepositoryImpl.java Wed Feb 11 04:59:33 2009
@@ -37,10 +37,14 @@
 import org.apache.servicemix.kernel.gshell.features.Feature;
 import org.apache.servicemix.kernel.gshell.features.Repository;
 import org.xml.sax.SAXException;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedOperation;
 
 /**
  * The repository implementation.
  */
+@ManagedResource
 public class RepositoryImpl implements Repository {
 
     private URI uri;
@@ -51,10 +55,12 @@
         this.uri = uri;
     }
 
+    @ManagedAttribute
     public URI getURI() {
         return uri;
     }
 
+    @ManagedOperation
     public URI[] getRepositories() throws Exception {
         if (repositories == null) {
             load();
@@ -62,6 +68,7 @@
         return repositories.toArray(new URI[repositories.size()]);
     }
 
+    @ManagedOperation(description = "List of Features provided by this repository")
     public Feature[] getFeatures() throws Exception {
         if (features == null) {
             load();

Added: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/DefaultNamingStrategy.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/DefaultNamingStrategy.java?rev=743226&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/DefaultNamingStrategy.java (added)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/DefaultNamingStrategy.java Wed Feb 11 04:59:33 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.servicemix.kernel.gshell.features.management;
+
+import javax.management.ObjectName;
+import javax.management.MalformedObjectNameException;
+
+import org.apache.servicemix.kernel.gshell.features.FeaturesRegistry;
+
+/**
+ * Naming strategy for JMX MBeans.
+ */
+public class DefaultNamingStrategy implements NamingStrategy {
+
+    private String jmxDomainName;
+
+    public String getJmxDomainName() {
+        return jmxDomainName;
+    }
+
+    public void setJmxDomainName(String jmxDomainName) {
+        this.jmxDomainName = jmxDomainName;
+    }
+
+    public ObjectName getObjectName(ManagedFeature feature) throws MalformedObjectNameException {
+        return getObjectName(feature, false);
+    }
+
+    public ObjectName getObjectName(ManagedFeature feature, boolean installed) throws MalformedObjectNameException {
+        StringBuffer sb = new StringBuffer();
+        sb.append(jmxDomainName).append(":Service=Features,");
+
+        if (installed) {
+            sb.append("Type=Installed,");
+        } else {
+            sb.append("Type=Available,");
+        }
+
+        sb.append("Name=").append(sanitize(feature.getName())).append(",")
+          .append("FeatureVersion=").append(sanitize(feature.getVersion()));
+
+        return new ObjectName(sb.toString());
+    }
+
+    public ObjectName getObjectName(ManagedRepository repository) throws MalformedObjectNameException {
+        return new ObjectName(jmxDomainName + ":" +
+                                    "Service=Features," +
+                                    "Type=Repositories," +
+                                    "Name=" + sanitize(repository.getUri().toString())); // + "," +
+    }
+
+    public ObjectName getObjectName(FeaturesRegistry featuresRegistry) throws MalformedObjectNameException {
+        return new ObjectName(jmxDomainName + ":" +
+                                    "Service=Features," +
+                                    "Name=FeaturesService");
+    }
+
+    private String sanitize(String in) {
+        String result = null;
+        if (in != null) {
+            result = in.replace(':', '_');
+            result = result.replace('/', '_');
+            result = result.replace('\\', '_');
+            result = result.replace('?', '_');
+            result = result.replace('=', '_');
+            result = result.replace(',', '_');
+        }
+        return result;
+    }
+}
\ No newline at end of file

Added: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeature.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeature.java?rev=743226&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeature.java (added)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeature.java Wed Feb 11 04:59:33 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.servicemix.kernel.gshell.features.management;
+
+import java.util.List;
+
+import org.apache.servicemix.kernel.gshell.features.Feature;
+import org.apache.servicemix.kernel.gshell.features.FeaturesService;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+
+/**
+ * Managed Repository MBean
+ */
+@ManagedResource(description = "Feature")
+public class ManagedFeature {
+    private Feature feature;
+    private FeaturesService featuresService;
+    private String id;
+
+    public ManagedFeature(Feature feature, FeaturesService featuresService) {
+        this.feature = feature;
+        id = feature.getName() + "-" + feature.getVersion();
+        this.featuresService = featuresService;
+    }
+
+    @ManagedAttribute
+    public String getId() {
+        return id;    
+    }
+
+    @ManagedAttribute
+    public String getName() {
+        return feature.getName();
+    }
+
+    @ManagedAttribute
+    public String getVersion() {
+        return feature.getVersion();
+    }
+
+    @ManagedAttribute
+    public List<Feature> getDependencies() {
+        return feature.getDependencies();
+    }
+
+    @ManagedAttribute
+    public List<String> getBundles() {
+        return feature.getBundles();
+    }
+
+    @ManagedOperation
+    public void uninstallFeature() throws Exception {
+        featuresService.uninstallFeature(feature.getName(), feature.getVersion());
+    }
+
+    @ManagedOperation
+    public void installFeature() throws Exception {
+        featuresService.installFeature(feature.getName(), feature.getVersion());
+    }
+
+}
+

Copied: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeaturesRegistry.java (from r742215, servicemix/smx4/nmr/trunk/nmr/management/src/main/java/org/apache/servicemix/nmr/management/ManagementEndpointRegistry.java)
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeaturesRegistry.java?p2=servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeaturesRegistry.java&p1=servicemix/smx4/nmr/trunk/nmr/management/src/main/java/org/apache/servicemix/nmr/management/ManagementEndpointRegistry.java&r1=742215&r2=743226&rev=743226&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/management/src/main/java/org/apache/servicemix/nmr/management/ManagementEndpointRegistry.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedFeaturesRegistry.java Wed Feb 11 04:59:33 2009
@@ -14,121 +14,158 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicemix.nmr.management;
+package org.apache.servicemix.kernel.gshell.features.management;
 
+import java.net.URI;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import javax.management.MBeanServer;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.servicemix.nmr.api.Exchange;
-import org.apache.servicemix.nmr.api.Role;
-import org.apache.servicemix.nmr.api.Status;
-import org.apache.servicemix.nmr.api.event.ExchangeListener;
-import org.apache.servicemix.nmr.api.internal.InternalEndpoint;
-import org.apache.servicemix.nmr.api.internal.InternalExchange;
+import org.apache.servicemix.kernel.gshell.features.Feature;
+import org.apache.servicemix.kernel.gshell.features.FeaturesService;
+import org.apache.servicemix.kernel.gshell.features.Repository;
+import org.apache.servicemix.kernel.gshell.features.FeaturesRegistry;
 import org.springframework.beans.factory.InitializingBean;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedResource;
 
 /**
+ * The FeaturesServiceRegistry maintains the managed Features and Repositories
+ * for JMX management.
  */
-public class ManagementEndpointRegistry implements ExchangeListener, InitializingBean {
+@ManagedResource(description = "Features Service Registry and Management")
+public class ManagedFeaturesRegistry implements InitializingBean, FeaturesRegistry {
 
-    private static final transient Log LOG = LogFactory.getLog(ManagementEndpointRegistry.class);
+    private static final transient Log LOG = LogFactory.getLog(ManagedFeaturesRegistry.class);
 
     private NamingStrategy namingStrategy;
     private ManagementAgent managementAgent;
-    private Map<String, ManagedEndpoint> endpoints;
+    private Map<String, ManagedFeature> availableFeatures;
+    private Map<String, ManagedFeature> installedFeatures;
+    private Map<String, ManagedRepository> repositories;
+    private boolean mbeanServerInitialized;
+    private FeaturesService featuresService;
 
-    public ManagementEndpointRegistry() {
-        endpoints = new ConcurrentHashMap<String, ManagedEndpoint>();
+    @ManagedOperation
+    public void installFeature(String name) throws Exception {
+        featuresService.installFeature(name);
     }
 
-    public NamingStrategy getNamingStrategy() {
-        return namingStrategy;
+    @ManagedOperation
+    public void installFeature(String name, String version) throws Exception {
+        featuresService.installFeature(name, version);
     }
 
-    public void setNamingStrategy(NamingStrategy namingStrategy) {
-        this.namingStrategy = namingStrategy;
+    @ManagedOperation
+    public void installRepository(String repositoryUri) throws Exception {
+        featuresService.addRepository(new URI(repositoryUri));
+    }
+
+    public ManagedFeaturesRegistry() {
+        availableFeatures = new ConcurrentHashMap<String, ManagedFeature>();
+        installedFeatures = new ConcurrentHashMap<String, ManagedFeature>();
+        repositories = new ConcurrentHashMap<String, ManagedRepository>();
     }
 
-    public ManagementAgent getManagementAgent() {
-        return managementAgent;
+    public void setFeaturesService(FeaturesService featuresService) {
+        this.featuresService = featuresService;
+    }
+
+    public void setNamingStrategy(NamingStrategy namingStrategy) {
+        this.namingStrategy = namingStrategy;
     }
 
     public void setManagementAgent(ManagementAgent managementAgent) {
         this.managementAgent = managementAgent;
     }
 
-    public void register(InternalEndpoint endpoint, Map<String, ?> properties) {
+    public void register(Feature feature) {
+        try {
+            LOG.info("Registering feature: " + feature);
+            ManagedFeature mf = new ManagedFeature(feature, featuresService);
+            availableFeatures.put(feature.getId(), mf);
+            if ( mbeanServerInitialized ) {
+                managementAgent.register(mf, namingStrategy.getObjectName(mf));
+            }
+        } catch (Exception e) {
+            LOG.warn("Unable to register managed feature: " + e, e);
+        }
+    }
+
+    public void unregister(Feature feature) {
+        try {
+            LOG.info("Unregistering feature: " + feature);
+            ManagedFeature mf = availableFeatures.remove(feature.getId());
+            if ( mbeanServerInitialized ) {
+                managementAgent.unregister(namingStrategy.getObjectName(mf));
+            }
+        } catch (Exception e) {
+            LOG.warn("Unable to unregister managed feature: " + e, e);
+        }
+    }
+
+    public void registerInstalled(Feature feature) {
         try {
-            LOG.info("Registering endpoint: " + endpoint + " with properties " + properties);
-            ManagedEndpoint ep = new ManagedEndpoint(endpoint, properties);
-            endpoints.put(endpoint.getId(), ep);
-            managementAgent.register(ep, namingStrategy.getObjectName(ep));
+            LOG.info("Registering installed feature: " + feature);
+            ManagedFeature mf = new ManagedFeature(feature, featuresService);
+            installedFeatures.put(feature.getId(), mf);
+            if ( mbeanServerInitialized ) {
+                managementAgent.register(mf, namingStrategy.getObjectName(mf, true));
+            }
         } catch (Exception e) {
-            LOG.warn("Unable to register managed endpoint: " + e, e);
+            LOG.warn("Unable to register managed feature: " + e, e);
         }
     }
 
-    public void unregister(InternalEndpoint endpoint, Map<String, ?> properties) {
+    public void unregisterInstalled(Feature feature) {
         try {
-            LOG.info("Unregistering endpoint: " + endpoint + " with properties " + properties);
-            ManagedEndpoint ep = endpoints.remove(endpoint.getId());
-            managementAgent.unregister(namingStrategy.getObjectName(ep));
+            LOG.info("Unregistering installed feature: " + feature);
+            ManagedFeature mf = installedFeatures.remove(feature.getId());
+            if ( mbeanServerInitialized ) {
+                managementAgent.unregister(namingStrategy.getObjectName(mf, true));
+            }
         } catch (Exception e) {
-            LOG.warn("Unable to unregister managed endpoint: " + e, e);
+            LOG.warn("Unable to unregister managed feature: " + e, e);
         }
     }
 
-    public void exchangeSent(Exchange exchange) {
+    public void register(Repository repository) {
         try {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Sending exchange: " + exchange);
+            LOG.info("Registering repository: " + repository);
+            ManagedRepository mr = new ManagedRepository(repository, featuresService);
+            repositories.put(repository.getURI().toString(), mr);
+
+            for (Feature f : repository.getFeatures()) {
+                // TODO: Associate the feature with the Repo?
+                register(f);
             }
-            if (exchange.getStatus() == Status.Active &&
-                    exchange.getRole() == Role.Consumer &&
-                    exchange.getOut(false) == null &&
-                    exchange.getFault(false) == null &&
-                    exchange instanceof InternalExchange) {
-                String id = ((InternalExchange) exchange).getSource().getId();
-                if (LOG.isTraceEnabled()) {
-                    LOG.trace("Source endpoint: " + id + " (known endpoints: " + endpoints + ")");
-                }
-                ManagedEndpoint me = endpoints.get(id);
-                if (me == null) {
-                    LOG.warn("No managed endpoint registered with id: " + id);
-                } else {
-                    me.incrementOutbound();
-                }
+
+            if ( mbeanServerInitialized ) {
+                managementAgent.register(mr, namingStrategy.getObjectName(mr));
             }
-        } catch (Throwable t) {
-            LOG.warn("Caught exception while processing exchange: " + t, t);
+        } catch (Exception e) {
+            LOG.warn("Unable to register managed repository: " + e, e);
         }
     }
 
-    public void exchangeDelivered(Exchange exchange) {
+    public void unregister(Repository repository) {
         try {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Receiving exchange: " + exchange);
+            LOG.info("Unregistering repository: " + repository);
+            ManagedRepository mr = repositories.remove(repository.getURI().toString());
+
+            for (Feature f : repository.getFeatures()) {
+                // TODO: Associate the feature with the Repo?
+                unregister(f);
             }
-            if (exchange.getStatus() == Status.Active &&
-                    exchange.getRole() == Role.Provider &&
-                    exchange.getOut(false) == null &&
-                    exchange.getFault(false) == null &&
-                    exchange instanceof InternalExchange) {
-                String id = ((InternalExchange) exchange).getDestination().getId();
-                if (LOG.isTraceEnabled()) {
-                    LOG.trace("Dest endpoint: " + id + " (known endpoints: " + endpoints + ")");
-                }
-                ManagedEndpoint me = endpoints.get(id);
-                if (me == null) {
-                    LOG.warn("No managed endpoint registered with id: " + id);
-                } else {
-                    me.incrementInbound();
-                }
+
+            if ( mbeanServerInitialized ) {
+                managementAgent.unregister(namingStrategy.getObjectName(mr));
             }
-        } catch (Throwable t) {
-            LOG.warn("Caught exception while processing exchange: " + t, t);
+        } catch (Exception e) {
+            LOG.warn("Unable to unregister managed repository: " + e, e);
         }
     }
 
@@ -140,4 +177,23 @@
             throw new IllegalArgumentException("namingStrategy must not be null");
         }
     }
-}
+
+    public void registerMBeanServer(MBeanServer mbeanServer, Map props ) throws Exception {
+        if (mbeanServer != null) {
+            mbeanServerInitialized = true;
+        }
+
+        managementAgent.register(this, namingStrategy.getObjectName(this));
+
+        for (ManagedRepository repository : repositories.values()) {
+            managementAgent.register(repository, namingStrategy.getObjectName(repository));
+        }
+
+        for (ManagedFeature feature : availableFeatures.values()) {
+            managementAgent.register(feature, namingStrategy.getObjectName(feature));
+        }
+
+    }
+
+    
+}
\ No newline at end of file

Added: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedRepository.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedRepository.java?rev=743226&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedRepository.java (added)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagedRepository.java Wed Feb 11 04:59:33 2009
@@ -0,0 +1,57 @@
+/*
+ * 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.servicemix.kernel.gshell.features.management;
+
+import java.net.URI;
+
+import org.apache.servicemix.kernel.gshell.features.Feature;
+import org.apache.servicemix.kernel.gshell.features.FeaturesService;
+import org.apache.servicemix.kernel.gshell.features.Repository;
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+
+@ManagedResource(description = "Features Repository")
+public class ManagedRepository {
+    private Repository repository;
+    private FeaturesService featuresService;
+
+    public ManagedRepository(Repository repository, FeaturesService featuresService) {
+        this.repository = repository;
+        this.featuresService = featuresService;
+    }
+
+    @ManagedAttribute
+    public URI getUri() {
+        return repository.getURI();
+    }
+
+    @ManagedAttribute
+    public URI[] getRepositories() throws Exception {
+        return repository.getRepositories();
+    }
+
+    @ManagedAttribute
+    public Feature[] getFeatures() throws Exception {
+        return repository.getFeatures();
+    }
+
+    @ManagedOperation
+    public void removeRepository() throws Exception {
+        featuresService.removeRepository(repository.getURI());
+    }
+}

Added: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagementAgent.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagementAgent.java?rev=743226&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagementAgent.java (added)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/ManagementAgent.java Wed Feb 11 04:59:33 2009
@@ -0,0 +1,133 @@
+/*
+ * 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.servicemix.kernel.gshell.features.management;
+
+import java.util.Set;
+import java.util.HashSet;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.JMException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectInstance;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.RequiredModelMBean;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+
+import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
+import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
+import org.springframework.beans.factory.DisposableBean;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Management Agent that registers MBeans with JMX MBeanServer.
+ */
+public class ManagementAgent implements DisposableBean {
+
+    private static final transient Log LOG = LogFactory.getLog(ManagementAgent.class);
+
+    private MBeanServer mbeanServer;
+    private MetadataMBeanInfoAssembler assembler;
+    private Set<ObjectName> mbeans = new HashSet<ObjectName>();
+
+    public ManagementAgent() {
+        assembler = new MetadataMBeanInfoAssembler();
+        assembler.setAttributeSource(new AnnotationJmxAttributeSource());
+    }
+
+    public MBeanServer getMbeanServer() {
+        return mbeanServer;
+    }
+
+    public void setMbeanServer(MBeanServer mbeanServer) {
+        this.mbeanServer = mbeanServer;
+    }
+
+    public void destroy() throws Exception {
+        // Using the array to hold the busMBeans to avoid the
+        // CurrentModificationException
+        Object[] mBeans = mbeans.toArray();
+        int caught = 0;
+        for (Object name : mBeans) {
+            mbeans.remove((ObjectName)name);
+            try {
+                unregister((ObjectName)name);
+            } catch (JMException jmex) {
+                LOG.info("Exception unregistering MBean", jmex);
+                caught++;
+            }
+        }
+        if (caught > 0) {
+            LOG.warn("A number of " + caught
+                     + " exceptions caught while unregistering MBeans during stop operation.  "
+                     + "See INFO log for details.");
+        }
+    }
+
+    public void register(Object obj, ObjectName name) throws JMException {
+        register(obj, name, false);
+    }
+
+    public void register(Object obj, ObjectName name, boolean forceRegistration) throws JMException {
+        try {
+            registerMBeanWithServer(obj, name, forceRegistration);
+        } catch (NotCompliantMBeanException e) {
+            // If this is not a "normal" MBean, then try to deploy it using JMX
+            // annotations
+            LOG.info("It's not a normal MBean");
+            ModelMBeanInfo mbi = assembler.getMBeanInfo(obj, name.toString());
+            RequiredModelMBean mbean = (RequiredModelMBean) mbeanServer.instantiate(RequiredModelMBean.class.getName());
+            mbean.setModelMBeanInfo(mbi);
+            try {
+                mbean.setManagedResource(obj, "ObjectReference");
+            } catch (InvalidTargetObjectTypeException itotex) {
+                throw new JMException(itotex.getMessage());
+            }
+            registerMBeanWithServer(mbean, name, forceRegistration);
+        }
+    }
+
+    public synchronized void unregister(ObjectName name) throws JMException {
+        if (mbeans.contains(name)) {
+            //check if this bean already get removed in destory method
+            mbeanServer.unregisterMBean(name);
+        }
+    }
+
+    private void registerMBeanWithServer(Object obj, ObjectName name, boolean forceRegistration) throws JMException {
+        ObjectInstance instance = null;
+        try {
+            instance = mbeanServer.registerMBean(obj, name);
+        } catch (InstanceAlreadyExistsException e) {
+            if (forceRegistration) {
+                mbeanServer.unregisterMBean(name);
+                instance = mbeanServer.registerMBean(obj, name);
+            } else {
+                throw e;
+            }
+        } catch (NotCompliantMBeanException e) {
+            throw e;
+        }
+
+        if (instance != null) {
+            mbeans.add(name);
+        }
+    }
+
+}
\ No newline at end of file

Added: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/NamingStrategy.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/NamingStrategy.java?rev=743226&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/NamingStrategy.java (added)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/kernel/gshell/features/management/NamingStrategy.java Wed Feb 11 04:59:33 2009
@@ -0,0 +1,35 @@
+/*
+ * 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.servicemix.kernel.gshell.features.management;
+
+import javax.management.ObjectName;
+import javax.management.MalformedObjectNameException;
+
+import org.apache.servicemix.kernel.gshell.features.FeaturesRegistry;
+
+public interface NamingStrategy {
+
+    ObjectName getObjectName(ManagedFeature feature) throws MalformedObjectNameException;
+
+    ObjectName getObjectName(ManagedFeature feature, boolean installed) throws MalformedObjectNameException;
+
+    ObjectName getObjectName(ManagedRepository component) throws MalformedObjectNameException;
+
+    String getJmxDomainName();
+
+    ObjectName getObjectName(FeaturesRegistry features) throws MalformedObjectNameException;
+}
\ No newline at end of file

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/resources/META-INF/spring/gshell-features.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/resources/META-INF/spring/gshell-features.xml?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/resources/META-INF/spring/gshell-features.xml (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/resources/META-INF/spring/gshell-features.xml Wed Feb 11 04:59:33 2009
@@ -69,6 +69,21 @@
         <property name="boot" value="${featuresBoot}" />
         <property name="configAdmin" ref="configAdmin" />
         <property name="preferences" ref="preferences" />
+        <property name="featuresServiceRegistry" ref="featureServiceRegistry" />
+    </bean>
+
+    <bean id="namingStrategy" class="org.apache.servicemix.kernel.gshell.features.management.DefaultNamingStrategy">
+        <property name="jmxDomainName" value="org.apache.servicemix" />
+    </bean>
+
+    <bean id="managementAgent" class="org.apache.servicemix.kernel.gshell.features.management.ManagementAgent">
+        <property name="mbeanServer" ref="mbeanServer" />
+    </bean>
+
+    <bean id="featureServiceRegistry" class="org.apache.servicemix.kernel.gshell.features.management.ManagedFeaturesRegistry">
+        <property name="managementAgent" ref="managementAgent" />
+        <property name="namingStrategy" ref="namingStrategy" />
+        <property name="featuresService" ref="featuresService" />
     </bean>
 
     <osgi:reference id="configAdmin" interface="org.osgi.service.cm.ConfigurationAdmin" />
@@ -84,4 +99,10 @@
 
     <ctx:property-placeholder properties-ref="cmProps" />
 
+    <osgi:reference id="mbeanServer"
+                    interface="javax.management.MBeanServer"
+                    cardinality="0..1" >
+        <osgi:listener ref="featureServiceRegistry" bind-method="registerMBeanServer" />
+    </osgi:reference>
+
 </beans>
\ No newline at end of file

Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/test/java/org/apache/servicemix/kernel/gshell/features/FeaturesServiceTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/test/java/org/apache/servicemix/kernel/gshell/features/FeaturesServiceTest.java?rev=743226&r1=743225&r2=743226&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/test/java/org/apache/servicemix/kernel/gshell/features/FeaturesServiceTest.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/test/java/org/apache/servicemix/kernel/gshell/features/FeaturesServiceTest.java Wed Feb 11 04:59:33 2009
@@ -17,10 +17,8 @@
 package org.apache.servicemix.kernel.gshell.features;
 
 import java.net.URI;
-import java.net.URL;
 import java.io.InputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.PrintWriter;
 
@@ -28,6 +26,7 @@
 
 import org.apache.servicemix.kernel.gshell.features.internal.FeatureImpl;
 import org.apache.servicemix.kernel.gshell.features.internal.FeaturesServiceImpl;
+import org.apache.servicemix.kernel.gshell.features.FeaturesRegistry;
 import org.easymock.EasyMock;
 import org.osgi.service.prefs.PreferencesService;
 import org.osgi.service.prefs.Preferences;
@@ -62,6 +61,7 @@
         Preferences featuresNode = EasyMock.createMock(Preferences.class);
         BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
         Bundle installedBundle = EasyMock.createMock(Bundle.class);
+        FeaturesRegistry featuresRegistry = EasyMock.createNiceMock(FeaturesRegistry.class);
 
         expect(preferencesService.getUserPreferences("FeaturesServiceState")).andStubReturn(prefs);
         expect(prefs.node("repositories")).andReturn(repositoriesNode);
@@ -72,12 +72,14 @@
         featuresNode.clear();
         prefs.putBoolean("bootFeaturesInstalled", false);
         prefs.flush();
+        featuresRegistry.register(isA(Repository.class));
 
-        replay(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle);
+        replay(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle, featuresRegistry);
 
         FeaturesServiceImpl svc = new FeaturesServiceImpl();
         svc.setPreferences(preferencesService);
         svc.setBundleContext(bundleContext);
+        svc.setFeaturesServiceRegistry(featuresRegistry);
         svc.addRepository(uri);
         
         Repository[] repositories = svc.listRepositories();
@@ -95,9 +97,9 @@
         assertEquals(1, features[0].getBundles().size());
         assertEquals(name, features[0].getBundles().get(0));
 
-        verify(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle);
+        verify(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle, featuresRegistry);
 
-        reset(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle);
+        reset(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle, featuresRegistry);
 
         expect(bundleContext.getBundles()).andReturn(new Bundle[0]);
         expect(bundleContext.installBundle(isA(String.class),