Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vetoed-bean support to metrics CDI extension #2507

Merged
merged 10 commits into from
Nov 6, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static <A extends Annotation> List<LookupResult<A>> lookupAnnotations(
return result;
}

private static <A extends Annotation> List<LookupResult<A>> lookupAnnotations(Annotated annotated,
static <A extends Annotation> List<LookupResult<A>> lookupAnnotations(Annotated annotated,
Class<A> annotClass) {
// We have to filter by annotation class ourselves, because annotatedMethod.getAnnotations(Class) delegates
// to the Java method. That would bypass any annotations that had been added dynamically to the configurator.
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import io.helidon.metrics.RegistryFactory;
import io.helidon.microprofile.tests.junit5.AddConfig;
import io.helidon.microprofile.tests.junit5.HelidonTest;
import org.eclipse.microprofile.metrics.Metric;
import org.eclipse.microprofile.metrics.MetricFilter;
import org.eclipse.microprofile.metrics.MetricID;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.SimpleTimer;
import org.eclipse.microprofile.metrics.Tag;
Expand Down Expand Up @@ -97,6 +100,12 @@ void testSyntheticSimpleTimer(long expectedSyntheticSimpleTimerCount) {
SimpleTimer getSyntheticSimpleTimer() {
Tag[] tags = new Tag[] {new Tag("class", HelloWorldResource.class.getName()),
new Tag("method", "messageWithArg_java.lang.String")};
assertThat("Synthetic simple timer "
+ MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METRIC_NAME
+ " should appear in registry but does not",
syntheticSimpleTimerRegistry().getSimpleTimers((metricID, metric) ->
metricID.getName().equals(MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METRIC_NAME)).isEmpty(),
is(false));
SimpleTimer syntheticSimpleTimer = syntheticSimpleTimerRegistry().simpleTimer(
MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METADATA, tags);
return syntheticSimpleTimer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ MetricRegistry syntheticSimpleTimerRegistry() {
return baseRegistry;
}

MetricRegistry registry() {
return registry;
}

boolean isSyntheticSimpleTimerPresent() {
return !syntheticSimpleTimerRegistry().getSimpleTimers((metricID, metric) ->
metricID.equals(MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METRIC_NAME))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates.
*
* Licensed 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 io.helidon.microprofile.metrics;

import io.helidon.microprofile.tests.junit5.AddExtension;
import io.helidon.microprofile.tests.junit5.HelidonTest;
import org.eclipse.microprofile.metrics.MetricID;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import java.lang.reflect.Method;

@HelidonTest
@AddExtension(VetoCdiExtension.class)
public class TestVetoedResource extends MetricsMpServiceTest {

@Test
void testNoAnnotatedMetricForVetoedResource() throws NoSuchMethodException {
// The metrics CDI extension should ignore the vetoed resource's explicitly-annotated metrics.
MetricID vetoedID = new MetricID(VetoedResource.COUNTER_NAME);
assertThat("Metrics CDI extension incorrectly registered a metric on a vetoed resource",
registry().getCounters()
.containsKey(vetoedID), is(false));
}

@Test
void testNoSyntheticSimplyTimedMetricForVetoedResource() throws NoSuchMethodException {
// Makes sure that a vetoed JAX-RS resource with an explicit metric annotation was not registered with a synthetic
// SimplyTimed metric.
Method method = VetoedResource.class.getMethod("get");
assertThat(
"Metrics CDI extension incorrectly registered a synthetic simple timer on a vetoed resource JAX-RS endpoint "
+ "method with an explicit metrics annotation",
syntheticSimpleTimerRegistry()
.getSimpleTimers()
.containsKey(MetricsCdiExtension.syntheticSimpleTimerMetricID(method)),
is(false));
}

@Test
void testNoSyntheticSimplyTimedMetricForVetoedResourceWithJaxRsEndpointButOtherwiseUnmeasured() throws NoSuchMethodException {
// Makes sure that a vetoed JAX-RS resource with no explicit metric annotation was not registered with a synthetic
// SimpleTimed metric.
Method method = VetoedJaxRsButOtherwiseUnmeasuredResource.class.getMethod("get");
assertThat(
"Metrics CDI extension incorrectly registered a synthetic simple timer on JAX-RS endpoint method with no "
+ "explicit metrics annotation: "
+ VetoedJaxRsButOtherwiseUnmeasuredResource.class.getName() + "#" + method.getName(),
MetricsCdiExtension.getRegistryForSyntheticSimpleTimers()
.getSimpleTimers()
.containsKey(MetricsCdiExtension.syntheticSimpleTimerMetricID(method)),
is(false));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates.
*
* Licensed 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 io.helidon.microprofile.metrics;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.WithAnnotations;
import javax.ws.rs.Path;
import java.util.Set;

/**
* Vetoes selected resources which should suppress the registration of their annotation-defined metrics and
* implicitly-created synthetic simply timed metrics.
*/
public class VetoCdiExtension implements Extension {

private static final Set<Class<?>> VETOED_RESOURCE_CLASSES = Set.of(VetoedResource.class,
VetoedJaxRsButOtherwiseUnmeasuredResource.class);

private void vetoResourceClass(@Observes @WithAnnotations(Path.class) ProcessAnnotatedType<?> resourceType) {
Class<?> resourceClass = resourceType.getAnnotatedType().getJavaClass();
if (VETOED_RESOURCE_CLASSES.contains(resourceClass)) {
resourceType.veto();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates.
*
* Licensed 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 io.helidon.microprofile.metrics;

import javax.enterprise.context.RequestScoped;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

/**
* JAX-RS resource, vetoed by a test CDI extension, with no explicit metrics annotation.
*/
@Path("/vetoedOtherwiseUnmeasured")
@RequestScoped
public class VetoedJaxRsButOtherwiseUnmeasuredResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
public Response get() {
return Response.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates.
*
* Licensed 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 io.helidon.microprofile.metrics;

import org.eclipse.microprofile.metrics.annotation.Counted;

import javax.enterprise.context.RequestScoped;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

/**
* JAX-RS resource, vetoed by a test CDI extension, with an explicit metrics annotation.
*/
@Path("/vetoed")
@RequestScoped
public class VetoedResource {

static final String COUNTER_NAME = "vetoedCounter";

@Counted(name = COUNTER_NAME, absolute = true)
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response get() {
return Response.ok().build();
}
}