@nsshunt/ststestrunner 1.1.103 → 1.1.105

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