Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
* [ENHANCEMENT] Add servicediscovery package. #469
* [ENHANCEMENT] Expose `InstancesInZoneCount` and `ZonesCount` in `ring.ReadRing` interface. #494
* [ENHANCEMENT] Add optimization to run `concurrency.ForEachJob()` with no parallelism when there's only 1 job. #486 #495
* [ENHANCEMENT] Reduced memory allocations by `user.ExtractFromGRPCRequest()`. #502
* [BUGFIX] spanlogger: Support multiple tenant IDs. #59
* [BUGFIX] Memberlist: fixed corrupted packets when sending compound messages with more than 255 messages or messages bigger than 64KB. #85
* [BUGFIX] Ring: `ring_member_ownership_percent` and `ring_tokens_owned` metrics are not updated on scale down. #109
Expand Down
9 changes: 2 additions & 7 deletions user/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@ import (
// ExtractFromGRPCRequest extracts the user ID from the request metadata and returns
// the user ID and a context with the user ID injected.
func ExtractFromGRPCRequest(ctx context.Context) (string, context.Context, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return "", ctx, ErrNoOrgID
}

orgIDs, ok := md[lowerOrgIDHeaderName]
if !ok || len(orgIDs) != 1 {
orgIDs := metadata.ValueFromIncomingContext(ctx, lowerOrgIDHeaderName)
if len(orgIDs) != 1 {
return "", ctx, ErrNoOrgID
}

Expand Down
61 changes: 61 additions & 0 deletions user/grpc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package user

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"google.golang.org/grpc/metadata"
)

func TestExtractFromGRPCRequest(t *testing.T) {
t.Run("should return error if no org ID is set in the gRPC request context", func(t *testing.T) {
inputCtx := context.Background()

_, returnedCtx, err := ExtractFromGRPCRequest(inputCtx)
assert.Equal(t, inputCtx, returnedCtx)
assert.Equal(t, ErrNoOrgID, err)
})

t.Run("should return a context with org ID injected if org ID is set in the gRPC request context", func(t *testing.T) {
inputCtx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{
lowerOrgIDHeaderName: "user-1",
}))

// Pre-condition check: no org ID should be set in the input context.
_, err := ExtractOrgID(inputCtx)
assert.Equal(t, ErrNoOrgID, err)

actualOrgID, returnedCtx, err := ExtractFromGRPCRequest(inputCtx)
assert.NotEqual(t, inputCtx, returnedCtx)
assert.NoError(t, err)
assert.Equal(t, "user-1", actualOrgID)

// Org ID should be set in the returned context.
actualOrgID, err = ExtractOrgID(returnedCtx)
assert.NoError(t, err)
assert.Equal(t, "user-1", actualOrgID)
})
}

func BenchmarkExtractFromGRPCRequest(b *testing.B) {
// The following fixture has been generated looking at the actual metadata received by Grafana Mimir.
ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{
"authority": "1.1.1.1",
"content-type": "application/grpc",
"grpc-accept-encoding": "snappy,gzip",
"uber-trace-id": "xxx",
"user-agent": "grpc-go/1.61.1",
lowerOrgIDHeaderName: "user-1",
}))

for n := 0; n < b.N; n++ {
orgID, _, err := ExtractFromGRPCRequest(ctx)
if orgID != "user-1" {
b.Fatalf("unexpected org ID: %s", orgID)
}
if err != nil {
b.Fatal(err)
}
}
}