Define the Metadata¶
All Metadata is strongly typed and keyed. That means, rather than using a string as a key you pass into a Map, you have to create a Metadata Key.
Open chat-service/src/main/java/com/example/chat/grpc/Constant.java to define a new metadata for transferring JWT token between services:
// TODO Add a JWT_METADATA_KEY
public static final Metadata.Key<String> JWT_METADATA_KEY =
Metadata.Key.of("jwt", ASCII_STRING_MARSHALLER);
Using Interceptors to pass Metadata¶
Capture Metadata from Server Interceptor¶
On the server side, metadata can only be captured from a server interceptor. Open chat-service/src/main/java/com/example/chat/grpc/JwtServerInterceptor.java.
Capture the JWT token and print it out:
public class JwtServerInterceptor implements ServerInterceptor {
...
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
// TODO Get token from Metadata
String token = metadata.get(Constant.JWT_METADATA_KEY);
System.out.println("Token: " + token);
return serverCallHandler.startCall(serverCall, metadata);
}
}
Attach Server Interceptor¶
Open chat-service/src/main/java/com/example/chat/grpc/ChatServer.java. The JwtServerInterceptor is already instantiated. However, we need to add it into the interceptor chain:
In the ServerBuilder, where we register existing service instances, we can modify it to apply interceptors for each of the service:
// TODO Add JWT Server Interceptor, then later, trace interceptor
final Server server = ServerBuilder.forPort(9092)
.addService(ServerInterceptors
.intercept(chatRoomService, jwtServerInterceptor))
.addService(ServerInterceptors
.intercept(chatStreamService, jwtServerInterceptor))
.build();
Now, every request sent to these services will first be intercepted by the JWTServerInterceptor.
Run the server:
$ cd chat-service
$ mvn install exec:java