我最终要尝试
1)从每个传入请求中获取作为标头附加的元数据(cred元数据)
2)将其附加到grpc范围/上下文,以便服务器端在请求进入时可以访问它。
这是一种无法解决API的变通方法。尽管如此,我已经定义了一个拦截器,它将剥离元数据的每个传入请求。
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);
}
}
此代码尝试查找“ on-behalf-of”字符串,如果找到它,则将其附加到当前上下文。
现在,当我调试当前的Context时,我可以看到以下输出
Context.current().keyValueEntries.root.values[1]
result
key "on-behalf-of"
value "my id"
这是.onNext()调用中的调试输出,我能够看到上下文变量,正如我认为的那样。但是,当我不在调试运行时环境中时,我无法获取“ keyValueEntries”。我猜想这是调试器提供的,不一定是Context类的成员。
因此...如何正确访问附加到当前上下文的变量?我尝试了一些不同的示例,并调试了它们的方式。
Context.current().get(Context.key("on-behalf-of"))
// this ^ returns null
我只是在想这个错误吗?有没有更简单的方法可以从传入请求中获取元数据?
答案 0 :(得分:0)
Context.Key
使用引用相等。您应该在两个位置使用相同的Key
实例。传递的字符串只是调试字符串。如the documentation中所述:
使用给定的调试名称创建Context.Key。多个不同的键可能具有相同的名称;该名称仅用于调试目的,不会影响行为。
使用引用相等性意味着您可以使用Java可见性限制来限制哪些代码可以访问上下文状态,就像ThreadLocal
一样。