package org.yamcs.web.websocket; import java.io.IOException; import java.io.InputStream; import org.yamcs.api.ws.WSConstants; import org.yamcs.protobuf.Web.WebSocketClientMessage; import com.google.protobuf.ByteString; import com.google.protobuf.MessageLite; import io.protostuff.Schema; /** * Decodes an incoming web socket message using protobuf. */ public class ProtobufDecoder implements WebSocketDecoder { @Override public WebSocketDecodeContext decodeMessage(InputStream in) throws WebSocketException { int requestId = WSConstants.NO_REQUEST_ID; try { WebSocketClientMessage request = WebSocketClientMessage.parseFrom(in); if (!request.hasSequenceNumber()) throw new WebSocketException(requestId, "sequenceNumber must be specified"); requestId = request.getSequenceNumber(); if (!request.hasProtocolVersion()) throw new WebSocketException(requestId, "protocol version must be specified"); if (request.getProtocolVersion() != WSConstants.PROTOCOL_VERSION) throw new WebSocketException(requestId, "Invalid version (expected " + WSConstants.PROTOCOL_VERSION + ", but got " + request.getProtocolVersion()); if (!request.hasResource()) throw new WebSocketException(requestId, "resource must be specified"); if (!request.hasOperation()) throw new WebSocketException(requestId, "operation must be specified"); WebSocketDecodeContext ctx = new WebSocketDecodeContext(request.getProtocolVersion(), WSConstants.MESSAGE_TYPE_REQUEST, requestId, request.getResource(), request.getOperation()); if (request.hasData()) ctx.setData(request.getData()); return ctx; } catch (IOException e) { throw new WebSocketException(requestId, e); } } @Override public <T extends MessageLite.Builder> T decodeMessageData(WebSocketDecodeContext ctx, Schema<T> dataSchema) throws WebSocketException { try { T msg = dataSchema.newMessage(); msg.mergeFrom((ByteString) ctx.getData()); return msg; } catch (IOException e) { throw new WebSocketException(ctx.getRequestId(), e); } } }