package org.yamcs.web.websocket; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yamcs.management.LinkListener; import org.yamcs.management.ManagementService; import org.yamcs.protobuf.SchemaYamcsManagement; import org.yamcs.protobuf.Web.WebSocketServerMessage.WebSocketReplyData; import org.yamcs.protobuf.Yamcs.ProtoDataType; import org.yamcs.protobuf.YamcsManagement.LinkEvent; import org.yamcs.protobuf.YamcsManagement.LinkInfo; /** * Provides realtime data-link subscription via web. */ public class LinkResource extends AbstractWebSocketResource implements LinkListener { private static final Logger log = LoggerFactory.getLogger(LinkResource.class); public static final String RESOURCE_NAME = "links"; public static final String OP_subscribe = "subscribe"; public static final String OP_unsubscribe = "unsubscribe"; public LinkResource(WebSocketProcessorClient client) { super(client); } @Override public WebSocketReplyData processRequest(WebSocketDecodeContext ctx, WebSocketDecoder decoder) throws WebSocketException { switch (ctx.getOperation()) { case OP_subscribe: return subscribe(ctx.getRequestId()); case OP_unsubscribe: return unsubscribe(ctx.getRequestId()); default: throw new WebSocketException(ctx.getRequestId(), "Unsupported operation '"+ctx.getOperation()+"'"); } } private WebSocketReplyData subscribe(int requestId) throws WebSocketException { ManagementService mservice = ManagementService.getInstance(); try { WebSocketReplyData reply = toAckReply(requestId); wsHandler.sendReply(reply); for (LinkInfo linkInfo : mservice.getLinkInfo()) { sendLinkInfo(LinkEvent.Type.REGISTERED, linkInfo); } mservice.addLinkListener(this); return null; } catch (IOException e) { log.error("Exception when sending data", e); return null; } } private WebSocketReplyData unsubscribe(int requestId) throws WebSocketException { ManagementService mservice = ManagementService.getInstance(); mservice.removeLinkListener(this); return toAckReply(requestId); } @Override public void quit() { ManagementService mservice = ManagementService.getInstance(); mservice.removeLinkListener(this); } @Override public void registerLink(LinkInfo linkInfo) { sendLinkInfo(LinkEvent.Type.REGISTERED, linkInfo); } @Override public void unregisterLink(String instance, String name) { // TODO Currently not handled correctly by ManagementService } @Override public void linkChanged(LinkInfo linkInfo) { sendLinkInfo(LinkEvent.Type.UPDATED, linkInfo); } private void sendLinkInfo(LinkEvent.Type type, LinkInfo linkInfo) { try { LinkEvent.Builder linkb = LinkEvent.newBuilder(); linkb.setType(type); linkb.setLinkInfo(linkInfo); wsHandler.sendData(ProtoDataType.LINK_EVENT, linkb.build(), SchemaYamcsManagement.LinkEvent.WRITE); } catch (Exception e) { log.warn("got error when sending link event, quitting", e); quit(); } } }