| /* |
| * 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 static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPorts; |
| import static org.apache.geode.test.compiler.ClassBuilder.writeJarFromClasses; |
| import static org.assertj.core.api.Assertions.assertThat; |
| |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import java.util.List; |
| |
| import io.micrometer.core.instrument.Meter; |
| import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; |
| import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; |
| import io.micrometer.core.instrument.binder.system.ProcessorMetrics; |
| import io.micrometer.core.instrument.binder.system.UptimeMetrics; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| |
| import org.apache.geode.cache.client.ClientCache; |
| import org.apache.geode.cache.client.ClientCacheFactory; |
| import org.apache.geode.cache.client.Pool; |
| import org.apache.geode.cache.client.PoolManager; |
| import org.apache.geode.cache.execute.Execution; |
| import org.apache.geode.cache.execute.Function; |
| import org.apache.geode.cache.execute.FunctionContext; |
| import org.apache.geode.cache.execute.FunctionService; |
| import org.apache.geode.rules.ServiceJarRule; |
| import org.apache.geode.test.junit.rules.gfsh.GfshRule; |
| |
| public class MicrometerBinderTest { |
| |
| private Path serverFolder; |
| private ClientCache clientCache; |
| private Pool serverPool; |
| private Execution<String, Boolean, List<Boolean>> functionExecution; |
| |
| @Rule |
| public TemporaryFolder temporaryFolder = new TemporaryFolder(); |
| |
| @Rule |
| public GfshRule gfshRule = new GfshRule(); |
| |
| @Rule |
| public ServiceJarRule serviceJarRule = new ServiceJarRule(); |
| |
| @Before |
| public void startServer() throws IOException { |
| serverFolder = temporaryFolder.getRoot().toPath().toAbsolutePath(); |
| |
| int[] ports = getRandomAvailableTCPPorts(2); |
| |
| int serverPort = ports[0]; |
| int jmxRmiPort = ports[1]; |
| |
| Path serviceJarPath = serviceJarRule.createJarFor("metrics-publishing-service.jar", |
| MetricsPublishingService.class, SimpleMetricsPublishingService.class); |
| |
| String startServerCommand = String.join(" ", |
| "start server", |
| "--name=server", |
| "--dir=" + serverFolder, |
| "--server-port=" + serverPort, |
| "--classpath=" + serviceJarPath, |
| "--http-service-port=0", |
| "--J=-Dgemfire.enable-cluster-config=true", |
| "--J=-Dgemfire.jmx-manager=true", |
| "--J=-Dgemfire.jmx-manager-start=true", |
| "--J=-Dgemfire.jmx-manager-port=" + jmxRmiPort); |
| |
| gfshRule.execute(startServerCommand); |
| |
| Path functionJarPath = serverFolder.resolve("function.jar").toAbsolutePath(); |
| writeJarFromClasses(functionJarPath.toFile(), CheckIfMeterExistsFunction.class); |
| |
| String connectCommand = "connect --jmx-manager=localhost[" + jmxRmiPort + "]"; |
| String deployCommand = "deploy --jar=" + functionJarPath.toAbsolutePath(); |
| |
| gfshRule.execute(connectCommand, deployCommand); |
| |
| clientCache = new ClientCacheFactory().addPoolServer("localhost", serverPort).create(); |
| |
| serverPool = PoolManager.createFactory() |
| .addServer("localhost", serverPort) |
| .create("server-pool"); |
| |
| @SuppressWarnings("unchecked") |
| Execution<String, Boolean, List<Boolean>> functionExecution = |
| (Execution<String, Boolean, List<Boolean>>) FunctionService.onServer(serverPool); |
| this.functionExecution = functionExecution; |
| } |
| |
| @After |
| public void stopServer() { |
| clientCache.close(); |
| serverPool.destroy(); |
| |
| String stopServerCommand = "stop server --dir=" + serverFolder; |
| gfshRule.execute(stopServerCommand); |
| } |
| |
| @Test |
| public void jvmMemoryMetricsBinderExists() { |
| String meterNameToCheck = "jvm.memory.used"; |
| |
| List<Boolean> results = functionExecution |
| .setArguments(meterNameToCheck) |
| .execute(CheckIfMeterExistsFunction.ID) |
| .getResult(); |
| |
| assertThat(results) |
| .as("Meter from %s binder should exist", JvmMemoryMetrics.class.getSimpleName()) |
| .containsOnly(true); |
| } |
| |
| @Test |
| public void jvmThreadMetricsBinderExists() { |
| String meterNameToCheck = "jvm.threads.peak"; |
| |
| List<Boolean> results = functionExecution |
| .setArguments(meterNameToCheck) |
| .execute(CheckIfMeterExistsFunction.ID) |
| .getResult(); |
| |
| assertThat(results) |
| .as("Meter from %s binder should exist", JvmThreadMetrics.class.getSimpleName()) |
| .containsOnly(true); |
| } |
| |
| @Test |
| public void processorMetricsBinderExists() { |
| String meterNameToCheck = "system.cpu.count"; |
| |
| List<Boolean> results = functionExecution |
| .setArguments(meterNameToCheck) |
| .execute(CheckIfMeterExistsFunction.ID) |
| .getResult(); |
| |
| assertThat(results) |
| .as("Meter from %s binder should exist", ProcessorMetrics.class.getSimpleName()) |
| .containsOnly(true); |
| } |
| |
| @Test |
| public void uptimeMetricsBinderExists() { |
| String meterNameToCheck = "process.uptime"; |
| |
| List<Boolean> results = functionExecution |
| .setArguments(meterNameToCheck) |
| .execute(CheckIfMeterExistsFunction.ID) |
| .getResult(); |
| |
| assertThat(results) |
| .as("Meter from %s binder should exist", UptimeMetrics.class.getSimpleName()) |
| .containsOnly(true); |
| } |
| |
| public static class CheckIfMeterExistsFunction implements Function<String> { |
| private static final String ID = "CheckIfMeterExistsFunction"; |
| |
| @Override |
| public void execute(FunctionContext<String> context) { |
| String meterName = context.getArguments(); |
| |
| Meter meter = SimpleMetricsPublishingService.getRegistry() |
| .find(meterName) |
| .meter(); |
| |
| boolean isMeterFound = meter != null; |
| |
| context.<Boolean>getResultSender().lastResult(isMeterFound); |
| } |
| |
| @Override |
| public String getId() { |
| return ID; |
| } |
| } |
| } |