Skip to content

Commit ee0ce6e

Browse files
authored
Add strict type checking to Node Filewatcher (#66)
* Add strict type checking to Node Filewatcher Signed-off-by: Jonathan West <jgwest@ca.ibm.com>
1 parent 7816ea0 commit ee0ce6e

24 files changed

+240
-162
lines changed

Filewatcherd-TypeScript/src/lib/AuthTokenWrapper.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,19 @@ export class AuthTokenWrapper {
3838
*/
3939
private _invalidKeysSet: Set<string /* token */>;
4040

41-
private readonly _authTokenProvider: IAuthTokenProvider;
41+
private readonly _authTokenProvider: IAuthTokenProvider | undefined;
4242

43-
constructor(authTokenProvider: IAuthTokenProvider) {
43+
constructor(authTokenProvider: IAuthTokenProvider | undefined) {
4444
this._recentInvalidKeysQueue = new Array<FWAuthToken>();
4545
this._authTokenProvider = authTokenProvider;
4646
this._invalidKeysSet = new Set();
4747
}
48-
public getLatestToken(): FWAuthToken {
49-
if (!this._authTokenProvider) { return null; }
48+
49+
public getLatestToken(): FWAuthToken | undefined {
50+
if (!this._authTokenProvider) { return undefined; }
5051

5152
const token = this._authTokenProvider.getLatestAuthToken();
52-
if (!token) { return null; }
53+
if (!token) { return undefined; }
5354

5455
log.info("IDE returned a new security token to filewatcher: " + this.digest(token));
5556

@@ -77,6 +78,11 @@ export class AuthTokenWrapper {
7778
while (this._recentInvalidKeysQueue.length > AuthTokenWrapper.KEEP_LAST_X_STALE_KEYS) {
7879

7980
const keyToRemove = this._recentInvalidKeysQueue.shift(); // remove from front
81+
82+
if (!keyToRemove) {
83+
break;
84+
}
85+
8086
this._invalidKeysSet.delete(keyToRemove.accessToken);
8187
}
8288

@@ -88,11 +94,11 @@ export class AuthTokenWrapper {
8894
* Return a representation of the token that is at most 32 characters long, so
8995
* as not to overwhelm the log file.
9096
*/
91-
private digest(token: FWAuthToken): string {
92-
if (!token) { return null; }
97+
private digest(token: FWAuthToken): string | undefined {
98+
if (!token) { return undefined; }
9399

94100
const key = token.accessToken;
95-
if (!key) { return null; }
101+
if (!key) { return undefined; }
96102

97103
return key.substring(0, Math.min(key.length, 32));
98104

Filewatcherd-TypeScript/src/lib/CLIState.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ export class CLIState {
3939
private readonly _projectPath: string;
4040

4141
/** For automated testing only */
42-
private readonly _mockInstallerPath: string;
42+
private readonly _mockInstallerPath: string | undefined;
4343

4444
/** For automated testing only */
45-
private _lastDebugPtwSeen: ProjectToWatch = undefined;
45+
private _lastDebugPtwSeen: ProjectToWatch | undefined;
4646

4747
constructor(projectId: string, installerPath: string, projectPath: string) {
4848
this._projectId = projectId;
@@ -52,7 +52,7 @@ export class CLIState {
5252
this._mockInstallerPath = process.env.MOCK_CWCTL_INSTALLER_PATH;
5353
}
5454

55-
public onFileChangeEvent(projectCreationTimeInAbsoluteMsecsParam: number, debugPtw: ProjectToWatch) {
55+
public onFileChangeEvent(projectCreationTimeInAbsoluteMsecsParam: number | undefined, debugPtw: ProjectToWatch | undefined) {
5656

5757
if (!this._projectPath || this._projectPath.trim().length === 0) {
5858
log.error("Project path passed to CLIState is empty, so ignoring file change event.");
@@ -95,7 +95,7 @@ export class CLIState {
9595
}
9696
}
9797

98-
private async callCLIAsync(debugPtw: ProjectToWatch) {
98+
private async callCLIAsync(debugPtw: ProjectToWatch | undefined) {
9999

100100
const DEBUG_FAKE_CMD_OUTPUT = false; // Enable this for debugging purposes.
101101

@@ -141,7 +141,7 @@ export class CLIState {
141141
}
142142
}
143143

144-
private async runProjectCommand(debugPtw: ProjectToWatch): Promise<IRunProjectReturn> {
144+
private async runProjectCommand(debugPtw: ProjectToWatch | undefined): Promise<IRunProjectReturn> {
145145

146146
const executableDir = path.dirname(this._installerPath);
147147

@@ -161,6 +161,10 @@ export class CLIState {
161161
"" + lastTimestamp];
162162
} else {
163163

164+
if(!debugPtw) {
165+
throw new Error("debugPtw ProjectToWatch object was not defined, but is required when debug is enabled");
166+
}
167+
164168
// The filewatcher is being run in an automated test scenario: we will now run a
165169
// mock version of cwctl that simulates the project sync command. This mock
166170
// version takes slightly different parameters.

Filewatcherd-TypeScript/src/lib/DebugTimer.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2019 IBM Corporation and others.
2+
* Copyright (c) 2019, 2020 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -25,14 +25,8 @@ export class DebugTimer {
2525

2626
private readonly _parent: FileWatcher;
2727

28-
private _timer: NodeJS.Timer;
29-
3028
constructor(parent: FileWatcher) {
3129
this._parent = parent;
32-
33-
const debugTimer = this;
34-
35-
this.schedule();
3630
}
3731

3832
private tick() {
@@ -60,9 +54,9 @@ export class DebugTimer {
6054

6155
}
6256

63-
private schedule() {
57+
public schedule() {
6458
const debugTimer = this;
65-
this._timer = setTimeout(() => {
59+
setTimeout(() => {
6660
debugTimer.tick();
6761
}, 30 * 60 * 1000);
6862

Filewatcherd-TypeScript/src/lib/FileChangeEventBatchUtil.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
* IBM Corporation - initial API and implementation
1010
*******************************************************************************/
1111

12-
import zlib = require("zlib");
13-
import { ChangedFileEntry, IChangedFileEntryJson } from "./ChangedFileEntry";
12+
import { ChangedFileEntry } from "./ChangedFileEntry";
1413
import { FileWatcher } from "./FileWatcher";
1514
import * as log from "./Logger";
1615
import { EventType } from "./WatchEventEntry";
@@ -44,11 +43,9 @@ export class FileChangeEventBatchUtil {
4443

4544
private static readonly TIME_TO_WAIT_FOR_NO_NEW_EVENTS_IN_MSECS = 1000;
4645

47-
private static readonly MAX_REQUEST_SIZE_IN_PATHS = 625;
48-
4946
private _files: ChangedFileEntry[];
5047

51-
private _timer: NodeJS.Timer = null;
48+
private _timer: NodeJS.Timeout | undefined;
5249

5350
private _disposed: boolean = false;
5451

@@ -74,7 +71,7 @@ export class FileChangeEventBatchUtil {
7471
this._files.push(entry);
7572
}
7673

77-
if (this._timer != null) {
74+
if (this._timer) {
7875
clearTimeout(this._timer);
7976
}
8077

@@ -105,8 +102,10 @@ export class FileChangeEventBatchUtil {
105102
this._files = [];
106103

107104
// Clear the timeout if it already exists.
108-
clearTimeout(this._timer);
109-
this._timer = null;
105+
if(this._timer) {
106+
clearTimeout(this._timer);
107+
this._timer = undefined;
108+
}
110109

111110
if (entries.length === 0) {
112111
return;

Filewatcherd-TypeScript/src/lib/FileLogger.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ export class FileLogger {
4040

4141
private _initialized: boolean = false;
4242

43-
private readonly _parent: LogSettings;
44-
4543
public constructor(logDir: string) {
4644
this._logDir = logDir;
4745

Filewatcherd-TypeScript/src/lib/FileWatcher.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,22 @@ export class FileWatcher {
4949
private readonly _getStatusThread: HttpGetStatusThread;
5050

5151
private readonly _internalWatchService: IWatchService;
52-
private readonly _externalWatchService: IWatchService;
52+
private readonly _externalWatchService: IWatchService | undefined;
5353

5454
private readonly _webSocketManager: WebSocketManagerThread;
5555

5656
private readonly _clientUuid: string;
5757

58-
private readonly _installerPath: string; // May be null
58+
private readonly _installerPath: string;
5959

6060
private readonly _authTokenWrapper: AuthTokenWrapper;
6161

6262
private _disposed: boolean = false;
6363

6464
private _individualFileWatchService: IndividualFileWatchService;
6565

66-
constructor(urlParam: string, internalWatchService: IWatchService, externalWatchService: IWatchService,
67-
installerPath: string, clientUuid: string, authTokenProvider: IAuthTokenProvider) {
66+
constructor(urlParam: string, internalWatchService: IWatchService, externalWatchService: IWatchService | undefined,
67+
installerPath: string, clientUuid: string, authTokenProvider: IAuthTokenProvider | undefined) {
6868

6969
this._clientUuid = clientUuid;
7070
this._installerPath = installerPath;
@@ -100,7 +100,7 @@ export class FileWatcher {
100100
this._webSocketManager = new WebSocketManagerThread(this._wsBaseUrl, this);
101101
this._webSocketManager.queueEstablishConnection();
102102

103-
const debugTimer = new DebugTimer(this);
103+
new DebugTimer(this).schedule();
104104
}
105105

106106
public updateFileWatchStateFromGetRequest(projectsToWatch: ProjectToWatch[]) {
@@ -124,7 +124,7 @@ export class FileWatcher {
124124

125125
// For each of the projects in the local state map, if they aren't found
126126
// in the HTTP GET result, then they have been removed.
127-
for (const [_, value] of this._projectsMap) {
127+
for (const [, value] of this._projectsMap) {
128128
if (!projectIdInHttpResult.has(value.projectToWatch.projectId)) {
129129
removedProjects.push(value.projectToWatch);
130130
}
@@ -147,7 +147,7 @@ export class FileWatcher {
147147

148148
let projectsToWatch = new Array<ProjectToWatch>();
149149

150-
for (const [key, value] of this._projectsMap) {
150+
for (const [, value] of this._projectsMap) {
151151
if (value) {
152152
projectsToWatch.push(value.projectToWatch);
153153
}
@@ -164,7 +164,7 @@ export class FileWatcher {
164164
// This will be the absolute path on the local drive
165165
const fullLocalPath: string = watchEntry.absolutePathWithUnixSeparators;
166166

167-
let match: ProjectToWatch = null;
167+
let match: ProjectToWatch | undefined;
168168

169169
for (const ptw of projectsToWatch) {
170170

@@ -540,7 +540,7 @@ export class FileWatcher {
540540
const pctOldProjectToWatch = oldProjectToWatch.projectCreationTimeInAbsoluteMsecs;
541541
const pctNewProjectToWatch = ptw.projectCreationTimeInAbsoluteMsecs;
542542

543-
let newPct = null;
543+
let newPct : number | undefined;
544544

545545
// If both the old and new values are not null, but the value has changed, then
546546
// use the new value.
@@ -591,14 +591,14 @@ export class FileWatcher {
591591
// new.
592592
if (!pctOldProjectToWatch && pctNewProjectToWatch) {
593593
newPct = pctNewProjectToWatch;
594-
const newTimeInDate = newPct != null ? new Date(newPct).toString() : "";
594+
const newTimeInDate = newPct ? new Date(newPct).toString() : "";
595595
log.info("The project creation time has changed. Old: " + pctOldProjectToWatch + " New: "
596596
+ pctNewProjectToWatch + "(" + newTimeInDate + "), for project " + ptw.projectId);
597597

598598
pctUpdated = true;
599599
}
600600

601-
if (pctUpdated) {
601+
if (pctUpdated && newPct) {
602602
// Update the object itself, in case the if-branch below this one is executed.
603603

604604
if (ptw instanceof ProjectToWatchFromWebSocket) {
@@ -680,7 +680,6 @@ export class FileWatcher {
680680

681681
}
682682

683-
/** May return null if the installer path is not defined. */
684683
public get installerPath(): string {
685684
return this._installerPath;
686685
}

Filewatcherd-TypeScript/src/lib/HttpGetStatusThread.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ export class HttpGetStatusThread {
3838

3939
private _baseUrl: string;
4040

41-
private _inInnerLoop: boolean;
41+
private _inInnerLoop: boolean = false;
4242

43-
private _timer: NodeJS.Timer = null;
43+
private _timer: NodeJS.Timeout | undefined;
4444

4545
private _disposed: boolean = false;
4646

@@ -69,7 +69,7 @@ export class HttpGetStatusThread {
6969
this._disposed = true;
7070
}
7171

72-
private async doHttpGet(): Promise<ProjectToWatch[]> {
72+
private async doHttpGet(): Promise<ProjectToWatch[] | undefined> {
7373

7474
const requestObj = {
7575
headers: {},
@@ -101,9 +101,9 @@ export class HttpGetStatusThread {
101101

102102
log.info("GET response received: " + debugVal);
103103

104-
if (w == null || w === undefined) {
104+
if (!w) {
105105
log.error("Expected value not found for GET watchlist endpoint");
106-
return null;
106+
return undefined;
107107
}
108108

109109
const result = new Array<ProjectToWatch>();
@@ -113,7 +113,7 @@ export class HttpGetStatusThread {
113113
// Sanity check the JSON parsing
114114
if (!e.projectID || !e.pathToMonitor) {
115115
log.error("JSON parsing of GET watchlist endpoint failed with missing values");
116-
return null;
116+
return undefined;
117117
}
118118

119119
result.push(ProjectToWatch.createFromJson(e, false));
@@ -135,7 +135,7 @@ export class HttpGetStatusThread {
135135
authTokenWrapper.informBadToken(authToken);
136136
}
137137

138-
return null;
138+
return undefined;
139139
}
140140

141141
} catch (err) {
@@ -151,7 +151,7 @@ export class HttpGetStatusThread {
151151

152152
}
153153

154-
return null;
154+
return undefined;
155155
}
156156

157157
}
@@ -164,15 +164,15 @@ export class HttpGetStatusThread {
164164

165165
const delay = ExponentialBackoffUtil.getDefaultBackoffUtil(4000);
166166

167-
let result: ProjectToWatch[] = null;
167+
let result: ProjectToWatch[] | undefined;
168168

169169
while (!success && !this._disposed) {
170170

171171
result = await this.doHttpGet();
172172

173173
success = result != null;
174174

175-
if (!success) {
175+
if (!result) {
176176
log.error("HTTP get request failed");
177177
await delay.sleepAsync();
178178
delay.failIncrease();
@@ -192,7 +192,7 @@ export class HttpGetStatusThread {
192192

193193
}
194194
private resetTimer() {
195-
if (this._timer != null) {
195+
if (this._timer) {
196196
clearTimeout(this._timer);
197197
}
198198

0 commit comments

Comments
 (0)