Skip to content

Commit

Permalink
ignore server port change, ignore server state outside vscode (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
Summer authored Jan 23, 2018
1 parent 6b5dc0e commit 892ca55
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 47 deletions.
6 changes: 6 additions & 0 deletions src/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ export enum ServerState {
RunningServer = 'runningserver',
IdleServer = 'idleserver'
}

export enum PortKind {
Server = 'Server',
Http = 'Http',
Https = 'Https'
}
59 changes: 31 additions & 28 deletions src/Tomcat/TomcatController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class TomcatController {

if (this._tomcat.deleteServer(tomcatServer)) {
const output: vscode.OutputChannel = this.getOutput(tomcatServer);
this._outputChannels.delete(this.getChannelName(tomcatServer));
this._outputChannels.delete(`Tomcat_${tomcatServer.getName()}`);
output.dispose();
}
vscode.commands.executeCommand('tomcat.tree.refresh');
Expand Down Expand Up @@ -233,7 +233,7 @@ export class TomcatController {
}

private async getServerUri(serverInfo: TomcatServer, appName?: string): Promise<string> {
const serverPort: string = await Utility.getHttpPort(serverInfo.getServerConfigPath());
const serverPort: string = await Utility.getPort(serverInfo.getServerConfigPath(), Constants.PortKind.Http);
if (!serverPort) {
throw new Error('No http port found in server.xml');
}
Expand All @@ -247,6 +247,10 @@ export class TomcatController {
const serverName: string = serverInfo.getName();
let watcher: chokidar.FSWatcher;
const serverUri: string = await this.getServerUri(serverInfo, appName);
const serverConfig: string = serverInfo.getServerConfigPath();
const serverPort: string = await Utility.getPort(serverConfig, Constants.PortKind.Server);
const httpPort: string = await Utility.getPort(serverConfig, Constants.PortKind.Http);
const httpsPort: string = await Utility.getPort(serverConfig, Constants.PortKind.Https);

try {
if (serverUri) {
Expand All @@ -260,57 +264,56 @@ export class TomcatController {
statusBar.show();
}

watcher = chokidar.watch(serverInfo.getServerConfigPath());
watcher = chokidar.watch(serverConfig);
watcher.on('change', async () => {
const promptString: string = localize('tomcatExt.configChanged',
'server.xml of running server {0} has been changed. Would you like to restart it?',
serverName);
const item: vscode.MessageItem = await vscode.window.showInformationMessage(promptString, DialogMessage.yes, DialogMessage.no);
if (item === DialogMessage.yes) {
try {
// Need restart tomcat
await this.stopServer(serverInfo);
serverInfo.needRestart = true;
} catch (err) {
console.error(err.toString());
vscode.window.showErrorMessage(localize('tomcatExt.stopFailure', 'Failed to stop Tomcat Server {0}', serverName));
if (serverPort !== await Utility.getPort(serverConfig, Constants.PortKind.Server)) {
vscode.window.showErrorMessage(localize('tomcatExt.serverPortChangeError', `Changing the server port of a running server will cause errors, please change it back to ${ serverPort} !`));
} else if (httpPort !== await Utility.getPort(serverConfig, Constants.PortKind.Http) ||
httpsPort !== await Utility.getPort(serverConfig, Constants.PortKind.Https)) {
const promptString: string = localize('tomcatExt.configChanged',
'server.xml of running server {0} has been changed. Would you like to restart it?',
serverName);
const item: vscode.MessageItem = await vscode.window.showInformationMessage(promptString, DialogMessage.yes, DialogMessage.no);
if (item === DialogMessage.yes) {
try {
// Need restart tomcat
await this.stopServer(serverInfo);
serverInfo.needRestart = true;
} catch (err) {
console.error(err.toString());
vscode.window.showErrorMessage(localize('tomcatExt.stopFailure', 'Failed to stop Tomcat Server {0}', serverName));
}
}
}
});

const javaProcess: Promise<void> = Utility.executeCMD(output, 'java', { shell: true }, ...this.getJavaArgs(serverInfo, true));
this.setStarted(serverInfo, true);
this.startDebugSession(serverInfo);
setTimeout(() => this.setStarted(serverInfo, true), 500);
await javaProcess;
this.setStarted(serverInfo, false);
this.disposeResource(statusBarCommand);
this.disposeResource(statusBar);
this.disposeResources(statusBarCommand, statusBar);
watcher.close();
if (serverInfo.needRestart) {
serverInfo.needRestart = false;
await this.startTomcat(serverInfo, appName, output);
}
} catch (err) {
this.setStarted(serverInfo, false);
this.disposeResource(statusBarCommand);
this.disposeResource(statusBar);
this.disposeResources(statusBarCommand, statusBar);
if (watcher) { watcher.close(); }
throw new Error(err.toString());
}
}

private disposeResource(resource: vscode.Disposable | undefined): void {
if (resource) {
resource.dispose();
private disposeResources(...resources: vscode.Disposable[]): void {
if (resources) {
resources.forEach((item: vscode.Disposable) => item.dispose());
}
}

private getChannelName(serverInfo: TomcatServer): string {
return `Tomcat_${serverInfo.getName()}`;
}

private getOutput(serverInfo: TomcatServer): vscode.OutputChannel {
const channelName: string = this.getChannelName(serverInfo);
const channelName: string = `Tomcat_${serverInfo.getName()}`;
let output: vscode.OutputChannel = this._outputChannels.get(channelName);
if (!output) {
output = vscode.window.createOutputChannel(channelName);
Expand Down
5 changes: 5 additions & 0 deletions src/TomcatServerTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export class TomcatSeverTreeProvider implements vscode.TreeDataProvider<TomcatSe

public async getTreeItem(element: TomcatServer): Promise<vscode.TreeItem> {
const treeItem: TomcatTreeItem = new TomcatTreeItem(this._context, element);
/* qisun: checking http port is not a valid way to detect the server running or not
// update the logic when finding a proper way to check the server real state
// currently behavior is ignoring the server state outside vscode
// and always stop servers when exiting vscode
try {
const port: string = await Utility.getHttpPort(treeItem.serverConfig);
// tslint:disable-next-line:no-any no-http-string
Expand All @@ -62,6 +66,7 @@ export class TomcatSeverTreeProvider implements vscode.TreeDataProvider<TomcatSe
} catch (err) {
element.setStarted(false);
}
*/
treeItem.iconPath = this._context.asAbsolutePath(path.join('resources', `${element.getState()}.svg`));
return treeItem;
}
Expand Down
29 changes: 24 additions & 5 deletions src/Utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import * as child_process from "child_process";
import * as fse from "fs-extra";
import * as net from "net";
import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";
import * as xml2js from "xml2js";
Expand Down Expand Up @@ -59,7 +60,18 @@ export namespace Utility {
});
}

export async function getHttpPort(serverXml: string): Promise<string> | undefined {
export function getTempStoragePath(): string {
const chars: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
let result: string = '';
for (let i: number = 0; i < 5; i += 1) {
// tslint:disable-next-line:insecure-random
const idx: number = Math.floor(chars.length * Math.random());
result += chars[idx];
}
return path.resolve(os.tmpdir(), `vscodetomcat_${result}`);
}

export async function getPort(serverXml: string, kind: Constants.PortKind): Promise<string> {
if (!await fse.pathExists(serverXml)) {
throw new Error(localize('tomcatExt.noserver', 'No tomcat server.'));
}
Expand All @@ -68,15 +80,22 @@ export namespace Utility {
try {
/* tslint:disable:no-any */
const jsonObj: any = await parseXml(xml);
port = jsonObj.Server.Service.find((item: any) => item.$.name === Constants.CATALINA).Connector.find((item: any) =>
(item.$.protocol === undefined || item.$.protocol.startsWith(Constants.HTTP))).$.port;
if (kind === Constants.PortKind.Server) {
port = jsonObj.Server.$.port;
} else if (kind === Constants.PortKind.Http) {
port = jsonObj.Server.Service.find((item: any) => item.$.name === Constants.CATALINA).Connector.find((item: any) =>
(item.$.protocol === undefined || item.$.protocol.startsWith(Constants.HTTP))).$.port;
} else if (kind === Constants.PortKind.Https) {
port = jsonObj.Server.Service.find((item: any) => item.$.name === Constants.CATALINA).Connector.find((item: any) =>
(item.$.SSLEnabled.toLowerCase() === 'true')).$.port;
}
} catch (err) {
port = undefined;
}
return port;
}/* tslint:enable:no-any */

// tslint:disable-next-line:no-any
/* tslint:disable:no-any */
async function parseXml(xml: string): Promise<any> {
return new Promise((resolve: (obj: {}) => void, reject: (e: Error) => void): void => {
xml2js.parseString(xml, { explicitArray: true }, (err: Error, res: {}) => {
Expand All @@ -86,5 +105,5 @@ export namespace Utility {
return resolve(res);
});
});
}
}/* tslint:enable:no-any */
}
14 changes: 1 addition & 13 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import * as child_process from "child_process";
import * as fse from "fs-extra";
import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";
import { MessageItem } from "vscode";
Expand All @@ -17,7 +16,7 @@ import { Utility } from "./Utility";
export function activate(context: vscode.ExtensionContext): void {
let storagePath: string = context.storagePath;
if (!storagePath) {
storagePath = path.resolve(os.tmpdir(), `vscodetomcat_${makeRandomHexString(5)}`);
storagePath = Utility.getTempStoragePath();
}
const outputChannel: vscode.OutputChannel = vscode.window.createOutputChannel('Tomcat');
const tomcatData: Tomcat = new Tomcat(storagePath);
Expand Down Expand Up @@ -196,16 +195,5 @@ async function runOnTomcat(tomcatController: TomcatController, debug: boolean, u
await tomcatController.runOnServer(server, packagePath, debug);
}

function makeRandomHexString(length: number): string {
const chars: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
let result: string = '';
for (let i: number = 0; i < length; i += 1) {
// tslint:disable-next-line:insecure-random
const idx: number = Math.floor(chars.length * Math.random());
result += chars[idx];
}
return result;
}

// tslint:disable-next-line:no-empty
export function deactivate(): void {}
3 changes: 2 additions & 1 deletion test/utility.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as assert from "assert";
import * as path from "path";
import * as Constants from "../src/Constants";
import { TomcatServer } from "../src/Tomcat/TomcatServer";
import { Utility } from "../src/Utility";

Expand All @@ -15,7 +16,7 @@ suite('utility tests', () => {
test('getPort', async () => {
try {
const filePath: string = path.resolve(__dirname, '../../testResources/server.xml');
const port: string = await Utility.getHttpPort(filePath);
const port: string = await Utility.getPort(filePath, Constants.PortKind.Http);
assert.equal(port, '8081');
} catch (error) {
assert.fail('no error', 'error');
Expand Down

0 comments on commit 892ca55

Please sign in to comment.