IGNITE-6867 Implement new JMX metrics for topology monitoring HotFix Signed-off-by: Anton Vinogradov <[email protected]>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/80801cb2 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/80801cb2 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/80801cb2 Branch: refs/heads/ignite-zk Commit: 80801cb2fe471967435155e55c16822de2687760 Parents: 0dd16a7 Author: Aleksey Plekhanov <[email protected]> Authored: Fri Dec 8 17:13:54 2017 +0300 Committer: Anton Vinogradov <[email protected]> Committed: Mon Dec 11 14:09:19 2017 +0300 ---------------------------------------------------------------------- .../ClusterLocalNodeMetricsMXBeanImpl.java | 62 +++++++- .../internal/ClusterMetricsMXBeanImpl.java | 45 +++--- .../apache/ignite/internal/IgniteKernal.java | 13 +- .../internal/ClusterNodeMetricsSelfTest.java | 153 +++++++++++++------ 4 files changed, 194 insertions(+), 79 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/80801cb2/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java index 84079c3..a242345 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java @@ -17,24 +17,34 @@ package org.apache.ignite.internal; +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.mxbean.ClusterLocalNodeMetricsMXBean; +import org.apache.ignite.mxbean.ClusterMetricsMXBean; /** * Local node metrics MBean. */ -public class ClusterLocalNodeMetricsMXBeanImpl implements ClusterLocalNodeMetricsMXBean { +public class ClusterLocalNodeMetricsMXBeanImpl implements ClusterMetricsMXBean { /** Grid node. */ private final ClusterNode node; + /** Grid discovery manager. */ + private final GridDiscoveryManager discoMgr; + /** - * @param node Node to manage. + * @param discoMgr Grid discovery manager. */ - public ClusterLocalNodeMetricsMXBeanImpl(ClusterNode node) { - assert node != null; + public ClusterLocalNodeMetricsMXBeanImpl(GridDiscoveryManager discoMgr) { + assert discoMgr != null; + + this.discoMgr = discoMgr; - this.node = node; + this.node = discoMgr.localNode(); } /** {@inheritDoc} */ @@ -323,6 +333,46 @@ public class ClusterLocalNodeMetricsMXBeanImpl implements ClusterLocalNodeMetric } /** {@inheritDoc} */ + @Override public int getTotalServerNodes() { + return !node.isClient() ? 1 : 0; + } + + /** {@inheritDoc} */ + @Override public int getTotalClientNodes() { + return node.isClient() ? 1 : 0; + } + + /** {@inheritDoc} */ + @Override public long getTopologyVersion() { + return discoMgr.topologyVersion(); + } + + /** {@inheritDoc} */ + @Override public Set<String> attributeNames() { + return new TreeSet<>(node.attributes().keySet()); + } + + /** {@inheritDoc} */ + @Override public Set<String> attributeValues(String attrName) { + Object val = node.attribute(attrName); + + return val == null ? Collections.<String>emptySet() : Collections.singleton(val.toString()); + } + + /** {@inheritDoc} */ + @Override public Set<UUID> nodeIdsForAttribute(String attrName, String attrVal, boolean includeSrvs, + boolean includeClients) { + if ((includeClients && node.isClient()) || (includeSrvs && !node.isClient())) { + Object nodeVal = node.attribute(attrName); + + if (nodeVal != null && nodeVal.toString().equals(attrVal)) + return Collections.singleton(node.id()); + } + + return Collections.emptySet(); + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(ClusterLocalNodeMetricsMXBeanImpl.class, this); } http://git-wip-us.apache.org/repos/asf/ignite/blob/80801cb2/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java index e3c75c6..e09ad3c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java @@ -18,9 +18,10 @@ package org.apache.ignite.internal; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; import org.apache.ignite.cluster.ClusterGroup; import org.apache.ignite.cluster.ClusterMetrics; import org.apache.ignite.cluster.ClusterNode; @@ -373,34 +374,42 @@ public class ClusterMetricsMXBeanImpl implements ClusterMetricsMXBean { } /** {@inheritDoc} */ - @Override public int countNodes(String attrName, String attrVal, boolean srv, boolean client) { - int cnt = 0; + @Override public Set<String> attributeNames() { + Set<String> attrs = new TreeSet<>(); - for (ClusterNode node : nodesList(srv, client)) { + for (ClusterNode node : cluster.nodes()) + attrs.addAll(node.attributes().keySet()); + + return attrs; + } + + /** {@inheritDoc} */ + @Override public Set<String> attributeValues(String attrName) { + Set<String> values = new TreeSet<>(); + + for (ClusterNode node : cluster.nodes()) { Object val = node.attribute(attrName); - if (val != null && val.toString().equals(attrVal)) - ++cnt; + if (val != null) + values.add(val.toString()); } - return cnt; + return values; } /** {@inheritDoc} */ - @Override public Map<Object, Integer> groupNodes(String attrName, boolean srv, boolean client) { - Map<Object, Integer> attrGroups = new HashMap<>(); + @Override public Set<UUID> nodeIdsForAttribute(String attrName, String attrVal, boolean includeSrvs, + boolean includeClients) { + Set<UUID> nodes = new TreeSet<>(); - for (ClusterNode node : nodesList(srv, client)) { - Object attrVal = node.attribute(attrName); - - if (attrVal != null) { - Integer cnt = attrGroups.get(attrVal); + for (ClusterNode node : nodesList(includeSrvs, includeClients)) { + Object val = node.attribute(attrName); - attrGroups.put(attrVal, cnt == null ? 1 : ++cnt); - } + if (val != null && val.toString().equals(attrVal)) + nodes.add(node.id()); } - return attrGroups; + return nodes; } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/80801cb2/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index f6ad9b3..f3b3925 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -182,7 +182,6 @@ import org.apache.ignite.lifecycle.LifecycleBean; import org.apache.ignite.lifecycle.LifecycleEventType; import org.apache.ignite.marshaller.MarshallerExclusions; import org.apache.ignite.marshaller.jdk.JdkMarshaller; -import org.apache.ignite.mxbean.ClusterLocalNodeMetricsMXBean; import org.apache.ignite.mxbean.ClusterMetricsMXBean; import org.apache.ignite.mxbean.IgniteMXBean; import org.apache.ignite.mxbean.StripedExecutorMXBean; @@ -1706,11 +1705,9 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { * Register instance of ClusterMetricsMBean. * * @param mbean MBean instance to register. - * @param clazz MBean interface to register. - * @param <T> MBean type. * @throws IgniteCheckedException If registration failed. */ - private <T> ObjectName registerClusterMetricsMBean(T mbean, Class<T> clazz) throws IgniteCheckedException { + private ObjectName registerClusterMetricsMBean(ClusterMetricsMXBean mbean) throws IgniteCheckedException { if(U.IGNITE_MBEANS_DISABLED) return null; @@ -1723,7 +1720,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { "Kernal", mbean.getClass().getSimpleName(), mbean, - clazz); + ClusterMetricsMXBean.class); if (log.isDebugEnabled()) log.debug("Registered MBean: " + objName); @@ -1737,10 +1734,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { /** @throws IgniteCheckedException If registration failed. */ private void registerClusterMetricsMBeans() throws IgniteCheckedException { - locNodeMBean = registerClusterMetricsMBean(new ClusterLocalNodeMetricsMXBeanImpl(ctx.discovery().localNode()), - ClusterLocalNodeMetricsMXBean.class); - allNodesMBean = registerClusterMetricsMBean(new ClusterMetricsMXBeanImpl(cluster()), - ClusterMetricsMXBean.class); + locNodeMBean = registerClusterMetricsMBean(new ClusterLocalNodeMetricsMXBeanImpl(ctx.discovery())); + allNodesMBean = registerClusterMetricsMBean(new ClusterMetricsMXBeanImpl(cluster())); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/80801cb2/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java index 790a397..b573ca3 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java @@ -18,8 +18,10 @@ package org.apache.ignite.internal; import java.io.Serializable; +import java.util.Arrays; import java.util.Collections; -import java.util.Map; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; import javax.management.MBeanServer; @@ -38,10 +40,10 @@ import org.apache.ignite.events.Event; import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl; import org.apache.ignite.internal.processors.task.GridInternal; import org.apache.ignite.internal.util.lang.GridAbsPredicate; -import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.messaging.MessagingListenActor; +import org.apache.ignite.mxbean.ClusterMetricsMXBean; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; @@ -388,26 +390,81 @@ public class ClusterNodeMetricsSelfTest extends GridCommonAbstractTest { waitForDiscovery(node2, node1, node); - JmxClusterMetricsHelper h = new JmxClusterMetricsHelper(node.configuration()); + UUID nodeId0 = node.cluster().localNode().id(); + UUID nodeId1 = node1.cluster().localNode().id(); + UUID nodeId2 = node2.cluster().localNode().id(); - assertEquals(node.cluster().topologyVersion(), h.attr("TopologyVersion")); + Set<UUID> srvNodes = new HashSet<>(Arrays.asList(nodeId0, nodeId1)); + Set<UUID> clientNodes = Collections.singleton(nodeId2); + Set<UUID> allNodes = new HashSet<>(Arrays.asList(nodeId0, nodeId1, nodeId2)); - assertEquals(2, h.attr("TotalServerNodes")); - assertEquals(1, h.attr("TotalClientNodes")); + // ClusterMetricsMXBeanImpl test. + JmxClusterMetricsHelper helperCluster = new JmxClusterMetricsHelper(node.configuration(), + ClusterMetricsMXBeanImpl.class); - assertEquals(3, h.countNodes(ATTR_BUILD_VER, VER_STR, true, true)); - assertEquals(2, h.countNodes(ATTR_BUILD_VER, VER_STR, true, false)); - assertEquals(1, h.countNodes(ATTR_BUILD_VER, VER_STR, false, true)); - assertEquals(0, h.countNodes(ATTR_BUILD_VER, VER_STR, false, false)); + assertEquals(node.cluster().topologyVersion(), helperCluster.attr("TopologyVersion")); - assertEquals(2, h.countNodes(ATTR_CLIENT_MODE, "false", true, true)); - assertEquals(0, h.countNodes(ATTR_CLIENT_MODE, "false", false, false)); - assertEquals(1, h.countNodes(ATTR_CLIENT_MODE, "true", true, true)); + assertEquals(2, helperCluster.attr("TotalServerNodes")); + assertEquals(1, helperCluster.attr("TotalClientNodes")); - assertEquals(F.asMap(false, 2, true, 1), h.groupNodes(ATTR_CLIENT_MODE, true, true)); - assertEquals(F.asMap(false, 2), h.groupNodes(ATTR_CLIENT_MODE, true, false)); - assertEquals(F.asMap(true, 1), h.groupNodes(ATTR_CLIENT_MODE, false, true)); - assertEquals(Collections.emptyMap(), h.groupNodes(ATTR_CLIENT_MODE, false, false)); + assertEquals(allNodes, helperCluster.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, true, true)); + assertEquals(srvNodes, helperCluster.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, true, false)); + assertEquals(clientNodes, helperCluster.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, false, true)); + assertEquals(Collections.emptySet(), helperCluster.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, false, false)); + + assertEquals(srvNodes, helperCluster.nodeIdsForAttribute(ATTR_CLIENT_MODE, "false", true, true)); + assertEquals(Collections.emptySet(), helperCluster.nodeIdsForAttribute(ATTR_CLIENT_MODE, "false", false, + false)); + assertEquals(clientNodes, helperCluster.nodeIdsForAttribute(ATTR_CLIENT_MODE, "true", true, true)); + + assertTrue(helperCluster.attributeNames().containsAll(node.cluster().localNode().attributes().keySet())); + assertTrue(helperCluster.attributeNames().containsAll(node1.cluster().localNode().attributes().keySet())); + assertTrue(helperCluster.attributeNames().containsAll(node2.cluster().localNode().attributes().keySet())); + + assertEquals(new HashSet<>(Arrays.asList("true", "false")), helperCluster.attributeValues(ATTR_CLIENT_MODE)); + assertEquals(Collections.emptySet(), helperCluster.attributeValues("NO_SUCH_ATTRIBUTE")); + + // ClusterLocalNodeMetricsMXBeanImpl test. + JmxClusterMetricsHelper helperNode0 = new JmxClusterMetricsHelper(node.configuration(), + ClusterLocalNodeMetricsMXBeanImpl.class); + JmxClusterMetricsHelper helperNode2 = new JmxClusterMetricsHelper(node2.configuration(), + ClusterLocalNodeMetricsMXBeanImpl.class); + + // For server node. + assertEquals(1, helperNode0.attr("TotalServerNodes")); + assertEquals(0, helperNode0.attr("TotalClientNodes")); + + assertEquals(node.cluster().topologyVersion(), helperNode0.attr("TopologyVersion")); + + assertEquals(node.cluster().localNode().attributes().keySet(), helperNode0.attributeNames()); + + assertEquals(Collections.singleton("false"), helperNode0.attributeValues(ATTR_CLIENT_MODE)); + assertEquals(Collections.emptySet(), helperNode0.attributeValues("NO_SUCH_ATTRIBUTE")); + + assertEquals(Collections.singleton(nodeId0), helperNode0.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, true, + true)); + assertEquals(Collections.singleton(nodeId0), helperNode0.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, true, + false)); + assertEquals(Collections.emptySet(), helperNode0.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, false, true)); + assertEquals(Collections.emptySet(), helperNode0.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, false, false)); + + // For client node. + assertEquals(0, helperNode2.attr("TotalServerNodes")); + assertEquals(1, helperNode2.attr("TotalClientNodes")); + + assertEquals(node.cluster().topologyVersion(), helperNode2.attr("TopologyVersion")); + + assertEquals(node2.cluster().localNode().attributes().keySet(), helperNode2.attributeNames()); + + assertEquals(Collections.singleton("true"), helperNode2.attributeValues(ATTR_CLIENT_MODE)); + assertEquals(Collections.emptySet(), helperNode2.attributeValues("NO_SUCH_ATTRIBUTE")); + + assertEquals(Collections.singleton(nodeId2), helperNode2.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, true, + true)); + assertEquals(Collections.emptySet(), helperNode2.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, true, false)); + assertEquals(Collections.singleton(nodeId2), helperNode2.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, false, + true)); + assertEquals(Collections.emptySet(), helperNode2.nodeIdsForAttribute(ATTR_BUILD_VER, VER_STR, false, false)); } /** @@ -441,55 +498,59 @@ public class ClusterNodeMetricsSelfTest extends GridCommonAbstractTest { * @param cfg Ignite configuration. * @throws MalformedObjectNameException Thrown in case of any errors. */ - private JmxClusterMetricsHelper(IgniteConfiguration cfg) throws MalformedObjectNameException { + private JmxClusterMetricsHelper(IgniteConfiguration cfg, Class<? extends ClusterMetricsMXBean> clazz) throws MalformedObjectNameException { this.mbeanSrv = cfg.getMBeanServer(); - this.mbean = U.makeMBeanName(cfg.getIgniteInstanceName(), "Kernal", - ClusterMetricsMXBeanImpl.class.getSimpleName()); + this.mbean = U.makeMBeanName(cfg.getIgniteInstanceName(), "Kernal", clazz.getSimpleName()); } /** - * Invoke "countNodes" method through MBean server. + * Get MBean attribute through MBean server. * - * @param attrName Node attribute name, - * @param attrVal Node attribute value, - * @param srv Include server nodes. - * @param client Include client nodes. - * @return Count of nodes filtered by node attribute. + * @param name Attribute name. + * @return Current value of attribute. * @throws Exception If failed. */ - private int countNodes(String attrName, String attrVal, boolean srv, boolean client) throws Exception { - String[] signature = {"java.lang.String", "java.lang.String", "boolean", "boolean"}; - Object[] params = {attrName, attrVal, srv, client}; + private Object attr(String name) throws Exception { + return mbeanSrv.getAttribute(mbean, name); + } - return (int)mbeanSrv.invoke(mbean, "countNodes", params, signature); + /** + * Get distinct attribute names for given nodes projection. + */ + public Set<String> attributeNames() throws Exception { + String[] signature = {}; + Object[] params = {}; + + return (Set<String>)mbeanSrv.invoke(mbean, "attributeNames", params, signature); } /** - * Invoke "groupNodes" method through MBean server. + * Get distinct attribute values for given nodes projection. * - * @param attrName Node attribute name. - * @param srv Include server nodes. - * @param client Include client nodes. - * @return The number of nodes grouped by node attribute name. - * @throws Exception If failed. + * @param attrName Attribute name. */ - private Map groupNodes(String attrName, boolean srv, boolean client) throws Exception { - String[] signature = {"java.lang.String", "boolean", "boolean"}; - Object[] params = {attrName, srv, client}; + public Set<String> attributeValues(String attrName) throws Exception { + String[] signature = {"java.lang.String"}; + Object[] params = {attrName}; - return (Map)mbeanSrv.invoke(mbean, "groupNodes", params, signature); + return (Set<String>)mbeanSrv.invoke(mbean, "attributeValues", params, signature); } /** - * Get MBean attribute through MBean server. + * Get node IDs with the given attribute value. * - * @param name Attribute name. - * @return Current value of attribute. - * @throws Exception If failed. + * @param attrName Attribute name. + * @param attrVal Attribute value. + * @param includeSrvs Include server nodes. + * @param includeClients Include client nodes. */ - private Object attr(String name) throws Exception { - return mbeanSrv.getAttribute(mbean, name); + public Set<UUID> nodeIdsForAttribute(String attrName, String attrVal, boolean includeSrvs, + boolean includeClients) throws Exception { + String[] signature = {"java.lang.String", "java.lang.String", "boolean", "boolean"}; + Object[] params = {attrName, attrVal, includeSrvs, includeClients}; + + return (Set<UUID>)mbeanSrv.invoke(mbean, "nodeIdsForAttribute", params, signature); } } }
