Skip to content

Commit

Permalink
Switch TestDocument (LSP) service to the websocket JSON-RPC (#5186)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Kuleshov authored and Roman Iuvshin committed May 26, 2017
1 parent f235e11 commit 2225b04
Show file tree
Hide file tree
Showing 50 changed files with 806 additions and 628 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,21 @@ public class JsonRpcMessageReceiver implements WebSocketMessageReceiver {
private final JsonRpcErrorTransmitter errorTransmitter;
private final JsonRpcQualifier jsonRpcQualifier;
private final JsonRpcUnmarshaller jsonRpcUnmarshaller;
private final RequestProcessor requestProcessor;

@Inject
public JsonRpcMessageReceiver(RequestDispatcher requestDispatcher,
ResponseDispatcher responseDispatcher,
JsonRpcErrorTransmitter errorTransmitter,
JsonRpcQualifier jsonRpcQualifier,
JsonRpcUnmarshaller jsonRpcUnmarshaller) {
JsonRpcUnmarshaller jsonRpcUnmarshaller,
RequestProcessor requestProcessor) {
this.requestDispatcher = requestDispatcher;
this.responseDispatcher = responseDispatcher;
this.errorTransmitter = errorTransmitter;
this.jsonRpcQualifier = jsonRpcQualifier;
this.jsonRpcUnmarshaller = jsonRpcUnmarshaller;
this.requestProcessor = requestProcessor;
}

@Override
Expand All @@ -67,7 +70,7 @@ public void receive(String endpointId, String message) {
List<String> messages = jsonRpcUnmarshaller.unmarshalArray(message);
for (String innerMessage : messages) {
if (jsonRpcQualifier.isJsonRpcRequest(innerMessage)) {
processRequest(endpointId, innerMessage);
requestProcessor.process(() -> processRequest(endpointId, innerMessage));
} else if (jsonRpcQualifier.isJsonRpcResponse(innerMessage)) {
processResponse(endpointId, innerMessage);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* 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;

/**
* Platfrom dependent implementation of of request handler processing
* algorithm.
*/
public interface RequestProcessor {
/**
* Process a runnable interface
*
* @param runnable runnable to be called for processing of a request
*/
void process(Runnable runnable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
*******************************************************************************/
package org.eclipse.che.api.core.jsonrpc.commons.reception;

import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcErrorTransmitter;
import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerManager;
import org.slf4j.Logger;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
Expand Down Expand Up @@ -43,12 +43,16 @@ public class ConsumerConfiguratorManyToNone<P> {
this.pClass = pClass;
}

public void withConsumer(BiConsumer<String, List<P>> biConsumer) {
public void withBiConsumer(BiConsumer<String, List<P>> biConsumer) {
checkNotNull(biConsumer, "Notification consumer must not be null");
LOGGER.debug("Configuring incoming request: " +
"binary consumer for method: " + method + ", " +
"params list items class: " + pClass);

handlerManager.registerManyToNone(method, pClass, biConsumer);
}

public void withConsumer(Consumer<List<P>> consumer) {
withBiConsumer((endpointId, pValue) -> consumer.accept(pValue));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerManager;
import org.slf4j.Logger;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
Expand Down Expand Up @@ -42,7 +44,7 @@ public class ConsumerConfiguratorOneToNone<P> {
this.pClass = pClass;
}

public void withConsumer(BiConsumer<String, P> biConsumer) {
public void withBiConsumer(BiConsumer<String, P> biConsumer) {
checkNotNull(biConsumer, "Notification consumer must not be null");

LOGGER.debug("Configuring incoming request binary: " +
Expand All @@ -51,4 +53,8 @@ public void withConsumer(BiConsumer<String, P> biConsumer) {

handlerManager.registerOneToNone(method, pClass, biConsumer);
}

public void withConsumer(Consumer<P> consumer) {
withBiConsumer((endpointId, pValue) -> consumer.accept(pValue));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
*******************************************************************************/
package org.eclipse.che.api.core.jsonrpc.commons.reception;

import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcErrorTransmitter;
import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerManager;
import org.slf4j.Logger;

import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
Expand Down Expand Up @@ -49,12 +49,12 @@ public class FunctionConfiguratorOneToMany<P, R> {
}

/**
* Define a function to be applied
* Define a binary function to be applied
*
* @param biFunction
* function
*/
public void withFunction(BiFunction<String, P, List<R>> biFunction) {
public void withBiFunction(BiFunction<String, P, List<R>> biFunction) {
checkNotNull(biFunction, "Request function must not be null");

LOGGER.debug("Configuring incoming request binary: " +
Expand All @@ -64,4 +64,14 @@ public void withFunction(BiFunction<String, P, List<R>> biFunction) {

handlerManager.registerOneToMany(method, pClass, rClass, biFunction);
}

/**
* Define a function to be applied
*
* @param biFunction
* function
*/
public void withFunction(Function<P, List<R>> biFunction) {
withBiFunction((s, p) -> biFunction.apply(p));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.slf4j.Logger;

import java.util.function.BiFunction;
import java.util.function.Function;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
Expand Down Expand Up @@ -48,12 +49,12 @@ public class FunctionConfiguratorOneToOne<P, R> {
}

/**
* Define a function to be applied
* Define a binary function to be applied
*
* @param biFunction
* function
*/
public void withFunction(BiFunction<String, P, R> biFunction) {
public void withBiFunction(BiFunction<String, P, R> biFunction) {
checkNotNull(biFunction, "Request function must not be null");

LOGGER.debug("Configuring incoming request binary: " +
Expand All @@ -63,4 +64,15 @@ public void withFunction(BiFunction<String, P, R> biFunction) {

handlerManager.registerOneToOne(method, pClass, rClass, biFunction);
}


/**
* Define a function to be applied
*
* @param function
* function
*/
public void withFunction(Function<P, R> function) {
withBiFunction((s, p) -> function.apply(p));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.google.inject.Provides;
import com.google.inject.assistedinject.FactoryModuleBuilder;

import org.eclipse.che.api.core.jsonrpc.commons.RequestProcessor;
import org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter;
import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcComposer;
import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcMarshaller;
Expand All @@ -34,6 +35,8 @@ protected void configure() {
bind(JsonRpcUnmarshaller.class).to(GsonJsonRpcUnmarshaller.class);
bind(JsonRpcQualifier.class).to(GsonJsonRpcQualifier.class);
bind(JsonRpcComposer.class).to(GsonJsonRpcComposer.class);

bind(RequestProcessor.class).to(ServerSideRequestProcessor.class);
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*******************************************************************************
* 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.impl;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.eclipse.che.api.core.jsonrpc.commons.RequestProcessor;
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import static java.util.concurrent.Executors.newCachedThreadPool;
import static java.util.concurrent.TimeUnit.SECONDS;

@Singleton
public class ServerSideRequestProcessor implements RequestProcessor {
private ExecutorService executorService;

@PostConstruct
private void postConstruct(){
ThreadFactory factory = new ThreadFactoryBuilder().setUncaughtExceptionHandler(LoggingUncaughtExceptionHandler.getInstance())
.setNameFormat(ServerSideRequestProcessor.class.getSimpleName())
.setDaemon(true)
.build();

executorService = newCachedThreadPool(factory);
}

@PreDestroy
private void preDestroy() {
executorService.shutdown();
try {
if (executorService.awaitTermination(5, SECONDS)) {
executorService.shutdownNow();
executorService.awaitTermination(5, SECONDS);
}
} catch (InterruptedException ie) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}

@Override
public void process(Runnable runnable) {
executorService.execute(runnable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.google.common.collect.Sets.newConcurrentHashSet;
import static java.util.Collections.emptySet;
Expand All @@ -34,7 +32,7 @@ private void configureSubscribeHandler(RequestHandlerConfigurator configurator)
.methodName("event:ws-agent-output:subscribe")
.paramsAsString()
.noResult()
.withConsumer((endpointId, workspaceId) -> {
.withBiConsumer((endpointId, workspaceId) -> {
endpointIds.putIfAbsent(endpointId, newConcurrentHashSet());
endpointIds.get(endpointId).add(workspaceId);
});
Expand All @@ -45,7 +43,7 @@ private void configureUnSubscribeHandler(RequestHandlerConfigurator configurator
.methodName("event:ws-agent-output:un-subscribe")
.paramsAsString()
.noResult()
.withConsumer((endpointId, workspaceId) -> {
.withBiConsumer((endpointId, workspaceId) -> {
endpointIds.getOrDefault(endpointId, emptySet()).remove(workspaceId);
endpointIds.entrySet().removeIf(entry -> entry.getValue().isEmpty());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.google.common.collect.Sets.newConcurrentHashSet;
import static java.util.Collections.emptySet;
Expand All @@ -33,7 +32,7 @@ private void configureSubscribeHandler(RequestHandlerConfigurator configurator)
.methodName("event:environment-output:subscribe-by-machine-name")
.paramsAsString()
.noResult()
.withConsumer((endpointId, workspaceIdPlusMachineName) -> {
.withBiConsumer((endpointId, workspaceIdPlusMachineName) -> {
endpointIds.putIfAbsent(endpointId, newConcurrentHashSet());
endpointIds.get(endpointId).add(workspaceIdPlusMachineName);
});
Expand All @@ -44,7 +43,7 @@ private void configureUnSubscribeHandler(RequestHandlerConfigurator configurator
.methodName("event:environment-output:un-subscribe-by-machine-name")
.paramsAsString()
.noResult()
.withConsumer((endpointId, workspaceIdPlusMachineName) -> {
.withBiConsumer((endpointId, workspaceIdPlusMachineName) -> {
endpointIds.getOrDefault(endpointId, emptySet()).remove(workspaceIdPlusMachineName);
endpointIds.entrySet().removeIf(entry -> entry.getValue().isEmpty());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class JsonRpcMessageReceiverTest {
JsonRpcQualifier jsonRpcQualifier;
@Mock
JsonRpcUnmarshaller jsonRpcUnmarshaller;
@Mock
RequestProcessor requestProcessor;
@InjectMocks
JsonRpcMessageReceiver jsonRpcMessageReceiver;

Expand Down Expand Up @@ -96,6 +98,6 @@ public void shouldDispatchRequestIfRequestReceived() throws Exception {

jsonRpcMessageReceiver.receive(ENDPOINT_ID, MESSAGE);

verify(requestDispatcher).dispatch(eq(ENDPOINT_ID), any(JsonRpcRequest.class));
verify(requestProcessor).process(any());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void configureHandler(RequestHandlerConfigurator configurator) {
.methodName("event:file-state-changed")
.paramsAsDto(FileStateUpdateDto.class)
.noResult()
.withConsumer(this);
.withBiConsumer(this);
}

public void inject(NotificationManager notificationManager) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void configureHandler(RequestHandlerConfigurator configurator) {
.methodName("event:project-tree-state-changed")
.paramsAsDto(ProjectTreeStateUpdateDto.class)
.noResult()
.withConsumer(this);
.withBiConsumer(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void configureHandler(RequestHandlerConfigurator configurator) {
.methodName("connected")
.paramsAsDto(ConnectedEventDto.class)
.noResult()
.withConsumer(this);
.withBiConsumer(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void configureHandler(RequestHandlerConfigurator configurator) {
.methodName("process_died")
.paramsAsDto(ProcessDiedEventDto.class)
.noResult()
.withConsumer(this);
.withBiConsumer(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void configureHandler(RequestHandlerConfigurator configurator) {
.methodName("process_started")
.paramsAsDto(ProcessStartedEventDto.class)
.noResult()
.withConsumer(this);
.withBiConsumer(this);
}

@Override
Expand Down
Loading

0 comments on commit 2225b04

Please sign in to comment.