Repository: quarkusio/quarkus
Issue: gRPC Context propagation does not work

### Describe the bug

We use OpenTelemetry with Quarkus version of 2.9.2 that already has a support for gRPC.
We has a gRPC server that get a request with OpenTelemetry's context and the context isn't propagated to the service's handler.

In addition, I used the `GrpcTracingServerInterceptor` interceptor and saw that the interceptor gets the context. 
I think the problem is that this interceptor close the scope `scope.close()` and doesn't pass any contextual data to the handler level.

### Expected behavior

I expect to be able to use `Context.current()` inside the gRPC service's handler and get the context.

### Actual behavior

`Context.current()` returns an empty context.

### How to Reproduce?

1. Setup a gRPC service
2. Send a request with context to the service
3. Debug and look on the value of `Context.current()` inside the service's handler

### Output of `uname -a` or `ver`

Darwin ShakharArad 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:22 PDT 2022; root:xnu-8020.121.3~4/RELEASE_X86_64 x86_64

### Output of `java -version`

openjdk 14.0.2 2020-07-14 OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

2.9.2

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

------------------------------------------------------------ Gradle 7.3.3 ------------------------------------------------------------  Build time:   2021-12-22 12:37:54 UTC Revision:     6f556c80f945dc54b50e0be633da6c62dbe8dc71  Kotlin:       1.5.31 Groovy:       3.0.9 Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM:          14.0.2 (AdoptOpenJDK 14.0.2+12) OS:           Mac OS X 10.16 x86_64

### Additional information

_No response_

Changed files:
extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingClientInterceptor.java
extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/GrpcOpenTelemetryTest.java
extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingServerInterceptor.java

diff --git a/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/GrpcOpenTelemetryTest.java b/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/GrpcOpenTelemetryTest.java
index d615bcc31e0..696a27bc90f 100644
--- a/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/GrpcOpenTelemetryTest.java
+++ b/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/GrpcOpenTelemetryTest.java
@@ -1,5 +1,6 @@
 package io.quarkus.opentelemetry.deployment;
 
+import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_PEER_IP;
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_PEER_PORT;
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NET_TRANSPORT;
@@ -7,6 +8,7 @@
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.RPC_METHOD;
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.RPC_SERVICE;
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.RPC_SYSTEM;
+import static io.quarkus.opentelemetry.runtime.OpenTelemetryConfig.INSTRUMENTATION_NAME;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -24,7 +26,11 @@
 
 import io.grpc.Status;
 import io.grpc.stub.StreamObserver;
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.trace.Span;
 import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.Tracer;
 import io.opentelemetry.extension.annotations.WithSpan;
 import io.opentelemetry.sdk.trace.data.SpanData;
 import io.quarkus.grpc.GrpcClient;
@@ -67,10 +73,15 @@ void grpc() {
                 .await().atMost(Duration.ofSeconds(5));
         assertEquals("Hello Naruto", response);
 
-        List<SpanData> spans = spanExporter.getFinishedSpanItems(2);
-        assertEquals(2, spans.size());
+        List<SpanData> spans = spanExporter.getFinishedSpanItems(3);
+        assertEquals(3, spans.size());
 
-        SpanData server = spans.get(0);
+        SpanData internal = spans.get(0);
+        assertEquals("span.internal", internal.getName());
+        assertEquals(INTERNAL, internal.getKind());
+        assertEquals("value", internal.getAttributes().get(AttributeKey.stringKey("grpc.internal")));
+
+        SpanData server = spans.get(1);
         assertEquals("helloworld.Greeter/SayHello", server.getName());
         assertEquals(SpanKind.SERVER, server.getKind());
         assertEquals("grpc", server.getAttributes().get(RPC_SYSTEM));
@@ -81,7 +92,7 @@ void grpc() {
         assertNotNull(server.getAttributes().get(NET_PEER_PORT));
         assertEquals("ip_tcp", server.getAttributes().get(NET_TRANSPORT));
 
-        SpanData client = spans.get(1);
+        SpanData client = spans.get(2);
         assertEquals("helloworld.Greeter/SayHello", client.getName());
         assertEquals(SpanKind.CLIENT, client.getKind());
         assertEquals("grpc", client.getAttributes().get(RPC_SYSTEM));
@@ -89,6 +100,7 @@ void grpc() {
         assertEquals("SayHello", client.getAttributes().get(RPC_METHOD));
         assertEquals(Status.Code.OK.value(), client.getAttributes().get(RPC_GRPC_STATUS_CODE));
 
+        assertEquals(internal.getTraceId(), server.getTraceId());
         assertEquals(server.getTraceId(), client.getTraceId());
     }
 
@@ -133,11 +145,12 @@ void error() {
     void withCdi() {
         assertEquals("Hello Naruto", helloBean.hello("Naruto"));
 
-        List<SpanData> spans = spanExporter.getFinishedSpanItems(3);
-        assertEquals(3, spans.size());
+        List<SpanData> spans = spanExporter.getFinishedSpanItems(4);
+        assertEquals(4, spans.size());
 
         assertEquals(spans.get(0).getTraceId(), spans.get(1).getTraceId());
         assertEquals(spans.get(0).getTraceId(), spans.get(2).getTraceId());
+        assertEquals(spans.get(0).getTraceId(), spans.get(3).getTraceId());
     }
 
     @GrpcService
@@ -149,6 +162,13 @@ public void sayHello(final HelloRequest request, final StreamObserver<HelloReply
                 return;
             }
 
+            Tracer tracer = GlobalOpenTelemetry.getTracer(INSTRUMENTATION_NAME);
+            Span span = tracer.spanBuilder("span.internal")
+                    .setSpanKind(INTERNAL)
+                    .setAttribute("grpc.internal", "value")
+                    .startSpan();
+            span.end();
+
             responseObserver.onNext(HelloReply.newBuilder().setMessage("Hello " + request.getName()).build());
             responseObserver.onCompleted();
         }
diff --git a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingClientInterceptor.java b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingClientInterceptor.java
index 6b054906ee8..aa63e542a40 100644
--- a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingClientInterceptor.java
+++ b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingClientInterceptor.java
@@ -49,22 +49,16 @@ public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
 
         GrpcRequest grpcRequest = GrpcRequest.client(method);
         Context parentContext = Context.current();
-        Context spanContext = null;
-        Scope scope = null;
         boolean shouldStart = instrumenter.shouldStart(parentContext, grpcRequest);
         if (shouldStart) {
-            spanContext = instrumenter.start(parentContext, grpcRequest);
-            scope = spanContext.makeCurrent();
-        }
-
-        try {
-            ClientCall<ReqT, RespT> clientCall = next.newCall(method, callOptions);
-            return new TracingClientCall<>(clientCall, spanContext, grpcRequest);
-        } finally {
-            if (scope != null) {
-                scope.close();
+            Context spanContext = instrumenter.start(parentContext, grpcRequest);
+            try (Scope ignored = spanContext.makeCurrent()) {
+                ClientCall<ReqT, RespT> clientCall = next.newCall(method, callOptions);
+                return new TracingClientCall<>(clientCall, spanContext, grpcRequest);
             }
         }
+
+        return next.newCall(method, callOptions);
     }
 
     private enum GrpcTextMapSetter implements TextMapSetter<GrpcRequest> {
diff --git a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingServerInterceptor.java b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingServerInterceptor.java
index 959188539fe..9166bd10329 100644
--- a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingServerInterceptor.java
+++ b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/grpc/GrpcTracingServerInterceptor.java
@@ -53,22 +53,16 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
 
         GrpcRequest grpcRequest = GrpcRequest.server(call.getMethodDescriptor(), headers, call.getAttributes());
         Context parentContext = Context.current();
-        Context spanContext = null;
-        Scope scope = null;
         boolean shouldStart = instrumenter.shouldStart(parentContext, grpcRequest);
         if (shouldStart) {
-            spanContext = instrumenter.start(parentContext, grpcRequest);
-            scope = spanContext.makeCurrent();
-        }
-
-        try {
-            TracingServerCall<ReqT, RespT> tracingServerCall = new TracingServerCall<>(call, spanContext, grpcRequest);
-            return new TracingServerCallListener<>(next.startCall(tracingServerCall, headers), spanContext, grpcRequest);
-        } finally {
-            if (scope != null) {
-                scope.close();
+            Context spanContext = instrumenter.start(parentContext, grpcRequest);
+            try (Scope ignored = spanContext.makeCurrent()) {
+                TracingServerCall<ReqT, RespT> tracingServerCall = new TracingServerCall<>(call, spanContext, grpcRequest);
+                return new TracingServerCallListener<>(next.startCall(tracingServerCall, headers), spanContext, grpcRequest);
             }
         }
+
+        return next.startCall(call, headers);
     }
 
     private static class GrpcServerNetServerAttributesGetter extends InetSocketAddressNetServerAttributesGetter<GrpcRequest> {
@@ -116,7 +110,7 @@ protected TracingServerCallListener(final ServerCall.Listener<ReqT> delegate, fi
 
         @Override
         public void onHalfClose() {
-            try {
+            try (Scope ignored = spanContext.makeCurrent()) {
                 super.onHalfClose();
             } catch (Exception e) {
                 instrumenter.end(spanContext, grpcRequest, null, e);
@@ -126,18 +120,18 @@ public void onHalfClose() {
 
         @Override
         public void onCancel() {
-            try {
+            try (Scope ignored = spanContext.makeCurrent()) {
                 super.onCancel();
+                instrumenter.end(spanContext, grpcRequest, Status.CANCELLED, null);
             } catch (Exception e) {
                 instrumenter.end(spanContext, grpcRequest, null, e);
                 throw e;
             }
-            instrumenter.end(spanContext, grpcRequest, Status.CANCELLED, null);
         }
 
         @Override
         public void onComplete() {
-            try {
+            try (Scope ignored = spanContext.makeCurrent()) {
                 super.onComplete();
             } catch (Exception e) {
                 instrumenter.end(spanContext, grpcRequest, null, e);
@@ -147,7 +141,7 @@ public void onComplete() {
 
         @Override
         public void onReady() {
-            try {
+            try (Scope ignored = spanContext.makeCurrent()) {
                 super.onReady();
             } catch (Exception e) {
                 instrumenter.end(spanContext, grpcRequest, null, e);