Skip to content

Commit 7fed50a

Browse files
committed
Polish "Auto-configure Micrometer Observations"
- Add name attribute to ConditionalOnProperty - Add autconfig to imports file - Add a few tests to cover the other autoconfig conditonals Signed-off-by: Chris Bono <[email protected]>
1 parent 61b1323 commit 7fed50a

File tree

3 files changed

+95
-28
lines changed

3 files changed

+95
-28
lines changed

spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/GrpcServerObservationAutoConfiguration.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/*
2+
* Copyright 2024-2024 the original author or authors.
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+
* https://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+
*/
116
package org.springframework.grpc.autoconfigure.server;
217

318
import io.grpc.ServerBuilder;
@@ -15,18 +30,19 @@
1530
afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")
1631
@ConditionalOnClass(value = { ObservationRegistry.class, ObservationGrpcServerInterceptor.class })
1732
@ConditionalOnBean(ObservationRegistry.class)
18-
@ConditionalOnProperty(value = "spring.grpc.server.observation.enabled", matchIfMissing = true)
33+
@ConditionalOnProperty(name = "spring.grpc.server.observation.enabled", havingValue = "true", matchIfMissing = true)
1934
public class GrpcServerObservationAutoConfiguration {
2035

36+
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
2137
@Bean
22-
public ServerInterceptor observationGrpcServerInterceptor(ObservationRegistry observationRegistry) {
38+
ServerInterceptor observationGrpcServerInterceptor(ObservationRegistry observationRegistry) {
2339
return new ObservationGrpcServerInterceptor(observationRegistry);
2440
}
2541

2642
@Bean
27-
<T extends ServerBuilder<T>> ServerBuilderCustomizer<T> metricsInterceptor(
43+
<T extends ServerBuilder<T>> ServerBuilderCustomizer<T> observationGrpcServerInterceptorCustomizer(
2844
ServerInterceptor observationGrpcServerInterceptor) {
2945
return (serverBuilder) -> serverBuilder.intercept(observationGrpcServerInterceptor);
3046
}
3147

32-
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
org.springframework.grpc.autoconfigure.server.GrpcServerFactoryAutoConfiguration
22
org.springframework.grpc.autoconfigure.server.GrpcServerAutoConfiguration
3+
org.springframework.grpc.autoconfigure.server.GrpcServerObservationAutoConfiguration
34
org.springframework.grpc.autoconfigure.client.GrpcClientAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,98 @@
1+
/*
2+
* Copyright 2024-2024 the original author or authors.
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+
* https://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+
117
package org.springframework.grpc.autoconfigure.server;
218

319
import io.grpc.ServerBuilder;
4-
import io.grpc.ServerInterceptor;
20+
import io.micrometer.core.instrument.binder.grpc.ObservationGrpcServerInterceptor;
521
import io.micrometer.observation.ObservationRegistry;
622
import org.junit.jupiter.api.Test;
23+
import org.mockito.Mockito;
24+
725
import org.springframework.boot.autoconfigure.AutoConfigurations;
26+
import org.springframework.boot.test.context.FilteredClassLoader;
827
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
928
import org.springframework.grpc.server.ServerBuilderCustomizer;
1029

1130
import static org.assertj.core.api.Assertions.assertThat;
31+
import static org.mockito.Mockito.mock;
32+
import static org.mockito.Mockito.verify;
1233

34+
/**
35+
* Tests for the {@link GrpcServerObservationAutoConfiguration}.
36+
*/
1337
class GrpcServerObservationAutoConfigurationTests {
1438

15-
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
39+
private final ApplicationContextRunner baseContextRunner = new ApplicationContextRunner()
1640
.withConfiguration(AutoConfigurations.of(GrpcServerObservationAutoConfiguration.class));
1741

42+
private ApplicationContextRunner validContextRunner() {
43+
return new ApplicationContextRunner()
44+
.withConfiguration(AutoConfigurations.of(GrpcServerObservationAutoConfiguration.class))
45+
.withBean("observationRegistry", ObservationRegistry.class, Mockito::mock);
46+
}
47+
1848
@Test
19-
void whenObservationRegistryNotProvided_thenObservationInterceptorNotConfigured() {
20-
this.contextRunner.run(context -> {
21-
assertThat(context).doesNotHaveBean(ServerBuilderCustomizer.class);
22-
});
49+
void whenObservationRegistryNotOnClasspathAutoConfigSkipped() {
50+
this.validContextRunner()
51+
.withClassLoader(new FilteredClassLoader(ObservationRegistry.class))
52+
.run((context) -> assertThat(context).doesNotHaveBean(GrpcServerObservationAutoConfiguration.class));
2353
}
2454

2555
@Test
26-
void whenObservationInterceptorConfigured_thenServerBuilderCustomizerConfigured() {
27-
this.contextRunner.withBean(ObservationRegistry.class, ObservationRegistry::create).run(context -> {
28-
assertThat(context).hasSingleBean(ServerBuilderCustomizer.class);
29-
assertThat(context).hasSingleBean(ServerInterceptor.class);
30-
ServerInterceptor interceptor = context.getBean(ServerInterceptor.class);
31-
ServerBuilderCustomizer customizer = context.getBean(ServerBuilderCustomizer.class);
32-
ServerBuilder<?> builder = org.mockito.Mockito.mock(ServerBuilder.class);
33-
customizer.customize(builder);
34-
org.mockito.Mockito.verify(builder, org.mockito.Mockito.times(1)).intercept(interceptor);
35-
});
56+
void whenObservationGrpcServerInterceptorNotOnClasspathAutoConfigSkipped() {
57+
this.validContextRunner()
58+
.withClassLoader(new FilteredClassLoader(ObservationGrpcServerInterceptor.class))
59+
.run((context) -> assertThat(context).doesNotHaveBean(GrpcServerObservationAutoConfiguration.class));
60+
}
61+
62+
@Test
63+
void whenObservationRegistryNotProvidedThenAutoConfigSkipped() {
64+
this.baseContextRunner
65+
.run(context -> assertThat(context).doesNotHaveBean(GrpcServerObservationAutoConfiguration.class));
3666
}
3767

3868
@Test
39-
void whenObservationPropertyDisabled_thenServerBuilderCustomizerNotConfigured() {
40-
this.contextRunner.withPropertyValues("spring.grpc.server.observation.enabled=false")
41-
.withBean(ObservationRegistry.class, ObservationRegistry::create)
42-
.run(context -> {
43-
assertThat(context).doesNotHaveBean(ServerBuilderCustomizer.class);
44-
assertThat(context).doesNotHaveBean(ServerInterceptor.class);
45-
});
69+
void whenObservationPropertyEnabledThenAutoConfigNotSkipped() {
70+
this.validContextRunner()
71+
.withPropertyValues("spring.grpc.server.observation.enabled=true")
72+
.run(context -> assertThat(context).hasSingleBean(GrpcServerObservationAutoConfiguration.class));
73+
}
74+
75+
@Test
76+
void whenObservationPropertyDisabledThenAutoConfigIsSkipped() {
77+
this.validContextRunner()
78+
.withPropertyValues("spring.grpc.server.observation.enabled=false")
79+
.run(context -> assertThat(context).doesNotHaveBean(GrpcServerObservationAutoConfiguration.class));
80+
}
81+
82+
@SuppressWarnings({ "rawtypes", "unchecked" })
83+
@Test
84+
void whenAllConditionsAreMetThenInterceptorConfiguredAsExpected() {
85+
this.validContextRunner().run((context) -> {
86+
assertThat(context).hasSingleBean(ObservationGrpcServerInterceptor.class);
87+
assertThat(context).hasSingleBean(ServerBuilderCustomizer.class);
88+
// ensure the customizer in fact adds the interceptor to the builder
89+
ObservationGrpcServerInterceptor serverInterceptor = context
90+
.getBean(ObservationGrpcServerInterceptor.class);
91+
ServerBuilder<?> serverBuilder = mock();
92+
ServerBuilderCustomizer serverBuilderCustomizer = context.getBean(ServerBuilderCustomizer.class);
93+
serverBuilderCustomizer.customize(serverBuilder);
94+
verify(serverBuilder).intercept(serverInterceptor);
95+
});
4696
}
4797

48-
}
98+
}

0 commit comments

Comments
 (0)