This is an automated email from the ASF dual-hosted git repository.
klund pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new 8ee587c GEODE-6295: Add Micrometer-based metrics system (#3277)
8ee587c is described below
commit 8ee587c0d2e301775dae6a1eecba4f9a9a258ca6
Author: Kirk Lund <[email protected]>
AuthorDate: Wed Mar 13 14:16:34 2019 -0700
GEODE-6295: Add Micrometer-based metrics system (#3277)
- Add MetricsSession interface that represents the lifecycle of a meter
registry, and allows connecting "downstream" registries.
- Add MetricsPublishingService interface that defines a service that
can be implemented to interact with MetricsSessions by connecting
"downstream" registries to publish metrics to external monitoring
systems.
- Add CompositeMeterRegistryFactory whichs handles creating the
composite meter registry for the cache and defining its common tags.
- Add CacheLifecycleMetricsSession class that loads implementations of
MetricsPublishingService and manages the cache meter registry based
on the cache lifecycle.
- InternalCacheBuilder uses CompositeMeterRegistryFactory to create the
cache meter registry and starts a CacheLifecycleMetricsSession. The
cache meter registry is passed to GemFireCacheImpl and exposed to
internal Geode code by InternalCache.getMeterRegistry().
Co-Authored-By: Dale Emery <[email protected]>
Co-Authored-By: Michael Oleske <[email protected]>
Co-Authored-By: Mark Hanson <[email protected]>
Co-Authored-By: Kirk Lund <[email protected]>
---
.../src/test/resources/expected-pom.xml | 5 +
.../gradle/plugins/DependencyConstraints.groovy | 2 +
extensions/geode-modules-assembly/build.gradle | 1 +
.../release/session/bin/modify_war | 2 +
.../apache/geode/session/tests/TomcatInstall.java | 4 +-
.../integrationTest/resources/assembly_content.txt | 8 +
.../resources/dependency_classpath.txt | 3 +
.../integrationTest/resources/expected_jars.txt | 3 +
geode-assembly/src/main/dist/LICENSE | 2 +
geode-core/build.gradle | 2 +
.../geode/internal/cache/GemFireCacheImpl.java | 17 +-
.../apache/geode/internal/cache/InternalCache.java | 4 +
.../geode/internal/cache/InternalCacheBuilder.java | 33 +++-
.../cache/InternalCacheForClientAccess.java | 7 +
.../internal/cache/xmlcache/CacheCreation.java | 7 +
.../metrics/CacheLifecycleMetricsSession.java | 129 ++++++++++++
.../internal/metrics/CollectingServiceLoader.java | 29 +++
.../metrics/CompositeMeterRegistryFactory.java | 44 +++++
.../geode/metrics/MetricsPublishingService.java | 89 +++++++++
.../org/apache/geode/metrics/MetricsSession.java | 44 +++++
.../org/apache/geode/metrics/package-info.java | 37 ++++
...nalDistributedSystemStatisticsManagerTest.java} | 2 +-
.../geode/internal/cache/GemFireCacheImplTest.java | 10 +
...ernalCacheBuilderAllowsMultipleSystemsTest.java | 56 +++++-
.../internal/cache/InternalCacheBuilderTest.java | 116 +++++++++--
.../CacheLifecycleMetricsSessionBuilderTest.java | 108 ++++++++++
.../metrics/CacheLifecycleMetricsSessionTest.java | 220 +++++++++++++++++++++
.../metrics/CompositeMeterRegistryFactoryTest.java | 79 ++++++++
geode-core/src/test/resources/expected-pom.xml | 5 +
29 files changed, 1038 insertions(+), 30 deletions(-)
diff --git a/boms/geode-all-bom/src/test/resources/expected-pom.xml
b/boms/geode-all-bom/src/test/resources/expected-pom.xml
index b6b6d40..a8dcc11 100644
--- a/boms/geode-all-bom/src/test/resources/expected-pom.xml
+++ b/boms/geode-all-bom/src/test/resources/expected-pom.xml
@@ -173,6 +173,11 @@
<version>4.0.6</version>
</dependency>
<dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-core</artifactId>
+ <version>1.1.3</version>
+ </dependency>
+ <dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.31.Final</version>
diff --git
a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
index c7c15b4..004c593 100644
---
a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
+++
b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
@@ -41,6 +41,7 @@ class DependencyConstraints implements Plugin<Project> {
deps.put("javax.transaction-api.version", "1.3")
deps.put("jgroups.version", "3.6.14.Final")
deps.put("log4j.version", "2.11.1")
+ deps.put("micrometer.version", "1.1.3")
deps.put("shiro.version", "1.4.0")
deps.put("slf4j-api.version", "1.7.25")
@@ -111,6 +112,7 @@ class DependencyConstraints implements Plugin<Project> {
api(group: 'commons-modeler', name: 'commons-modeler', version:
'2.0.1')
api(group: 'commons-validator', name: 'commons-validator', version:
get('commons-validator.version'))
api(group: 'io.github.classgraph', name: 'classgraph', version:
'4.0.6')
+ api(group: 'io.micrometer', name: 'micrometer-core', version:
get('micrometer.version'))
api(group: 'io.netty', name: 'netty-all', version: '4.1.31.Final')
api(group: 'it.unimi.dsi', name: 'fastutil', version:
get('fastutil.version'))
api(group: 'javax.annotation', name: 'javax.annotation-api', version:
'1.3.2')
diff --git a/extensions/geode-modules-assembly/build.gradle
b/extensions/geode-modules-assembly/build.gradle
index efa66cf..13c9597 100644
--- a/extensions/geode-modules-assembly/build.gradle
+++ b/extensions/geode-modules-assembly/build.gradle
@@ -208,6 +208,7 @@ task distAppServer(type: Zip, dependsOn:
[':extensions:geode-modules-session:jar
filter(ReplaceTokens, tokens:['LOG4J_VERSION':
DependencyConstraints.get('log4j.version')])
filter(ReplaceTokens, tokens:['FASTUTIL_VERSION':
DependencyConstraints.get('fastutil.version')])
filter(ReplaceTokens, tokens:['ANTLR_VERSION':
DependencyConstraints.get('antlr.version')])
+ filter(ReplaceTokens, tokens:['MICROMETER_VERSION':
DependencyConstraints.get('micrometer.version')])
filter(ReplaceTokens, tokens:['TX_VERSION':
DependencyConstraints.get('javax.transaction-api.version')])
filter(ReplaceTokens, tokens:['JGROUPS_VERSION':
DependencyConstraints.get('jgroups.version')])
filter(ReplaceTokens, tokens:['JETTY_VERSION':
DependencyConstraints.get('jetty.version')])
diff --git a/extensions/geode-modules-assembly/release/session/bin/modify_war
b/extensions/geode-modules-assembly/release/session/bin/modify_war
index bdafa4c..1a44e5d 100755
--- a/extensions/geode-modules-assembly/release/session/bin/modify_war
+++ b/extensions/geode-modules-assembly/release/session/bin/modify_war
@@ -97,6 +97,7 @@ WHERE <args>:
fastutil.jar
javax.transactions-api.jar
jgroups.jar
+ micrometer-core.jar
slf4j-api.jar
slf4j-jdk14.jar (not for WebLogic)
geode-modules-slf4j-weblogic.jar (WebLogic only)
@@ -280,6 +281,7 @@ OTHER_JARS=(${GEODE}/lib/geode-core-${VERSION}.jar \
${GEODE}/lib/commons-lang3-@[email protected] \
${GEODE}/lib/shiro-core-@[email protected] \
${GEODE}/lib/commons-validator-@[email protected] \
+ ${GEODE}/lib/micrometer-core-@[email protected] \
${LIB_DIR}/geode-modules-${VERSION}.jar \
${LIB_DIR}/geode-modules-session-internal-${VERSION}.jar \
${LIB_DIR}/slf4j-api-@[email protected] \
diff --git
a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
index 31958bc..dabf7df 100644
---
a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
+++
b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
@@ -92,8 +92,8 @@ public class TomcatInstall extends ContainerInstall {
private static final String[] tomcatRequiredJars =
{"antlr", "commons-io", "commons-lang", "commons-validator", "fastutil",
"geode-common",
"geode-core", "geode-management", "javax.transaction-api",
"jgroups", "log4j-api",
- "log4j-core", "log4j-jul", "shiro-core", "jetty-server",
"jetty-util", "jetty-http",
- "jetty-io"};
+ "log4j-core", "log4j-jul", "micrometer", "shiro-core",
"jetty-server", "jetty-util",
+ "jetty-http", "jetty-io"};
private final TomcatVersion version;
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt
b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index abca10f..09c988d 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -724,6 +724,11 @@
javadoc/org/apache/geode/memcached/GemFireMemcachedServer.html
javadoc/org/apache/geode/memcached/package-frame.html
javadoc/org/apache/geode/memcached/package-summary.html
javadoc/org/apache/geode/memcached/package-tree.html
+javadoc/org/apache/geode/metrics/MetricsPublishingService.html
+javadoc/org/apache/geode/metrics/MetricsSession.html
+javadoc/org/apache/geode/metrics/package-frame.html
+javadoc/org/apache/geode/metrics/package-summary.html
+javadoc/org/apache/geode/metrics/package-tree.html
javadoc/org/apache/geode/modules/gatewaydelta/AbstractGatewayDeltaEvent.html
javadoc/org/apache/geode/modules/gatewaydelta/GatewayDelta.html
javadoc/org/apache/geode/modules/gatewaydelta/GatewayDeltaCreateEvent.html
@@ -874,7 +879,9 @@ javadoc/package-list
javadoc/script.js
javadoc/serialized-form.html
javadoc/stylesheet.css
+lib/HdrHistogram-2.1.9.jar
lib/HikariCP-3.2.0.jar
+lib/LatencyUtils-2.0.3.jar
lib/antlr-2.7.7.jar
lib/classgraph-4.0.6.jar
lib/commons-beanutils-1.9.3.jar
@@ -945,6 +952,7 @@ lib/lucene-analyzers-phonetic-6.6.2.jar
lib/lucene-core-6.6.2.jar
lib/lucene-queries-6.6.2.jar
lib/lucene-queryparser-6.6.2.jar
+lib/micrometer-core-1.1.3.jar
lib/mx4j-3.0.2.jar
lib/mx4j-remote-3.0.2.jar
lib/mx4j-tools-3.0.1.jar
diff --git
a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
index e488c40..92f206e 100644
--- a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
+++ b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
@@ -1,4 +1,6 @@
+HdrHistogram-2.1.9.jar
HikariCP-3.2.0.jar
+LatencyUtils-2.0.3.jar
antlr-2.7.7.jar
classgraph-4.0.6.jar
commons-beanutils-1.9.3.jar
@@ -61,6 +63,7 @@ lucene-analyzers-phonetic-6.6.2.jar
lucene-core-6.6.2.jar
lucene-queries-6.6.2.jar
lucene-queryparser-6.6.2.jar
+micrometer-core-1.1.3.jar
netty-all-4.1.31.Final.jar
protobuf-java-3.6.1.jar
rmiio-2.1.2.jar
diff --git a/geode-assembly/src/integrationTest/resources/expected_jars.txt
b/geode-assembly/src/integrationTest/resources/expected_jars.txt
index 1b3e988..8240782 100644
--- a/geode-assembly/src/integrationTest/resources/expected_jars.txt
+++ b/geode-assembly/src/integrationTest/resources/expected_jars.txt
@@ -1,4 +1,6 @@
+HdrHistogram
HikariCP
+LatencyUtils
animal-sniffer-annotations
antlr
aopalliance
@@ -68,6 +70,7 @@ lucene-core
lucene-queries
lucene-queryparser
mapstruct
+micrometer-core
mx4j
mx4j-remote
mx4j-tools
diff --git a/geode-assembly/src/main/dist/LICENSE
b/geode-assembly/src/main/dist/LICENSE
index 348706e..94a70e6 100644
--- a/geode-assembly/src/main/dist/LICENSE
+++ b/geode-assembly/src/main/dist/LICENSE
@@ -725,4 +725,6 @@ domain:
- AOP Alliance v1.0 (http://aopalliance.sourceforge.net)
- CompactConcurrentHashSet2, derived from JSR-166 ConcurrentHashMap v1.43
(http://gee.cs.oswego.edu/dl/concurrency-interest).
+ - HdrHistogram (https://github.com/HdrHistogram/HdrHistogram)
+ - LatencyUtils (https://github.com/LatencyUtils/LatencyUtils)
- tooltip.js v1.2.6 (https://github.com/jquerytools/jquerytools)
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index c91ba88..5b5da3e 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -194,6 +194,8 @@ dependencies {
exclude module: 'xml-apis'
ext.optional = true
}
+ compile('io.micrometer:micrometer-core')
+
compile('io.netty:netty-all') {
ext.optional = true
}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
index 741d86e..c13b5f7 100755
---
a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
+++
b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
@@ -77,6 +77,7 @@ import javax.transaction.TransactionManager;
import com.sun.jna.Native;
import com.sun.jna.Platform;
+import io.micrometer.core.instrument.MeterRegistry;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
@@ -281,7 +282,8 @@ public class GemFireCacheImpl implements InternalCache,
InternalClientCache, Has
* The {@code CacheLifecycleListener} s that have been registered in this VM
*/
@MakeNotStatic
- private static final Set<CacheLifecycleListener> cacheLifecycleListeners =
new HashSet<>();
+ private static final Set<CacheLifecycleListener> cacheLifecycleListeners =
+ new CopyOnWriteArraySet<>();
/**
* Define gemfire.Cache.ASYNC_EVENT_LISTENERS=true to invoke event listeners
in the background
@@ -613,6 +615,8 @@ public class GemFireCacheImpl implements InternalCache,
InternalClientCache, Has
private Optional<HttpService> httpService = Optional.ofNullable(null);
+ private final MeterRegistry meterRegistry;
+
static {
// this works around jdk bug 6427854, reported in ticket #44434
String propertyName = "sun.nio.ch.bugLevel";
@@ -763,6 +767,7 @@ public class GemFireCacheImpl implements InternalCache,
InternalClientCache, Has
* @deprecated Rather than fishing for a cache with this static method, use
a cache that is passed
* in to your method.
*/
+ @Deprecated
public static GemFireCacheImpl getForPdx(String reason) {
InternalDistributedSystem system = getAnyInstance();
@@ -784,12 +789,13 @@ public class GemFireCacheImpl implements InternalCache,
InternalClientCache, Has
* Currently only unit tests set the typeRegistry parameter to a non-null
value
*/
GemFireCacheImpl(boolean isClient, PoolFactory poolFactory,
- InternalDistributedSystem internalDistributedSystem,
- CacheConfig cacheConfig, boolean useAsyncEventListeners, TypeRegistry
typeRegistry) {
+ InternalDistributedSystem internalDistributedSystem, CacheConfig
cacheConfig,
+ boolean useAsyncEventListeners, TypeRegistry typeRegistry, MeterRegistry
meterRegistry) {
this.isClient = isClient;
this.poolFactory = poolFactory;
this.cacheConfig = cacheConfig; // do early for bug 43213
this.pdxRegistry = typeRegistry;
+ this.meterRegistry = meterRegistry;
// Synchronized to prevent a new cache from being created
// before an old one has finished closing
@@ -953,6 +959,11 @@ public class GemFireCacheImpl implements InternalCache,
InternalClientCache, Has
}
@Override
+ public MeterRegistry getMeterRegistry() {
+ return meterRegistry;
+ }
+
+ @Override
public Optional<HttpService> getHttpService() {
return httpService;
}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java
index a3d38ba..ddd0a92 100644
---
a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java
+++
b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java
@@ -27,6 +27,8 @@ import java.util.concurrent.Executor;
import javax.transaction.TransactionManager;
+import io.micrometer.core.instrument.MeterRegistry;
+
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.cache.Declarable;
@@ -377,4 +379,6 @@ public interface InternalCache extends Cache,
Extensible<Cache>, CacheTime {
void initialize();
void throwCacheExistsException();
+
+ MeterRegistry getMeterRegistry();
}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheBuilder.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheBuilder.java
index 342cef9..8c8702e 100644
---
a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheBuilder.java
+++
b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheBuilder.java
@@ -20,8 +20,11 @@ import static
org.apache.geode.distributed.internal.InternalDistributedSystem.AL
import java.util.Optional;
import java.util.Properties;
+import java.util.function.Consumer;
import java.util.function.Supplier;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import org.apache.logging.log4j.Logger;
import org.apache.geode.annotations.VisibleForTesting;
@@ -39,6 +42,8 @@ import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.distributed.internal.SecurityConfig;
import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.metrics.CacheLifecycleMetricsSession;
+import org.apache.geode.internal.metrics.CompositeMeterRegistryFactory;
import org.apache.geode.pdx.PdxSerializer;
import org.apache.geode.pdx.internal.TypeRegistry;
import org.apache.geode.security.AuthenticationFailedException;
@@ -58,6 +63,8 @@ public class InternalCacheBuilder {
private final Properties configProperties;
private final CacheConfig cacheConfig;
+ private final CompositeMeterRegistryFactory compositeMeterRegistryFactory;
+ private final Consumer<CompositeMeterRegistry> metricsSessionInitializer;
private final Supplier<InternalDistributedSystem> singletonSystemSupplier;
private final Supplier<InternalCache> singletonCacheSupplier;
private final InternalDistributedSystemConstructor
internalDistributedSystemConstructor;
@@ -102,20 +109,29 @@ public class InternalCacheBuilder {
}
private InternalCacheBuilder(Properties configProperties, CacheConfig
cacheConfig) {
- this(configProperties, cacheConfig,
InternalDistributedSystem::getConnectedInstance,
+ this(configProperties,
+ cacheConfig,
+ new CompositeMeterRegistryFactory() {},
+ CacheLifecycleMetricsSession.builder()::build,
+ InternalDistributedSystem::getConnectedInstance,
InternalDistributedSystem::connectInternal,
- GemFireCacheImpl::getInstance, GemFireCacheImpl::new);
+ GemFireCacheImpl::getInstance,
+ GemFireCacheImpl::new);
}
@VisibleForTesting
InternalCacheBuilder(Properties configProperties,
CacheConfig cacheConfig,
+ CompositeMeterRegistryFactory compositeMeterRegistryFactory,
+ Consumer<CompositeMeterRegistry> metricsSessionInitializer,
Supplier<InternalDistributedSystem> singletonSystemSupplier,
InternalDistributedSystemConstructor
internalDistributedSystemConstructor,
Supplier<InternalCache> singletonCacheSupplier,
InternalCacheConstructor internalCacheConstructor) {
this.configProperties = configProperties;
this.cacheConfig = cacheConfig;
+ this.compositeMeterRegistryFactory = compositeMeterRegistryFactory;
+ this.metricsSessionInitializer = metricsSessionInitializer;
this.singletonSystemSupplier = singletonSystemSupplier;
this.internalDistributedSystemConstructor =
internalDistributedSystemConstructor;
this.internalCacheConstructor = internalCacheConstructor;
@@ -173,9 +189,18 @@ public class InternalCacheBuilder {
existingCache(internalDistributedSystem::getCache,
singletonCacheSupplier);
if (cache == null) {
+ int systemId =
internalDistributedSystem.getConfig().getDistributedSystemId();
+ String memberName = internalDistributedSystem.getName();
+ String hostName =
internalDistributedSystem.getDistributedMember().getHost();
+
+ CompositeMeterRegistry compositeMeterRegistry =
compositeMeterRegistryFactory
+ .create(systemId, memberName, hostName);
+
+ metricsSessionInitializer.accept(compositeMeterRegistry);
+
cache =
internalCacheConstructor.construct(isClient, poolFactory,
internalDistributedSystem,
- cacheConfig, useAsyncEventListeners, typeRegistry);
+ cacheConfig, useAsyncEventListeners, typeRegistry,
compositeMeterRegistry);
internalDistributedSystem.setCache(cache);
cache.initialize();
@@ -384,7 +409,7 @@ public class InternalCacheBuilder {
interface InternalCacheConstructor {
InternalCache construct(boolean isClient, PoolFactory poolFactory,
InternalDistributedSystem internalDistributedSystem, CacheConfig
cacheConfig,
- boolean useAsyncEventListeners, TypeRegistry typeRegistry);
+ boolean useAsyncEventListeners, TypeRegistry typeRegistry,
MeterRegistry meterRegistry);
}
@VisibleForTesting
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java
index bde6506..39d9b73 100644
---
a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java
+++
b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalCacheForClientAccess.java
@@ -32,6 +32,8 @@ import java.util.concurrent.TimeUnit;
import javax.naming.Context;
import javax.transaction.TransactionManager;
+import io.micrometer.core.instrument.MeterRegistry;
+
import org.apache.geode.CancelCriterion;
import org.apache.geode.LogWriter;
import org.apache.geode.cache.Cache;
@@ -1234,4 +1236,9 @@ public class InternalCacheForClientAccess implements
InternalCache {
public void throwCacheExistsException() {
delegate.throwCacheExistsException();
}
+
+ @Override
+ public MeterRegistry getMeterRegistry() {
+ return delegate.getMeterRegistry();
+ }
}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
index 7f47d09..2548f23 100755
---
a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
+++
b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
@@ -40,6 +40,8 @@ import java.util.concurrent.TimeUnit;
import javax.naming.Context;
import javax.transaction.TransactionManager;
+import io.micrometer.core.instrument.MeterRegistry;
+
import org.apache.geode.CancelCriterion;
import org.apache.geode.GemFireIOException;
import org.apache.geode.LogWriter;
@@ -2441,4 +2443,9 @@ public class CacheCreation implements InternalCache {
public Optional<HttpService> getHttpService() {
throw new UnsupportedOperationException("Should not be invoked");
}
+
+ @Override
+ public MeterRegistry getMeterRegistry() {
+ throw new UnsupportedOperationException("Should not be invoked");
+ }
}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSession.java
b/geode-core/src/main/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSession.java
new file mode 100644
index 0000000..a621185
--- /dev/null
+++
b/geode-core/src/main/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSession.java
@@ -0,0 +1,129 @@
+/*
+ * 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.geode.internal.metrics;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+
+import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.internal.cache.CacheLifecycleListener;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.metrics.MetricsPublishingService;
+import org.apache.geode.metrics.MetricsSession;
+
+public class CacheLifecycleMetricsSession implements MetricsSession,
CacheLifecycleListener {
+ private final CacheLifecycle cacheLifecycle;
+ private final CompositeMeterRegistry registry;
+ private final Collection<MetricsPublishingService> metricsPublishingServices;
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @VisibleForTesting
+ CacheLifecycleMetricsSession(CacheLifecycle cacheLifecycle,
CompositeMeterRegistry registry,
+ Collection<MetricsPublishingService> metricsPublishingServices) {
+ this.cacheLifecycle = cacheLifecycle;
+ this.registry = registry;
+ this.metricsPublishingServices = metricsPublishingServices;
+ }
+
+ @Override
+ public void addSubregistry(MeterRegistry subregistry) {
+ registry.add(subregistry);
+ }
+
+ @Override
+ public void removeSubregistry(MeterRegistry subregistry) {
+ registry.remove(subregistry);
+ }
+
+ @Override
+ public void cacheCreated(InternalCache cache) {
+ for (MetricsPublishingService metricsPublishingService :
metricsPublishingServices) {
+ metricsPublishingService.start(this);
+ }
+ }
+
+ @Override
+ public void cacheClosed(InternalCache cache) {
+ cacheLifecycle.removeListener(this);
+
+ for (MetricsPublishingService metricsPublishingService :
metricsPublishingServices) {
+ metricsPublishingService.stop();
+ }
+
+ for (MeterRegistry downstream : new HashSet<>(registry.getRegistries())) {
+ removeSubregistry(downstream);
+ }
+ }
+
+ @VisibleForTesting
+ CompositeMeterRegistry meterRegistry() {
+ return registry;
+ }
+
+ @VisibleForTesting
+ Collection<MetricsPublishingService> metricsPublishingServices() {
+ return metricsPublishingServices;
+ }
+
+ public static class Builder {
+
+ private CollectingServiceLoader serviceLoader = new
CollectingServiceLoader() {};
+ private CacheLifecycle cacheLifecycle = new CacheLifecycle() {};
+
+ private Builder() {
+ // private to prevent instantiation
+ }
+
+ @VisibleForTesting
+ Builder setCacheLifecycle(CacheLifecycle cacheLifecycle) {
+ this.cacheLifecycle = cacheLifecycle;
+ return this;
+ }
+
+ @VisibleForTesting
+ Builder setServiceLoader(CollectingServiceLoader serviceLoader) {
+ this.serviceLoader = serviceLoader;
+ return this;
+ }
+
+ public CacheLifecycleMetricsSession build(CompositeMeterRegistry registry)
{
+ Collection<MetricsPublishingService> services =
+ serviceLoader.loadServices(MetricsPublishingService.class);
+ CacheLifecycleMetricsSession cacheLifecycleMetricsSession =
+ new CacheLifecycleMetricsSession(cacheLifecycle, registry, services);
+ cacheLifecycle.addListener(cacheLifecycleMetricsSession);
+ return cacheLifecycleMetricsSession;
+ }
+ }
+
+ @VisibleForTesting
+ interface CacheLifecycle {
+
+ default void addListener(CacheLifecycleListener listener) {
+ GemFireCacheImpl.addCacheLifecycleListener(listener);
+ }
+
+ default void removeListener(CacheLifecycleListener listener) {
+ GemFireCacheImpl.removeCacheLifecycleListener(listener);
+ }
+ }
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/metrics/CollectingServiceLoader.java
b/geode-core/src/main/java/org/apache/geode/internal/metrics/CollectingServiceLoader.java
new file mode 100644
index 0000000..c5cbd69
--- /dev/null
+++
b/geode-core/src/main/java/org/apache/geode/internal/metrics/CollectingServiceLoader.java
@@ -0,0 +1,29 @@
+/*
+ * 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.geode.internal.metrics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.ServiceLoader;
+
+interface CollectingServiceLoader {
+
+ default <S> Collection<S> loadServices(Class<S> service) {
+ List<S> services = new ArrayList<>();
+ ServiceLoader.load(service).iterator().forEachRemaining(services::add);
+ return services;
+ }
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/internal/metrics/CompositeMeterRegistryFactory.java
b/geode-core/src/main/java/org/apache/geode/internal/metrics/CompositeMeterRegistryFactory.java
new file mode 100644
index 0000000..a0e378d
--- /dev/null
+++
b/geode-core/src/main/java/org/apache/geode/internal/metrics/CompositeMeterRegistryFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.geode.internal.metrics;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+
+import org.apache.geode.annotations.VisibleForTesting;
+
+/**
+ * Creates {@code CompositeMeterRegistry} and configures commonTags.
+ */
+public interface CompositeMeterRegistryFactory {
+
+ @VisibleForTesting
+ String CLUSTER_ID_TAG = "ClusterId";
+ @VisibleForTesting
+ String MEMBER_NAME_TAG = "MemberName";
+ @VisibleForTesting
+ String HOST_NAME_TAG = "HostName";
+
+ default CompositeMeterRegistry create(int systemId, String memberName,
String hostName) {
+ CompositeMeterRegistry registry = new CompositeMeterRegistry();
+
+ MeterRegistry.Config registryConfig = registry.config();
+ registryConfig.commonTags(CLUSTER_ID_TAG, String.valueOf(systemId));
+ registryConfig.commonTags(MEMBER_NAME_TAG, memberName == null ? "" :
memberName);
+ registryConfig.commonTags(HOST_NAME_TAG, hostName == null ? "" : hostName);
+
+ return registry;
+ }
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/metrics/MetricsPublishingService.java
b/geode-core/src/main/java/org/apache/geode/metrics/MetricsPublishingService.java
new file mode 100644
index 0000000..0baf765
--- /dev/null
+++
b/geode-core/src/main/java/org/apache/geode/metrics/MetricsPublishingService.java
@@ -0,0 +1,89 @@
+/*
+ * 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.geode.metrics;
+
+import java.util.ServiceLoader;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * Publishes metrics generated by Micrometer meters in the cache meter
registry.
+ *
+ * <p>
+ * Geode discovers {@code MetricsPublishingService}s during cache creation,
using the standard Java
+ * {@link ServiceLoader} mechanism:
+ *
+ * <p>
+ *
+ * <pre>
+ * package com.application;
+ *
+ * public class MyMetricsPublishingService implements MetricsPublishingService
{
+ * private volatile MeterRegistry registry;
+ * private volatile MetricsSession session;
+ *
+ * {@literal @}Override
+ * public void start(MetricsSession session) {
+ * this.session = session;
+ * registry = ... // configure your meter registry and start publishing
+ *
+ * // add your registry as a sub-registry to the cache's composite registry
+ * session.addSubregistry(registry);
+ * }
+ *
+ * {@literal @}Override
+ * public void stop() {
+ * ...
+ * // clean up any resources used by your meter registry
+ * ...
+ *
+ * session.removeSubregistry(registry);
+ * }
+ * }
+ * </pre>
+ *
+ * <p>
+ * To make your service available for loading, add the following
provider-configuration file in the
+ * resource directory of your application Jar:
+ *
+ * <p>
+ * {@code META-INF/services/org.apache.geode.metrics.MetricsPublishingService}
+ *
+ * <p>
+ * Add a line inside the file indicating the fully qualified class name of
your implementation:
+ *
+ * <p>
+ * {@code com.application.MyMetricsPublishingService}
+ *
+ * @see <a href="https://micrometer.io/docs">Micrometer Documentation</a>
+ * @see <a href="https://micrometer.io/docs/concepts">Micrometer Concepts</a>
+ */
+@Experimental("Micrometer metrics is a new addition to Geode and the API may
change")
+public interface MetricsPublishingService {
+
+ /**
+ * Invoked when a metrics session is started during cache initialization.
The implementation can
+ * use the metrics session to add sub-registries to the cache's composite
registry for publishing
+ * metrics to external monitoring systems.
+ *
+ * @param session the metrics session that is used to connect sub-registries
+ */
+ void start(MetricsSession session);
+
+ /**
+ * Invoked when a metrics session is stopped during cache close.
+ */
+ void stop();
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/metrics/MetricsSession.java
b/geode-core/src/main/java/org/apache/geode/metrics/MetricsSession.java
new file mode 100644
index 0000000..dcad5f4
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/metrics/MetricsSession.java
@@ -0,0 +1,44 @@
+/*
+ * 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.geode.metrics;
+
+import io.micrometer.core.instrument.MeterRegistry;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * Provides the ability to add and remove a meter registry for publishing
cache metrics to external
+ * monitoring systems.
+ */
+@Experimental("Micrometer metrics is a new addition to Geode and the API may
change")
+public interface MetricsSession {
+ /**
+ * Adds the given registry to the cache's composite registry.
+ *
+ * @param subregistry the registry to add
+ */
+ void addSubregistry(MeterRegistry subregistry);
+
+ /**
+ * Removes the given registry from the cache's composite registry.
+ *
+ * <p>
+ * <strong>Caution:</strong> This method deletes from the sub-registry each
meter that corresponds
+ * to a meter in the cache's composite registry.
+ *
+ * @param subregistry the registry to remove
+ */
+ void removeSubregistry(MeterRegistry subregistry);
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/metrics/package-info.java
b/geode-core/src/main/java/org/apache/geode/metrics/package-info.java
new file mode 100644
index 0000000..63bfcc0
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/metrics/package-info.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/**
+ * Geode uses Micrometer for its metrics. Each Geode cache maintains a
registry of all meters that
+ * instrument Geode code. Users can add sub-registries for various purposes. A
key purpose for a
+ * sub-registry is to publish a cache's metrics to an external monitoring
system.
+ *
+ * <p>
+ * The {@link org.apache.geode.metrics.MetricsSession MetricsSession} provides
the ability to add
+ * and remove a meter registry for publishing cache metrics to external
monitoring systems.
+ *
+ * <p>
+ * The {@link org.apache.geode.metrics.MetricsPublishingService
MetricsPublishingService} defines
+ * a service that users can implement to be notified when a metrics session
starts or stops. When
+ * a session starts, the service can add a meter registry to the cache's
composite registry. When
+ * the session stops, the service can clean up any resources and remove its
meter registry from the
+ * cache's composite registry.
+ *
+ * @see <a href="https://micrometer.io/docs">Micrometer Documentation</a>
+ * @see <a href="https://micrometer.io/docs/concepts">Micrometer Concepts</a>
+ */
+@Experimental("Micrometer metrics is a new addition to Geode and the API may
change")
+package org.apache.geode.metrics;
+
+import org.apache.geode.annotations.Experimental;
diff --git
a/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalDistributedSystemTest.java
b/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalDistributedSystemStatisticsManagerTest.java
similarity index 99%
rename from
geode-core/src/test/java/org/apache/geode/distributed/internal/InternalDistributedSystemTest.java
rename to
geode-core/src/test/java/org/apache/geode/distributed/internal/InternalDistributedSystemStatisticsManagerTest.java
index 3c8ad85..71f1848 100644
---
a/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalDistributedSystemTest.java
+++
b/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalDistributedSystemStatisticsManagerTest.java
@@ -42,7 +42,7 @@ import
org.apache.geode.internal.statistics.StatisticsManagerFactory;
/**
* Unit tests for {@link InternalDistributedSystem}.
*/
-public class InternalDistributedSystemTest {
+public class InternalDistributedSystemStatisticsManagerTest {
private static final String STATISTIC_NAME = "statistic-name";
private static final String STATISTIC_DESCRIPTION = "statistic-description";
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/cache/GemFireCacheImplTest.java
b/geode-core/src/test/java/org/apache/geode/internal/cache/GemFireCacheImplTest.java
index b278f08..5f97af0 100644
---
a/geode-core/src/test/java/org/apache/geode/internal/cache/GemFireCacheImplTest.java
+++
b/geode-core/src/test/java/org/apache/geode/internal/cache/GemFireCacheImplTest.java
@@ -30,6 +30,7 @@ import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
+import io.micrometer.core.instrument.MeterRegistry;
import org.junit.After;
import org.junit.Test;
@@ -54,6 +55,8 @@ public class GemFireCacheImplTest {
@After
public void tearDown() {
+ InternalDistributedSystem.ALLOW_MULTIPLE_SYSTEMS = false;
+
if (gemFireCacheImpl != null) {
gemFireCacheImpl.close();
}
@@ -338,6 +341,13 @@ public class GemFireCacheImplTest {
InternalDistributedSystem.ALLOW_MULTIPLE_SYSTEMS = oldValue;
}
+ @Test
+ public void getMeterRegistryReturnsTheMeterRegistry() {
+ gemFireCacheImpl = createGemFireCacheImpl();
+
+
assertThat(gemFireCacheImpl.getMeterRegistry()).isInstanceOf(MeterRegistry.class);
+ }
+
private static GemFireCacheImpl createGemFireCacheImpl() {
return (GemFireCacheImpl) new
InternalCacheBuilder().create(Fakes.distributedSystem());
}
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderAllowsMultipleSystemsTest.java
b/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderAllowsMultipleSystemsTest.java
index baba452..ed0ac66 100644
---
a/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderAllowsMultipleSystemsTest.java
+++
b/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderAllowsMultipleSystemsTest.java
@@ -26,20 +26,26 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
import java.util.Properties;
+import java.util.function.Consumer;
import java.util.function.Supplier;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import org.assertj.core.api.ThrowableAssert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
import org.apache.geode.cache.CacheExistsException;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import
org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import
org.apache.geode.internal.cache.InternalCacheBuilder.InternalCacheConstructor;
import
org.apache.geode.internal.cache.InternalCacheBuilder.InternalDistributedSystemConstructor;
+import org.apache.geode.internal.metrics.CompositeMeterRegistryFactory;
/**
* Unit tests for {@link InternalCacheBuilder} when
@@ -49,6 +55,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
private static final int ANY_SYSTEM_ID = 12;
private static final String ANY_MEMBER_NAME = "a-member-name";
+ private static final String ANY_HOST_NAME = "a-host-name";
private static final Supplier<InternalDistributedSystem>
THROWING_SYSTEM_SUPPLIER =
() -> {
@@ -64,12 +71,20 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
throw new AssertionError("throwing system constructor");
};
private static final InternalCacheConstructor THROWING_CACHE_CONSTRUCTOR =
- (a, b, c, d, e, f) -> {
+ (a, b, c, d, e, f, g) -> {
throw new AssertionError("throwing cache constructor");
};
+ @Mock
+ private CompositeMeterRegistryFactory compositeMeterRegistryFactory;
+
+ @Mock
+ private Consumer<CompositeMeterRegistry> metricsSessionInitializer;
+
@Before
public void setUp() {
+ initMocks(this);
+
InternalDistributedSystem.ALLOW_MULTIPLE_SYSTEMS = true;
}
@@ -82,6 +97,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
public void create_throwsNullPointerException_ifConfigPropertiesIsNull() {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
null, new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, constructorOf(constructedSystem()),
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache()));
@@ -95,6 +111,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
public void create_throwsNullPointerException_andCacheConfigIsNull() {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), null,
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, constructorOf(constructedSystem()),
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache()));
@@ -113,6 +130,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
configProperties, new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, systemConstructor,
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -127,6 +145,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, constructorOf(constructedSystem()),
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -142,6 +161,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, constructorOf(constructedSystem),
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -158,13 +178,14 @@ public class
InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, constructorOf(constructedSystem),
THROWING_CACHE_SUPPLIER, cacheConstructor);
internalCacheBuilder.create();
verify(cacheConstructor).construct(anyBoolean(), any(),
same(constructedSystem), any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@@ -172,6 +193,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
public void createWithSystem_throwsNullPointerException_ifSystemIsNull() {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -186,6 +208,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -202,6 +225,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -219,6 +243,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, cacheConstructor);
@@ -226,7 +251,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
.create(givenSystem);
verify(cacheConstructor).construct(anyBoolean(), any(), same(givenSystem),
any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
@@ -236,6 +261,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -252,6 +278,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, constructorOf(constructedCache));
@@ -269,6 +296,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, cacheConstructor);
@@ -276,7 +304,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
.create(givenSystem);
verify(cacheConstructor).construct(anyBoolean(), any(), same(givenSystem),
any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
@@ -285,6 +313,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -301,6 +330,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -319,6 +349,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), throwingCacheConfig(thrownByCacheConfig),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -335,6 +366,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), throwingCacheConfig(new
IllegalStateException("incompatible")),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -352,6 +384,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -369,6 +402,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -380,25 +414,29 @@ public class
InternalCacheBuilderAllowsMultipleSystemsTest {
}
private InternalDistributedSystem constructedSystem() {
- return systemWith("constructedSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME);
+ return systemWith("constructedSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME,
ANY_HOST_NAME);
}
private InternalDistributedSystem givenSystem() {
- return systemWith("givenSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME);
+ return systemWith("givenSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME,
ANY_HOST_NAME);
}
- private InternalDistributedSystem systemWith(String mockName, int systemId,
String memberName) {
+ private InternalDistributedSystem systemWith(String mockName, int systemId,
String memberName,
+ String hostName) {
InternalDistributedSystem system = mock(InternalDistributedSystem.class,
mockName);
DistributionConfig distributionConfig = mock(DistributionConfig.class);
+ InternalDistributedMember distributedMember =
mock(InternalDistributedMember.class);
when(distributionConfig.getDistributedSystemId()).thenReturn(systemId);
+ when(distributedMember.getHost()).thenReturn(hostName);
when(system.getConfig()).thenReturn(distributionConfig);
+ when(system.getDistributedMember()).thenReturn(distributedMember);
when(system.getName()).thenReturn(memberName);
return system;
}
private InternalDistributedSystem givenSystemWithCache(CacheState state) {
InternalDistributedSystem system =
- systemWith("givenSystemWithCache", ANY_SYSTEM_ID, ANY_MEMBER_NAME);
+ systemWith("givenSystemWithCache", ANY_SYSTEM_ID, ANY_MEMBER_NAME,
ANY_HOST_NAME);
systemCache(system, state);
return system;
}
@@ -433,7 +471,7 @@ public class InternalCacheBuilderAllowsMultipleSystemsTest {
private static InternalCacheConstructor constructorOf(InternalCache
constructedCache) {
InternalCacheConstructor constructor =
mock(InternalCacheConstructor.class, "internal cache constructor");
- when(constructor.construct(anyBoolean(), any(), any(), any(),
anyBoolean(), any()))
+ when(constructor.construct(anyBoolean(), any(), any(), any(),
anyBoolean(), any(), any()))
.thenReturn(constructedCache);
return constructor;
}
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderTest.java
b/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderTest.java
index 2814376..e30a1a7 100644
---
a/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderTest.java
+++
b/geode-core/src/test/java/org/apache/geode/internal/cache/InternalCacheBuilderTest.java
@@ -19,6 +19,8 @@ import static
org.apache.geode.internal.cache.InternalCacheBuilderTest.CacheStat
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@@ -30,8 +32,10 @@ import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import java.util.Properties;
+import java.util.function.Consumer;
import java.util.function.Supplier;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.Before;
import org.junit.Test;
@@ -40,8 +44,10 @@ import org.mockito.Mock;
import org.apache.geode.cache.CacheExistsException;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import
org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import
org.apache.geode.internal.cache.InternalCacheBuilder.InternalCacheConstructor;
import
org.apache.geode.internal.cache.InternalCacheBuilder.InternalDistributedSystemConstructor;
+import org.apache.geode.internal.metrics.CompositeMeterRegistryFactory;
/**
* Unit tests for {@link InternalCacheBuilder}.
@@ -50,6 +56,7 @@ public class InternalCacheBuilderTest {
private static final int ANY_SYSTEM_ID = 12;
private static final String ANY_MEMBER_NAME = "a-member-name";
+ private static final String ANY_HOST_NAME = "a-host-name";
private static final Supplier<InternalDistributedSystem>
THROWING_SYSTEM_SUPPLIER =
() -> {
@@ -65,7 +72,7 @@ public class InternalCacheBuilderTest {
throw new AssertionError("throwing system constructor");
};
private static final InternalCacheConstructor THROWING_CACHE_CONSTRUCTOR =
- (a, b, c, d, e, f) -> {
+ (a, b, c, d, e, f, g) -> {
throw new AssertionError("throwing cache constructor");
};
@@ -75,6 +82,12 @@ public class InternalCacheBuilderTest {
@Mock
private Supplier<InternalCache> nullSingletonCacheSupplier;
+ @Mock
+ private CompositeMeterRegistryFactory compositeMeterRegistryFactory;
+
+ @Mock
+ private Consumer<CompositeMeterRegistry> metricsSessionInitializer;
+
@Before
public void setUp() {
initMocks(this);
@@ -89,6 +102,7 @@ public class InternalCacheBuilderTest {
public void create_throwsNullPointerException_ifConfigPropertiesIsNull() {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
null, new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
nullSingletonSystemSupplier, constructorOf(constructedSystem()),
nullSingletonCacheSupplier, constructorOf(constructedCache()));
@@ -102,6 +116,7 @@ public class InternalCacheBuilderTest {
public void create_throwsNullPointerException_andCacheConfigIsNull() {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), null,
+ compositeMeterRegistryFactory, metricsSessionInitializer,
nullSingletonSystemSupplier, constructorOf(constructedSystem()),
nullSingletonCacheSupplier, constructorOf(constructedCache()));
@@ -120,6 +135,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
configProperties, new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
nullSingletonSystemSupplier, systemConstructor,
nullSingletonCacheSupplier, constructorOf(constructedCache));
@@ -130,11 +146,61 @@ public class InternalCacheBuilderTest {
}
@Test
+ public void create_constructsCompositeMeterRegistry_ifNoCacheExists() {
+ int theSystemId = 21;
+ String theMemberName = "theMemberName";
+ String theHostName = "theHostName";
+ InternalDistributedSystem theConstructedSystem =
+ systemWith("theConstructedSystem", theSystemId, theMemberName,
theHostName);
+ InternalCache constructedCache = constructedCache();
+
+ CompositeMeterRegistryFactory theCompositeMeterRegistryFactory =
+ mock(CompositeMeterRegistryFactory.class);
+
+ InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
+ new Properties(), new CacheConfig(),
+ theCompositeMeterRegistryFactory, metricsSessionInitializer,
+ nullSingletonSystemSupplier, constructorOf(theConstructedSystem),
+ nullSingletonCacheSupplier, constructorOf(constructedCache));
+
+ internalCacheBuilder
+ .create();
+
+ verify(theCompositeMeterRegistryFactory)
+ .create(eq(theSystemId), eq(theMemberName), eq(theHostName));
+ }
+
+ @Test
+ public void
create_setsConstructedCompositeMeterRegistry_onTheConstructedCache_ifNoCacheExists()
{
+ InternalCache constructedCache = constructedCache();
+ InternalCacheConstructor cacheConstructor =
constructorOf(constructedCache);
+
+ CompositeMeterRegistry theCompositeMeterRegistry = new
CompositeMeterRegistry();
+ CompositeMeterRegistryFactory theCompositeMeterRegistryFactory =
+ mock(CompositeMeterRegistryFactory.class);
+ when(theCompositeMeterRegistryFactory.create(anyInt(), any(), any()))
+ .thenReturn(theCompositeMeterRegistry);
+
+ InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
+ new Properties(), new CacheConfig(),
+ theCompositeMeterRegistryFactory, metricsSessionInitializer,
+ nullSingletonSystemSupplier, constructorOf(constructedSystem()),
+ nullSingletonCacheSupplier, cacheConstructor);
+
+ internalCacheBuilder
+ .create();
+
+ verify(cacheConstructor).construct(anyBoolean(), any(), any(), any(),
+ anyBoolean(), any(), same(theCompositeMeterRegistry));
+ }
+
+ @Test
public void create_returnsConstructedCache_ifNoSystemExists() {
InternalCache constructedCache = constructedCache();
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
nullSingletonSystemSupplier, constructorOf(constructedSystem()),
nullSingletonCacheSupplier, constructorOf(constructedCache));
@@ -151,6 +217,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
nullSingletonSystemSupplier, constructorOf(constructedSystem),
nullSingletonCacheSupplier, constructorOf(constructedCache));
@@ -169,6 +236,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
nullSingletonSystemSupplier, constructorOf(constructedSystem),
nullSingletonCacheSupplier, cacheConstructor);
@@ -176,7 +244,7 @@ public class InternalCacheBuilderTest {
.create();
verify(cacheConstructor).construct(anyBoolean(), any(),
same(constructedSystem), any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
@@ -185,6 +253,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem()), THROWING_SYSTEM_CONSTRUCTOR,
nullSingletonCacheSupplier, constructorOf(constructedCache));
@@ -203,6 +272,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem), THROWING_SYSTEM_CONSTRUCTOR,
nullSingletonCacheSupplier, cacheConstructor);
@@ -221,6 +291,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem), THROWING_SYSTEM_CONSTRUCTOR,
nullSingletonCacheSupplier, cacheConstructor);
@@ -228,7 +299,7 @@ public class InternalCacheBuilderTest {
.create();
verify(cacheConstructor).construct(anyBoolean(), any(),
same(singletonSystem), any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
@@ -237,6 +308,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem()), THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(CLOSED)), constructorOf(constructedCache));
@@ -253,6 +325,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem), THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(CLOSED)), constructorOf(constructedCache));
@@ -270,6 +343,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem), THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(CLOSED)), cacheConstructor);
@@ -277,13 +351,14 @@ public class InternalCacheBuilderTest {
.create();
verify(cacheConstructor).construct(anyBoolean(), any(),
same(singletonSystem), any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
public void
create_throwsCacheExistsException_ifSingletonSystemExists_andSingletonCacheIsOpen_butExistingIsNotOk()
{
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem()), THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(OPEN)), THROWING_CACHE_CONSTRUCTOR);
@@ -300,6 +375,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), throwingCacheConfig(thrownByCacheConfig),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem()), THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(OPEN)), THROWING_CACHE_CONSTRUCTOR);
@@ -316,6 +392,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
supplierOf(singletonSystem()), THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache), THROWING_CACHE_CONSTRUCTOR);
@@ -329,6 +406,7 @@ public class InternalCacheBuilderTest {
public void createWithSystem_throwsNullPointerException_ifSystemIsNull() {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
THROWING_CACHE_SUPPLIER, THROWING_CACHE_CONSTRUCTOR);
@@ -344,6 +422,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
nullSingletonCacheSupplier, constructorOf(constructedCache));
@@ -360,6 +439,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
nullSingletonCacheSupplier, constructorOf(constructedCache));
@@ -377,6 +457,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
nullSingletonCacheSupplier, cacheConstructor);
@@ -384,7 +465,7 @@ public class InternalCacheBuilderTest {
.create(givenSystem);
verify(cacheConstructor).construct(anyBoolean(), any(), same(givenSystem),
any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
@@ -393,6 +474,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(CLOSED)), constructorOf(constructedCache));
@@ -409,6 +491,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(CLOSED)), constructorOf(constructedCache));
@@ -426,6 +509,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(CLOSED)), cacheConstructor);
@@ -433,13 +517,14 @@ public class InternalCacheBuilderTest {
.create(givenSystem);
verify(cacheConstructor).construct(anyBoolean(), any(), same(givenSystem),
any(),
- anyBoolean(), any());
+ anyBoolean(), any(), any());
}
@Test
public void
createWithSystem_throwsCacheExistsException_ifSingletonCacheIsOpen_butExistingIsNotOk()
{
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(OPEN)), THROWING_CACHE_CONSTRUCTOR);
@@ -456,6 +541,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(OPEN)), THROWING_CACHE_CONSTRUCTOR);
@@ -472,6 +558,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), throwingCacheConfig(thrownByCacheConfig),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(OPEN)), THROWING_CACHE_CONSTRUCTOR);
@@ -488,6 +575,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), throwingCacheConfig(new
IllegalStateException("incompatible")),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache(OPEN)), THROWING_CACHE_CONSTRUCTOR);
@@ -504,6 +592,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache), THROWING_CACHE_CONSTRUCTOR);
@@ -521,6 +610,7 @@ public class InternalCacheBuilderTest {
InternalCacheBuilder internalCacheBuilder = new InternalCacheBuilder(
new Properties(), new CacheConfig(),
+ compositeMeterRegistryFactory, metricsSessionInitializer,
THROWING_SYSTEM_SUPPLIER, THROWING_SYSTEM_CONSTRUCTOR,
supplierOf(singletonCache), THROWING_CACHE_CONSTRUCTOR);
@@ -532,22 +622,26 @@ public class InternalCacheBuilderTest {
}
private InternalDistributedSystem constructedSystem() {
- return systemWith("constructedSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME);
+ return systemWith("constructedSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME,
ANY_HOST_NAME);
}
private InternalDistributedSystem givenSystem() {
- return systemWith("givenSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME);
+ return systemWith("givenSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME,
ANY_HOST_NAME);
}
private InternalDistributedSystem singletonSystem() {
- return systemWith("singletonSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME);
+ return systemWith("singletonSystem", ANY_SYSTEM_ID, ANY_MEMBER_NAME,
ANY_HOST_NAME);
}
- private InternalDistributedSystem systemWith(String mockName, int systemId,
String memberName) {
+ private InternalDistributedSystem systemWith(String mockName, int systemId,
String memberName,
+ String hostName) {
InternalDistributedSystem system = mock(InternalDistributedSystem.class,
mockName);
DistributionConfig distributionConfig = mock(DistributionConfig.class);
+ InternalDistributedMember distributedMember =
mock(InternalDistributedMember.class);
when(distributionConfig.getDistributedSystemId()).thenReturn(systemId);
+ when(distributedMember.getHost()).thenReturn(hostName);
when(system.getConfig()).thenReturn(distributionConfig);
+ when(system.getDistributedMember()).thenReturn(distributedMember);
when(system.getName()).thenReturn(memberName);
return system;
}
@@ -579,7 +673,7 @@ public class InternalCacheBuilderTest {
private static InternalCacheConstructor constructorOf(InternalCache
constructedCache) {
InternalCacheConstructor constructor =
mock(InternalCacheConstructor.class, "internal cache constructor");
- when(constructor.construct(anyBoolean(), any(), any(), any(),
anyBoolean(), any()))
+ when(constructor.construct(anyBoolean(), any(), any(), any(),
anyBoolean(), any(), any()))
.thenReturn(constructedCache);
return constructor;
}
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSessionBuilderTest.java
b/geode-core/src/test/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSessionBuilderTest.java
new file mode 100644
index 0000000..d8f5dbb
--- /dev/null
+++
b/geode-core/src/test/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSessionBuilderTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.geode.internal.metrics;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.internal.metrics.CacheLifecycleMetricsSession.Builder;
+import
org.apache.geode.internal.metrics.CacheLifecycleMetricsSession.CacheLifecycle;
+import org.apache.geode.metrics.MetricsPublishingService;
+
+public class CacheLifecycleMetricsSessionBuilderTest {
+
+ private CompositeMeterRegistry registry;
+ private Builder builder;
+
+ @Before
+ public void setUp() {
+ CacheLifecycle cacheLifecycle = mock(CacheLifecycle.class);
+ registry = new CompositeMeterRegistry();
+ builder = CacheLifecycleMetricsSession
+ .builder()
+ .setCacheLifecycle(cacheLifecycle);
+ }
+
+ @Test
+ public void buildsCacheMetricsSession() {
+
assertThat(builder.build(registry)).isInstanceOf(CacheLifecycleMetricsSession.class);
+ }
+
+ @Test
+ public void buildsCacheMetricsSession_withGivenMeterRegistry() {
+ CompositeMeterRegistry givenRegistry = new CompositeMeterRegistry();
+
+ CacheLifecycleMetricsSession session = builder
+ .build(givenRegistry);
+
+ assertThat(session.meterRegistry()).isSameAs(givenRegistry);
+ }
+
+ @Test
+ public void addsSessionAsCacheLifecycleListener() {
+ CacheLifecycle theCacheLifecycle = mock(CacheLifecycle.class);
+
+ CacheLifecycleMetricsSession session = builder
+ .setCacheLifecycle(theCacheLifecycle)
+ .build(registry);
+
+ verify(theCacheLifecycle).addListener(same(session));
+ }
+
+ @Test
+ public void loadsMetricsPublishingServices() {
+ CollectingServiceLoader theMetricsPublishingServicesLoader =
+ mock(CollectingServiceLoader.class);
+
+ builder
+ .setServiceLoader(theMetricsPublishingServicesLoader)
+ .build(registry);
+
+
verify(theMetricsPublishingServicesLoader).loadServices(MetricsPublishingService.class);
+ }
+
+ @Test
+ public void buildsCacheMetricsSession_withMetricsPublishingServices() {
+ CollectingServiceLoader theMetricsPublishingServicesLoader =
+ mock(CollectingServiceLoader.class);
+ Collection<MetricsPublishingService> theMetricsPublishingServices =
Arrays.asList(
+ metricsPublishingService("metricsPublishingService1"),
+ metricsPublishingService("metricsPublishingService2"),
+ metricsPublishingService("metricsPublishingService3"));
+
when(theMetricsPublishingServicesLoader.loadServices(MetricsPublishingService.class))
+ .thenReturn(theMetricsPublishingServices);
+
+ CacheLifecycleMetricsSession session = builder
+ .setServiceLoader(theMetricsPublishingServicesLoader)
+ .build(registry);
+
+ assertThat(session.metricsPublishingServices())
+ .hasSameElementsAs(theMetricsPublishingServices);
+ }
+
+ private MetricsPublishingService metricsPublishingService(String name) {
+ return mock(MetricsPublishingService.class, name);
+ }
+}
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSessionTest.java
b/geode-core/src/test/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSessionTest.java
new file mode 100644
index 0000000..4a9af35
--- /dev/null
+++
b/geode-core/src/test/java/org/apache/geode/internal/metrics/CacheLifecycleMetricsSessionTest.java
@@ -0,0 +1,220 @@
+/*
+ * 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.geode.internal.metrics;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
+import org.junit.After;
+import org.junit.Test;
+
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.InternalCache;
+import
org.apache.geode.internal.metrics.CacheLifecycleMetricsSession.CacheLifecycle;
+import org.apache.geode.metrics.MetricsPublishingService;
+
+public class CacheLifecycleMetricsSessionTest {
+
+ private final CompositeMeterRegistry compositeRegistry = new
CompositeMeterRegistry();
+
+ private CacheLifecycleMetricsSession metricsSession;
+
+ @After
+ public void tearDown() {
+ if (metricsSession != null) {
+ GemFireCacheImpl.removeCacheLifecycleListener(metricsSession);
+ }
+ }
+
+ @Test
+ public void startsWithNoDownstreamRegistries() {
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ Collections.emptyList());
+
+ Set<MeterRegistry> downstreamRegistries =
compositeRegistry.getRegistries();
+
+ assertThat(downstreamRegistries)
+ .isEmpty();
+ }
+
+ @Test
+ public void remembersConnectedDownstreamRegistries() {
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ Collections.emptyList());
+
+ MeterRegistry downstreamRegistry = new SimpleMeterRegistry();
+
+ metricsSession.addSubregistry(downstreamRegistry);
+
+ assertThat(compositeRegistry.getRegistries())
+ .contains(downstreamRegistry);
+ }
+
+ @Test
+ public void forgetsDisconnectedDownstreamRegistries() {
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ Collections.emptyList());
+
+ MeterRegistry downstreamRegistry = new SimpleMeterRegistry();
+ metricsSession.addSubregistry(downstreamRegistry);
+
+ metricsSession.removeSubregistry(downstreamRegistry);
+
+ assertThat(compositeRegistry.getRegistries())
+ .doesNotContain(downstreamRegistry);
+ }
+
+ @Test
+ public void connectsExistingMetersToNewDownstreamRegistries() {
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ Collections.emptyList());
+
+ String counterName = "the.counter";
+ Counter primaryCounter = compositeRegistry.counter(counterName);
+
+ double amountIncrementedBeforeConnectingDownstreamRegistry = 3.0;
+
primaryCounter.increment(amountIncrementedBeforeConnectingDownstreamRegistry);
+
+ MeterRegistry downstreamRegistry = new SimpleMeterRegistry();
+ metricsSession.addSubregistry(downstreamRegistry);
+
+ Counter downstreamCounter = downstreamRegistry.find(counterName).counter();
+ assertThat(downstreamCounter)
+ .as("downstream counter after connecting, before incrementing")
+ .isNotNull();
+
+ // Note that the newly-created downstream counter starts at zero, ignoring
+ // any increments that happened before the downstream registry was added.
+ assertThat(downstreamCounter.count())
+ .as("downstream counter value after connecting, before incrementing")
+ .isNotEqualTo(amountIncrementedBeforeConnectingDownstreamRegistry)
+ .isEqualTo(0);
+
+ double amountIncrementedAfterConnectingDownstreamRegistry = 42.0;
+
primaryCounter.increment(amountIncrementedAfterConnectingDownstreamRegistry);
+
+ assertThat(downstreamCounter.count())
+ .as("downstream counter value after incrementing")
+ .isEqualTo(amountIncrementedAfterConnectingDownstreamRegistry);
+ }
+
+ @Test
+ public void connectsNewMetersToExistingDownstreamRegistries() {
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ Collections.emptyList());
+
+ MeterRegistry downstreamRegistry = new SimpleMeterRegistry();
+ metricsSession.addSubregistry(downstreamRegistry);
+
+ String counterName = "the.counter";
+ Counter newCounter = compositeRegistry.counter(counterName);
+
+ Counter downstreamCounter = downstreamRegistry.find(counterName).counter();
+ assertThat(downstreamCounter)
+ .as("downstream counter before incrementing")
+ .isNotNull();
+
+ assertThat(downstreamCounter.count())
+ .as("downstream counter value before incrementing")
+ .isEqualTo(newCounter.count())
+ .isEqualTo(0);
+
+ double amountIncrementedAfterConnectingDownstreamRegistry = 93.0;
+ newCounter.increment(amountIncrementedAfterConnectingDownstreamRegistry);
+
+ assertThat(downstreamCounter.count())
+ .as("downstream counter value after incrementing")
+ .isEqualTo(newCounter.count());
+ }
+
+ @Test
+ public void cacheCreatedStartsEachMetricsPublishingService() {
+ List<MetricsPublishingService> metricsPublishingServices = Arrays.asList(
+ metricsPublishingService("metricsPublishingService1"),
+ metricsPublishingService("metricsPublishingService2"),
+ metricsPublishingService("metricsPublishingService3"));
+
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ metricsPublishingServices);
+
+ metricsSession.cacheCreated(mock(InternalCache.class));
+
+ for (MetricsPublishingService metricsPublishingService :
metricsPublishingServices) {
+ verify(metricsPublishingService).start(same(metricsSession));
+ }
+ }
+
+ @Test
+ public void cacheClosedStopsEachMetricsPublishingService() {
+ List<MetricsPublishingService> metricsPublishingServices = Arrays.asList(
+ metricsPublishingService("metricsPublishingService1"),
+ metricsPublishingService("metricsPublishingService2"),
+ metricsPublishingService("metricsPublishingService3"));
+
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ metricsPublishingServices);
+
+ metricsSession.cacheClosed(mock(InternalCache.class));
+
+ for (MetricsPublishingService metricsPublishingService :
metricsPublishingServices) {
+ verify(metricsPublishingService).stop();
+ }
+ }
+
+ @Test
+ public void cacheClosedDisconnectsAllDownstreamRegistries() {
+ metricsSession = new
CacheLifecycleMetricsSession(mock(CacheLifecycle.class), compositeRegistry,
+ Collections.emptyList());
+
+ MeterRegistry downstreamMeterRegistry1 = new SimpleMeterRegistry();
+ MeterRegistry downstreamMeterRegistry2 = new SimpleMeterRegistry();
+ MeterRegistry downstreamMeterRegistry3 = new SimpleMeterRegistry();
+
+ metricsSession.addSubregistry(downstreamMeterRegistry1);
+ metricsSession.addSubregistry(downstreamMeterRegistry2);
+ metricsSession.addSubregistry(downstreamMeterRegistry3);
+
+ metricsSession.cacheClosed(mock(InternalCache.class));
+
+ assertThat(compositeRegistry.getRegistries()).isEmpty();
+ }
+
+ @Test
+ public void cacheClosedRemovesSessionAsCacheLifecycleListener() {
+ CacheLifecycle theCacheLifecycle = mock(CacheLifecycle.class);
+ metricsSession =
+ new CacheLifecycleMetricsSession(theCacheLifecycle, compositeRegistry,
+ Collections.emptyList());
+
+ metricsSession.cacheClosed(mock(InternalCache.class));
+
+ verify(theCacheLifecycle).removeListener(same(metricsSession));
+ }
+
+ private MetricsPublishingService metricsPublishingService(String name) {
+ return mock(MetricsPublishingService.class, name);
+ }
+}
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/metrics/CompositeMeterRegistryFactoryTest.java
b/geode-core/src/test/java/org/apache/geode/internal/metrics/CompositeMeterRegistryFactoryTest.java
new file mode 100644
index 0000000..0a31db9
--- /dev/null
+++
b/geode-core/src/test/java/org/apache/geode/internal/metrics/CompositeMeterRegistryFactoryTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.geode.internal.metrics;
+
+import static
org.apache.geode.internal.metrics.CompositeMeterRegistryFactory.CLUSTER_ID_TAG;
+import static
org.apache.geode.internal.metrics.CompositeMeterRegistryFactory.HOST_NAME_TAG;
+import static
org.apache.geode.internal.metrics.CompositeMeterRegistryFactory.MEMBER_NAME_TAG;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.micrometer.core.instrument.Meter;
+import io.micrometer.core.instrument.Tag;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+import org.junit.Test;
+
+public class CompositeMeterRegistryFactoryTest {
+
+ private static final int CLUSTER_ID = 42;
+ private static final String MEMBER_NAME = "member-name";
+ private static final String HOST_NAME = "host-name";
+
+ @Test
+ public void createsCompositeMeterRegistry() {
+ CompositeMeterRegistryFactory factory = new
CompositeMeterRegistryFactory() {};
+
+ assertThat(factory.create(CLUSTER_ID, MEMBER_NAME, HOST_NAME))
+ .isInstanceOf(CompositeMeterRegistry.class);
+ }
+
+ @Test
+ public void addsMemberNameCommonTag() {
+ CompositeMeterRegistryFactory factory = new
CompositeMeterRegistryFactory() {};
+ String theMemberName = "the-member-name";
+
+ CompositeMeterRegistry registry = factory.create(CLUSTER_ID,
theMemberName, HOST_NAME);
+
+ Meter meter = registry.counter("my.meter");
+
+ assertThat(meter.getId().getTags())
+ .contains(Tag.of(MEMBER_NAME_TAG, theMemberName));
+ }
+
+ @Test
+ public void addsClusterIdCommonTag() {
+ CompositeMeterRegistryFactory factory = new
CompositeMeterRegistryFactory() {};
+ int theSystemId = 21;
+
+ CompositeMeterRegistry registry = factory.create(theSystemId, MEMBER_NAME,
HOST_NAME);
+
+ Meter meter = registry.counter("my.meter");
+
+ assertThat(meter.getId().getTags())
+ .contains(Tag.of(CLUSTER_ID_TAG, String.valueOf(theSystemId)));
+ }
+
+ @Test
+ public void addsHostNameCommonTag() {
+ CompositeMeterRegistryFactory factory = new
CompositeMeterRegistryFactory() {};
+ String theHostName = "the-host-name";
+
+ CompositeMeterRegistry registry = factory.create(CLUSTER_ID, MEMBER_NAME,
theHostName);
+
+ Meter meter = registry.counter("my.meter");
+
+ assertThat(meter.getId().getTags())
+ .contains(Tag.of(HOST_NAME_TAG, theHostName));
+ }
+}
diff --git a/geode-core/src/test/resources/expected-pom.xml
b/geode-core/src/test/resources/expected-pom.xml
index 3bbcc55..5df710a 100644
--- a/geode-core/src/test/resources/expected-pom.xml
+++ b/geode-core/src/test/resources/expected-pom.xml
@@ -142,6 +142,11 @@
<optional>true</optional>
</dependency>
<dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-core</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<scope>compile</scope>