/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.core.jsonrpc.commons; import org.eclipse.che.api.core.websocket.commons.WebSocketMessageReceiver; import org.slf4j.Logger; import javax.inject.Inject; import javax.inject.Singleton; import java.util.List; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; /** * Receives and process messages coming from web socket service. Basically * it validates, qualifies and transforms a raw web socket message to a JSON * RPC known structure and pass it further to appropriate dispatchers. In case * of any {@link JsonRpcException} happens during request/response processing * this class is also responsible for an error transmission. */ @Singleton public class JsonRpcMessageReceiver implements WebSocketMessageReceiver { private final static Logger LOGGER = getLogger(JsonRpcMessageReceiver.class); private final RequestDispatcher requestDispatcher; private final ResponseDispatcher responseDispatcher; private final JsonRpcErrorTransmitter errorTransmitter; private final JsonRpcQualifier jsonRpcQualifier; private final JsonRpcUnmarshaller jsonRpcUnmarshaller; @Inject public JsonRpcMessageReceiver(RequestDispatcher requestDispatcher, ResponseDispatcher responseDispatcher, JsonRpcErrorTransmitter errorTransmitter, JsonRpcQualifier jsonRpcQualifier, JsonRpcUnmarshaller jsonRpcUnmarshaller) { this.requestDispatcher = requestDispatcher; this.responseDispatcher = responseDispatcher; this.errorTransmitter = errorTransmitter; this.jsonRpcQualifier = jsonRpcQualifier; this.jsonRpcUnmarshaller = jsonRpcUnmarshaller; } @Override public void receive(String endpointId, String message) { checkNotNull(endpointId, "Endpoint ID must not be null"); checkArgument(!endpointId.isEmpty(), "Endpoint ID name must not be empty"); checkNotNull(message, "Message must not be null"); checkArgument(!message.isEmpty(), "Message must not be empty"); LOGGER.debug("Receiving message: " + message + ", from endpoint: " + endpointId); if (!jsonRpcQualifier.isValidJson(message)) { String error = "An error occurred on the server while parsing the JSON text"; errorTransmitter.transmit(endpointId, new JsonRpcException(-32700, error)); } List<String> messages = jsonRpcUnmarshaller.unmarshalArray(message); for (String innerMessage : messages) { if (jsonRpcQualifier.isJsonRpcRequest(innerMessage)) { processRequest(endpointId, innerMessage); } else if (jsonRpcQualifier.isJsonRpcResponse(innerMessage)) { processResponse(endpointId, innerMessage); } else { processError(); } } } private void processError() { String error = "Something wen't wrong during incoming websocket message parsing"; IllegalStateException exception = new IllegalStateException(error); LOGGER.error(error, exception); throw exception; } private void processResponse(String endpointId, String innerMessage) { JsonRpcResponse response = jsonRpcUnmarshaller.unmarshalResponse(innerMessage); responseDispatcher.dispatch(endpointId, response); } private void processRequest(String endpointId, String innerMessage) { JsonRpcRequest request = null; try { request = jsonRpcUnmarshaller.unmarshalRequest(innerMessage); requestDispatcher.dispatch(endpointId, request); } catch (JsonRpcException e) { if (request == null || request.getId() == null) { errorTransmitter.transmit(endpointId, e); } else { errorTransmitter.transmit(endpointId, new JsonRpcException(e.getCode(), e.getMessage(), request.getId())); } } } }