2
votes

I'm trying to implement an example of Envoy gRPC Bridge in Java follow this https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/grpc_bridge

In the source code of example from Envoy, there is the code building the gRPC frame from grpc request, then put it as data in the http request to envoy proxy

 r = kv.GetRequest(key=key)

# Build the gRPC frame
data = r.SerializeToString()
data = pack('!cI', b'\0', len(data)) + data

resp = requests.post(HOST + "/kv.KV/Get", data=data, headers=HEADERS)

return kv.GetResponse().FromString(resp.content[5:])

But I don't know how to do the same (build the grpc frame) in Java

Please help me to know how I can do this?

You guys can find full of example code here https://github.com/envoyproxy/envoy/tree/master/examples/grpc-bridge

Thanks

2

2 Answers

1
votes

I implemented functions following this https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_http1_bridge_filter

The body should be the serialized grpc body which is:

  • 1 byte of zero (not compressed).

  • network order 4 bytes of proto message length.

  • serialized proto message.

public static byte[] serializeGRPCRequest(GeneratedMessageV3 message) {
    byte[] bytes = message.toByteArray();
    byte[] length = intToNetworkByteOrder(bytes.length);
    byte[] data = new byte[bytes.length + 5];
    data[0] = (byte) '\0';
    System.arraycopy(length, 0, data, 1, length.length);
    System.arraycopy(bytes, 0, data, 5, bytes.length);
    return data;
}

public static byte[] intToNetworkByteOrder(int num) {
    byte[] buf = new byte[4];
    for (int i = 3; i >= 0; i--) {
        buf[i] = (byte) (num & 0xff);
        num >>>= 8;
    }
    return buf;
}

Leave it here for anyone searching for the same issue

I just tried to make it work, so if you guys find anything not good in my code, please let me know :)

0
votes

You could use Java's ByteBuffer to replicate python's pack function. The python pack call pack('!cI', b'\0', len(data)) specifies to use BIG_ENDIAN byte order (ByteBuffer default) and to write a char/byte followed by a uint. So in java this would translate to:

public byte[] serializeGrpcRequest(Message message) {
  byte[] messageBytes = message.toByteArray();
  return ByteBuffer.allocate(messageBytes.length + 5)
      .put((byte) 0)
      .putInt(messageBytes.length)
      .put(messageBytes)
      .array();
}