mirror of https://github.com/dapr/dapr.git
grpc baggage
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
This commit is contained in:
parent
d6a64d8946
commit
b0e27ea2d9
|
@ -18,6 +18,7 @@ import (
|
|||
|
||||
"github.com/dapr/dapr/pkg/api/grpc/proxy/codec"
|
||||
"github.com/dapr/dapr/pkg/diagnostics"
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
"github.com/dapr/dapr/pkg/resiliency"
|
||||
"github.com/dapr/kit/utils"
|
||||
)
|
||||
|
@ -96,7 +97,7 @@ func (s *handler) handler(srv any, serverStream grpc.ServerStream) error {
|
|||
// Fetch the AppId so we can reference it for resiliency.
|
||||
ctx := serverStream.Context()
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
v := md[diagnostics.GRPCProxyAppIDKey]
|
||||
v := md[diagConsts.GRPCProxyAppIDKey]
|
||||
|
||||
// The app id check is handled in the StreamDirector. If we don't have it here, we just use a NoOp policy since we know the request is impossible.
|
||||
var policyDef *resiliency.PolicyDefinition
|
||||
|
|
|
@ -61,6 +61,25 @@ const (
|
|||
// Keys used in the context's metadata for streaming calls
|
||||
// Note: these keys must always be all-lowercase
|
||||
DaprCallLocalStreamMethodKey = "__dapr_calllocalstream_method"
|
||||
|
||||
// We have leveraged the code from opencensus-go plugin to adhere the w3c trace context.
|
||||
// Reference : https://github.com/census-instrumentation/opencensus-go/blob/master/plugin/ochttp/propagation/tracecontext/propagation.go
|
||||
// Trace context headers
|
||||
TraceparentHeader = "traceparent"
|
||||
TracestateHeader = "tracestate"
|
||||
BaggageHeader = "baggage"
|
||||
|
||||
GRPCTraceContextKey = "grpc-trace-bin"
|
||||
GRPCProxyAppIDKey = "dapr-app-id"
|
||||
|
||||
// Trace sampling constants
|
||||
SupportedVersion = 0
|
||||
MaxVersion = 254
|
||||
MaxTracestateLen = 512
|
||||
|
||||
// MaxBaggageLength is the maximum length of a baggage header according to W3C spec
|
||||
// Reverence: https://www.w3.org/TR/baggage/#limits
|
||||
MaxBaggageLength = 8192
|
||||
)
|
||||
|
||||
// GrpcAppendSpanAttributesFn is the interface that applies to gRPC requests that add span attributes.
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/dapr/dapr/pkg/api/grpc/metadata"
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
diagUtils "github.com/dapr/dapr/pkg/diagnostics/utils"
|
||||
)
|
||||
|
||||
|
@ -264,7 +265,7 @@ func (g *grpcMetrics) StreamingServerInterceptor() grpc.StreamServerInterceptor
|
|||
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||
ctx := ss.Context()
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
vals, ok := md[GRPCProxyAppIDKey]
|
||||
vals, ok := md[diagConsts.GRPCProxyAppIDKey]
|
||||
if !ok || len(vals) == 0 {
|
||||
return handler(srv, ss)
|
||||
}
|
||||
|
@ -285,7 +286,7 @@ func (g *grpcMetrics) StreamingClientInterceptor() grpc.StreamServerInterceptor
|
|||
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||
ctx := ss.Context()
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
vals, ok := md[GRPCProxyAppIDKey]
|
||||
vals, ok := md[diagConsts.GRPCProxyAppIDKey]
|
||||
if !ok || len(vals) == 0 {
|
||||
return handler(srv, ss)
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"github.com/dapr/dapr/pkg/api/grpc/metadata"
|
||||
"github.com/dapr/dapr/pkg/config"
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
)
|
||||
|
||||
type fakeProxyStream struct {
|
||||
|
@ -41,7 +42,7 @@ func (f *fakeProxyStream) Context() context.Context {
|
|||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = grpcMetadata.NewIncomingContext(ctx, grpcMetadata.New(map[string]string{GRPCProxyAppIDKey: f.appID}))
|
||||
ctx = grpcMetadata.NewIncomingContext(ctx, grpcMetadata.New(map[string]string{diagConsts.GRPCProxyAppIDKey: f.appID}))
|
||||
ctx, _ = metadata.SetMetadataInTapHandle(ctx, nil)
|
||||
return ctx
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"strings"
|
||||
|
||||
grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
otelbaggage "go.opentelemetry.io/otel/baggage"
|
||||
otelcodes "go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/grpc"
|
||||
|
@ -33,8 +34,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
GRPCTraceContextKey = "grpc-trace-bin"
|
||||
GRPCProxyAppIDKey = "dapr-app-id"
|
||||
daprInternalPrefix = "/dapr.proto.internals."
|
||||
daprRuntimePrefix = "/dapr.proto.runtime."
|
||||
daprInvokeServiceMethod = "/dapr.proto.runtime.v1.Dapr/InvokeService"
|
||||
|
@ -42,6 +41,38 @@ const (
|
|||
daprWorkflowPrefix = "/TaskHubSidecarService"
|
||||
)
|
||||
|
||||
// handleBaggage processes baggage from incoming metadata, validates it, and updates the context accordingly.
|
||||
func handleBaggage(ctx context.Context) context.Context {
|
||||
md, ok := grpcMetadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return ctx
|
||||
}
|
||||
|
||||
baggageValues, exists := md[diagConsts.BaggageHeader]
|
||||
if !exists {
|
||||
return ctx
|
||||
}
|
||||
|
||||
var validBaggage []string
|
||||
for _, b := range baggageValues {
|
||||
if diagUtils.IsValidBaggage(b) {
|
||||
if member, err := otelbaggage.Parse(b); err == nil {
|
||||
ctx = otelbaggage.ContextWithBaggage(ctx, member)
|
||||
validBaggage = append(validBaggage, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(validBaggage) > 0 {
|
||||
md[diagConsts.BaggageHeader] = []string{strings.Join(validBaggage, ",")}
|
||||
} else {
|
||||
// Remove the baggage header if no valid entries
|
||||
delete(md, diagConsts.BaggageHeader)
|
||||
}
|
||||
|
||||
return grpcMetadata.NewIncomingContext(ctx, md)
|
||||
}
|
||||
|
||||
// GRPCTraceUnaryServerInterceptor sets the trace context or starts the trace client span based on request.
|
||||
func GRPCTraceUnaryServerInterceptor(appID string, spec config.TracingSpec) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
|
||||
|
@ -51,6 +82,14 @@ func GRPCTraceUnaryServerInterceptor(appID string, spec config.TracingSpec) grpc
|
|||
prefixedMetadata map[string]string
|
||||
reqSpanAttr map[string]string
|
||||
)
|
||||
|
||||
ctx = handleBaggage(ctx)
|
||||
// set header for outgoing response headers
|
||||
md, _ := grpcMetadata.FromIncomingContext(ctx)
|
||||
if baggage, exists := md[diagConsts.BaggageHeader]; exists {
|
||||
grpc.SetHeader(ctx, grpcMetadata.Pairs(diagConsts.BaggageHeader, strings.Join(baggage, ",")))
|
||||
}
|
||||
|
||||
sc, _ := SpanContextFromIncomingGRPCMetadata(ctx)
|
||||
// This middleware is shared by internal gRPC for service invocation and API
|
||||
// so that it needs to handle separately.
|
||||
|
@ -89,7 +128,7 @@ func GRPCTraceUnaryServerInterceptor(appID string, spec config.TracingSpec) grpc
|
|||
// Add grpc-trace-bin header for all non-invocation api's
|
||||
if info.FullMethod != daprInvokeServiceMethod {
|
||||
traceContextBinary := diagUtils.BinaryFromSpanContext(span.SpanContext())
|
||||
grpc.SetHeader(ctx, grpcMetadata.Pairs(GRPCTraceContextKey, string(traceContextBinary)))
|
||||
grpc.SetHeader(ctx, grpcMetadata.Pairs(diagConsts.GRPCTraceContextKey, string(traceContextBinary)))
|
||||
}
|
||||
|
||||
UpdateSpanStatusFromGRPCError(span, err)
|
||||
|
@ -110,7 +149,12 @@ func GRPCTraceStreamServerInterceptor(appID string, spec config.TracingSpec) grp
|
|||
)
|
||||
|
||||
ctx := ss.Context()
|
||||
|
||||
ctx = handleBaggage(ctx)
|
||||
// set header, ensures consistency with traceparent and tracestate headers
|
||||
md, _ := grpcMetadata.FromIncomingContext(ctx)
|
||||
if baggage, exists := md[diagConsts.BaggageHeader]; exists {
|
||||
grpc.SetHeader(ctx, grpcMetadata.Pairs(diagConsts.BaggageHeader, strings.Join(baggage, ",")))
|
||||
}
|
||||
// This middleware is shared by multiple services and proxied requests, which need to be handled separately
|
||||
switch {
|
||||
// For gRPC service invocation, this generates ServerSpan
|
||||
|
@ -129,9 +173,9 @@ func GRPCTraceStreamServerInterceptor(appID string, spec config.TracingSpec) grp
|
|||
default:
|
||||
isProxied = true
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
vals := md.Get(GRPCProxyAppIDKey)
|
||||
vals := md.Get(diagConsts.GRPCProxyAppIDKey)
|
||||
if len(vals) == 0 {
|
||||
return fmt.Errorf("cannot proxy request: missing %s metadata", GRPCProxyAppIDKey)
|
||||
return fmt.Errorf("cannot proxy request: missing %s metadata", diagConsts.GRPCProxyAppIDKey)
|
||||
}
|
||||
// vals[0] is the target app ID
|
||||
if appID == vals[0] {
|
||||
|
@ -181,7 +225,7 @@ func GRPCTraceStreamServerInterceptor(appID string, spec config.TracingSpec) grp
|
|||
// Add grpc-trace-bin header for all non-invocation api's
|
||||
if !isProxied && info.FullMethod != daprInvokeServiceMethod {
|
||||
traceContextBinary := diagUtils.BinaryFromSpanContext(span.SpanContext())
|
||||
grpc.SetHeader(ctx, grpcMetadata.Pairs(GRPCTraceContextKey, string(traceContextBinary)))
|
||||
grpc.SetHeader(ctx, grpcMetadata.Pairs(diagConsts.GRPCTraceContextKey, string(traceContextBinary)))
|
||||
}
|
||||
|
||||
UpdateSpanStatusFromGRPCError(span, err)
|
||||
|
@ -243,7 +287,7 @@ func SpanContextFromIncomingGRPCMetadata(ctx context.Context) (trace.SpanContext
|
|||
if md, ok = metadata.FromIncomingContext(ctx); !ok {
|
||||
return sc, false
|
||||
}
|
||||
traceContext := md[GRPCTraceContextKey]
|
||||
traceContext := md[diagConsts.GRPCTraceContextKey]
|
||||
if len(traceContext) > 0 {
|
||||
sc, ok = diagUtils.SpanContextFromBinary([]byte(traceContext[0]))
|
||||
} else {
|
||||
|
@ -251,11 +295,11 @@ func SpanContextFromIncomingGRPCMetadata(ctx context.Context) (trace.SpanContext
|
|||
// as grpc-trace-bin is not yet there in OpenTelemetry unlike OpenCensus , tracking issue https://github.com/open-telemetry/opentelemetry-specification/issues/639
|
||||
// and grpc-dotnet client adheres to OpenTelemetry Spec which only supports http based traceparent header in gRPC path
|
||||
// TODO : Remove this workaround fix once grpc-dotnet supports grpc-trace-bin header. Tracking issue https://github.com/dapr/dapr/issues/1827
|
||||
traceContext = md[TraceparentHeader]
|
||||
traceContext = md[diagConsts.TraceparentHeader]
|
||||
if len(traceContext) > 0 {
|
||||
sc, ok = SpanContextFromW3CString(traceContext[0])
|
||||
if ok && len(md[TracestateHeader]) > 0 {
|
||||
ts := TraceStateFromW3CString(md[TracestateHeader][0])
|
||||
if ok && len(md[diagConsts.TracestateHeader]) > 0 {
|
||||
ts := TraceStateFromW3CString(md[diagConsts.TracestateHeader][0])
|
||||
sc.WithTraceState(*ts)
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +314,7 @@ func SpanContextToGRPCMetadata(ctx context.Context, spanContext trace.SpanContex
|
|||
return ctx
|
||||
}
|
||||
|
||||
return grpcMetadata.AppendToOutgoingContext(ctx, GRPCTraceContextKey, string(traceContextBinary))
|
||||
return grpcMetadata.AppendToOutgoingContext(ctx, diagConsts.GRPCTraceContextKey, string(traceContextBinary))
|
||||
}
|
||||
|
||||
// spanAttributesMapFromGRPC builds the span trace attributes map for gRPC calls based on given parameters as per open-telemetry specs.
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.opentelemetry.io/otel"
|
||||
otelbaggage "go.opentelemetry.io/otel/baggage"
|
||||
otelcodes "go.opentelemetry.io/otel/codes"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
@ -96,6 +97,171 @@ func TestSpanContextToGRPCMetadata(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestBaggageHeaderPropagation(t *testing.T) {
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "key1=value1,key2=value2",
|
||||
))
|
||||
|
||||
ctx = handleBaggage(ctx)
|
||||
|
||||
// ensure baggage is in the ctx
|
||||
baggage := otelbaggage.FromContext(ctx)
|
||||
assert.NotNil(t, baggage)
|
||||
|
||||
member := baggage.Member("key1")
|
||||
assert.Equal(t, "value1", member.Value())
|
||||
member = baggage.Member("key2")
|
||||
assert.Equal(t, "value2", member.Value())
|
||||
}
|
||||
|
||||
// runBaggageHeaderPropagationTest runs the same baggage tests across both types of interceptors
|
||||
func runBaggageHeaderPropagationTest(t *testing.T, interceptor interface{}) {
|
||||
// handle both types of interceptors
|
||||
var runInterceptor func(ctx context.Context) (context.Context, error)
|
||||
|
||||
fakeInfo := &grpc.UnaryServerInfo{
|
||||
FullMethod: "/dapr.proto.runtime.v1.Dapr/GetState",
|
||||
}
|
||||
fakeReq := &runtimev1pb.GetStateRequest{
|
||||
StoreName: "statestore",
|
||||
Key: "state",
|
||||
}
|
||||
|
||||
switch intercept := interceptor.(type) {
|
||||
case grpc.UnaryServerInterceptor:
|
||||
runInterceptor = func(ctx context.Context) (context.Context, error) {
|
||||
var handlerCtx context.Context
|
||||
assertHandler := func(ctx context.Context, req any) (any, error) {
|
||||
handlerCtx = ctx
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
_, err := intercept(ctx, fakeReq, fakeInfo, assertHandler)
|
||||
return handlerCtx, err
|
||||
}
|
||||
case grpc.StreamServerInterceptor:
|
||||
streamInfo := &grpc.StreamServerInfo{
|
||||
FullMethod: fakeInfo.FullMethod,
|
||||
}
|
||||
|
||||
runInterceptor = func(ctx context.Context) (context.Context, error) {
|
||||
var handlerCtx context.Context
|
||||
fakeStream := &fakeStream{ctx: ctx}
|
||||
|
||||
streamHandler := func(srv interface{}, stream grpc.ServerStream) error {
|
||||
handlerCtx = stream.Context()
|
||||
return nil
|
||||
}
|
||||
|
||||
err := intercept(nil, fakeStream, streamInfo, streamHandler)
|
||||
return handlerCtx, err
|
||||
}
|
||||
|
||||
default:
|
||||
t.Fatalf("Unsupported interceptor type %T", interceptor)
|
||||
}
|
||||
|
||||
t.Run("baggage header propagation", func(t *testing.T) {
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "key1=value1",
|
||||
))
|
||||
|
||||
handlerCtx, err := runInterceptor(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify baggage is in the context
|
||||
baggage := otelbaggage.FromContext(handlerCtx)
|
||||
assert.NotNil(t, baggage)
|
||||
member := baggage.Member("key1")
|
||||
assert.Equal(t, "value1", member.Value())
|
||||
|
||||
// Verify baggage header is set in incoming metadata
|
||||
md, ok := grpcMetadata.FromIncomingContext(handlerCtx)
|
||||
require.True(t, ok)
|
||||
bag := md.Get(diagConsts.BaggageHeader)
|
||||
require.NotEmpty(t, bag, "Expected baggage header to be set in metadata")
|
||||
assert.Equal(t, "key1=value1", bag[0])
|
||||
})
|
||||
|
||||
t.Run("empty baggage", func(t *testing.T) {
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "",
|
||||
))
|
||||
|
||||
handlerCtx, err := runInterceptor(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify empty baggage is not propagated
|
||||
md, ok := grpcMetadata.FromIncomingContext(handlerCtx)
|
||||
require.True(t, ok)
|
||||
assert.Empty(t, md.Get(diagConsts.BaggageHeader))
|
||||
})
|
||||
|
||||
t.Run("baggage with properties", func(t *testing.T) {
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "key1=value1;prop1=propvalue1,key2=value2;prop2=propvalue2",
|
||||
))
|
||||
|
||||
handlerCtx, err := runInterceptor(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
md, ok := grpcMetadata.FromIncomingContext(handlerCtx)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "key1=value1;prop1=propvalue1,key2=value2;prop2=propvalue2", md.Get(diagConsts.BaggageHeader)[0])
|
||||
})
|
||||
|
||||
t.Run("baggage with special characters", func(t *testing.T) {
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "key1=value1%20with%20spaces,key2=value2%2Fwith%2Fslashes",
|
||||
))
|
||||
|
||||
handlerCtx, err := runInterceptor(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
md, ok := grpcMetadata.FromIncomingContext(handlerCtx)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "key1=value1%20with%20spaces,key2=value2%2Fwith%2Fslashes", md.Get(diagConsts.BaggageHeader)[0])
|
||||
})
|
||||
|
||||
t.Run("invalid baggage format", func(t *testing.T) {
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "invalid-baggage",
|
||||
))
|
||||
|
||||
handlerCtx, err := runInterceptor(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// invalid baggage should not be propagated in the new context
|
||||
md, ok := grpcMetadata.FromIncomingContext(handlerCtx)
|
||||
require.True(t, ok)
|
||||
assert.Empty(t, md.Get(diagConsts.BaggageHeader))
|
||||
})
|
||||
|
||||
t.Run("multiple baggage values in header", func(t *testing.T) {
|
||||
// single baggage header with multiple values
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), grpcMetadata.Pairs(
|
||||
diagConsts.BaggageHeader, "key1=value1,key2=value2",
|
||||
))
|
||||
|
||||
handlerCtx, err := runInterceptor(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
baggage := otelbaggage.FromContext(handlerCtx)
|
||||
assert.NotNil(t, baggage)
|
||||
member := baggage.Member("key1")
|
||||
assert.Equal(t, "value1", member.Value())
|
||||
member = baggage.Member("key2")
|
||||
assert.Equal(t, "value2", member.Value())
|
||||
|
||||
// baggage headers are combined in metadata
|
||||
md, ok := grpcMetadata.FromIncomingContext(handlerCtx)
|
||||
require.True(t, ok)
|
||||
bag := md.Get(diagConsts.BaggageHeader)
|
||||
require.NotEmpty(t, bag)
|
||||
assert.Equal(t, "key1=value1,key2=value2", bag[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestGRPCTraceUnaryServerInterceptor(t *testing.T) {
|
||||
exp := newOtelFakeExporter()
|
||||
|
||||
|
@ -106,6 +272,7 @@ func TestGRPCTraceUnaryServerInterceptor(t *testing.T) {
|
|||
otel.SetTracerProvider(tp)
|
||||
|
||||
interceptor := GRPCTraceUnaryServerInterceptor("fakeAppID", config.TracingSpec{SamplingRate: "1"})
|
||||
runBaggageHeaderPropagationTest(t, interceptor)
|
||||
|
||||
testTraceParent := "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||
testSpanContext, _ := SpanContextFromW3CString(testTraceParent)
|
||||
|
@ -243,6 +410,7 @@ func TestGRPCTraceStreamServerInterceptor(t *testing.T) {
|
|||
otel.SetTracerProvider(tp)
|
||||
|
||||
interceptor := GRPCTraceStreamServerInterceptor("test", config.TracingSpec{SamplingRate: "1"})
|
||||
runBaggageHeaderPropagationTest(t, interceptor)
|
||||
|
||||
testTraceParent := "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||
testSpanContext, _ := SpanContextFromW3CString(testTraceParent)
|
||||
|
@ -380,8 +548,8 @@ func TestGRPCTraceStreamServerInterceptor(t *testing.T) {
|
|||
}
|
||||
|
||||
md := grpcMetadata.New(map[string]string{
|
||||
GRPCProxyAppIDKey: "myapp",
|
||||
"grpc-trace-bin": string(testTraceBinary),
|
||||
diagConsts.GRPCProxyAppIDKey: "myapp",
|
||||
"grpc-trace-bin": string(testTraceBinary),
|
||||
})
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), md)
|
||||
ctx, _ = metadata.SetMetadataInTapHandle(ctx, nil)
|
||||
|
@ -408,7 +576,7 @@ func TestGRPCTraceStreamServerInterceptor(t *testing.T) {
|
|||
}
|
||||
|
||||
md := grpcMetadata.New(map[string]string{
|
||||
GRPCProxyAppIDKey: "myapp",
|
||||
diagConsts.GRPCProxyAppIDKey: "myapp",
|
||||
})
|
||||
ctx := grpcMetadata.NewIncomingContext(t.Context(), md)
|
||||
ctx, _ = metadata.SetMetadataInTapHandle(ctx, nil)
|
||||
|
|
|
@ -42,7 +42,7 @@ func SpanContextToW3CString(sc trace.SpanContext) string {
|
|||
spanID := sc.SpanID()
|
||||
traceFlags := sc.TraceFlags()
|
||||
return fmt.Sprintf("%x-%x-%x-%x",
|
||||
[]byte{supportedVersion},
|
||||
[]byte{diagConsts.SupportedVersion},
|
||||
traceID[:],
|
||||
spanID[:],
|
||||
[]byte{byte(traceFlags)})
|
||||
|
@ -71,7 +71,7 @@ func SpanContextFromW3CString(h string) (sc trace.SpanContext, ok bool) {
|
|||
return trace.SpanContext{}, false
|
||||
}
|
||||
version := int(ver[0])
|
||||
if version > maxVersion {
|
||||
if version > diagConsts.MaxVersion {
|
||||
return trace.SpanContext{}, false
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ import (
|
|||
|
||||
"github.com/dapr/dapr/pkg/acl"
|
||||
grpcProxy "github.com/dapr/dapr/pkg/api/grpc/proxy"
|
||||
codec "github.com/dapr/dapr/pkg/api/grpc/proxy/codec"
|
||||
"github.com/dapr/dapr/pkg/api/grpc/proxy/codec"
|
||||
"github.com/dapr/dapr/pkg/config"
|
||||
"github.com/dapr/dapr/pkg/diagnostics"
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
invokev1 "github.com/dapr/dapr/pkg/messaging/v1"
|
||||
"github.com/dapr/dapr/pkg/proto/common/v1"
|
||||
"github.com/dapr/dapr/pkg/resiliency"
|
||||
|
@ -98,9 +98,9 @@ func nopTeardown(destroy bool) {
|
|||
func (p *proxy) intercept(ctx context.Context, fullName string) (context.Context, *grpc.ClientConn, *grpcProxy.ProxyTarget, func(destroy bool), error) {
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
|
||||
v := md[diagnostics.GRPCProxyAppIDKey]
|
||||
v := md[diagConsts.GRPCProxyAppIDKey]
|
||||
if len(v) == 0 {
|
||||
return ctx, nil, nil, nopTeardown, fmt.Errorf("failed to proxy request: required metadata %s not found", diagnostics.GRPCProxyAppIDKey)
|
||||
return ctx, nil, nil, nopTeardown, fmt.Errorf("failed to proxy request: required metadata %s not found", diagConsts.GRPCProxyAppIDKey)
|
||||
}
|
||||
|
||||
appID := v[0]
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
diag "github.com/dapr/dapr/pkg/diagnostics"
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
diagUtils "github.com/dapr/dapr/pkg/diagnostics/utils"
|
||||
internalv1pb "github.com/dapr/dapr/pkg/proto/internals/v1"
|
||||
)
|
||||
|
@ -57,11 +58,6 @@ const (
|
|||
// gRPCBinaryMetadata is the suffix of grpc metadata binary value.
|
||||
gRPCBinaryMetadataSuffix = "-bin"
|
||||
|
||||
// W3C trace correlation headers.
|
||||
traceparentHeader = "traceparent"
|
||||
tracestateHeader = "tracestate"
|
||||
tracebinMetadata = "grpc-trace-bin"
|
||||
|
||||
// DestinationIDHeader is the header carrying the value of the invoked app id.
|
||||
DestinationIDHeader = "destination-app-id"
|
||||
|
||||
|
@ -149,13 +145,13 @@ func InternalMetadataToGrpcMetadata(ctx context.Context, internalMD DaprInternal
|
|||
keyName := strings.ToLower(k)
|
||||
// get both the trace headers for HTTP/GRPC and continue
|
||||
switch keyName {
|
||||
case traceparentHeader:
|
||||
case diagConsts.TraceparentHeader:
|
||||
traceparentValue = listVal.GetValues()[0]
|
||||
continue
|
||||
case tracestateHeader:
|
||||
case diagConsts.TracestateHeader:
|
||||
tracestateValue = listVal.GetValues()[0]
|
||||
continue
|
||||
case tracebinMetadata:
|
||||
case diagConsts.GRPCTraceContextKey:
|
||||
grpctracebinValue = listVal.GetValues()[0]
|
||||
continue
|
||||
case DestinationIDHeader:
|
||||
|
@ -220,17 +216,20 @@ func InternalMetadataToHTTPHeader(ctx context.Context, internalMD DaprInternalMe
|
|||
keyName := strings.ToLower(k)
|
||||
// get both the trace headers for HTTP/GRPC and continue
|
||||
switch keyName {
|
||||
case traceparentHeader:
|
||||
case diagConsts.TraceparentHeader:
|
||||
traceparentValue = listVal.GetValues()[0]
|
||||
continue
|
||||
case tracestateHeader:
|
||||
case diagConsts.TracestateHeader:
|
||||
tracestateValue = listVal.GetValues()[0]
|
||||
continue
|
||||
case tracebinMetadata:
|
||||
case diagConsts.GRPCTraceContextKey:
|
||||
grpctracebinValue = listVal.GetValues()[0]
|
||||
continue
|
||||
case DestinationIDHeader:
|
||||
continue
|
||||
case diagConsts.BaggageHeader:
|
||||
setHeader(diagConsts.BaggageHeader, listVal.GetValues()[0])
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasSuffix(keyName, gRPCBinaryMetadataSuffix) || keyName == ContentTypeHeader {
|
||||
|
@ -387,9 +386,9 @@ func processHTTPToHTTPTraceHeaders(ctx context.Context, traceparentValue, traceS
|
|||
span := diagUtils.SpanFromContext(ctx)
|
||||
diag.SpanContextToHTTPHeaders(span.SpanContext(), setHeader)
|
||||
} else {
|
||||
setHeader(traceparentHeader, traceparentValue)
|
||||
setHeader(diagConsts.TraceparentHeader, traceparentValue)
|
||||
if traceStateValue != "" {
|
||||
setHeader(tracestateHeader, traceStateValue)
|
||||
setHeader(diagConsts.TracestateHeader, traceStateValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +409,7 @@ func processHTTPToGRPCTraceHeader(ctx context.Context, md metadata.MD, tracepare
|
|||
diag.SpanContextToHTTPHeaders(sc, func(header, value string) {
|
||||
md.Set(header, value)
|
||||
})
|
||||
md.Set(tracebinMetadata, string(diagUtils.BinaryFromSpanContext(sc)))
|
||||
md.Set(diagConsts.GRPCTraceContextKey, string(diagUtils.BinaryFromSpanContext(sc)))
|
||||
}
|
||||
|
||||
func processGRPCToGRPCTraceHeader(ctx context.Context, md metadata.MD, grpctracebinValue string) {
|
||||
|
@ -424,7 +423,7 @@ func processGRPCToGRPCTraceHeader(ctx context.Context, md metadata.MD, grpctrace
|
|||
diag.SpanContextToHTTPHeaders(sc, func(header, value string) {
|
||||
md.Set(header, value)
|
||||
})
|
||||
md.Set(tracebinMetadata, string(diagUtils.BinaryFromSpanContext(sc)))
|
||||
md.Set(diagConsts.GRPCTraceContextKey, string(diagUtils.BinaryFromSpanContext(sc)))
|
||||
} else {
|
||||
decoded, err := base64.StdEncoding.DecodeString(grpctracebinValue)
|
||||
if err == nil {
|
||||
|
@ -436,7 +435,7 @@ func processGRPCToGRPCTraceHeader(ctx context.Context, md metadata.MD, grpctrace
|
|||
md.Set(header, value)
|
||||
})
|
||||
}
|
||||
md.Set(tracebinMetadata, string(decoded))
|
||||
md.Set(diagConsts.GRPCTraceContextKey, string(decoded))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/dapr/dapr/pkg/components"
|
||||
stateLoader "github.com/dapr/dapr/pkg/components/state"
|
||||
diag "github.com/dapr/dapr/pkg/diagnostics"
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
diagUtils "github.com/dapr/dapr/pkg/diagnostics/utils"
|
||||
invokev1 "github.com/dapr/dapr/pkg/messaging/v1"
|
||||
runtimev1pb "github.com/dapr/dapr/pkg/proto/runtime/v1"
|
||||
|
@ -233,16 +234,16 @@ func (b *binding) sendBindingEventToApp(ctx context.Context, bindingName string,
|
|||
|
||||
// Check the grpc-trace-bin with fallback to traceparent.
|
||||
validTraceparent := false
|
||||
if val, ok := metadata[diag.GRPCTraceContextKey]; ok {
|
||||
if val, ok := metadata[diagConsts.GRPCTraceContextKey]; ok {
|
||||
if sc, ok := diagUtils.SpanContextFromBinary([]byte(val)); ok {
|
||||
spanContext = sc
|
||||
}
|
||||
} else if val, ok := metadata[diag.TraceparentHeader]; ok {
|
||||
} else if val, ok := metadata[diagConsts.TraceparentHeader]; ok {
|
||||
if sc, ok := diag.SpanContextFromW3CString(val); ok {
|
||||
spanContext = sc
|
||||
validTraceparent = true
|
||||
// Only parse the tracestate if we've successfully parsed the traceparent.
|
||||
if val, ok := metadata[diag.TracestateHeader]; ok {
|
||||
if val, ok := metadata[diagConsts.TracestateHeader]; ok {
|
||||
ts := diag.TraceStateFromW3CString(val)
|
||||
spanContext.WithTraceState(*ts)
|
||||
}
|
||||
|
@ -340,11 +341,13 @@ func (b *binding) sendBindingEventToApp(ctx context.Context, bindingName string,
|
|||
for k, v := range metadata {
|
||||
reqMetadata[k] = []string{v}
|
||||
}
|
||||
|
||||
req := invokev1.NewInvokeMethodRequest(path).
|
||||
WithHTTPExtension(http.MethodPost, "").
|
||||
WithRawDataBytes(data).
|
||||
WithContentType(invokev1.JSONContentType).
|
||||
WithMetadata(reqMetadata)
|
||||
|
||||
if policyDef != nil {
|
||||
req.WithReplay(policyDef.HasRetries())
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
grpcMetadata "google.golang.org/grpc/metadata"
|
||||
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
"github.com/dapr/dapr/pkg/proto/runtime/v1"
|
||||
"github.com/dapr/dapr/tests/integration/framework"
|
||||
"github.com/dapr/dapr/tests/integration/framework/client"
|
||||
|
@ -42,17 +43,24 @@ type output struct {
|
|||
daprd *daprd.Daprd
|
||||
|
||||
traceparent atomic.Bool
|
||||
baggage atomic.Bool
|
||||
}
|
||||
|
||||
func (b *output) Setup(t *testing.T) []framework.Option {
|
||||
handler := http.NewServeMux()
|
||||
handler.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||
if tp := r.Header.Get("traceparent"); tp != "" {
|
||||
if tp := r.Header.Get(diagConsts.TraceparentHeader); tp != "" {
|
||||
b.traceparent.Store(true)
|
||||
} else {
|
||||
b.traceparent.Store(false)
|
||||
}
|
||||
|
||||
if baggage := r.Header.Get(diagConsts.BaggageHeader); baggage != "" {
|
||||
b.baggage.Store(true)
|
||||
} else {
|
||||
b.baggage.Store(false)
|
||||
}
|
||||
|
||||
w.Write([]byte(`OK`))
|
||||
})
|
||||
|
||||
|
@ -83,7 +91,7 @@ func (b *output) Run(t *testing.T, ctx context.Context) {
|
|||
httpClient := client.HTTP(t)
|
||||
client := b.daprd.GRPCClient(t, ctx)
|
||||
|
||||
t.Run("no traceparent header provided", func(t *testing.T) {
|
||||
t.Run("no traceparent header or baggage provided", func(t *testing.T) {
|
||||
// invoke binding
|
||||
reqURL := fmt.Sprintf("http://localhost:%d/v1.0/bindings/http-binding-traceparent", b.daprd.HTTPPort())
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, strings.NewReader("{\"operation\":\"get\"}"))
|
||||
|
@ -93,6 +101,7 @@ func (b *output) Run(t *testing.T, ctx context.Context) {
|
|||
defer resp.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.True(t, b.traceparent.Load())
|
||||
assert.False(t, b.baggage.Load())
|
||||
|
||||
invokereq := runtime.InvokeBindingRequest{
|
||||
Name: "http-binding-traceparent",
|
||||
|
@ -104,9 +113,10 @@ func (b *output) Run(t *testing.T, ctx context.Context) {
|
|||
require.NoError(t, err)
|
||||
require.NotNil(t, invokeresp)
|
||||
assert.True(t, b.traceparent.Load())
|
||||
assert.False(t, b.baggage.Load())
|
||||
})
|
||||
|
||||
t.Run("traceparent header provided", func(t *testing.T) {
|
||||
t.Run("traceparent and baggage headers provided", func(t *testing.T) {
|
||||
// invoke binding
|
||||
ctx := t.Context()
|
||||
reqURL := fmt.Sprintf("http://localhost:%d/v1.0/bindings/http-binding-traceparent", b.daprd.HTTPPort())
|
||||
|
@ -114,13 +124,16 @@ func (b *output) Run(t *testing.T, ctx context.Context) {
|
|||
require.NoError(t, err)
|
||||
|
||||
tp := "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||
req.Header.Set("traceparent", tp)
|
||||
req.Header.Set(diagConsts.TraceparentHeader, tp)
|
||||
bag := "key1=value1,key2=value2"
|
||||
req.Header.Set(diagConsts.BaggageHeader, bag)
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.True(t, b.traceparent.Load())
|
||||
assert.True(t, b.baggage.Load())
|
||||
|
||||
invokereq := runtime.InvokeBindingRequest{
|
||||
Name: "http-binding-traceparent",
|
||||
|
@ -129,10 +142,14 @@ func (b *output) Run(t *testing.T, ctx context.Context) {
|
|||
|
||||
// invoke binding
|
||||
tp = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-02"
|
||||
ctx = grpcMetadata.AppendToOutgoingContext(ctx, "traceparent", tp)
|
||||
ctx = grpcMetadata.AppendToOutgoingContext(ctx,
|
||||
diagConsts.TraceparentHeader, tp,
|
||||
diagConsts.BaggageHeader, bag,
|
||||
)
|
||||
invokeresp, err := client.InvokeBinding(ctx, &invokereq)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, invokeresp)
|
||||
assert.True(t, b.traceparent.Load())
|
||||
assert.True(t, b.baggage.Load())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
grpcMetadata "google.golang.org/grpc/metadata"
|
||||
|
||||
diagConsts "github.com/dapr/dapr/pkg/diagnostics/consts"
|
||||
"github.com/dapr/dapr/pkg/proto/common/v1"
|
||||
"github.com/dapr/dapr/pkg/proto/runtime/v1"
|
||||
"github.com/dapr/dapr/tests/integration/framework"
|
||||
|
@ -47,16 +48,22 @@ type invoke struct {
|
|||
|
||||
traceparent atomic.Bool
|
||||
grpctracectxkey atomic.Bool
|
||||
baggage atomic.Bool
|
||||
}
|
||||
|
||||
func (i *invoke) Setup(t *testing.T) []framework.Option {
|
||||
handler := http.NewServeMux()
|
||||
handler.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||
if tp := r.Header.Get("traceparent"); tp != "" {
|
||||
if tp := r.Header.Get(diagConsts.TraceparentHeader); tp != "" {
|
||||
i.traceparent.Store(true)
|
||||
} else {
|
||||
i.traceparent.Store(false)
|
||||
}
|
||||
if baggage := r.Header.Get(diagConsts.BaggageHeader); baggage != "" {
|
||||
i.baggage.Store(true)
|
||||
} else {
|
||||
i.baggage.Store(false)
|
||||
}
|
||||
w.Write([]byte(`OK`))
|
||||
})
|
||||
|
||||
|
@ -67,11 +74,16 @@ func (i *invoke) Setup(t *testing.T) []framework.Option {
|
|||
switch in.GetMethod() {
|
||||
case "test":
|
||||
if md, ok := grpcMetadata.FromIncomingContext(ctx); ok {
|
||||
if _, exists := md["grpc-trace-bin"]; exists {
|
||||
if _, exists := md[diagConsts.GRPCTraceContextKey]; exists {
|
||||
i.grpctracectxkey.Store(true)
|
||||
} else {
|
||||
i.grpctracectxkey.Store(false)
|
||||
}
|
||||
if _, exists := md[diagConsts.BaggageHeader]; exists {
|
||||
i.baggage.Store(true)
|
||||
} else {
|
||||
i.baggage.Store(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -94,7 +106,7 @@ func (i *invoke) Run(t *testing.T, ctx context.Context) {
|
|||
httpClient := client.HTTP(t)
|
||||
client := i.daprd.GRPCClient(t, ctx)
|
||||
|
||||
t.Run("no traceparent header provided", func(t *testing.T) {
|
||||
t.Run("no traceparent header or baggage provided", func(t *testing.T) {
|
||||
// invoke both grpc & http apps
|
||||
appURL := fmt.Sprintf("http://localhost:%d/v1.0/invoke/%s/method/test", i.daprd.HTTPPort(), i.daprd.AppID())
|
||||
appreq, err := http.NewRequestWithContext(ctx, http.MethodPost, appURL, strings.NewReader("{\"operation\":\"get\"}"))
|
||||
|
@ -104,6 +116,7 @@ func (i *invoke) Run(t *testing.T, ctx context.Context) {
|
|||
defer appresp.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, appresp.StatusCode)
|
||||
assert.True(t, i.traceparent.Load())
|
||||
assert.False(t, i.baggage.Load())
|
||||
|
||||
svcreq := runtime.InvokeServiceRequest{
|
||||
Id: i.daprd.AppID(),
|
||||
|
@ -122,6 +135,7 @@ func (i *invoke) Run(t *testing.T, ctx context.Context) {
|
|||
require.NoError(t, err)
|
||||
require.NotNil(t, svcresp)
|
||||
assert.True(t, i.traceparent.Load())
|
||||
assert.False(t, i.baggage.Load())
|
||||
|
||||
grpcappreq := runtime.InvokeServiceRequest{
|
||||
Id: i.grpcdaprd.AppID(),
|
||||
|
@ -142,22 +156,26 @@ func (i *invoke) Run(t *testing.T, ctx context.Context) {
|
|||
require.NoError(t, err)
|
||||
require.NotNil(t, svcresp)
|
||||
assert.True(t, i.grpctracectxkey.Load()) // this is set for grpc, instead of traceparent
|
||||
assert.False(t, i.baggage.Load())
|
||||
})
|
||||
|
||||
t.Run("traceparent header provided", func(t *testing.T) {
|
||||
t.Run("traceparent and baggage headers provided", func(t *testing.T) {
|
||||
// invoke both grpc & http apps
|
||||
appURL := fmt.Sprintf("http://localhost:%d/v1.0/invoke/%s/method/test", i.daprd.HTTPPort(), i.daprd.AppID())
|
||||
appreq, err := http.NewRequestWithContext(ctx, http.MethodPost, appURL, strings.NewReader("{\"operation\":\"get\"}"))
|
||||
require.NoError(t, err)
|
||||
|
||||
tp := "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||
appreq.Header.Set("traceparent", tp)
|
||||
appreq.Header.Set(diagConsts.TraceparentHeader, tp)
|
||||
bag := "key1=value1,key2=value2"
|
||||
appreq.Header.Set(diagConsts.BaggageHeader, bag)
|
||||
|
||||
appresp, err := httpClient.Do(appreq)
|
||||
require.NoError(t, err)
|
||||
defer appresp.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, appresp.StatusCode)
|
||||
assert.True(t, i.traceparent.Load())
|
||||
assert.True(t, i.baggage.Load())
|
||||
|
||||
svcreq := runtime.InvokeServiceRequest{
|
||||
Id: i.daprd.AppID(),
|
||||
|
@ -173,11 +191,15 @@ func (i *invoke) Run(t *testing.T, ctx context.Context) {
|
|||
}
|
||||
|
||||
tp = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-02"
|
||||
tctx := grpcMetadata.AppendToOutgoingContext(ctx, "traceparent", tp)
|
||||
tctx := grpcMetadata.AppendToOutgoingContext(ctx,
|
||||
diagConsts.TraceparentHeader, tp,
|
||||
diagConsts.BaggageHeader, bag,
|
||||
)
|
||||
svcresp, err := client.InvokeService(tctx, &svcreq)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, svcresp)
|
||||
assert.True(t, i.traceparent.Load())
|
||||
assert.True(t, i.baggage.Load())
|
||||
|
||||
grpcappreq := runtime.InvokeServiceRequest{
|
||||
Id: i.grpcdaprd.AppID(),
|
||||
|
@ -193,11 +215,15 @@ func (i *invoke) Run(t *testing.T, ctx context.Context) {
|
|||
}
|
||||
|
||||
tp = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-03"
|
||||
tctx = grpcMetadata.AppendToOutgoingContext(tctx, "traceparent", tp)
|
||||
tctx = grpcMetadata.AppendToOutgoingContext(tctx,
|
||||
diagConsts.TraceparentHeader, tp,
|
||||
diagConsts.BaggageHeader, bag,
|
||||
)
|
||||
grpcclient := i.grpcdaprd.GRPCClient(t, tctx)
|
||||
svcresp, err = grpcclient.InvokeService(tctx, &grpcappreq)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, svcresp)
|
||||
assert.True(t, i.grpctracectxkey.Load()) // this is set for grpc, instead of traceparent
|
||||
assert.True(t, i.baggage.Load())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||
package tracing
|
||||
|
||||
import (
|
||||
_ "github.com/dapr/dapr/tests/integration/suite/daprd/tracing/baggage"
|
||||
_ "github.com/dapr/dapr/tests/integration/suite/daprd/tracing/binding"
|
||||
_ "github.com/dapr/dapr/tests/integration/suite/daprd/tracing/serviceinvocation"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue