@nsshunt/ststestrunner 1.1.104 → 1.1.106
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 +595 -381
- package/dist/ststestrunner.cjs.map +1 -1
- package/dist/ststestrunner.mjs +594 -380
- package/dist/ststestrunner.mjs.map +1 -1
- package/package.json +3 -2
- package/types/libmodule/authHelper.d.ts +37 -0
- package/types/libmodule/authHelper.d.ts.map +1 -0
- package/types/libmodule/clientHelper.d.ts +32 -0
- package/types/libmodule/clientHelper.d.ts.map +1 -0
- package/types/libmodule/lockHelper.d.ts +8 -0
- package/types/libmodule/lockHelper.d.ts.map +1 -0
- package/types/libmodule/testCaseFhirBase.d.ts +6 -27
- package/types/libmodule/testCaseFhirBase.d.ts.map +1 -1
- package/types/libmodule/workerFhirTestCases.d.ts +20 -13
- package/types/libmodule/workerFhirTestCases.d.ts.map +1 -1
package/dist/ststestrunner.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { AbstractRunnerExecutionWorker } from "@nsshunt/stsrunnerframework";
|
|
2
|
-
import chalk from "chalk";
|
|
3
2
|
import { STSAxiosConfig, Sleep, createAgentManager, isNode } from "@nsshunt/stsutils";
|
|
4
|
-
import
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import axios from "axios";
|
|
5
5
|
import http from "node:http";
|
|
6
6
|
import https from "node:https";
|
|
7
|
-
import
|
|
7
|
+
import { FhirRESTClient, FhirSocketClientAllInOne, FhirSocketClientIndividual, createRetryAxiosClient } from "@nsshunt/stsfhirclient";
|
|
8
8
|
//#region \0rolldown/runtime.js
|
|
9
9
|
var __defProp = Object.defineProperty;
|
|
10
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
10
11
|
var __exportAll = (all, no_symbols) => {
|
|
11
12
|
let target = {};
|
|
12
13
|
for (var name in all) __defProp(target, name, {
|
|
@@ -379,190 +380,40 @@ var StatusCodes;
|
|
|
379
380
|
//#region src/libmodule/testCaseFhirBase.ts
|
|
380
381
|
var TestCaseFhirBase = class {
|
|
381
382
|
#options;
|
|
382
|
-
#randomDataRecordset = [];
|
|
383
383
|
#runner;
|
|
384
384
|
#runnerExecutionWorker;
|
|
385
|
-
#accesssToken = null;
|
|
386
385
|
#publishTelemetryCount = 0;
|
|
387
386
|
#maxBufferSize = 50;
|
|
388
387
|
#publishTelemetryTimeout = null;
|
|
389
388
|
#publishTelemetryTimeoutVal = 1e3;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
389
|
+
_RetryMap = [
|
|
390
|
+
100,
|
|
391
|
+
250,
|
|
392
|
+
500,
|
|
393
|
+
1e3,
|
|
394
|
+
2e3,
|
|
395
|
+
3e3
|
|
396
|
+
];
|
|
394
397
|
_id = crypto.randomUUID();
|
|
395
398
|
retryCount = 0;
|
|
396
399
|
maxAuthRetryCount = 5;
|
|
397
400
|
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
401
|
constructor(runnerExecutionWorker, runner) {
|
|
427
402
|
this.#options = runner.options;
|
|
428
403
|
this.#runnerExecutionWorker = runnerExecutionWorker;
|
|
429
404
|
this.#runner = runner;
|
|
430
|
-
this.#authAgentManager = this.GetAuthAgentManager();
|
|
431
405
|
}
|
|
432
406
|
get runnerExecutionWorker() {
|
|
433
407
|
return this.#runnerExecutionWorker;
|
|
434
408
|
}
|
|
435
409
|
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
410
|
Error = (message) => {
|
|
557
411
|
this.#runnerExecutionWorker.logger.error(message);
|
|
558
412
|
this.#runner.instrumentData.message.push(chalk.red(`${message}`));
|
|
559
413
|
};
|
|
560
|
-
|
|
561
|
-
this.#runnerExecutionWorker.logger.
|
|
414
|
+
Debug = (message) => {
|
|
415
|
+
this.#runnerExecutionWorker.logger.debug(message);
|
|
562
416
|
};
|
|
563
|
-
get accesssToken() {
|
|
564
|
-
return this.#accesssToken;
|
|
565
|
-
}
|
|
566
417
|
get runner() {
|
|
567
418
|
return this.#runner;
|
|
568
419
|
}
|
|
@@ -605,125 +456,6 @@ var TestCaseFhirBase = class {
|
|
|
605
456
|
this.#runner.instrumentData.rx = 0;
|
|
606
457
|
await this.SleepImmediate();
|
|
607
458
|
};
|
|
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
459
|
HandleError = (error) => {
|
|
728
460
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] Error: [${error}]`));
|
|
729
461
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] description: [${this.runner.options.description}]`));
|
|
@@ -738,48 +470,18 @@ var TestCaseFhirBase = class {
|
|
|
738
470
|
if (axiosError.response.status === StatusCodes.UNAUTHORIZED) {
|
|
739
471
|
this.runner.instrumentData.authenticationErrorCount++;
|
|
740
472
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
|
|
741
|
-
this.ResetAccessToken();
|
|
473
|
+
this.runnerExecutionWorker.authHelper.ResetAccessToken();
|
|
742
474
|
return true;
|
|
743
475
|
}
|
|
744
476
|
} else this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] AXIOS Error = [${axiosError}]`));
|
|
745
477
|
} else if (error.message === "UNAUTHORIZED") {
|
|
746
478
|
this.runner.instrumentData.authenticationErrorCount++;
|
|
747
479
|
this.Error(chalk.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
|
|
748
|
-
this.ResetAccessToken();
|
|
480
|
+
this.runnerExecutionWorker.authHelper.ResetAccessToken();
|
|
749
481
|
return true;
|
|
750
482
|
}
|
|
751
483
|
return false;
|
|
752
484
|
};
|
|
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
485
|
GetPersonRecord = async (prefix, index, version) => {
|
|
784
486
|
const { workerIndex, runnerIndex, runId } = this.#options;
|
|
785
487
|
const useId = `${prefix}-${index}`;
|
|
@@ -806,37 +508,12 @@ var TestCaseFhirBase = class {
|
|
|
806
508
|
}
|
|
807
509
|
};
|
|
808
510
|
};
|
|
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
511
|
#ForcePublishTelemetryData = async () => {
|
|
834
512
|
await this.#PublishTelemetryData();
|
|
835
513
|
};
|
|
836
514
|
#SetupTimeout = async () => {
|
|
837
515
|
if (!this.#publishTelemetryTimeout) {
|
|
838
516
|
this.#publishTelemetryTimeout = setTimeout(async () => {
|
|
839
|
-
this.#LogMessage(chalk.yellow(` **** TIMEOUT **** `));
|
|
840
517
|
await this.#PublishTelemetryData();
|
|
841
518
|
this.#publishTelemetryCount = 0;
|
|
842
519
|
this.#publishTelemetryTimeout = null;
|
|
@@ -846,7 +523,6 @@ var TestCaseFhirBase = class {
|
|
|
846
523
|
};
|
|
847
524
|
PublishTelemetry = async () => {
|
|
848
525
|
this.#publishTelemetryCount++;
|
|
849
|
-
this.#LogMessage(chalk.red(this.#publishTelemetryCount));
|
|
850
526
|
if (this.#publishTelemetryCount % this.#maxBufferSize === 0) {
|
|
851
527
|
this.#publishTelemetryCount = 0;
|
|
852
528
|
if (this.#publishTelemetryTimeout) {
|
|
@@ -859,7 +535,6 @@ var TestCaseFhirBase = class {
|
|
|
859
535
|
};
|
|
860
536
|
#OutputLogMessage = async (message) => {
|
|
861
537
|
const messageOutput = chalk.grey(message);
|
|
862
|
-
this.#LogMessage(messageOutput);
|
|
863
538
|
this.#runner.instrumentData.message.push(messageOutput);
|
|
864
539
|
await this.PublishTelemetry();
|
|
865
540
|
};
|
|
@@ -907,12 +582,6 @@ var TestCaseFhirBase = class {
|
|
|
907
582
|
await this.#ForcePublishTelemetryData();
|
|
908
583
|
return true;
|
|
909
584
|
};
|
|
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
585
|
_GetDetail = () => {
|
|
917
586
|
return `testType: [${this.runner.options.testType}], description: [${this.runner.options.description}], workerManagerId: [${this.runner.workerManagerId}], Iteration: [${this.runner.iteration}]`;
|
|
918
587
|
};
|
|
@@ -929,14 +598,6 @@ var TestCaseFhirBase = class {
|
|
|
929
598
|
this.retryCount = 0;
|
|
930
599
|
return this._ExecuteQuery();
|
|
931
600
|
};
|
|
932
|
-
_RetryMap = [
|
|
933
|
-
100,
|
|
934
|
-
250,
|
|
935
|
-
500,
|
|
936
|
-
1e3,
|
|
937
|
-
2e3,
|
|
938
|
-
3e3
|
|
939
|
-
];
|
|
940
601
|
_ExecuteQuery = async () => {
|
|
941
602
|
try {
|
|
942
603
|
return await this.PerformExecuteQuery();
|
|
@@ -959,6 +620,9 @@ var TestCaseFhirBase = class {
|
|
|
959
620
|
else throw error;
|
|
960
621
|
}
|
|
961
622
|
};
|
|
623
|
+
GetClient = async () => {
|
|
624
|
+
return this.runnerExecutionWorker.GetClient();
|
|
625
|
+
};
|
|
962
626
|
};
|
|
963
627
|
//#endregion
|
|
964
628
|
//#region src/libmodule/testCaseFhirQueryBase.ts
|
|
@@ -1040,9 +704,9 @@ var TestCaseFhirQueryBase = class extends TestCaseFhirBase {
|
|
|
1040
704
|
var TestCaseFhir01 = class extends TestCaseFhirQueryBase {
|
|
1041
705
|
PerformExecuteQuery = async () => {
|
|
1042
706
|
const __snapshot1 = performance.now();
|
|
1043
|
-
await this.GetAccessToken();
|
|
707
|
+
await this.runnerExecutionWorker.authHelper.GetAccessToken();
|
|
1044
708
|
this._CheckOutputLongDurationError(__snapshot1, "await this.GetAccessToken()");
|
|
1045
|
-
this.ResetAccessToken();
|
|
709
|
+
this.runnerExecutionWorker.authHelper.ResetAccessToken();
|
|
1046
710
|
return null;
|
|
1047
711
|
};
|
|
1048
712
|
};
|
|
@@ -36370,27 +36034,535 @@ var ResourceDataGenerator = class {
|
|
|
36370
36034
|
};
|
|
36371
36035
|
};
|
|
36372
36036
|
//#endregion
|
|
36037
|
+
//#region src/libmodule/lockHelper.ts
|
|
36038
|
+
var import_tiny_emitter = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
36039
|
+
function E() {}
|
|
36040
|
+
E.prototype = {
|
|
36041
|
+
on: function(name, callback, ctx) {
|
|
36042
|
+
var e = this.e || (this.e = {});
|
|
36043
|
+
(e[name] || (e[name] = [])).push({
|
|
36044
|
+
fn: callback,
|
|
36045
|
+
ctx
|
|
36046
|
+
});
|
|
36047
|
+
return this;
|
|
36048
|
+
},
|
|
36049
|
+
once: function(name, callback, ctx) {
|
|
36050
|
+
var self = this;
|
|
36051
|
+
function listener() {
|
|
36052
|
+
self.off(name, listener);
|
|
36053
|
+
callback.apply(ctx, arguments);
|
|
36054
|
+
}
|
|
36055
|
+
listener._ = callback;
|
|
36056
|
+
return this.on(name, listener, ctx);
|
|
36057
|
+
},
|
|
36058
|
+
emit: function(name) {
|
|
36059
|
+
var data = [].slice.call(arguments, 1);
|
|
36060
|
+
var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
|
|
36061
|
+
var i = 0;
|
|
36062
|
+
var len = evtArr.length;
|
|
36063
|
+
for (; i < len; i++) evtArr[i].fn.apply(evtArr[i].ctx, data);
|
|
36064
|
+
return this;
|
|
36065
|
+
},
|
|
36066
|
+
off: function(name, callback) {
|
|
36067
|
+
var e = this.e || (this.e = {});
|
|
36068
|
+
var evts = e[name];
|
|
36069
|
+
var liveEvents = [];
|
|
36070
|
+
if (evts && callback) {
|
|
36071
|
+
for (var i = 0, len = evts.length; i < len; i++) if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]);
|
|
36072
|
+
}
|
|
36073
|
+
liveEvents.length ? e[name] = liveEvents : delete e[name];
|
|
36074
|
+
return this;
|
|
36075
|
+
}
|
|
36076
|
+
};
|
|
36077
|
+
module.exports = E;
|
|
36078
|
+
module.exports.TinyEmitter = E;
|
|
36079
|
+
})))();
|
|
36080
|
+
var LockHelper = class {
|
|
36081
|
+
_onHoldKeys = {};
|
|
36082
|
+
GetOnHold = (holdKey) => {
|
|
36083
|
+
if (this._onHoldKeys[holdKey]) return true;
|
|
36084
|
+
return false;
|
|
36085
|
+
};
|
|
36086
|
+
WaitOnHold = async (holdKey, timeout) => {
|
|
36087
|
+
const start = performance.now();
|
|
36088
|
+
for (;;) {
|
|
36089
|
+
if (this._onHoldKeys[holdKey]) await Sleep(100);
|
|
36090
|
+
else break;
|
|
36091
|
+
if (performance.now() - start > timeout) throw new Error(`WorkerFhirTestCases:WaitOnHold(): Timeout: [${timeout}] reached.`);
|
|
36092
|
+
}
|
|
36093
|
+
return true;
|
|
36094
|
+
};
|
|
36095
|
+
SetOnHold = (holdKey) => {
|
|
36096
|
+
this._onHoldKeys[holdKey] = true;
|
|
36097
|
+
};
|
|
36098
|
+
ReleaseOnHold = (holdKey) => {
|
|
36099
|
+
delete this._onHoldKeys[holdKey];
|
|
36100
|
+
};
|
|
36101
|
+
};
|
|
36102
|
+
//#endregion
|
|
36103
|
+
//#region src/libmodule/authHelper.ts
|
|
36104
|
+
var AuthHelper = class extends import_tiny_emitter.TinyEmitter {
|
|
36105
|
+
_options;
|
|
36106
|
+
_id = crypto.randomUUID();
|
|
36107
|
+
_lockHelper = new LockHelper();
|
|
36108
|
+
#accesssToken = null;
|
|
36109
|
+
_authMaxTimeout = 5e3;
|
|
36110
|
+
#originRegex = /^(api:\/\/\w+)/;
|
|
36111
|
+
#authAgentManager;
|
|
36112
|
+
logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
|
|
36113
|
+
constructor(options) {
|
|
36114
|
+
super();
|
|
36115
|
+
this._options = options;
|
|
36116
|
+
this.#authAgentManager = this.GetAuthAgentManager();
|
|
36117
|
+
}
|
|
36118
|
+
Warning = (message) => {
|
|
36119
|
+
this._options.logger.warn(`${this.logPrefix}${message}`);
|
|
36120
|
+
};
|
|
36121
|
+
Error = (message) => {
|
|
36122
|
+
this._options.logger.error(`${this.logPrefix}${message}`);
|
|
36123
|
+
};
|
|
36124
|
+
Debug = (message) => {
|
|
36125
|
+
this._options.logger.debug(`${this.logPrefix}${message}`);
|
|
36126
|
+
};
|
|
36127
|
+
get id() {
|
|
36128
|
+
return this._id;
|
|
36129
|
+
}
|
|
36130
|
+
defaultAgentOptions = {
|
|
36131
|
+
keepAlive: true,
|
|
36132
|
+
maxSockets: 10,
|
|
36133
|
+
maxTotalSockets: 20,
|
|
36134
|
+
maxFreeSockets: 10,
|
|
36135
|
+
timeout: 6e4,
|
|
36136
|
+
rejectUnauthorized: false
|
|
36137
|
+
};
|
|
36138
|
+
stressTestAgentOptions = {
|
|
36139
|
+
keepAlive: true,
|
|
36140
|
+
maxSockets: 200,
|
|
36141
|
+
maxTotalSockets: 500,
|
|
36142
|
+
maxFreeSockets: 50,
|
|
36143
|
+
timeout: 3e4,
|
|
36144
|
+
rejectUnauthorized: false
|
|
36145
|
+
};
|
|
36146
|
+
stressTestExtremeAgentOptions = {
|
|
36147
|
+
keepAlive: true,
|
|
36148
|
+
maxSockets: 500,
|
|
36149
|
+
maxTotalSockets: 1e3,
|
|
36150
|
+
maxFreeSockets: 500,
|
|
36151
|
+
timeout: 3e4,
|
|
36152
|
+
rejectUnauthorized: false
|
|
36153
|
+
};
|
|
36154
|
+
GetAgentManager = (testingAgentOptions) => {
|
|
36155
|
+
let agentManager = void 0;
|
|
36156
|
+
let agentOptions = void 0;
|
|
36157
|
+
switch (testingAgentOptions.nodeAgentMode) {
|
|
36158
|
+
case "no-agent": break;
|
|
36159
|
+
case "custom-agent-options":
|
|
36160
|
+
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
36161
|
+
else agentOptions = { ...this.defaultAgentOptions };
|
|
36162
|
+
break;
|
|
36163
|
+
case "default-agent-options":
|
|
36164
|
+
agentOptions = { ...this.defaultAgentOptions };
|
|
36165
|
+
break;
|
|
36166
|
+
case "stress-test-agent-options":
|
|
36167
|
+
agentOptions = { ...this.stressTestAgentOptions };
|
|
36168
|
+
break;
|
|
36169
|
+
case "stress-test-extreme-agent-options":
|
|
36170
|
+
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
36171
|
+
break;
|
|
36172
|
+
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
36173
|
+
}
|
|
36174
|
+
if (agentOptions) agentManager = createAgentManager({
|
|
36175
|
+
agentOptions,
|
|
36176
|
+
httpAgentFactory(options) {
|
|
36177
|
+
return new http.Agent(options);
|
|
36178
|
+
},
|
|
36179
|
+
httpsAgentFactory(options) {
|
|
36180
|
+
return new https.Agent(options);
|
|
36181
|
+
}
|
|
36182
|
+
});
|
|
36183
|
+
return agentManager;
|
|
36184
|
+
};
|
|
36185
|
+
GetAuthAgentManager = () => {
|
|
36186
|
+
return this.GetAgentManager(this._options.authOptions.asagentoptions);
|
|
36187
|
+
};
|
|
36188
|
+
ExtractOrigin = (uri) => {
|
|
36189
|
+
const match = uri.match(this.#originRegex);
|
|
36190
|
+
return match ? match[1] : null;
|
|
36191
|
+
};
|
|
36192
|
+
GetAPITokenFromAuthServerUsingScope = async (options) => {
|
|
36193
|
+
const { scope, clientId, authClientSecret, endPoint } = options;
|
|
36194
|
+
let stage = "1";
|
|
36195
|
+
try {
|
|
36196
|
+
stage = "2";
|
|
36197
|
+
const scopes = scope.split(" ");
|
|
36198
|
+
let origin = null;
|
|
36199
|
+
let error = null;
|
|
36200
|
+
stage = "3";
|
|
36201
|
+
for (let i = 0; i < scopes.length; i++) {
|
|
36202
|
+
const s = scopes[i];
|
|
36203
|
+
if (!origin) {
|
|
36204
|
+
origin = this.ExtractOrigin(s);
|
|
36205
|
+
if (!origin) {
|
|
36206
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
36207
|
+
break;
|
|
36208
|
+
}
|
|
36209
|
+
} else {
|
|
36210
|
+
const nextOrigin = this.ExtractOrigin(s);
|
|
36211
|
+
if (!nextOrigin) {
|
|
36212
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
|
|
36213
|
+
break;
|
|
36214
|
+
} else if (origin.localeCompare(nextOrigin) !== 0) {
|
|
36215
|
+
error = /* @__PURE__ */ new Error(`Scope: [${scope}] not all from the same client API. All scopes must come from the same client API.`);
|
|
36216
|
+
break;
|
|
36217
|
+
}
|
|
36218
|
+
}
|
|
36219
|
+
}
|
|
36220
|
+
stage = "4";
|
|
36221
|
+
if (error) throw error;
|
|
36222
|
+
stage = "5";
|
|
36223
|
+
const payload = {
|
|
36224
|
+
client_id: clientId,
|
|
36225
|
+
client_secret: authClientSecret,
|
|
36226
|
+
scope,
|
|
36227
|
+
grant_type: "client_credentials"
|
|
36228
|
+
};
|
|
36229
|
+
stage = "6";
|
|
36230
|
+
const url = endPoint ? `${endPoint}${this._options.authOptions.asoauthapiroot}/token` : `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}${this._options.authOptions.asoauthapiroot}/token`;
|
|
36231
|
+
stage = `6.5: url: [${url}] payload: [${JSON.stringify(payload)}]`;
|
|
36232
|
+
const axiosConfig = new STSAxiosConfig(url, "post").withDefaultHeaders().withData(payload);
|
|
36233
|
+
if (this.#authAgentManager) axiosConfig.withAgentManager(this.#authAgentManager);
|
|
36234
|
+
const retVal = await createRetryAxiosClient({
|
|
36235
|
+
maxRetries: 4,
|
|
36236
|
+
retryDelayMs: 300,
|
|
36237
|
+
retryJitterMs: 150,
|
|
36238
|
+
maxRetryDurationMs: 5e3,
|
|
36239
|
+
onRetryAttempt: (attempt, error, delayMs) => {
|
|
36240
|
+
this.emit("authenticationErrorCount", 1);
|
|
36241
|
+
this.emit("authenticationRetryCount", 1);
|
|
36242
|
+
const message = `GetAPITokenFromAuthServerUsingScope(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
36243
|
+
this.Warning(message);
|
|
36244
|
+
this.emit("logMessage", chalk.red(message));
|
|
36245
|
+
}
|
|
36246
|
+
})(url, axiosConfig.config);
|
|
36247
|
+
this.emit("authenticationCount", 1);
|
|
36248
|
+
stage = "7";
|
|
36249
|
+
if (retVal.status) {
|
|
36250
|
+
if (retVal.status !== 200) this.Warning(chalk.magenta(`GetAPITokenFromAuthServerUsingScope(): [${this._id}] Invalid response from server: [${retVal.status}]`));
|
|
36251
|
+
} else throw new Error(chalk.red(`No retVal.status)`));
|
|
36252
|
+
stage = "8";
|
|
36253
|
+
if (retVal.data) {
|
|
36254
|
+
stage = "9";
|
|
36255
|
+
if (retVal.data.access_token) {
|
|
36256
|
+
stage = "12";
|
|
36257
|
+
return retVal.data.access_token;
|
|
36258
|
+
} else {
|
|
36259
|
+
stage = "13";
|
|
36260
|
+
throw new Error(`No retVal.data.access_token)`);
|
|
36261
|
+
}
|
|
36262
|
+
} else {
|
|
36263
|
+
stage = "14";
|
|
36264
|
+
throw new Error(`No retVal.data)`);
|
|
36265
|
+
}
|
|
36266
|
+
} catch (error) {
|
|
36267
|
+
this.Error(error);
|
|
36268
|
+
let details = "None available.";
|
|
36269
|
+
if (error.response && error.response.data) try {
|
|
36270
|
+
details = JSON.stringify(error.response.data);
|
|
36271
|
+
} catch (error) {
|
|
36272
|
+
details = `Could not JSON.stringify(error.response.data)`;
|
|
36273
|
+
}
|
|
36274
|
+
error.message = `${this.logPrefix}GetAPITokenFromAuthServerUsingScope(): Error: [${error}], Stage: [${stage}], Details: [${details}]`;
|
|
36275
|
+
throw error;
|
|
36276
|
+
}
|
|
36277
|
+
};
|
|
36278
|
+
GetAccessToken = async () => {
|
|
36279
|
+
let timeout = void 0;
|
|
36280
|
+
const start = performance.now();
|
|
36281
|
+
try {
|
|
36282
|
+
if (this.#accesssToken) return this.#accesssToken;
|
|
36283
|
+
const lockKey = "GetAccessToken";
|
|
36284
|
+
const lockTimeout = 6e4;
|
|
36285
|
+
if (this._lockHelper.GetOnHold(lockKey) === true) {
|
|
36286
|
+
this.Debug(chalk.magenta(`GetAccessToken(): accesssToken does not exist - some other client setting up the new accesssToken (on hold/lock), lock key: [${lockKey}] - waiting ...`));
|
|
36287
|
+
try {
|
|
36288
|
+
const miniStart = performance.now();
|
|
36289
|
+
await this._lockHelper.WaitOnHold(lockKey, lockTimeout);
|
|
36290
|
+
this.Debug(chalk.yellow(`GetAccessToken(): hold (lock) released after: [${performance.now() - miniStart}ms], lock key: [${lockKey}]`));
|
|
36291
|
+
if (this.#accesssToken) {
|
|
36292
|
+
this.Debug(chalk.green(`GetAccessToken(): Getting existing accesssToken (post hold release), lock key: [${lockKey}]`));
|
|
36293
|
+
return this.#accesssToken;
|
|
36294
|
+
} else {
|
|
36295
|
+
this.Error(chalk.red(`GetAccessToken(): Could not get existing accesssToken (post hold release), lock key: [${lockKey}]`));
|
|
36296
|
+
this.Error(chalk.red(`GetAccessToken(): continue anyway ...`));
|
|
36297
|
+
}
|
|
36298
|
+
} catch (error) {
|
|
36299
|
+
this.Error(chalk.red(`GetAccessToken(): Error: [${error}]`));
|
|
36300
|
+
}
|
|
36301
|
+
}
|
|
36302
|
+
this.Debug(chalk.yellow(`GetAccessToken(): accesssToken does not exist - setting up new accesssToken`));
|
|
36303
|
+
this.Debug(chalk.yellow(`GetAccessToken(): setting hold (lock), lock key: [${lockKey}]`));
|
|
36304
|
+
this._lockHelper.SetOnHold(lockKey);
|
|
36305
|
+
timeout = setTimeout(() => {
|
|
36306
|
+
this.Warning(chalk.magenta(`GetAccessToken(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`));
|
|
36307
|
+
}, this._authMaxTimeout);
|
|
36308
|
+
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:All`.split(" ").sort().join(" ");
|
|
36309
|
+
const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
|
|
36310
|
+
const workingAaccesssToken = await this.GetAPITokenFromAuthServerUsingScope({
|
|
36311
|
+
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
36312
|
+
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
36313
|
+
scope: scopes,
|
|
36314
|
+
endPoint: authendpointUrl
|
|
36315
|
+
});
|
|
36316
|
+
if (timeout) clearTimeout(timeout);
|
|
36317
|
+
const totalTime = performance.now() - start;
|
|
36318
|
+
if (totalTime > this._authMaxTimeout) this.Warning(chalk.magenta(`GetAccessToken(): The total time for getting the access token: [${totalTime}]`));
|
|
36319
|
+
this.#accesssToken = workingAaccesssToken;
|
|
36320
|
+
this._lockHelper.ReleaseOnHold(lockKey);
|
|
36321
|
+
this.Debug(chalk.yellow(`GetAccessToken(): release hold (lock) Time taken for get access token: [${performance.now() - start}ms]`));
|
|
36322
|
+
return this.#accesssToken;
|
|
36323
|
+
} catch (error) {
|
|
36324
|
+
if (timeout) clearTimeout(timeout);
|
|
36325
|
+
error.message = `GetAccessToken(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
|
|
36326
|
+
this.Error(error);
|
|
36327
|
+
return "";
|
|
36328
|
+
}
|
|
36329
|
+
};
|
|
36330
|
+
GetAccessTokenForSocketClientAccess = async () => {
|
|
36331
|
+
const timeout = setTimeout(() => {
|
|
36332
|
+
this.Warning(`GetAccessTokenForSocketClientAccess(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`);
|
|
36333
|
+
}, this._authMaxTimeout);
|
|
36334
|
+
const start = performance.now();
|
|
36335
|
+
try {
|
|
36336
|
+
const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:SocketConnection`.split(" ").sort().join(" ");
|
|
36337
|
+
const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
|
|
36338
|
+
const retVal = await this.GetAPITokenFromAuthServerUsingScope({
|
|
36339
|
+
clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
|
|
36340
|
+
authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
|
|
36341
|
+
scope: scopes,
|
|
36342
|
+
endPoint: authendpointUrl
|
|
36343
|
+
});
|
|
36344
|
+
clearTimeout(timeout);
|
|
36345
|
+
const totalTime = performance.now() - start;
|
|
36346
|
+
if (totalTime > this._authMaxTimeout) this.Warning(chalk.magenta(`GetAccessTokenForSocketClientAccess(): The total time for getting the access token: [${totalTime}]`));
|
|
36347
|
+
return retVal;
|
|
36348
|
+
} catch (error) {
|
|
36349
|
+
clearTimeout(timeout);
|
|
36350
|
+
error.message = `GetAccessTokenForSocketClientAccess(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
|
|
36351
|
+
this.Error(error);
|
|
36352
|
+
return "";
|
|
36353
|
+
}
|
|
36354
|
+
};
|
|
36355
|
+
ResetAccessToken = () => {
|
|
36356
|
+
this.#accesssToken = null;
|
|
36357
|
+
};
|
|
36358
|
+
};
|
|
36359
|
+
//#endregion
|
|
36360
|
+
//#region src/libmodule/clientHelper.ts
|
|
36361
|
+
var ClientHelper = class extends import_tiny_emitter.TinyEmitter {
|
|
36362
|
+
_options;
|
|
36363
|
+
fhirClient = void 0;
|
|
36364
|
+
_id = crypto.randomUUID();
|
|
36365
|
+
_lockHelper = new LockHelper();
|
|
36366
|
+
restFhirClient = null;
|
|
36367
|
+
logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
|
|
36368
|
+
constructor(options) {
|
|
36369
|
+
super();
|
|
36370
|
+
this._options = options;
|
|
36371
|
+
}
|
|
36372
|
+
Warning = (message) => {
|
|
36373
|
+
this._options.logger.warn(`${this.logPrefix}${message}`);
|
|
36374
|
+
};
|
|
36375
|
+
Error = (message) => {
|
|
36376
|
+
this._options.logger.error(`${this.logPrefix}${message}`);
|
|
36377
|
+
};
|
|
36378
|
+
Debug = (message) => {
|
|
36379
|
+
this._options.logger.debug(`${this.logPrefix}${message}`);
|
|
36380
|
+
};
|
|
36381
|
+
get id() {
|
|
36382
|
+
return this._id;
|
|
36383
|
+
}
|
|
36384
|
+
defaultAgentOptions = {
|
|
36385
|
+
keepAlive: true,
|
|
36386
|
+
maxSockets: 10,
|
|
36387
|
+
maxTotalSockets: 20,
|
|
36388
|
+
maxFreeSockets: 10,
|
|
36389
|
+
timeout: 6e4,
|
|
36390
|
+
rejectUnauthorized: false
|
|
36391
|
+
};
|
|
36392
|
+
stressTestAgentOptions = {
|
|
36393
|
+
keepAlive: true,
|
|
36394
|
+
maxSockets: 200,
|
|
36395
|
+
maxTotalSockets: 500,
|
|
36396
|
+
maxFreeSockets: 50,
|
|
36397
|
+
timeout: 3e4,
|
|
36398
|
+
rejectUnauthorized: false
|
|
36399
|
+
};
|
|
36400
|
+
stressTestExtremeAgentOptions = {
|
|
36401
|
+
keepAlive: true,
|
|
36402
|
+
maxSockets: 500,
|
|
36403
|
+
maxTotalSockets: 1e3,
|
|
36404
|
+
maxFreeSockets: 500,
|
|
36405
|
+
timeout: 3e4,
|
|
36406
|
+
rejectUnauthorized: false
|
|
36407
|
+
};
|
|
36408
|
+
GetAgentManager = (testingAgentOptions) => {
|
|
36409
|
+
let agentManager = void 0;
|
|
36410
|
+
let agentOptions = void 0;
|
|
36411
|
+
switch (testingAgentOptions.nodeAgentMode) {
|
|
36412
|
+
case "no-agent": break;
|
|
36413
|
+
case "custom-agent-options":
|
|
36414
|
+
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
36415
|
+
else agentOptions = { ...this.defaultAgentOptions };
|
|
36416
|
+
break;
|
|
36417
|
+
case "default-agent-options":
|
|
36418
|
+
agentOptions = { ...this.defaultAgentOptions };
|
|
36419
|
+
break;
|
|
36420
|
+
case "stress-test-agent-options":
|
|
36421
|
+
agentOptions = { ...this.stressTestAgentOptions };
|
|
36422
|
+
break;
|
|
36423
|
+
case "stress-test-extreme-agent-options":
|
|
36424
|
+
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
36425
|
+
break;
|
|
36426
|
+
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
36427
|
+
}
|
|
36428
|
+
if (agentOptions) agentManager = createAgentManager({
|
|
36429
|
+
agentOptions,
|
|
36430
|
+
httpAgentFactory(options) {
|
|
36431
|
+
return new http.Agent(options);
|
|
36432
|
+
},
|
|
36433
|
+
httpsAgentFactory(options) {
|
|
36434
|
+
return new https.Agent(options);
|
|
36435
|
+
}
|
|
36436
|
+
});
|
|
36437
|
+
return agentManager;
|
|
36438
|
+
};
|
|
36439
|
+
GetFhirAgentManager = () => {
|
|
36440
|
+
return this.GetAgentManager(this._options.fhirOptions.stsfhiragentOptions);
|
|
36441
|
+
};
|
|
36442
|
+
GetFhirSocketClient = async () => {
|
|
36443
|
+
try {
|
|
36444
|
+
if (this.fhirClient) return this.fhirClient;
|
|
36445
|
+
const lockKey = "GetFhirSocketClient";
|
|
36446
|
+
const lockTimeout = 6e4;
|
|
36447
|
+
if (this._lockHelper.GetOnHold(lockKey) === true) {
|
|
36448
|
+
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 ...`));
|
|
36449
|
+
try {
|
|
36450
|
+
const start = performance.now();
|
|
36451
|
+
await this._lockHelper.WaitOnHold(lockKey, lockTimeout);
|
|
36452
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): hold (lock) released after: [${performance.now() - start}ms], lock key: [${lockKey}]`));
|
|
36453
|
+
if (this.fhirClient) {
|
|
36454
|
+
this.Debug(chalk.green(`GetFhirSocketClient(): Getting existing fhir client (post hold release), lock key: [${lockKey}]`));
|
|
36455
|
+
return this.fhirClient;
|
|
36456
|
+
} else {
|
|
36457
|
+
this.Error(chalk.red(`GetFhirSocketClient(): Could not get existing fhir client (post hold release), lock key: [${lockKey}]`));
|
|
36458
|
+
this.Error(chalk.red(`GetFhirSocketClient(): continue anyway ...`));
|
|
36459
|
+
}
|
|
36460
|
+
} catch (error) {
|
|
36461
|
+
this.Error(chalk.red(`GetFhirSocketClient(): Error: [${error}]`));
|
|
36462
|
+
}
|
|
36463
|
+
}
|
|
36464
|
+
const start = performance.now();
|
|
36465
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): fhir client does not exist - setting up new client`));
|
|
36466
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): setting hold (lock), lock key: [${lockKey}]`));
|
|
36467
|
+
this._lockHelper.SetOnHold(lockKey);
|
|
36468
|
+
const fhirOptions = this._options.fhirOptions;
|
|
36469
|
+
const options = {
|
|
36470
|
+
fhirServerEndpoint: fhirOptions.stsfhirserverendpoint,
|
|
36471
|
+
fhirapiroot: fhirOptions.stsfhirapiroot,
|
|
36472
|
+
fhirServerPort: fhirOptions.stsfhirport,
|
|
36473
|
+
socketClientName: fhirOptions.stsfhirsocketname,
|
|
36474
|
+
socketIoCustomPath: fhirOptions.stsfhirsocketcustompath,
|
|
36475
|
+
timeout: fhirOptions.stsfhirsockettimeout,
|
|
36476
|
+
baseUrl: fhirOptions.stsfhirbaseurl,
|
|
36477
|
+
agentManager: this.GetFhirAgentManager(),
|
|
36478
|
+
joinRooms: [],
|
|
36479
|
+
logger: this._options.logger,
|
|
36480
|
+
verboseLogging: true,
|
|
36481
|
+
GetConnectionAccessToken: this._options.authHelper.GetAccessTokenForSocketClientAccess,
|
|
36482
|
+
GetAccessToken: this._options.authHelper.GetAccessToken
|
|
36483
|
+
};
|
|
36484
|
+
let workingFhirClient;
|
|
36485
|
+
if (this._options.fhirOptions.stsfhirsocketclientmode === "socket-client-all-in-one") workingFhirClient = new FhirSocketClientAllInOne("FhirSocketClient", options);
|
|
36486
|
+
else workingFhirClient = new FhirSocketClientIndividual("FhirSocketClient", options);
|
|
36487
|
+
await workingFhirClient.WaitForSocketConnected();
|
|
36488
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): setting fhir client into object`));
|
|
36489
|
+
this.fhirClient = workingFhirClient;
|
|
36490
|
+
this._lockHelper.ReleaseOnHold(lockKey);
|
|
36491
|
+
this.Debug(chalk.yellow(`GetFhirSocketClient(): release hold (lock) Time taken for socket connection and set object: [${performance.now() - start}ms], lock key: [${lockKey}]`));
|
|
36492
|
+
return this.fhirClient;
|
|
36493
|
+
} catch (error) {
|
|
36494
|
+
this.Error(error);
|
|
36495
|
+
throw error;
|
|
36496
|
+
}
|
|
36497
|
+
};
|
|
36498
|
+
GetRESTClient = async () => {
|
|
36499
|
+
if (this.restFhirClient) return this.restFhirClient;
|
|
36500
|
+
const onRetryAttempt = (attempt, error, delayMs) => {
|
|
36501
|
+
const message = `TestCaseFhirBase:onRetryAttempt(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
|
|
36502
|
+
this.Warning(message);
|
|
36503
|
+
this.emit("retry", message);
|
|
36504
|
+
};
|
|
36505
|
+
const fhirOptions = this._options.fhirOptions;
|
|
36506
|
+
const fhirRESTClient = new FhirRESTClient({
|
|
36507
|
+
GetAccessToken: this._options.authHelper.GetAccessToken,
|
|
36508
|
+
user: "USR_user01@stsmda.com.au",
|
|
36509
|
+
endpoint: fhirOptions.stsfhirserverendpoint,
|
|
36510
|
+
stsfhirapiroot: fhirOptions.stsfhirapiroot,
|
|
36511
|
+
stsfhirport: fhirOptions.stsfhirport,
|
|
36512
|
+
logger: this._options.logger,
|
|
36513
|
+
agentManager: this.GetFhirAgentManager(),
|
|
36514
|
+
onRetryAttempt
|
|
36515
|
+
});
|
|
36516
|
+
this.restFhirClient = fhirRESTClient;
|
|
36517
|
+
return fhirRESTClient;
|
|
36518
|
+
};
|
|
36519
|
+
GetClient = async () => {
|
|
36520
|
+
let client;
|
|
36521
|
+
if (this._options.fhirOptions.stsfhirsocketclientmode === "no-socket-client") client = await this.GetRESTClient();
|
|
36522
|
+
else client = await this.GetFhirSocketClient();
|
|
36523
|
+
return client;
|
|
36524
|
+
};
|
|
36525
|
+
};
|
|
36526
|
+
//#endregion
|
|
36373
36527
|
//#region src/libmodule/workerFhirTestCases.ts
|
|
36374
36528
|
var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
36375
36529
|
_options;
|
|
36376
36530
|
_resourceDataGenerator;
|
|
36377
36531
|
fhirClient = void 0;
|
|
36378
36532
|
_id = crypto.randomUUID();
|
|
36379
|
-
|
|
36533
|
+
_clientHelper;
|
|
36534
|
+
_authHelper;
|
|
36535
|
+
restFhirClient = null;
|
|
36536
|
+
logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
|
|
36380
36537
|
constructor(options) {
|
|
36381
36538
|
super();
|
|
36382
36539
|
this._options = options;
|
|
36383
36540
|
this._resourceDataGenerator = new ResourceDataGenerator();
|
|
36541
|
+
this._authHelper = new AuthHelper({
|
|
36542
|
+
authOptions: options.authOptions,
|
|
36543
|
+
logger: options.logger
|
|
36544
|
+
});
|
|
36545
|
+
this._clientHelper = new ClientHelper({
|
|
36546
|
+
authHelper: this._authHelper,
|
|
36547
|
+
logger: options.logger,
|
|
36548
|
+
fhirOptions: options.fhirOptions
|
|
36549
|
+
});
|
|
36384
36550
|
}
|
|
36385
|
-
get
|
|
36386
|
-
return this.
|
|
36551
|
+
get authHelper() {
|
|
36552
|
+
return this._authHelper;
|
|
36387
36553
|
}
|
|
36388
|
-
|
|
36389
|
-
|
|
36554
|
+
Warning = (message) => {
|
|
36555
|
+
this.logger.warn(`${this.logPrefix}${message}`);
|
|
36390
36556
|
};
|
|
36391
|
-
|
|
36392
|
-
this.
|
|
36557
|
+
Error = (message) => {
|
|
36558
|
+
this.logger.error(`${this.logPrefix}${message}`);
|
|
36393
36559
|
};
|
|
36560
|
+
Debug = (message) => {
|
|
36561
|
+
this.logger.debug(`${this.logPrefix}${message}`);
|
|
36562
|
+
};
|
|
36563
|
+
get id() {
|
|
36564
|
+
return this._id;
|
|
36565
|
+
}
|
|
36394
36566
|
get resourceDataGenerator() {
|
|
36395
36567
|
return this._resourceDataGenerator;
|
|
36396
36568
|
}
|
|
@@ -36401,9 +36573,9 @@ var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
|
36401
36573
|
return AsyncRunnerFactory.CreateAsyncRunner(this, testRunnerTelemetryPayload);
|
|
36402
36574
|
};
|
|
36403
36575
|
async ProcessPreTerminateWorkerMessage(messagePayload) {
|
|
36404
|
-
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: [${JSON.stringify(messagePayload, null, 2)}]`));
|
|
36576
|
+
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): [${JSON.stringify(messagePayload, null, 2)}]`));
|
|
36405
36577
|
if (this.fhirClient) {
|
|
36406
|
-
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: ResetSocket()`));
|
|
36578
|
+
this.logger.debug(chalk.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): ResetSocket()`));
|
|
36407
36579
|
this.fhirClient.ResetSocket();
|
|
36408
36580
|
this.fhirClient = void 0;
|
|
36409
36581
|
}
|
|
@@ -36413,24 +36585,66 @@ var WorkerFhirTestCases = class extends AbstractRunnerExecutionWorker {
|
|
|
36413
36585
|
myresponsepreterminate: `I got: [${JSON.stringify(messagePayload.payload.data)}]`
|
|
36414
36586
|
};
|
|
36415
36587
|
}
|
|
36416
|
-
|
|
36417
|
-
|
|
36418
|
-
|
|
36588
|
+
defaultAgentOptions = {
|
|
36589
|
+
keepAlive: true,
|
|
36590
|
+
maxSockets: 10,
|
|
36591
|
+
maxTotalSockets: 20,
|
|
36592
|
+
maxFreeSockets: 10,
|
|
36593
|
+
timeout: 6e4,
|
|
36594
|
+
rejectUnauthorized: false
|
|
36419
36595
|
};
|
|
36420
|
-
|
|
36421
|
-
|
|
36422
|
-
|
|
36423
|
-
|
|
36424
|
-
|
|
36425
|
-
|
|
36596
|
+
stressTestAgentOptions = {
|
|
36597
|
+
keepAlive: true,
|
|
36598
|
+
maxSockets: 200,
|
|
36599
|
+
maxTotalSockets: 500,
|
|
36600
|
+
maxFreeSockets: 50,
|
|
36601
|
+
timeout: 3e4,
|
|
36602
|
+
rejectUnauthorized: false
|
|
36603
|
+
};
|
|
36604
|
+
stressTestExtremeAgentOptions = {
|
|
36605
|
+
keepAlive: true,
|
|
36606
|
+
maxSockets: 500,
|
|
36607
|
+
maxTotalSockets: 1e3,
|
|
36608
|
+
maxFreeSockets: 500,
|
|
36609
|
+
timeout: 3e4,
|
|
36610
|
+
rejectUnauthorized: false
|
|
36611
|
+
};
|
|
36612
|
+
GetAgentManager = (testingAgentOptions) => {
|
|
36613
|
+
let agentManager = void 0;
|
|
36614
|
+
let agentOptions = void 0;
|
|
36615
|
+
switch (testingAgentOptions.nodeAgentMode) {
|
|
36616
|
+
case "no-agent": break;
|
|
36617
|
+
case "custom-agent-options":
|
|
36618
|
+
if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
|
|
36619
|
+
else agentOptions = { ...this.defaultAgentOptions };
|
|
36620
|
+
break;
|
|
36621
|
+
case "default-agent-options":
|
|
36622
|
+
agentOptions = { ...this.defaultAgentOptions };
|
|
36623
|
+
break;
|
|
36624
|
+
case "stress-test-agent-options":
|
|
36625
|
+
agentOptions = { ...this.stressTestAgentOptions };
|
|
36626
|
+
break;
|
|
36627
|
+
case "stress-test-extreme-agent-options":
|
|
36628
|
+
agentOptions = { ...this.stressTestExtremeAgentOptions };
|
|
36629
|
+
break;
|
|
36630
|
+
default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
|
|
36426
36631
|
}
|
|
36427
|
-
|
|
36632
|
+
if (agentOptions) agentManager = createAgentManager({
|
|
36633
|
+
agentOptions,
|
|
36634
|
+
httpAgentFactory(options) {
|
|
36635
|
+
return new http.Agent(options);
|
|
36636
|
+
},
|
|
36637
|
+
httpsAgentFactory(options) {
|
|
36638
|
+
return new https.Agent(options);
|
|
36639
|
+
}
|
|
36640
|
+
});
|
|
36641
|
+
return agentManager;
|
|
36428
36642
|
};
|
|
36429
|
-
|
|
36430
|
-
this.
|
|
36643
|
+
GetFhirAgentManager = () => {
|
|
36644
|
+
return this.GetAgentManager(this._options.fhirOptions.stsfhiragentOptions);
|
|
36431
36645
|
};
|
|
36432
|
-
|
|
36433
|
-
|
|
36646
|
+
GetClient = async () => {
|
|
36647
|
+
return this._clientHelper.GetClient();
|
|
36434
36648
|
};
|
|
36435
36649
|
};
|
|
36436
36650
|
//#endregion
|