diff --git a/microprofile-telemetry-metrics/pom.xml b/microprofile-telemetry-metrics/pom.xml
index 7bcde4e0..9bd6c8c2 100644
--- a/microprofile-telemetry-metrics/pom.xml
+++ b/microprofile-telemetry-metrics/pom.xml
@@ -10,7 +10,7 @@
1.0.0.Final-SNAPSHOT
- microprofile-metrics
+ microprofile-telemetry-metrics
@@ -33,11 +33,57 @@
wildfly-arquillian-container-managed
test
+
+ jakarta.annotation
+ jakarta.annotation-api
+ provided
+
+
+ jakarta.enterprise
+ jakarta.enterprise.cdi-api
+ provided
+
+
+ jakarta.inject
+ jakarta.inject-api
+ provided
+
+
+ jakarta.json
+ jakarta.json-api
+ provided
+
jakarta.servlet
jakarta.servlet-api
provided
+
+ org.eclipse.microprofile.config
+ microprofile-config-api
+ provided
+
+
+ org.eclipse.microprofile.telemetry
+ microprofile-telemetry-api
+ pom
+ provided
+
+
+ jakarta.ws.rs
+ jakarta.ws.rs-api
+ provided
+
+
+ org.jboss.eap.qe
+ tooling-docker
+ test
+
+
+ org.jboss.eap.qe
+ tooling-observability
+ test
+
org.jboss.eap.qe
tooling-server-configuration
diff --git a/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingOneService.java b/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingOneService.java
index c79716cf..bc4f43cf 100644
--- a/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingOneService.java
+++ b/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingOneService.java
@@ -1,17 +1,34 @@
package org.jboss.eap.qe.microprofile.metrics.namefellow;
+import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
-import org.eclipse.microprofile.metrics.annotation.Counted;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.metrics.LongCounter;
+import io.opentelemetry.api.metrics.Meter;
@ApplicationScoped
public class PingOneService {
public static final String MESSAGE = "pong one";
public static final String PING_ONE_SERVICE_TAG = "ping-one-service-tag";
- @Counted(name = "ping-count", absolute = true, displayName = "Pong Count", description = "Number of ping invocations", tags = "_app="
- + PING_ONE_SERVICE_TAG)
+ @Inject
+ private Meter meter;
+ private LongCounter longCounter;
+
+ @PostConstruct
+ public void init() {
+ longCounter = meter
+ .counterBuilder("ping_count")
+ .setDescription("Number of ping invocations")
+ .build();
+ }
+
public String ping() {
+ longCounter.add(1, Attributes.of(
+ AttributeKey.stringKey("_app"), PING_ONE_SERVICE_TAG));
return MESSAGE;
}
}
diff --git a/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingTwoService.java b/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingTwoService.java
index 5d0ad901..00db4d6c 100644
--- a/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingTwoService.java
+++ b/microprofile-telemetry-metrics/src/main/java/org/jboss/eap/qe/microprofile/metrics/namefellow/PingTwoService.java
@@ -1,17 +1,34 @@
package org.jboss.eap.qe.microprofile.metrics.namefellow;
+import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
-import org.eclipse.microprofile.metrics.annotation.Counted;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.metrics.LongCounter;
+import io.opentelemetry.api.metrics.Meter;
@ApplicationScoped
public class PingTwoService {
public static final String MESSAGE = "pong two";
public static final String PING_TWO_SERVICE_TAG = "ping-two-service-tag";
- @Counted(name = "ping-count", absolute = true, displayName = "Pong Count", description = "Number of ping invocations", tags = "_app="
- + PING_TWO_SERVICE_TAG)
+ @Inject
+ private Meter meter;
+ private LongCounter longCounter;
+
+ @PostConstruct
+ public void init() {
+ longCounter = meter
+ .counterBuilder("ping_count")
+ .setDescription("Number of ping invocations")
+ .build();
+ }
+
public String ping() {
+ longCounter.add(1, Attributes.of(
+ AttributeKey.stringKey("_app"), PING_TWO_SERVICE_TAG));
return MESSAGE;
}
}
diff --git a/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/MPTelemetryServerSetupTask.java b/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/MPTelemetryServerSetupTask.java
new file mode 100644
index 00000000..689f9801
--- /dev/null
+++ b/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/MPTelemetryServerSetupTask.java
@@ -0,0 +1,50 @@
+package org.jboss.eap.qe.microprofile.metrics;
+
+import org.jboss.as.arquillian.api.ServerSetupTask;
+import org.jboss.as.arquillian.container.ManagementClient;
+import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileTelemetryServerConfiguration;
+import org.jboss.eap.qe.microprofile.common.setuptasks.MicrometerServerConfiguration;
+import org.jboss.eap.qe.observability.containers.OpenTelemetryCollectorContainer;
+import org.jboss.eap.qe.ts.common.docker.Docker;
+
+/**
+ * Server setup task for configuration of MicroProfile Telemetry and otel collector
+ */
+public class MPTelemetryServerSetupTask implements ServerSetupTask {
+
+ private static OpenTelemetryCollectorContainer otelCollector;
+
+ /**
+ * Start otel collector in container and configure OpenTelemetry and MP Telemetry in application server
+ */
+ @Override
+ public void setup(ManagementClient managementClient, String containerId) throws Exception {
+ // we need a Docker container for The OTel collector here, so throw an exception if a docker service is not available
+ try {
+ Docker.checkDockerPresent();
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot verify Docker availability: " + e.getMessage());
+ }
+ // disable micrometer
+ MicrometerServerConfiguration.disableMicrometer();
+ // start the OTel collector container
+ otelCollector = OpenTelemetryCollectorContainer.getInstance();
+ otelCollector.start();
+ // Enable MP Telemetry based metrics, which rely on OpenTelemetry subsystem
+ MicroProfileTelemetryServerConfiguration.enableOpenTelemetry();
+ MicroProfileTelemetryServerConfiguration.addOpenTelemetryCollectorConfiguration(otelCollector.getOtlpGrpcEndpoint());
+ MicroProfileTelemetryServerConfiguration.enableMicroProfileTelemetry();
+ }
+
+ /**
+ * Stop otel collector in container and disable OpenTelemetry and MP Telemetry in application server
+ */
+ @Override
+ public void tearDown(ManagementClient managementClient, String containerId) throws Exception {
+ // disable MP Telemetry based metrics
+ MicroProfileTelemetryServerConfiguration.disableMicroProfileTelemetry();
+ MicroProfileTelemetryServerConfiguration.disableOpenTelemetry();
+ // stop the OTel collector container
+ otelCollector.stop();
+ }
+}
diff --git a/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/namefellow/MultipleDeploymentsMetricsTest.java b/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/namefellow/MultipleDeploymentsMetricsTest.java
index 82444104..714743e7 100644
--- a/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/namefellow/MultipleDeploymentsMetricsTest.java
+++ b/microprofile-telemetry-metrics/src/test/java/org/jboss/eap/qe/microprofile/metrics/namefellow/MultipleDeploymentsMetricsTest.java
@@ -1,152 +1,110 @@
package org.jboss.eap.qe.microprofile.metrics.namefellow;
import static io.restassured.RestAssured.get;
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasKey;
-import static org.hamcrest.Matchers.hasSize;
import java.net.URL;
+import java.util.List;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.eap.qe.microprofile.tooling.server.configuration.ConfigurationException;
-import org.jboss.eap.qe.microprofile.tooling.server.configuration.arquillian.ArquillianContainerProperties;
-import org.jboss.eap.qe.microprofile.tooling.server.configuration.arquillian.ArquillianDescriptorWrapper;
+import org.jboss.as.arquillian.api.ServerSetup;
+import org.jboss.eap.qe.microprofile.metrics.MPTelemetryServerSetupTask;
+import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
+import org.jboss.eap.qe.observability.containers.OpenTelemetryCollectorContainer;
+import org.jboss.eap.qe.observability.prometheus.model.PrometheusMetric;
+import org.jboss.eap.qe.ts.common.docker.junit.DockerRequiredTests;
import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.BeforeClass;
+import org.junit.Assert;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
-import io.restassured.http.ContentType;
-import io.restassured.specification.RequestSpecification;
-
/**
* Multiple deployment scenario.
*/
@RunWith(Arquillian.class)
+@Category(DockerRequiredTests.class)
+@ServerSetup(MPTelemetryServerSetupTask.class)
public class MultipleDeploymentsMetricsTest {
public static final String PING_ONE_SERVICE = "ping-one-service";
public static final String PING_TWO_SERVICE = "ping-two-service";
+ private static final String DEFAULT_MP_CONFIG = "otel.sdk.disabled=false\n" +
+ "otel.metric.export.interval=100";
@Deployment(name = PING_ONE_SERVICE, order = 1)
public static WebArchive createDeployment1() {
+ String mpConfig = "otel.service.name=MultipleDeploymentsMetricsTest-first-deployment\n" + DEFAULT_MP_CONFIG;
return ShrinkWrap.create(WebArchive.class, PING_ONE_SERVICE + ".war")
- .addClasses(PingApplication.class, PingOneService.class, PingOneResource.class);
+ .addClasses(PingApplication.class, PingOneService.class, PingOneResource.class)
+ .addAsManifestResource(ConfigurationUtil.BEANS_XML_FILE_LOCATION, "beans.xml")
+ .addAsManifestResource(new StringAsset(mpConfig), "microprofile-config.properties");
}
@Deployment(name = PING_TWO_SERVICE, order = 2)
public static WebArchive createDeployment2() {
+ String mpConfig = "otel.service.name=MultipleDeploymentsMetricsTest-second-deployment\n" + DEFAULT_MP_CONFIG;
return ShrinkWrap.create(WebArchive.class, PING_TWO_SERVICE + ".war")
- .addClasses(PingApplication.class, PingTwoService.class, PingTwoResource.class);
- }
-
- private static RequestSpecification jsonMetricsRequest;
- private static RequestSpecification textMetricsRequest;
-
- @BeforeClass
- public static void prepare() throws ConfigurationException {
- ArquillianContainerProperties arqProps = new ArquillianContainerProperties(
- ArquillianDescriptorWrapper.getArquillianDescriptor());
- String url = "http://" + arqProps.getDefaultManagementAddress() + ":" + arqProps.getDefaultManagementPort()
- + "/metrics";
- jsonMetricsRequest = given()
- .baseUri(url)
- .accept(ContentType.JSON);
- textMetricsRequest = given()
- .baseUri(url)
- .accept(ContentType.TEXT);
- }
-
- /**
- * @tpTestDetails High level scenario to verify two none-reusable counter metrics of the same name are registered
- * and tagged properly. The information is available under {@code /metrics} endpoint via HTTP OPTIONS.
- * Metrics are in separate archives - multiple-deployment.
- * @tpPassCrit Metrics are tagged properly
- * @tpSince EAP 7.4.0.CD19
- */
- @Test
- @RunAsClient
- public void applicationMetricsAreRegisteredAtDeploymentTime() {
- jsonMetricsRequest.options().then()
- .contentType(ContentType.JSON)
- .header("Content-Type", containsString("application/json"))
- .body("$", hasKey("application"),
- "application", hasKey("ping-count"),
- "application.ping-count", hasKey("tags"), // 11 at `/` + 1 at `/another-hello`
- "application.ping-count.tags", hasSize(2),
- "application.ping-count.tags[0]", hasSize(1),
- "application.ping-count.tags[1]", hasSize(1),
- "application.ping-count.tags.flatten()",
- contains("_app=" + PingOneService.PING_ONE_SERVICE_TAG, "_app=" + PingTwoService.PING_TWO_SERVICE_TAG));
+ .addClasses(PingApplication.class, PingTwoService.class, PingTwoResource.class)
+ .addAsManifestResource(ConfigurationUtil.BEANS_XML_FILE_LOCATION, "beans.xml")
+ .addAsManifestResource(new StringAsset(mpConfig), "microprofile-config.properties");
}
/**
* @tpTestDetails High level scenario to verify two none-reusable counter metrics of the same name are incremented
* properly according to the number of a CDI beans invocation.
* Metrics are in separate archives - multiple-deployment.
- * @tpPassCrit Counters have correct values (according to number of the CDI bean invocations) in JSON and prometheus format.
+ * @tpPassCrit Counters have correct values (according to number of the CDI bean invocations) in Jprometheus format.
* @tpSince EAP 7.4.0.CD19
*/
@Test
@RunAsClient
public void dataTest(@ArquillianResource @OperateOnDeployment(PING_ONE_SERVICE) URL pingOneUrl,
- @ArquillianResource @OperateOnDeployment(PING_TWO_SERVICE) URL pingTwoUrl) {
-
+ @ArquillianResource @OperateOnDeployment(PING_TWO_SERVICE) URL pingTwoUrl) throws Exception {
+ // increase metrics counters
get(pingOneUrl.toString() + PingOneResource.RESOURCE)
.then()
.statusCode(200)
.body(equalTo(PingOneService.MESSAGE));
-
get(pingTwoUrl.toString() + PingTwoResource.RESOURCE)
.then()
.statusCode(200)
.body(equalTo(PingTwoService.MESSAGE));
-
- get(pingTwoUrl.toString() + PingTwoResource.RESOURCE).then().statusCode(200);
- get(pingTwoUrl.toString() + PingTwoResource.RESOURCE).then().statusCode(200);
- get(pingTwoUrl.toString() + PingTwoResource.RESOURCE).then().statusCode(200);
-
- get(pingOneUrl.toString() + PingOneResource.RESOURCE).then().statusCode(200);
-
- jsonDataTest();
- prometheusDataTest();
- }
-
- /**
- * Verify correct data of counters in JSON format. ping one: 2, ping-two: 4
- */
- private void jsonDataTest() {
- jsonMetricsRequest.get().then()
- .contentType(ContentType.JSON)
- .header("Content-Type", containsString("application/json"))
- .body("$", hasKey("application"),
- "application", hasKey("ping-count;_app=" + PingOneService.PING_ONE_SERVICE_TAG),
- "application.ping-count;_app=" + PingOneService.PING_ONE_SERVICE_TAG, equalTo(2),
-
- "application", hasKey("ping-count;_app=" + PingTwoService.PING_TWO_SERVICE_TAG),
- "application.ping-count;_app=" + PingTwoService.PING_TWO_SERVICE_TAG, equalTo(4));
- }
-
- /**
- * Verify correct data of counters in prometheus format. ping one: 2, ping-two: 4
- */
- private void prometheusDataTest() {
- textMetricsRequest.get().then()
- .contentType(ContentType.TEXT)
- .header("Content-Type", containsString("text/plain"))
- .body(
- containsString(
- "application_ping_count_total{_app=\"" + PingTwoService.PING_TWO_SERVICE_TAG + "\"} 4.0"),
- containsString(
- "application_ping_count_total{_app=\"" + PingOneService.PING_ONE_SERVICE_TAG + "\"} 2.0"));
+ get(pingTwoUrl + PingTwoResource.RESOURCE).then().statusCode(200);
+ get(pingTwoUrl + PingTwoResource.RESOURCE).then().statusCode(200);
+ get(pingTwoUrl + PingTwoResource.RESOURCE).then().statusCode(200);
+ get(pingOneUrl + PingOneResource.RESOURCE).then().statusCode(200);
+
+ // give it some time to actually be able and report some metrics via the Pmetheus URL
+ Thread.sleep(1_000);
+
+ // get metrics
+ List metrics = OpenTelemetryCollectorContainer.getInstance().fetchMetrics("");
+
+ // verify metrics
+ Assert.assertTrue("\"ping_count\" metric for deployment one not found or not expected",
+ metrics.stream()
+ .filter(m -> "ping_count_total".equals(m.getKey()))
+ .filter(m -> m.getTags().entrySet().stream().anyMatch(
+ t -> "key_app".equals(t.getKey())
+ && "ping-one-service-tag"
+ .equals(t.getValue())))
+ .anyMatch(m -> "2".equals(m.getValue())));
+
+ Assert.assertTrue("\"ping_count\" metric for deployment two not found or not expected",
+ metrics.stream()
+ .filter(m -> "ping_count_total".equals(m.getKey()))
+ .filter(m -> m.getTags().entrySet().stream().anyMatch(
+ t -> "key_app".equals(t.getKey())
+ && "ping-two-service-tag"
+ .equals(t.getValue())))
+ .anyMatch(m -> "4".equals(m.getValue())));
}
}
diff --git a/microprofile-telemetry-metrics/src/test/resources/arquillian-bootable.xml b/microprofile-telemetry-metrics/src/test/resources/arquillian-bootable.xml
index c7de7366..870292ea 100644
--- a/microprofile-telemetry-metrics/src/test/resources/arquillian-bootable.xml
+++ b/microprofile-telemetry-metrics/src/test/resources/arquillian-bootable.xml
@@ -17,4 +17,4 @@
-
\ No newline at end of file
+
diff --git a/microprofile-fault-tolerance/src/test/resources/otel-collector-config.yaml b/tooling-observability/src/main/resources/otel-collector-config.yaml
similarity index 100%
rename from microprofile-fault-tolerance/src/test/resources/otel-collector-config.yaml
rename to tooling-observability/src/main/resources/otel-collector-config.yaml