Bug 2853 : Adding Remote RPC MX bean 58/19358/2
authorHarman Singh <harmasin@cisco.com>
Thu, 30 Apr 2015 01:26:44 +0000 (18:26 -0700)
committerHarman Singh <harmasin@cisco.com>
Thu, 30 Apr 2015 18:23:52 +0000 (18:23 +0000)
This bean gives three attributes - bucket versions,local registered routed rpc names and global rpc
bucket versions will give information of latest version of remote rpc buckets on all nodes of cluster.
Name of locally registered RPCs can be found in other two attributes.

Two Search operations - findByRpcName and findByRpcRoute helps to search RPCs registered in cluster
via name or route keyword. Search happens in both local and remote bucket.

Change-Id: Ief08eb2e42deafdf2627c61e58c2e2a50f7dcd09
Signed-off-by: Harman Singh <harmasin@cisco.com>
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBean.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBeanImpl.java [new file with mode: 0644]

index f12fda0..f3cb78a 100644 (file)
@@ -75,7 +75,7 @@ public class RpcManager extends AbstractUntypedActor {
         LOG.debug("Create rpc registry and broker actors");
 
         rpcRegistry =
-                getContext().actorOf(Props.create(RpcRegistry.class).
+                getContext().actorOf(RpcRegistry.props().
                     withMailbox(config.getMailBoxName()), config.getRpcRegistryName());
 
         rpcBroker =
index f67657f..fa93a3b 100644 (file)
@@ -13,6 +13,8 @@ import akka.japi.Pair;
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+
 import org.opendaylight.controller.remote.rpc.registry.gossip.Copier;
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 
@@ -41,6 +43,10 @@ public class RoutingTable implements Copier<RoutingTable>, Serializable {
         }
     }
 
+    public Set<RpcRouter.RouteIdentifier<?, ?, ?>> getRoutes() {
+        return table.keySet();
+    }
+
     public void addRoute(RpcRouter.RouteIdentifier<?,?,?> routeId){
         table.put(routeId, System.currentTimeMillis());
     }
index 219646d..1dcc4e1 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.controller.remote.rpc.registry;
 
 import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.japi.Creator;
 import akka.japi.Option;
 import akka.japi.Pair;
 import com.google.common.base.Preconditions;
@@ -19,6 +21,8 @@ import org.opendaylight.controller.remote.rpc.registry.RpcRegistry.Messages.Remo
 import org.opendaylight.controller.remote.rpc.registry.RpcRegistry.Messages.SetLocalRouter;
 import org.opendaylight.controller.remote.rpc.registry.gossip.Bucket;
 import org.opendaylight.controller.remote.rpc.registry.gossip.BucketStore;
+import org.opendaylight.controller.remote.rpc.registry.mbeans.RemoteRpcRegistryMXBean;
+import org.opendaylight.controller.remote.rpc.registry.mbeans.RemoteRpcRegistryMXBeanImpl;
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.controller.sal.connector.api.RpcRouter.RouteIdentifier;
 
@@ -34,6 +38,10 @@ public class RpcRegistry extends BucketStore<RoutingTable> {
         getLocalBucket().setData(new RoutingTable());
     }
 
+    public static Props props() {
+        return Props.create(new RpcRegistryCreator());
+    }
+
     @Override
     protected void handleReceive(Object message) throws Exception {
         //TODO: if sender is remote, reject message
@@ -220,4 +228,15 @@ public class RpcRegistry extends BucketStore<RoutingTable> {
             }
         }
     }
+
+    private static class RpcRegistryCreator implements Creator<RpcRegistry> {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public RpcRegistry create() throws Exception {
+            RpcRegistry registry =  new RpcRegistry();
+            RemoteRpcRegistryMXBean mxBean = new RemoteRpcRegistryMXBeanImpl(registry);
+            return registry;
+        }
+    }
 }
index 628deb4..febff0b 100644 (file)
@@ -13,7 +13,6 @@ import akka.actor.ActorRefProvider;
 import akka.actor.Address;
 import akka.actor.Props;
 import akka.cluster.ClusterActorRefProvider;
-import com.google.common.annotations.VisibleForTesting;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -230,7 +229,7 @@ public class BucketStore<T extends Copier<T>> extends AbstractUntypedActorWithMe
         }
     }
 
-    protected BucketImpl<T> getLocalBucket() {
+    public BucketImpl<T> getLocalBucket() {
         return localBucket;
     }
 
@@ -239,12 +238,11 @@ public class BucketStore<T extends Copier<T>> extends AbstractUntypedActorWithMe
         versions.put(selfAddress, localBucket.getVersion());
     }
 
-    protected Map<Address, Bucket<T>> getRemoteBuckets() {
+    public Map<Address, Bucket<T>> getRemoteBuckets() {
         return remoteBuckets;
     }
 
-    @VisibleForTesting
-    Map<Address, Long> getVersions() {
+    public Map<Address, Long> getVersions() {
         return versions;
     }
 }
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBean.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBean.java
new file mode 100644 (file)
index 0000000..ddd3333
--- /dev/null
@@ -0,0 +1,22 @@
+package org.opendaylight.controller.remote.rpc.registry.mbeans;
+
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * JMX bean to check remote rpc registry
+ */
+
+public interface RemoteRpcRegistryMXBean {
+
+    Set<String> getGlobalRpc();
+
+    String getBucketVersions();
+
+    Set<String> getLocalRegisteredRoutedRpc();
+
+    Map<String,String> findRpcByName(String name);
+
+    Map<String,String> findRpcByRoute(String route);
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBeanImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBeanImpl.java
new file mode 100644 (file)
index 0000000..c7d9b99
--- /dev/null
@@ -0,0 +1,156 @@
+package org.opendaylight.controller.remote.rpc.registry.mbeans;
+
+import akka.actor.Address;
+import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
+import org.opendaylight.controller.remote.rpc.registry.RoutingTable;
+import org.opendaylight.controller.remote.rpc.registry.RpcRegistry;
+import org.opendaylight.controller.remote.rpc.registry.gossip.Bucket;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+
+public class RemoteRpcRegistryMXBeanImpl extends AbstractMXBean implements RemoteRpcRegistryMXBean {
+
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final String NULL_CONSTANT = "null";
+
+    private final String LOCAL_CONSTANT = "local";
+
+    private final String ROUTE_CONSTANT = "route:";
+
+    private final String NAME_CONSTANT = " | name:";
+
+    private final RpcRegistry rpcRegistry;
+
+    public RemoteRpcRegistryMXBeanImpl(final RpcRegistry rpcRegistry) {
+        super("RemoteRpcRegistry", "RemoteRpcBroker", null);
+        this.rpcRegistry = rpcRegistry;
+        registerMBean();
+    }
+
+    @Override
+    public Set<String> getGlobalRpc() {
+        RoutingTable table = rpcRegistry.getLocalBucket().getData();
+        Set<String> globalRpc = new HashSet<>(table.getRoutes().size());
+        for(RpcRouter.RouteIdentifier<?, ?, ?> route : table.getRoutes()){
+            if(route.getRoute() == null) {
+                globalRpc.add(route.getType() != null ? route.getType().toString() : NULL_CONSTANT);
+            }
+        }
+        if(log.isDebugEnabled()) {
+            log.debug("Locally registered global RPCs {}", globalRpc);
+        }
+        return globalRpc;
+    }
+
+    @Override
+    public Set<String> getLocalRegisteredRoutedRpc() {
+        RoutingTable table = rpcRegistry.getLocalBucket().getData();
+        Set<String> routedRpc = new HashSet<>(table.getRoutes().size());
+        for(RpcRouter.RouteIdentifier<?, ?, ?> route : table.getRoutes()){
+            if(route.getRoute() != null) {
+                StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
+                builder.append(route.getRoute().toString()).append(NAME_CONSTANT).append(route.getType() != null ?
+                    route.getType().toString() : NULL_CONSTANT);
+                routedRpc.add(builder.toString());
+            }
+        }
+        if(log.isDebugEnabled()) {
+            log.debug("Locally registered routed RPCs {}", routedRpc);
+        }
+        return routedRpc;
+    }
+
+    @Override
+    public Map<String, String> findRpcByName(final String name) {
+        RoutingTable localTable = rpcRegistry.getLocalBucket().getData();
+        // Get all RPCs from local bucket
+        Map<String, String> rpcMap = new HashMap<>(getRpcMemberMapByName(localTable, name, LOCAL_CONSTANT));
+
+        // Get all RPCs from remote bucket
+        Map<Address, Bucket<RoutingTable>> buckets = rpcRegistry.getRemoteBuckets();
+        for(Address address : buckets.keySet()) {
+            RoutingTable table = buckets.get(address).getData();
+            rpcMap.putAll(getRpcMemberMapByName(table, name, address.toString()));
+        }
+        if(log.isDebugEnabled()) {
+            log.debug("list of RPCs {} searched by name {}", rpcMap, name);
+        }
+        return rpcMap;
+    }
+
+    @Override
+    public Map<String, String> findRpcByRoute(String routeId) {
+        RoutingTable localTable = rpcRegistry.getLocalBucket().getData();
+        Map<String, String> rpcMap = new HashMap<>(getRpcMemberMapByRoute(localTable, routeId, LOCAL_CONSTANT));
+
+        Map<Address, Bucket<RoutingTable>> buckets = rpcRegistry.getRemoteBuckets();
+        for(Address address : buckets.keySet()) {
+            RoutingTable table = buckets.get(address).getData();
+            rpcMap.putAll(getRpcMemberMapByRoute(table, routeId, address.toString()));
+
+        }
+        if(log.isDebugEnabled()) {
+            log.debug("list of RPCs {} searched by route {}", rpcMap, routeId);
+        }
+        return rpcMap;
+    }
+
+    /**
+     * Search if the routing table route String contains routeName
+     */
+
+    private Map<String,String> getRpcMemberMapByRoute(final RoutingTable table, final String routeName,
+                                                      final String address) {
+        Set<RpcRouter.RouteIdentifier<?, ?, ?>> routes = table.getRoutes();
+        Map<String, String> rpcMap = new HashMap<>(routes.size());
+        for(RpcRouter.RouteIdentifier<?, ?, ?> route : table.getRoutes()){
+            if(route.getRoute() != null) {
+                String routeString = route.getRoute().toString();
+                if(routeString.contains(routeName)) {
+                    StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
+                    builder.append(routeString).append(NAME_CONSTANT).append(route.getType() != null ?
+                        route.getType().toString() : NULL_CONSTANT);
+                    rpcMap.put(builder.toString(), address);
+                }
+            }
+        }
+        return rpcMap;
+    }
+
+    /**
+     * Search if the routing table route type contains name
+     */
+    private Map<String, String>  getRpcMemberMapByName(final RoutingTable table, final String name,
+                                                       final String address) {
+        Set<RpcRouter.RouteIdentifier<?, ?, ?>> routes = table.getRoutes();
+        Map<String, String> rpcMap = new HashMap<>(routes.size());
+        for(RpcRouter.RouteIdentifier<?, ?, ?> route : routes){
+            if(route.getType() != null) {
+                String type = route.getType().toString();
+                if(type.contains(name)) {
+                    StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
+                    builder.append(route.getRoute() != null ? route.getRoute().toString(): NULL_CONSTANT)
+                        .append(NAME_CONSTANT).append(type);
+                    rpcMap.put(builder.toString(), address);
+                }
+            }
+        }
+        return rpcMap;
+    }
+
+
+
+    @Override
+    public String getBucketVersions() {
+        return rpcRegistry.getVersions().toString();
+    }
+
+}
\ No newline at end of file

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.