Skip to content

Commit e7dd2c1

Browse files
authored
Add vetoed-bean support to metrics CDI extension (helidon-io#2507)
* Use ProcessManagedBean instead of ProcessAnnotatedType to actually define metrics Signed-off-by: tim.quinn@oracle.com <tim.quinn@oracle.com>
1 parent 22ff1b3 commit e7dd2c1

8 files changed

Lines changed: 440 additions & 148 deletions

File tree

microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/MetricUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static <A extends Annotation> List<LookupResult<A>> lookupAnnotations(
107107
return result;
108108
}
109109

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

microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/MetricsCdiExtension.java

Lines changed: 234 additions & 147 deletions
Large diffs are not rendered by default.

microprofile/metrics/src/test/java/io/helidon/microprofile/metrics/HelloWorldTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import io.helidon.metrics.RegistryFactory;
2828
import io.helidon.microprofile.tests.junit5.AddConfig;
2929
import io.helidon.microprofile.tests.junit5.HelidonTest;
30+
import org.eclipse.microprofile.metrics.Metric;
31+
import org.eclipse.microprofile.metrics.MetricFilter;
32+
import org.eclipse.microprofile.metrics.MetricID;
3033
import org.eclipse.microprofile.metrics.MetricRegistry;
3134
import org.eclipse.microprofile.metrics.SimpleTimer;
3235
import org.eclipse.microprofile.metrics.Tag;
@@ -97,6 +100,12 @@ void testSyntheticSimpleTimer(long expectedSyntheticSimpleTimerCount) {
97100
SimpleTimer getSyntheticSimpleTimer() {
98101
Tag[] tags = new Tag[] {new Tag("class", HelloWorldResource.class.getName()),
99102
new Tag("method", "messageWithArg_java.lang.String")};
103+
assertThat("Synthetic simple timer "
104+
+ MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METRIC_NAME
105+
+ " should appear in registry but does not",
106+
syntheticSimpleTimerRegistry().getSimpleTimers((metricID, metric) ->
107+
metricID.getName().equals(MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METRIC_NAME)).isEmpty(),
108+
is(false));
100109
SimpleTimer syntheticSimpleTimer = syntheticSimpleTimerRegistry().simpleTimer(
101110
MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METADATA, tags);
102111
return syntheticSimpleTimer;

microprofile/metrics/src/test/java/io/helidon/microprofile/metrics/MetricsMpServiceTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ MetricRegistry syntheticSimpleTimerRegistry() {
4646
return baseRegistry;
4747
}
4848

49+
MetricRegistry registry() {
50+
return registry;
51+
}
52+
4953
boolean isSyntheticSimpleTimerPresent() {
5054
return !syntheticSimpleTimerRegistry().getSimpleTimers((metricID, metric) ->
5155
metricID.equals(MetricsCdiExtension.SYNTHETIC_SIMPLE_TIMER_METRIC_NAME))
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
package io.helidon.microprofile.metrics;
18+
19+
import io.helidon.microprofile.tests.junit5.AddExtension;
20+
import io.helidon.microprofile.tests.junit5.HelidonTest;
21+
import org.eclipse.microprofile.metrics.MetricID;
22+
import org.junit.jupiter.api.Test;
23+
24+
import static org.hamcrest.MatcherAssert.assertThat;
25+
import static org.hamcrest.Matchers.is;
26+
27+
import java.lang.reflect.Method;
28+
29+
@HelidonTest
30+
@AddExtension(VetoCdiExtension.class)
31+
public class TestVetoedResource extends MetricsMpServiceTest {
32+
33+
@Test
34+
void testNoAnnotatedMetricForVetoedResource() throws NoSuchMethodException {
35+
// The metrics CDI extension should ignore the vetoed resource's explicitly-annotated metrics.
36+
MetricID vetoedID = new MetricID(VetoedResource.COUNTER_NAME);
37+
assertThat("Metrics CDI extension incorrectly registered a metric on a vetoed resource",
38+
registry().getCounters()
39+
.containsKey(vetoedID), is(false));
40+
}
41+
42+
@Test
43+
void testNoSyntheticSimplyTimedMetricForVetoedResource() throws NoSuchMethodException {
44+
// Makes sure that a vetoed JAX-RS resource with an explicit metric annotation was not registered with a synthetic
45+
// SimplyTimed metric.
46+
Method method = VetoedResource.class.getMethod("get");
47+
assertThat(
48+
"Metrics CDI extension incorrectly registered a synthetic simple timer on a vetoed resource JAX-RS endpoint "
49+
+ "method with an explicit metrics annotation",
50+
syntheticSimpleTimerRegistry()
51+
.getSimpleTimers()
52+
.containsKey(MetricsCdiExtension.syntheticSimpleTimerMetricID(method)),
53+
is(false));
54+
}
55+
56+
@Test
57+
void testNoSyntheticSimplyTimedMetricForVetoedResourceWithJaxRsEndpointButOtherwiseUnmeasured() throws NoSuchMethodException {
58+
// Makes sure that a vetoed JAX-RS resource with no explicit metric annotation was not registered with a synthetic
59+
// SimpleTimed metric.
60+
Method method = VetoedJaxRsButOtherwiseUnmeasuredResource.class.getMethod("get");
61+
assertThat(
62+
"Metrics CDI extension incorrectly registered a synthetic simple timer on JAX-RS endpoint method with no "
63+
+ "explicit metrics annotation: "
64+
+ VetoedJaxRsButOtherwiseUnmeasuredResource.class.getName() + "#" + method.getName(),
65+
MetricsCdiExtension.getRegistryForSyntheticSimpleTimers()
66+
.getSimpleTimers()
67+
.containsKey(MetricsCdiExtension.syntheticSimpleTimerMetricID(method)),
68+
is(false));
69+
}
70+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
package io.helidon.microprofile.metrics;
18+
19+
import javax.enterprise.event.Observes;
20+
import javax.enterprise.inject.spi.Extension;
21+
import javax.enterprise.inject.spi.ProcessAnnotatedType;
22+
import javax.enterprise.inject.spi.WithAnnotations;
23+
import javax.ws.rs.Path;
24+
import java.util.Set;
25+
26+
/**
27+
* Vetoes selected resources which should suppress the registration of their annotation-defined metrics and
28+
* implicitly-created synthetic simply timed metrics.
29+
*/
30+
public class VetoCdiExtension implements Extension {
31+
32+
private static final Set<Class<?>> VETOED_RESOURCE_CLASSES = Set.of(VetoedResource.class,
33+
VetoedJaxRsButOtherwiseUnmeasuredResource.class);
34+
35+
private void vetoResourceClass(@Observes @WithAnnotations(Path.class) ProcessAnnotatedType<?> resourceType) {
36+
Class<?> resourceClass = resourceType.getAnnotatedType().getJavaClass();
37+
if (VETOED_RESOURCE_CLASSES.contains(resourceClass)) {
38+
resourceType.veto();
39+
}
40+
}
41+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
package io.helidon.microprofile.metrics;
18+
19+
import javax.enterprise.context.RequestScoped;
20+
import javax.ws.rs.GET;
21+
import javax.ws.rs.Path;
22+
import javax.ws.rs.Produces;
23+
import javax.ws.rs.core.MediaType;
24+
import javax.ws.rs.core.Response;
25+
26+
/**
27+
* JAX-RS resource, vetoed by a test CDI extension, with no explicit metrics annotation.
28+
*/
29+
@Path("/vetoedOtherwiseUnmeasured")
30+
@RequestScoped
31+
public class VetoedJaxRsButOtherwiseUnmeasuredResource {
32+
33+
@GET
34+
@Produces(MediaType.TEXT_PLAIN)
35+
public Response get() {
36+
return Response.ok().build();
37+
}
38+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
package io.helidon.microprofile.metrics;
18+
19+
import org.eclipse.microprofile.metrics.annotation.Counted;
20+
21+
import javax.enterprise.context.RequestScoped;
22+
import javax.ws.rs.GET;
23+
import javax.ws.rs.Path;
24+
import javax.ws.rs.Produces;
25+
import javax.ws.rs.core.MediaType;
26+
import javax.ws.rs.core.Response;
27+
28+
/**
29+
* JAX-RS resource, vetoed by a test CDI extension, with an explicit metrics annotation.
30+
*/
31+
@Path("/vetoed")
32+
@RequestScoped
33+
public class VetoedResource {
34+
35+
static final String COUNTER_NAME = "vetoedCounter";
36+
37+
@Counted(name = COUNTER_NAME, absolute = true)
38+
@GET
39+
@Produces(MediaType.TEXT_PLAIN)
40+
public Response get() {
41+
return Response.ok().build();
42+
}
43+
}

0 commit comments

Comments
 (0)