Skip to content

Commit

Permalink
Merge pull request #378 from monstermunchkin/grpc-external-dependencies
Browse files Browse the repository at this point in the history
grpc: Add external dependencies to context
  • Loading branch information
monstermunchkin authored Aug 30, 2024
2 parents 68dbe32 + 3503b4c commit 3c3440d
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 20 deletions.
12 changes: 9 additions & 3 deletions grpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"

"github.com/pace/bricks/http/middleware"
"github.com/pace/bricks/http/security"
"github.com/pace/bricks/locale"
"github.com/pace/bricks/maintenance/log"
Expand Down Expand Up @@ -72,14 +73,19 @@ func dialCtx(ctx context.Context, addr string) (*grpc.ClientConn, error) {

func prepareClientContext(ctx context.Context) context.Context {
if loc, ok := locale.FromCtx(ctx); ok {
ctx = metadata.AppendToOutgoingContext(ctx, "locale", loc.Serialize())
ctx = metadata.AppendToOutgoingContext(ctx, MetadataKeyLocale, loc.Serialize())
}
if token, ok := security.GetTokenFromContext(ctx); ok {
ctx = metadata.AppendToOutgoingContext(ctx, "bearer_token", token.GetValue())
ctx = metadata.AppendToOutgoingContext(ctx, MetadataKeyBearerToken, token.GetValue())
}
if reqID := log.RequestIDFromContext(ctx); reqID != "" {
ctx = metadata.AppendToOutgoingContext(ctx, "req_id", reqID)
ctx = metadata.AppendToOutgoingContext(ctx, MetadataKeyRequestID, reqID)
}
ctx = EncodeContextWithUTMData(ctx)

if dep := middleware.ExternalDependencyContextFromContext(ctx); dep != nil {
ctx = metadata.AppendToOutgoingContext(ctx, MetadataKeyExternalDependencies, dep.String())
}

return ctx
}
9 changes: 9 additions & 0 deletions grpc/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package grpc

const (
MetadataKeyBearerToken = "bearer_token"
MetadataKeyContentType = "content-type"
MetadataKeyExternalDependencies = "external_dependencies"
MetadataKeyLocale = "locale"
MetadataKeyRequestID = "req_id"
)
26 changes: 19 additions & 7 deletions grpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"github.com/pace/bricks/http/middleware"
"github.com/pace/bricks/http/security"
"github.com/pace/bricks/locale"
"github.com/pace/bricks/maintenance/errors"
Expand Down Expand Up @@ -151,7 +152,7 @@ func prepareContext(ctx context.Context) (context.Context, metadata.MD) {

// add request context if req_id is given
var reqID xid.ID
if ri := md.Get("req_id"); len(ri) > 0 {
if ri := md.Get(MetadataKeyRequestID); len(ri) > 0 {
var err error
reqID, err = xid.FromString(ri[0])
if err != nil {
Expand All @@ -174,7 +175,7 @@ func prepareContext(ctx context.Context) (context.Context, metadata.MD) {
})

// handle locale
if l := md.Get("locale"); len(l) > 0 {
if l := md.Get(MetadataKeyLocale); len(l) > 0 {
loc, err := locale.ParseLocale(l[0])
if err != nil {
log.Ctx(ctx).Debug().Err(err).Msgf("unable to parse locale: %v", err)
Expand All @@ -186,13 +187,24 @@ func prepareContext(ctx context.Context) (context.Context, metadata.MD) {
ctx = ContextWithUTMFromMetadata(ctx, md)

// add security context if bearer token is given
if bt := md.Get("bearer_token"); len(bt) > 0 {
if bt := md.Get(MetadataKeyBearerToken); len(bt) > 0 {
ctx = security.ContextWithToken(ctx, security.TokenString(bt[0]))
}
delete(md, "content-type")
delete(md, "locale")
delete(md, "bearer_token")
delete(md, "req_id")

// add external dependencies to context
externalDependencyContext := middleware.ExternalDependencyContext{}

if externalDependencies := md.Get(MetadataKeyExternalDependencies); len(externalDependencies) > 0 {
externalDependencyContext.Parse(externalDependencies[0])
}

ctx = middleware.ContextWithExternalDependency(ctx, &externalDependencyContext)

delete(md, MetadataKeyContentType)
delete(md, MetadataKeyLocale)
delete(md, MetadataKeyBearerToken)
delete(md, MetadataKeyRequestID)
delete(md, MetadataKeyExternalDependencies)

return ctx, md
}
40 changes: 31 additions & 9 deletions grpc/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"context"
"testing"

"github.com/pace/bricks/http/middleware"
"github.com/pace/bricks/locale"
"github.com/pace/bricks/maintenance/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/metadata"
)

Expand All @@ -29,14 +31,14 @@ func TestPrepareContext(t *testing.T) {

// remote site is providing data using a bearer token
ctx = metadata.NewIncomingContext(ctx, metadata.MD{
"req_id": []string{"c690uu0ta2rv348epm8g"},
"locale": []string{"fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5|Europe/Paris"},
"bearer_token": []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"},
MetadataKeyRequestID: []string{"c690uu0ta2rv348epm8g"},
MetadataKeyLocale: []string{"fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5|Europe/Paris"},
MetadataKeyBearerToken: []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"},
})

ctx1, md := prepareContext(ctx)
assert.Len(t, md.Get("req_id"), 0)
assert.Len(t, md.Get("bearer_token"), 0)
assert.Len(t, md.Get(MetadataKeyRequestID), 0)
assert.Len(t, md.Get(MetadataKeyBearerToken), 0)
assert.Equal(t, "c690uu0ta2rv348epm8g", log.RequestIDFromContext(ctx1))
loc, ok := locale.FromCtx(ctx1)
assert.True(t, ok)
Expand All @@ -51,13 +53,13 @@ func TestPrepareContext(t *testing.T) {

// remote site is providing data using a bearer token
ctx = metadata.NewIncomingContext(ctx, metadata.MD{
"req_id": []string{"c690uu0ta2rv348epm8g"},
"bearer_token": []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"},
MetadataKeyRequestID: []string{"c690uu0ta2rv348epm8g"},
MetadataKeyBearerToken: []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"},
})

ctx2, md := prepareContext(ctx)
assert.Len(t, md.Get("req_id"), 0)
assert.Len(t, md.Get("bearer_token"), 0)
assert.Len(t, md.Get(MetadataKeyRequestID), 0)
assert.Len(t, md.Get(MetadataKeyBearerToken), 0)
assert.Equal(t, "c690uu0ta2rv348epm8g", log.RequestIDFromContext(ctx1))

var buf2 bytes.Buffer
Expand All @@ -67,4 +69,24 @@ func TestPrepareContext(t *testing.T) {
assert.Contains(t, buf2.String(), ",\"message\":\"test\"}\n")
_, ok = locale.FromCtx(ctx2)
assert.False(t, ok)

ctx = metadata.NewIncomingContext(ctx, metadata.MD{
MetadataKeyExternalDependencies: []string{"foo:60000,bar:1000"},
})

ctx3, md := prepareContext(ctx)
assert.Len(t, md.Get(MetadataKeyExternalDependencies), 0)

externalDependencyContext := middleware.ExternalDependencyContextFromContext(ctx3)
require.NotNil(t, externalDependencyContext)
assert.Equal(t, "foo:60000,bar:1000", externalDependencyContext.String())

ctx = metadata.NewIncomingContext(context.Background(), metadata.MD{})

ctx4, md := prepareContext(ctx)
assert.Len(t, md.Get(MetadataKeyExternalDependencies), 0)

externalDependencyContext = middleware.ExternalDependencyContextFromContext(ctx4)
require.NotNil(t, externalDependencyContext)
assert.Empty(t, externalDependencyContext.String())
}
5 changes: 4 additions & 1 deletion pkg/context/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ func Transfer(in context.Context) context.Context {
out = utm.ContextTransfer(in, out)
out = hlog.ContextTransfer(in, out)
out = TransferTracingContext(in, out)
return locale.ContextTransfer(in, out)
out = locale.ContextTransfer(in, out)
out = TransferExternalDependencyContext(in, out)

return out
}

func TransferTracingContext(in, out context.Context) context.Context {
Expand Down

0 comments on commit 3c3440d

Please sign in to comment.