@eclipse-glsp/server 1.1.0-RC07 → 1.1.0-RC08
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/di/app-module.d.ts +2 -7
- package/lib/browser/di/app-module.d.ts.map +1 -1
- package/lib/browser/di/app-module.js +5 -30
- package/lib/browser/di/app-module.js.map +1 -1
- package/lib/browser/index.d.ts +0 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +0 -1
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/launch/worker-server-launcher.d.ts +4 -4
- package/lib/browser/launch/worker-server-launcher.d.ts.map +1 -1
- package/lib/browser/launch/worker-server-launcher.js +5 -11
- package/lib/browser/launch/worker-server-launcher.js.map +1 -1
- package/lib/common/actions/client-action-handler.d.ts +1 -2
- package/lib/common/actions/client-action-handler.d.ts.map +1 -1
- package/lib/common/actions/client-action-handler.js +17 -2
- package/lib/common/actions/client-action-handler.js.map +1 -1
- package/lib/common/command/command-stack.d.ts +16 -1
- package/lib/common/command/command-stack.d.ts.map +1 -1
- package/lib/common/command/command-stack.js +0 -15
- package/lib/common/command/command-stack.js.map +1 -1
- package/lib/common/di/client-session-module.d.ts +1 -1
- package/lib/common/di/client-session-module.d.ts.map +1 -1
- package/lib/common/di/client-session-module.js +2 -2
- package/lib/common/di/client-session-module.js.map +1 -1
- package/lib/common/di/glsp-module.d.ts +3 -1
- package/lib/common/di/glsp-module.d.ts.map +1 -1
- package/lib/common/di/glsp-module.js +0 -15
- package/lib/common/di/glsp-module.js.map +1 -1
- package/lib/common/di/multi-binding.d.ts +19 -4
- package/lib/common/di/multi-binding.d.ts.map +1 -1
- package/lib/common/di/multi-binding.js.map +1 -1
- package/lib/common/di/server-module.d.ts +1 -6
- package/lib/common/di/server-module.d.ts.map +1 -1
- package/lib/common/di/server-module.js +21 -17
- package/lib/common/di/server-module.js.map +1 -1
- package/lib/common/index.d.ts +1 -2
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +1 -2
- package/lib/common/index.js.map +1 -1
- package/lib/common/launch/glsp-server-launcher.d.ts +1 -1
- package/lib/common/launch/glsp-server-launcher.d.ts.map +1 -1
- package/lib/common/launch/glsp-server-launcher.js +2 -2
- package/lib/common/launch/glsp-server-launcher.js.map +1 -1
- package/lib/common/launch/jsonrpc-server-launcher.d.ts +38 -0
- package/lib/common/launch/jsonrpc-server-launcher.d.ts.map +1 -0
- package/lib/common/launch/jsonrpc-server-launcher.js +84 -0
- package/lib/common/launch/jsonrpc-server-launcher.js.map +1 -0
- package/lib/common/protocol/glsp-server.d.ts +4 -104
- package/lib/common/protocol/glsp-server.d.ts.map +1 -1
- package/lib/common/protocol/glsp-server.js +13 -20
- package/lib/common/protocol/glsp-server.js.map +1 -1
- package/lib/common/protocol/glsp-server.spec.js +18 -5
- package/lib/common/protocol/glsp-server.spec.js.map +1 -1
- package/lib/common/session/client-session-factory.d.ts +1 -2
- package/lib/common/session/client-session-factory.d.ts.map +1 -1
- package/lib/common/session/client-session-factory.js +17 -2
- package/lib/common/session/client-session-factory.js.map +1 -1
- package/lib/common/session/client-session-factory.spec.js +2 -2
- package/lib/common/session/client-session-factory.spec.js.map +1 -1
- package/lib/common/session/client-session-manager.d.ts +1 -3
- package/lib/common/session/client-session-manager.d.ts.map +1 -1
- package/lib/common/session/client-session-manager.js.map +1 -1
- package/lib/common/test/mock-util.d.ts +3 -6
- package/lib/common/test/mock-util.d.ts.map +1 -1
- package/lib/common/test/mock-util.js.map +1 -1
- package/lib/{browser/di → common/utils}/console-logger.d.ts +7 -1
- package/lib/common/utils/console-logger.d.ts.map +1 -0
- package/lib/{browser/di → common/utils}/console-logger.js +26 -8
- package/lib/common/utils/console-logger.js.map +1 -0
- package/lib/common/utils/logger.d.ts +21 -0
- package/lib/common/utils/logger.d.ts.map +1 -1
- package/lib/common/utils/logger.js +12 -1
- package/lib/common/utils/logger.js.map +1 -1
- package/lib/node/di/app-module.d.ts +2 -2
- package/lib/node/di/app-module.d.ts.map +1 -1
- package/lib/node/di/app-module.js +10 -35
- package/lib/node/di/app-module.js.map +1 -1
- package/lib/node/launch/cli-parser.d.ts +2 -3
- package/lib/node/launch/cli-parser.d.ts.map +1 -1
- package/lib/node/launch/cli-parser.js.map +1 -1
- package/lib/node/launch/socket-cli-parser.js +1 -1
- package/lib/node/launch/socket-cli-parser.js.map +1 -1
- package/lib/node/launch/socket-server-launcher.d.ts +2 -23
- package/lib/node/launch/socket-server-launcher.d.ts.map +1 -1
- package/lib/node/launch/socket-server-launcher.js +8 -28
- package/lib/node/launch/socket-server-launcher.js.map +1 -1
- package/lib/node/launch/socket-server-launcher.spec.js +5 -0
- package/lib/node/launch/socket-server-launcher.spec.js.map +1 -1
- package/lib/node/launch/websocket-server-launcher.d.ts +2 -8
- package/lib/node/launch/websocket-server-launcher.d.ts.map +1 -1
- package/lib/node/launch/websocket-server-launcher.js +4 -28
- package/lib/node/launch/websocket-server-launcher.js.map +1 -1
- package/package.json +4 -4
- package/src/browser/di/app-module.ts +4 -32
- package/src/browser/index.ts +0 -1
- package/src/browser/launch/worker-server-launcher.ts +7 -13
- package/src/common/actions/client-action-handler.ts +1 -2
- package/src/common/command/command-stack.ts +1 -1
- package/src/common/di/client-session-module.ts +1 -1
- package/src/common/di/glsp-module.ts +3 -1
- package/src/common/di/multi-binding.ts +4 -5
- package/src/common/di/server-module.ts +6 -21
- package/src/common/index.ts +1 -2
- package/src/common/launch/glsp-server-launcher.ts +2 -2
- package/src/common/launch/jsonrpc-server-launcher.ts +95 -0
- package/src/common/protocol/glsp-server.spec.ts +7 -4
- package/src/common/protocol/glsp-server.ts +17 -132
- package/src/common/session/client-session-factory.spec.ts +1 -1
- package/src/common/session/client-session-factory.ts +1 -2
- package/src/common/session/client-session-manager.ts +1 -3
- package/src/common/test/mock-util.ts +5 -5
- package/src/{browser/di → common/utils}/console-logger.ts +19 -1
- package/src/common/utils/logger.ts +16 -1
- package/src/node/di/app-module.ts +4 -13
- package/src/node/launch/cli-parser.ts +2 -3
- package/src/node/launch/socket-cli-parser.ts +1 -1
- package/src/node/launch/socket-server-launcher.spec.ts +6 -0
- package/src/node/launch/socket-server-launcher.ts +8 -30
- package/src/node/launch/websocket-server-launcher.ts +5 -31
- package/lib/browser/di/console-logger.d.ts.map +0 -1
- package/lib/browser/di/console-logger.js.map +0 -1
- package/lib/common/protocol/glsp-client-proxy.d.ts +0 -45
- package/lib/common/protocol/glsp-client-proxy.d.ts.map +0 -1
- package/lib/common/protocol/glsp-client-proxy.js +0 -53
- package/lib/common/protocol/glsp-client-proxy.js.map +0 -1
- package/lib/common/protocol/glsp-server-listener.d.ts +0 -37
- package/lib/common/protocol/glsp-server-listener.d.ts.map +0 -1
- package/lib/common/protocol/glsp-server-listener.js +0 -5
- package/lib/common/protocol/glsp-server-listener.js.map +0 -1
- package/src/common/protocol/glsp-client-proxy.ts +0 -65
- package/src/common/protocol/glsp-server-listener.ts +0 -39
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2023 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
Disposable,
|
|
19
|
+
GLSPClientProxy,
|
|
20
|
+
GLSPServer,
|
|
21
|
+
JsonrpcClientProxy,
|
|
22
|
+
JsonrpcGLSPClient,
|
|
23
|
+
configureClientConnection
|
|
24
|
+
} from '@eclipse-glsp/protocol';
|
|
25
|
+
import { Container, ContainerModule, inject, injectable } from 'inversify';
|
|
26
|
+
import * as jsonrpc from 'vscode-jsonrpc';
|
|
27
|
+
import { Logger } from '../utils/logger';
|
|
28
|
+
import { GLSPServerLauncher } from './glsp-server-launcher';
|
|
29
|
+
|
|
30
|
+
export const START_UP_COMPLETE_MSG = '[GLSP-Server]:Startup completed. Accepting requests on port:';
|
|
31
|
+
|
|
32
|
+
export interface JsonRpcServerInstance {
|
|
33
|
+
server: GLSPServer;
|
|
34
|
+
clientConnection: jsonrpc.MessageConnection;
|
|
35
|
+
container: Container;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@injectable()
|
|
39
|
+
export abstract class JsonRpcGLSPServerLauncher<T> extends GLSPServerLauncher<T> {
|
|
40
|
+
@inject(Logger)
|
|
41
|
+
protected override logger: Logger;
|
|
42
|
+
|
|
43
|
+
protected serverInstances = new Map<jsonrpc.MessageConnection, JsonRpcServerInstance>();
|
|
44
|
+
protected startupCompleteMessage = START_UP_COMPLETE_MSG;
|
|
45
|
+
|
|
46
|
+
constructor() {
|
|
47
|
+
super();
|
|
48
|
+
this.toDispose.push(
|
|
49
|
+
Disposable.create(() => {
|
|
50
|
+
this.serverInstances.forEach(instance => this.disposeServerInstance(instance));
|
|
51
|
+
})
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
protected disposeServerInstance(instance: JsonRpcServerInstance): void {
|
|
56
|
+
this.serverInstances.delete(instance.clientConnection);
|
|
57
|
+
instance.server.shutdown();
|
|
58
|
+
instance.container.unbindAll();
|
|
59
|
+
instance.clientConnection.dispose();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected createServerInstance(clientConnection: jsonrpc.MessageConnection): void {
|
|
63
|
+
const container = this.createContainer(this.createJsonRpcModule(clientConnection));
|
|
64
|
+
const server = container.get<GLSPServer>(GLSPServer);
|
|
65
|
+
const instance = { container, clientConnection, server };
|
|
66
|
+
this.serverInstances.set(clientConnection, instance);
|
|
67
|
+
this.configureClientConnection(instance);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
protected createJsonRpcModule(clientConnection: jsonrpc.MessageConnection): ContainerModule {
|
|
71
|
+
return new ContainerModule(bind => {
|
|
72
|
+
bind(GLSPClientProxy).toDynamicValue(ctx => {
|
|
73
|
+
const proxy = ctx.container.resolve(JsonrpcClientProxy);
|
|
74
|
+
proxy.initialize(clientConnection);
|
|
75
|
+
return proxy;
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected configureClientConnection(serverInstance: JsonRpcServerInstance): void {
|
|
81
|
+
configureClientConnection(serverInstance.clientConnection, serverInstance.server);
|
|
82
|
+
|
|
83
|
+
serverInstance.clientConnection.onNotification(JsonrpcGLSPClient.ShutdownNotification, () =>
|
|
84
|
+
this.disposeServerInstance(serverInstance)
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
this.logger.info('Starting GLSP server connection');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
protected createClientProxy(serverInstance: JsonRpcServerInstance): GLSPClientProxy {
|
|
91
|
+
const proxy = serverInstance.container.resolve(JsonrpcClientProxy);
|
|
92
|
+
proxy.initialize(serverInstance.clientConnection);
|
|
93
|
+
return proxy;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
DisposeClientSessionParameters,
|
|
18
|
+
GLSPClientProxy,
|
|
19
|
+
GLSPServerListener,
|
|
20
|
+
InitializeClientSessionParameters,
|
|
21
|
+
InitializeParameters
|
|
22
|
+
} from '@eclipse-glsp/protocol';
|
|
17
23
|
import { expect } from 'chai';
|
|
18
24
|
import { Container, ContainerModule } from 'inversify';
|
|
19
25
|
import * as sinon from 'sinon';
|
|
@@ -21,9 +27,7 @@ import { GlobalActionProvider } from '../actions/global-action-provider';
|
|
|
21
27
|
import { ClientSessionManager } from '../session/client-session-manager';
|
|
22
28
|
import * as mock from '../test/mock-util';
|
|
23
29
|
import { Logger } from '../utils/logger';
|
|
24
|
-
import { GLSPClientProxy, JsonRpcGLSPClientProxy } from './glsp-client-proxy';
|
|
25
30
|
import { DefaultGLSPServer } from './glsp-server';
|
|
26
|
-
import { GLSPServerListener } from './glsp-server-listener';
|
|
27
31
|
import assert = require('assert');
|
|
28
32
|
|
|
29
33
|
describe('test DefaultGLSPServer', () => {
|
|
@@ -48,7 +52,6 @@ describe('test DefaultGLSPServer', () => {
|
|
|
48
52
|
new ContainerModule(bind => {
|
|
49
53
|
bind(Logger).toConstantValue(new mock.StubLogger());
|
|
50
54
|
bind(GLSPClientProxy).toConstantValue(new mock.StubGLSPClientProxy());
|
|
51
|
-
bind(JsonRpcGLSPClientProxy).toConstantValue(new mock.StubGLSPClientProxy());
|
|
52
55
|
bind(ClientSessionManager).toConstantValue(sessionManager);
|
|
53
56
|
bind(GlobalActionProvider).toConstantValue({ clientActionKinds: new Map<string, string[]>(), serverActionKinds });
|
|
54
57
|
bind(GLSPServerListener).toConstantValue(listener1);
|
|
@@ -18,134 +18,26 @@ import {
|
|
|
18
18
|
Args,
|
|
19
19
|
DisposeClientSessionParameters,
|
|
20
20
|
distinctAdd,
|
|
21
|
+
GLSPClientProxy,
|
|
22
|
+
GLSPServer,
|
|
23
|
+
GLSPServerListener,
|
|
21
24
|
InitializeClientSessionParameters,
|
|
22
25
|
InitializeParameters,
|
|
23
26
|
InitializeResult,
|
|
24
|
-
JsonrpcGLSPClient,
|
|
25
27
|
MaybePromise,
|
|
26
28
|
remove,
|
|
27
29
|
ServerActions,
|
|
28
30
|
ServerMessageAction
|
|
29
31
|
} from '@eclipse-glsp/protocol';
|
|
30
32
|
import { inject, injectable, multiInject, optional } from 'inversify';
|
|
31
|
-
import * as jsonrpc from 'vscode-jsonrpc';
|
|
32
|
-
import { MessageConnection } from 'vscode-jsonrpc';
|
|
33
33
|
import { GlobalActionProvider } from '../actions/global-action-provider';
|
|
34
34
|
import { ClientSession } from '../session/client-session';
|
|
35
35
|
import { ClientSessionManager } from '../session/client-session-manager';
|
|
36
36
|
import { GLSPServerError } from '../utils/glsp-server-error';
|
|
37
37
|
import { Logger } from '../utils/logger';
|
|
38
|
-
import { JsonRpcGLSPClientProxy } from './glsp-client-proxy';
|
|
39
|
-
import { GLSPServerListener } from './glsp-server-listener';
|
|
40
|
-
|
|
41
|
-
export const GLSPServer = Symbol('GLSPServer');
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Interface for implementations of a server component using json-rpc for client-server communication.
|
|
45
|
-
* Based on the specification of the Graphical Language Server Protocol:
|
|
46
|
-
* https://github.com/eclipse-glsp/glsp/blob/master/PROTOCOL.md
|
|
47
|
-
*/
|
|
48
|
-
export interface GLSPServer {
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
51
|
-
* The `initialize` request has to be the first request from the client to the server. Until the server has responded
|
|
52
|
-
* with an {@link InitializeResult} no other request or notification can be handled and is expected to throw an
|
|
53
|
-
* error. A client is uniquely identified by an `applicationId` and has to specify on which `protocolVersion` it is
|
|
54
|
-
* based on. In addition, custom arguments can be provided in the `args` map to allow for custom initialization
|
|
55
|
-
* behavior on the server.
|
|
56
|
-
*
|
|
57
|
-
* After successfully initialization all {@link GLSPServerListener}s are notified via the
|
|
58
|
-
* {@link GLSPServerListener.serverInitialized} method.
|
|
59
|
-
*
|
|
60
|
-
* @param params the {@link InitializeParameters}.
|
|
61
|
-
* @returns A promise of the {@link InitializeResult} .
|
|
62
|
-
*
|
|
63
|
-
* @throws {@link Error} Subsequent initialize requests return the {@link InitializeResult} of the initial request
|
|
64
|
-
* if the given application id and protocol version are matching, otherwise the promise rejects with an error.
|
|
65
|
-
*
|
|
66
|
-
*/
|
|
67
|
-
initialize(params: InitializeParameters): Promise<InitializeResult>;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* The `initializeClientSession` request is sent to the server whenever a new graphical representation (diagram) is
|
|
71
|
-
* created. Each individual diagram on the client side counts as one session and has to provide a unique
|
|
72
|
-
* `clientSessionId` and its `diagramType`. In addition, custom arguments can be provided in the `args` map to allow
|
|
73
|
-
* for custom initialization behavior on the server. Subsequent `initializeClientSession` requests for the same
|
|
74
|
-
* client id and diagram type are expected to resolve successfully but don't have an actual effect because the
|
|
75
|
-
* corresponding client session is already initialized.
|
|
76
|
-
*
|
|
77
|
-
* @param params the {@link InitializeClientSessionParameters}.
|
|
78
|
-
* @returns A promise that completes when the initialization was successful.
|
|
79
|
-
*/
|
|
80
|
-
initializeClientSession(params: InitializeClientSessionParameters): Promise<void>;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The 'DisposeClientSession' request is sent to the server when a graphical representation (diagram) is no longer
|
|
84
|
-
* needed, e.g. the tab containing the diagram widget has been closed. The session is identified by its unique
|
|
85
|
-
* `clientSessionId`. In addition, custom arguments can be provided in the `args` map to allow for custom dispose
|
|
86
|
-
* behavior on the server.
|
|
87
|
-
*
|
|
88
|
-
* @param params the {@link DisposeClientSessionParameters}.
|
|
89
|
-
* @returns A `void` promise that completes if the disposal was successful.
|
|
90
|
-
*
|
|
91
|
-
*/
|
|
92
|
-
disposeClientSession(params: DisposeClientSessionParameters): Promise<void>;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* A `process` notification is sent from the client to server when the server should handle i.e. process a specific
|
|
96
|
-
* {@link ActionMessage}. Any communication that is performed between initialization and shutdown is handled by
|
|
97
|
-
* sending action messages, either from the client to the server or from the server to the client. This is the core
|
|
98
|
-
* part of the Graphical Language Server Protocol.
|
|
99
|
-
*
|
|
100
|
-
* @param message The {@link ActionMessage} that should be processed.
|
|
101
|
-
*/
|
|
102
|
-
process(message: ActionMessage): void;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The `shutdown` notification is sent from the client to the server if the client disconnects from the server (e.g.
|
|
106
|
-
* the client application has been closed).
|
|
107
|
-
* This gives the server a chance to clean up and dispose any resources dedicated to the client and its sessions.
|
|
108
|
-
* All {@link GLSPServerListener}s are notified via the {@link GLSPServerListener.serverShutDown} method.
|
|
109
|
-
* Afterwards the server instance is considered to be disposed and can no longer be used for handling requests.
|
|
110
|
-
*
|
|
111
|
-
*/
|
|
112
|
-
shutdown(): void;
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Register a new {@link GLSPServerListener}.
|
|
116
|
-
*
|
|
117
|
-
* @param listener The listener that should be registered.
|
|
118
|
-
* @returns `true` if the listener was registered successfully, `false` otherwise (e.g. listener is already
|
|
119
|
-
* registered).
|
|
120
|
-
*/
|
|
121
|
-
addListener(listener: GLSPServerListener): boolean;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Unregister a {@link GLSPServerListener}.
|
|
125
|
-
*
|
|
126
|
-
* @param listener The listener that should be removed
|
|
127
|
-
* @returns 'true' if the listener was unregistered successfully, `false` otherwise (e.g. listener is was not
|
|
128
|
-
* registered in the first place).
|
|
129
|
-
*/
|
|
130
|
-
removeListener(listener: GLSPServerListener): boolean;
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* get a {@link ClientSession}.
|
|
134
|
-
*
|
|
135
|
-
* @param sessionId The id of the session to get
|
|
136
|
-
* @returns The either the ClientSession or undefined, if no ClientSession was found for the given id.
|
|
137
|
-
*/
|
|
138
|
-
getClientSession(sessionId: string): ClientSession | undefined;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export const JsonRpcGLSPServer = Symbol('JsonRpcGLSPServer');
|
|
142
|
-
|
|
143
|
-
export interface JsonRpcGLSPServer extends GLSPServer {
|
|
144
|
-
connect(connection: jsonrpc.MessageConnection): void;
|
|
145
|
-
}
|
|
146
38
|
|
|
147
39
|
@injectable()
|
|
148
|
-
export class DefaultGLSPServer implements
|
|
40
|
+
export class DefaultGLSPServer implements GLSPServer {
|
|
149
41
|
public static readonly PROTOCOL_VERSION = '1.0.0';
|
|
150
42
|
|
|
151
43
|
@inject(Logger)
|
|
@@ -157,8 +49,9 @@ export class DefaultGLSPServer implements JsonRpcGLSPServer {
|
|
|
157
49
|
@inject(GlobalActionProvider)
|
|
158
50
|
protected actionProvider: GlobalActionProvider;
|
|
159
51
|
|
|
160
|
-
@inject(
|
|
161
|
-
|
|
52
|
+
@inject(GLSPClientProxy)
|
|
53
|
+
@optional()
|
|
54
|
+
protected glspClientProxy?: GLSPClientProxy;
|
|
162
55
|
|
|
163
56
|
protected initializeResult?: InitializeResult;
|
|
164
57
|
|
|
@@ -172,18 +65,6 @@ export class DefaultGLSPServer implements JsonRpcGLSPServer {
|
|
|
172
65
|
serverListeners.forEach(listener => this.addListener(listener));
|
|
173
66
|
}
|
|
174
67
|
|
|
175
|
-
protected setupJsonRpc(connection: MessageConnection): void {
|
|
176
|
-
connection.onRequest(JsonrpcGLSPClient.InitializeRequest.method, (params: InitializeParameters) => this.initialize(params));
|
|
177
|
-
connection.onRequest(JsonrpcGLSPClient.InitializeClientSessionRequest, (params: InitializeClientSessionParameters) =>
|
|
178
|
-
this.initializeClientSession(params)
|
|
179
|
-
);
|
|
180
|
-
connection.onRequest(JsonrpcGLSPClient.DisposeClientSessionRequest, (params: DisposeClientSessionParameters) =>
|
|
181
|
-
this.disposeClientSession(params)
|
|
182
|
-
);
|
|
183
|
-
connection.onNotification(JsonrpcGLSPClient.ActionMessageNotification, message => this.process(message));
|
|
184
|
-
connection.onNotification(JsonrpcGLSPClient.ShutdownNotification, () => this.shutdown());
|
|
185
|
-
}
|
|
186
|
-
|
|
187
68
|
protected validateProtocolVersion(params: InitializeParameters): void {
|
|
188
69
|
if (params.protocolVersion !== DefaultGLSPServer.PROTOCOL_VERSION) {
|
|
189
70
|
throw new Error(
|
|
@@ -237,6 +118,7 @@ export class DefaultGLSPServer implements JsonRpcGLSPServer {
|
|
|
237
118
|
this.validateServerInitialized();
|
|
238
119
|
|
|
239
120
|
const session = this.sessionManager.getOrCreateClientSession(params);
|
|
121
|
+
|
|
240
122
|
this.clientSessions.set(params.clientSessionId, session);
|
|
241
123
|
return this.handleInitializeClientSessionArgs(params.args);
|
|
242
124
|
}
|
|
@@ -281,7 +163,15 @@ export class DefaultGLSPServer implements JsonRpcGLSPServer {
|
|
|
281
163
|
errorMsg = reason.message;
|
|
282
164
|
}
|
|
283
165
|
const errorAction = ServerMessageAction.create(errorMsg, { severity: 'ERROR', details });
|
|
284
|
-
this.
|
|
166
|
+
this.sendToClient({ clientId: message.clientId, action: errorAction });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
protected sendToClient(message: ActionMessage): void {
|
|
170
|
+
if (this.glspClientProxy) {
|
|
171
|
+
this.glspClientProxy.process(message);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
throw new Error("Could not send message to client. No 'GLSPClientProxy' is connected");
|
|
285
175
|
}
|
|
286
176
|
|
|
287
177
|
getClientSession(sessionId: string): ClientSession | undefined {
|
|
@@ -295,11 +185,6 @@ export class DefaultGLSPServer implements JsonRpcGLSPServer {
|
|
|
295
185
|
this.initializeResult = undefined;
|
|
296
186
|
}
|
|
297
187
|
|
|
298
|
-
public connect(connection: jsonrpc.MessageConnection): void {
|
|
299
|
-
this.setupJsonRpc(connection);
|
|
300
|
-
this.glspClient.connect(connection);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
188
|
protected isInitialized(): boolean {
|
|
304
189
|
return this.initializeResult !== undefined;
|
|
305
190
|
}
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
+
import { GLSPClientProxy } from '@eclipse-glsp/protocol';
|
|
16
17
|
import { expect } from 'chai';
|
|
17
18
|
import { Container, ContainerModule } from 'inversify';
|
|
18
19
|
import { ActionDispatcher } from '../actions/action-dispatcher';
|
|
19
20
|
import { DiagramModules, InjectionContainer } from '../di/service-identifiers';
|
|
20
|
-
import { GLSPClientProxy } from '../protocol/glsp-client-proxy';
|
|
21
21
|
import * as mock from '../test/mock-util';
|
|
22
22
|
import { GLSPServerError } from '../utils/glsp-server-error';
|
|
23
23
|
import { Logger } from '../utils/logger';
|
|
@@ -13,12 +13,11 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { InitializeClientSessionParameters } from '@eclipse-glsp/protocol';
|
|
16
|
+
import { GLSPClientProxy, InitializeClientSessionParameters } from '@eclipse-glsp/protocol';
|
|
17
17
|
import { Container, ContainerModule, inject, injectable } from 'inversify';
|
|
18
18
|
import { ActionDispatcher } from '../actions/action-dispatcher';
|
|
19
19
|
import { createClientSessionModule } from '../di/client-session-module';
|
|
20
20
|
import { DiagramModules, InjectionContainer } from '../di/service-identifiers';
|
|
21
|
-
import { GLSPClientProxy } from '../protocol/glsp-client-proxy';
|
|
22
21
|
import { GLSPServerError } from '../utils/glsp-server-error';
|
|
23
22
|
import { ClientSession, DefaultClientSession } from './client-session';
|
|
24
23
|
import { ClientSessionInitializer } from './client-session-initializer';
|
|
@@ -13,10 +13,8 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { InitializeClientSessionParameters, remove } from '@eclipse-glsp/protocol';
|
|
16
|
+
import { GLSPServer, GLSPServerListener, InitializeClientSessionParameters, remove } from '@eclipse-glsp/protocol';
|
|
17
17
|
import { inject, injectable } from 'inversify';
|
|
18
|
-
import { GLSPServer } from '../protocol/glsp-server';
|
|
19
|
-
import { GLSPServerListener } from '../protocol/glsp-server-listener';
|
|
20
18
|
import { GLSPServerError } from '../utils/glsp-server-error';
|
|
21
19
|
import { ClientSession } from './client-session';
|
|
22
20
|
import { ClientSessionFactory } from './client-session-factory';
|
|
@@ -23,6 +23,9 @@ import {
|
|
|
23
23
|
Args,
|
|
24
24
|
CreateNodeOperation,
|
|
25
25
|
EdgeTypeHint,
|
|
26
|
+
GLSPClientProxy,
|
|
27
|
+
GLSPServer,
|
|
28
|
+
GLSPServerListener,
|
|
26
29
|
InitializeClientSessionParameters,
|
|
27
30
|
MaybeArray,
|
|
28
31
|
MaybePromise,
|
|
@@ -41,15 +44,12 @@ import { DiagramConfiguration, ServerLayoutKind } from '../diagram/diagram-confi
|
|
|
41
44
|
import { ContextEditValidator } from '../features/directediting/context-edit-validator';
|
|
42
45
|
import { LabelEditValidator } from '../features/directediting/label-edit-validator';
|
|
43
46
|
import { GModelCreateEdgeOperationHandler, GModelCreateNodeOperationHandler } from '../gmodel/index';
|
|
44
|
-
import { JsonRpcGLSPClientProxy } from '../protocol/glsp-client-proxy';
|
|
45
|
-
import { GLSPServer } from '../protocol/glsp-server';
|
|
46
|
-
import { GLSPServerListener } from '../protocol/glsp-server-listener';
|
|
47
47
|
import { ClientSession } from '../session/client-session';
|
|
48
48
|
import { ClientSessionFactory } from '../session/client-session-factory';
|
|
49
49
|
import { ClientSessionInitializer } from '../session/client-session-initializer';
|
|
50
50
|
import { ClientSessionListener } from '../session/client-session-listener';
|
|
51
51
|
import { ClientSessionManager } from '../session/client-session-manager';
|
|
52
|
-
import {
|
|
52
|
+
import { LogLevel, Logger } from '../utils/logger';
|
|
53
53
|
|
|
54
54
|
export async function delay(ms: number): Promise<void> {
|
|
55
55
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
@@ -194,7 +194,7 @@ export class StubClientSessionListener implements ClientSessionListener {
|
|
|
194
194
|
sessionDisposed(clientSession: ClientSession): void {}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
export class StubGLSPClientProxy implements
|
|
197
|
+
export class StubGLSPClientProxy implements GLSPClientProxy {
|
|
198
198
|
connect(connection: MessageConnection): void {}
|
|
199
199
|
|
|
200
200
|
process(message: ActionMessage<Action>): void {}
|
|
@@ -14,9 +14,14 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
+
import { BindingContext } from '@eclipse-glsp/protocol';
|
|
17
18
|
import { injectable } from 'inversify';
|
|
18
|
-
import { Logger,
|
|
19
|
+
import { LogLevel, Logger, LoggerConfigOptions, LoggerFactory, NullLogger, getRequestParentName } from './logger';
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Simple logger implementation that forwards logging calls to the `console` and
|
|
23
|
+
* can be used in both the browser and node context.
|
|
24
|
+
*/
|
|
20
25
|
@injectable()
|
|
21
26
|
export class ConsoleLogger extends Logger {
|
|
22
27
|
constructor(public logLevel: LogLevel = LogLevel.none, public caller?: string) {
|
|
@@ -69,3 +74,16 @@ export class ConsoleLogger extends Logger {
|
|
|
69
74
|
return JSON.stringify(param, undefined, 4);
|
|
70
75
|
}
|
|
71
76
|
}
|
|
77
|
+
|
|
78
|
+
export function configureConsoleLogger<T extends LoggerConfigOptions>(context: BindingContext, options: T): void {
|
|
79
|
+
if (!options.consoleLog) {
|
|
80
|
+
context.bind(Logger).to(NullLogger).inSingletonScope();
|
|
81
|
+
} else {
|
|
82
|
+
context.bind(Logger).toDynamicValue(ctx => new ConsoleLogger(options.logLevel, getRequestParentName(ctx)));
|
|
83
|
+
}
|
|
84
|
+
context.bind(LoggerFactory).toFactory(dynamicContext => (caller: string) => {
|
|
85
|
+
const logger = dynamicContext.container.get(Logger);
|
|
86
|
+
logger.caller = caller;
|
|
87
|
+
return logger;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { injectable } from 'inversify';
|
|
16
|
+
import { injectable, interfaces } from 'inversify';
|
|
17
17
|
|
|
18
18
|
@injectable()
|
|
19
19
|
export abstract class Logger {
|
|
@@ -70,3 +70,18 @@ export function asLogLevel(level: string | number): LogLevel | undefined {
|
|
|
70
70
|
}
|
|
71
71
|
return undefined;
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
export interface LoggerConfigOptions {
|
|
75
|
+
consoleLog?: boolean;
|
|
76
|
+
logLevel?: LogLevel;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function getRequestParentName(context: interfaces.Context): string | undefined {
|
|
80
|
+
if (context.currentRequest.parentRequest) {
|
|
81
|
+
const bindings = context.currentRequest.parentRequest.bindings;
|
|
82
|
+
if (bindings.length > 0) {
|
|
83
|
+
return bindings[0].implementationType?.name;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import {
|
|
16
|
+
import { BindingContext } from '@eclipse-glsp/protocol';
|
|
17
|
+
import { ContainerModule } from 'inversify';
|
|
17
18
|
import * as winston from 'winston';
|
|
18
|
-
import { InjectionContainer, Logger, LoggerFactory,
|
|
19
|
+
import { InjectionContainer, LogLevel, Logger, LoggerFactory, getRequestParentName } from '../../common';
|
|
19
20
|
import { LaunchOptions } from '../launch/cli-parser';
|
|
20
21
|
import { WinstonLogger } from './winston-logger';
|
|
21
22
|
|
|
@@ -68,7 +69,7 @@ export function createWinstonInstance<T extends LaunchOptions>(options: T): wins
|
|
|
68
69
|
* @param baseLoggerCreator The underling global {@link winston.Logger} instance.
|
|
69
70
|
*/
|
|
70
71
|
export function configureWinstonLogger<T extends LaunchOptions>(
|
|
71
|
-
context:
|
|
72
|
+
context: BindingContext,
|
|
72
73
|
options: T,
|
|
73
74
|
rebind = true,
|
|
74
75
|
baseLoggerCreator: (launchOptions: T) => winston.Logger = createWinstonInstance
|
|
@@ -90,13 +91,3 @@ export function configureWinstonLogger<T extends LaunchOptions>(
|
|
|
90
91
|
return logger;
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
-
function getRequestParentName(context: interfaces.Context): string | undefined {
|
|
95
|
-
if (context.currentRequest.parentRequest) {
|
|
96
|
-
const bindings = context.currentRequest.parentRequest.bindings;
|
|
97
|
-
if (bindings.length > 0) {
|
|
98
|
-
return bindings[0].implementationType?.name;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
|
@@ -16,13 +16,12 @@
|
|
|
16
16
|
import * as cmd from 'commander';
|
|
17
17
|
import * as fs from 'fs-extra';
|
|
18
18
|
import * as path from 'path';
|
|
19
|
-
import {
|
|
19
|
+
import { LogLevel, LoggerConfigOptions, asLogLevel } from '../../common/utils/logger';
|
|
20
20
|
|
|
21
|
-
export interface LaunchOptions {
|
|
21
|
+
export interface LaunchOptions extends LoggerConfigOptions {
|
|
22
22
|
logLevel: LogLevel;
|
|
23
23
|
logDir?: string;
|
|
24
24
|
fileLog: boolean;
|
|
25
|
-
consoleLog: boolean;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
export interface CliParser<O extends LaunchOptions = LaunchOptions> {
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
+
import { GLSPServer } from '@eclipse-glsp/protocol';
|
|
17
18
|
import { expect } from 'chai';
|
|
18
19
|
import { Container } from 'inversify';
|
|
19
20
|
import * as net from 'net';
|
|
21
|
+
import * as sinon from 'sinon';
|
|
22
|
+
import { DefaultGLSPServer } from '../../common/protocol/glsp-server';
|
|
20
23
|
import { createAppModule } from '../di/app-module';
|
|
21
24
|
import { defaultSocketLaunchOptions } from './socket-cli-parser';
|
|
22
25
|
import { SocketServerLauncher } from './socket-server-launcher';
|
|
@@ -24,7 +27,10 @@ const severPort = 5008;
|
|
|
24
27
|
describe('test SocketServerLauncher', () => {
|
|
25
28
|
it('starts and stops', async () => {
|
|
26
29
|
const appContainer = new Container();
|
|
30
|
+
const serverStub = sinon.createStubInstance(DefaultGLSPServer);
|
|
27
31
|
appContainer.load(createAppModule(defaultSocketLaunchOptions));
|
|
32
|
+
|
|
33
|
+
appContainer.bind(GLSPServer).toConstantValue(serverStub);
|
|
28
34
|
const launcher = appContainer.resolve(SocketServerLauncher);
|
|
29
35
|
launcher.start({ port: severPort });
|
|
30
36
|
const sockStart = new net.Socket();
|
|
@@ -13,36 +13,35 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import {
|
|
16
|
+
import { Disposable } from '@eclipse-glsp/protocol';
|
|
17
|
+
import { inject, injectable } from 'inversify';
|
|
17
18
|
import * as net from 'net';
|
|
18
19
|
import * as jsonrpc from 'vscode-jsonrpc/node';
|
|
19
|
-
import {
|
|
20
|
-
import { GLSPServerLauncher } from '../../common/launch/glsp-server-launcher';
|
|
21
|
-
import { GLSPServer, JsonRpcGLSPServer } from '../../common/protocol/glsp-server';
|
|
20
|
+
import { JsonRpcGLSPServerLauncher } from '../../common/launch/jsonrpc-server-launcher';
|
|
22
21
|
import { Logger } from '../../common/utils/logger';
|
|
23
22
|
|
|
24
23
|
export const START_UP_COMPLETE_MSG = '[GLSP-Server]:Startup completed. Accepting requests on port:';
|
|
25
24
|
|
|
26
25
|
@injectable()
|
|
27
|
-
export class SocketServerLauncher extends
|
|
26
|
+
export class SocketServerLauncher extends JsonRpcGLSPServerLauncher<net.TcpSocketConnectOpts> {
|
|
28
27
|
@inject(Logger) protected override logger: Logger;
|
|
29
28
|
|
|
30
|
-
protected currentConnections: jsonrpc.MessageConnection[] = [];
|
|
31
|
-
protected startupCompleteMessage = START_UP_COMPLETE_MSG;
|
|
32
29
|
protected netServer: net.Server;
|
|
33
30
|
|
|
34
31
|
constructor() {
|
|
35
32
|
super();
|
|
36
33
|
this.toDispose.push(
|
|
37
34
|
Disposable.create(() => {
|
|
38
|
-
this.currentConnections.forEach(connection => connection.dispose());
|
|
39
35
|
this.netServer.close();
|
|
40
36
|
})
|
|
41
37
|
);
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
protected run(opts: net.TcpSocketConnectOpts): Promise<void> {
|
|
45
|
-
this.netServer = net.createServer(socket =>
|
|
41
|
+
this.netServer = net.createServer(socket => {
|
|
42
|
+
const connection = this.createConnection(socket);
|
|
43
|
+
this.createServerInstance(connection);
|
|
44
|
+
});
|
|
46
45
|
|
|
47
46
|
this.netServer.listen(opts.port, opts.host);
|
|
48
47
|
this.netServer.on('listening', () => {
|
|
@@ -69,27 +68,6 @@ export class SocketServerLauncher extends GLSPServerLauncher<net.TcpSocketConnec
|
|
|
69
68
|
});
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
protected async createClientConnection(socket: net.Socket): Promise<void> {
|
|
73
|
-
const container = this.createContainer();
|
|
74
|
-
const connection = this.createConnection(socket);
|
|
75
|
-
this.currentConnections.push(connection);
|
|
76
|
-
const glspServer = container.get<JsonRpcGLSPServer>(JsonRpcGLSPServer);
|
|
77
|
-
glspServer.connect(connection);
|
|
78
|
-
this.logger.info(`Starting GLSP server connection for client: '${socket.localAddress}'`);
|
|
79
|
-
connection.listen();
|
|
80
|
-
connection.onDispose(() => this.disposeClientConnection(container, glspServer));
|
|
81
|
-
socket.on('close', () => this.disposeClientConnection(container, glspServer));
|
|
82
|
-
return new Promise((resolve, rejects) => {
|
|
83
|
-
connection.onClose(() => resolve(undefined));
|
|
84
|
-
connection.onError(error => rejects(error));
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
protected disposeClientConnection(container: Container, glspServer: GLSPServer): void {
|
|
89
|
-
glspServer.shutdown();
|
|
90
|
-
container.unbindAll();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
71
|
protected createConnection(socket: net.Socket): jsonrpc.MessageConnection {
|
|
94
72
|
return jsonrpc.createMessageConnection(new jsonrpc.SocketMessageReader(socket), new jsonrpc.SocketMessageWriter(socket), console);
|
|
95
73
|
}
|