Repository: yidongnan/grpc-spring-boot-starter (java)

Issue:
Upgrade Micrometer to latest release
The version of Micrometer currently building with this project is old and doesn't contain the new tracing/observation APIs. If we upgrade to 1.10.3 (or later) there shouldn't be any problems for the build or for existing users because existing APIs are unchanged, and it will clear a path to supporting Spring Boot 3 properly.

Pull request:
Bump micrometer version to latest
Fixes #828

Patch:
diff --git a/.gitignore b/.gitignore
index a53f2903..99fbe20d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,7 @@ bin/
 .settings/
 .factorypath
 .checkstyle
+
+## VSCode
+.vscode/
+.devcontainer/
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 90beab54..e994e03a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -187,8 +187,8 @@ allprojects { project ->
         }
 
         ext {
+            // not explicitly needed in subprojects, as the BOM for Spring Boot sets this version
             micrometerVersion = dependencyManagement.importedProperties['micrometer.version']
-            // not explicitly needed in subprojects, as the BOM for Sprint Boot sets this version
             springFrameworkVersion = dependencyManagement.importedProperties['spring-framework.version']
             springSecurityVersion = dependencyManagement.importedProperties['spring-security.version']
             springCloudCommonsVersion = dependencyManagement.importedProperties['spring-cloud-commons.version']
diff --git a/grpc-client-spring-boot-autoconfigure/build.gradle b/grpc-client-spring-boot-autoconfigure/build.gradle
index 393139f1..17662d2c 100644
--- a/grpc-client-spring-boot-autoconfigure/build.gradle
+++ b/grpc-client-spring-boot-autoconfigure/build.gradle
@@ -16,6 +16,7 @@ dependencies {
     api project(':grpc-common-spring-boot')
     api 'org.springframework.boot:spring-boot-starter'
     api 'jakarta.validation:jakarta.validation-api'
+    optionalSupportImplementation "io.micrometer:micrometer-observation"
     optionalSupportImplementation 'org.springframework.boot:spring-boot-starter-actuator'
     optionalSupportImplementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
     optionalSupportImplementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
diff --git a/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/autoconfigure/GrpcClientMicrometerTraceAutoConfiguration.java b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/autoconfigure/GrpcClientMicrometerTraceAutoConfiguration.java
new file mode 100644
index 00000000..f53d3f3c
--- /dev/null
+++ b/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/autoconfigure/GrpcClientMicrometerTraceAutoConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016-2022 Michael Zhang <yidongnan@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.devh.boot.grpc.client.autoconfigure;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+
+import io.grpc.ClientInterceptor;
+import io.micrometer.core.instrument.binder.grpc.ObservationGrpcClientInterceptor;
+import io.micrometer.observation.ObservationRegistry;
+import net.devh.boot.grpc.client.interceptor.GrpcGlobalClientInterceptor;
+import net.devh.boot.grpc.common.util.InterceptorOrder;
+
+/**
+ * The configuration used to configure micrometer tracing for grpc.
+ *
+ * @author Dave Syer (dsyer@vmware.com)
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnProperty(value = "management.tracing.grpc.enabled", matchIfMissing = true)
+@AutoConfigureAfter(name = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")
+@ConditionalOnBean(ObservationRegistry.class)
+public class GrpcClientMicrometerTraceAutoConfiguration {
+
+    /**
+     * Configures a global client interceptor that applies micrometer tracing logic to the requests.
+     *
+     * @param observations The observation registry bean.
+     * @return The tracing client interceptor bean.
+     */
+    @GrpcGlobalClientInterceptor
+    @Order(InterceptorOrder.ORDER_TRACING_METRICS + 1)
+    ClientInterceptor globalObservationClientInterceptorConfigurer(final ObservationRegistry observations) {
+        return new ObservationGrpcClientInterceptor(observations);
+    }
+
+}
diff --git a/grpc-client-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/grpc-client-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 5da13695..c43842c1 100644
--- a/grpc-client-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/grpc-client-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,5 +1,6 @@
 net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration
 net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration
 net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration
+net.devh.boot.grpc.client.autoconfigure.GrpcClientMicrometerTraceAutoConfiguration
 net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration
 net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration
diff --git a/grpc-server-spring-boot-autoconfigure/build.gradle b/grpc-server-spring-boot-autoconfigure/build.gradle
index 3b437e34..c3f39af1 100644
--- a/grpc-server-spring-boot-autoconfigure/build.gradle
+++ b/grpc-server-spring-boot-autoconfigure/build.gradle
@@ -15,6 +15,7 @@ dependencies {
 
     api project(':grpc-common-spring-boot')
     api 'org.springframework.boot:spring-boot-starter'
+    optionalSupportImplementation "io.micrometer:micrometer-observation"
     optionalSupportImplementation 'org.springframework.boot:spring-boot-starter-actuator'
     optionalSupportImplementation 'org.springframework.security:spring-security-core'
     optionalSupportImplementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
diff --git a/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/autoconfigure/GrpcServerMicrometerTraceAutoConfiguration.java b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/autoconfigure/GrpcServerMicrometerTraceAutoConfiguration.java
new file mode 100644
index 00000000..1e6dd786
--- /dev/null
+++ b/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/autoconfigure/GrpcServerMicrometerTraceAutoConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016-2022 Michael Zhang <yidongnan@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.devh.boot.grpc.server.autoconfigure;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+
+import io.grpc.ServerInterceptor;
+import io.micrometer.core.instrument.binder.grpc.ObservationGrpcServerInterceptor;
+import io.micrometer.observation.ObservationRegistry;
+import net.devh.boot.grpc.common.util.InterceptorOrder;
+import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor;
+
+/**
+ * The configuration used to configure micrometer tracing for grpc.
+ *
+ * @author Dave Syer (dsyer@vmware.com)
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnProperty(value = "management.tracing.grpc.enabled", matchIfMissing = true)
+@AutoConfigureAfter(name = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")
+@ConditionalOnBean(ObservationRegistry.class)
+public class GrpcServerMicrometerTraceAutoConfiguration {
+
+    /**
+     * Configures a global server interceptor that applies micrometer tracing logic to the requests.
+     *
+     * @param observations The observation registry.
+     * @return The tracing server interceptor bean.
+     */
+    @GrpcGlobalServerInterceptor
+    @Order(InterceptorOrder.ORDER_TRACING_METRICS + 1)
+    public ServerInterceptor globalObservationGrpcServerInterceptorConfigurer(final ObservationRegistry observations) {
+        return new ObservationGrpcServerInterceptor(observations);
+    }
+
+}
diff --git a/grpc-server-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/grpc-server-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index e2487bf3..a5503fe6 100644
--- a/grpc-server-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/grpc-server-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -8,4 +8,5 @@ net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration
 net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration
 net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration
 net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration
+net.devh.boot.grpc.server.autoconfigure.GrpcServerMicrometerTraceAutoConfiguration
 net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration


Test patch:
diff --git a/tests/src/test/java/net/devh/boot/grpc/test/interceptor/DefaultServerInterceptorTest.java b/tests/src/test/java/net/devh/boot/grpc/test/interceptor/DefaultServerInterceptorTest.java
index 7745c8af..04ae9564 100644
--- a/tests/src/test/java/net/devh/boot/grpc/test/interceptor/DefaultServerInterceptorTest.java
+++ b/tests/src/test/java/net/devh/boot/grpc/test/interceptor/DefaultServerInterceptorTest.java
@@ -34,6 +34,7 @@
 
 import io.grpc.ServerInterceptor;
 import io.micrometer.core.instrument.binder.grpc.MetricCollectingServerInterceptor;
+import io.micrometer.core.instrument.binder.grpc.ObservationGrpcServerInterceptor;
 import net.devh.boot.grpc.server.interceptor.GlobalServerInterceptorRegistry;
 import net.devh.boot.grpc.server.scope.GrpcRequestScope;
 import net.devh.boot.grpc.server.security.interceptors.AuthenticatingServerInterceptor;
@@ -63,6 +64,7 @@ void testOrderingOfTheDefaultInterceptors() {
         final List<ServerInterceptor> expected = new ArrayList<>();
         expected.add(this.applicationContext.getBean(GrpcRequestScope.class));
         expected.add(this.applicationContext.getBean(MetricCollectingServerInterceptor.class));
+        expected.add(this.applicationContext.getBean(ObservationGrpcServerInterceptor.class));
         expected.add(this.applicationContext.getBean(ExceptionTranslatingServerInterceptor.class));
         expected.add(this.applicationContext.getBean(AuthenticatingServerInterceptor.class));
         expected.add(this.applicationContext.getBean(AuthorizationCheckingServerInterceptor.class));