@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.
@@ -6,6 +6,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
9
10
  var __exportAll = (all, no_symbols) => {
10
11
  let target = {};
11
12
  for (var name in all) __defProp(target, name, {
@@ -31,16 +32,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
32
  }) : target, mod));
32
33
  //#endregion
33
34
  let _nsshunt_stsrunnerframework = require("@nsshunt/stsrunnerframework");
35
+ let _nsshunt_stsutils = require("@nsshunt/stsutils");
34
36
  let chalk = require("chalk");
35
37
  chalk = __toESM(chalk, 1);
36
- let _nsshunt_stsutils = require("@nsshunt/stsutils");
37
- let _nsshunt_stsfhirclient = require("@nsshunt/stsfhirclient");
38
+ let axios = require("axios");
39
+ axios = __toESM(axios, 1);
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
+ let _nsshunt_stsfhirclient = require("@nsshunt/stsfhirclient");
44
45
  //#region node_modules/http-status-codes/build/es/status-codes.js
45
46
  var StatusCodes;
46
47
  (function(StatusCodes) {
@@ -403,190 +404,40 @@ var StatusCodes;
403
404
  //#region src/libmodule/testCaseFhirBase.ts
404
405
  var TestCaseFhirBase = class {
405
406
  #options;
406
- #randomDataRecordset = [];
407
407
  #runner;
408
408
  #runnerExecutionWorker;
409
- #accesssToken = null;
410
409
  #publishTelemetryCount = 0;
411
410
  #maxBufferSize = 50;
412
411
  #publishTelemetryTimeout = null;
413
412
  #publishTelemetryTimeoutVal = 1e3;
414
- #originRegex = /^(api:\/\/\w+)/;
415
- #resetSocketClientTrigger = 50;
416
- #clientSocketFetchCount = 0;
417
- #authAgentManager;
413
+ _RetryMap = [
414
+ 100,
415
+ 250,
416
+ 500,
417
+ 1e3,
418
+ 2e3,
419
+ 3e3
420
+ ];
418
421
  _id = crypto.randomUUID();
419
422
  retryCount = 0;
420
423
  maxAuthRetryCount = 5;
421
424
  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
425
  constructor(runnerExecutionWorker, runner) {
451
426
  this.#options = runner.options;
452
427
  this.#runnerExecutionWorker = runnerExecutionWorker;
453
428
  this.#runner = runner;
454
- this.#authAgentManager = this.GetAuthAgentManager();
455
429
  }
456
430
  get runnerExecutionWorker() {
457
431
  return this.#runnerExecutionWorker;
458
432
  }
459
433
  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
434
  Error = (message) => {
581
435
  this.#runnerExecutionWorker.logger.error(message);
582
436
  this.#runner.instrumentData.message.push(chalk.default.red(`${message}`));
583
437
  };
584
- Warning = (message) => {
585
- this.#runnerExecutionWorker.logger.warn(message);
438
+ Debug = (message) => {
439
+ this.#runnerExecutionWorker.logger.debug(message);
586
440
  };
587
- get accesssToken() {
588
- return this.#accesssToken;
589
- }
590
441
  get runner() {
591
442
  return this.#runner;
592
443
  }
@@ -629,125 +480,6 @@ var TestCaseFhirBase = class {
629
480
  this.#runner.instrumentData.rx = 0;
630
481
  await this.SleepImmediate();
631
482
  };
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
483
  HandleError = (error) => {
752
484
  this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] Error: [${error}]`));
753
485
  this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] description: [${this.runner.options.description}]`));
@@ -762,48 +494,18 @@ var TestCaseFhirBase = class {
762
494
  if (axiosError.response.status === StatusCodes.UNAUTHORIZED) {
763
495
  this.runner.instrumentData.authenticationErrorCount++;
764
496
  this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
765
- this.ResetAccessToken();
497
+ this.runnerExecutionWorker.authHelper.ResetAccessToken();
766
498
  return true;
767
499
  }
768
500
  } else this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] AXIOS Error = [${axiosError}]`));
769
501
  } else if (error.message === "UNAUTHORIZED") {
770
502
  this.runner.instrumentData.authenticationErrorCount++;
771
503
  this.Error(chalk.default.red(`TestCaseFhirBase:HandleError(): [${this._id}] UNAUTHORIZED - Reset Access Token`));
772
- this.ResetAccessToken();
504
+ this.runnerExecutionWorker.authHelper.ResetAccessToken();
773
505
  return true;
774
506
  }
775
507
  return false;
776
508
  };
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
509
  GetPersonRecord = async (prefix, index, version) => {
808
510
  const { workerIndex, runnerIndex, runId } = this.#options;
809
511
  const useId = `${prefix}-${index}`;
@@ -830,37 +532,12 @@ var TestCaseFhirBase = class {
830
532
  }
831
533
  };
832
534
  };
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
535
  #ForcePublishTelemetryData = async () => {
858
536
  await this.#PublishTelemetryData();
859
537
  };
860
538
  #SetupTimeout = async () => {
861
539
  if (!this.#publishTelemetryTimeout) {
862
540
  this.#publishTelemetryTimeout = setTimeout(async () => {
863
- this.#LogMessage(chalk.default.yellow(` **** TIMEOUT **** `));
864
541
  await this.#PublishTelemetryData();
865
542
  this.#publishTelemetryCount = 0;
866
543
  this.#publishTelemetryTimeout = null;
@@ -870,7 +547,6 @@ var TestCaseFhirBase = class {
870
547
  };
871
548
  PublishTelemetry = async () => {
872
549
  this.#publishTelemetryCount++;
873
- this.#LogMessage(chalk.default.red(this.#publishTelemetryCount));
874
550
  if (this.#publishTelemetryCount % this.#maxBufferSize === 0) {
875
551
  this.#publishTelemetryCount = 0;
876
552
  if (this.#publishTelemetryTimeout) {
@@ -883,7 +559,6 @@ var TestCaseFhirBase = class {
883
559
  };
884
560
  #OutputLogMessage = async (message) => {
885
561
  const messageOutput = chalk.default.grey(message);
886
- this.#LogMessage(messageOutput);
887
562
  this.#runner.instrumentData.message.push(messageOutput);
888
563
  await this.PublishTelemetry();
889
564
  };
@@ -931,12 +606,6 @@ var TestCaseFhirBase = class {
931
606
  await this.#ForcePublishTelemetryData();
932
607
  return true;
933
608
  };
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
609
  _GetDetail = () => {
941
610
  return `testType: [${this.runner.options.testType}], description: [${this.runner.options.description}], workerManagerId: [${this.runner.workerManagerId}], Iteration: [${this.runner.iteration}]`;
942
611
  };
@@ -953,14 +622,6 @@ var TestCaseFhirBase = class {
953
622
  this.retryCount = 0;
954
623
  return this._ExecuteQuery();
955
624
  };
956
- _RetryMap = [
957
- 100,
958
- 250,
959
- 500,
960
- 1e3,
961
- 2e3,
962
- 3e3
963
- ];
964
625
  _ExecuteQuery = async () => {
965
626
  try {
966
627
  return await this.PerformExecuteQuery();
@@ -983,6 +644,9 @@ var TestCaseFhirBase = class {
983
644
  else throw error;
984
645
  }
985
646
  };
647
+ GetClient = async () => {
648
+ return this.runnerExecutionWorker.GetClient();
649
+ };
986
650
  };
987
651
  //#endregion
988
652
  //#region src/libmodule/testCaseFhirQueryBase.ts
@@ -1064,9 +728,9 @@ var TestCaseFhirQueryBase = class extends TestCaseFhirBase {
1064
728
  var TestCaseFhir01 = class extends TestCaseFhirQueryBase {
1065
729
  PerformExecuteQuery = async () => {
1066
730
  const __snapshot1 = performance.now();
1067
- await this.GetAccessToken();
731
+ await this.runnerExecutionWorker.authHelper.GetAccessToken();
1068
732
  this._CheckOutputLongDurationError(__snapshot1, "await this.GetAccessToken()");
1069
- this.ResetAccessToken();
733
+ this.runnerExecutionWorker.authHelper.ResetAccessToken();
1070
734
  return null;
1071
735
  };
1072
736
  };
@@ -36394,27 +36058,535 @@ var ResourceDataGenerator = class {
36394
36058
  };
36395
36059
  };
36396
36060
  //#endregion
36061
+ //#region src/libmodule/lockHelper.ts
36062
+ var import_tiny_emitter = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
36063
+ function E() {}
36064
+ E.prototype = {
36065
+ on: function(name, callback, ctx) {
36066
+ var e = this.e || (this.e = {});
36067
+ (e[name] || (e[name] = [])).push({
36068
+ fn: callback,
36069
+ ctx
36070
+ });
36071
+ return this;
36072
+ },
36073
+ once: function(name, callback, ctx) {
36074
+ var self = this;
36075
+ function listener() {
36076
+ self.off(name, listener);
36077
+ callback.apply(ctx, arguments);
36078
+ }
36079
+ listener._ = callback;
36080
+ return this.on(name, listener, ctx);
36081
+ },
36082
+ emit: function(name) {
36083
+ var data = [].slice.call(arguments, 1);
36084
+ var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
36085
+ var i = 0;
36086
+ var len = evtArr.length;
36087
+ for (; i < len; i++) evtArr[i].fn.apply(evtArr[i].ctx, data);
36088
+ return this;
36089
+ },
36090
+ off: function(name, callback) {
36091
+ var e = this.e || (this.e = {});
36092
+ var evts = e[name];
36093
+ var liveEvents = [];
36094
+ if (evts && callback) {
36095
+ for (var i = 0, len = evts.length; i < len; i++) if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]);
36096
+ }
36097
+ liveEvents.length ? e[name] = liveEvents : delete e[name];
36098
+ return this;
36099
+ }
36100
+ };
36101
+ module.exports = E;
36102
+ module.exports.TinyEmitter = E;
36103
+ })))();
36104
+ var LockHelper = class {
36105
+ _onHoldKeys = {};
36106
+ GetOnHold = (holdKey) => {
36107
+ if (this._onHoldKeys[holdKey]) return true;
36108
+ return false;
36109
+ };
36110
+ WaitOnHold = async (holdKey, timeout) => {
36111
+ const start = performance.now();
36112
+ for (;;) {
36113
+ if (this._onHoldKeys[holdKey]) await (0, _nsshunt_stsutils.Sleep)(100);
36114
+ else break;
36115
+ if (performance.now() - start > timeout) throw new Error(`WorkerFhirTestCases:WaitOnHold(): Timeout: [${timeout}] reached.`);
36116
+ }
36117
+ return true;
36118
+ };
36119
+ SetOnHold = (holdKey) => {
36120
+ this._onHoldKeys[holdKey] = true;
36121
+ };
36122
+ ReleaseOnHold = (holdKey) => {
36123
+ delete this._onHoldKeys[holdKey];
36124
+ };
36125
+ };
36126
+ //#endregion
36127
+ //#region src/libmodule/authHelper.ts
36128
+ var AuthHelper = class extends import_tiny_emitter.TinyEmitter {
36129
+ _options;
36130
+ _id = crypto.randomUUID();
36131
+ _lockHelper = new LockHelper();
36132
+ #accesssToken = null;
36133
+ _authMaxTimeout = 5e3;
36134
+ #originRegex = /^(api:\/\/\w+)/;
36135
+ #authAgentManager;
36136
+ logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
36137
+ constructor(options) {
36138
+ super();
36139
+ this._options = options;
36140
+ this.#authAgentManager = this.GetAuthAgentManager();
36141
+ }
36142
+ Warning = (message) => {
36143
+ this._options.logger.warn(`${this.logPrefix}${message}`);
36144
+ };
36145
+ Error = (message) => {
36146
+ this._options.logger.error(`${this.logPrefix}${message}`);
36147
+ };
36148
+ Debug = (message) => {
36149
+ this._options.logger.debug(`${this.logPrefix}${message}`);
36150
+ };
36151
+ get id() {
36152
+ return this._id;
36153
+ }
36154
+ defaultAgentOptions = {
36155
+ keepAlive: true,
36156
+ maxSockets: 10,
36157
+ maxTotalSockets: 20,
36158
+ maxFreeSockets: 10,
36159
+ timeout: 6e4,
36160
+ rejectUnauthorized: false
36161
+ };
36162
+ stressTestAgentOptions = {
36163
+ keepAlive: true,
36164
+ maxSockets: 200,
36165
+ maxTotalSockets: 500,
36166
+ maxFreeSockets: 50,
36167
+ timeout: 3e4,
36168
+ rejectUnauthorized: false
36169
+ };
36170
+ stressTestExtremeAgentOptions = {
36171
+ keepAlive: true,
36172
+ maxSockets: 500,
36173
+ maxTotalSockets: 1e3,
36174
+ maxFreeSockets: 500,
36175
+ timeout: 3e4,
36176
+ rejectUnauthorized: false
36177
+ };
36178
+ GetAgentManager = (testingAgentOptions) => {
36179
+ let agentManager = void 0;
36180
+ let agentOptions = void 0;
36181
+ switch (testingAgentOptions.nodeAgentMode) {
36182
+ case "no-agent": break;
36183
+ case "custom-agent-options":
36184
+ if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
36185
+ else agentOptions = { ...this.defaultAgentOptions };
36186
+ break;
36187
+ case "default-agent-options":
36188
+ agentOptions = { ...this.defaultAgentOptions };
36189
+ break;
36190
+ case "stress-test-agent-options":
36191
+ agentOptions = { ...this.stressTestAgentOptions };
36192
+ break;
36193
+ case "stress-test-extreme-agent-options":
36194
+ agentOptions = { ...this.stressTestExtremeAgentOptions };
36195
+ break;
36196
+ default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
36197
+ }
36198
+ if (agentOptions) agentManager = (0, _nsshunt_stsutils.createAgentManager)({
36199
+ agentOptions,
36200
+ httpAgentFactory(options) {
36201
+ return new node_http.default.Agent(options);
36202
+ },
36203
+ httpsAgentFactory(options) {
36204
+ return new node_https.default.Agent(options);
36205
+ }
36206
+ });
36207
+ return agentManager;
36208
+ };
36209
+ GetAuthAgentManager = () => {
36210
+ return this.GetAgentManager(this._options.authOptions.asagentoptions);
36211
+ };
36212
+ ExtractOrigin = (uri) => {
36213
+ const match = uri.match(this.#originRegex);
36214
+ return match ? match[1] : null;
36215
+ };
36216
+ GetAPITokenFromAuthServerUsingScope = async (options) => {
36217
+ const { scope, clientId, authClientSecret, endPoint } = options;
36218
+ let stage = "1";
36219
+ try {
36220
+ stage = "2";
36221
+ const scopes = scope.split(" ");
36222
+ let origin = null;
36223
+ let error = null;
36224
+ stage = "3";
36225
+ for (let i = 0; i < scopes.length; i++) {
36226
+ const s = scopes[i];
36227
+ if (!origin) {
36228
+ origin = this.ExtractOrigin(s);
36229
+ if (!origin) {
36230
+ error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
36231
+ break;
36232
+ }
36233
+ } else {
36234
+ const nextOrigin = this.ExtractOrigin(s);
36235
+ if (!nextOrigin) {
36236
+ error = /* @__PURE__ */ new Error(`Scope: [${scope}] not in required format. Must use (space seperated) api://<client id>[/<resource>.<permission>].`);
36237
+ break;
36238
+ } else if (origin.localeCompare(nextOrigin) !== 0) {
36239
+ error = /* @__PURE__ */ new Error(`Scope: [${scope}] not all from the same client API. All scopes must come from the same client API.`);
36240
+ break;
36241
+ }
36242
+ }
36243
+ }
36244
+ stage = "4";
36245
+ if (error) throw error;
36246
+ stage = "5";
36247
+ const payload = {
36248
+ client_id: clientId,
36249
+ client_secret: authClientSecret,
36250
+ scope,
36251
+ grant_type: "client_credentials"
36252
+ };
36253
+ stage = "6";
36254
+ const url = endPoint ? `${endPoint}${this._options.authOptions.asoauthapiroot}/token` : `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}${this._options.authOptions.asoauthapiroot}/token`;
36255
+ stage = `6.5: url: [${url}] payload: [${JSON.stringify(payload)}]`;
36256
+ const axiosConfig = new _nsshunt_stsutils.STSAxiosConfig(url, "post").withDefaultHeaders().withData(payload);
36257
+ if (this.#authAgentManager) axiosConfig.withAgentManager(this.#authAgentManager);
36258
+ const retVal = await (0, _nsshunt_stsfhirclient.createRetryAxiosClient)({
36259
+ maxRetries: 4,
36260
+ retryDelayMs: 300,
36261
+ retryJitterMs: 150,
36262
+ maxRetryDurationMs: 5e3,
36263
+ onRetryAttempt: (attempt, error, delayMs) => {
36264
+ this.emit("authenticationErrorCount", 1);
36265
+ this.emit("authenticationRetryCount", 1);
36266
+ const message = `GetAPITokenFromAuthServerUsingScope(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
36267
+ this.Warning(message);
36268
+ this.emit("logMessage", chalk.default.red(message));
36269
+ }
36270
+ })(url, axiosConfig.config);
36271
+ this.emit("authenticationCount", 1);
36272
+ stage = "7";
36273
+ if (retVal.status) {
36274
+ if (retVal.status !== 200) this.Warning(chalk.default.magenta(`GetAPITokenFromAuthServerUsingScope(): [${this._id}] Invalid response from server: [${retVal.status}]`));
36275
+ } else throw new Error(chalk.default.red(`No retVal.status)`));
36276
+ stage = "8";
36277
+ if (retVal.data) {
36278
+ stage = "9";
36279
+ if (retVal.data.access_token) {
36280
+ stage = "12";
36281
+ return retVal.data.access_token;
36282
+ } else {
36283
+ stage = "13";
36284
+ throw new Error(`No retVal.data.access_token)`);
36285
+ }
36286
+ } else {
36287
+ stage = "14";
36288
+ throw new Error(`No retVal.data)`);
36289
+ }
36290
+ } catch (error) {
36291
+ this.Error(error);
36292
+ let details = "None available.";
36293
+ if (error.response && error.response.data) try {
36294
+ details = JSON.stringify(error.response.data);
36295
+ } catch (error) {
36296
+ details = `Could not JSON.stringify(error.response.data)`;
36297
+ }
36298
+ error.message = `${this.logPrefix}GetAPITokenFromAuthServerUsingScope(): Error: [${error}], Stage: [${stage}], Details: [${details}]`;
36299
+ throw error;
36300
+ }
36301
+ };
36302
+ GetAccessToken = async () => {
36303
+ let timeout = void 0;
36304
+ const start = performance.now();
36305
+ try {
36306
+ if (this.#accesssToken) return this.#accesssToken;
36307
+ const lockKey = "GetAccessToken";
36308
+ const lockTimeout = 6e4;
36309
+ if (this._lockHelper.GetOnHold(lockKey) === true) {
36310
+ 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 ...`));
36311
+ try {
36312
+ const miniStart = performance.now();
36313
+ await this._lockHelper.WaitOnHold(lockKey, lockTimeout);
36314
+ this.Debug(chalk.default.yellow(`GetAccessToken(): hold (lock) released after: [${performance.now() - miniStart}ms], lock key: [${lockKey}]`));
36315
+ if (this.#accesssToken) {
36316
+ this.Debug(chalk.default.green(`GetAccessToken(): Getting existing accesssToken (post hold release), lock key: [${lockKey}]`));
36317
+ return this.#accesssToken;
36318
+ } else {
36319
+ this.Error(chalk.default.red(`GetAccessToken(): Could not get existing accesssToken (post hold release), lock key: [${lockKey}]`));
36320
+ this.Error(chalk.default.red(`GetAccessToken(): continue anyway ...`));
36321
+ }
36322
+ } catch (error) {
36323
+ this.Error(chalk.default.red(`GetAccessToken(): Error: [${error}]`));
36324
+ }
36325
+ }
36326
+ this.Debug(chalk.default.yellow(`GetAccessToken(): accesssToken does not exist - setting up new accesssToken`));
36327
+ this.Debug(chalk.default.yellow(`GetAccessToken(): setting hold (lock), lock key: [${lockKey}]`));
36328
+ this._lockHelper.SetOnHold(lockKey);
36329
+ timeout = setTimeout(() => {
36330
+ this.Warning(chalk.default.magenta(`GetAccessToken(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`));
36331
+ }, this._authMaxTimeout);
36332
+ const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:All`.split(" ").sort().join(" ");
36333
+ const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
36334
+ const workingAaccesssToken = await this.GetAPITokenFromAuthServerUsingScope({
36335
+ clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
36336
+ authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
36337
+ scope: scopes,
36338
+ endPoint: authendpointUrl
36339
+ });
36340
+ if (timeout) clearTimeout(timeout);
36341
+ const totalTime = performance.now() - start;
36342
+ if (totalTime > this._authMaxTimeout) this.Warning(chalk.default.magenta(`GetAccessToken(): The total time for getting the access token: [${totalTime}]`));
36343
+ this.#accesssToken = workingAaccesssToken;
36344
+ this._lockHelper.ReleaseOnHold(lockKey);
36345
+ this.Debug(chalk.default.yellow(`GetAccessToken(): release hold (lock) Time taken for get access token: [${performance.now() - start}ms]`));
36346
+ return this.#accesssToken;
36347
+ } catch (error) {
36348
+ if (timeout) clearTimeout(timeout);
36349
+ error.message = `GetAccessToken(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
36350
+ this.Error(error);
36351
+ return "";
36352
+ }
36353
+ };
36354
+ GetAccessTokenForSocketClientAccess = async () => {
36355
+ const timeout = setTimeout(() => {
36356
+ this.Warning(`GetAccessTokenForSocketClientAccess(): Timeout: [${this._authMaxTimeout}] exceeded for getting access token ...`);
36357
+ }, this._authMaxTimeout);
36358
+ const start = performance.now();
36359
+ try {
36360
+ const scopes = `api://fb6513e4-16fe-4931-bed8-33b82b404a14/_.stsfhir5:SocketConnection`.split(" ").sort().join(" ");
36361
+ const authendpointUrl = `${this._options.authOptions.asendpoint}:${this._options.authOptions.asport}`;
36362
+ const retVal = await this.GetAPITokenFromAuthServerUsingScope({
36363
+ clientId: "d8277fce-bb48-44c2-bbf1-257fe13a444b",
36364
+ authClientSecret: "64e3ef37-c7b8-4cb1-880a-e6ad3ab36e3c",
36365
+ scope: scopes,
36366
+ endPoint: authendpointUrl
36367
+ });
36368
+ clearTimeout(timeout);
36369
+ const totalTime = performance.now() - start;
36370
+ if (totalTime > this._authMaxTimeout) this.Warning(chalk.default.magenta(`GetAccessTokenForSocketClientAccess(): The total time for getting the access token: [${totalTime}]`));
36371
+ return retVal;
36372
+ } catch (error) {
36373
+ clearTimeout(timeout);
36374
+ error.message = `GetAccessTokenForSocketClientAccess(): Error: [${error}], Duration until error: [${performance.now() - start}]`;
36375
+ this.Error(error);
36376
+ return "";
36377
+ }
36378
+ };
36379
+ ResetAccessToken = () => {
36380
+ this.#accesssToken = null;
36381
+ };
36382
+ };
36383
+ //#endregion
36384
+ //#region src/libmodule/clientHelper.ts
36385
+ var ClientHelper = class extends import_tiny_emitter.TinyEmitter {
36386
+ _options;
36387
+ fhirClient = void 0;
36388
+ _id = crypto.randomUUID();
36389
+ _lockHelper = new LockHelper();
36390
+ restFhirClient = null;
36391
+ logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
36392
+ constructor(options) {
36393
+ super();
36394
+ this._options = options;
36395
+ }
36396
+ Warning = (message) => {
36397
+ this._options.logger.warn(`${this.logPrefix}${message}`);
36398
+ };
36399
+ Error = (message) => {
36400
+ this._options.logger.error(`${this.logPrefix}${message}`);
36401
+ };
36402
+ Debug = (message) => {
36403
+ this._options.logger.debug(`${this.logPrefix}${message}`);
36404
+ };
36405
+ get id() {
36406
+ return this._id;
36407
+ }
36408
+ defaultAgentOptions = {
36409
+ keepAlive: true,
36410
+ maxSockets: 10,
36411
+ maxTotalSockets: 20,
36412
+ maxFreeSockets: 10,
36413
+ timeout: 6e4,
36414
+ rejectUnauthorized: false
36415
+ };
36416
+ stressTestAgentOptions = {
36417
+ keepAlive: true,
36418
+ maxSockets: 200,
36419
+ maxTotalSockets: 500,
36420
+ maxFreeSockets: 50,
36421
+ timeout: 3e4,
36422
+ rejectUnauthorized: false
36423
+ };
36424
+ stressTestExtremeAgentOptions = {
36425
+ keepAlive: true,
36426
+ maxSockets: 500,
36427
+ maxTotalSockets: 1e3,
36428
+ maxFreeSockets: 500,
36429
+ timeout: 3e4,
36430
+ rejectUnauthorized: false
36431
+ };
36432
+ GetAgentManager = (testingAgentOptions) => {
36433
+ let agentManager = void 0;
36434
+ let agentOptions = void 0;
36435
+ switch (testingAgentOptions.nodeAgentMode) {
36436
+ case "no-agent": break;
36437
+ case "custom-agent-options":
36438
+ if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
36439
+ else agentOptions = { ...this.defaultAgentOptions };
36440
+ break;
36441
+ case "default-agent-options":
36442
+ agentOptions = { ...this.defaultAgentOptions };
36443
+ break;
36444
+ case "stress-test-agent-options":
36445
+ agentOptions = { ...this.stressTestAgentOptions };
36446
+ break;
36447
+ case "stress-test-extreme-agent-options":
36448
+ agentOptions = { ...this.stressTestExtremeAgentOptions };
36449
+ break;
36450
+ default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
36451
+ }
36452
+ if (agentOptions) agentManager = (0, _nsshunt_stsutils.createAgentManager)({
36453
+ agentOptions,
36454
+ httpAgentFactory(options) {
36455
+ return new node_http.default.Agent(options);
36456
+ },
36457
+ httpsAgentFactory(options) {
36458
+ return new node_https.default.Agent(options);
36459
+ }
36460
+ });
36461
+ return agentManager;
36462
+ };
36463
+ GetFhirAgentManager = () => {
36464
+ return this.GetAgentManager(this._options.fhirOptions.stsfhiragentOptions);
36465
+ };
36466
+ GetFhirSocketClient = async () => {
36467
+ try {
36468
+ if (this.fhirClient) return this.fhirClient;
36469
+ const lockKey = "GetFhirSocketClient";
36470
+ const lockTimeout = 6e4;
36471
+ if (this._lockHelper.GetOnHold(lockKey) === true) {
36472
+ 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 ...`));
36473
+ try {
36474
+ const start = performance.now();
36475
+ await this._lockHelper.WaitOnHold(lockKey, lockTimeout);
36476
+ this.Debug(chalk.default.yellow(`GetFhirSocketClient(): hold (lock) released after: [${performance.now() - start}ms], lock key: [${lockKey}]`));
36477
+ if (this.fhirClient) {
36478
+ this.Debug(chalk.default.green(`GetFhirSocketClient(): Getting existing fhir client (post hold release), lock key: [${lockKey}]`));
36479
+ return this.fhirClient;
36480
+ } else {
36481
+ this.Error(chalk.default.red(`GetFhirSocketClient(): Could not get existing fhir client (post hold release), lock key: [${lockKey}]`));
36482
+ this.Error(chalk.default.red(`GetFhirSocketClient(): continue anyway ...`));
36483
+ }
36484
+ } catch (error) {
36485
+ this.Error(chalk.default.red(`GetFhirSocketClient(): Error: [${error}]`));
36486
+ }
36487
+ }
36488
+ const start = performance.now();
36489
+ this.Debug(chalk.default.yellow(`GetFhirSocketClient(): fhir client does not exist - setting up new client`));
36490
+ this.Debug(chalk.default.yellow(`GetFhirSocketClient(): setting hold (lock), lock key: [${lockKey}]`));
36491
+ this._lockHelper.SetOnHold(lockKey);
36492
+ const fhirOptions = this._options.fhirOptions;
36493
+ const options = {
36494
+ fhirServerEndpoint: fhirOptions.stsfhirserverendpoint,
36495
+ fhirapiroot: fhirOptions.stsfhirapiroot,
36496
+ fhirServerPort: fhirOptions.stsfhirport,
36497
+ socketClientName: fhirOptions.stsfhirsocketname,
36498
+ socketIoCustomPath: fhirOptions.stsfhirsocketcustompath,
36499
+ timeout: fhirOptions.stsfhirsockettimeout,
36500
+ baseUrl: fhirOptions.stsfhirbaseurl,
36501
+ agentManager: this.GetFhirAgentManager(),
36502
+ joinRooms: [],
36503
+ logger: this._options.logger,
36504
+ verboseLogging: true,
36505
+ GetConnectionAccessToken: this._options.authHelper.GetAccessTokenForSocketClientAccess,
36506
+ GetAccessToken: this._options.authHelper.GetAccessToken
36507
+ };
36508
+ let workingFhirClient;
36509
+ if (this._options.fhirOptions.stsfhirsocketclientmode === "socket-client-all-in-one") workingFhirClient = new _nsshunt_stsfhirclient.FhirSocketClientAllInOne("FhirSocketClient", options);
36510
+ else workingFhirClient = new _nsshunt_stsfhirclient.FhirSocketClientIndividual("FhirSocketClient", options);
36511
+ await workingFhirClient.WaitForSocketConnected();
36512
+ this.Debug(chalk.default.yellow(`GetFhirSocketClient(): setting fhir client into object`));
36513
+ this.fhirClient = workingFhirClient;
36514
+ this._lockHelper.ReleaseOnHold(lockKey);
36515
+ this.Debug(chalk.default.yellow(`GetFhirSocketClient(): release hold (lock) Time taken for socket connection and set object: [${performance.now() - start}ms], lock key: [${lockKey}]`));
36516
+ return this.fhirClient;
36517
+ } catch (error) {
36518
+ this.Error(error);
36519
+ throw error;
36520
+ }
36521
+ };
36522
+ GetRESTClient = async () => {
36523
+ if (this.restFhirClient) return this.restFhirClient;
36524
+ const onRetryAttempt = (attempt, error, delayMs) => {
36525
+ const message = `TestCaseFhirBase:onRetryAttempt(): [${this._id}] Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`;
36526
+ this.Warning(message);
36527
+ this.emit("retry", message);
36528
+ };
36529
+ const fhirOptions = this._options.fhirOptions;
36530
+ const fhirRESTClient = new _nsshunt_stsfhirclient.FhirRESTClient({
36531
+ GetAccessToken: this._options.authHelper.GetAccessToken,
36532
+ user: "USR_user01@stsmda.com.au",
36533
+ endpoint: fhirOptions.stsfhirserverendpoint,
36534
+ stsfhirapiroot: fhirOptions.stsfhirapiroot,
36535
+ stsfhirport: fhirOptions.stsfhirport,
36536
+ logger: this._options.logger,
36537
+ agentManager: this.GetFhirAgentManager(),
36538
+ onRetryAttempt
36539
+ });
36540
+ this.restFhirClient = fhirRESTClient;
36541
+ return fhirRESTClient;
36542
+ };
36543
+ GetClient = async () => {
36544
+ let client;
36545
+ if (this._options.fhirOptions.stsfhirsocketclientmode === "no-socket-client") client = await this.GetRESTClient();
36546
+ else client = await this.GetFhirSocketClient();
36547
+ return client;
36548
+ };
36549
+ };
36550
+ //#endregion
36397
36551
  //#region src/libmodule/workerFhirTestCases.ts
36398
36552
  var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunnerExecutionWorker {
36399
36553
  _options;
36400
36554
  _resourceDataGenerator;
36401
36555
  fhirClient = void 0;
36402
36556
  _id = crypto.randomUUID();
36403
- _onHoldKeys = {};
36557
+ _clientHelper;
36558
+ _authHelper;
36559
+ restFhirClient = null;
36560
+ logPrefix = `WorkerFhirTestCases:[${this._id}]:`;
36404
36561
  constructor(options) {
36405
36562
  super();
36406
36563
  this._options = options;
36407
36564
  this._resourceDataGenerator = new ResourceDataGenerator();
36565
+ this._authHelper = new AuthHelper({
36566
+ authOptions: options.authOptions,
36567
+ logger: options.logger
36568
+ });
36569
+ this._clientHelper = new ClientHelper({
36570
+ authHelper: this._authHelper,
36571
+ logger: options.logger,
36572
+ fhirOptions: options.fhirOptions
36573
+ });
36408
36574
  }
36409
- get id() {
36410
- return this._id;
36575
+ get authHelper() {
36576
+ return this._authHelper;
36411
36577
  }
36412
- GetFhirClient = () => {
36413
- return this.fhirClient;
36578
+ Warning = (message) => {
36579
+ this.logger.warn(`${this.logPrefix}${message}`);
36414
36580
  };
36415
- SetFhirClient = (fhirClient) => {
36416
- this.fhirClient = fhirClient;
36581
+ Error = (message) => {
36582
+ this.logger.error(`${this.logPrefix}${message}`);
36417
36583
  };
36584
+ Debug = (message) => {
36585
+ this.logger.debug(`${this.logPrefix}${message}`);
36586
+ };
36587
+ get id() {
36588
+ return this._id;
36589
+ }
36418
36590
  get resourceDataGenerator() {
36419
36591
  return this._resourceDataGenerator;
36420
36592
  }
@@ -36425,9 +36597,9 @@ var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunn
36425
36597
  return AsyncRunnerFactory.CreateAsyncRunner(this, testRunnerTelemetryPayload);
36426
36598
  };
36427
36599
  async ProcessPreTerminateWorkerMessage(messagePayload) {
36428
- this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: [${JSON.stringify(messagePayload, null, 2)}]`));
36600
+ this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): [${JSON.stringify(messagePayload, null, 2)}]`));
36429
36601
  if (this.fhirClient) {
36430
- this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage: ResetSocket()`));
36602
+ this.logger.debug(chalk.default.rgb(220, 100, 0)(`ProcessPreTerminateWorkerMessage(): ResetSocket()`));
36431
36603
  this.fhirClient.ResetSocket();
36432
36604
  this.fhirClient = void 0;
36433
36605
  }
@@ -36437,24 +36609,66 @@ var WorkerFhirTestCases = class extends _nsshunt_stsrunnerframework.AbstractRunn
36437
36609
  myresponsepreterminate: `I got: [${JSON.stringify(messagePayload.payload.data)}]`
36438
36610
  };
36439
36611
  }
36440
- GetOnHold = (holdKey) => {
36441
- if (this._onHoldKeys[holdKey]) return true;
36442
- return false;
36612
+ defaultAgentOptions = {
36613
+ keepAlive: true,
36614
+ maxSockets: 10,
36615
+ maxTotalSockets: 20,
36616
+ maxFreeSockets: 10,
36617
+ timeout: 6e4,
36618
+ rejectUnauthorized: false
36443
36619
  };
36444
- WaitOnHold = async (holdKey, timeout) => {
36445
- const start = performance.now();
36446
- for (;;) {
36447
- if (this._onHoldKeys[holdKey]) await (0, _nsshunt_stsutils.Sleep)(100);
36448
- else break;
36449
- if (performance.now() - start > timeout) throw new Error(`WaitOnHold timeout: [${timeout}] reached.`);
36620
+ stressTestAgentOptions = {
36621
+ keepAlive: true,
36622
+ maxSockets: 200,
36623
+ maxTotalSockets: 500,
36624
+ maxFreeSockets: 50,
36625
+ timeout: 3e4,
36626
+ rejectUnauthorized: false
36627
+ };
36628
+ stressTestExtremeAgentOptions = {
36629
+ keepAlive: true,
36630
+ maxSockets: 500,
36631
+ maxTotalSockets: 1e3,
36632
+ maxFreeSockets: 500,
36633
+ timeout: 3e4,
36634
+ rejectUnauthorized: false
36635
+ };
36636
+ GetAgentManager = (testingAgentOptions) => {
36637
+ let agentManager = void 0;
36638
+ let agentOptions = void 0;
36639
+ switch (testingAgentOptions.nodeAgentMode) {
36640
+ case "no-agent": break;
36641
+ case "custom-agent-options":
36642
+ if (testingAgentOptions.nodeAgentCustomOptions) agentOptions = { ...testingAgentOptions.nodeAgentCustomOptions };
36643
+ else agentOptions = { ...this.defaultAgentOptions };
36644
+ break;
36645
+ case "default-agent-options":
36646
+ agentOptions = { ...this.defaultAgentOptions };
36647
+ break;
36648
+ case "stress-test-agent-options":
36649
+ agentOptions = { ...this.stressTestAgentOptions };
36650
+ break;
36651
+ case "stress-test-extreme-agent-options":
36652
+ agentOptions = { ...this.stressTestExtremeAgentOptions };
36653
+ break;
36654
+ default: throw new Error(`TestCaseFhirBase:GetAgentManager(): [${this._id}] unknown nodeAgentMode: [${testingAgentOptions.nodeAgentMode}]`);
36450
36655
  }
36451
- return true;
36656
+ if (agentOptions) agentManager = (0, _nsshunt_stsutils.createAgentManager)({
36657
+ agentOptions,
36658
+ httpAgentFactory(options) {
36659
+ return new node_http.default.Agent(options);
36660
+ },
36661
+ httpsAgentFactory(options) {
36662
+ return new node_https.default.Agent(options);
36663
+ }
36664
+ });
36665
+ return agentManager;
36452
36666
  };
36453
- SetOnHold = (holdKey) => {
36454
- this._onHoldKeys[holdKey] = true;
36667
+ GetFhirAgentManager = () => {
36668
+ return this.GetAgentManager(this._options.fhirOptions.stsfhiragentOptions);
36455
36669
  };
36456
- ReleaseOnHold = (holdKey) => {
36457
- delete this._onHoldKeys[holdKey];
36670
+ GetClient = async () => {
36671
+ return this._clientHelper.GetClient();
36458
36672
  };
36459
36673
  };
36460
36674
  //#endregion