Override Request Initializers/Interceptors for Google Cloud Client Libraries

2021-12-15

Do not use, this is still a TODO

This is also similar to trace logging but in this case, customers would want to override our library and inject custom headers or options.

In this case, add on a gRPC per-request header to annotate why the api call was made.

For non grpc clients, here are some examples in java:

More generally, it would be helpful to know “when and why you would want to do this”

TODO

TODO

  • PubSub gRPC request initializers
package main

import (
	"context"
	"flag"
	"fmt"
	"os"

	"cloud.google.com/go/pubsub"

	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var (
	projectID = flag.String("project", "", "Project ID")
)

type clientMetadataKey string

func main() {
	flag.Parse()

	if *projectID == "" {
		fmt.Fprintln(os.Stderr, "missing -project flag")
		flag.Usage()
		os.Exit(2)
	}
	// https://cloud.google.com/service-infrastructure/docs/service-control/reference/rpc/google.rpc/context#request

	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, *projectID, option.WithGRPCDialOption(grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {

		c := ctx.Value(clientMetadataKey("reason")).(string)
		send, _ := metadata.FromOutgoingContext(ctx)
		send.Set("X-Goog-Request-Reason", c)

		ctx = metadata.NewOutgoingContext(ctx, send)
		err := invoker(ctx, method, req, reply, cc, opts...)

		return err
	})))

	if err != nil {
		fmt.Errorf("Could not create pubsub Client: %v", err)
		return
	}

	newCtx := context.WithValue(ctx, clientMetadataKey("reason"), "foo")
	topics := client.Topics(newCtx)
	for {
		topic, err := topics.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			fmt.Errorf("Error listing topics %v", err)
			return
		}
		fmt.Println(topic)
	}

	newCtx = context.WithValue(ctx, clientMetadataKey("reason"), "bar")
	topics = client.Topics(newCtx)
	for {
		topic, err := topics.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			fmt.Errorf("Error listing topics %v", err)
			return
		}
		fmt.Println(topic)
	}

}

TODO

TODO

This site supports webmentions. Send me a mention via this form.