Passing Metadata from a Client

Decorate with MetadataUtils

In ChatClient.initChatServices(), we instantiated the authService stub. We can decorate the stub using MetadataUtils to attach additional headers:

public void initChatService() {

  Metadata metadata = new Metadata();
  metadata.put(Constant.JWT_METADATA_KEY, token);

  chatRoomService = MetadataUtils.attachHeaders(
    ChatRoomServiceGrpc.newBlockingStub(chatChannel), metadata);
  chatStreamService = ChatStreamServiceGrpc.newStub(chatChannel);
}

Now, every outgoing call from chatRoomService will have the JWT metadata attached. Let’s try it by running the client, and login as admin user, and then create a new room:

$ cd chat-cli-client
$ mvn install exec:java
-> /login admin
Jun 28, 2017 4:45:47 PM com.example.chat.ChatClient readLogin
INFO: processing login user
password> qwerty
...
INFO: initializing chat services with token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlzcyI6ImF1dGgtaXNzdWVyIn0.oQebRc48QIig1R5-JajeTCP3TWP1fThBilNpoOtKavA
[chat message] | /join [room] | /leave [room] | /create [room] | /list | /quit
admin-> /create test

On the server side, you should see the JWT token printed in the console:

INFO: Server Started on port 9092
Token: eyJ0eXAiOiJKV1QiLCJhbGci...

Metadata Client Interceptor

Alternatively, you can use a client interceptor to attach headers too. There is an out of the box interceptor to do just that. In ChatServer.initChatServices(), use the stub normally. But you can add the client interceptor to the Channel:

public void initChatService() {
...
Metadata metadata = new Metadata();
metadata.put(Constant.JWT_METADATA_KEY, token);

// TODO Add JWT Token via a Call Credential
chatChannel = ManagedChannelBuilder.forTarget("localhost:9092")
  .intercept(MetadataUtils.newAttachHeadersInterceptor(metadata))
  .usePlaintext(true)
  .build();

chatRoomService = ChatRoomServiceGrpc.newBlockingStub(chatChannel);
chatStreamService = ChatStreamServiceGrpc.newStub(chatChannel);