IGNITE-6870 Implement new JMX metric for cache topology validation monitoring
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/bf089e28 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bf089e28 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bf089e28 Branch: refs/heads/ignite-zk Commit: bf089e287bfa1049960221c14ee3ef0efb3b2421 Parents: 555fceb Author: Aleksey Plekhanov <[email protected]> Authored: Fri Nov 24 14:44:07 2017 +0300 Committer: Anton Vinogradov <[email protected]> Committed: Fri Nov 24 14:44:07 2017 +0300 ---------------------------------------------------------------------- .../org/apache/ignite/cache/CacheMetrics.java | 16 ++- .../cache/CacheClusterMetricsMXBeanImpl.java | 12 +- .../cache/CacheLocalMetricsMXBeanImpl.java | 12 +- .../processors/cache/CacheMetricsImpl.java | 31 +++++ .../processors/cache/CacheMetricsSnapshot.java | 20 ++++ .../ignite/mxbean/CacheMetricsMXBean.java | 10 +- .../cache/CacheValidatorMetricsTest.java | 116 +++++++++++++++++++ .../platform/PlatformCacheWriteMetricsTask.java | 11 +- .../IgniteCacheMetricsSelfTestSuite.java | 3 + 9 files changed, 226 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java b/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java index fe789ca..609f345 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java @@ -576,4 +576,18 @@ public interface CacheMetrics { * @see CacheWriter */ public boolean isWriteThrough(); -} \ No newline at end of file + + /** + * Checks whether cache topology is valid for read operations. + * + * @return {@code true} when cache topology is valid for reading. + */ + public boolean isValidForReading(); + + /** + * Checks whether cache topology is valid for write operations. + * + * @return {@code true} when cache topology is valid for writing. + */ + public boolean isValidForWriting(); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java index 1611840..7d57eb0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java @@ -402,4 +402,14 @@ class CacheClusterMetricsMXBeanImpl implements CacheMetricsMXBean { @Override public long getRebalancingStartTime() { return cache.clusterMetrics().getRebalancingStartTime(); } -} \ No newline at end of file + + /** {@inheritDoc} */ + @Override public boolean isValidForReading() { + return cache.clusterMetrics().isValidForReading(); + } + + /** {@inheritDoc} */ + @Override public boolean isValidForWriting() { + return cache.clusterMetrics().isValidForWriting(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java index 4a8c25c..88cc6db 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java @@ -402,4 +402,14 @@ class CacheLocalMetricsMXBeanImpl implements CacheMetricsMXBean { @Override public long getRebalancingStartTime() { return cache.metrics0().getRebalancingStartTime(); } -} \ No newline at end of file + + /** {@inheritDoc} */ + @Override public boolean isValidForReading() { + return cache.metrics0().isValidForReading(); + } + + /** {@inheritDoc} */ + @Override public boolean isValidForWriting() { + return cache.metrics0().isValidForWriting(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java index 4e6b279..78a4f97 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java @@ -25,6 +25,7 @@ import org.apache.ignite.cache.CacheMetrics; import org.apache.ignite.cache.CachePeekMode; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState; +import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics; import org.apache.ignite.internal.processors.cache.store.GridCacheWriteBehindStore; import org.apache.ignite.internal.util.tostring.GridToStringExclude; @@ -716,6 +717,36 @@ public class CacheMetricsImpl implements CacheMetrics { return ccfg != null && ccfg.isWriteThrough(); } + /** + * Checks whether cache topology is valid for operations. + * + * @param read {@code True} if validating read operations, {@code false} if validating write. + * @return Valid ot not. + */ + private boolean isValidForOperation(boolean read) { + if (cctx.isLocal()) + return true; + + try { + GridDhtTopologyFuture fut = cctx.shared().exchange().lastFinishedFuture(); + + return (fut != null && fut.validateCache(cctx, false, read, null, null) == null); + } + catch (Exception ignored) { + return false; + } + } + + /** {@inheritDoc} */ + @Override public boolean isValidForReading() { + return isValidForOperation(true); + } + + /** {@inheritDoc} */ + @Override public boolean isValidForWriting() { + return isValidForOperation(false); + } + /** {@inheritDoc} */ @Override public boolean isStoreByValue() { CacheConfiguration ccfg = cctx.config(); http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java index 9590c88..08fc571 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java @@ -230,6 +230,12 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable { /** */ private boolean isWriteThrough; + /** */ + private boolean isValidForReading; + + /** */ + private boolean isValidForWriting; + /** * Default constructor. */ @@ -307,6 +313,8 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable { isManagementEnabled = m.isManagementEnabled(); isReadThrough = m.isReadThrough(); isWriteThrough = m.isWriteThrough(); + isValidForReading = m.isValidForReading(); + isValidForWriting = m.isValidForWriting(); totalPartitionsCnt = m.getTotalPartitionsCount(); rebalancingPartitionsCnt = m.getRebalancingPartitionsCount(); @@ -342,6 +350,8 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable { isManagementEnabled = loc.isManagementEnabled(); isReadThrough = loc.isReadThrough(); isWriteThrough = loc.isWriteThrough(); + isValidForReading = loc.isValidForReading(); + isValidForWriting = loc.isValidForWriting(); for (CacheMetrics e : metrics) { reads += e.getCacheGets(); @@ -824,6 +834,16 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable { } /** {@inheritDoc} */ + @Override public boolean isValidForReading() { + return isValidForReading; + } + + /** {@inheritDoc} */ + @Override public boolean isValidForWriting() { + return isValidForWriting; + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(CacheMetricsSnapshot.class, this); } http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/main/java/org/apache/ignite/mxbean/CacheMetricsMXBean.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/CacheMetricsMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/CacheMetricsMXBean.java index 32ddd5e..f7bd8bd 100644 --- a/modules/core/src/main/java/org/apache/ignite/mxbean/CacheMetricsMXBean.java +++ b/modules/core/src/main/java/org/apache/ignite/mxbean/CacheMetricsMXBean.java @@ -282,4 +282,12 @@ public interface CacheMetricsMXBean extends CacheStatisticsMXBean, CacheMXBean, /** {@inheritDoc} */ @MXBeanDescription("True when a cache is in write-through mode.") public boolean isWriteThrough(); -} \ No newline at end of file + + /** {@inheritDoc} */ + @MXBeanDescription("True when a cache topology is valid for read operations.") + public boolean isValidForReading(); + + /** {@inheritDoc} */ + @MXBeanDescription("True when a cache topology is valid for write operations.") + public boolean isValidForWriting(); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheValidatorMetricsTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheValidatorMetricsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheValidatorMetricsTest.java new file mode 100644 index 0000000..ba3ad5a --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheValidatorMetricsTest.java @@ -0,0 +1,116 @@ +/* + * 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.ignite.internal.processors.cache; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import org.apache.ignite.Ignite; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.cache.PartitionLossPolicy; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.TopologyValidator; +import org.apache.ignite.internal.util.typedef.G; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Cache validator metrics test. + */ +public class CacheValidatorMetricsTest extends GridCommonAbstractTest implements Serializable { + /** Cache name 1. */ + private static String CACHE_NAME_1 = "cache1"; + + /** Cache name 2. */ + private static String CACHE_NAME_2 = "cache2"; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + CacheConfiguration cCfg1 = new CacheConfiguration() + .setName(CACHE_NAME_1) + .setCacheMode(CacheMode.PARTITIONED) + .setBackups(0) + .setPartitionLossPolicy(PartitionLossPolicy.READ_ONLY_ALL); + + CacheConfiguration cCfg2 = new CacheConfiguration() + .setName(CACHE_NAME_2) + .setCacheMode(CacheMode.REPLICATED) + .setTopologyValidator(new TopologyValidator() { + @Override public boolean validate(Collection<ClusterNode> nodes) { + return nodes.size() == 2; + } + }); + + cfg.setCacheConfiguration(cCfg1, cCfg2); + + return cfg; + } + + /** + * Asserts that the cache has appropriate status (indicated by the cache metrics). + * + * @param cacheName Cache name. + * @param validForReading Cache is valid for reading. + * @param validForWriting Cache is valid for writing. + */ + void assertCacheStatus(String cacheName, boolean validForReading, boolean validForWriting) { + List<Ignite> nodes = G.allGrids(); + + assertFalse(nodes.isEmpty()); + + for (Ignite node : nodes) { + assertEquals(validForReading, node.cache(cacheName).metrics().isValidForReading()); + assertEquals(validForWriting, node.cache(cacheName).metrics().isValidForWriting()); + } + } + + /** + * Test the cache validator metrics. + * Cache can be invalid for writing due to invalid topology or due to partitions loss. + * Now we can't reproduce test case with invalid for reading cache. At present, reading from the cache can be + * invalid only for certain keys or when the cluster is not active (in this case caches are not available at all). + * + * @throws Exception If failed. + */ + public void testCacheValidatorMetrics() throws Exception { + startGrid(1); + + assertCacheStatus(CACHE_NAME_1, true, true); + assertCacheStatus(CACHE_NAME_2, true, false); + + startGrid(2); + + waitForRebalancing(); + + assertCacheStatus(CACHE_NAME_1, true, true); + assertCacheStatus(CACHE_NAME_2, true, true); + + stopGrid(1); + + waitForRebalancing(); + + // Invalid for writing due to invalid topology. + assertCacheStatus(CACHE_NAME_1, true, false); + + // Invalid for writing due to partitions loss. + assertCacheStatus(CACHE_NAME_2, true, false); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java index e7404fa..3b9c27e 100644 --- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java +++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java @@ -405,6 +405,16 @@ public class PlatformCacheWriteMetricsTask extends ComputeTaskAdapter<Long, Obje } /** {@inheritDoc} */ + @Override public boolean isValidForReading() { + return true; + } + + /** {@inheritDoc} */ + @Override public boolean isValidForWriting() { + return true; + } + + /** {@inheritDoc} */ @Override public int getTotalPartitionsCount() { return 54; } @@ -455,4 +465,3 @@ public class PlatformCacheWriteMetricsTask extends ComputeTaskAdapter<Long, Obje } } } - http://git-wip-us.apache.org/repos/asf/ignite/blob/bf089e28/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMetricsSelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMetricsSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMetricsSelfTestSuite.java index cb20442..6a2fcea 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMetricsSelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMetricsSelfTestSuite.java @@ -20,6 +20,7 @@ package org.apache.ignite.testsuites; import junit.framework.TestSuite; import org.apache.ignite.internal.processors.cache.CacheGroupsMetricsRebalanceTest; import org.apache.ignite.internal.processors.cache.CacheMetricsForClusterGroupSelfTest; +import org.apache.ignite.internal.processors.cache.CacheValidatorMetricsTest; import org.apache.ignite.internal.processors.cache.OffheapCacheMetricsForClusterGroupSelfTest; import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheAtomicPartitionedMetricsSelfTest; import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheAtomicPartitionedTckMetricsSelfTestImpl; @@ -62,6 +63,8 @@ public class IgniteCacheMetricsSelfTestSuite extends TestSuite { suite.addTestSuite(CacheGroupsMetricsRebalanceTest.class); + suite.addTestSuite(CacheValidatorMetricsTest.class); + // Cluster wide metrics. suite.addTestSuite(CacheMetricsForClusterGroupSelfTest.class); suite.addTestSuite(OffheapCacheMetricsForClusterGroupSelfTest.class);
