From 40245b770caf5043a8339f6804606d32181ae1f8 Mon Sep 17 00:00:00 2001 From: Marina Moiseenko Date: Fri, 11 Oct 2024 13:05:37 +0100 Subject: [PATCH 1/5] Added support of @MeterTag annotation on method level --- ...tedParameter.java => AnnotatedObject.java} | 8 +- .../common/annotation/AnnotationHandler.java | 72 ++++- .../common/annotation/AnnotationUtils.java | 8 +- .../io/micrometer/core/aop/CountedAspect.java | 23 +- .../java/io/micrometer/core/aop/MeterTag.java | 2 +- .../io/micrometer/core/aop/MeterTags.java | 2 +- .../io/micrometer/core/aop/TimedAspect.java | 21 +- .../spring6/aop/CountedAspectTest.java | 183 +++++++++-- .../samples/spring6/aop/TimedAspectTest.java | 303 ++++++++++++++---- 9 files changed, 491 insertions(+), 131 deletions(-) rename micrometer-commons/src/main/java/io/micrometer/common/annotation/{AnnotatedParameter.java => AnnotatedObject.java} (86%) diff --git a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotatedParameter.java b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotatedObject.java similarity index 86% rename from micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotatedParameter.java rename to micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotatedObject.java index fa21bfd53a..2e1d202ecd 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotatedParameter.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotatedObject.java @@ -25,15 +25,15 @@ * * @author Christian Schwerdtfeger */ -class AnnotatedParameter { +class AnnotatedObject { final Annotation annotation; - final Object argument; + final Object object; - AnnotatedParameter(Annotation annotation, Object argument) { + AnnotatedObject(Annotation annotation, Object object) { this.annotation = annotation; - this.argument = argument; + this.object = object; } } diff --git a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java index 2a49b4c172..baca92aff9 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java @@ -26,7 +26,9 @@ import java.util.*; import java.util.function.BiConsumer; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; /** * This class is able to find all methods annotated with the Micrometer annotations. All @@ -89,9 +91,9 @@ public void addAnnotatedParameters(T objectToModify, ProceedingJoinPoint pjp) { try { Method method = ((MethodSignature) pjp.getSignature()).getMethod(); method = tryToTakeMethodFromTargetClass(pjp, method); - List annotatedParameters = AnnotationUtils.findAnnotatedParameters(annotationClass, + List annotatedParameters = AnnotationUtils.findAnnotatedParameters(annotationClass, method, pjp.getArgs()); - getAnnotationsFromInterfaces(pjp, method, annotatedParameters); + getParametersAnnotationsFromInterfaces(pjp, method, annotatedParameters); addAnnotatedArguments(objectToModify, annotatedParameters); } catch (Exception ex) { @@ -99,6 +101,28 @@ public void addAnnotatedParameters(T objectToModify, ProceedingJoinPoint pjp) { } } + public void addAnnotatedMethodResult(T objectToModify, ProceedingJoinPoint pjp, Object result) { + try { + Method method = ((MethodSignature) pjp.getSignature()).getMethod(); + method = tryToTakeMethodFromTargetClass(pjp, method); + + List annotatedResult = new ArrayList<>(); + Arrays.stream(method.getAnnotationsByType(annotationClass)) + .map(annotation -> new AnnotatedObject(annotation, result)) + .forEach(annotatedResult::add); + getMethodAnnotationsFromInterfaces(pjp, method) + .stream().map(annotation -> new AnnotatedObject(annotation, result)) + .forEach(annotatedResult::add); + + + + addAnnotatedArguments(objectToModify, annotatedResult); + } + catch (Exception ex) { + log.error("Exception occurred while trying to add annotated method result", ex); + } + } + private static Method tryToTakeMethodFromTargetClass(ProceedingJoinPoint pjp, Method method) { try { return pjp.getTarget().getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()); @@ -109,34 +133,52 @@ private static Method tryToTakeMethodFromTargetClass(ProceedingJoinPoint pjp, Me return method; } - private void getAnnotationsFromInterfaces(ProceedingJoinPoint pjp, Method mostSpecificMethod, - List annotatedParameters) { + private void getParametersAnnotationsFromInterfaces(ProceedingJoinPoint pjp, Method mostSpecificMethod, + List annotatedParameters) { + traverseInterfacesHierarchy( + pjp, mostSpecificMethod, + method -> { + List annotatedParametersForActualMethod = AnnotationUtils + .findAnnotatedParameters(annotationClass, method, pjp.getArgs()); + // annotations for a single parameter can be `duplicated` by the ones + // from parent interface, + // however later on during key-based deduplication the ones from + // specific method(target class) + // will take precedence + annotatedParameters.addAll(annotatedParametersForActualMethod); + } + ); + } + + private void traverseInterfacesHierarchy(ProceedingJoinPoint pjp, + Method mostSpecificMethod, Consumer consumer) { Class[] implementedInterfaces = pjp.getThis().getClass().getInterfaces(); for (Class implementedInterface : implementedInterfaces) { for (Method methodFromInterface : implementedInterface.getMethods()) { if (methodsAreTheSame(mostSpecificMethod, methodFromInterface)) { - List annotatedParametersForActualMethod = AnnotationUtils - .findAnnotatedParameters(annotationClass, methodFromInterface, pjp.getArgs()); - // annotations for a single parameter can be `duplicated` by the ones - // from parent interface, - // however later on during key-based deduplication the ones from - // specific method(target class) - // will take precedence - annotatedParameters.addAll(annotatedParametersForActualMethod); + consumer.accept(methodFromInterface); } } } } + private List getMethodAnnotationsFromInterfaces(ProceedingJoinPoint pjp, Method mostSpecificMethod) { + List allAnnotations = new ArrayList<>(); + traverseInterfacesHierarchy(pjp, mostSpecificMethod, + method -> allAnnotations.addAll( + Arrays.asList(method.getAnnotationsByType(annotationClass)))); + return allAnnotations; + } + private boolean methodsAreTheSame(Method mostSpecificMethod, Method method) { return method.getName().equals(mostSpecificMethod.getName()) && Arrays.equals(method.getParameterTypes(), mostSpecificMethod.getParameterTypes()); } - private void addAnnotatedArguments(T objectToModify, List toBeAdded) { + private void addAnnotatedArguments(T objectToModify, List toBeAdded) { Set seen = new HashSet<>(); - for (AnnotatedParameter container : toBeAdded) { - KeyValue keyValue = toKeyValue.apply(container.annotation, container.argument); + for (AnnotatedObject container : toBeAdded) { + KeyValue keyValue = toKeyValue.apply(container.annotation, container.object); if (seen.add(keyValue.getKey())) { keyValueConsumer.accept(keyValue, objectToModify); } diff --git a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java index f2a056241b..a630fab0c1 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java @@ -35,14 +35,14 @@ private AnnotationUtils() { } - static List findAnnotatedParameters(Class annotationClazz, Method method, - Object[] args) { + static List findAnnotatedParameters(Class annotationClazz, Method method, + Object[] args) { Parameter[] parameters = method.getParameters(); - List result = new ArrayList<>(); + List result = new ArrayList<>(); for (int i = 0; i < parameters.length; i++) { Parameter parameter = parameters[i]; for (Annotation annotation : parameter.getAnnotationsByType(annotationClazz)) { - result.add(new AnnotatedParameter(annotation, args[i])); + result.add(new AnnotatedObject(annotation, args[i])); } } return result; diff --git a/micrometer-core/src/main/java/io/micrometer/core/aop/CountedAspect.java b/micrometer-core/src/main/java/io/micrometer/core/aop/CountedAspect.java index 94166eecf6..78fe2c4a5d 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/aop/CountedAspect.java +++ b/micrometer-core/src/main/java/io/micrometer/core/aop/CountedAspect.java @@ -221,10 +221,10 @@ private Object perform(ProceedingJoinPoint pjp, Counted counted) throws Throwabl if (stopWhenCompleted) { try { return ((CompletionStage) pjp.proceed()) - .whenComplete((result, throwable) -> recordCompletionResult(pjp, counted, throwable)); + .whenComplete((result, throwable) -> recordCompletionResult(pjp, result, counted, throwable)); } catch (Throwable e) { - record(pjp, counted, e.getClass().getSimpleName(), RESULT_TAG_FAILURE_VALUE); + record(pjp, null, counted, e.getClass().getSimpleName(), RESULT_TAG_FAILURE_VALUE); throw e; } } @@ -232,38 +232,40 @@ private Object perform(ProceedingJoinPoint pjp, Counted counted) throws Throwabl try { Object result = pjp.proceed(); if (!counted.recordFailuresOnly()) { - record(pjp, counted, DEFAULT_EXCEPTION_TAG_VALUE, RESULT_TAG_SUCCESS_VALUE); + record(pjp, result, counted, DEFAULT_EXCEPTION_TAG_VALUE, RESULT_TAG_SUCCESS_VALUE); } return result; } catch (Throwable e) { - record(pjp, counted, e.getClass().getSimpleName(), RESULT_TAG_FAILURE_VALUE); + record(pjp, null, counted, e.getClass().getSimpleName(), RESULT_TAG_FAILURE_VALUE); throw e; } } - private void recordCompletionResult(ProceedingJoinPoint pjp, Counted counted, Throwable throwable) { + private void recordCompletionResult(ProceedingJoinPoint pjp, Object methodResult, Counted counted, + Throwable throwable) { if (throwable != null) { String exceptionTagValue = throwable.getCause() == null ? throwable.getClass().getSimpleName() : throwable.getCause().getClass().getSimpleName(); - record(pjp, counted, exceptionTagValue, RESULT_TAG_FAILURE_VALUE); + record(pjp, methodResult, counted, exceptionTagValue, RESULT_TAG_FAILURE_VALUE); } else if (!counted.recordFailuresOnly()) { - record(pjp, counted, DEFAULT_EXCEPTION_TAG_VALUE, RESULT_TAG_SUCCESS_VALUE); + record(pjp, methodResult, counted, DEFAULT_EXCEPTION_TAG_VALUE, RESULT_TAG_SUCCESS_VALUE); } } - private void record(ProceedingJoinPoint pjp, Counted counted, String exception, String result) { - counter(pjp, counted).tag(EXCEPTION_TAG, exception) + private void record(ProceedingJoinPoint pjp, Object methodResult, Counted counted, String exception, + String result) { + counter(pjp, methodResult, counted).tag(EXCEPTION_TAG, exception) .tag(RESULT_TAG, result) .tags(counted.extraTags()) .register(registry) .increment(); } - private Counter.Builder counter(ProceedingJoinPoint pjp, Counted counted) { + private Counter.Builder counter(ProceedingJoinPoint pjp, Object methodResult, Counted counted) { Counter.Builder builder = Counter.builder(counted.value()).tags(tagsBasedOnJoinPoint.apply(pjp)); String description = counted.description(); if (!description.isEmpty()) { @@ -271,6 +273,7 @@ private Counter.Builder counter(ProceedingJoinPoint pjp, Counted counted) { } if (meterTagAnnotationHandler != null) { meterTagAnnotationHandler.addAnnotatedParameters(builder, pjp); + meterTagAnnotationHandler.addAnnotatedMethodResult(builder, pjp, methodResult); } return builder; } diff --git a/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTag.java b/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTag.java index 07415baf65..f6243224a7 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTag.java +++ b/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTag.java @@ -37,7 +37,7 @@ */ @Retention(RetentionPolicy.RUNTIME) @Inherited -@Target(ElementType.PARAMETER) +@Target({ ElementType.PARAMETER, ElementType.METHOD }) @Repeatable(MeterTags.class) public @interface MeterTag { diff --git a/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTags.java b/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTags.java index 28a954333d..64f8708961 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTags.java +++ b/micrometer-core/src/main/java/io/micrometer/core/aop/MeterTags.java @@ -37,7 +37,7 @@ */ @Retention(RetentionPolicy.RUNTIME) @Inherited -@Target(ElementType.PARAMETER) +@Target({ ElementType.METHOD, ElementType.PARAMETER }) @Documented public @interface MeterTags { diff --git a/micrometer-core/src/main/java/io/micrometer/core/aop/TimedAspect.java b/micrometer-core/src/main/java/io/micrometer/core/aop/TimedAspect.java index cb6712b983..80e06c76a1 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/aop/TimedAspect.java +++ b/micrometer-core/src/main/java/io/micrometer/core/aop/TimedAspect.java @@ -218,39 +218,41 @@ private Object processWithTimer(ProceedingJoinPoint pjp, Timed timed, String met if (stopWhenCompleted) { try { - return ((CompletionStage) pjp.proceed()).whenComplete( - (result, throwable) -> record(pjp, timed, metricName, sample, getExceptionTag(throwable))); + return ((CompletionStage) pjp.proceed()).whenComplete((result, throwable) -> record(pjp, result, + timed, metricName, sample, getExceptionTag(throwable))); } catch (Throwable e) { - record(pjp, timed, metricName, sample, e.getClass().getSimpleName()); + record(pjp, null, timed, metricName, sample, e.getClass().getSimpleName()); throw e; } } String exceptionClass = DEFAULT_EXCEPTION_TAG_VALUE; + Object result = null; try { - return pjp.proceed(); + result = pjp.proceed(); + return result; } catch (Throwable e) { exceptionClass = e.getClass().getSimpleName(); throw e; } finally { - record(pjp, timed, metricName, sample, exceptionClass); + record(pjp, result, timed, metricName, sample, exceptionClass); } } - private void record(ProceedingJoinPoint pjp, Timed timed, String metricName, Timer.Sample sample, - String exceptionClass) { + private void record(ProceedingJoinPoint pjp, Object methodResult, Timed timed, String metricName, + Timer.Sample sample, String exceptionClass) { try { - sample.stop(recordBuilder(pjp, timed, metricName, exceptionClass).register(registry)); + sample.stop(recordBuilder(pjp, methodResult, timed, metricName, exceptionClass).register(registry)); } catch (Exception e) { // ignoring on purpose } } - private Timer.Builder recordBuilder(ProceedingJoinPoint pjp, Timed timed, String metricName, + private Timer.Builder recordBuilder(ProceedingJoinPoint pjp, Object methodResult, Timed timed, String metricName, String exceptionClass) { Timer.Builder builder = Timer.builder(metricName) .description(timed.description().isEmpty() ? null : timed.description()) @@ -266,6 +268,7 @@ private Timer.Builder recordBuilder(ProceedingJoinPoint pjp, Timed timed, String if (meterTagAnnotationHandler != null) { meterTagAnnotationHandler.addAnnotatedParameters(builder, pjp); + meterTagAnnotationHandler.addAnnotatedMethodResult(builder, pjp, methodResult); } return builder; } diff --git a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java index d41b84c12c..cdb0d3abe3 100644 --- a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java +++ b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java @@ -21,11 +21,14 @@ import io.micrometer.core.aop.CountedAspect; import io.micrometer.core.aop.CountedMeterTagAnnotationHandler; import io.micrometer.core.aop.MeterTag; +import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.search.MeterNotFoundException; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.aspectj.lang.ProceedingJoinPoint; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -370,7 +373,8 @@ String greet() { } - static class MeterTagsTests { + @Nested + class MeterTagsTests { ValueResolver valueResolver = parameter -> "Value from myCustomTagValueResolver [" + parameter + "]"; @@ -379,34 +383,33 @@ static class MeterTagsTests { CountedMeterTagAnnotationHandler meterTagAnnotationHandler = new CountedMeterTagAnnotationHandler( aClass -> valueResolver, aClass -> valueExpressionResolver); + MeterRegistry registry; + CountedAspect countedAspect; + + @BeforeEach + void setup() { + registry = new SimpleMeterRegistry(); + countedAspect = new CountedAspect(registry); + countedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); + } + @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void meterTagsWithText(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - CountedAspect countedAspect = new CountedAspect(registry); - countedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(countedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithCountedAspect(annotatedClass.newInstance()); service.getAnnotationForArgumentToString(15L); - assertThat(registry.get("method.counted").tag("test", "15").counter().count()).isEqualTo(1); + assertThat(registry.get("method.counted") + .tag("test", "15") + .counter() + .count()).isEqualTo(1); } @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void meterTagsWithResolver(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - CountedAspect countedAspect = new CountedAspect(registry); - countedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(countedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithCountedAspect(annotatedClass.newInstance()); service.getAnnotationForTagValueResolver("foo"); @@ -419,26 +422,18 @@ void meterTagsWithResolver(AnnotatedTestClass annotatedClass) { @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void meterTagsWithExpression(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - CountedAspect countedAspect = new CountedAspect(registry); - countedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(countedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithCountedAspect(annotatedClass.newInstance()); service.getAnnotationForTagValueExpression("15L"); - assertThat(registry.get("method.counted").tag("test", "hello characters").counter().count()).isEqualTo(1); + assertThat(registry.get("method.counted") + .tag("test", "hello characters") + .counter(). + count()).isEqualTo(1); } @Test void meterTagOnPackagePrivateMethod() { - MeterRegistry registry = new SimpleMeterRegistry(); - CountedAspect countedAspect = new CountedAspect(registry); - countedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - AspectJProxyFactory pf = new AspectJProxyFactory(new MeterTagClass()); pf.setProxyTargetClass(true); pf.addAspect(countedAspect); @@ -447,9 +442,74 @@ void meterTagOnPackagePrivateMethod() { service.getAnnotationForPackagePrivateMethod("bar"); - assertThat(registry.get("method.counted").tag("foo", "bar").counter().count()).isEqualTo(1); + assertThat(registry.get("method.counted") + .tag("foo", "bar") + .counter() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void meterTagsOnReturnValueWithText(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithCountedAspect(annotatedClass.newInstance()); + + service.getAnnotationForArgumentToString(); + + assertThat(registry.get("method.counted") + .tag("test", "15") + .counter() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void meterTagsOnReturnValueWithResolver(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithCountedAspect(annotatedClass.newInstance()); + + service.getAnnotationForTagValueResolver(); + + assertThat(registry.get("method.counted") + .tag("test", "Value from myCustomTagValueResolver [foo]") + .counter() + .count()).isEqualTo(1); } + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void meterTagsOnReturnValueWithExpression(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithCountedAspect(annotatedClass.newInstance()); + + service.getAnnotationForTagValueExpression(); + + assertThat(registry.get("method.counted") + .tag("test", "hello characters") + .counter(). + count()).isEqualTo(1); + } + + @Test + void meterTagOnReturnValueOnPackagePrivateMethod() { + AspectJProxyFactory pf = new AspectJProxyFactory(new MeterTagClass()); + pf.setProxyTargetClass(true); + pf.addAspect(countedAspect); + + MeterTagClass service = pf.getProxy(); + + service.getAnnotationForPackagePrivateMethod(); + + assertThat(registry.get("method.counted") + .tag("foo", "bar") + .counter() + .count()).isEqualTo(1); + } + + private T getProxyWithCountedAspect(T object) { + AspectJProxyFactory pf = new AspectJProxyFactory(object); + pf.addAspect(countedAspect); + return pf.getProxy(); + } + + enum AnnotatedTestClass { CLASS_WITHOUT_INTERFACE(MeterTagClass.class), CLASS_WITH_INTERFACE(MeterTagClassChild.class); @@ -477,13 +537,27 @@ interface MeterTagClassInterface { @Counted void getAnnotationForTagValueResolver(@MeterTag(key = "test", resolver = ValueResolver.class) String test); + @Counted + @MeterTag(key = "test", resolver = ValueResolver.class) + String getAnnotationForTagValueResolver(); + @Counted void getAnnotationForTagValueExpression( @MeterTag(key = "test", expression = "'hello' + ' characters'") String test); + + @Counted + @MeterTag(key = "test", expression = "'hello' + ' characters'") + String getAnnotationForTagValueExpression(); + @Counted void getAnnotationForArgumentToString(@MeterTag("test") Long param); + + @Counted + @MeterTag("test") + Long getAnnotationForArgumentToString(); + } static class MeterTagClass implements MeterTagClassInterface { @@ -494,21 +568,48 @@ public void getAnnotationForTagValueResolver( @MeterTag(key = "test", resolver = ValueResolver.class) String test) { } + @Counted + @MeterTag(key = "test", resolver = ValueResolver.class) + @Override + public String getAnnotationForTagValueResolver() { + return "foo"; + } + @Counted @Override public void getAnnotationForTagValueExpression( @MeterTag(key = "test", expression = "'hello' + ' characters'") String test) { } + @Counted + @MeterTag(key = "test", expression = "'hello' + ' characters'") + @Override + public String getAnnotationForTagValueExpression() { + return "15L"; + } + @Counted @Override public void getAnnotationForArgumentToString(@MeterTag("test") Long param) { } + @Counted + @MeterTag("test") + @Override + public Long getAnnotationForArgumentToString() { + return 15L; + } + @Counted void getAnnotationForPackagePrivateMethod(@MeterTag("foo") String foo) { } + @MeterTag("foo") + @Counted + String getAnnotationForPackagePrivateMethod() { + return "bar"; + } + } static class MeterTagClassChild implements MeterTagClassInterface { @@ -518,16 +619,34 @@ static class MeterTagClassChild implements MeterTagClassInterface { public void getAnnotationForTagValueResolver(String test) { } + @Counted + @Override + public String getAnnotationForTagValueResolver() { + return "foo"; + } + @Counted @Override public void getAnnotationForTagValueExpression(String test) { } + @Counted + @Override + public String getAnnotationForTagValueExpression() { + return "15L"; + } + @Counted @Override public void getAnnotationForArgumentToString(Long param) { } + @Counted + @Override + public Long getAnnotationForArgumentToString() { + return 15L; + } + } } diff --git a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java index 343a5012a7..7b667c151d 100644 --- a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java +++ b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java @@ -31,6 +31,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.micrometer.core.instrument.util.TimeUtils; import org.aspectj.lang.ProceedingJoinPoint; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -454,34 +455,33 @@ class MeterTagsTests { MeterTagAnnotationHandler meterTagAnnotationHandler = new MeterTagAnnotationHandler(aClass -> valueResolver, aClass -> valueExpressionResolver); + MeterRegistry registry; + TimedAspect timedAspect; + + @BeforeEach + void setup() { + registry = new SimpleMeterRegistry(); + timedAspect = new TimedAspect(registry); + timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); + } + @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void meterTagsWithText(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(timedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); service.getAnnotationForArgumentToString(15L); - assertThat(registry.get("method.timed").tag("test", "15").timer().count()).isEqualTo(1); + assertThat(registry.get("method.timed") + .tag("test", "15") + .timer() + .count()).isEqualTo(1); } @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void meterTagsWithResolver(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(timedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); service.getAnnotationForTagValueResolver("foo"); @@ -494,32 +494,20 @@ void meterTagsWithResolver(AnnotatedTestClass annotatedClass) { @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void meterTagsWithExpression(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(timedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); service.getAnnotationForTagValueExpression("15L"); - assertThat(registry.get("method.timed").tag("test", "hello characters. overridden").timer().count()) - .isEqualTo(1); + assertThat(registry.get("method.timed") + .tag("test", "hello characters. overridden") + .timer() + .count()).isEqualTo(1); } @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void multipleMeterTagsWithExpression(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(timedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); service.getMultipleAnnotationsForTagValueExpression(new DataHolder("zxe", "qwe")); @@ -533,14 +521,7 @@ void multipleMeterTagsWithExpression(AnnotatedTestClass annotatedClass) { @ParameterizedTest @EnumSource(AnnotatedTestClass.class) void multipleMeterTagsWithinContainerWithExpression(AnnotatedTestClass annotatedClass) { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - - AspectJProxyFactory pf = new AspectJProxyFactory(annotatedClass.newInstance()); - pf.addAspect(timedAspect); - - MeterTagClassInterface service = pf.getProxy(); + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); service.getMultipleAnnotationsWithContainerForTagValueExpression(new DataHolder("zxe", "qwe")); @@ -554,10 +535,6 @@ void multipleMeterTagsWithinContainerWithExpression(AnnotatedTestClass annotated @Test void meterTagOnPackagePrivateMethod() { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); - AspectJProxyFactory pf = new AspectJProxyFactory(new MeterTagClass()); pf.setProxyTargetClass(true); pf.addAspect(timedAspect); @@ -566,24 +543,124 @@ void meterTagOnPackagePrivateMethod() { service.getAnnotationForPackagePrivateMethod("bar"); - assertThat(registry.get("method.timed").tag("foo", "bar").timer().count()).isEqualTo(1); + assertThat(registry.get("method.timed") + .tag("foo", "bar") + .timer() + .count()).isEqualTo(1); } @Test void meterTagOnSuperClass() { - MeterRegistry registry = new SimpleMeterRegistry(); - TimedAspect timedAspect = new TimedAspect(registry); - timedAspect.setMeterTagAnnotationHandler(meterTagAnnotationHandler); + MeterTagSub service = getProxyWithTimedAspect(new MeterTagSub()); - AspectJProxyFactory pf = new AspectJProxyFactory(new MeterTagSub()); + service.superMethod("someValue"); + + assertThat(registry.get("method.timed") + .tag("superTag", "someValue") + .timer() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void meterTagsOnReturnValueWithText(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); + + service.getAnnotationForArgumentToString(); + + assertThat(registry.get("method.timed") + .tag("test", "15") + .timer() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void meterTagsOnReturnValueWithResolver(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); + + service.getAnnotationForTagValueResolver(); + + assertThat(registry.get("method.timed") + .tag("test", "Value from myCustomTagValueResolver [foo]") + .timer() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void meterTagsOnReturnValueWithExpression(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); + + service.getAnnotationForTagValueExpression(); + + assertThat(registry.get("method.timed") + .tag("test", "hello characters. overridden") + .timer() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void multipleMeterTagsOnReturnValueWithExpression(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); + + service.getMultipleAnnotationsForTagValueExpression(); + + assertThat(registry.get("method.timed") + .tag("value1", "value1: zxe") + .tag("value2", "value2. overridden: qwe") + .timer() + .count()).isEqualTo(1); + } + + @ParameterizedTest + @EnumSource(AnnotatedTestClass.class) + void multipleMeterTagsOnReturnValueWithinContainerWithExpression(AnnotatedTestClass annotatedClass) { + MeterTagClassInterface service = getProxyWithTimedAspect(annotatedClass.newInstance()); + + service.getMultipleAnnotationsWithContainerForTagValueExpression(); + + assertThat(registry.get("method.timed") + .tag("value1", "value1: zxe") + .tag("value2", "value2: qwe") + .tag("value3", "value3. overridden: ZXEQWE") + .timer() + .count()).isEqualTo(1); + } + + @Test + void meterTagOnReturnValueOnPackagePrivateMethod() { + AspectJProxyFactory pf = new AspectJProxyFactory(new MeterTagClass()); pf.setProxyTargetClass(true); pf.addAspect(timedAspect); - MeterTagSub service = pf.getProxy(); + MeterTagClass service = pf.getProxy(); - service.superMethod("someValue"); + service.getAnnotationForPackagePrivateMethod(); - assertThat(registry.get("method.timed").tag("superTag", "someValue").timer().count()).isEqualTo(1); + assertThat(registry.get("method.timed") + .tag("foo", "bar") + .timer() + .count()).isEqualTo(1); + } + + @Test + void meterTagOnReturnValueOnSuperClass() { + MeterTagSub service = getProxyWithTimedAspect(new MeterTagSub()); + + service.superMethod(); + + assertThat(registry.get("method.timed") + .tag("superTag", "someValue") + .timer() + .count()).isEqualTo(1); + } + + private T getProxyWithTimedAspect(T object) { + AspectJProxyFactory pf = new AspectJProxyFactory(object); + pf.addAspect(timedAspect); + return pf.getProxy(); } } @@ -615,24 +692,48 @@ interface MeterTagClassInterface { @Timed void getAnnotationForTagValueResolver(@MeterTag(key = "test", resolver = ValueResolver.class) String test); + @Timed + @MeterTag(key = "test", resolver = ValueResolver.class) + String getAnnotationForTagValueResolver(); + @Timed void getAnnotationForTagValueExpression( @MeterTag(key = "test", expression = "'hello' + ' characters'") String test); + @Timed + @MeterTag(key = "test", expression = "'hello' + ' characters'") + String getAnnotationForTagValueExpression(); + @Timed void getAnnotationForArgumentToString(@MeterTag("test") Long param); + @Timed + @MeterTag("test") + Long getAnnotationForArgumentToString(); + @Timed void getMultipleAnnotationsForTagValueExpression( @MeterTag(key = "value1", expression = "'value1: ' + value1") @MeterTag(key = "value2", expression = "'value2: ' + value2") DataHolder param); + @Timed + @MeterTag(key = "value1", expression = "'value1: ' + value1") + @MeterTag(key = "value2", expression = "'value2: ' + value2") + DataHolder getMultipleAnnotationsForTagValueExpression(); + @Timed void getMultipleAnnotationsWithContainerForTagValueExpression(@MeterTags({ @MeterTag(key = "value1", expression = "'value1: ' + value1"), @MeterTag(key = "value2", expression = "'value2: ' + value2"), @MeterTag(key = "value3", expression = "'value3: ' + value1.toUpperCase + value2.toUpperCase") }) DataHolder param); + @Timed + @MeterTags({ + @MeterTag(key = "value1", expression = "'value1: ' + value1"), + @MeterTag(key = "value2", expression = "'value2: ' + value2"), @MeterTag(key = "value3", + expression = "'value3: ' + value1.toUpperCase + value2.toUpperCase") }) + DataHolder getMultipleAnnotationsWithContainerForTagValueExpression(); + } static class MeterTagClass implements MeterTagClassInterface { @@ -643,21 +744,49 @@ public void getAnnotationForTagValueResolver( @MeterTag(key = "test", resolver = ValueResolver.class) String test) { } + @Timed + @MeterTag(key = "test", resolver = ValueResolver.class) + @Override + public String getAnnotationForTagValueResolver() { + return "foo"; + } + @Timed @Override public void getAnnotationForTagValueExpression( @MeterTag(key = "test", expression = "'hello' + ' characters. overridden'") String test) { } + @Timed + @MeterTag(key = "test", expression = "'hello' + ' characters. overridden'") + @Override + public String getAnnotationForTagValueExpression() { + return "foo"; + } + @Timed @Override public void getAnnotationForArgumentToString(@MeterTag("test") Long param) { } + @Timed + @MeterTag("test") + @Override + public Long getAnnotationForArgumentToString() { + return 15L; + } + @Timed void getAnnotationForPackagePrivateMethod(@MeterTag("foo") String foo) { } + + @Timed + @MeterTag("foo") + String getAnnotationForPackagePrivateMethod() { + return "bar"; + } + @Timed @Override public void getMultipleAnnotationsForTagValueExpression( @@ -666,6 +795,15 @@ public void getMultipleAnnotationsForTagValueExpression( } + + @Timed + @MeterTag(key = "value1", expression = "'value1: ' + value1") + @MeterTag(key = "value2", expression = "'value2. overridden: ' + value2") + @Override + public DataHolder getMultipleAnnotationsForTagValueExpression() { + return new DataHolder("zxe", "qwe"); + } + @Timed @Override public void getMultipleAnnotationsWithContainerForTagValueExpression(@MeterTags({ @@ -674,6 +812,16 @@ public void getMultipleAnnotationsWithContainerForTagValueExpression(@MeterTags( expression = "'value3. overridden: ' + value1.toUpperCase + value2.toUpperCase") }) DataHolder param) { } + @Timed + @MeterTags({ + @MeterTag(key = "value1", expression = "'value1: ' + value1"), + @MeterTag(key = "value2", expression = "'value2: ' + value2"), @MeterTag(key = "value3", + expression = "'value3. overridden: ' + value1.toUpperCase + value2.toUpperCase") }) + @Override + public DataHolder getMultipleAnnotationsWithContainerForTagValueExpression() { + return new DataHolder("zxe", "qwe"); + } + } static class MeterTagClassChild implements MeterTagClassInterface { @@ -683,29 +831,62 @@ static class MeterTagClassChild implements MeterTagClassInterface { public void getAnnotationForTagValueResolver(String test) { } + @Timed + @Override + public String getAnnotationForTagValueResolver() { + return "foo"; + } + @Timed @Override public void getAnnotationForTagValueExpression( @MeterTag(key = "test", expression = "'hello' + ' characters. overridden'") String test) { } + @Timed + @MeterTag(key = "test", expression = "'hello' + ' characters. overridden'") + @Override + public String getAnnotationForTagValueExpression() { + return "foo"; + } + @Timed @Override public void getAnnotationForArgumentToString(Long param) { } + @Timed + @Override + public Long getAnnotationForArgumentToString() { + return 15L; + } + @Timed @Override public void getMultipleAnnotationsForTagValueExpression( @MeterTag(key = "value2", expression = "'value2. overridden: ' + value2") DataHolder param) { } + @Timed + @Override + @MeterTag(key = "value2", expression = "'value2. overridden: ' + value2") + public DataHolder getMultipleAnnotationsForTagValueExpression() { + return new DataHolder("zxe", "qwe"); + } + @Timed @Override public void getMultipleAnnotationsWithContainerForTagValueExpression(@MeterTag(key = "value3", expression = "'value3. overridden: ' + value1.toUpperCase + value2.toUpperCase") DataHolder param) { } + @Timed + @MeterTag(key = "value3", expression = "'value3. overridden: ' + value1.toUpperCase + value2.toUpperCase") + @Override + public DataHolder getMultipleAnnotationsWithContainerForTagValueExpression() { + return new DataHolder("zxe", "qwe"); + } + } static class MeterTagSuper { @@ -714,6 +895,12 @@ static class MeterTagSuper { public void superMethod(@MeterTag("superTag") String foo) { } + @Timed + @MeterTag("superTag") + public String superMethod() { + return "someValue"; + } + } static class MeterTagSub extends MeterTagSuper { @@ -722,6 +909,12 @@ static class MeterTagSub extends MeterTagSuper { public void subMethod(@MeterTag("subTag") String foo) { } + @Timed + @MeterTag("subTag") + public String subMethod() { + return "someValue"; + } + } private static final class FailingMeterRegistry extends SimpleMeterRegistry { From dce0f194e93092bec0a53e45c7ca91d5a52b8dd4 Mon Sep 17 00:00:00 2001 From: Marina Moiseenko Date: Fri, 11 Oct 2024 13:34:42 +0100 Subject: [PATCH 2/5] Fixed formatting --- .../common/annotation/AnnotationHandler.java | 44 ++++++++----------- .../common/annotation/AnnotationUtils.java | 2 +- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java index baca92aff9..55c38d6bc8 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java @@ -91,8 +91,8 @@ public void addAnnotatedParameters(T objectToModify, ProceedingJoinPoint pjp) { try { Method method = ((MethodSignature) pjp.getSignature()).getMethod(); method = tryToTakeMethodFromTargetClass(pjp, method); - List annotatedParameters = AnnotationUtils.findAnnotatedParameters(annotationClass, - method, pjp.getArgs()); + List annotatedParameters = AnnotationUtils.findAnnotatedParameters(annotationClass, method, + pjp.getArgs()); getParametersAnnotationsFromInterfaces(pjp, method, annotatedParameters); addAnnotatedArguments(objectToModify, annotatedParameters); } @@ -110,11 +110,9 @@ public void addAnnotatedMethodResult(T objectToModify, ProceedingJoinPoint pjp, Arrays.stream(method.getAnnotationsByType(annotationClass)) .map(annotation -> new AnnotatedObject(annotation, result)) .forEach(annotatedResult::add); - getMethodAnnotationsFromInterfaces(pjp, method) - .stream().map(annotation -> new AnnotatedObject(annotation, result)) - .forEach(annotatedResult::add); - - + getMethodAnnotationsFromInterfaces(pjp, method).stream() + .map(annotation -> new AnnotatedObject(annotation, result)) + .forEach(annotatedResult::add); addAnnotatedArguments(objectToModify, annotatedResult); } @@ -134,24 +132,21 @@ private static Method tryToTakeMethodFromTargetClass(ProceedingJoinPoint pjp, Me } private void getParametersAnnotationsFromInterfaces(ProceedingJoinPoint pjp, Method mostSpecificMethod, - List annotatedParameters) { - traverseInterfacesHierarchy( - pjp, mostSpecificMethod, - method -> { - List annotatedParametersForActualMethod = AnnotationUtils - .findAnnotatedParameters(annotationClass, method, pjp.getArgs()); - // annotations for a single parameter can be `duplicated` by the ones - // from parent interface, - // however later on during key-based deduplication the ones from - // specific method(target class) - // will take precedence - annotatedParameters.addAll(annotatedParametersForActualMethod); - } - ); + List annotatedParameters) { + traverseInterfacesHierarchy(pjp, mostSpecificMethod, method -> { + List annotatedParametersForActualMethod = AnnotationUtils + .findAnnotatedParameters(annotationClass, method, pjp.getArgs()); + // annotations for a single parameter can be `duplicated` by the ones + // from parent interface, + // however later on during key-based deduplication the ones from + // specific method(target class) + // will take precedence + annotatedParameters.addAll(annotatedParametersForActualMethod); + }); } - private void traverseInterfacesHierarchy(ProceedingJoinPoint pjp, - Method mostSpecificMethod, Consumer consumer) { + private void traverseInterfacesHierarchy(ProceedingJoinPoint pjp, Method mostSpecificMethod, + Consumer consumer) { Class[] implementedInterfaces = pjp.getThis().getClass().getInterfaces(); for (Class implementedInterface : implementedInterfaces) { for (Method methodFromInterface : implementedInterface.getMethods()) { @@ -165,8 +160,7 @@ private void traverseInterfacesHierarchy(ProceedingJoinPoint pjp, private List getMethodAnnotationsFromInterfaces(ProceedingJoinPoint pjp, Method mostSpecificMethod) { List allAnnotations = new ArrayList<>(); traverseInterfacesHierarchy(pjp, mostSpecificMethod, - method -> allAnnotations.addAll( - Arrays.asList(method.getAnnotationsByType(annotationClass)))); + method -> allAnnotations.addAll(Arrays.asList(method.getAnnotationsByType(annotationClass)))); return allAnnotations; } diff --git a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java index a630fab0c1..4969365dc2 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationUtils.java @@ -36,7 +36,7 @@ private AnnotationUtils() { } static List findAnnotatedParameters(Class annotationClazz, Method method, - Object[] args) { + Object[] args) { Parameter[] parameters = method.getParameters(); List result = new ArrayList<>(); for (int i = 0; i < parameters.length; i++) { From c6e13063928455ef4aa8a291ff06c6e8d7a40cfc Mon Sep 17 00:00:00 2001 From: Marina Moiseenko Date: Fri, 11 Oct 2024 13:48:18 +0100 Subject: [PATCH 3/5] Deleted unused imports --- .../java/io/micrometer/common/annotation/AnnotationHandler.java | 1 - 1 file changed, 1 deletion(-) diff --git a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java index 55c38d6bc8..18b507ff08 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/annotation/AnnotationHandler.java @@ -28,7 +28,6 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; -import java.util.stream.Collectors; /** * This class is able to find all methods annotated with the Micrometer annotations. All From d3f860c18a103263bbd088f92a3cdba7886571c5 Mon Sep 17 00:00:00 2001 From: Marina Moiseenko Date: Fri, 11 Oct 2024 14:08:55 +0100 Subject: [PATCH 4/5] Fixed formatting --- .../spring6/aop/CountedAspectTest.java | 34 +++-------- .../samples/spring6/aop/TimedAspectTest.java | 60 ++++++------------- 2 files changed, 25 insertions(+), 69 deletions(-) diff --git a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java index cdb0d3abe3..fbeaedd19b 100644 --- a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java +++ b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java @@ -384,6 +384,7 @@ class MeterTagsTests { aClass -> valueResolver, aClass -> valueExpressionResolver); MeterRegistry registry; + CountedAspect countedAspect; @BeforeEach @@ -400,10 +401,7 @@ void meterTagsWithText(AnnotatedTestClass annotatedClass) { service.getAnnotationForArgumentToString(15L); - assertThat(registry.get("method.counted") - .tag("test", "15") - .counter() - .count()).isEqualTo(1); + assertThat(registry.get("method.counted").tag("test", "15").counter().count()).isEqualTo(1); } @ParameterizedTest @@ -426,10 +424,7 @@ void meterTagsWithExpression(AnnotatedTestClass annotatedClass) { service.getAnnotationForTagValueExpression("15L"); - assertThat(registry.get("method.counted") - .tag("test", "hello characters") - .counter(). - count()).isEqualTo(1); + assertThat(registry.get("method.counted").tag("test", "hello characters").counter().count()).isEqualTo(1); } @Test @@ -442,10 +437,7 @@ void meterTagOnPackagePrivateMethod() { service.getAnnotationForPackagePrivateMethod("bar"); - assertThat(registry.get("method.counted") - .tag("foo", "bar") - .counter() - .count()).isEqualTo(1); + assertThat(registry.get("method.counted").tag("foo", "bar").counter().count()).isEqualTo(1); } @ParameterizedTest @@ -455,10 +447,7 @@ void meterTagsOnReturnValueWithText(AnnotatedTestClass annotatedClass) { service.getAnnotationForArgumentToString(); - assertThat(registry.get("method.counted") - .tag("test", "15") - .counter() - .count()).isEqualTo(1); + assertThat(registry.get("method.counted").tag("test", "15").counter().count()).isEqualTo(1); } @ParameterizedTest @@ -481,10 +470,7 @@ void meterTagsOnReturnValueWithExpression(AnnotatedTestClass annotatedClass) { service.getAnnotationForTagValueExpression(); - assertThat(registry.get("method.counted") - .tag("test", "hello characters") - .counter(). - count()).isEqualTo(1); + assertThat(registry.get("method.counted").tag("test", "hello characters").counter().count()).isEqualTo(1); } @Test @@ -497,10 +483,7 @@ void meterTagOnReturnValueOnPackagePrivateMethod() { service.getAnnotationForPackagePrivateMethod(); - assertThat(registry.get("method.counted") - .tag("foo", "bar") - .counter() - .count()).isEqualTo(1); + assertThat(registry.get("method.counted").tag("foo", "bar").counter().count()).isEqualTo(1); } private T getProxyWithCountedAspect(T object) { @@ -509,7 +492,6 @@ private T getProxyWithCountedAspect(T object) { return pf.getProxy(); } - enum AnnotatedTestClass { CLASS_WITHOUT_INTERFACE(MeterTagClass.class), CLASS_WITH_INTERFACE(MeterTagClassChild.class); @@ -545,7 +527,6 @@ interface MeterTagClassInterface { void getAnnotationForTagValueExpression( @MeterTag(key = "test", expression = "'hello' + ' characters'") String test); - @Counted @MeterTag(key = "test", expression = "'hello' + ' characters'") String getAnnotationForTagValueExpression(); @@ -553,7 +534,6 @@ void getAnnotationForTagValueExpression( @Counted void getAnnotationForArgumentToString(@MeterTag("test") Long param); - @Counted @MeterTag("test") Long getAnnotationForArgumentToString(); diff --git a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java index 7b667c151d..a36178f248 100644 --- a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java +++ b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/TimedAspectTest.java @@ -456,6 +456,7 @@ class MeterTagsTests { aClass -> valueExpressionResolver); MeterRegistry registry; + TimedAspect timedAspect; @BeforeEach @@ -472,10 +473,7 @@ void meterTagsWithText(AnnotatedTestClass annotatedClass) { service.getAnnotationForArgumentToString(15L); - assertThat(registry.get("method.timed") - .tag("test", "15") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("test", "15").timer().count()).isEqualTo(1); } @ParameterizedTest @@ -498,10 +496,8 @@ void meterTagsWithExpression(AnnotatedTestClass annotatedClass) { service.getAnnotationForTagValueExpression("15L"); - assertThat(registry.get("method.timed") - .tag("test", "hello characters. overridden") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("test", "hello characters. overridden").timer().count()) + .isEqualTo(1); } @ParameterizedTest @@ -543,10 +539,7 @@ void meterTagOnPackagePrivateMethod() { service.getAnnotationForPackagePrivateMethod("bar"); - assertThat(registry.get("method.timed") - .tag("foo", "bar") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("foo", "bar").timer().count()).isEqualTo(1); } @Test @@ -555,10 +548,7 @@ void meterTagOnSuperClass() { service.superMethod("someValue"); - assertThat(registry.get("method.timed") - .tag("superTag", "someValue") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("superTag", "someValue").timer().count()).isEqualTo(1); } @ParameterizedTest @@ -568,10 +558,7 @@ void meterTagsOnReturnValueWithText(AnnotatedTestClass annotatedClass) { service.getAnnotationForArgumentToString(); - assertThat(registry.get("method.timed") - .tag("test", "15") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("test", "15").timer().count()).isEqualTo(1); } @ParameterizedTest @@ -594,10 +581,8 @@ void meterTagsOnReturnValueWithExpression(AnnotatedTestClass annotatedClass) { service.getAnnotationForTagValueExpression(); - assertThat(registry.get("method.timed") - .tag("test", "hello characters. overridden") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("test", "hello characters. overridden").timer().count()) + .isEqualTo(1); } @ParameterizedTest @@ -639,10 +624,7 @@ void meterTagOnReturnValueOnPackagePrivateMethod() { service.getAnnotationForPackagePrivateMethod(); - assertThat(registry.get("method.timed") - .tag("foo", "bar") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("foo", "bar").timer().count()).isEqualTo(1); } @Test @@ -651,10 +633,7 @@ void meterTagOnReturnValueOnSuperClass() { service.superMethod(); - assertThat(registry.get("method.timed") - .tag("superTag", "someValue") - .timer() - .count()).isEqualTo(1); + assertThat(registry.get("method.timed").tag("superTag", "someValue").timer().count()).isEqualTo(1); } private T getProxyWithTimedAspect(T object) { @@ -728,10 +707,9 @@ void getMultipleAnnotationsWithContainerForTagValueExpression(@MeterTags({ expression = "'value3: ' + value1.toUpperCase + value2.toUpperCase") }) DataHolder param); @Timed - @MeterTags({ - @MeterTag(key = "value1", expression = "'value1: ' + value1"), - @MeterTag(key = "value2", expression = "'value2: ' + value2"), @MeterTag(key = "value3", - expression = "'value3: ' + value1.toUpperCase + value2.toUpperCase") }) + @MeterTags({ @MeterTag(key = "value1", expression = "'value1: ' + value1"), + @MeterTag(key = "value2", expression = "'value2: ' + value2"), + @MeterTag(key = "value3", expression = "'value3: ' + value1.toUpperCase + value2.toUpperCase") }) DataHolder getMultipleAnnotationsWithContainerForTagValueExpression(); } @@ -780,7 +758,6 @@ public Long getAnnotationForArgumentToString() { void getAnnotationForPackagePrivateMethod(@MeterTag("foo") String foo) { } - @Timed @MeterTag("foo") String getAnnotationForPackagePrivateMethod() { @@ -795,7 +772,6 @@ public void getMultipleAnnotationsForTagValueExpression( } - @Timed @MeterTag(key = "value1", expression = "'value1: ' + value1") @MeterTag(key = "value2", expression = "'value2. overridden: ' + value2") @@ -813,10 +789,10 @@ public void getMultipleAnnotationsWithContainerForTagValueExpression(@MeterTags( } @Timed - @MeterTags({ - @MeterTag(key = "value1", expression = "'value1: ' + value1"), - @MeterTag(key = "value2", expression = "'value2: ' + value2"), @MeterTag(key = "value3", - expression = "'value3. overridden: ' + value1.toUpperCase + value2.toUpperCase") }) + @MeterTags({ @MeterTag(key = "value1", expression = "'value1: ' + value1"), + @MeterTag(key = "value2", expression = "'value2: ' + value2"), + @MeterTag(key = "value3", + expression = "'value3. overridden: ' + value1.toUpperCase + value2.toUpperCase") }) @Override public DataHolder getMultipleAnnotationsWithContainerForTagValueExpression() { return new DataHolder("zxe", "qwe"); From 885ff680628dedbdfd1e1bb08e47d9cbb7899906 Mon Sep 17 00:00:00 2001 From: Marina Moiseenko Date: Fri, 11 Oct 2024 14:14:22 +0100 Subject: [PATCH 5/5] Deleted unused imports --- .../io/micrometer/samples/spring6/aop/CountedAspectTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java index fbeaedd19b..fe921d008c 100644 --- a/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java +++ b/samples/micrometer-samples-spring-framework6/src/test/java/io/micrometer/samples/spring6/aop/CountedAspectTest.java @@ -21,7 +21,6 @@ import io.micrometer.core.aop.CountedAspect; import io.micrometer.core.aop.CountedMeterTagAnnotationHandler; import io.micrometer.core.aop.MeterTag; -import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.search.MeterNotFoundException;