aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java')
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java94
1 files changed, 94 insertions, 0 deletions
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
new file mode 100644
index 00000000..25f67545
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
@@ -0,0 +1,94 @@
1package tools.refinery.language.web.xtext.servlet;
2
3import java.io.IOException;
4import java.io.Reader;
5
6import org.eclipse.jetty.websocket.api.Session;
7import org.eclipse.jetty.websocket.api.StatusCode;
8import org.eclipse.jetty.websocket.api.WriteCallback;
9import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
10import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
11import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
12import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
13import org.eclipse.jetty.websocket.api.annotations.WebSocket;
14import org.eclipse.xtext.resource.IResourceServiceProvider;
15import org.eclipse.xtext.web.server.ISession;
16import org.slf4j.Logger;
17import org.slf4j.LoggerFactory;
18
19import com.google.gson.Gson;
20import com.google.gson.JsonIOException;
21import com.google.gson.JsonParseException;
22
23@WebSocket
24public class XtextWebSocket {
25 private static final Logger LOG = LoggerFactory.getLogger(XtextWebSocket.class);
26
27 private final Gson gson = new Gson();
28
29 private final TransactionExecutor executor;
30
31 public XtextWebSocket(TransactionExecutor executor) {
32 this.executor = executor;
33 }
34
35 public XtextWebSocket(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) {
36 this(new TransactionExecutor(session, resourceServiceProviderRegistry));
37 }
38
39 @OnWebSocketConnect
40 public void onConnect(Session webSocketSession) {
41 LOG.debug("New websocket connection from {}", webSocketSession.getRemoteAddress());
42 }
43
44 @OnWebSocketClose
45 public void onClose(Session webSocketSession, int statusCode, String reason) {
46 if (statusCode == StatusCode.NORMAL) {
47 LOG.debug("{} closed connection normally: {}", webSocketSession.getRemoteAddress(), reason);
48 } else {
49 LOG.warn("{} closed connection with status code {}: {}", webSocketSession.getRemoteAddress(), statusCode,
50 reason);
51 }
52 }
53
54 @OnWebSocketError
55 public void onError(Session webSocketSession, Throwable error) {
56 LOG.error("Internal websocket error in connection from" + webSocketSession.getRemoteAddress(), error);
57 }
58
59 @OnWebSocketMessage
60 public void onMessage(Session webSocketSession, Reader reader) {
61 XtextWebSocketRequest request;
62 try {
63 request = gson.fromJson(reader, XtextWebSocketRequest.class);
64 } catch (JsonIOException e) {
65 LOG.error("Cannot read from websocket from" + webSocketSession.getRemoteAddress(), e);
66 if (webSocketSession.isOpen()) {
67 webSocketSession.close(StatusCode.SERVER_ERROR, "Cannot read payload");
68 }
69 return;
70 } catch (JsonParseException e) {
71 LOG.warn("Malformed websocket request from" + webSocketSession.getRemoteAddress(), e);
72 webSocketSession.close(XtextStatusCode.INVALID_JSON, "Invalid JSON payload");
73 return;
74 }
75 try {
76 executor.handleRequest(request, response -> sendResponse(webSocketSession, response));
77 } catch (IOException e) {
78 LOG.warn("Cannot initiaite async write to websocket " + webSocketSession.getRemoteAddress(), e);
79 if (webSocketSession.isOpen()) {
80 webSocketSession.close(StatusCode.SERVER_ERROR, "Cannot write payload");
81 }
82 }
83 }
84
85 protected void sendResponse(Session webSocketSession, XtextWebSocketResponse response) throws IOException {
86 var responseString = gson.toJson(response);
87 webSocketSession.getRemote().sendPartialString(responseString, true, new WriteCallback() {
88 @Override
89 public void writeFailed(Throwable x) {
90 LOG.warn("Cannot complete async write to websocket " + webSocketSession.getRemoteAddress(), x);
91 }
92 });
93 }
94}