Skip to content

Commit 4e67159

Browse files
committed
Ignore class level AOP annotation if method level present
Do not advise twice
1 parent 8604662 commit 4e67159

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed

micrometer-core/src/main/java/io/micrometer/core/aop/CountedAspect.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
* @author Ali Dehghani
7070
* @author Jonatan Ivanov
7171
* @author Johnny Lim
72+
* @author Yanming Zhou
7273
* @since 1.2.0
7374
* @see Counted
7475
*/
@@ -166,7 +167,7 @@ public CountedAspect(MeterRegistry registry, Function<ProceedingJoinPoint, Itera
166167
this.shouldSkip = shouldSkip;
167168
}
168169

169-
@Around("@within(io.micrometer.core.annotation.Counted)")
170+
@Around("@within(io.micrometer.core.annotation.Counted) and not @annotation(io.micrometer.core.annotation.Counted)")
170171
@Nullable
171172
public Object countedClass(ProceedingJoinPoint pjp) throws Throwable {
172173
if (shouldSkip.test(pjp)) {

micrometer-core/src/main/java/io/micrometer/core/aop/TimedAspect.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
* @author Johnny Lim
7777
* @author Nejc Korasa
7878
* @author Jonatan Ivanov
79+
* @author Yanming Zhou
7980
* @since 1.0.0
8081
*/
8182
@Aspect
@@ -160,7 +161,7 @@ public TimedAspect(MeterRegistry registry, Function<ProceedingJoinPoint, Iterabl
160161
this.shouldSkip = shouldSkip;
161162
}
162163

163-
@Around("@within(io.micrometer.core.annotation.Timed)")
164+
@Around("@within(io.micrometer.core.annotation.Timed) and not @annotation(io.micrometer.core.annotation.Timed)")
164165
@Nullable
165166
public Object timedClass(ProceedingJoinPoint pjp) throws Throwable {
166167
if (shouldSkip.test(pjp)) {

micrometer-core/src/test/java/io/micrometer/core/aop/CountedAspectTest.java

+25-2
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@
2828
import java.util.function.Predicate;
2929

3030
import static java.util.concurrent.CompletableFuture.supplyAsync;
31-
import static org.assertj.core.api.Assertions.assertThat;
32-
import static org.assertj.core.api.Assertions.assertThatThrownBy;
31+
import static org.assertj.core.api.Assertions.*;
3332

3433
/**
3534
* Unit tests for the {@link CountedAspect} aspect.
3635
*
3736
* @author Ali Dehghani
3837
* @author Tommy Ludwig
3938
* @author Johnny Lim
39+
* @author Yanming Zhou
4040
*/
4141
class CountedAspectTest {
4242

@@ -327,6 +327,24 @@ void countClassWithFailure() {
327327
.count()).isEqualTo(1);
328328
}
329329

330+
@Test
331+
void ignoreClassLevelAnnotationIfMethodLevelPresent() {
332+
CountedClassService service = getAdvisedService(new CountedClassService());
333+
334+
service.greet();
335+
336+
assertThatExceptionOfType(MeterNotFoundException.class)
337+
.isThrownBy(() -> meterRegistry.get("class.counted").counter());
338+
339+
assertThat(meterRegistry.get("method.counted")
340+
.tag("class", "io.micrometer.core.aop.CountedAspectTest$CountedClassService")
341+
.tag("method", "greet")
342+
.tag("result", "success")
343+
.tag("exception", "none")
344+
.counter()
345+
.count()).isEqualTo(1);
346+
}
347+
330348
@Counted("class.counted")
331349
static class CountedClassService {
332350

@@ -338,6 +356,11 @@ void fail() {
338356
throw new RuntimeException("Oops");
339357
}
340358

359+
@Counted("method.counted")
360+
String greet() {
361+
return "hello";
362+
}
363+
341364
}
342365

343366
}

micrometer-core/src/test/java/io/micrometer/core/aop/TimedAspectTest.java

+24
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,26 @@ void timeClassFailure() {
374374
});
375375
}
376376

377+
@Test
378+
void ignoreClassLevelAnnotationIfMethodLevelPresent() {
379+
MeterRegistry registry = new SimpleMeterRegistry();
380+
381+
AspectJProxyFactory pf = new AspectJProxyFactory(new TimedClass());
382+
pf.addAspect(new TimedAspect(registry));
383+
384+
TimedClass service = pf.getProxy();
385+
386+
service.annotatedOnMethod();
387+
388+
assertThatExceptionOfType(MeterNotFoundException.class).isThrownBy(() -> registry.get("call").timer());
389+
assertThat(registry.get("annotatedOnMethod")
390+
.tag("class", "io.micrometer.core.aop.TimedAspectTest$TimedClass")
391+
.tag("method", "annotatedOnMethod")
392+
.tag("extra", "tag2")
393+
.timer()
394+
.count()).isEqualTo(1);
395+
}
396+
377397
static class MeterTagsTests {
378398

379399
ValueResolver valueResolver = parameter -> "Value from myCustomTagValueResolver [" + parameter + "]";
@@ -625,6 +645,10 @@ static class TimedClass {
625645
void call() {
626646
}
627647

648+
@Timed(value = "annotatedOnMethod", extraTags = { "extra", "tag2" })
649+
void annotatedOnMethod() {
650+
}
651+
628652
}
629653

630654
interface TimedInterface {

micrometer-observation/src/main/java/io/micrometer/observation/aop/ObservedAspect.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
* </pre>
6969
*
7070
* @author Jonatan Ivanov
71+
* @author Yanming Zhou
7172
* @since 1.10.0
7273
*/
7374
@Aspect
@@ -104,7 +105,7 @@ public ObservedAspect(ObservationRegistry registry,
104105
this.shouldSkip = shouldSkip;
105106
}
106107

107-
@Around("@within(io.micrometer.observation.annotation.Observed)")
108+
@Around("@within(io.micrometer.observation.annotation.Observed) and not @annotation(io.micrometer.observation.annotation.Observed)")
108109
@Nullable
109110
public Object observeClass(ProceedingJoinPoint pjp) throws Throwable {
110111
if (shouldSkip.test(pjp)) {

micrometer-observation/src/test/java/io/micrometer/observation/aop/ObservedAspectTests.java

+21
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,23 @@ void skipPredicateShouldTakeEffectForClass() {
335335
TestObservationRegistryAssert.assertThat(registry).doesNotHaveAnyObservation();
336336
}
337337

338+
@Test
339+
void ignoreClassLevelAnnotationIfMethodLevelPresent() {
340+
registry.observationConfig().observationHandler(new ObservationTextPublisher());
341+
342+
AspectJProxyFactory pf = new AspectJProxyFactory(new ObservedClassLevelAnnotatedService());
343+
pf.addAspect(new ObservedAspect(registry));
344+
345+
ObservedClassLevelAnnotatedService service = pf.getProxy();
346+
service.annotatedOnMethod();
347+
TestObservationRegistryAssert.assertThat(registry)
348+
.doesNotHaveAnyRemainingCurrentObservation()
349+
.hasSingleObservationThat()
350+
.hasBeenStopped()
351+
.hasNameEqualTo("test.class")
352+
.hasContextualNameEqualTo("test.class#annotatedOnMethod");
353+
}
354+
338355
static class ObservedService {
339356

340357
@Observed(name = "test.call", contextualName = "test#call",
@@ -387,6 +404,10 @@ CompletableFuture<String> async(FakeAsyncTask fakeAsyncTask) {
387404
contextSnapshot.wrapExecutor(Executors.newSingleThreadExecutor()));
388405
}
389406

407+
@Observed(name = "test.class", contextualName = "test.class#annotatedOnMethod")
408+
void annotatedOnMethod() {
409+
}
410+
390411
}
391412

392413
static class FakeAsyncTask implements Supplier<String> {

0 commit comments

Comments
 (0)