Skip to content

Commit 1b3fd90

Browse files
authored
Merge pull request #1218 from ChinthakaJ98/remote-debugging
Support remote server debugging
2 parents b3e444c + 6e29f4d commit 1b3fd90

File tree

9 files changed

+222
-71
lines changed

9 files changed

+222
-71
lines changed

workspaces/mi/mi-core/src/rpc-types/mi-diagram/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,7 @@ export interface SwaggerFromAPIRequest {
17791779
swaggerPath?: string;
17801780
isJsonIn?: boolean;
17811781
isJsonOut?: boolean;
1782+
host?: string;
17821783
port?: number;
17831784
projectPath?: string;
17841785
}

workspaces/mi/mi-extension/package.json

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,50 @@
8282
"type": "string"
8383
},
8484
"default": []
85+
},
86+
"properties": {
87+
"type": "object",
88+
"description": "Debug properties for remote debugging",
89+
"additionalProperties": {
90+
"type": [
91+
"string",
92+
"number"
93+
]
94+
},
95+
"default": {}
8596
}
8697
}
8798
}
8899
},
89100
"initialConfigurations": [
90101
{
91102
"type": "mi",
92-
"name": "MI: Run and Debug",
103+
"name": "MI: Local Server Run and Debug",
104+
"request": "launch",
105+
"internalConsoleOptions": "openOnSessionStart",
106+
"vmArgs": [],
107+
"properties": {
108+
"type": "local"
109+
}
110+
},
111+
{
112+
"type": "mi",
113+
"name": "MI: Remote Server Run and Debug",
93114
"request": "launch",
94115
"internalConsoleOptions": "openOnSessionStart",
95-
"vmArgs": []
116+
"vmArgs": [],
117+
"properties": {
118+
"type": "remote",
119+
"commandPort": 9005,
120+
"eventPort": 9006,
121+
"serverHost": "localhost",
122+
"serverPort": 8290,
123+
"serverReadinessPort": 9201,
124+
"managementPort": 9164,
125+
"managementUsername": "admin",
126+
"managementPassword": "admin",
127+
"connectionTimeoutInSecs": 10
128+
}
96129
}
97130
]
98131
}

workspaces/mi/mi-extension/src/debugger/activate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,6 @@ class InlineDebugAdapterFactory implements vscode.DebugAdapterDescriptorFactory
368368
window.showErrorMessage(errorMessage);
369369
return;
370370
}
371-
return new vscode.DebugAdapterInlineImplementation(new MiDebugAdapter(projectUri));
371+
return new vscode.DebugAdapterInlineImplementation(new MiDebugAdapter(projectUri, session));
372372
}
373373
}

workspaces/mi/mi-extension/src/debugger/config.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import * as vscode from 'vscode';
2121
import * as path from "path";
22+
import { LOCALHOST, ADMIN } from './constants';
2223

2324
const toml = require('@iarna/toml');
2425
const fs = require('fs');
@@ -29,20 +30,22 @@ export class DebuggerConfig {
2930
private static baseServerPort: number = vscode.workspace.getConfiguration().get<number>('MI.serverPort', 8290);
3031
private static serverReadinessPort: number = 9201;
3132
private static managementPort: number = 9164;
32-
private static host: string = 'localhost';
33+
private static host: string = LOCALHOST;
3334
private static internalOffset = 10;
3435
private static envVariables: { [key: string]: string } = {};
3536
private static vmArgs: string[] = [];
3637
private static vmArgsPortOffset: number | null = null;
3738
private static configPortOffset: number | null = null;
39+
private static remoteDebuggingEnabled: boolean = false;
40+
private static connectionTimeout: number = 10000;
3841

3942
//Capps and Libs copied to the MI server
4043
private static copiedCappUri: string[] = [];
4144
private static copiedLibs: string[] = [];
4245

4346
// Management API username and password
44-
private static managementUserName: string = "admin";
45-
private static managementPassword: string = "admin";
47+
private static managementUserName: string = ADMIN;
48+
private static managementPassword: string = ADMIN;
4649

4750
private static portOffset: number | undefined;
4851

@@ -96,6 +99,10 @@ export class DebuggerConfig {
9699
this.copiedLibs = [];
97100
}
98101

102+
public static setServerPort(port: number): void {
103+
this.baseServerPort = port;
104+
}
105+
99106
public static getServerPort(): number {
100107
if (this.vmArgsPortOffset !== null) {
101108
return this.baseServerPort + this.vmArgsPortOffset - this.internalOffset;
@@ -106,6 +113,10 @@ export class DebuggerConfig {
106113
return this.baseServerPort;
107114
}
108115

116+
public static setServerReadinessPort(port: number): void {
117+
this.serverReadinessPort = port;
118+
}
119+
109120
public static getServerReadinessPort(): number {
110121
if (this.vmArgsPortOffset !== null) {
111122
return this.serverReadinessPort + this.vmArgsPortOffset - this.internalOffset;
@@ -116,6 +127,10 @@ export class DebuggerConfig {
116127
return this.serverReadinessPort;
117128
}
118129

130+
public static setManagementPort(port: number): void {
131+
this.managementPort = port;
132+
}
133+
119134
public static getManagementPort(): number {
120135
if (this.vmArgsPortOffset !== null) {
121136
return this.managementPort + this.vmArgsPortOffset - this.internalOffset;
@@ -130,6 +145,10 @@ export class DebuggerConfig {
130145
return this.host;
131146
}
132147

148+
public static setHost(host: string): void {
149+
this.host = host;
150+
}
151+
133152
public static getManagementUserName(): string {
134153
return this.managementUserName;
135154
}
@@ -164,4 +183,23 @@ export class DebuggerConfig {
164183
const configs = toml.parse(fs.readFileSync(deploymentConfig, 'utf8'));
165184
this.configPortOffset = configs.server?.offset ?? null;
166185
}
186+
187+
public static setRemoteDebuggingEnabled(enabled: boolean): void {
188+
this.remoteDebuggingEnabled = enabled;
189+
}
190+
191+
public static isRemoteDebuggingEnabled(): boolean {
192+
return this.remoteDebuggingEnabled;
193+
}
194+
195+
public static getDefaultServerPort(): number {
196+
return vscode.workspace.getConfiguration().get<number>('MI.serverPort', 8290);
197+
}
198+
199+
public static getConnectionTimeout(): number {
200+
return this.connectionTimeout;
201+
}
202+
public static setConnectionTimeout(timeout: number): void {
203+
this.connectionTimeout = timeout * 1000;
204+
}
167205
}

workspaces/mi/mi-extension/src/debugger/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ export const SELECTED_JAVA_HOME = "JAVA_HOME";
2121

2222
export const INCORRECT_SERVER_PATH_MSG = "Unable to locate the MI server at the provided path. Please provide the correct path.";
2323

24+
export const REMOTE = "remote";
25+
export const LOCALHOST = "localhost";
26+
export const ADMIN = "admin";

workspaces/mi/mi-extension/src/debugger/debugAdapter.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { getStateMachine, openView, refreshUI } from '../stateMachine';
2626
import { webviews } from '../visualizer/webview';
2727
import { ViewColumn } from 'vscode';
2828
import { COMMANDS } from '../constants';
29+
import { LOCALHOST, ADMIN, REMOTE } from './constants';
2930
import { INCORRECT_SERVER_PATH_MSG } from './constants';
3031
import { extension } from '../MIExtensionContext';
3132
import { EVENT_TYPE, miServerRunStateChanged } from '@wso2/mi-core';
@@ -47,13 +48,39 @@ export class MiDebugAdapter extends LoggingDebugSession {
4748

4849
private variableHandles: Handles<any>;
4950

50-
public constructor(private projectUri: string) {
51+
public constructor(private projectUri: string, session?: vscode.DebugSession) {
5152
super();
5253
// debugger uses zero-based lines and columns
5354
this.setDebuggerLinesStartAt1(false);
5455
this.setDebuggerColumnsStartAt1(false);
5556

56-
this.debuggerHandler = new Debugger(DebuggerConfig.getCommandPort(), DebuggerConfig.getEventPort(), DebuggerConfig.getHost(), projectUri);
57+
const debuggerProperties = session?.configuration?.properties;
58+
if (debuggerProperties) {
59+
DebuggerConfig.setRemoteDebuggingEnabled(debuggerProperties.type === REMOTE);
60+
} else {
61+
DebuggerConfig.setRemoteDebuggingEnabled(false);
62+
}
63+
if (DebuggerConfig.isRemoteDebuggingEnabled()) {
64+
const commandPort = debuggerProperties.commandPort || 9005;
65+
const eventPort = debuggerProperties.eventPort || 9006;
66+
const serverHost = debuggerProperties.serverHost || LOCALHOST;
67+
DebuggerConfig.setHost(serverHost);
68+
DebuggerConfig.setServerPort(debuggerProperties.serverPort || 8290);
69+
DebuggerConfig.setServerReadinessPort(debuggerProperties.serverReadinessPort || 9201);
70+
DebuggerConfig.setManagementPort(debuggerProperties.managementPort || 9164);
71+
DebuggerConfig.setManagementUserName(debuggerProperties.managementUsername || ADMIN);
72+
DebuggerConfig.setManagementPassword(debuggerProperties.managementPassword || ADMIN);
73+
DebuggerConfig.setConnectionTimeout(debuggerProperties.connectionTimeoutInSecs || 10);
74+
this.debuggerHandler = new Debugger(commandPort, eventPort, serverHost, projectUri);
75+
} else {
76+
DebuggerConfig.setHost(LOCALHOST);
77+
DebuggerConfig.setServerPort(DebuggerConfig.getDefaultServerPort());
78+
DebuggerConfig.setServerReadinessPort(9201);
79+
DebuggerConfig.setManagementPort(9164);
80+
DebuggerConfig.setManagementUserName(ADMIN);
81+
DebuggerConfig.setManagementPassword(ADMIN);
82+
this.debuggerHandler = new Debugger(DebuggerConfig.getCommandPort(), DebuggerConfig.getEventPort(), DebuggerConfig.getHost(), projectUri);
83+
}
5784
// setup event handlers
5885
this.debuggerHandler.on('stopOnEntry', () => {
5986
this.sendEvent(new StoppedEvent('entry', MiDebugAdapter.threadID));
@@ -284,10 +311,23 @@ export class MiDebugAdapter extends LoggingDebugSession {
284311

285312
DebuggerConfig.setVmArgs(args?.vmArgs ? args?.vmArgs : []);
286313

287-
await setManagementCredentials(serverPath);
288-
289314
vscode.commands.executeCommand('setContext', 'MI.isRunning', 'true');
290-
executeTasks(this.projectUri, serverPath, isDebugAllowed)
315+
if (DebuggerConfig.isRemoteDebuggingEnabled()) {
316+
this.debuggerHandler?.initializeDebugger().then(() => {
317+
openRuntimeServicesWebview(this.projectUri);
318+
extension.isServerStarted = true;
319+
RPCLayer._messengers.get(this.projectUri)?.sendNotification(miServerRunStateChanged, { type: 'webview', webviewType: 'micro-integrator.runtime-services-panel' }, 'Running');
320+
response.success = true;
321+
this.sendResponse(response);
322+
}).catch(error => {
323+
const completeError = `Error while initializing the Debugger: ${error}`;
324+
vscode.window.showErrorMessage(completeError);
325+
this.sendError(response, 1, completeError);
326+
vscode.commands.executeCommand('setContext', 'MI.isRunning', 'false');
327+
});
328+
} else {
329+
await setManagementCredentials(serverPath);
330+
executeTasks(this.projectUri, serverPath, isDebugAllowed)
291331
.then(async () => {
292332
if (args?.noDebug) {
293333
checkServerReadiness(this.projectUri).then(() => {
@@ -328,6 +368,7 @@ export class MiDebugAdapter extends LoggingDebugSession {
328368
}
329369
this.sendError(response, 1, completeError);
330370
});
371+
}
331372
});
332373
}
333374
});

workspaces/mi/mi-extension/src/debugger/debugger.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { extension } from '../MIExtensionContext';
2828
import { reject } from 'lodash';
2929
import { LogLevel, logDebug } from '../util/logger';
3030
import { MILanguageClient } from '../lang-client/activator';
31+
import { DebuggerConfig } from './config';
3132

3233
export interface RuntimeBreakpoint {
3334
id: number;
@@ -393,7 +394,7 @@ export class Debugger extends EventEmitter {
393394
resolve();
394395
}).catch((error) => {
395396
logDebug(`Error while sending the resume command: ${error}`, LogLevel.ERROR);
396-
reject(`Error while resuming the debugger server: ${error}`);
397+
reject(`Error while resuming the debugger server. ${error}`);
397398
});
398399

399400
}).catch((error) => {
@@ -595,8 +596,13 @@ export class Debugger extends EventEmitter {
595596
logDebug(`Command: ${request}`, LogLevel.INFO);
596597
this.commandClient?.write(request);
597598

599+
const timeout = setTimeout(() => {
600+
reject("Server did not respond within the timeout period. Please restart the server in debug mode and try again.");
601+
}, DebuggerConfig.getConnectionTimeout());
602+
598603
// Listen for response from the command port
599604
this.commandClient?.once('data', (data) => {
605+
clearTimeout(timeout);
600606
// Convert buffer to string
601607
const receivedData = data.toString();
602608

@@ -617,6 +623,11 @@ export class Debugger extends EventEmitter {
617623
incompleteMessage = incompleteMessage.slice(newlineIndex + 1);
618624
}
619625
});
626+
627+
this.commandClient?.once('error', (err) => {
628+
clearTimeout(timeout);
629+
reject(err);
630+
});
620631
});
621632
}
622633

workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5439,7 +5439,7 @@ ${keyValuesXML}`;
54395439
let response;
54405440
if (params.isRuntimeService) {
54415441
const versionedUrl = await exposeVersionedServices(this.projectUri);
5442-
response = await langClient.swaggerFromAPI({ apiPath: params.apiPath, port: DebuggerConfig.getServerPort(), projectPath: versionedUrl ? this.projectUri : "", ...(fs.existsSync(swaggerPath) && { swaggerPath: swaggerPath }) });
5442+
response = await langClient.swaggerFromAPI({ apiPath: params.apiPath, host: DebuggerConfig.getHost(), port: DebuggerConfig.getServerPort(), projectPath: versionedUrl ? this.projectUri : "", ...(fs.existsSync(swaggerPath) && { swaggerPath: swaggerPath }) });
54435443
} else {
54445444
response = await langClient.swaggerFromAPI({ apiPath: params.apiPath, ...(fs.existsSync(swaggerPath) && { swaggerPath: swaggerPath }) });
54455445
}

0 commit comments

Comments
 (0)