From: Harman Singh Date: Thu, 30 Apr 2015 01:26:44 +0000 (-0700) Subject: Bug 2853 : Adding Remote RPC MX bean X-Git-Tag: release/beryllium~625^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=62d994b658818ee2f2e097461e01422e8c4fb60a Bug 2853 : Adding Remote RPC MX bean 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 --- diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java index f12fda0aa1..f3cb78a301 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java @@ -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 = diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java index f67657f692..fa93a3b83f 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java @@ -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, Serializable { } } + public Set> getRoutes() { + return table.keySet(); + } + public void addRoute(RpcRouter.RouteIdentifier routeId){ table.put(routeId, System.currentTimeMillis()); } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java index 219646d847..1dcc4e1405 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java @@ -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 { 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 { } } } + + private static class RpcRegistryCreator implements Creator { + private static final long serialVersionUID = 1L; + + @Override + public RpcRegistry create() throws Exception { + RpcRegistry registry = new RpcRegistry(); + RemoteRpcRegistryMXBean mxBean = new RemoteRpcRegistryMXBeanImpl(registry); + return registry; + } + } } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java index 628deb4311..febff0bc92 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java @@ -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> extends AbstractUntypedActorWithMe } } - protected BucketImpl getLocalBucket() { + public BucketImpl getLocalBucket() { return localBucket; } @@ -239,12 +238,11 @@ public class BucketStore> extends AbstractUntypedActorWithMe versions.put(selfAddress, localBucket.getVersion()); } - protected Map> getRemoteBuckets() { + public Map> getRemoteBuckets() { return remoteBuckets; } - @VisibleForTesting - Map getVersions() { + public Map 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 index 0000000000..ddd33336ed --- /dev/null +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBean.java @@ -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 getGlobalRpc(); + + String getBucketVersions(); + + Set getLocalRegisteredRoutedRpc(); + + Map findRpcByName(String name); + + Map 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 index 0000000000..c7d9b9955d --- /dev/null +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/mbeans/RemoteRpcRegistryMXBeanImpl.java @@ -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 getGlobalRpc() { + RoutingTable table = rpcRegistry.getLocalBucket().getData(); + Set 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 getLocalRegisteredRoutedRpc() { + RoutingTable table = rpcRegistry.getLocalBucket().getData(); + Set 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 findRpcByName(final String name) { + RoutingTable localTable = rpcRegistry.getLocalBucket().getData(); + // Get all RPCs from local bucket + Map rpcMap = new HashMap<>(getRpcMemberMapByName(localTable, name, LOCAL_CONSTANT)); + + // Get all RPCs from remote bucket + Map> 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 findRpcByRoute(String routeId) { + RoutingTable localTable = rpcRegistry.getLocalBucket().getData(); + Map rpcMap = new HashMap<>(getRpcMemberMapByRoute(localTable, routeId, LOCAL_CONSTANT)); + + Map> 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 getRpcMemberMapByRoute(final RoutingTable table, final String routeName, + final String address) { + Set> routes = table.getRoutes(); + Map 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 getRpcMemberMapByName(final RoutingTable table, final String name, + final String address) { + Set> routes = table.getRoutes(); + Map 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