Reputation: 13972
I am working with contexts within grpc/java.
I am ultimately trying to
1) grab metadata attached as a header from each incoming request (cred metadata)
2) attach this to the grpc scope/context, so that I have access to it when the request comes in, server side.
It's kind of a work around for not being able to change the API as much as I would like to. Nonetheless, I have defined an Interceptor that will strip each incoming request of the metadata.
public class OnBehalfOfInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
final ServerCall<ReqT, RespT> call,
final Metadata headers,
final ServerCallHandler<ReqT, RespT> next
) {
Context ctx = Context.current();
String mayDelegate = headers.get(
Metadata.Key.of("may-delegate", Metadata.ASCII_STRING_MARSHALLER)
);
String onBehalfOf;
if (mayDelegate != null && str2bool(mayDelegate)) {
onBehalfOf = headers.get(
Metadata.Key.of("on-behalf-of", Metadata.ASCII_STRING_MARSHALLER)
);
ctx = ctx.withValue(
Context.key("on-behalf-of"),
onBehalfOf
);
}
return Contexts.interceptCall(ctx, call, headers, next);
}
}
This code attempts to find a string "on-behalf-of" and if it finds it, attaches it to the current context.
Now, when I go to debug the current Context, I am able to see the following output
Context.current().keyValueEntries.root.values[1]
result
key "on-behalf-of"
value "my id"
This was the debug output inside a .onNext() call, I was able to see the context variables as I figured I should be able to. However, I am not able to grab "keyValueEntries" while I am not in the debug run time environment. I'm guessing that it is something that the debugger provides, not necessarily a member of the Context class.
So... How do I properly get access to the variables that I had attached to the current context? I've tried a few different examples and debugged my way through them.
Context.current().get(Context.key("on-behalf-of"))
// this ^ returns null
Am I just thinking about this wrong? Is there an easier way to grab metadata off of the incoming request?
Upvotes: 3
Views: 1577
Reputation: 26414
Context.Key
uses reference equality. You should use the same Key
instance in both locations. The String passed is just a debug string. As written in the documentation:
Create a Context.Key with the given debug name. Multiple different keys may have the same name; the name is intended for debugging purposes and does not impact behavior.
Using reference equality means you can use Java visibility restrictions to limit what code has access to the context state, in the same way that's possible with ThreadLocal
.
Upvotes: 4