Skip to content

Commit

Permalink
first try
Browse files Browse the repository at this point in the history
  • Loading branch information
aureamunoz committed Sep 14, 2023
1 parent 3dce2bd commit 62da5bf
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 4 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<smallrye-reactive-types-converter.version>3.0.1</smallrye-reactive-types-converter.version>
<smallrye-mutiny-vertx-binding.version>3.6.0</smallrye-mutiny-vertx-binding.version>
<smallrye-reactive-messaging.version>4.9.0</smallrye-reactive-messaging.version>
<smallrye-stork.version>2.3.1</smallrye-stork.version>
<smallrye-stork.version>2.4.0-SNAPSHOT</smallrye-stork.version>
<jakarta.activation.version>2.1.2</jakarta.activation.version>
<jakarta.annotation-api.version>2.1.1</jakarta.annotation-api.version>
<jakarta.authentication-api>3.0.0</jakarta.authentication-api>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.quarkus.micrometer.deployment.binder;

import java.util.function.BooleanSupplier;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.micrometer.runtime.MicrometerRecorder;
import io.quarkus.micrometer.runtime.config.MicrometerConfig;

public class StorkBinderProcessor {

static final String OBSERVABLE_CLIENT = "io.smallrye.stork.api.Service";
static final String METRICS_BEAN_CLASS = "io.quarkus.micrometer.runtime.binder.stork.StorkObservationCollectorBean";

static final Class<?> OBSERVABLE_CLIENT_CLASS = MicrometerRecorder.getClassForName(OBSERVABLE_CLIENT);

static class StorkMetricsSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;

public boolean getAsBoolean() {
return OBSERVABLE_CLIENT_CLASS != null && mConfig.checkBinderEnabledWithDefault(mConfig.binder.stork);
}
}

@BuildStep(onlyIf = StorkMetricsSupportEnabled.class)
AdditionalBeanBuildItem addRedisClientMetric() {
return AdditionalBeanBuildItem.unremovableOf(METRICS_BEAN_CLASS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkus.micrometer.deployment.binder;

import static org.junit.jupiter.api.Assertions.assertTrue;

import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.smallrye.stork.api.Service;

public class StorkMetricsDisabledTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withConfigurationResource("test-logging.properties")
.overrideConfigKey("quarkus.micrometer.binder.stork.enabled", "false")
.overrideConfigKey("quarkus.micrometer.binder-enabled-default", "false")
.overrideConfigKey("quarkus.micrometer.registry-enabled-default", "false")
.withEmptyApplication();

@Inject
Instance<Service> bean;

@Test
void testNoInstancePresentIfNoRedisClientsClass() {
assertTrue(bean.isUnsatisfied(),
"No redis metrics bean");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

package io.quarkus.micrometer.deployment.binder;

import jakarta.inject.Inject;

import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.micrometer.core.instrument.MeterRegistry;
import io.quarkus.test.QuarkusUnitTest;

@DisabledOnOs(OS.WINDOWS)
public class StorkMetricsTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest();

@Inject
MeterRegistry registry;

}
12 changes: 12 additions & 0 deletions extensions/micrometer/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-redis-client</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-stork</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.quarkus.resteasy.reactive</groupId>
<artifactId>resteasy-reactive-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.quarkus.micrometer.runtime.binder.stork;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Typed;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.smallrye.stork.api.ServiceInstance;
import io.smallrye.stork.api.observability.ObservationCollector;
import io.smallrye.stork.api.observability.ObservationPoints;

@ApplicationScoped
@Typed(ObservationCollector.class)
public class StorkObservationCollectorBean implements ObservationCollector {

final MeterRegistry registry = Metrics.globalRegistry;

private final EventCompletionHandler STORK_HANDLER = ev -> {
//TODO
};
public static ObservationPoints.StorkResolutionEvent STORK_METRICS;

@Override
public ObservationPoints.StorkResolutionEvent create(String serviceName, String serviceDiscoveryType,
String serviceSelectionType) {
STORK_METRICS = new ObservationPoints.StorkResolutionEvent(serviceName, serviceDiscoveryType, serviceSelectionType,
STORK_HANDLER) {

private final Tags tags = Tags.of(Tag.of("client-name", getServiceName()));;
private final Counter instanceCounter = Counter.builder("stork.instances.count")
.description("The number of service instances discovered")
.tags(tags)
.register(registry);;
private String name = serviceName;

private volatile long endOfServiceDiscovery;

private final Timer timer = Timer.builder("stork.service-discovery.duration")
.description("The duration of the operations (commands of batches")
.tags(tags)
.register(registry);

@Override
public void onServiceDiscoverySuccess(List<ServiceInstance> instances) {
this.endOfServiceDiscovery = System.nanoTime();
if (instances != null) {
instanceCounter.increment(instances.size());
}

}

@Override
public void onServiceDiscoveryFailure(Throwable throwable) {
// Noop
}

@Override
public void onServiceSelectionSuccess(long id) {
// Noop
}

@Override
public void onServiceSelectionFailure(Throwable throwable) {
// Noop
}

};
return STORK_METRICS;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public static class BinderConfig {
public KafkaConfigGroup kafka;

public RedisConfigGroup redis;
public StorkConfigGroup stork;

public GrpcServerConfigGroup grpcServer;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkus.micrometer.runtime.config;

import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;

@ConfigGroup
public class StorkConfigGroup implements MicrometerConfig.CapabilityEnabled {
/**
* Stork metrics support.
* <p>
* Support for Stork metrics will be enabled if Micrometer support is enabled,
* the Quarkus Stork extension is on the classpath
* and either this value is true, or this value is unset and
* {@code quarkus.micrometer.binder-enabled-default} is true.
*/
@ConfigItem
public Optional<Boolean> enabled;

@Override
public Optional<Boolean> getEnabled() {
return enabled;
}

@Override
public String toString() {
return this.getClass().getSimpleName()
+ "{enabled=" + enabled
+ '}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

import java.util.List;

import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.spi.CDI;

import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import io.smallrye.stork.Stork;
import io.smallrye.stork.api.config.ServiceConfig;
import io.smallrye.stork.api.observability.ObservationCollector;
import io.smallrye.stork.integration.ObservableStorkInfrastructure;
import io.vertx.core.Vertx;

@Recorder
Expand All @@ -15,7 +20,13 @@ public class SmallRyeStorkRecorder {
public void initialize(ShutdownContext shutdown, RuntimeValue<Vertx> vertx, StorkConfiguration configuration) {
List<ServiceConfig> serviceConfigs = StorkConfigUtil.toStorkServiceConfig(configuration);
StorkConfigProvider.init(serviceConfigs);
Stork.initialize(new QuarkusStorkInfrastructure(vertx.getValue()));
Instance<ObservationCollector> instance = CDI.current().select(ObservationCollector.class);
if (instance.isResolvable()) {
Stork.initialize(new ObservableStorkInfrastructure(instance.get()));
} else {
Stork.initialize(new QuarkusStorkInfrastructure(vertx.getValue()));
}

shutdown.addShutdownTask(new Runnable() {
@Override
public void run() {
Expand Down
2 changes: 1 addition & 1 deletion independent-projects/resteasy-reactive/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<rest-assured.version>5.3.0</rest-assured.version>
<commons-logging-jboss-logging.version>1.0.0.Final</commons-logging-jboss-logging.version>
<jackson-bom.version>2.15.2</jackson-bom.version>
<smallrye-stork.version>2.3.1</smallrye-stork.version>
<smallrye-stork.version>2.4.0-SNAPSHOT</smallrye-stork.version>
<jakarta.validation-api.version>3.0.2</jakarta.validation-api.version>
<yasson.version>3.0.3</yasson.version>
<jakarta.json.bind-api.version>3.0.0</jakarta.json.bind-api.version>
Expand Down
13 changes: 13 additions & 0 deletions integration-tests/rest-client-reactive-stork/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-registry-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ hello/mp-rest/url=stork://hello-service/hello
# slow-service and fast-service come from Slow- and FastWiremockServer
quarkus.stork.hello-service.service-discovery.address-list=${slow-service},${fast-service}
quarkus.stork.hello-service.service-discovery.secure=true
quarkus.tls.trust-all=true
quarkus.tls.trust-all=true

quarkus.micrometer.binder.stork.enabled=true
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

import io.quarkus.arc.Arc;
import io.quarkus.it.rest.client.reactive.stork.MyServiceDiscoveryProvider;
import io.quarkus.micrometer.runtime.binder.stork.StorkObservationCollectorBean;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.DisabledOnIntegrationTest;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.response.Response;
import io.smallrye.stork.api.observability.ObservationPoints;
import io.vertx.core.Vertx;

@QuarkusTest
Expand Down Expand Up @@ -54,4 +56,29 @@ void shouldUseFasterService() {
// after hitting the slow endpoint, we should only use the fast one:
assertThat(responses).containsOnly(FAST_RESPONSE, FAST_RESPONSE, FAST_RESPONSE);
}

@Test
void shouldGetStorkMetrics() {
Set<String> responses = new HashSet<>();

for (int i = 0; i < 2; i++) {
Response response = when().get("/client");
response.then().statusCode(200);
responses.add(response.asString());
}

assertThat(responses).contains(FAST_RESPONSE, SLOW_RESPONSE);

ObservationPoints.StorkResolutionEvent metrics = StorkObservationCollectorBean.STORK_METRICS;
assertThat(metrics.getDiscoveredInstancesCount()).isEqualTo(2);
assertThat(metrics.getServiceName()).isEqualTo("hello-service");
assertThat(metrics.isDone()).isTrue();
assertThat(metrics.failure()).isNull();
assertThat(metrics.getOverallDuration()).isNotNull();
assertThat(metrics.getServiceDiscoveryType()).isEqualTo("my");
assertThat(metrics.getServiceSelectionType()).isEqualTo("least-response-time");
assertThat(metrics.getServiceDiscoveryDuration()).isNotNull();
assertThat(metrics.getServiceSelectionDuration()).isNotNull();

}
}

0 comments on commit 62da5bf

Please sign in to comment.