@nsshunt/ststestrunner 1.1.104 → 1.1.105
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/dist/ststestrunner.cjs +355 -366
- package/dist/ststestrunner.cjs.map +1 -1
- package/dist/ststestrunner.mjs +354 -365
- package/dist/ststestrunner.mjs.map +1 -1
- package/package.json +1 -1
- package/types/libmodule/testCaseFhirBase.d.ts +6 -27
- package/types/libmodule/testCaseFhirBase.d.ts.map +1 -1
- package/types/libmodule/workerFhirTestCases.d.ts +34 -5
- package/types/libmodule/workerFhirTestCases.d.ts.map +1 -1
package/dist/ststestrunner.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AbstractRunnerExecutionWorker } from "@nsshunt/stsrunnerframework";
|
|
2
|
-
import chalk from "chalk";
|
|
3
2
|
import { STSAxiosConfig, Sleep, createAgentManager, isNode } from "@nsshunt/stsutils";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import axios from "axios";
|
|
4
5
|
import { FhirRESTClient, FhirSocketClientAllInOne, FhirSocketClientIndividual, createRetryAxiosClient } from "@nsshunt/stsfhirclient";
|
|
5
6
|
import http from "node:http";
|
|
6
7
|
import https from "node:https";
|
|
7
|
-
import axios from "axios";
|
|
8
8
|
//#region \0rolldown/runtime.js
|
|
9
9
|
var __defProp = Object.defineProperty;
|
|
10
10
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -379,190 +379,40 @@ var StatusCodes;
|
|
|
379
379
|
//#region src/libmodule/testCaseFhirBase.ts
|
|
380
380
|
var TestCaseFhirBase = class {
|
|
381
381
|
#options;
|
|
382
|
-
#randomDataRecordset = [];
|
|
383
382
|
#runner;
|
|
384
383
|
#runnerExecutionWorker;
|
|
385
|
-
#accesssToken = null;
|
|
386
384
|
#publishTelemetryCount = 0;
|
|
387
385
|
#maxBufferSize = 50;
|
|
388
386
|
#publishTelemetryTimeout = null;
|
|
389
387
|
#publishTelemetryTimeoutVal = 1e3;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
388
|
+
_RetryMap = [
|
|
389
|
+
100,
|
|
390
|
+
250,
|
|
391
|
+
500,
|
|
392
|
+
1e3,
|
|
393
|
+
2e3,
|
|
394
|
+
3e3
|
|
395
|
+
];
|
|
394
396
|
_id = crypto.randomUUID();
|
|
395
397
|
retryCount = 0;
|
|
396
398
|
maxAuthRetryCount = 5;
|
|
397
399
|
runnerDurationList = [];
|
|
398
|
-
_authMaxTimeout = 5e3;
|
|
399
|
-
accessTokenTime = performance.now();
|
|
400
|
-
newTokenLimitTime = 30;
|
|
401
|
-
restFhirClient = null;
|
|
402
|
-
defaultAgentOptions = {
|
|
403
|
-
keepAlive: true,
|
|
404
|
-
maxSockets: 10,
|
|
405
|
-
maxTotalSockets: 20,
|
|
406
|
-
maxFreeSockets: 10,
|
|
407
|
-
timeout: 6e4,
|
|
408
|
-
rejectUnauthorized: false
|
|
409
|
-
};
|
|
410
|
-
stressTestAgentOptions = {
|
|
411
|
-
keepAlive: true,
|
|
412
|
-
maxSockets: 200,
|
|
413
|
-
maxTotalSockets: 500,
|
|
414
|
-
maxFreeSockets: 50,
|
|
415
|
-
timeout: 3e4,
|
|
416
|
-
rejectUnauthorized: false
|
|
417
|
-
};
|
|
418
|
-
stressTestExtremeAgentOptions = {
|
|
419
|
-
keepAlive: true,
|
|
420
|
-
maxSockets: 500,
|
|
421
|
-
maxTotalSockets: 1e3,
|
|
422
|
-
maxFreeSockets: 500,
|
|
423
|
-
timeout: 3e4,
|
|
424
|
-
rejectUnauthorized: false
|
|
425
|
-
};
|
|
426
400
|
constructor(runnerExecutionWorker, runner) {
|
|
427
401
|
this.#options = runner.options;
|
|
428
402
|
this.#runnerExecutionWorker = runnerExecutionWorker;
|
|
429
403
|
this.#runner = runner;
|
|
430
|
-
this.#authAgentManager = this.GetAuthAgentManager();
|
|
431
404
|
}
|
|
432
405
|
get runnerExecutionWorker() {
|
|
433
406
|
return this.#runnerExecutionWorker;
|
|
434
407
|
}
|
|
435
408
|
ResetClient = () => {};
|
|
436
|
-
GetRESTClient = async () => {
|
|
437
|
-
if (this.restFhirClient) return this.restFhirClient;
|
|
438
|
-
const onRetryAttempt = (attempt, error, delayMs) => {
|
|
439
|
-
this.#runner.instrumentData.errorCount++;
|
|
440
|
-
this.#runner.instrumentData.requestCount++;
|
|
441
|
-
const message = `TestCaseFhirBase:onRetryAttempt(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
442
|
-
this.Warning(message);
|
|
443
|
-
this.#runner.instrumentData.message.push(chalk.red(message));
|
|
444
|
-
};
|
|
445
|
-
const fhirOptions = this.#options.fhirOptions;
|
|
446
|
-
const fhirRESTClient = new FhirRESTClient({
|
|
447
|
-
GetAccessToken: this.GetAccessToken,
|
|
448
|
-
user: "USR_user01@stsmda.com.au",
|
|
449
|
-
endpoint: fhirOptions.stsfhirserverendpoint,
|
|
450
|
-
stsfhirapiroot: fhirOptions.stsfhirapiroot,
|
|
451
|
-
stsfhirport: fhirOptions.stsfhirport,
|
|
452
|
-
logger: this.#runnerExecutionWorker.logger,
|
|
453
|
-
agentManager: this.GetFhirAgentManager(),
|
|
454
|
-
onRetryAttempt
|
|
455
|
-
});
|
|
456
|
-
this.restFhirClient = fhirRESTClient;
|
|
457
|
-
return fhirRESTClient;
|
|
458
|
-
};
|
|
459
|
-
GetAgentManager = (testingAgentOptions) => {
|
|
460
|
-
let agentManager = void 0;
|
|
461
|
-
let agentOptions = void 0;
|
|
462
|
-
switch (testingAgentOptions.nodeAgentMode) {
|
|
463
|
-
case "no-agent": break;
|
|
464
|
-
case "custom-agent-options":
|
|
465
|
-
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
466
|
-
else agentOptions = { ...this.defaultAgentOptions };
|
|
467
|
-
break;
|
|
468
|
-
case "default-agent-options":
|
|
469
|
-
agentOptions = { ...this.defaultAgentOptions };
|
|
470
|
-
break;
|
|
471
|
-
case "stress-test-agent-options":
|
|
472
|
-
agentOptions = { ...this.stressTestAgentOptions };
|
|
473
|
-
break;
|
|
474
|
-
case "stress-test-extreme-agent-options":
|
|
475
|
-
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
476
|
-
break;
|
|
477
|
-
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
478
|
-
}
|
|
479
|
-
if (agentOptions) agentManager = createAgentManager({
|
|
480
|
-
agentOptions,
|
|
481
|
-
httpAgentFactory(options) {
|
|
482
|
-
return new http.Agent(options);
|
|
483
|
-
},
|
|
484
|
-
httpsAgentFactory(options) {
|
|
485
|
-
return new https.Agent(options);
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
return agentManager;
|
|
489
|
-
};
|
|
490
|
-
GetFhirAgentManager = () => {
|
|
491
|
-
return this.GetAgentManager(this.#options.fhirOptions.stsfhiragentOptions);
|
|
492
|
-
};
|
|
493
|
-
GetAuthAgentManager = () => {
|
|
494
|
-
return this.GetAgentManager(this.#options.authOptions.asagentoptions);
|
|
495
|
-
};
|
|
496
|
-
GetFhirSocketClient = async () => {
|
|
497
|
-
try {
|
|
498
|
-
this.#clientSocketFetchCount++;
|
|
499
|
-
let fhirClient = this.runnerExecutionWorker.GetFhirClient();
|
|
500
|
-
if (fhirClient) return fhirClient;
|
|
501
|
-
if (this.runnerExecutionWorker.GetOnHold("fhirclient") === true) {
|
|
502
|
-
this.Debug(chalk.magenta(`[${this.runnerExecutionWorker.id}] [${this._id}] fhir client does not exist - some other client setting up the new client (on hold/lock) - waiting ...`));
|
|
503
|
-
try {
|
|
504
|
-
const start = performance.now();
|
|
505
|
-
await this.runnerExecutionWorker.WaitOnHold("fhirclient", 6e4);
|
|
506
|
-
this.Debug(chalk.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] hold (lock) released after: [${performance.now() - start}ms]`));
|
|
507
|
-
const fhirClient = this.runnerExecutionWorker.GetFhirClient();
|
|
508
|
-
if (fhirClient) {
|
|
509
|
-
this.Debug(chalk.green(`[${this.runnerExecutionWorker.id}] [${this._id}] Getting existing fhir client (post hold release)`));
|
|
510
|
-
return fhirClient;
|
|
511
|
-
} else {
|
|
512
|
-
this.Error(chalk.red(`[${this.runnerExecutionWorker.id}] [${this._id}] Could not get existing fhir client (post hold release)`));
|
|
513
|
-
this.Error(chalk.red(`continue anyway ...`));
|
|
514
|
-
}
|
|
515
|
-
} catch (error) {
|
|
516
|
-
this.Error(chalk.red(`GetFhirSocketClient(): Error: [${error}]`));
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
const start = performance.now();
|
|
520
|
-
this.Debug(chalk.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] fhir client does not exist - setting up new client`));
|
|
521
|
-
this.Debug(chalk.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] setting hold (lock)`));
|
|
522
|
-
this.runnerExecutionWorker.SetOnHold("fhirclient");
|
|
523
|
-
const fhirOptions = this.#options.fhirOptions;
|
|
524
|
-
const options = {
|
|
525
|
-
fhirServerEndpoint: fhirOptions.stsfhirserverendpoint,
|
|
526
|
-
fhirapiroot: fhirOptions.stsfhirapiroot,
|
|
527
|
-
fhirServerPort: fhirOptions.stsfhirport,
|
|
528
|
-
socketClientName: fhirOptions.stsfhirsocketname,
|
|
529
|
-
socketIoCustomPath: fhirOptions.stsfhirsocketcustompath,
|
|
530
|
-
timeout: fhirOptions.stsfhirsockettimeout,
|
|
531
|
-
baseUrl: fhirOptions.stsfhirbaseurl,
|
|
532
|
-
agentManager: this.GetFhirAgentManager(),
|
|
533
|
-
joinRooms: [],
|
|
534
|
-
logger: this.#runnerExecutionWorker.logger,
|
|
535
|
-
verboseLogging: true,
|
|
536
|
-
GetConnectionAccessToken: this.GetAccessTokenForSocketClientAccess,
|
|
537
|
-
GetAccessToken: this.GetAccessToken
|
|
538
|
-
};
|
|
539
|
-
if (this.runner.options.fhirOptions.stsfhirsocketclientmode === "socket-client-all-in-one") fhirClient = new FhirSocketClientAllInOne("FhirSocketClient", options);
|
|
540
|
-
else fhirClient = new FhirSocketClientIndividual("FhirSocketClient", options);
|
|
541
|
-
await fhirClient.WaitForSocketConnected();
|
|
542
|
-
this.Debug(chalk.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] setting fhir client into object`));
|
|
543
|
-
this.runnerExecutionWorker.SetFhirClient(fhirClient);
|
|
544
|
-
this.runnerExecutionWorker.ReleaseOnHold("fhirclient");
|
|
545
|
-
this.Debug(chalk.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] release hold (lock) Time taken for socket connection and set object: [${performance.now() - start}ms]`));
|
|
546
|
-
return fhirClient;
|
|
547
|
-
} catch (error) {
|
|
548
|
-
this.Error(error);
|
|
549
|
-
throw error;
|
|
550
|
-
}
|
|
551
|
-
};
|
|
552
|
-
#LogMessage = (message) => {};
|
|
553
|
-
Debug = (message) => {
|
|
554
|
-
this.#runnerExecutionWorker.logger.debug(message);
|
|
555
|
-
};
|
|
556
409
|
Error = (message) => {
|
|
557
410
|
this.#runnerExecutionWorker.logger.error(message);
|
|
558
411
|
this.#runner.instrumentData.message.push(chalk.red(`${message}`));
|
|
559
412
|
};
|
|
560
|
-
|
|
561
|
-
this.#runnerExecutionWorker.logger.
|
|
413
|
+
Debug = (message) => {
|
|
414
|
+
this.#runnerExecutionWorker.logger.debug(message);
|
|
562
415
|
};
|
|
563
|
-
get accesssToken() {
|
|
564
|
-
return this.#accesssToken;
|
|
565
|
-
}
|
|
566
416
|
get runner() {
|
|
567
417
|
return this.#runner;
|
|
568
418
|
}
|
|
@@ -605,125 +455,6 @@ var TestCaseFhirBase = class {
|
|
|
605
455
|
this.#runner.instrumentData.rx = 0;
|
|
606
456
|
await this.SleepImmediate();
|
|
607
457
|
};
|
|
608
|
-
ExtractOrigin = (uri) => {
|
|
609
|
-
const match = uri.match(this.#originRegex);
|
|
610
|
-
return match ? match[1] : null;
|
|
611
|
-
};
|
|
612
|
-
GetAPITokenFromAuthServerUsingScope = async (options) => {
|
|
613
|
-
const { scope, clientId, authClientSecret, endPoint } = options;
|
|
614
|
-
let stage = "1";
|
|
615
|
-
try {
|
|
616
|
-
stage = "2";
|
|
617
|
-
const scopes = scope.split(" ");
|
|
618
|
-
let origin = null;
|
|
619
|
-
let error = null;
|
|
620
|
-
stage = "3";
|
|
621
|
-
for (let i = 0; i < scopes.length; i++) {
|
|
622
|
-
const s = scopes[i];
|
|
623
|
-
if (!origin) {
|
|
624
|
-
origin = this.ExtractOrigin(s);
|
|
625
|
-
if (!origin) {
|
|
626
|
-
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
627
|
-
break;
|
|
628
|
-
}
|
|
629
|
-
} else {
|
|
630
|
-
const nextOrigin = this.ExtractOrigin(s);
|
|
631
|
-
if (!nextOrigin) {
|
|
632
|
-
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
633
|
-
break;
|
|
634
|
-
} else if (origin.localeCompare(nextOrigin) !== 0) {
|
|
635
|
-
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not all from the same client API. All scopes must come from the same client API.`);
|
|
636
|
-
break;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
stage = "4";
|
|
641
|
-
if (error) throw error;
|
|
642
|
-
stage = "5";
|
|
643
|
-
const payload = {
|
|
644
|
-
client_id: clientId,
|
|
645
|
-
client_secret: authClientSecret,
|
|
646
|
-
scope,
|
|
647
|
-
grant_type: "client_credentials"
|
|
648
|
-
};
|
|
649
|
-
stage = "6";
|
|
650
|
-
const url = endPoint ? `${endPoint}${this.#options.authOptions.asoauthapiroot}/token` : `${this.#options.authOptions.asendpoint}:${this.#options.authOptions.asport}${this.#options.authOptions.asoauthapiroot}/token`;
|
|
651
|
-
stage = `6.5: url: [${url}] payload: [${JSON.stringify(payload)}]`;
|
|
652
|
-
const axiosConfig = new STSAxiosConfig(url, "post").withDefaultHeaders().withData(payload);
|
|
653
|
-
if (this.#authAgentManager) axiosConfig.withAgentManager(this.#authAgentManager);
|
|
654
|
-
const retVal = await createRetryAxiosClient({
|
|
655
|
-
maxRetries: 4,
|
|
656
|
-
retryDelayMs: 300,
|
|
657
|
-
retryJitterMs: 150,
|
|
658
|
-
maxRetryDurationMs: 5e3,
|
|
659
|
-
onRetryAttempt: (attempt, error, delayMs) => {
|
|
660
|
-
this.#runner.instrumentData.authenticationErrorCount++;
|
|
661
|
-
this.#runner.instrumentData.authenticationRetryCount++;
|
|
662
|
-
const message = `TestCaseFhirBase:GetAPITokenFromAuthServerUsingScope(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
663
|
-
this.Warning(message);
|
|
664
|
-
this.#runner.instrumentData.message.push(chalk.red(message));
|
|
665
|
-
}
|
|
666
|
-
})(url, axiosConfig.config);
|
|
667
|
-
this.#runner.instrumentData.authenticationCount++;
|
|
668
|
-
stage = "7";
|
|
669
|
-
if (retVal.status) {
|
|
670
|
-
if (retVal.status !== 200) this.Warning(chalk.magenta(`TestCaseFhirBase:GetAPITokenFromAuthServerUsingScope(): [${this._id}] Invalid response from server: [${retVal.status}]`));
|
|
671
|
-
} else throw new Error(chalk.red(`No retVal.status)`));
|
|
672
|
-
stage = "8";
|
|
673
|
-
if (retVal.data) {
|
|
674
|
-
stage = "9";
|
|
675
|
-
if (retVal.data.access_token) {
|
|
676
|
-
stage = "12";
|
|
677
|
-
return retVal.data.access_token;
|
|
678
|
-
} else {
|
|
679
|
-
stage = "13";
|
|
680
|
-
throw new Error(`No retVal.data.access_token)`);
|
|
681
|
-
}
|
|
682
|
-
} else {
|
|
683
|
-
stage = "14";
|
|
684
|
-
throw new Error(`No retVal.data)`);
|
|
685
|
-
}
|
|
686
|
-
} catch (error) {
|
|
687
|
-
this.Error(error);
|
|
688
|
-
let details = "None available.";
|
|
689
|
-
if (error.response && error.response.data) try {
|
|
690
|
-
details = JSON.stringify(error.response.data);
|
|
691
|
-
} catch (error) {
|
|
692
|
-
details = `Could not JSON.stringify(error.response.data)`;
|
|
693
|
-
}
|
|
694
|
-
error.message = `TestCaseFhirBase:GetAPITokenFromAuthServerUsingScope(): [${this._id}] Error: [${error}], Stage: [${stage}], Details: [${details}]`;
|
|
695
|
-
throw error;
|
|
696
|
-
}
|
|
697
|
-
};
|
|
698
|
-
GetAccessTokenForSocketClientAccess = async () => {
|
|
699
|
-
const timeout = setTimeout(() => {
|
|
700
|
-
this.Warning(`TestCaseFhirBase:GetAccessTokenForSocketClientAccess(): [${this._id}] Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`);
|
|
701
|
-
}, this._authMaxTimeout);
|
|
702
|
-
const start = performance.now();
|
|
703
|
-
try {
|
|
704
|
-
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:SocketConnection`.split(" ").sort().join(" ");
|
|
705
|
-
const authendpointUrl = `${this.#options.authOptions.asendpoint}:${this.#options.authOptions.asport}`;
|
|
706
|
-
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
707
|
-
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
708
|
-
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
709
|
-
scope: scopes,
|
|
710
|
-
endPoint: authendpointUrl
|
|
711
|
-
});
|
|
712
|
-
clearTimeout(timeout);
|
|
713
|
-
const totalTime = performance.now() - start;
|
|
714
|
-
if (totalTime > this._authMaxTimeout) this.Warning(chalk.magenta(`TestCaseFhirBase:GetAccessTokenForSocketClientAccess(): [${this._id}] The total time for getting the access token: [${totalTime}]`));
|
|
715
|
-
return retVal;
|
|
716
|
-
} catch (error) {
|
|
717
|
-
clearTimeout(timeout);
|
|
718
|
-
const totalTime = performance.now() - start;
|
|
719
|
-
error.message = `TestCaseFhirBase:GetAccessTokenForSocketClientAccess(): [${this._id}] Error: [${error}], Duration until error: [${totalTime}]`;
|
|
720
|
-
this.Error(error);
|
|
721
|
-
return "";
|
|
722
|
-
}
|
|
723
|
-
};
|
|
724
|
-
ResetAccessToken = () => {
|
|
725
|
-
this.#accesssToken = null;
|
|
726
|
-
};
|
|
727
458
|
HandleError = (error) => {
|
|
728
459
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] Error: [${error}]`));
|
|
729
460
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] description: [${this.runner.options.description}]`));
|
|
@@ -738,48 +469,18 @@ var TestCaseFhirBase = class {
|
|
|
738
469
|
if (axiosError.response.status === StatusCodes.UNAUTHORIZED) {
|
|
739
470
|
this.runner.instrumentData.authenticationErrorCount++;
|
|
740
471
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
|
|
741
|
-
this.ResetAccessToken();
|
|
472
|
+
this.runnerExecutionWorker.ResetAccessToken();
|
|
742
473
|
return true;
|
|
743
474
|
}
|
|
744
475
|
} else this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] AXIOS Error = [${axiosError}]`));
|
|
745
476
|
} else if (error.message === "UNAUTHORIZED") {
|
|
746
477
|
this.runner.instrumentData.authenticationErrorCount++;
|
|
747
478
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
|
|
748
|
-
this.ResetAccessToken();
|
|
479
|
+
this.runnerExecutionWorker.ResetAccessToken();
|
|
749
480
|
return true;
|
|
750
481
|
}
|
|
751
482
|
return false;
|
|
752
483
|
};
|
|
753
|
-
GetAccessToken = async () => {
|
|
754
|
-
let timeout = void 0;
|
|
755
|
-
let start = performance.now();
|
|
756
|
-
try {
|
|
757
|
-
if (this.#accesssToken) return this.#accesssToken;
|
|
758
|
-
timeout = setTimeout(() => {
|
|
759
|
-
this.Warning(chalk.magenta(`TestCaseFhirBase:GetAccessToken(): [${this._id}] Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`));
|
|
760
|
-
}, this._authMaxTimeout);
|
|
761
|
-
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:All`.split(" ").sort().join(" ");
|
|
762
|
-
const authendpointUrl = `${this.#options.authOptions.asendpoint}:${this.#options.authOptions.asport}`;
|
|
763
|
-
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
764
|
-
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
765
|
-
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
766
|
-
scope: scopes,
|
|
767
|
-
endPoint: authendpointUrl
|
|
768
|
-
});
|
|
769
|
-
this.accessTokenTime = performance.now();
|
|
770
|
-
this.#accesssToken = retVal;
|
|
771
|
-
if (timeout) clearTimeout(timeout);
|
|
772
|
-
const totalTime = performance.now() - start;
|
|
773
|
-
if (totalTime > this._authMaxTimeout) this.Warning(chalk.magenta(`TestCaseFhirBase:GetAccessToken(): [${this._id}] The total time for getting the access token: [${totalTime}]`));
|
|
774
|
-
return retVal;
|
|
775
|
-
} catch (error) {
|
|
776
|
-
if (timeout) clearTimeout(timeout);
|
|
777
|
-
const totalTime = performance.now() - start;
|
|
778
|
-
error.message = `TestCaseFhirBase:GetAccessToken(): [${this._id}] Error: [${error}], Duration until error: [${totalTime}]`;
|
|
779
|
-
this.Error(error);
|
|
780
|
-
return "";
|
|
781
|
-
}
|
|
782
|
-
};
|
|
783
484
|
GetPersonRecord = async (prefix, index, version) => {
|
|
784
485
|
const { workerIndex, runnerIndex, runId } = this.#options;
|
|
785
486
|
const useId = `${prefix}-${index}`;
|
|
@@ -806,37 +507,12 @@ var TestCaseFhirBase = class {
|
|
|
806
507
|
}
|
|
807
508
|
};
|
|
808
509
|
};
|
|
809
|
-
StartTestDataLoad = async () => {
|
|
810
|
-
this.Debug(chalk.magenta(`StartTestDataLoad(): Start ...`));
|
|
811
|
-
let VU = 0;
|
|
812
|
-
const blockNum = VU * 200;
|
|
813
|
-
const blocksToLoad = 20;
|
|
814
|
-
for (let i = 0; i < blocksToLoad; i++) {
|
|
815
|
-
const recordId = `stsres_${blockNum + i}`;
|
|
816
|
-
const retVal = await (await this.GetFhirSocketClient()).GetResource("Person", recordId);
|
|
817
|
-
if (retVal) {
|
|
818
|
-
const recordsetData = retVal.body.address;
|
|
819
|
-
if (recordsetData) {
|
|
820
|
-
const qqq = recordsetData[0].text;
|
|
821
|
-
for (let j = 0; j < qqq.length; j++) this.#randomDataRecordset.push(qqq[j]);
|
|
822
|
-
this.Error(chalk.magenta(this.#randomDataRecordset.length));
|
|
823
|
-
}
|
|
824
|
-
} else this.Error(chalk.magenta(`StartTestDataLoad(): Could not get person records.`));
|
|
825
|
-
await Sleep(10);
|
|
826
|
-
}
|
|
827
|
-
this.Debug(`Finished load for VU: [${VU}]`);
|
|
828
|
-
this.Debug(`First 10 entries`);
|
|
829
|
-
for (let i = 0; i < 10; i++) this.Debug(this.#randomDataRecordset[i].id);
|
|
830
|
-
this.Debug(`block num: [${blockNum}] length: [${this.#randomDataRecordset.length}] VU: [${VU}]`);
|
|
831
|
-
this.Debug(chalk.magenta(`StartTestDataLoad(): End`));
|
|
832
|
-
};
|
|
833
510
|
#ForcePublishTelemetryData = async () => {
|
|
834
511
|
await this.#PublishTelemetryData();
|
|
835
512
|
};
|
|
836
513
|
#SetupTimeout = async () => {
|
|
837
514
|
if (!this.#publishTelemetryTimeout) {
|
|
838
515
|
this.#publishTelemetryTimeout = setTimeout(async () => {
|
|
839
|
-
this.#LogMessage(chalk.yellow(` **** TIMEOUT **** `));
|
|
840
516
|
await this.#PublishTelemetryData();
|
|
841
517
|
this.#publishTelemetryCount = 0;
|
|
842
518
|
this.#publishTelemetryTimeout = null;
|
|
@@ -846,7 +522,6 @@ var TestCaseFhirBase = class {
|
|
|
846
522
|
};
|
|
847
523
|
PublishTelemetry = async () => {
|
|
848
524
|
this.#publishTelemetryCount++;
|
|
849
|
-
this.#LogMessage(chalk.red(this.#publishTelemetryCount));
|
|
850
525
|
if (this.#publishTelemetryCount % this.#maxBufferSize === 0) {
|
|
851
526
|
this.#publishTelemetryCount = 0;
|
|
852
527
|
if (this.#publishTelemetryTimeout) {
|
|
@@ -859,7 +534,6 @@ var TestCaseFhirBase = class {
|
|
|
859
534
|
};
|
|
860
535
|
#OutputLogMessage = async (message) => {
|
|
861
536
|
const messageOutput = chalk.grey(message);
|
|
862
|
-
this.#LogMessage(messageOutput);
|
|
863
537
|
this.#runner.instrumentData.message.push(messageOutput);
|
|
864
538
|
await this.PublishTelemetry();
|
|
865
539
|
};
|
|
@@ -907,12 +581,6 @@ var TestCaseFhirBase = class {
|
|
|
907
581
|
await this.#ForcePublishTelemetryData();
|
|
908
582
|
return true;
|
|
909
583
|
};
|
|
910
|
-
GetClient = async () => {
|
|
911
|
-
let client;
|
|
912
|
-
if (this.runner.options.fhirOptions.stsfhirsocketclientmode === "no-socket-client") client = await this.GetRESTClient();
|
|
913
|
-
else client = await this.GetFhirSocketClient();
|
|
914
|
-
return client;
|
|
915
|
-
};
|
|
916
584
|
_GetDetail = () => {
|
|
917
585
|
return `testType: [${this.runner.options.testType}], description: [${this.runner.options.description}], workerManagerId: [${this.runner.workerManagerId}], Iteration: [${this.runner.iteration}]`;
|
|
918
586
|
};
|
|
@@ -929,14 +597,6 @@ var TestCaseFhirBase = class {
|
|
|
929
597
|
this.retryCount = 0;
|
|
930
598
|
return this._ExecuteQuery();
|
|
931
599
|
};
|
|
932
|
-
_RetryMap = [
|
|
933
|
-
100,
|
|
934
|
-
250,
|
|
935
|
-
500,
|
|
936
|
-
1e3,
|
|
937
|
-
2e3,
|
|
938
|
-
3e3
|
|
939
|
-
];
|
|
940
600
|
_ExecuteQuery = async () => {
|
|
941
601
|
try {
|
|
942
602
|
return await this.PerformExecuteQuery();
|
|
@@ -959,6 +619,9 @@ var TestCaseFhirBase = class {
|
|
|
959
619
|
else throw error;
|
|
960
620
|
}
|
|
961
621
|
};
|
|
622
|
+
GetClient = async () => {
|
|
623
|
+
return this.runnerExecutionWorker.GetClient();
|
|
624
|
+
};
|
|
962
625
|
};
|
|
963
626
|
//#endregion
|
|
964
627
|
//#region src/libmodule/testCaseFhirQueryBase.ts
|
|
@@ -1040,9 +703,9 @@ var TestCaseFhirQueryBase = class extends TestCaseFhirBase {
|
|
|
1040
703
|
var TestCaseFhir01 = class extends TestCaseFhirQueryBase {
|
|
1041
704
|
PerformExecuteQuery = async () => {
|
|
1042
705
|
const __snapshot1 = performance.now();
|
|
1043
|
-
await this.GetAccessToken();
|
|
706
|
+
await this.runnerExecutionWorker.GetAccessToken();
|
|
1044
707
|
this._CheckOutputLongDurationError(__snapshot1, "await this.GetAccessToken()");
|
|
1045
|
-
this.ResetAccessToken();
|
|
708
|
+
this.runnerExecutionWorker.ResetAccessToken();
|
|
1046
709
|
return null;
|
|
1047
710
|
};
|
|
1048
711
|
};
|
|
@@ -36377,20 +36040,30 @@ var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
|
36377
36040
|
fhirClient = void 0;
|
|
36378
36041
|
_id = crypto.randomUUID();
|
|
36379
36042
|
_onHoldKeys = {};
|
|
36043
|
+
#accesssToken = null;
|
|
36044
|
+
_authMaxTimeout = 5e3;
|
|
36045
|
+
#originRegex = /^(api:\/\/\w+)/;
|
|
36046
|
+
#authAgentManager;
|
|
36047
|
+
restFhirClient = null;
|
|
36048
|
+
logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
|
|
36380
36049
|
constructor(options) {
|
|
36381
36050
|
super();
|
|
36382
36051
|
this._options = options;
|
|
36383
36052
|
this._resourceDataGenerator = new ResourceDataGenerator();
|
|
36053
|
+
this.#authAgentManager = this.GetAuthAgentManager();
|
|
36384
36054
|
}
|
|
36055
|
+
Warning = (message) => {
|
|
36056
|
+
this.logger.warn(`${this.logPrefix}${message}`);
|
|
36057
|
+
};
|
|
36058
|
+
Error = (message) => {
|
|
36059
|
+
this.logger.error(`${this.logPrefix}${message}`);
|
|
36060
|
+
};
|
|
36061
|
+
Debug = (message) => {
|
|
36062
|
+
this.logger.debug(`${this.logPrefix}${message}`);
|
|
36063
|
+
};
|
|
36385
36064
|
get id() {
|
|
36386
36065
|
return this._id;
|
|
36387
36066
|
}
|
|
36388
|
-
GetFhirClient = () => {
|
|
36389
|
-
return this.fhirClient;
|
|
36390
|
-
};
|
|
36391
|
-
SetFhirClient = (fhirClient) => {
|
|
36392
|
-
this.fhirClient = fhirClient;
|
|
36393
|
-
};
|
|
36394
36067
|
get resourceDataGenerator() {
|
|
36395
36068
|
return this._resourceDataGenerator;
|
|
36396
36069
|
}
|
|
@@ -36401,9 +36074,9 @@ var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
|
36401
36074
|
return AsyncRunnerFactory.CreateAsyncRunner(this, testRunnerTelemetryPayload);
|
|
36402
36075
|
};
|
|
36403
36076
|
async ProcessPreTerminateWorkerMessage(messagePayload) {
|
|
36404
|
-
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: [${JSON.stringify(messagePayload, null, 2)}]`));
|
|
36077
|
+
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): [${JSON.stringify(messagePayload, null, 2)}]`));
|
|
36405
36078
|
if (this.fhirClient) {
|
|
36406
|
-
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: ResetSocket()`));
|
|
36079
|
+
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): ResetSocket()`));
|
|
36407
36080
|
this.fhirClient.ResetSocket();
|
|
36408
36081
|
this.fhirClient = void 0;
|
|
36409
36082
|
}
|
|
@@ -36422,7 +36095,7 @@ var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
|
36422
36095
|
for (;;) {
|
|
36423
36096
|
if (this._onHoldKeys[holdKey]) await Sleep(100);
|
|
36424
36097
|
else break;
|
|
36425
|
-
if (performance.now() - start > timeout) throw new Error(`WaitOnHold
|
|
36098
|
+
if (performance.now() - start > timeout) throw new Error(`WorkerFhirTestCases:WaitOnHold(): Timeout: [${timeout}] reached.`);
|
|
36426
36099
|
}
|
|
36427
36100
|
return true;
|
|
36428
36101
|
};
|
|
@@ -36432,6 +36105,322 @@ var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
|
36432
36105
|
ReleaseOnHold = (holdKey) => {
|
|
36433
36106
|
delete this._onHoldKeys[holdKey];
|
|
36434
36107
|
};
|
|
36108
|
+
defaultAgentOptions = {
|
|
36109
|
+
keepAlive: true,
|
|
36110
|
+
maxSockets: 10,
|
|
36111
|
+
maxTotalSockets: 20,
|
|
36112
|
+
maxFreeSockets: 10,
|
|
36113
|
+
timeout: 6e4,
|
|
36114
|
+
rejectUnauthorized: false
|
|
36115
|
+
};
|
|
36116
|
+
stressTestAgentOptions = {
|
|
36117
|
+
keepAlive: true,
|
|
36118
|
+
maxSockets: 200,
|
|
36119
|
+
maxTotalSockets: 500,
|
|
36120
|
+
maxFreeSockets: 50,
|
|
36121
|
+
timeout: 3e4,
|
|
36122
|
+
rejectUnauthorized: false
|
|
36123
|
+
};
|
|
36124
|
+
stressTestExtremeAgentOptions = {
|
|
36125
|
+
keepAlive: true,
|
|
36126
|
+
maxSockets: 500,
|
|
36127
|
+
maxTotalSockets: 1e3,
|
|
36128
|
+
maxFreeSockets: 500,
|
|
36129
|
+
timeout: 3e4,
|
|
36130
|
+
rejectUnauthorized: false
|
|
36131
|
+
};
|
|
36132
|
+
GetAgentManager = (testingAgentOptions) => {
|
|
36133
|
+
let agentManager = void 0;
|
|
36134
|
+
let agentOptions = void 0;
|
|
36135
|
+
switch (testingAgentOptions.nodeAgentMode) {
|
|
36136
|
+
case "no-agent": break;
|
|
36137
|
+
case "custom-agent-options":
|
|
36138
|
+
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
36139
|
+
else agentOptions = { ...this.defaultAgentOptions };
|
|
36140
|
+
break;
|
|
36141
|
+
case "default-agent-options":
|
|
36142
|
+
agentOptions = { ...this.defaultAgentOptions };
|
|
36143
|
+
break;
|
|
36144
|
+
case "stress-test-agent-options":
|
|
36145
|
+
agentOptions = { ...this.stressTestAgentOptions };
|
|
36146
|
+
break;
|
|
36147
|
+
case "stress-test-extreme-agent-options":
|
|
36148
|
+
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
36149
|
+
break;
|
|
36150
|
+
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
36151
|
+
}
|
|
36152
|
+
if (agentOptions) agentManager = createAgentManager({
|
|
36153
|
+
agentOptions,
|
|
36154
|
+
httpAgentFactory(options) {
|
|
36155
|
+
return new http.Agent(options);
|
|
36156
|
+
},
|
|
36157
|
+
httpsAgentFactory(options) {
|
|
36158
|
+
return new https.Agent(options);
|
|
36159
|
+
}
|
|
36160
|
+
});
|
|
36161
|
+
return agentManager;
|
|
36162
|
+
};
|
|
36163
|
+
GetFhirAgentManager = () => {
|
|
36164
|
+
return this.GetAgentManager(this._options.fhirOptions.stsfhiragentOptions);
|
|
36165
|
+
};
|
|
36166
|
+
GetAuthAgentManager = () => {
|
|
36167
|
+
return this.GetAgentManager(this._options.authOptions.asagentoptions);
|
|
36168
|
+
};
|
|
36169
|
+
ExtractOrigin = (uri) => {
|
|
36170
|
+
const match = uri.match(this.#originRegex);
|
|
36171
|
+
return match ? match[1] : null;
|
|
36172
|
+
};
|
|
36173
|
+
GetAPITokenFromAuthServerUsingScope = async (options) => {
|
|
36174
|
+
const { scope, clientId, authClientSecret, endPoint } = options;
|
|
36175
|
+
let stage = "1";
|
|
36176
|
+
try {
|
|
36177
|
+
stage = "2";
|
|
36178
|
+
const scopes = scope.split(" ");
|
|
36179
|
+
let origin = null;
|
|
36180
|
+
let error = null;
|
|
36181
|
+
stage = "3";
|
|
36182
|
+
for (let i = 0; i < scopes.length; i++) {
|
|
36183
|
+
const s = scopes[i];
|
|
36184
|
+
if (!origin) {
|
|
36185
|
+
origin = this.ExtractOrigin(s);
|
|
36186
|
+
if (!origin) {
|
|
36187
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
36188
|
+
break;
|
|
36189
|
+
}
|
|
36190
|
+
} else {
|
|
36191
|
+
const nextOrigin = this.ExtractOrigin(s);
|
|
36192
|
+
if (!nextOrigin) {
|
|
36193
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
36194
|
+
break;
|
|
36195
|
+
} else if (origin.localeCompare(nextOrigin) !== 0) {
|
|
36196
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not all from the same client API. All scopes must come from the same client API.`);
|
|
36197
|
+
break;
|
|
36198
|
+
}
|
|
36199
|
+
}
|
|
36200
|
+
}
|
|
36201
|
+
stage = "4";
|
|
36202
|
+
if (error) throw error;
|
|
36203
|
+
stage = "5";
|
|
36204
|
+
const payload = {
|
|
36205
|
+
client_id: clientId,
|
|
36206
|
+
client_secret: authClientSecret,
|
|
36207
|
+
scope,
|
|
36208
|
+
grant_type: "client_credentials"
|
|
36209
|
+
};
|
|
36210
|
+
stage = "6";
|
|
36211
|
+
const url = endPoint ? `${endPoint}${this._options.authOptions.asoauthapiroot}/token` : `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}${this._options.authOptions.asoauthapiroot}/token`;
|
|
36212
|
+
stage = `6.5: url: [${url}] payload: [${JSON.stringify(payload)}]`;
|
|
36213
|
+
const axiosConfig = new STSAxiosConfig(url, "post").withDefaultHeaders().withData(payload);
|
|
36214
|
+
if (this.#authAgentManager) axiosConfig.withAgentManager(this.#authAgentManager);
|
|
36215
|
+
const retVal = await createRetryAxiosClient({
|
|
36216
|
+
maxRetries: 4,
|
|
36217
|
+
retryDelayMs: 300,
|
|
36218
|
+
retryJitterMs: 150,
|
|
36219
|
+
maxRetryDurationMs: 5e3,
|
|
36220
|
+
onRetryAttempt: (attempt, error, delayMs) => {
|
|
36221
|
+
this._options.runner.instrumentData.authenticationErrorCount++;
|
|
36222
|
+
this._options.runner.instrumentData.authenticationRetryCount++;
|
|
36223
|
+
const message = `GetAPITokenFromAuthServerUsingScope(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
36224
|
+
this.Warning(message);
|
|
36225
|
+
this._options.runner.instrumentData.message.push(chalk.red(message));
|
|
36226
|
+
}
|
|
36227
|
+
})(url, axiosConfig.config);
|
|
36228
|
+
this._options.runner.instrumentData.authenticationCount++;
|
|
36229
|
+
stage = "7";
|
|
36230
|
+
if (retVal.status) {
|
|
36231
|
+
if (retVal.status !== 200) this.Warning(chalk.magenta(`GetAPITokenFromAuthServerUsingScope(): [${this._id}] Invalid response from server: [${retVal.status}]`));
|
|
36232
|
+
} else throw new Error(chalk.red(`No retVal.status)`));
|
|
36233
|
+
stage = "8";
|
|
36234
|
+
if (retVal.data) {
|
|
36235
|
+
stage = "9";
|
|
36236
|
+
if (retVal.data.access_token) {
|
|
36237
|
+
stage = "12";
|
|
36238
|
+
return retVal.data.access_token;
|
|
36239
|
+
} else {
|
|
36240
|
+
stage = "13";
|
|
36241
|
+
throw new Error(`No retVal.data.access_token)`);
|
|
36242
|
+
}
|
|
36243
|
+
} else {
|
|
36244
|
+
stage = "14";
|
|
36245
|
+
throw new Error(`No retVal.data)`);
|
|
36246
|
+
}
|
|
36247
|
+
} catch (error) {
|
|
36248
|
+
this.Error(error);
|
|
36249
|
+
let details = "None available.";
|
|
36250
|
+
if (error.response && error.response.data) try {
|
|
36251
|
+
details = JSON.stringify(error.response.data);
|
|
36252
|
+
} catch (error) {
|
|
36253
|
+
details = `Could not JSON.stringify(error.response.data)`;
|
|
36254
|
+
}
|
|
36255
|
+
error.message = `${this.logPrefix}GetAPITokenFromAuthServerUsingScope(): Error: [${error}], Stage: [${stage}], Details: [${details}]`;
|
|
36256
|
+
throw error;
|
|
36257
|
+
}
|
|
36258
|
+
};
|
|
36259
|
+
GetAccessToken = async () => {
|
|
36260
|
+
let timeout = void 0;
|
|
36261
|
+
const start = performance.now();
|
|
36262
|
+
try {
|
|
36263
|
+
if (this.#accesssToken) return this.#accesssToken;
|
|
36264
|
+
const lockKey = "GetAccessToken";
|
|
36265
|
+
const lockTimeout = 6e4;
|
|
36266
|
+
if (this.GetOnHold(lockKey) === true) {
|
|
36267
|
+
this.Debug(chalk.magenta(`GetAccessToken(): accesssToken does not exist - some other client setting up the new accesssToken (on hold/lock), lock key: [${lockKey}] - waiting ...`));
|
|
36268
|
+
try {
|
|
36269
|
+
const miniStart = performance.now();
|
|
36270
|
+
await this.WaitOnHold(lockKey, lockTimeout);
|
|
36271
|
+
this.Debug(chalk.yellow(`GetAccessToken(): hold (lock) released after: [${performance.now() - miniStart}ms], lock key: [${lockKey}]`));
|
|
36272
|
+
if (this.#accesssToken) {
|
|
36273
|
+
this.Debug(chalk.green(`GetAccessToken(): Getting existing accesssToken (post hold release), lock key: [${lockKey}]`));
|
|
36274
|
+
return this.#accesssToken;
|
|
36275
|
+
} else {
|
|
36276
|
+
this.Error(chalk.red(`GetAccessToken(): Could not get existing accesssToken (post hold release), lock key: [${lockKey}]`));
|
|
36277
|
+
this.Error(chalk.red(`GetAccessToken(): continue anyway ...`));
|
|
36278
|
+
}
|
|
36279
|
+
} catch (error) {
|
|
36280
|
+
this.Error(chalk.red(`GetAccessToken(): Error: [${error}]`));
|
|
36281
|
+
}
|
|
36282
|
+
}
|
|
36283
|
+
this.Debug(chalk.yellow(`GetAccessToken(): accesssToken does not exist - setting up new accesssToken`));
|
|
36284
|
+
this.Debug(chalk.yellow(`GetAccessToken(): setting hold (lock), lock key: [${lockKey}]`));
|
|
36285
|
+
this.SetOnHold(lockKey);
|
|
36286
|
+
timeout = setTimeout(() => {
|
|
36287
|
+
this.Warning(chalk.magenta(`GetAccessToken(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`));
|
|
36288
|
+
}, this._authMaxTimeout);
|
|
36289
|
+
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:All`.split(" ").sort().join(" ");
|
|
36290
|
+
const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
|
|
36291
|
+
const workingAaccesssToken = await this.GetAPITokenFromAuthServerUsingScope({
|
|
36292
|
+
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
36293
|
+
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
36294
|
+
scope: scopes,
|
|
36295
|
+
endPoint: authendpointUrl
|
|
36296
|
+
});
|
|
36297
|
+
if (timeout) clearTimeout(timeout);
|
|
36298
|
+
const totalTime = performance.now() - start;
|
|
36299
|
+
if (totalTime > this._authMaxTimeout) this.Warning(chalk.magenta(`GetAccessToken(): The total time for getting the access token: [${totalTime}]`));
|
|
36300
|
+
this.#accesssToken = workingAaccesssToken;
|
|
36301
|
+
this.ReleaseOnHold(lockKey);
|
|
36302
|
+
this.Debug(chalk.yellow(`GetAccessToken(): release hold (lock) Time taken for get access token: [${performance.now() - start}ms]`));
|
|
36303
|
+
return this.#accesssToken;
|
|
36304
|
+
} catch (error) {
|
|
36305
|
+
if (timeout) clearTimeout(timeout);
|
|
36306
|
+
error.message = `GetAccessToken(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
|
|
36307
|
+
this.Error(error);
|
|
36308
|
+
return "";
|
|
36309
|
+
}
|
|
36310
|
+
};
|
|
36311
|
+
GetAccessTokenForSocketClientAccess = async () => {
|
|
36312
|
+
const timeout = setTimeout(() => {
|
|
36313
|
+
this.Warning(`GetAccessTokenForSocketClientAccess(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`);
|
|
36314
|
+
}, this._authMaxTimeout);
|
|
36315
|
+
const start = performance.now();
|
|
36316
|
+
try {
|
|
36317
|
+
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:SocketConnection`.split(" ").sort().join(" ");
|
|
36318
|
+
const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
|
|
36319
|
+
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
36320
|
+
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
36321
|
+
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
36322
|
+
scope: scopes,
|
|
36323
|
+
endPoint: authendpointUrl
|
|
36324
|
+
});
|
|
36325
|
+
clearTimeout(timeout);
|
|
36326
|
+
const totalTime = performance.now() - start;
|
|
36327
|
+
if (totalTime > this._authMaxTimeout) this.Warning(chalk.magenta(`GetAccessTokenForSocketClientAccess(): The total time for getting the access token: [${totalTime}]`));
|
|
36328
|
+
return retVal;
|
|
36329
|
+
} catch (error) {
|
|
36330
|
+
clearTimeout(timeout);
|
|
36331
|
+
error.message = `GetAccessTokenForSocketClientAccess(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
|
|
36332
|
+
this.Error(error);
|
|
36333
|
+
return "";
|
|
36334
|
+
}
|
|
36335
|
+
};
|
|
36336
|
+
ResetAccessToken = () => {
|
|
36337
|
+
this.#accesssToken = null;
|
|
36338
|
+
};
|
|
36339
|
+
GetFhirSocketClient = async () => {
|
|
36340
|
+
try {
|
|
36341
|
+
if (this.fhirClient) return this.fhirClient;
|
|
36342
|
+
const lockKey = "GetFhirSocketClient";
|
|
36343
|
+
const lockTimeout = 6e4;
|
|
36344
|
+
if (this.GetOnHold(lockKey) === true) {
|
|
36345
|
+
this.Debug(chalk.magenta(`GetFhirSocketClient(): fhir client does not exist - some other client setting up the new client (on hold/lock), lock key: [${lockKey}] - waiting ...`));
|
|
36346
|
+
try {
|
|
36347
|
+
const start = performance.now();
|
|
36348
|
+
await this.WaitOnHold(lockKey, lockTimeout);
|
|
36349
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): hold (lock) released after: [${performance.now() - start}ms], lock key: [${lockKey}]`));
|
|
36350
|
+
if (this.fhirClient) {
|
|
36351
|
+
this.Debug(chalk.green(`GetFhirSocketClient(): Getting existing fhir client (post hold release), lock key: [${lockKey}]`));
|
|
36352
|
+
return this.fhirClient;
|
|
36353
|
+
} else {
|
|
36354
|
+
this.Error(chalk.red(`GetFhirSocketClient(): Could not get existing fhir client (post hold release), lock key: [${lockKey}]`));
|
|
36355
|
+
this.Error(chalk.red(`GetFhirSocketClient(): continue anyway ...`));
|
|
36356
|
+
}
|
|
36357
|
+
} catch (error) {
|
|
36358
|
+
this.Error(chalk.red(`GetFhirSocketClient(): Error: [${error}]`));
|
|
36359
|
+
}
|
|
36360
|
+
}
|
|
36361
|
+
const start = performance.now();
|
|
36362
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): fhir client does not exist - setting up new client`));
|
|
36363
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): setting hold (lock), lock key: [${lockKey}]`));
|
|
36364
|
+
this.SetOnHold(lockKey);
|
|
36365
|
+
const fhirOptions = this._options.fhirOptions;
|
|
36366
|
+
const options = {
|
|
36367
|
+
fhirServerEndpoint: fhirOptions.stsfhirserverendpoint,
|
|
36368
|
+
fhirapiroot: fhirOptions.stsfhirapiroot,
|
|
36369
|
+
fhirServerPort: fhirOptions.stsfhirport,
|
|
36370
|
+
socketClientName: fhirOptions.stsfhirsocketname,
|
|
36371
|
+
socketIoCustomPath: fhirOptions.stsfhirsocketcustompath,
|
|
36372
|
+
timeout: fhirOptions.stsfhirsockettimeout,
|
|
36373
|
+
baseUrl: fhirOptions.stsfhirbaseurl,
|
|
36374
|
+
agentManager: this.GetFhirAgentManager(),
|
|
36375
|
+
joinRooms: [],
|
|
36376
|
+
logger: this.logger,
|
|
36377
|
+
verboseLogging: true,
|
|
36378
|
+
GetConnectionAccessToken: this.GetAccessTokenForSocketClientAccess,
|
|
36379
|
+
GetAccessToken: this.GetAccessToken
|
|
36380
|
+
};
|
|
36381
|
+
let workingFhirClient;
|
|
36382
|
+
if (this._options.runner.options.fhirOptions.stsfhirsocketclientmode === "socket-client-all-in-one") workingFhirClient = new FhirSocketClientAllInOne("FhirSocketClient", options);
|
|
36383
|
+
else workingFhirClient = new FhirSocketClientIndividual("FhirSocketClient", options);
|
|
36384
|
+
await workingFhirClient.WaitForSocketConnected();
|
|
36385
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): setting fhir client into object`));
|
|
36386
|
+
this.fhirClient = workingFhirClient;
|
|
36387
|
+
this.ReleaseOnHold(lockKey);
|
|
36388
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): release hold (lock) Time taken for socket connection and set object: [${performance.now() - start}ms], lock key: [${lockKey}]`));
|
|
36389
|
+
return this.fhirClient;
|
|
36390
|
+
} catch (error) {
|
|
36391
|
+
this.Error(error);
|
|
36392
|
+
throw error;
|
|
36393
|
+
}
|
|
36394
|
+
};
|
|
36395
|
+
GetRESTClient = async () => {
|
|
36396
|
+
if (this.restFhirClient) return this.restFhirClient;
|
|
36397
|
+
const onRetryAttempt = (attempt, error, delayMs) => {
|
|
36398
|
+
this._options.runner.instrumentData.errorCount++;
|
|
36399
|
+
this._options.runner.instrumentData.requestCount++;
|
|
36400
|
+
const message = `TestCaseFhirBase:onRetryAttempt(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
36401
|
+
this.Warning(message);
|
|
36402
|
+
this._options.runner.instrumentData.message.push(chalk.red(message));
|
|
36403
|
+
};
|
|
36404
|
+
const fhirOptions = this._options.fhirOptions;
|
|
36405
|
+
const fhirRESTClient = new FhirRESTClient({
|
|
36406
|
+
GetAccessToken: this.GetAccessToken,
|
|
36407
|
+
user: "USR_user01@stsmda.com.au",
|
|
36408
|
+
endpoint: fhirOptions.stsfhirserverendpoint,
|
|
36409
|
+
stsfhirapiroot: fhirOptions.stsfhirapiroot,
|
|
36410
|
+
stsfhirport: fhirOptions.stsfhirport,
|
|
36411
|
+
logger: this.logger,
|
|
36412
|
+
agentManager: this.GetFhirAgentManager(),
|
|
36413
|
+
onRetryAttempt
|
|
36414
|
+
});
|
|
36415
|
+
this.restFhirClient = fhirRESTClient;
|
|
36416
|
+
return fhirRESTClient;
|
|
36417
|
+
};
|
|
36418
|
+
GetClient = async () => {
|
|
36419
|
+
let client;
|
|
36420
|
+
if (this._options.runner.options.fhirOptions.stsfhirsocketclientmode === "no-socket-client") client = await this.GetRESTClient();
|
|
36421
|
+
else client = await this.GetFhirSocketClient();
|
|
36422
|
+
return client;
|
|
36423
|
+
};
|
|
36435
36424
|
};
|
|
36436
36425
|
//#endregion
|
|
36437
36426
|
export { WorkerFhirTestCases };
|