From afd19ba70dc45b433fecca95fced9d7842c916bc Mon Sep 17 00:00:00 2001 From: Mikhail Petrov <32207922+petrov-mg@users.noreply.github.com> Date: Mon, 21 Aug 2023 19:36:31 +0300 Subject: [PATCH] IGNITE-20201 Fixed availability to set configuration for unregistered metrics (#10903) --- .../processors/metric/GridMetricManager.java | 10 ++ .../processors/metric/MetricRegistry.java | 3 + .../processors/metric/impl/MetricUtils.java | 19 +++- .../metric/MetricConfigurationTest.java | 104 ++++++++++++++++++ .../internal/metric/MetricsSelfTest.java | 2 +- .../internal/metric/SystemViewSelfTest.java | 6 +- .../testsuites/IgniteBasicTestSuite2.java | 2 + 7 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/metric/MetricConfigurationTest.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java index ebd62e3ce015e..241539791096e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java @@ -425,6 +425,8 @@ public void configureHitRate(String name, long rateTimeInterval) throws IgniteCh if (ctx.isStopping()) throw new NodeStoppingException("Operation has been cancelled (node is stopping)"); + ensureMetricRegistered(name, HitRateMetric.class); + metastorage.write(metricName(HITRATE_CFG_PREFIX, name), rateTimeInterval); } @@ -443,6 +445,8 @@ public void configureHistogram(String name, long[] bounds) throws IgniteCheckedE if (ctx.isStopping()) throw new NodeStoppingException("Operation has been cancelled (node is stopping)"); + ensureMetricRegistered(name, HistogramMetric.class); + metastorage.write(metricName(HISTOGRAM_CFG_PREFIX, name), bounds); } @@ -565,6 +569,12 @@ public MemoryUsage heapMemoryUsage() { } } + /** */ + private void ensureMetricRegistered(String name, Class cls) { + if (find(name, cls) == null) + throw new IgniteException("Failed to find registered metric with specified name [metricName=" + name + ']'); + } + /** * @return Total system memory. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/MetricRegistry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/MetricRegistry.java index 0ace7e5d30ab1..8602d594039fd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/MetricRegistry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/MetricRegistry.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.processors.metric.impl.LongGauge; import org.apache.ignite.internal.processors.metric.impl.ObjectGauge; import org.apache.ignite.internal.processors.metric.impl.ObjectMetricImpl; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.spi.metric.BooleanMetric; import org.apache.ignite.spi.metric.IntMetric; import org.apache.ignite.spi.metric.Metric; @@ -322,6 +323,8 @@ public HistogramMetricImpl histogram(String name, long[] bounds, @Nullable Strin * @return Registered metric. */ private T addMetric(String name, T metric) { + assert !F.isEmpty(name); + T old = (T)metrics.putIfAbsent(name, metric); if (old != null) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/impl/MetricUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/impl/MetricUtils.java index 8e9c1d25f2fe5..716762f790e20 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/impl/MetricUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/impl/MetricUtils.java @@ -68,10 +68,21 @@ public static String metricName(String... names) { * @return Array consist of registry name and metric name. */ public static T2 fromFullName(String name) { - return new T2<>( - name.substring(0, name.lastIndexOf(SEPARATOR)), - name.substring(name.lastIndexOf(SEPARATOR) + 1) - ); + int metricNamePos = name.lastIndexOf(SEPARATOR); + + String regName; + String metricName; + + if (metricNamePos == -1) { + regName = name; + metricName = ""; + } + else { + regName = name.substring(0, metricNamePos); + metricName = name.substring(metricNamePos + 1); + } + + return new T2<>(regName, metricName); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricConfigurationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricConfigurationTest.java new file mode 100644 index 0000000000000..9f955fc507bef --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricConfigurationTest.java @@ -0,0 +1,104 @@ +/* + * 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.metric; + +import org.apache.ignite.IgniteException; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +import static org.apache.ignite.cluster.ClusterState.ACTIVE; +import static org.apache.ignite.cluster.ClusterState.INACTIVE; +import static org.apache.ignite.internal.processors.cache.persistence.DataStorageMetricsImpl.DATASTORAGE_METRIC_PREFIX; + +/** */ +public class MetricConfigurationTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName) + .setDataStorageConfiguration(new DataStorageConfiguration() + .setDefaultDataRegionConfiguration(new DataRegionConfiguration() + .setPersistenceEnabled(true))); + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + cleanPersistenceDir(); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + super.afterTest(); + + stopAllGrids(); + cleanPersistenceDir(); + } + + /** */ + @Test + public void testInvalidMetricConfigurationName() throws Exception { + startGrid(0); + + grid(0).cluster().state(ACTIVE); + + checkMetricConfigurationUpdateFailed("invalid"); + checkMetricConfigurationUpdateFailed("."); + checkMetricConfigurationUpdateFailed(".invalid"); + checkMetricConfigurationUpdateFailed("invalid.metric.name"); + checkMetricConfigurationUpdateFailed(DATASTORAGE_METRIC_PREFIX); + checkMetricConfigurationUpdateFailed(DATASTORAGE_METRIC_PREFIX + '.'); + + grid(0).cluster().state(INACTIVE); + + stopAllGrids(); + + startGrid(0); + + grid(0).cluster().state(ACTIVE); + } + + /** */ + private void checkMetricConfigurationUpdateFailed(String name) { + GridTestUtils.assertThrowsAnyCause( + log, + () -> { + grid(0).context().metric().configureHistogram(name, new long[] {1, 2, 3}); + + return null; + }, + IgniteException.class, + "Failed to find registered metric with specified name [metricName=" + name + ']' + ); + + GridTestUtils.assertThrowsAnyCause( + log, + () -> { + grid(0).context().metric().configureHitRate(name, 1000); + + return null; + }, + IgniteException.class, + "Failed to find registered metric with specified name [metricName=" + name + ']' + ); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricsSelfTest.java index 6b241b3b1a0f1..9775e196d1003 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/MetricsSelfTest.java @@ -145,7 +145,7 @@ public void testRegister() throws Exception { assertEquals(0, l.value()); assertThrowsWithCause(() -> mreg.register(new AtomicLongMetric(mName, "")), - StringIndexOutOfBoundsException.class); + AssertionError.class); assertThrowsWithCause(() -> mreg.register(new AtomicLongMetric(metricName("mreg", mName), "")), AssertionError.class); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java index dff7e9cdb1fa3..d69c1c005fd3e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java @@ -157,6 +157,7 @@ import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId; import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId; import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.BINARY_METADATA_VIEW; +import static org.apache.ignite.internal.processors.cache.persistence.DataStorageMetricsImpl.DATASTORAGE_METRIC_PREFIX; import static org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.METASTORE_VIEW; import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.DATA_REGION_PAGE_LIST_VIEW; import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.PAGE_TS_HISTOGRAM_VIEW; @@ -178,6 +179,7 @@ import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.STAMPED_VIEW; import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.VOLATILE_DATA_REGION_NAME; import static org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl.DISTRIBUTED_METASTORE_VIEW; +import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName; import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_ATTR_VIEW; import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_VIEW; import static org.apache.ignite.internal.processors.pool.PoolProcessor.STREAM_POOL_QUEUE_VIEW; @@ -2055,9 +2057,9 @@ public void testDistributedMetastorage() throws Exception { )))) { ignite.cluster().state(ClusterState.ACTIVE); - String histogramName = "my-histogram"; + String histogramName = "CheckpointBeforeLockHistogram"; - ignite.context().metric().configureHistogram(histogramName, new long[] { 1, 2, 3}); + ignite.context().metric().configureHistogram(metricName(DATASTORAGE_METRIC_PREFIX, histogramName), new long[] { 1, 2, 3}); DistributedMetaStorage dms = ignite.context().distributedMetastorage(); diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite2.java index 8492bd34f0b28..f4fd9a08a5542 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite2.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite2.java @@ -38,6 +38,7 @@ import org.apache.ignite.internal.managers.IgniteDiagnosticPartitionReleaseFutureLimitTest; import org.apache.ignite.internal.managers.communication.GridIoManagerFileTransmissionSelfTest; import org.apache.ignite.internal.managers.discovery.IncompleteDeserializationExceptionTest; +import org.apache.ignite.internal.metric.MetricConfigurationTest; import org.apache.ignite.internal.metric.MetricsClusterActivationTest; import org.apache.ignite.internal.metric.PeriodicHistogramMetricImplTest; import org.apache.ignite.internal.mxbean.IgniteStandardMXBeanTest; @@ -135,6 +136,7 @@ CacheFreeListSelfTest.class, DataRegionMetricsSelfTest.class, MetricsClusterActivationTest.class, + MetricConfigurationTest.class, SwapPathConstructionSelfTest.class, BitSetIntSetTest.class, ImmutableIntSetTest.class,