@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.cjs
CHANGED
|
@@ -31,16 +31,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
}) : target, mod));
|
|
32
32
|
//#endregion
|
|
33
33
|
let _nsshunt_stsrunnerframework = require("@nsshunt/stsrunnerframework");
|
|
34
|
+
let _nsshunt_stsutils = require("@nsshunt/stsutils");
|
|
34
35
|
let chalk = require("chalk");
|
|
35
36
|
chalk = __toESM(chalk, 1);
|
|
36
|
-
let
|
|
37
|
+
let axios = require("axios");
|
|
38
|
+
axios = __toESM(axios, 1);
|
|
37
39
|
let _nsshunt_stsfhirclient = require("@nsshunt/stsfhirclient");
|
|
38
40
|
let node_http = require("node:http");
|
|
39
41
|
node_http = __toESM(node_http, 1);
|
|
40
42
|
let node_https = require("node:https");
|
|
41
43
|
node_https = __toESM(node_https, 1);
|
|
42
|
-
let axios = require("axios");
|
|
43
|
-
axios = __toESM(axios, 1);
|
|
44
44
|
//#region node_modules/http-status-codes/build/es/status-codes.js
|
|
45
45
|
var StatusCodes;
|
|
46
46
|
(function(StatusCodes) {
|
|
@@ -403,190 +403,40 @@ var StatusCodes;
|
|
|
403
403
|
//#region src/libmodule/testCaseFhirBase.ts
|
|
404
404
|
var TestCaseFhirBase = class {
|
|
405
405
|
#options;
|
|
406
|
-
#randomDataRecordset = [];
|
|
407
406
|
#runner;
|
|
408
407
|
#runnerExecutionWorker;
|
|
409
|
-
#accesssToken = null;
|
|
410
408
|
#publishTelemetryCount = 0;
|
|
411
409
|
#maxBufferSize = 50;
|
|
412
410
|
#publishTelemetryTimeout = null;
|
|
413
411
|
#publishTelemetryTimeoutVal = 1e3;
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
412
|
+
_RetryMap = [
|
|
413
|
+
100,
|
|
414
|
+
250,
|
|
415
|
+
500,
|
|
416
|
+
1e3,
|
|
417
|
+
2e3,
|
|
418
|
+
3e3
|
|
419
|
+
];
|
|
418
420
|
_id = crypto.randomUUID();
|
|
419
421
|
retryCount = 0;
|
|
420
422
|
maxAuthRetryCount = 5;
|
|
421
423
|
runnerDurationList = [];
|
|
422
|
-
_authMaxTimeout = 5e3;
|
|
423
|
-
accessTokenTime = performance.now();
|
|
424
|
-
newTokenLimitTime = 30;
|
|
425
|
-
restFhirClient = null;
|
|
426
|
-
defaultAgentOptions = {
|
|
427
|
-
keepAlive: true,
|
|
428
|
-
maxSockets: 10,
|
|
429
|
-
maxTotalSockets: 20,
|
|
430
|
-
maxFreeSockets: 10,
|
|
431
|
-
timeout: 6e4,
|
|
432
|
-
rejectUnauthorized: false
|
|
433
|
-
};
|
|
434
|
-
stressTestAgentOptions = {
|
|
435
|
-
keepAlive: true,
|
|
436
|
-
maxSockets: 200,
|
|
437
|
-
maxTotalSockets: 500,
|
|
438
|
-
maxFreeSockets: 50,
|
|
439
|
-
timeout: 3e4,
|
|
440
|
-
rejectUnauthorized: false
|
|
441
|
-
};
|
|
442
|
-
stressTestExtremeAgentOptions = {
|
|
443
|
-
keepAlive: true,
|
|
444
|
-
maxSockets: 500,
|
|
445
|
-
maxTotalSockets: 1e3,
|
|
446
|
-
maxFreeSockets: 500,
|
|
447
|
-
timeout: 3e4,
|
|
448
|
-
rejectUnauthorized: false
|
|
449
|
-
};
|
|
450
424
|
constructor(runnerExecutionWorker, runner) {
|
|
451
425
|
this.#options = runner.options;
|
|
452
426
|
this.#runnerExecutionWorker = runnerExecutionWorker;
|
|
453
427
|
this.#runner = runner;
|
|
454
|
-
this.#authAgentManager = this.GetAuthAgentManager();
|
|
455
428
|
}
|
|
456
429
|
get runnerExecutionWorker() {
|
|
457
430
|
return this.#runnerExecutionWorker;
|
|
458
431
|
}
|
|
459
432
|
ResetClient = () => {};
|
|
460
|
-
GetRESTClient = async () => {
|
|
461
|
-
if (this.restFhirClient) return this.restFhirClient;
|
|
462
|
-
const onRetryAttempt = (attempt, error, delayMs) => {
|
|
463
|
-
this.#runner.instrumentData.errorCount++;
|
|
464
|
-
this.#runner.instrumentData.requestCount++;
|
|
465
|
-
const message = `TestCaseFhirBase:onRetryAttempt(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
466
|
-
this.Warning(message);
|
|
467
|
-
this.#runner.instrumentData.message.push(chalk.default.red(message));
|
|
468
|
-
};
|
|
469
|
-
const fhirOptions = this.#options.fhirOptions;
|
|
470
|
-
const fhirRESTClient = new _nsshunt_stsfhirclient.FhirRESTClient({
|
|
471
|
-
GetAccessToken: this.GetAccessToken,
|
|
472
|
-
user: "USR_user01@stsmda.com.au",
|
|
473
|
-
endpoint: fhirOptions.stsfhirserverendpoint,
|
|
474
|
-
stsfhirapiroot: fhirOptions.stsfhirapiroot,
|
|
475
|
-
stsfhirport: fhirOptions.stsfhirport,
|
|
476
|
-
logger: this.#runnerExecutionWorker.logger,
|
|
477
|
-
agentManager: this.GetFhirAgentManager(),
|
|
478
|
-
onRetryAttempt
|
|
479
|
-
});
|
|
480
|
-
this.restFhirClient = fhirRESTClient;
|
|
481
|
-
return fhirRESTClient;
|
|
482
|
-
};
|
|
483
|
-
GetAgentManager = (testingAgentOptions) => {
|
|
484
|
-
let agentManager = void 0;
|
|
485
|
-
let agentOptions = void 0;
|
|
486
|
-
switch (testingAgentOptions.nodeAgentMode) {
|
|
487
|
-
case "no-agent": break;
|
|
488
|
-
case "custom-agent-options":
|
|
489
|
-
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
490
|
-
else agentOptions = { ...this.defaultAgentOptions };
|
|
491
|
-
break;
|
|
492
|
-
case "default-agent-options":
|
|
493
|
-
agentOptions = { ...this.defaultAgentOptions };
|
|
494
|
-
break;
|
|
495
|
-
case "stress-test-agent-options":
|
|
496
|
-
agentOptions = { ...this.stressTestAgentOptions };
|
|
497
|
-
break;
|
|
498
|
-
case "stress-test-extreme-agent-options":
|
|
499
|
-
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
500
|
-
break;
|
|
501
|
-
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
502
|
-
}
|
|
503
|
-
if (agentOptions) agentManager = (0, _nsshunt_stsutils.createAgentManager)({
|
|
504
|
-
agentOptions,
|
|
505
|
-
httpAgentFactory(options) {
|
|
506
|
-
return new node_http.default.Agent(options);
|
|
507
|
-
},
|
|
508
|
-
httpsAgentFactory(options) {
|
|
509
|
-
return new node_https.default.Agent(options);
|
|
510
|
-
}
|
|
511
|
-
});
|
|
512
|
-
return agentManager;
|
|
513
|
-
};
|
|
514
|
-
GetFhirAgentManager = () => {
|
|
515
|
-
return this.GetAgentManager(this.#options.fhirOptions.stsfhiragentOptions);
|
|
516
|
-
};
|
|
517
|
-
GetAuthAgentManager = () => {
|
|
518
|
-
return this.GetAgentManager(this.#options.authOptions.asagentoptions);
|
|
519
|
-
};
|
|
520
|
-
GetFhirSocketClient = async () => {
|
|
521
|
-
try {
|
|
522
|
-
this.#clientSocketFetchCount++;
|
|
523
|
-
let fhirClient = this.runnerExecutionWorker.GetFhirClient();
|
|
524
|
-
if (fhirClient) return fhirClient;
|
|
525
|
-
if (this.runnerExecutionWorker.GetOnHold("fhirclient") === true) {
|
|
526
|
-
this.Debug(chalk.default.magenta(`[${this.runnerExecutionWorker.id}] [${this._id}] fhir client does not exist - some other client setting up the new client (on hold/lock) - waiting ...`));
|
|
527
|
-
try {
|
|
528
|
-
const start = performance.now();
|
|
529
|
-
await this.runnerExecutionWorker.WaitOnHold("fhirclient", 6e4);
|
|
530
|
-
this.Debug(chalk.default.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] hold (lock) released after: [${performance.now() - start}ms]`));
|
|
531
|
-
const fhirClient = this.runnerExecutionWorker.GetFhirClient();
|
|
532
|
-
if (fhirClient) {
|
|
533
|
-
this.Debug(chalk.default.green(`[${this.runnerExecutionWorker.id}] [${this._id}] Getting existing fhir client (post hold release)`));
|
|
534
|
-
return fhirClient;
|
|
535
|
-
} else {
|
|
536
|
-
this.Error(chalk.default.red(`[${this.runnerExecutionWorker.id}] [${this._id}] Could not get existing fhir client (post hold release)`));
|
|
537
|
-
this.Error(chalk.default.red(`continue anyway ...`));
|
|
538
|
-
}
|
|
539
|
-
} catch (error) {
|
|
540
|
-
this.Error(chalk.default.red(`GetFhirSocketClient(): Error: [${error}]`));
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
const start = performance.now();
|
|
544
|
-
this.Debug(chalk.default.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] fhir client does not exist - setting up new client`));
|
|
545
|
-
this.Debug(chalk.default.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] setting hold (lock)`));
|
|
546
|
-
this.runnerExecutionWorker.SetOnHold("fhirclient");
|
|
547
|
-
const fhirOptions = this.#options.fhirOptions;
|
|
548
|
-
const options = {
|
|
549
|
-
fhirServerEndpoint: fhirOptions.stsfhirserverendpoint,
|
|
550
|
-
fhirapiroot: fhirOptions.stsfhirapiroot,
|
|
551
|
-
fhirServerPort: fhirOptions.stsfhirport,
|
|
552
|
-
socketClientName: fhirOptions.stsfhirsocketname,
|
|
553
|
-
socketIoCustomPath: fhirOptions.stsfhirsocketcustompath,
|
|
554
|
-
timeout: fhirOptions.stsfhirsockettimeout,
|
|
555
|
-
baseUrl: fhirOptions.stsfhirbaseurl,
|
|
556
|
-
agentManager: this.GetFhirAgentManager(),
|
|
557
|
-
joinRooms: [],
|
|
558
|
-
logger: this.#runnerExecutionWorker.logger,
|
|
559
|
-
verboseLogging: true,
|
|
560
|
-
GetConnectionAccessToken: this.GetAccessTokenForSocketClientAccess,
|
|
561
|
-
GetAccessToken: this.GetAccessToken
|
|
562
|
-
};
|
|
563
|
-
if (this.runner.options.fhirOptions.stsfhirsocketclientmode === "socket-client-all-in-one") fhirClient = new _nsshunt_stsfhirclient.FhirSocketClientAllInOne("FhirSocketClient", options);
|
|
564
|
-
else fhirClient = new _nsshunt_stsfhirclient.FhirSocketClientIndividual("FhirSocketClient", options);
|
|
565
|
-
await fhirClient.WaitForSocketConnected();
|
|
566
|
-
this.Debug(chalk.default.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] setting fhir client into object`));
|
|
567
|
-
this.runnerExecutionWorker.SetFhirClient(fhirClient);
|
|
568
|
-
this.runnerExecutionWorker.ReleaseOnHold("fhirclient");
|
|
569
|
-
this.Debug(chalk.default.yellow(`[${this.runnerExecutionWorker.id}] [${this._id}] release hold (lock) Time taken for socket connection and set object: [${performance.now() - start}ms]`));
|
|
570
|
-
return fhirClient;
|
|
571
|
-
} catch (error) {
|
|
572
|
-
this.Error(error);
|
|
573
|
-
throw error;
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
#LogMessage = (message) => {};
|
|
577
|
-
Debug = (message) => {
|
|
578
|
-
this.#runnerExecutionWorker.logger.debug(message);
|
|
579
|
-
};
|
|
580
433
|
Error = (message) => {
|
|
581
434
|
this.#runnerExecutionWorker.logger.error(message);
|
|
582
435
|
this.#runner.instrumentData.message.push(chalk.default.red(`${message}`));
|
|
583
436
|
};
|
|
584
|
-
|
|
585
|
-
this.#runnerExecutionWorker.logger.
|
|
437
|
+
Debug = (message) => {
|
|
438
|
+
this.#runnerExecutionWorker.logger.debug(message);
|
|
586
439
|
};
|
|
587
|
-
get accesssToken() {
|
|
588
|
-
return this.#accesssToken;
|
|
589
|
-
}
|
|
590
440
|
get runner() {
|
|
591
441
|
return this.#runner;
|
|
592
442
|
}
|
|
@@ -629,125 +479,6 @@ var TestCaseFhirBase = class {
|
|
|
629
479
|
this.#runner.instrumentData.rx = 0;
|
|
630
480
|
await this.SleepImmediate();
|
|
631
481
|
};
|
|
632
|
-
ExtractOrigin = (uri) => {
|
|
633
|
-
const match = uri.match(this.#originRegex);
|
|
634
|
-
return match ? match[1] : null;
|
|
635
|
-
};
|
|
636
|
-
GetAPITokenFromAuthServerUsingScope = async (options) => {
|
|
637
|
-
const { scope, clientId, authClientSecret, endPoint } = options;
|
|
638
|
-
let stage = "1";
|
|
639
|
-
try {
|
|
640
|
-
stage = "2";
|
|
641
|
-
const scopes = scope.split(" ");
|
|
642
|
-
let origin = null;
|
|
643
|
-
let error = null;
|
|
644
|
-
stage = "3";
|
|
645
|
-
for (let i = 0; i < scopes.length; i++) {
|
|
646
|
-
const s = scopes[i];
|
|
647
|
-
if (!origin) {
|
|
648
|
-
origin = this.ExtractOrigin(s);
|
|
649
|
-
if (!origin) {
|
|
650
|
-
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
651
|
-
break;
|
|
652
|
-
}
|
|
653
|
-
} else {
|
|
654
|
-
const nextOrigin = this.ExtractOrigin(s);
|
|
655
|
-
if (!nextOrigin) {
|
|
656
|
-
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
657
|
-
break;
|
|
658
|
-
} else if (origin.localeCompare(nextOrigin) !== 0) {
|
|
659
|
-
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not all from the same client API. All scopes must come from the same client API.`);
|
|
660
|
-
break;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
stage = "4";
|
|
665
|
-
if (error) throw error;
|
|
666
|
-
stage = "5";
|
|
667
|
-
const payload = {
|
|
668
|
-
client_id: clientId,
|
|
669
|
-
client_secret: authClientSecret,
|
|
670
|
-
scope,
|
|
671
|
-
grant_type: "client_credentials"
|
|
672
|
-
};
|
|
673
|
-
stage = "6";
|
|
674
|
-
const url = endPoint ? `${endPoint}${this.#options.authOptions.asoauthapiroot}/token` : `${this.#options.authOptions.asendpoint}:${this.#options.authOptions.asport}${this.#options.authOptions.asoauthapiroot}/token`;
|
|
675
|
-
stage = `6.5: url: [${url}] payload: [${JSON.stringify(payload)}]`;
|
|
676
|
-
const axiosConfig = new _nsshunt_stsutils.STSAxiosConfig(url, "post").withDefaultHeaders().withData(payload);
|
|
677
|
-
if (this.#authAgentManager) axiosConfig.withAgentManager(this.#authAgentManager);
|
|
678
|
-
const retVal = await (0, _nsshunt_stsfhirclient.createRetryAxiosClient)({
|
|
679
|
-
maxRetries: 4,
|
|
680
|
-
retryDelayMs: 300,
|
|
681
|
-
retryJitterMs: 150,
|
|
682
|
-
maxRetryDurationMs: 5e3,
|
|
683
|
-
onRetryAttempt: (attempt, error, delayMs) => {
|
|
684
|
-
this.#runner.instrumentData.authenticationErrorCount++;
|
|
685
|
-
this.#runner.instrumentData.authenticationRetryCount++;
|
|
686
|
-
const message = `TestCaseFhirBase:GetAPITokenFromAuthServerUsingScope(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
687
|
-
this.Warning(message);
|
|
688
|
-
this.#runner.instrumentData.message.push(chalk.default.red(message));
|
|
689
|
-
}
|
|
690
|
-
})(url, axiosConfig.config);
|
|
691
|
-
this.#runner.instrumentData.authenticationCount++;
|
|
692
|
-
stage = "7";
|
|
693
|
-
if (retVal.status) {
|
|
694
|
-
if (retVal.status !== 200) this.Warning(chalk.default.magenta(`TestCaseFhirBase:GetAPITokenFromAuthServerUsingScope(): [${this._id}] Invalid response from server: [${retVal.status}]`));
|
|
695
|
-
} else throw new Error(chalk.default.red(`No retVal.status)`));
|
|
696
|
-
stage = "8";
|
|
697
|
-
if (retVal.data) {
|
|
698
|
-
stage = "9";
|
|
699
|
-
if (retVal.data.access_token) {
|
|
700
|
-
stage = "12";
|
|
701
|
-
return retVal.data.access_token;
|
|
702
|
-
} else {
|
|
703
|
-
stage = "13";
|
|
704
|
-
throw new Error(`No retVal.data.access_token)`);
|
|
705
|
-
}
|
|
706
|
-
} else {
|
|
707
|
-
stage = "14";
|
|
708
|
-
throw new Error(`No retVal.data)`);
|
|
709
|
-
}
|
|
710
|
-
} catch (error) {
|
|
711
|
-
this.Error(error);
|
|
712
|
-
let details = "None available.";
|
|
713
|
-
if (error.response && error.response.data) try {
|
|
714
|
-
details = JSON.stringify(error.response.data);
|
|
715
|
-
} catch (error) {
|
|
716
|
-
details = `Could not JSON.stringify(error.response.data)`;
|
|
717
|
-
}
|
|
718
|
-
error.message = `TestCaseFhirBase:GetAPITokenFromAuthServerUsingScope(): [${this._id}] Error: [${error}], Stage: [${stage}], Details: [${details}]`;
|
|
719
|
-
throw error;
|
|
720
|
-
}
|
|
721
|
-
};
|
|
722
|
-
GetAccessTokenForSocketClientAccess = async () => {
|
|
723
|
-
const timeout = setTimeout(() => {
|
|
724
|
-
this.Warning(`TestCaseFhirBase:GetAccessTokenForSocketClientAccess(): [${this._id}] Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`);
|
|
725
|
-
}, this._authMaxTimeout);
|
|
726
|
-
const start = performance.now();
|
|
727
|
-
try {
|
|
728
|
-
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:SocketConnection`.split(" ").sort().join(" ");
|
|
729
|
-
const authendpointUrl = `${this.#options.authOptions.asendpoint}:${this.#options.authOptions.asport}`;
|
|
730
|
-
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
731
|
-
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
732
|
-
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
733
|
-
scope: scopes,
|
|
734
|
-
endPoint: authendpointUrl
|
|
735
|
-
});
|
|
736
|
-
clearTimeout(timeout);
|
|
737
|
-
const totalTime = performance.now() - start;
|
|
738
|
-
if (totalTime > this._authMaxTimeout) this.Warning(chalk.default.magenta(`TestCaseFhirBase:GetAccessTokenForSocketClientAccess(): [${this._id}] The total time for getting the access token: [${totalTime}]`));
|
|
739
|
-
return retVal;
|
|
740
|
-
} catch (error) {
|
|
741
|
-
clearTimeout(timeout);
|
|
742
|
-
const totalTime = performance.now() - start;
|
|
743
|
-
error.message = `TestCaseFhirBase:GetAccessTokenForSocketClientAccess(): [${this._id}] Error: [${error}], Duration until error: [${totalTime}]`;
|
|
744
|
-
this.Error(error);
|
|
745
|
-
return "";
|
|
746
|
-
}
|
|
747
|
-
};
|
|
748
|
-
ResetAccessToken = () => {
|
|
749
|
-
this.#accesssToken = null;
|
|
750
|
-
};
|
|
751
482
|
HandleError = (error) => {
|
|
752
483
|
this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] Error: [${error}]`));
|
|
753
484
|
this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] description: [${this.runner.options.description}]`));
|
|
@@ -762,48 +493,18 @@ var TestCaseFhirBase = class {
|
|
|
762
493
|
if (axiosError.response.status === StatusCodes.UNAUTHORIZED) {
|
|
763
494
|
this.runner.instrumentData.authenticationErrorCount++;
|
|
764
495
|
this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
|
|
765
|
-
this.ResetAccessToken();
|
|
496
|
+
this.runnerExecutionWorker.ResetAccessToken();
|
|
766
497
|
return true;
|
|
767
498
|
}
|
|
768
499
|
} else this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] AXIOS Error = [${axiosError}]`));
|
|
769
500
|
} else if (error.message === "UNAUTHORIZED") {
|
|
770
501
|
this.runner.instrumentData.authenticationErrorCount++;
|
|
771
502
|
this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
|
|
772
|
-
this.ResetAccessToken();
|
|
503
|
+
this.runnerExecutionWorker.ResetAccessToken();
|
|
773
504
|
return true;
|
|
774
505
|
}
|
|
775
506
|
return false;
|
|
776
507
|
};
|
|
777
|
-
GetAccessToken = async () => {
|
|
778
|
-
let timeout = void 0;
|
|
779
|
-
let start = performance.now();
|
|
780
|
-
try {
|
|
781
|
-
if (this.#accesssToken) return this.#accesssToken;
|
|
782
|
-
timeout = setTimeout(() => {
|
|
783
|
-
this.Warning(chalk.default.magenta(`TestCaseFhirBase:GetAccessToken(): [${this._id}] Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`));
|
|
784
|
-
}, this._authMaxTimeout);
|
|
785
|
-
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:All`.split(" ").sort().join(" ");
|
|
786
|
-
const authendpointUrl = `${this.#options.authOptions.asendpoint}:${this.#options.authOptions.asport}`;
|
|
787
|
-
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
788
|
-
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
789
|
-
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
790
|
-
scope: scopes,
|
|
791
|
-
endPoint: authendpointUrl
|
|
792
|
-
});
|
|
793
|
-
this.accessTokenTime = performance.now();
|
|
794
|
-
this.#accesssToken = retVal;
|
|
795
|
-
if (timeout) clearTimeout(timeout);
|
|
796
|
-
const totalTime = performance.now() - start;
|
|
797
|
-
if (totalTime > this._authMaxTimeout) this.Warning(chalk.default.magenta(`TestCaseFhirBase:GetAccessToken(): [${this._id}] The total time for getting the access token: [${totalTime}]`));
|
|
798
|
-
return retVal;
|
|
799
|
-
} catch (error) {
|
|
800
|
-
if (timeout) clearTimeout(timeout);
|
|
801
|
-
const totalTime = performance.now() - start;
|
|
802
|
-
error.message = `TestCaseFhirBase:GetAccessToken(): [${this._id}] Error: [${error}], Duration until error: [${totalTime}]`;
|
|
803
|
-
this.Error(error);
|
|
804
|
-
return "";
|
|
805
|
-
}
|
|
806
|
-
};
|
|
807
508
|
GetPersonRecord = async (prefix, index, version) => {
|
|
808
509
|
const { workerIndex, runnerIndex, runId } = this.#options;
|
|
809
510
|
const useId = `${prefix}-${index}`;
|
|
@@ -830,37 +531,12 @@ var TestCaseFhirBase = class {
|
|
|
830
531
|
}
|
|
831
532
|
};
|
|
832
533
|
};
|
|
833
|
-
StartTestDataLoad = async () => {
|
|
834
|
-
this.Debug(chalk.default.magenta(`StartTestDataLoad(): Start ...`));
|
|
835
|
-
let VU = 0;
|
|
836
|
-
const blockNum = VU * 200;
|
|
837
|
-
const blocksToLoad = 20;
|
|
838
|
-
for (let i = 0; i < blocksToLoad; i++) {
|
|
839
|
-
const recordId = `stsres_${blockNum + i}`;
|
|
840
|
-
const retVal = await (await this.GetFhirSocketClient()).GetResource("Person", recordId);
|
|
841
|
-
if (retVal) {
|
|
842
|
-
const recordsetData = retVal.body.address;
|
|
843
|
-
if (recordsetData) {
|
|
844
|
-
const qqq = recordsetData[0].text;
|
|
845
|
-
for (let j = 0; j < qqq.length; j++) this.#randomDataRecordset.push(qqq[j]);
|
|
846
|
-
this.Error(chalk.default.magenta(this.#randomDataRecordset.length));
|
|
847
|
-
}
|
|
848
|
-
} else this.Error(chalk.default.magenta(`StartTestDataLoad(): Could not get person records.`));
|
|
849
|
-
await (0, _nsshunt_stsutils.Sleep)(10);
|
|
850
|
-
}
|
|
851
|
-
this.Debug(`Finished load for VU: [${VU}]`);
|
|
852
|
-
this.Debug(`First 10 entries`);
|
|
853
|
-
for (let i = 0; i < 10; i++) this.Debug(this.#randomDataRecordset[i].id);
|
|
854
|
-
this.Debug(`block num: [${blockNum}] length: [${this.#randomDataRecordset.length}] VU: [${VU}]`);
|
|
855
|
-
this.Debug(chalk.default.magenta(`StartTestDataLoad(): End`));
|
|
856
|
-
};
|
|
857
534
|
#ForcePublishTelemetryData = async () => {
|
|
858
535
|
await this.#PublishTelemetryData();
|
|
859
536
|
};
|
|
860
537
|
#SetupTimeout = async () => {
|
|
861
538
|
if (!this.#publishTelemetryTimeout) {
|
|
862
539
|
this.#publishTelemetryTimeout = setTimeout(async () => {
|
|
863
|
-
this.#LogMessage(chalk.default.yellow(` **** TIMEOUT **** `));
|
|
864
540
|
await this.#PublishTelemetryData();
|
|
865
541
|
this.#publishTelemetryCount = 0;
|
|
866
542
|
this.#publishTelemetryTimeout = null;
|
|
@@ -870,7 +546,6 @@ var TestCaseFhirBase = class {
|
|
|
870
546
|
};
|
|
871
547
|
PublishTelemetry = async () => {
|
|
872
548
|
this.#publishTelemetryCount++;
|
|
873
|
-
this.#LogMessage(chalk.default.red(this.#publishTelemetryCount));
|
|
874
549
|
if (this.#publishTelemetryCount % this.#maxBufferSize === 0) {
|
|
875
550
|
this.#publishTelemetryCount = 0;
|
|
876
551
|
if (this.#publishTelemetryTimeout) {
|
|
@@ -883,7 +558,6 @@ var TestCaseFhirBase = class {
|
|
|
883
558
|
};
|
|
884
559
|
#OutputLogMessage = async (message) => {
|
|
885
560
|
const messageOutput = chalk.default.grey(message);
|
|
886
|
-
this.#LogMessage(messageOutput);
|
|
887
561
|
this.#runner.instrumentData.message.push(messageOutput);
|
|
888
562
|
await this.PublishTelemetry();
|
|
889
563
|
};
|
|
@@ -931,12 +605,6 @@ var TestCaseFhirBase = class {
|
|
|
931
605
|
await this.#ForcePublishTelemetryData();
|
|
932
606
|
return true;
|
|
933
607
|
};
|
|
934
|
-
GetClient = async () => {
|
|
935
|
-
let client;
|
|
936
|
-
if (this.runner.options.fhirOptions.stsfhirsocketclientmode === "no-socket-client") client = await this.GetRESTClient();
|
|
937
|
-
else client = await this.GetFhirSocketClient();
|
|
938
|
-
return client;
|
|
939
|
-
};
|
|
940
608
|
_GetDetail = () => {
|
|
941
609
|
return `testType: [${this.runner.options.testType}], description: [${this.runner.options.description}], workerManagerId: [${this.runner.workerManagerId}], Iteration: [${this.runner.iteration}]`;
|
|
942
610
|
};
|
|
@@ -953,14 +621,6 @@ var TestCaseFhirBase = class {
|
|
|
953
621
|
this.retryCount = 0;
|
|
954
622
|
return this._ExecuteQuery();
|
|
955
623
|
};
|
|
956
|
-
_RetryMap = [
|
|
957
|
-
100,
|
|
958
|
-
250,
|
|
959
|
-
500,
|
|
960
|
-
1e3,
|
|
961
|
-
2e3,
|
|
962
|
-
3e3
|
|
963
|
-
];
|
|
964
624
|
_ExecuteQuery = async () => {
|
|
965
625
|
try {
|
|
966
626
|
return await this.PerformExecuteQuery();
|
|
@@ -983,6 +643,9 @@ var TestCaseFhirBase = class {
|
|
|
983
643
|
else throw error;
|
|
984
644
|
}
|
|
985
645
|
};
|
|
646
|
+
GetClient = async () => {
|
|
647
|
+
return this.runnerExecutionWorker.GetClient();
|
|
648
|
+
};
|
|
986
649
|
};
|
|
987
650
|
//#endregion
|
|
988
651
|
//#region src/libmodule/testCaseFhirQueryBase.ts
|
|
@@ -1064,9 +727,9 @@ var TestCaseFhirQueryBase = class extends TestCaseFhirBase {
|
|
|
1064
727
|
var TestCaseFhir01 = class extends TestCaseFhirQueryBase {
|
|
1065
728
|
PerformExecuteQuery = async () => {
|
|
1066
729
|
const __snapshot1 = performance.now();
|
|
1067
|
-
await this.GetAccessToken();
|
|
730
|
+
await this.runnerExecutionWorker.GetAccessToken();
|
|
1068
731
|
this._CheckOutputLongDurationError(__snapshot1, "await this.GetAccessToken()");
|
|
1069
|
-
this.ResetAccessToken();
|
|
732
|
+
this.runnerExecutionWorker.ResetAccessToken();
|
|
1070
733
|
return null;
|
|
1071
734
|
};
|
|
1072
735
|
};
|
|
@@ -36401,20 +36064,30 @@ var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunn
|
|
|
36401
36064
|
fhirClient = void 0;
|
|
36402
36065
|
_id = crypto.randomUUID();
|
|
36403
36066
|
_onHoldKeys = {};
|
|
36067
|
+
#accesssToken = null;
|
|
36068
|
+
_authMaxTimeout = 5e3;
|
|
36069
|
+
#originRegex = /^(api:\/\/\w+)/;
|
|
36070
|
+
#authAgentManager;
|
|
36071
|
+
restFhirClient = null;
|
|
36072
|
+
logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
|
|
36404
36073
|
constructor(options) {
|
|
36405
36074
|
super();
|
|
36406
36075
|
this._options = options;
|
|
36407
36076
|
this._resourceDataGenerator = new ResourceDataGenerator();
|
|
36077
|
+
this.#authAgentManager = this.GetAuthAgentManager();
|
|
36408
36078
|
}
|
|
36079
|
+
Warning = (message) => {
|
|
36080
|
+
this.logger.warn(`${this.logPrefix}${message}`);
|
|
36081
|
+
};
|
|
36082
|
+
Error = (message) => {
|
|
36083
|
+
this.logger.error(`${this.logPrefix}${message}`);
|
|
36084
|
+
};
|
|
36085
|
+
Debug = (message) => {
|
|
36086
|
+
this.logger.debug(`${this.logPrefix}${message}`);
|
|
36087
|
+
};
|
|
36409
36088
|
get id() {
|
|
36410
36089
|
return this._id;
|
|
36411
36090
|
}
|
|
36412
|
-
GetFhirClient = () => {
|
|
36413
|
-
return this.fhirClient;
|
|
36414
|
-
};
|
|
36415
|
-
SetFhirClient = (fhirClient) => {
|
|
36416
|
-
this.fhirClient = fhirClient;
|
|
36417
|
-
};
|
|
36418
36091
|
get resourceDataGenerator() {
|
|
36419
36092
|
return this._resourceDataGenerator;
|
|
36420
36093
|
}
|
|
@@ -36425,9 +36098,9 @@ var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunn
|
|
|
36425
36098
|
return AsyncRunnerFactory.CreateAsyncRunner(this, testRunnerTelemetryPayload);
|
|
36426
36099
|
};
|
|
36427
36100
|
async ProcessPreTerminateWorkerMessage(messagePayload) {
|
|
36428
|
-
this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: [${JSON.stringify(messagePayload, null, 2)}]`));
|
|
36101
|
+
this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): [${JSON.stringify(messagePayload, null, 2)}]`));
|
|
36429
36102
|
if (this.fhirClient) {
|
|
36430
|
-
this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: ResetSocket()`));
|
|
36103
|
+
this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): ResetSocket()`));
|
|
36431
36104
|
this.fhirClient.ResetSocket();
|
|
36432
36105
|
this.fhirClient = void 0;
|
|
36433
36106
|
}
|
|
@@ -36446,7 +36119,7 @@ var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunn
|
|
|
36446
36119
|
for (;;) {
|
|
36447
36120
|
if (this._onHoldKeys[holdKey]) await (0, _nsshunt_stsutils.Sleep)(100);
|
|
36448
36121
|
else break;
|
|
36449
|
-
if (performance.now() - start > timeout) throw new Error(`WaitOnHold
|
|
36122
|
+
if (performance.now() - start > timeout) throw new Error(`WorkerFhirTestCases:WaitOnHold(): Timeout: [${timeout}] reached.`);
|
|
36450
36123
|
}
|
|
36451
36124
|
return true;
|
|
36452
36125
|
};
|
|
@@ -36456,6 +36129,322 @@ var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunn
|
|
|
36456
36129
|
ReleaseOnHold = (holdKey) => {
|
|
36457
36130
|
delete this._onHoldKeys[holdKey];
|
|
36458
36131
|
};
|
|
36132
|
+
defaultAgentOptions = {
|
|
36133
|
+
keepAlive: true,
|
|
36134
|
+
maxSockets: 10,
|
|
36135
|
+
maxTotalSockets: 20,
|
|
36136
|
+
maxFreeSockets: 10,
|
|
36137
|
+
timeout: 6e4,
|
|
36138
|
+
rejectUnauthorized: false
|
|
36139
|
+
};
|
|
36140
|
+
stressTestAgentOptions = {
|
|
36141
|
+
keepAlive: true,
|
|
36142
|
+
maxSockets: 200,
|
|
36143
|
+
maxTotalSockets: 500,
|
|
36144
|
+
maxFreeSockets: 50,
|
|
36145
|
+
timeout: 3e4,
|
|
36146
|
+
rejectUnauthorized: false
|
|
36147
|
+
};
|
|
36148
|
+
stressTestExtremeAgentOptions = {
|
|
36149
|
+
keepAlive: true,
|
|
36150
|
+
maxSockets: 500,
|
|
36151
|
+
maxTotalSockets: 1e3,
|
|
36152
|
+
maxFreeSockets: 500,
|
|
36153
|
+
timeout: 3e4,
|
|
36154
|
+
rejectUnauthorized: false
|
|
36155
|
+
};
|
|
36156
|
+
GetAgentManager = (testingAgentOptions) => {
|
|
36157
|
+
let agentManager = void 0;
|
|
36158
|
+
let agentOptions = void 0;
|
|
36159
|
+
switch (testingAgentOptions.nodeAgentMode) {
|
|
36160
|
+
case "no-agent": break;
|
|
36161
|
+
case "custom-agent-options":
|
|
36162
|
+
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
36163
|
+
else agentOptions = { ...this.defaultAgentOptions };
|
|
36164
|
+
break;
|
|
36165
|
+
case "default-agent-options":
|
|
36166
|
+
agentOptions = { ...this.defaultAgentOptions };
|
|
36167
|
+
break;
|
|
36168
|
+
case "stress-test-agent-options":
|
|
36169
|
+
agentOptions = { ...this.stressTestAgentOptions };
|
|
36170
|
+
break;
|
|
36171
|
+
case "stress-test-extreme-agent-options":
|
|
36172
|
+
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
36173
|
+
break;
|
|
36174
|
+
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
36175
|
+
}
|
|
36176
|
+
if (agentOptions) agentManager = (0, _nsshunt_stsutils.createAgentManager)({
|
|
36177
|
+
agentOptions,
|
|
36178
|
+
httpAgentFactory(options) {
|
|
36179
|
+
return new node_http.default.Agent(options);
|
|
36180
|
+
},
|
|
36181
|
+
httpsAgentFactory(options) {
|
|
36182
|
+
return new node_https.default.Agent(options);
|
|
36183
|
+
}
|
|
36184
|
+
});
|
|
36185
|
+
return agentManager;
|
|
36186
|
+
};
|
|
36187
|
+
GetFhirAgentManager = () => {
|
|
36188
|
+
return this.GetAgentManager(this._options.fhirOptions.stsfhiragentOptions);
|
|
36189
|
+
};
|
|
36190
|
+
GetAuthAgentManager = () => {
|
|
36191
|
+
return this.GetAgentManager(this._options.authOptions.asagentoptions);
|
|
36192
|
+
};
|
|
36193
|
+
ExtractOrigin = (uri) => {
|
|
36194
|
+
const match = uri.match(this.#originRegex);
|
|
36195
|
+
return match ? match[1] : null;
|
|
36196
|
+
};
|
|
36197
|
+
GetAPITokenFromAuthServerUsingScope = async (options) => {
|
|
36198
|
+
const { scope, clientId, authClientSecret, endPoint } = options;
|
|
36199
|
+
let stage = "1";
|
|
36200
|
+
try {
|
|
36201
|
+
stage = "2";
|
|
36202
|
+
const scopes = scope.split(" ");
|
|
36203
|
+
let origin = null;
|
|
36204
|
+
let error = null;
|
|
36205
|
+
stage = "3";
|
|
36206
|
+
for (let i = 0; i < scopes.length; i++) {
|
|
36207
|
+
const s = scopes[i];
|
|
36208
|
+
if (!origin) {
|
|
36209
|
+
origin = this.ExtractOrigin(s);
|
|
36210
|
+
if (!origin) {
|
|
36211
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
36212
|
+
break;
|
|
36213
|
+
}
|
|
36214
|
+
} else {
|
|
36215
|
+
const nextOrigin = this.ExtractOrigin(s);
|
|
36216
|
+
if (!nextOrigin) {
|
|
36217
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
36218
|
+
break;
|
|
36219
|
+
} else if (origin.localeCompare(nextOrigin) !== 0) {
|
|
36220
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not all from the same client API. All scopes must come from the same client API.`);
|
|
36221
|
+
break;
|
|
36222
|
+
}
|
|
36223
|
+
}
|
|
36224
|
+
}
|
|
36225
|
+
stage = "4";
|
|
36226
|
+
if (error) throw error;
|
|
36227
|
+
stage = "5";
|
|
36228
|
+
const payload = {
|
|
36229
|
+
client_id: clientId,
|
|
36230
|
+
client_secret: authClientSecret,
|
|
36231
|
+
scope,
|
|
36232
|
+
grant_type: "client_credentials"
|
|
36233
|
+
};
|
|
36234
|
+
stage = "6";
|
|
36235
|
+
const url = endPoint ? `${endPoint}${this._options.authOptions.asoauthapiroot}/token` : `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}${this._options.authOptions.asoauthapiroot}/token`;
|
|
36236
|
+
stage = `6.5: url: [${url}] payload: [${JSON.stringify(payload)}]`;
|
|
36237
|
+
const axiosConfig = new _nsshunt_stsutils.STSAxiosConfig(url, "post").withDefaultHeaders().withData(payload);
|
|
36238
|
+
if (this.#authAgentManager) axiosConfig.withAgentManager(this.#authAgentManager);
|
|
36239
|
+
const retVal = await (0, _nsshunt_stsfhirclient.createRetryAxiosClient)({
|
|
36240
|
+
maxRetries: 4,
|
|
36241
|
+
retryDelayMs: 300,
|
|
36242
|
+
retryJitterMs: 150,
|
|
36243
|
+
maxRetryDurationMs: 5e3,
|
|
36244
|
+
onRetryAttempt: (attempt, error, delayMs) => {
|
|
36245
|
+
this._options.runner.instrumentData.authenticationErrorCount++;
|
|
36246
|
+
this._options.runner.instrumentData.authenticationRetryCount++;
|
|
36247
|
+
const message = `GetAPITokenFromAuthServerUsingScope(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
36248
|
+
this.Warning(message);
|
|
36249
|
+
this._options.runner.instrumentData.message.push(chalk.default.red(message));
|
|
36250
|
+
}
|
|
36251
|
+
})(url, axiosConfig.config);
|
|
36252
|
+
this._options.runner.instrumentData.authenticationCount++;
|
|
36253
|
+
stage = "7";
|
|
36254
|
+
if (retVal.status) {
|
|
36255
|
+
if (retVal.status !== 200) this.Warning(chalk.default.magenta(`GetAPITokenFromAuthServerUsingScope(): [${this._id}] Invalid response from server: [${retVal.status}]`));
|
|
36256
|
+
} else throw new Error(chalk.default.red(`No retVal.status)`));
|
|
36257
|
+
stage = "8";
|
|
36258
|
+
if (retVal.data) {
|
|
36259
|
+
stage = "9";
|
|
36260
|
+
if (retVal.data.access_token) {
|
|
36261
|
+
stage = "12";
|
|
36262
|
+
return retVal.data.access_token;
|
|
36263
|
+
} else {
|
|
36264
|
+
stage = "13";
|
|
36265
|
+
throw new Error(`No retVal.data.access_token)`);
|
|
36266
|
+
}
|
|
36267
|
+
} else {
|
|
36268
|
+
stage = "14";
|
|
36269
|
+
throw new Error(`No retVal.data)`);
|
|
36270
|
+
}
|
|
36271
|
+
} catch (error) {
|
|
36272
|
+
this.Error(error);
|
|
36273
|
+
let details = "None available.";
|
|
36274
|
+
if (error.response && error.response.data) try {
|
|
36275
|
+
details = JSON.stringify(error.response.data);
|
|
36276
|
+
} catch (error) {
|
|
36277
|
+
details = `Could not JSON.stringify(error.response.data)`;
|
|
36278
|
+
}
|
|
36279
|
+
error.message = `${this.logPrefix}GetAPITokenFromAuthServerUsingScope(): Error: [${error}], Stage: [${stage}], Details: [${details}]`;
|
|
36280
|
+
throw error;
|
|
36281
|
+
}
|
|
36282
|
+
};
|
|
36283
|
+
GetAccessToken = async () => {
|
|
36284
|
+
let timeout = void 0;
|
|
36285
|
+
const start = performance.now();
|
|
36286
|
+
try {
|
|
36287
|
+
if (this.#accesssToken) return this.#accesssToken;
|
|
36288
|
+
const lockKey = "GetAccessToken";
|
|
36289
|
+
const lockTimeout = 6e4;
|
|
36290
|
+
if (this.GetOnHold(lockKey) === true) {
|
|
36291
|
+
this.Debug(chalk.default.magenta(`GetAccessToken(): accesssToken does not exist - some other client setting up the new accesssToken (on hold/lock), lock key: [${lockKey}] - waiting ...`));
|
|
36292
|
+
try {
|
|
36293
|
+
const miniStart = performance.now();
|
|
36294
|
+
await this.WaitOnHold(lockKey, lockTimeout);
|
|
36295
|
+
this.Debug(chalk.default.yellow(`GetAccessToken(): hold (lock) released after: [${performance.now() - miniStart}ms], lock key: [${lockKey}]`));
|
|
36296
|
+
if (this.#accesssToken) {
|
|
36297
|
+
this.Debug(chalk.default.green(`GetAccessToken(): Getting existing accesssToken (post hold release), lock key: [${lockKey}]`));
|
|
36298
|
+
return this.#accesssToken;
|
|
36299
|
+
} else {
|
|
36300
|
+
this.Error(chalk.default.red(`GetAccessToken(): Could not get existing accesssToken (post hold release), lock key: [${lockKey}]`));
|
|
36301
|
+
this.Error(chalk.default.red(`GetAccessToken(): continue anyway ...`));
|
|
36302
|
+
}
|
|
36303
|
+
} catch (error) {
|
|
36304
|
+
this.Error(chalk.default.red(`GetAccessToken(): Error: [${error}]`));
|
|
36305
|
+
}
|
|
36306
|
+
}
|
|
36307
|
+
this.Debug(chalk.default.yellow(`GetAccessToken(): accesssToken does not exist - setting up new accesssToken`));
|
|
36308
|
+
this.Debug(chalk.default.yellow(`GetAccessToken(): setting hold (lock), lock key: [${lockKey}]`));
|
|
36309
|
+
this.SetOnHold(lockKey);
|
|
36310
|
+
timeout = setTimeout(() => {
|
|
36311
|
+
this.Warning(chalk.default.magenta(`GetAccessToken(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`));
|
|
36312
|
+
}, this._authMaxTimeout);
|
|
36313
|
+
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:All`.split(" ").sort().join(" ");
|
|
36314
|
+
const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
|
|
36315
|
+
const workingAaccesssToken = await this.GetAPITokenFromAuthServerUsingScope({
|
|
36316
|
+
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
36317
|
+
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
36318
|
+
scope: scopes,
|
|
36319
|
+
endPoint: authendpointUrl
|
|
36320
|
+
});
|
|
36321
|
+
if (timeout) clearTimeout(timeout);
|
|
36322
|
+
const totalTime = performance.now() - start;
|
|
36323
|
+
if (totalTime > this._authMaxTimeout) this.Warning(chalk.default.magenta(`GetAccessToken(): The total time for getting the access token: [${totalTime}]`));
|
|
36324
|
+
this.#accesssToken = workingAaccesssToken;
|
|
36325
|
+
this.ReleaseOnHold(lockKey);
|
|
36326
|
+
this.Debug(chalk.default.yellow(`GetAccessToken(): release hold (lock) Time taken for get access token: [${performance.now() - start}ms]`));
|
|
36327
|
+
return this.#accesssToken;
|
|
36328
|
+
} catch (error) {
|
|
36329
|
+
if (timeout) clearTimeout(timeout);
|
|
36330
|
+
error.message = `GetAccessToken(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
|
|
36331
|
+
this.Error(error);
|
|
36332
|
+
return "";
|
|
36333
|
+
}
|
|
36334
|
+
};
|
|
36335
|
+
GetAccessTokenForSocketClientAccess = async () => {
|
|
36336
|
+
const timeout = setTimeout(() => {
|
|
36337
|
+
this.Warning(`GetAccessTokenForSocketClientAccess(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`);
|
|
36338
|
+
}, this._authMaxTimeout);
|
|
36339
|
+
const start = performance.now();
|
|
36340
|
+
try {
|
|
36341
|
+
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:SocketConnection`.split(" ").sort().join(" ");
|
|
36342
|
+
const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
|
|
36343
|
+
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
36344
|
+
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
36345
|
+
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
36346
|
+
scope: scopes,
|
|
36347
|
+
endPoint: authendpointUrl
|
|
36348
|
+
});
|
|
36349
|
+
clearTimeout(timeout);
|
|
36350
|
+
const totalTime = performance.now() - start;
|
|
36351
|
+
if (totalTime > this._authMaxTimeout) this.Warning(chalk.default.magenta(`GetAccessTokenForSocketClientAccess(): The total time for getting the access token: [${totalTime}]`));
|
|
36352
|
+
return retVal;
|
|
36353
|
+
} catch (error) {
|
|
36354
|
+
clearTimeout(timeout);
|
|
36355
|
+
error.message = `GetAccessTokenForSocketClientAccess(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
|
|
36356
|
+
this.Error(error);
|
|
36357
|
+
return "";
|
|
36358
|
+
}
|
|
36359
|
+
};
|
|
36360
|
+
ResetAccessToken = () => {
|
|
36361
|
+
this.#accesssToken = null;
|
|
36362
|
+
};
|
|
36363
|
+
GetFhirSocketClient = async () => {
|
|
36364
|
+
try {
|
|
36365
|
+
if (this.fhirClient) return this.fhirClient;
|
|
36366
|
+
const lockKey = "GetFhirSocketClient";
|
|
36367
|
+
const lockTimeout = 6e4;
|
|
36368
|
+
if (this.GetOnHold(lockKey) === true) {
|
|
36369
|
+
this.Debug(chalk.default.magenta(`GetFhirSocketClient(): fhir client does not exist - some other client setting up the new client (on hold/lock), lock key: [${lockKey}] - waiting ...`));
|
|
36370
|
+
try {
|
|
36371
|
+
const start = performance.now();
|
|
36372
|
+
await this.WaitOnHold(lockKey, lockTimeout);
|
|
36373
|
+
this.Debug(chalk.default.yellow(`GetFhirSocketClient(): hold (lock) released after: [${performance.now() - start}ms], lock key: [${lockKey}]`));
|
|
36374
|
+
if (this.fhirClient) {
|
|
36375
|
+
this.Debug(chalk.default.green(`GetFhirSocketClient(): Getting existing fhir client (post hold release), lock key: [${lockKey}]`));
|
|
36376
|
+
return this.fhirClient;
|
|
36377
|
+
} else {
|
|
36378
|
+
this.Error(chalk.default.red(`GetFhirSocketClient(): Could not get existing fhir client (post hold release), lock key: [${lockKey}]`));
|
|
36379
|
+
this.Error(chalk.default.red(`GetFhirSocketClient(): continue anyway ...`));
|
|
36380
|
+
}
|
|
36381
|
+
} catch (error) {
|
|
36382
|
+
this.Error(chalk.default.red(`GetFhirSocketClient(): Error: [${error}]`));
|
|
36383
|
+
}
|
|
36384
|
+
}
|
|
36385
|
+
const start = performance.now();
|
|
36386
|
+
this.Debug(chalk.default.yellow(`GetFhirSocketClient(): fhir client does not exist - setting up new client`));
|
|
36387
|
+
this.Debug(chalk.default.yellow(`GetFhirSocketClient(): setting hold (lock), lock key: [${lockKey}]`));
|
|
36388
|
+
this.SetOnHold(lockKey);
|
|
36389
|
+
const fhirOptions = this._options.fhirOptions;
|
|
36390
|
+
const options = {
|
|
36391
|
+
fhirServerEndpoint: fhirOptions.stsfhirserverendpoint,
|
|
36392
|
+
fhirapiroot: fhirOptions.stsfhirapiroot,
|
|
36393
|
+
fhirServerPort: fhirOptions.stsfhirport,
|
|
36394
|
+
socketClientName: fhirOptions.stsfhirsocketname,
|
|
36395
|
+
socketIoCustomPath: fhirOptions.stsfhirsocketcustompath,
|
|
36396
|
+
timeout: fhirOptions.stsfhirsockettimeout,
|
|
36397
|
+
baseUrl: fhirOptions.stsfhirbaseurl,
|
|
36398
|
+
agentManager: this.GetFhirAgentManager(),
|
|
36399
|
+
joinRooms: [],
|
|
36400
|
+
logger: this.logger,
|
|
36401
|
+
verboseLogging: true,
|
|
36402
|
+
GetConnectionAccessToken: this.GetAccessTokenForSocketClientAccess,
|
|
36403
|
+
GetAccessToken: this.GetAccessToken
|
|
36404
|
+
};
|
|
36405
|
+
let workingFhirClient;
|
|
36406
|
+
if (this._options.runner.options.fhirOptions.stsfhirsocketclientmode === "socket-client-all-in-one") workingFhirClient = new _nsshunt_stsfhirclient.FhirSocketClientAllInOne("FhirSocketClient", options);
|
|
36407
|
+
else workingFhirClient = new _nsshunt_stsfhirclient.FhirSocketClientIndividual("FhirSocketClient", options);
|
|
36408
|
+
await workingFhirClient.WaitForSocketConnected();
|
|
36409
|
+
this.Debug(chalk.default.yellow(`GetFhirSocketClient(): setting fhir client into object`));
|
|
36410
|
+
this.fhirClient = workingFhirClient;
|
|
36411
|
+
this.ReleaseOnHold(lockKey);
|
|
36412
|
+
this.Debug(chalk.default.yellow(`GetFhirSocketClient(): release hold (lock) Time taken for socket connection and set object: [${performance.now() - start}ms], lock key: [${lockKey}]`));
|
|
36413
|
+
return this.fhirClient;
|
|
36414
|
+
} catch (error) {
|
|
36415
|
+
this.Error(error);
|
|
36416
|
+
throw error;
|
|
36417
|
+
}
|
|
36418
|
+
};
|
|
36419
|
+
GetRESTClient = async () => {
|
|
36420
|
+
if (this.restFhirClient) return this.restFhirClient;
|
|
36421
|
+
const onRetryAttempt = (attempt, error, delayMs) => {
|
|
36422
|
+
this._options.runner.instrumentData.errorCount++;
|
|
36423
|
+
this._options.runner.instrumentData.requestCount++;
|
|
36424
|
+
const message = `TestCaseFhirBase:onRetryAttempt(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
36425
|
+
this.Warning(message);
|
|
36426
|
+
this._options.runner.instrumentData.message.push(chalk.default.red(message));
|
|
36427
|
+
};
|
|
36428
|
+
const fhirOptions = this._options.fhirOptions;
|
|
36429
|
+
const fhirRESTClient = new _nsshunt_stsfhirclient.FhirRESTClient({
|
|
36430
|
+
GetAccessToken: this.GetAccessToken,
|
|
36431
|
+
user: "USR_user01@stsmda.com.au",
|
|
36432
|
+
endpoint: fhirOptions.stsfhirserverendpoint,
|
|
36433
|
+
stsfhirapiroot: fhirOptions.stsfhirapiroot,
|
|
36434
|
+
stsfhirport: fhirOptions.stsfhirport,
|
|
36435
|
+
logger: this.logger,
|
|
36436
|
+
agentManager: this.GetFhirAgentManager(),
|
|
36437
|
+
onRetryAttempt
|
|
36438
|
+
});
|
|
36439
|
+
this.restFhirClient = fhirRESTClient;
|
|
36440
|
+
return fhirRESTClient;
|
|
36441
|
+
};
|
|
36442
|
+
GetClient = async () => {
|
|
36443
|
+
let client;
|
|
36444
|
+
if (this._options.runner.options.fhirOptions.stsfhirsocketclientmode === "no-socket-client") client = await this.GetRESTClient();
|
|
36445
|
+
else client = await this.GetFhirSocketClient();
|
|
36446
|
+
return client;
|
|
36447
|
+
};
|
|
36459
36448
|
};
|
|
36460
36449
|
//#endregion
|
|
36461
36450
|
exports.WorkerFhirTestCases = WorkerFhirTestCases;
|