From f5c292daa7e601d1f63301bd02d080e07e88b86f Mon Sep 17 00:00:00 2001 From: Lucas Huet-Hudson Date: Fri, 19 May 2023 10:39:05 -0400 Subject: [PATCH 1/2] move existing codebase Co-authored-by: Stuart Leeks Co-authored-by: Amin Espinoza Co-authored-by: Shawn Gaul Co-authored-by: Hannes Nel --- CHANGELOG.md | 20 +- CONTRIBUTING.md | 56 +- README.md | 60 +- .../.devcontainer/Dockerfile | 18 + .../.devcontainer/devcontainer.json | 46 + .../.devcontainer/kubelogin.sh | 9 + .../.env.sample | 8 + .../.gitattributes | 6 + .../aks-sb-azmonitor-microservices/.gitignore | 7 + .../aks-sb-azmonitor-microservices/README.md | 34 + .../api-spec/.devcontainer/Dockerfile | 14 + .../api-spec/.devcontainer/base.Dockerfile | 17 + .../api-spec/.devcontainer/devcontainer.json | 32 + .../api-spec/.gitignore | 2 + .../api-spec/cadl-project.yaml | 2 + .../api-spec/main.cadl | 26 + .../api-spec/models.cadl | 65 + .../api-spec/package-lock.json | 1756 +++++++ .../api-spec/package.json | 17 + .../assets/custom-metric-alert.png | Bin 0 -> 64237 bytes .../assets/custom-metric-dimensions.png | Bin 0 -> 21772 bytes .../assets/dimensions-rg-list.png | Bin 0 -> 52856 bytes .../assets/dimensions-workbook-initial.png | Bin 0 -> 131550 bytes .../assets/dimensions-workbook-slow1.png | Bin 0 -> 138607 bytes .../assets/dimensions-workbook-slow2.png | Bin 0 -> 254207 bytes .../assets/full-trace-invalid.png | Bin 0 -> 123190 bytes .../assets/full-trace-valid.png | Bin 0 -> 95134 bytes .../assets/health-check-logs.png | Bin 0 -> 8388 bytes .../assets/log-auto.png | Bin 0 -> 16583 bytes .../assets/log-manual.png | Bin 0 -> 15881 bytes .../assets/metric-auto-rus.png | Bin 0 -> 14517 bytes .../assets/metric-auto.png | Bin 0 -> 11792 bytes .../assets/metric-manual.png | Bin 0 -> 11970 bytes ...ervice-accelerator-arch-diagram.drawio.png | Bin 0 -> 128297 bytes .../assets/span-auto.png | Bin 0 -> 12956 bytes .../assets/span-manual.png | Bin 0 -> 11698 bytes .../assets/verify-invalid-cargo.png | Bin 0 -> 68401 bytes .../assets/verify-valid-cargo.png | Bin 0 -> 66231 bytes .../assets/workbook-aks-metric.png | Bin 0 -> 30233 bytes .../assets/workbook-key-vault-metric.png | Bin 0 -> 111505 bytes .../deploy-bicep.sh | 109 + .../deploy-terraform.sh | 109 + .../docs/alerts.md | 57 + ...auto-vs-manually-instrumented-telemetry.md | 26 + .../docs/custom-dimensions.md | 148 + .../docs/custom-metrics.md | 37 + .../docs/distributed-tracing.md | 42 + .../docs/getting-started.md | 108 + .../docs/health-checks.md | 66 + .../docs/introducing-chaos.md | 25 + .../docs/reducing-telemetry-volume.md | 11 + .../docs/workbooks.md | 74 + .../http/.env.sample | 6 + .../http/cargo-processing-api.http | 122 + .../infrastructure/bicep/abbreviations.json | 135 + .../bicep/azuredeploy.parameters.sample.json | 48 + .../infrastructure/bicep/main.bicep | 219 + .../infrastructure/bicep/modules/acr.bicep | 45 + .../infrastructure/bicep/modules/aks.bicep | 100 + .../infrastructure/bicep/modules/alerts.bicep | 953 ++++ .../bicep/modules/app-insights.bicep | 33 + .../infrastructure/bicep/modules/cosmos.bicep | 161 + .../bicep/modules/key-vault.bicep | 125 + .../bicep/modules/service-bus.bicep | 130 + .../bicep/modules/workbooks.bicep | 81 + .../scripts/build-and-push-images.sh | 78 + .../scripts/create-env-files-from-output.sh | 246 + .../scripts/deploy-bicep-infrastructure.sh | 169 + .../scripts/deploy-helm-charts.sh | 205 + .../deploy-terraform-infrastructure.sh | 152 + .../infrastructure/terraform/.gitignore | 5 + .../infrastructure/terraform/main.tf | 171 + .../terraform/modules/acr/main.tf | 7 + .../terraform/modules/acr/outputs.tf | 8 + .../terraform/modules/acr/variables.tf | 14 + .../terraform/modules/aks/main.tf | 63 + .../terraform/modules/aks/outputs.tf | 17 + .../terraform/modules/aks/variables.tf | 65 + .../terraform/modules/alerts/main.tf | 975 ++++ .../terraform/modules/alerts/variables.tf | 49 + .../terraform/modules/app_insights/main.tf | 28 + .../terraform/modules/app_insights/outputs.tf | 16 + .../modules/app_insights/variables.tf | 31 + .../terraform/modules/cosmos/main.tf | 151 + .../terraform/modules/cosmos/outputs.tf | 17 + .../terraform/modules/cosmos/variables.tf | 41 + .../terraform/modules/keyvault/main.tf | 97 + .../terraform/modules/keyvault/outputs.tf | 7 + .../terraform/modules/keyvault/variables.tf | 41 + .../terraform/modules/service_bus/main.tf | 103 + .../terraform/modules/service_bus/outputs.tf | 12 + .../modules/service_bus/variables.tf | 72 + .../terraform/modules/workbooks/main.tf | 42 + .../terraform/modules/workbooks/variables.tf | 34 + .../infrastructure/terraform/outputs.tf | 36 + .../infrastructure/terraform/provider.tf | 28 + .../infrastructure/terraform/sample.tfvars | 15 + .../infrastructure/terraform/variables.tf | 85 + .../infrastructure/workbooks/index.json | 218 + .../workbooks/infrastructure.json | 477 ++ .../workbooks/system-processing.json | 492 ++ .../run-local.sh | 20 + .../.devcontainer/Dockerfile | 25 + .../.devcontainer/devcontainer.json | 39 + .../src/cargo-processing-api/.dockerignore | 2 + .../src/cargo-processing-api/.env.sample | 9 + .../src/cargo-processing-api/.gitignore | 3 + .../cargo-processing-api/.vscode/launch.json | 24 + .../.vscode/settings.json | 3 + .../cargo-processing-api/.vscode/tasks.json | 19 + .../src/cargo-processing-api/Dockerfile | 27 + .../src/cargo-processing-api/README.md | 72 + .../applicationinsights.json | 17 + .../cargo-processing-api/docker-compose.yml | 11 + .../src/cargo-processing-api/helm/.helmignore | 23 + .../src/cargo-processing-api/helm/Chart.yaml | 24 + .../helm/cargo-processing-api.yaml | 36 + .../helm/templates/NOTES.txt | 5 + .../helm/templates/_helpers.tpl | 51 + .../helm/templates/deployment.yaml | 97 + .../helm/templates/hpa.yaml | 28 + .../helm/templates/secretProviderClass.yaml | 41 + .../helm/templates/service.yaml | 15 + .../helm/templates/tests/test-connection.yaml | 15 + .../src/cargo-processing-api/mvnw | 316 ++ .../src/cargo-processing-api/mvnw.cmd | 188 + .../src/cargo-processing-api/pom.xml | 172 + .../cse/cargoprocessing/api/Application.java | 13 + .../Exceptions/JsonValidationException.java | 33 + .../api/chaos/ChaosMonkey.java | 15 + .../api/chaos/impl/BaseMonkey.java | 41 + .../api/chaos/impl/ChaosMonkeyException.java | 7 + .../chaos/impl/DependantApiFailureMonkey.java | 17 + .../api/chaos/impl/ProcessKillingMonkey.java | 18 + .../chaos/impl/ServiceBusKillingMonkey.java | 22 + .../chaos/impl/ServiceBusThrollingMonkey.java | 50 + .../api/controllers/CargoController.java | 143 + .../controllers/ExceptionHandling/Error.java | 14 + .../ExceptionHandling/ErrorCodes.java | 11 + .../ExceptionHandling/ErrorDetail.java | 20 + .../ExceptionHandling/ExceptionAdvisor.java | 52 + .../ExceptionHandling/InnerError.java | 13 + .../ExceptionHandling/ValidationError.java | 19 + .../cse/cargoprocessing/api/models/Cargo.java | 18 + .../api/models/DemandDates.java | 16 + .../api/models/MessageEnvelope.java | 11 + .../cse/cargoprocessing/api/models/Port.java | 11 + .../cargoprocessing/api/models/Product.java | 11 + .../api/services/CargoPublisher.java | 7 + .../api/services/OperationPublisher.java | 7 + .../api/services/SchemaValidator.java | 7 + .../api/services/impl/CargoPublisher.java | 58 + .../api/services/impl/OperationPublisher.java | 37 + .../api/services/impl/SchemaValidator.java | 48 + .../src/main/resources/application.properties | 16 + .../static/json-schemas/cargo-sample.json | 14 + .../static/json-schemas/cargo-schema.json | 123 + .../api/ApplicationTestsIT.java | 13 + .../api/controllers/CargoControllerIT.java | 56 + .../api/controllers/CargoControllerTest.java | 81 + .../api/services/SchemaValidatorTest.java | 44 + .../src/test/resources/application.properties | 7 + .../cargo-test-objects/basic-cargo.json | 14 + .../invalid-cargo-object.json | 14 + .../cargo-test-objects/invalid-syntax.json | 13 + .../.devcontainer/Dockerfile | 5 + .../.devcontainer/devcontainer.json | 12 + .../cargo-processing-validator/.dockerignore | 2 + .../.dockerignore copy | 2 + .../cargo-processing-validator/.env.sample | 6 + .../src/cargo-processing-validator/.gitignore | 3 + .../.vscode/launch.json | 18 + .../src/cargo-processing-validator/Dockerfile | 12 + .../src/cargo-processing-validator/README.md | 48 + .../docker-compose.yml | 9 + .../helm/.helmignore | 23 + .../helm/Chart.yaml | 24 + .../helm/cargo-processing-validator.yaml | 34 + .../helm/templates/NOTES.txt | 5 + .../helm/templates/_helpers.tpl | 62 + .../helm/templates/deployment.yaml | 83 + .../helm/templates/hpa.yaml | 28 + .../helm/templates/secretProviderClass.yaml | 31 + .../helm/templates/service.yaml | 15 + .../helm/templates/tests/test-connection.yaml | 15 + .../package-lock.json | 4565 +++++++++++++++++ .../cargo-processing-validator/package.json | 32 + .../src/chaos/ChaosMonkey.ts | 29 + .../src/chaos/ProcessEndingMonkey.ts | 12 + .../src/chaos/ServiceBusKillingMonkey.ts | 14 + .../cargo-processing-validator/src/index.ts | 98 + .../src/models/Cargo.ts | 16 + .../src/models/MessageEnvelope.ts | 6 + .../src/models/ValidatedCargo.ts | 6 + .../src/schemas/cargo-envelope-schema.json | 186 + .../src/services/CargoSchemaValidation.ts | 25 + .../src/services/CargoValidationService.ts | 149 + .../services/ServiceBusProcessingService.ts | 192 + .../src/services/ServiceBusWithTelemetry.ts | 300 ++ .../src/services/TelemetryService.ts | 32 + .../src/tests/CargoValidationServiceTests.ts | 124 + .../cargo-processing-validator/tsconfig.json | 66 + .../.devcontainer/Dockerfile | 11 + .../.devcontainer/devcontainer.json | 34 + .../src/cargo-test-scripts/.env.sample | 5 + .../src/cargo-test-scripts/.gitignore | 3 + .../cargo-test-scripts/.vscode/launch.json | 30 + .../src/cargo-test-scripts/README.md | 224 + .../src/cargo-test-scripts/cargoValidation.js | 75 + .../src/cargo-test-scripts/config.js | 11 + .../cargo-test-scripts/dataBuilderUtils.js | 170 + .../generators/cargoProcessingApi.js | 87 + .../generators/cargoProcessingValidator.js | 85 + .../generators/validatedCargoManagers.js | 73 + .../src/cargo-test-scripts/index.js | 68 + .../cargo-test-scripts/outputTestResults.js | 65 + .../src/cargo-test-scripts/package-lock.json | 2943 +++++++++++ .../src/cargo-test-scripts/package.json | 22 + .../src/cargo-test-scripts/seed.json | 177 + .../test/dataBuilderUtils.test.js | 60 + .../cargo_processing_api_chaos_tests.json | 24 + .../testConfigurations/scale.json | 30 + .../valid-cargo-normal.json | 15 + .../valid-cargo-slow-port.json | 23 + .../testConfigurations/valid_tests.json | 28 + .../src/docker-compose.yml | 36 + .../.devcontainer/Dockerfile | 22 + .../.devcontainer/devcontainer.json | 59 + .../src/invalid-cargo-manager/.dockerignore | 2 + .../src/invalid-cargo-manager/.env.sample | 18 + .../src/invalid-cargo-manager/.gitignore | 3 + .../invalid-cargo-manager/.vscode/launch.json | 25 + .../src/invalid-cargo-manager/Dockerfile | 13 + .../src/invalid-cargo-manager/README.md | 45 + .../invalid-cargo-manager/docker-compose.yml | 9 + .../invalid-cargo-manager/helm/.helmignore | 23 + .../src/invalid-cargo-manager/helm/Chart.yaml | 24 + .../helm/invalid-cargo-manager.yaml | 35 + .../helm/templates/NOTES.txt | 5 + .../helm/templates/_helpers.tpl | 62 + .../helm/templates/deployment.yaml | 115 + .../helm/templates/hpa.yaml | 28 + .../helm/templates/secretProviderClass.yaml | 41 + .../helm/templates/service.yaml | 15 + .../helm/templates/tests/test-connection.yaml | 15 + .../invalid-cargo-manager/requirements.txt | 6 + .../invalid-cargo-manager/src/service/app.py | 12 + .../src/service/app_config.py | 25 + .../src/service/app_context.py | 36 + .../src/service/cargo_repo.py | 31 + .../src/service/logging_config.py | 31 + .../src/service/message_receiver.py | 129 + .../src/service/models.py | 59 + .../src/service/state_processor.py | 29 + .../src/service/telemetry_publisher.py | 71 + .../operations-api/.devcontainer/Dockerfile | 25 + .../.devcontainer/devcontainer.json | 39 + .../src/operations-api/.dockerignore | 2 + .../src/operations-api/.env.sample | 13 + .../src/operations-api/.gitignore | 3 + .../.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 58727 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 + .../src/operations-api/.vscode/launch.json | 24 + .../src/operations-api/.vscode/settings.json | 3 + .../src/operations-api/.vscode/tasks.json | 19 + .../src/operations-api/Dockerfile | 27 + .../src/operations-api/README.md | 24 + .../operations-api/applicationinsights.json | 17 + .../src/operations-api/docker-compose.yml | 11 + .../src/operations-api/helm/.helmignore | 23 + .../src/operations-api/helm/Chart.yaml | 25 + .../operations-api/helm/operations-api.yaml | 34 + .../operations-api/helm/templates/NOTES.txt | 5 + .../helm/templates/_helpers.tpl | 62 + .../helm/templates/deployment.yaml | 111 + .../operations-api/helm/templates/hpa.yaml | 28 + .../helm/templates/secretProviderClass.yaml | 41 + .../helm/templates/service.yaml | 15 + .../helm/templates/tests/test-connection.yaml | 15 + .../src/operations-api/mvnw | 316 ++ .../src/operations-api/mvnw.cmd | 188 + .../src/operations-api/pom.xml | 170 + .../operations/api/Application.java | 29 + .../api/ExceptionHandling/Error.java | 14 + .../api/ExceptionHandling/ErrorCodes.java | 11 + .../api/ExceptionHandling/ErrorDetail.java | 20 + .../ExceptionHandling/ExceptionAdvisor.java | 32 + .../api/ExceptionHandling/InnerError.java | 13 + .../configuration/CosmosConfiguration.java | 42 + .../api/configuration/CosmosProperties.java | 19 + .../configuration/ServiceBusProperties.java | 19 + .../api/controllers/OperationController.java | 10 + .../impl/HttpOperationController.java | 58 + .../operations/api/models/Cargo.java | 20 + .../operations/api/models/DemandDates.java | 16 + .../operations/api/models/Operation.java | 33 + .../operations/api/models/OperationState.java | 13 + .../operations/api/models/Port.java | 11 + .../operations/api/models/Product.java | 11 + .../api/repositories/OperationRepo.java | 10 + .../api/services/StateProcessor.java | 154 + .../src/main/resources/application.properties | 19 + .../operations/api/ApplicationTestsIT.java | 13 + .../src/solution/README.md | 5 + .../src/solution/helm/Chart.yaml | 24 + .../src/solution/helm/templates/NOTES.txt | 5 + .../src/solution/helm/templates/_helpers.tpl | 62 + .../src/solution/helm/templates/ingress.yaml | 35 + .../.devcontainer/Dockerfile | 8 + .../.devcontainer/devcontainer.json | 21 + .../src/valid-cargo-manager/.dockerignore | 28 + .../src/valid-cargo-manager/.gitignore | 38 + .../Controllers/HealthCheckController.cs | 81 + .../src/valid-cargo-manager/Dockerfile | 20 + .../HealthCheck/CosmosDbHealthChecker.cs | 152 + .../HealthCheck/HealthCheckResultBuilder.cs | 115 + .../HealthCheck/Models/HealthCheck.cs | 26 + .../HealthCheck/Models/IetfHealthCheck.cs | 62 + .../HealthCheck/ServiceBusHealthChecker.cs | 133 + .../Interfaces/ISubscriptionReceiver.cs | 12 + .../Models/OperationState.cs | 15 + .../valid-cargo-manager/Models/ValidCargo.cs | 54 + .../src/valid-cargo-manager/Program.cs | 89 + .../Properties/launchSettings.json | 14 + .../src/valid-cargo-manager/README.md | 56 + .../Services/SubscriptionReceiver.cs | 159 + .../Telemetry/TelemetryInitializer.cs | 16 + .../src/valid-cargo-manager/Worker.cs | 30 + .../appsettings.sample.json | 37 + .../valid-cargo-manager/docker-compose.yml | 7 + .../src/valid-cargo-manager/helm/.helmignore | 23 + .../src/valid-cargo-manager/helm/Chart.yaml | 24 + .../helm/templates/NOTES.txt | 5 + .../helm/templates/_helpers.tpl | 62 + .../helm/templates/deployment.yaml | 118 + .../helm/templates/hpa.yaml | 28 + .../helm/templates/secretProviderClass.yaml | 41 + .../helm/templates/service.yaml | 15 + .../helm/templates/tests/test-connection.yaml | 15 + .../helm/valid-cargo-manager.yaml | 35 + .../valid-cargo-manager.csproj | 25 + .../valid-cargo-manager.sln | 27 + 342 files changed, 26851 insertions(+), 84 deletions(-) create mode 100644 accelerators/aks-sb-azmonitor-microservices/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/.devcontainer/kubelogin.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/.gitattributes create mode 100644 accelerators/aks-sb-azmonitor-microservices/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/base.Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/cadl-project.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/main.cadl create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/models.cadl create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/package-lock.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/api-spec/package.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/custom-metric-alert.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/custom-metric-dimensions.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/dimensions-rg-list.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-initial.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-slow1.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-slow2.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/full-trace-invalid.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/full-trace-valid.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/health-check-logs.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/log-auto.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/log-manual.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/metric-auto-rus.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/metric-auto.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/metric-manual.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/sb-microservice-accelerator-arch-diagram.drawio.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/span-auto.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/span-manual.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/verify-invalid-cargo.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/verify-valid-cargo.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/workbook-aks-metric.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/assets/workbook-key-vault-metric.png create mode 100644 accelerators/aks-sb-azmonitor-microservices/deploy-bicep.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/deploy-terraform.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/alerts.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/auto-vs-manually-instrumented-telemetry.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/custom-dimensions.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/custom-metrics.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/distributed-tracing.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/getting-started.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/health-checks.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/introducing-chaos.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/reducing-telemetry-volume.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/docs/workbooks.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/http/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/http/cargo-processing-api.http create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/abbreviations.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/azuredeploy.parameters.sample.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/main.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/acr.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/aks.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/alerts.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/app-insights.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/cosmos.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/key-vault.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/service-bus.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/workbooks.bicep create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/build-and-push-images.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/create-env-files-from-output.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-bicep-infrastructure.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-helm-charts.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-terraform-infrastructure.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/main.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/outputs.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/provider.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/sample.tfvars create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/variables.tf create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/index.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/infrastructure.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/system-processing.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/run-local.sh create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.dockerignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/launch.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/settings.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/tasks.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/applicationinsights.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/docker-compose.yml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/.helmignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/Chart.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/cargo-processing-api.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/NOTES.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/_helpers.tpl create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/deployment.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/hpa.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/secretProviderClass.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/service.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/tests/test-connection.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw.cmd create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/pom.xml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Application.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Exceptions/JsonValidationException.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/ChaosMonkey.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/BaseMonkey.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ChaosMonkeyException.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/DependantApiFailureMonkey.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ProcessKillingMonkey.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusKillingMonkey.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusThrollingMonkey.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoController.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/Error.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorCodes.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorDetail.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ExceptionAdvisor.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/InnerError.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ValidationError.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Cargo.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/DemandDates.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/MessageEnvelope.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Port.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Product.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/CargoPublisher.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/OperationPublisher.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidator.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/CargoPublisher.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/OperationPublisher.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/SchemaValidator.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/application.properties create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-sample.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-schema.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/ApplicationTestsIT.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerIT.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerTest.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidatorTest.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/application.properties create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/basic-cargo.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-cargo-object.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-syntax.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore copy create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.vscode/launch.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/docker-compose.yml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/.helmignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/Chart.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/cargo-processing-validator.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/NOTES.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/_helpers.tpl create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/deployment.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/hpa.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/secretProviderClass.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/service.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/tests/test-connection.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ChaosMonkey.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ProcessEndingMonkey.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ServiceBusKillingMonkey.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/index.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/Cargo.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/MessageEnvelope.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/ValidatedCargo.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/schemas/cargo-envelope-schema.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoSchemaValidation.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoValidationService.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusProcessingService.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusWithTelemetry.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/TelemetryService.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/tests/CargoValidationServiceTests.ts create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/tsconfig.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.vscode/launch.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/cargoValidation.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/config.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/dataBuilderUtils.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingApi.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingValidator.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/validatedCargoManagers.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/index.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/outputTestResults.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package-lock.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/seed.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/test/dataBuilderUtils.test.js create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/cargo_processing_api_chaos_tests.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/scale.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-normal.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-slow-port.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid_tests.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/docker-compose.yml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.dockerignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.vscode/launch.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/docker-compose.yml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/.helmignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/Chart.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/invalid-cargo-manager.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/NOTES.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/_helpers.tpl create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/deployment.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/hpa.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/secretProviderClass.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/service.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/tests/test-connection.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/requirements.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_config.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_context.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/cargo_repo.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/logging_config.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/message_receiver.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/models.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/state_processor.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/telemetry_publisher.py create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.dockerignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.env.sample create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.jar create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.properties create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/launch.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/settings.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/tasks.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/applicationinsights.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/docker-compose.yml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/.helmignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/Chart.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/operations-api.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/NOTES.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/_helpers.tpl create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/deployment.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/hpa.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/secretProviderClass.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/service.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/tests/test-connection.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw.cmd create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/pom.xml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/Application.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/Error.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorCodes.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorDetail.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ExceptionAdvisor.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/InnerError.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosConfiguration.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosProperties.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/ServiceBusProperties.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/OperationController.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/impl/HttpOperationController.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Cargo.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/DemandDates.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Operation.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/OperationState.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Port.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Product.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/repositories/OperationRepo.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/services/StateProcessor.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/resources/application.properties create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/test/java/com/microsoft/cse/cargoprocessing/operations/api/ApplicationTestsIT.java create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/solution/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/solution/helm/Chart.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/NOTES.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/_helpers.tpl create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/ingress.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/devcontainer.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.dockerignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.gitignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Controllers/HealthCheckController.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Dockerfile create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/CosmosDbHealthChecker.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/HealthCheckResultBuilder.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/HealthCheck.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/IetfHealthCheck.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/ServiceBusHealthChecker.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Interfaces/ISubscriptionReceiver.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/OperationState.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/ValidCargo.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Program.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Properties/launchSettings.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/README.md create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Services/SubscriptionReceiver.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Telemetry/TelemetryInitializer.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Worker.cs create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/appsettings.sample.json create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/docker-compose.yml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/.helmignore create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/Chart.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/NOTES.txt create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/_helpers.tpl create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/deployment.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/hpa.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/secretProviderClass.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/service.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/tests/test-connection.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/valid-cargo-manager.yaml create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.csproj create mode 100644 accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.sln diff --git a/CHANGELOG.md b/CHANGELOG.md index 9824752..0beacfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,15 @@ -## [project-title] Changelog +# Observability Accelerators Changelog - -# x.y.z (yyyy-mm-dd) +## 1.0 (2023-05-19) -*Features* -* ... +### Features -*Bug Fixes* -* ... +- Initial public release -*Breaking Changes* -* ... +### Bug Fixes + +- Not applicable + +### Breaking Changes + +- Not applicable diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9115cf..1fe1f0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to [project-title] +# Contributing to Observability Accelerators -This project welcomes contributions and suggestions. Most contributions require you to agree to a +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. @@ -12,61 +12,67 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - - [Code of Conduct](#coc) - - [Issues and Bugs](#issue) - - [Feature Requests](#feature) - - [Submission Guidelines](#submit) +- [Code of Conduct](#coc) +- [Issues and Bugs](#issue) +- [Feature Requests](#feature) +- [Submission Guidelines](#submit) ## Code of Conduct + Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/). ## Found an Issue? + If you find a bug in the source code or a mistake in the documentation, you can help us by [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can [submit a Pull Request](#submit-pr) with a fix. ## Want a Feature? -You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub -Repository. If you would like to *implement* a new feature, please submit an issue with + +You can _request_ a new feature by [submitting an issue](#submit-issue) to the GitHub +Repository. If you would like to _implement_ a new feature, please submit an issue with a proposal for your work first, to be sure that we can use it. -* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). +- **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). ## Submission Guidelines ### Submitting an Issue + Before you submit an issue, search the archive, maybe your question was already answered. If your issue appears to be a bug, and hasn't been reported, open a new issue. Help us to maximize the effort we can spend fixing issues and adding new -features, by not reporting duplicate issues. Providing the following information will increase the +features, by not reporting duplicate issues. Providing the following information will increase the chances of your issue being dealt with quickly: -* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps -* **Version** - what version is affected (e.g. 0.1.2) -* **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you -* **Browsers and Operating System** - is this a problem with all browsers? -* **Reproduce the Error** - provide a live example or a unambiguous set of steps -* **Related Issues** - has a similar issue been reported before? -* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be +- **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps +- **Version** - what version is affected (e.g. 0.1.2) +- **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you +- **Browsers and Operating System** - is this a problem with all browsers? +- **Reproduce the Error** - provide a live example or a unambiguous set of steps +- **Related Issues** - has a similar issue been reported before? +- **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit) You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new]. ### Submitting a Pull Request (PR) + Before you submit your Pull Request (PR) consider the following guidelines: -* Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR +- Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate effort. -* Make your changes in a new git fork: +- Make your changes in a new git fork: + +- Commit your changes using a descriptive commit message +- Push your fork to GitHub: +- In GitHub, create a pull request +- If we suggest changes then: -* Commit your changes using a descriptive commit message -* Push your fork to GitHub: -* In GitHub, create a pull request -* If we suggest changes then: - * Make the required updates. - * Rebase your fork and force push to your GitHub repository (this will update your Pull Request): + - Make the required updates. + - Rebase your fork and force push to your GitHub repository (this will update your Pull Request): ```shell git rebase master -i diff --git a/README.md b/README.md index 364f052..c3d8fa3 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,17 @@ -# Project Name +# Observability Accelerators -(short, 1-3 sentenced, description of the project) +This repository contains multiple samples that are meant to accelerate development in the Observability and Monitoring space on Azure. -## Features +Each accelerator focuses on a different application architecture. They contain all source code and infrastructure as code necessary to deploy the application, as well as in-depth documentation that details important O&M concepts. -This project framework provides the following features: +Navigate to one of the accelerators in the list below. The README will include instructions on how to get started with that application. -* Feature 1 -* Feature 2 -* ... +## Accelerator Index -## Getting Started +| Accelerator | +| -------------------------------------------------------------------------------------------------------------------------- | +| [Azure Monitor in a Message-Based Distributed Application on AKS](./accelerators/aks-sb-azmonitor-microservices/README.md) | -### Prerequisites +## Trademarks -(ideally very short, if any) - -- OS -- Library version -- ... - -### Installation - -(ideally very short) - -- npm install [package name] -- mvn install -- ... - -### Quickstart -(Add steps to get up and running quickly) - -1. git clone [repository clone url] -2. cd [repository name] -3. ... - - -## Demo - -A demo app is included to show how to use the project. - -To run the demo, follow these steps: - -(Add steps to start up the demo) - -1. -2. -3. - -## Resources - -(Any additional resources or related projects) - -- Link to supporting information -- Link to similar sample -- ... +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies. diff --git a/accelerators/aks-sb-azmonitor-microservices/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/.devcontainer/Dockerfile new file mode 100644 index 0000000..a6bd0b3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/.devcontainer/Dockerfile @@ -0,0 +1,18 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu/.devcontainer/base.Dockerfile + +# [Choice] Ubuntu version (use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon): ubuntu-22.04, ubuntu-20.04, ubuntu-18.04 +ARG VARIANT="jammy" +FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} + +# [Optional] Uncomment this section to install additional OS packages. +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends figlet + + +ARG USERNAME=vscode +USER $USERNAME + +COPY kubelogin.sh /tmp/kubelogin.sh +RUN mkdir -p "/home/$USERNAME/.local/bin" && \ + /tmp/kubelogin.sh +ENV PATH="/home/vscode/.local/bin:${PATH}" \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/.devcontainer/devcontainer.json new file mode 100644 index 0000000..fb28795 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/.devcontainer/devcontainer.json @@ -0,0 +1,46 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu +{ + "name": "aks-sb-azmonitor-microservices", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Ubuntu version: jammy / ubuntu-22.04, focal / ubuntu-20.04, bionic /ubuntu-18.04 + // Use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon. + "args": { + "VARIANT": "ubuntu-22.04" + } + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "ghcr.io/devcontainers/features/terraform:1": { + "version": "1.3" + }, + "ghcr.io/devcontainers/features/azure-cli:1": {}, + "ghcr.io/stuartleeks/dev-container-features/azure-cli-persistence:0": {}, + "ghcr.io/stuartleeks/dev-container-features/shell-history:0": {}, + "ghcr.io/devcontainers/features/docker-from-docker:1": {}, + "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": { + "helm": "3.10.1" + } + }, + "runArgs": [ + // Attach dev container to host network so allow accessing services on the host + // when running via docker-compose + "--network", "host" + ], + "customizations": { + "vscode": { + "extensions": [ + "timonwong.shellcheck", + "hashicorp.terraform", + "ms-azuretools.vscode-bicep", + "humao.rest-client" + ] + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/.devcontainer/kubelogin.sh b/accelerators/aks-sb-azmonitor-microservices/.devcontainer/kubelogin.sh new file mode 100644 index 0000000..49d7f5c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/.devcontainer/kubelogin.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e + +wget -O /tmp/kubelogin-linux-amd64.zip \ + https://github.com/Azure/kubelogin/releases/download/v0.0.24/kubelogin-linux-amd64.zip + +unzip /tmp/kubelogin-linux-amd64.zip -d /tmp/kubelogin + +cp /tmp/kubelogin/bin/linux_amd64/kubelogin "/home/$USERNAME/.local/bin/kubelogin" diff --git a/accelerators/aks-sb-azmonitor-microservices/.env.sample b/accelerators/aks-sb-azmonitor-microservices/.env.sample new file mode 100644 index 0000000..01e996c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/.env.sample @@ -0,0 +1,8 @@ +# Unique name to assign in all deployed services, your high school hotmail alias is a great idea! +USERNAME= + +# Email address for alert notifications +EMAIL_ADDRESS= + +# Uncomment the following line to change the deployment location +# LOCATION=westeurope \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/.gitattributes b/accelerators/aks-sb-azmonitor-microservices/.gitattributes new file mode 100644 index 0000000..c91154c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/.gitattributes @@ -0,0 +1,6 @@ +# Ensure that all shell scripts are checked out with LF line endings +# on Windows. This is necessary because Git for Windows defaults to +# CRLF line endings, which breaks the shell scripts. +# NOTE: for best results on Windows, clone the code in a in a file system +# under Windows Subsystem for Linux (WSL) - see https://www.docker.com/blog/docker-desktop-wsl-2-best-practices/ +*.sh text eol=lf diff --git a/accelerators/aks-sb-azmonitor-microservices/.gitignore b/accelerators/aks-sb-azmonitor-microservices/.gitignore new file mode 100644 index 0000000..0f84b33 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/.gitignore @@ -0,0 +1,7 @@ +plan.out +terraform.tfvars +azuredeploy.parameters.json +.env + +output.json +env.yaml diff --git a/accelerators/aks-sb-azmonitor-microservices/README.md b/accelerators/aks-sb-azmonitor-microservices/README.md new file mode 100644 index 0000000..61e41c0 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/README.md @@ -0,0 +1,34 @@ +# Azure Monitor in a Message Based Distributed Application + +Using Azure Monitor to observe a distributed application comes with unique challenges and considerations. The ability to generate and view traces, ensure service availability, use custom telemetry to track business critical indicators, etc. are all more complex in a distributed environment. The sample is designed to demonstrate how to automatically and manually instrument data in variety of languages within a distributed application, as well as provide similar examples for visualization and alerts based on this incoming data. + +The sample contains a conceptual cargo processing application to demonstrate these points. The microservice-based solution is deployed to Azure Kubernetes Service and employs multiple communication protocols, including HTTP and message-based interactions, to enable seamless communication between its services. The services cover a wide variety of programming languages and instrumentation libraries - the Java services utilize OpenTelemetry exporters, while the Node, .NET, and Python services use the Application Insights SDKs for instrumentation purposes. + +The sample contains all code and documentation necessary to deploy and monitor the application. Source code for the microservices can be found in the [/src](./src/) folder, while Bicep and Terraform versions (identical output) of the supporting infrastructure can be found in the [/infrastructure/bicep](./infrastructure/bicep/) and [/infrastructure/terraform](./infrastructure/bicep/) folders, respectively. + +## Use Case + +![Architecture Diagram](./assets/sb-microservice-accelerator-arch-diagram.drawio.png) + +A `cargo-processing-api` service (Java) receives a PUT request with an object in the request body containing ports, products, and other cargo related information. The api validates the request schema and places a message containing the cargo object on an Azure Service Bus queue. A `cargo-processing-validator` service (Typescript) validates the internal cargo properties to ensure it can be successfully shipped before placing the cargo object with boolean validation result on a Service Bus topic. Finally, two services (.NET and Python) with subscriptions to the topic receive the final message, filtering for `valid = True` or `valid = False` flags, respectively, before storing the message in a dedicated Cosmos DB container for further processing. + +A fifth, `operations-api` service (Java) implements the [async request-reply](https://learn.microsoft.com/azure/architecture/patterns/async-request-reply) pattern, adding a level of resiliency to the long running operation. + +Each microservice sends telemetry data to Application Insights, while AKS, Key Vault, Cosmos DB, and Service Bus are each configured to export telemetry data directly to the Log Analytics Workspace associated with the Application Insights resource. + +## Docs + +Getting started instructions and documentation on observability and monitoring topics within the application can be found in the following pages: + +| Topic | Content | +| --------------------------------------- | ----------------------------------------------------------------------------------------------- | +| Getting Started | [getting-started.md](./docs/getting-started.md) | +| Auto vs Manually Instrumented Telemetry | [auto-vs-manually-instrumented-telemetry.md](./docs/auto-vs-manually-instrumented-telemetry.md) | +| Distributed Tracing | [distributed-tracing.md](./docs/distributed-tracing.md) | +| Health Checks | [health-checks.md](./docs/health-checks.md) | +| Custom Dimensions | [custom-dimensions.md](./docs/custom-dimensions.md) | +| Custom Metrics | [custom-metrics.md](./docs/custom-metrics.md) | +| Workbooks | [workbooks.md](./docs/workbooks.md) | +| Alerts | [alerts.md](./docs/alerts.md) | +| Introducing Chaos | [introducing-chaos.md](./docs/introducing-chaos.md) | +| Reducing Telemetry Volume | [reducing-telemetry-volume.md](./docs/reducing-telemetry-volume.md) | diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/Dockerfile new file mode 100644 index 0000000..d64dd2c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/Dockerfile @@ -0,0 +1,14 @@ +# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster +ARG VARIANT=16-bullseye +FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT} + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment if you want to install an additional version of node using nvm +# ARG EXTRA_NODE_VERSION=10 +# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" + +RUN su node -c "npm install -g @cadl-lang/compiler" +RUN su node -c "npm install -g cadl-vscode" diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/base.Dockerfile b/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/base.Dockerfile new file mode 100644 index 0000000..35b6654 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/base.Dockerfile @@ -0,0 +1,17 @@ +# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster +ARG VARIANT=16-bullseye +FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} + +# Install tslint, typescript. eslint is installed by javascript image +ARG NODE_MODULES="tslint-to-eslint-config typescript" +COPY library-scripts/meta.env /usr/local/etc/vscode-dev-containers +RUN su node -c "umask 0002 && npm install -g ${NODE_MODULES}" \ + && npm cache clean --force > /dev/null 2>&1 + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment if you want to install an additional version of node using nvm +# ARG EXTRA_NODE_VERSION=10 +# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/devcontainer.json new file mode 100644 index 0000000..bbc0729 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/.devcontainer/devcontainer.json @@ -0,0 +1,32 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/typescript-node +{ + "name": "Node.js, TypeScript & CADL", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick a Node version: 18, 16, 14. + // Append -bullseye or -buster to pin to an OS version. + // Use -bullseye variants on local on arm64/Apple Silicon. + "args": { + "VARIANT": "16-bullseye" + } + }, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "dbaeumer.vscode-eslint", + "/usr/local/share/npm-global/lib/node_modules/cadl-vscode/cadl-vscode-0.16.0.vsix" + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "node" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/.gitignore b/accelerators/aks-sb-azmonitor-microservices/api-spec/.gitignore new file mode 100644 index 0000000..9794b20 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/.gitignore @@ -0,0 +1,2 @@ +node_modules +cadl-output \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/cadl-project.yaml b/accelerators/aks-sb-azmonitor-microservices/api-spec/cadl-project.yaml new file mode 100644 index 0000000..43afbf8 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/cadl-project.yaml @@ -0,0 +1,2 @@ +emitters: + "@cadl-lang/openapi3": true \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/main.cadl b/accelerators/aks-sb-azmonitor-microservices/api-spec/main.cadl new file mode 100644 index 0000000..d8ee9c4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/main.cadl @@ -0,0 +1,26 @@ +import "@cadl-lang/rest"; +import "./models.cadl"; + +@serviceTitle("CargoProcessingService") +namespace CargoProcessingService; + +using Cadl.Http; +using Cadl.Rest; +using ServiceModels; + +@route("/operations") +interface OperationsService { + @put + @createsOrUpdatesResource(Operation) + putOperation(@path id: string): Operation | Error; + @get + getOperation(@path id: string): Operation | Error; +} + +@route("/cargo") +interface CargoService { + @put + updateCargo(@path id: string, @header("operation-id") operationId?: string, @body body: Cargo): CargoHydrated | Error; + @post + createCargo(@body body: Cargo): CargoHydrated | Error; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/models.cadl b/accelerators/aks-sb-azmonitor-microservices/api-spec/models.cadl new file mode 100644 index 0000000..e976cc4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/models.cadl @@ -0,0 +1,65 @@ +import "@cadl-lang/rest"; + +namespace ServiceModels; +using Cadl.Http; +using Cadl.Rest; + +@error +model Error { + code: int32; + message: string; + target: string; +} + +model Product { + name: string; + quantity: int32; +} + +model Port { + source: string; + destination: string; +} + +model DemandDates { + start: plainDate; + end: plainDate; +} + +model Cargo { + product: Product; + port: Port; + demandDates: DemandDates; + @header + operationId: string; +} + +model CargoHydrated { + ...Cargo; + @visibility("read") + @key + id: string; + @visibility("read") + timestamp: zonedDateTime; + @header + waitTime: int32 +} + +model CargoValidated { + ...Cargo; + @visibility("read") + @key + id: string; + @visibility("read") + timestamp: zonedDateTime; + valid: boolean; + error: string; +} + +model Operation { + id: string; + state: string; + result?: CargoValidated; + error?: string; + updatedAt: zonedDateTime; +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/package-lock.json b/accelerators/aks-sb-azmonitor-microservices/api-spec/package-lock.json new file mode 100644 index 0000000..df98e86 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/package-lock.json @@ -0,0 +1,1756 @@ +{ + "name": "api-spec", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "api-spec", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@cadl-lang/compiler": "0.35.0", + "@cadl-lang/openapi3": "0.15.0", + "@cadl-lang/rest": "0.17.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cadl-lang/compiler": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/compiler/-/compiler-0.35.0.tgz", + "integrity": "sha512-0hztF32Qev2K6NAenVx6at8zYGwaWrIVRIFdqyp3/6ZDJ3q8yffH9eERP0ddq2E5TOtKlWF52MgvuIOWY9qyEQ==", + "dependencies": { + "@babel/code-frame": "~7.16.7", + "ajv": "~8.9.0", + "change-case": "~4.1.2", + "globby": "~13.1.1", + "js-yaml": "~4.1.0", + "mkdirp": "~1.0.4", + "mustache": "~4.2.0", + "node-fetch": "3.2.8", + "node-watch": "~0.7.1", + "picocolors": "~1.0.0", + "prettier": "~2.7.1", + "prompts": "~2.4.1", + "vscode-languageserver": "~7.0.0", + "vscode-languageserver-textdocument": "~1.0.1", + "yargs": "~17.3.1" + }, + "bin": { + "cadl": "cmd/cadl.js", + "cadl-server": "cmd/cadl-server.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@cadl-lang/openapi": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/openapi/-/openapi-0.12.0.tgz", + "integrity": "sha512-yoP/gO03oZ09e3n0oW6XgAIcVqBcUmPLQEPvrYqo0/UsZx/ibGZG8oKhhf/C3Kqrp0Vr/qcr6y7SV3NCEHE8bw==", + "peer": true, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@cadl-lang/compiler": "~0.35.0", + "@cadl-lang/rest": "~0.17.0" + } + }, + "node_modules/@cadl-lang/openapi3": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/openapi3/-/openapi3-0.15.0.tgz", + "integrity": "sha512-Ee0muF6/S1eLDDQ9m2/R0N/PeXNNM7J3Q+JHWNE0SepJb/LTlihyN5n/0MAAsaT0mPXoQwSe5Lt8lZ3KaDULqQ==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@cadl-lang/compiler": "~0.35.0", + "@cadl-lang/openapi": "~0.12.0", + "@cadl-lang/rest": "~0.17.0", + "@cadl-lang/versioning": "~0.8.0" + } + }, + "node_modules/@cadl-lang/rest": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/rest/-/rest-0.17.0.tgz", + "integrity": "sha512-Q5UhVXWXW3XAuri/cAYLw3NJleCXzmqu9TDh6mc+YWbRThvfWx2GYKRbp+7WWCWI1e0zAQt4D49WkYwr/4OJRA==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@cadl-lang/compiler": "~0.35.0" + } + }, + "node_modules/@cadl-lang/versioning": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/versioning/-/versioning-0.8.0.tgz", + "integrity": "sha512-TF5iWtJEaQBKmo4RN/yvzdllWwwCWVTbQnEHHAefVRoq4/ThwO5mGKZI8/RG9zeHcJOGHlvGKyu7n1xY4SlqUw==", + "peer": true, + "dependencies": { + "@cadl-lang/compiler": "~0.35.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ajv": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.8.tgz", + "integrity": "sha512-KtpD1YhGszhntMpBDyp5lyagk8KIMopC1LEb7cQUAh7zcosaX5uK8HnbNb2i3NTQK3sIawCItS0uFC3QzcLHdg==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", + "engines": { + "node": ">=8.0.0 || >=10.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", + "dependencies": { + "vscode-languageserver-protocol": "3.16.0" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", + "dependencies": { + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.7.tgz", + "integrity": "sha512-bFJH7UQxlXT8kKeyiyu41r22jCZXG8kuuVVA33OEJn1diWOZK5n8zBSPZFHVBOu8kXZ6h0LIRhf5UnCo61J4Hg==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==" + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@cadl-lang/compiler": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/compiler/-/compiler-0.35.0.tgz", + "integrity": "sha512-0hztF32Qev2K6NAenVx6at8zYGwaWrIVRIFdqyp3/6ZDJ3q8yffH9eERP0ddq2E5TOtKlWF52MgvuIOWY9qyEQ==", + "requires": { + "@babel/code-frame": "~7.16.7", + "ajv": "~8.9.0", + "change-case": "~4.1.2", + "globby": "~13.1.1", + "js-yaml": "~4.1.0", + "mkdirp": "~1.0.4", + "mustache": "~4.2.0", + "node-fetch": "3.2.8", + "node-watch": "~0.7.1", + "picocolors": "~1.0.0", + "prettier": "~2.7.1", + "prompts": "~2.4.1", + "vscode-languageserver": "~7.0.0", + "vscode-languageserver-textdocument": "~1.0.1", + "yargs": "~17.3.1" + } + }, + "@cadl-lang/openapi": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/openapi/-/openapi-0.12.0.tgz", + "integrity": "sha512-yoP/gO03oZ09e3n0oW6XgAIcVqBcUmPLQEPvrYqo0/UsZx/ibGZG8oKhhf/C3Kqrp0Vr/qcr6y7SV3NCEHE8bw==", + "peer": true, + "requires": {} + }, + "@cadl-lang/openapi3": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/openapi3/-/openapi3-0.15.0.tgz", + "integrity": "sha512-Ee0muF6/S1eLDDQ9m2/R0N/PeXNNM7J3Q+JHWNE0SepJb/LTlihyN5n/0MAAsaT0mPXoQwSe5Lt8lZ3KaDULqQ==", + "requires": {} + }, + "@cadl-lang/rest": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/rest/-/rest-0.17.0.tgz", + "integrity": "sha512-Q5UhVXWXW3XAuri/cAYLw3NJleCXzmqu9TDh6mc+YWbRThvfWx2GYKRbp+7WWCWI1e0zAQt4D49WkYwr/4OJRA==", + "requires": {} + }, + "@cadl-lang/versioning": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cadl-lang/versioning/-/versioning-0.8.0.tgz", + "integrity": "sha512-TF5iWtJEaQBKmo4RN/yvzdllWwwCWVTbQnEHHAefVRoq4/ThwO5mGKZI8/RG9zeHcJOGHlvGKyu7n1xY4SlqUw==", + "peer": true, + "requires": { + "@cadl-lang/compiler": "~0.35.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "ajv": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "requires": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.8.tgz", + "integrity": "sha512-KtpD1YhGszhntMpBDyp5lyagk8KIMopC1LEb7cQUAh7zcosaX5uK8HnbNb2i3NTQK3sIawCItS0uFC3QzcLHdg==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, + "node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==" + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "vscode-jsonrpc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==" + }, + "vscode-languageserver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", + "requires": { + "vscode-languageserver-protocol": "3.16.0" + } + }, + "vscode-languageserver-protocol": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", + "requires": { + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" + } + }, + "vscode-languageserver-textdocument": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.7.tgz", + "integrity": "sha512-bFJH7UQxlXT8kKeyiyu41r22jCZXG8kuuVVA33OEJn1diWOZK5n8zBSPZFHVBOu8kXZ6h0LIRhf5UnCo61J4Hg==" + }, + "vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + }, + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/api-spec/package.json b/accelerators/aks-sb-azmonitor-microservices/api-spec/package.json new file mode 100644 index 0000000..4bcd4ff --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/api-spec/package.json @@ -0,0 +1,17 @@ +{ + "name": "api-spec", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@cadl-lang/compiler": "0.35.0", + "@cadl-lang/openapi3": "0.15.0", + "@cadl-lang/rest": "0.17.0" + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/custom-metric-alert.png b/accelerators/aks-sb-azmonitor-microservices/assets/custom-metric-alert.png new file mode 100644 index 0000000000000000000000000000000000000000..f078cb5e16c5663650bc19164cafe8d43a428cec GIT binary patch literal 64237 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ⅅ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 Pzl5>5{qwzlA7%aluvuFQ literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-rg-list.png b/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-rg-list.png new file mode 100644 index 0000000000000000000000000000000000000000..13659482e22c3987fabe55903f078d74fbdd0ad7 GIT binary patch literal 52856 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 J6W8 literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-initial.png b/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-initial.png new file mode 100644 index 0000000000000000000000000000000000000000..62dfdf8d1c16e4f28ce4d272f4bbc4caa8634723 GIT binary patch literal 131550 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 +&46qy%f?`qmU+hzZVa$tEBz< z0w~o@3LznzHWmMM*)OrM8aS{wX!SB!G@$>RvYgB^yto|F{xYyBz&j;vD#jxXX_2HT z_rm{g!}M9n;9>3W&H%p#c?#e%PL7L2mWjQM1_xVH`;HV3KLP&G$s)th2hd%XJ6y0x zEw2P}Z}@bW3y6VUe7rBf6}aejFFR`+=QBIue6b3KA)b=piSs!k^MVtd5QSNe!@Wpn zU4B1=8XIfr>sQe;)`6^kIG>QR1^&T8+1QW#?ef82Hn@RG985{j+DMcSv|W2vDo0N zRo38MNKp8#E=Q#N@FHuQIGq)(S{8ORmxdL|YUe&XoB2}_m*1%G08ur*(!$Z+hr)X` zahm95xB=Di;_^Oq70>m_X$1YZJLmvnI$*DOEUojKeYe3Hx%r^KDP7eBiuVeygX&K$ zXIU`ZaJNfMjJ`ViM=J#+W-(WQ?N>`|6O48cW5hVu;^9Ywqo9Jm3f8vu&U9|v+3@Dm zCN4%^Mg=F{hC&R-&yoy125_ZYA5U+$KU(Ur;5wKi7L7pa`%kqKYG4dSDLGPs|5}9P zvTF4u^n6>GgVbrKG@C|ut3KI4&Z*JiYHbyNQ?lW}j`G7TRhXh)NOqJTBiEVh?CkzY z>|0h$goqQGG|1OIV(}XI>IRW&7;f$-QU7?HCD6LwlBa&Tql0m16=C-CrI2jfGM$`6 z!gtG9-A*#9PP9iglBq8$Cd_PIbtHu{9Pu2a;d1%KF`jN7Mu>UXK}OkHwgMlCZa7sb zEOtF`T?uD|@O@?u@=s>tA1R2dojI(@LL-F%{lSHWDHh|^Li4l1G4E!z*o)%8Y;Jn1 zqqA3{+Gi(yNmSpDn~5VO^MZ#jK-upb|CRB*Q7!Vg?rr?=+RmCVuq-n;(H~XQqi>K zd^Vk!oaZ6RN_&Z^-*GNO{h5eL6Pmg-qXF^cVH`87ebL%I@rEg$9jwT)(Y=8*?q$1^ z=jvL@>jNtWB>~Ut%W0t@xyZ} z)~qfxzbUZ^FB_`7SKxc4tXXh4JL+Ls^XXC_eG%OvqQbX{2o+Dg0PX{{;ZKaOHwj86 z+*tBYxuuKLI+OeCMWANM;9{kfZ4+anA>6szoG@a{4^rMLCwB#fxn2+;U;mU@gT?Dt zMos94T)S~Z4Psmer;=7qsM0*FOu6+5T3VHzw1CR;2BRzus(eV@@I8;)XPjTW!B>7e z9{PJV_-iwr2l|;^Yvf*#{&q_LI_(jKvUVdR*z9vi>&(*wXlj06g@G9U-r(AS0K4j^ zn#HM;RoZ@_;#f{jbTPi#QPE8Y5`)=Ts9w1~SEbeFn&;>dwrXb?@u+d~a|e9~N(UyGPnfsIK%rh^?A-a?-KlmJMf1A-l-;iatr$~v3f%!cwW%Ld0-LK(rpAr|5N=f9bGsLj! z>!(bNG}g5XM`9u>h6vCgX=9t;hXo;(mM5Z87$cU0=;zO zF-k>5VNJmr#GUnnl8gpNjn|wL`7{QC!EeH&qCD|2+WYK-luNdB8>U2J9$p%N)DQ3j zHZ2;~8S%6S>sUl?n5w<{M!3?~RA!u6f4^mzl9Vt9>;73@?%nsC%zJ6qtl?fx`*%50 z{O01cbJB(V>Yef4ypQm+=w<$MFLY+pVhrO+))7@vE^WX+9Ss_-z2S3}iVDTug()4O@ z(t2m5dq(xy@PQC#aVKl2!KZ;K;nIRbgNRuXx0JmCoJlCcLGMPQR+JQIos*Qd@n{iE?pHxnl4Ax$7Uf zWRizex%~p=a<#cWC$8+o^-x@f`@-&qa*Mez`Ll=?D89`gHoA|bawMk{vGiEj-_S>( z$4vj>ENu)6l1@$BTse@E>uqAQBlXX-0GUvp&%qAw|2q@zv>`ihqmGt}#qPl`%GN)fTK`D9w%;vuD08xSk8j|&zFmPT16I;6 z5zpI0zfD|TAcO_so0WIV#aJico=!lr+4)oC%k*7LMhNG2Sq(JG6WB&Oc9e|da270c zU_Yh|2U1Qe$M(}4oKV`b)0mKh&NF^|76Tj=NgMO&TLFM3Kj zL!UPx8$g4hG_HhB+(rqmv%u?TxbvW*uW+wk15X>NQ@5D;cJV7B5;0J^h1s7u?0{ZG z4)QY)O-N|Or45IF{dt2L=n4g;L7*yhRF>NBka<+(cfC1SQ&4T5eq4s4fdaHZ{Er&; z^?;K%JQ4U;FI!J}Jk$oaTlVKDE$?O7UVSq}Vkl9s;nic(P;D8a{?4W?E{f$PkqnK_ zIt0TH|04EEnLhA0YkBJT1NCN+WurAHs{=Y%M?3*r$hV!u^cPa=5MIh#<<&V-_?&OW zvb05b)`3fCtjuMGkWcwMbY8VQo;@9747`GTLSU1CTC87LE+qk#xvskl9^rj-8@*i; zvCTdR=++s-!D4A{?C!_fRC4d-$_Cb{4}Epmt9uJPyjxIS7(~Lt1mfY5&~!bVK-Z8ULoR_FOSH#9L#>ks5RB;bNLf8qb}O94n1$V$UDYga_es{3V& zQ{EL`cv%*G3%*og$5CKbk2(qhX1f=&cw9sp4^tqdN483y$A7|jg{6xOYm0@83M;mB z-~2Vczr|mTTJ?(|t+g*}sY6-CX925#`fYWq`Dd&^dXvE=sRwF9UZvrhBF5^lN#d|z zU0OMuljmKY&f-eCLNX9(@DQMGhX?B_M>9jP@Q9|B#M?K1^IVap|I+WE(AWlVRxTf{ z-00JR9I(Kn3U-zXP&UJR-@l1l<7Oi@IS2pKHOlkkIX}+<%St968;F~r%+x2Kh2l#7 zM!73&8;UkLxAN9AUv1#*4ppu_ehn>*@uFDJB?A%m>IWelL29b1L;Bl9ZGMFw z=*S5MvON;9x@hLbQ0)w8Qt@*Y(fx=e;tu4lHS=L}COR4l#nUesqrX=|DOPnB9yW!`PpJ?MVny~F>Ii4#8)~Jw~b|v zgmNVj(l~jO(Z8XIci{~HRo-_Iw4uqM2~dLjALyO??1{>mi~1PwrQ}j-1l0DpM`xQi z{p79nW!LXIkhC`&b32fFbl;{CQW^9pb!5sSzQWCpdksH|%a`cUhq7+HB%E&AqMe~` z^oy8-j6GvpJ-S51(#I)*^OpM|KPi8hV%nPbJ7CkPFXF0QM!RwAIa63C4K#mj8LITy zXkb7T8xln9!eFaWUevHsCgMQ|R@`?ggi=2vshm2HhVneGWTJ?(&RCOMGiugqXTGCv zlr%m#YFQbibh&OB!q=vDh0v7;LIy;+e*J8q(FW_=X%GC?$bB~En7ow#)aI8uCD44H zl}d|GrE!Md43?SF&h%xtUMk)$ab zJdB7P=cP~2vI_aS?DEculb0PH9x60VqZrP)m5zcqi^WiWQ=x06pCM+@=nnJL8fe|~ z+s1Vfs?%wiCWd83wtrI8~I&0QFjhl4cI^tnbltBwOcBwJgZYLN7I zKegPLXG25~0yJnk5Q4gLqHn(@fhrq=u0KE})ybm2yH3ET64|Ww-GFm0`U%Rk%?2DY zCrg#LpAQK@o1Ck_38Nh|X`B-d2p=UI=gKe&+`Y2rk~0ahy;-o&igSBqY_m}Y=Dl;Z zevYU*j89+SYq-yAG^n;7egM z^`oSrHzOF4B)s~xR$;F5{o*ZzqOGNvNRKqua)CDFfevI@rw}r>jBD4TMM^zLj2Oa( z_>THYFieBM)}Y|@2Lmh8nT>`>D2EF~sS$%{JbmiKeaiZ?C)N9uXxy6@_gySIbKF_# zodS12*Pu>bCuYPQbqIF#qZFIzm(@pY(#jm}5@RN=s~=aVw6R8z)#elE+OcL>3$aPu zK@2}oJpHt>|BQA->g=Ho;E1`qKJ9#X(X9R>$R^Z#mqYlF6P=L^$9|)+b7n4SEV_Z` zsSQDM=ngyzDBtC<{g%&N1Libx8HqvL7ur~n51jNF$zd=4tF`H0a-U;4ZQcJ#KR6^m z1v%Uxki!LeBDGA*Q#~@6FXC|VE3@m-5r*p-*c&#a=(IUhc5W@ggxj>}`TUj*c@tPx-odSJw;+Rnl0DG~ zT;&8$swBdDeLSH)xsq>+3XDFwPEP(1=a=!R@8x?>U0}LpQoJLY-11r>V5Bn`f0*^s5wP)@_}L*y6x!*KJi1G%C$fH9Wo4LY;*8tf}NggM17 zFnO2xwHv)w!*3b}U5eQMIP+2DfkSE{C!2^02PZl!0dea3McT@pvl!u^L2tEP;nl-b zN~DVMU~#dEE>9bHpZLmR6j(ROxe_Gxy+Cm%_wFao30ra|^W%bZP+D^TP0^}Z^`Tnx zQG9}$JOyYNJ7=Bf?r%nhm<5G-U-LU9V)d!kWba_cB123b>9PGfI9QvzPg* zKtD5`p7Y%?FpC~{%YDnqY^A&bei@@29K8DJnu-KGMeOGZH;wQPV#-(EP%S+7b%zb! z>19rwfiv-ZIpIdRiz_dK+3p^wA~LSeW(^Sbm)BL|u@>h-ylD%SSdiyY1F4;Y%}Y1<{z6d+TR)-D1DTaRv5zWX?G+ zidAO&W!qEZ0h_Ce4&8HOh#4Y^F!1^_bw1PvuF+B758!&hnyap*dF3MLpai1G}emvrb2X4K&DkYUmM|x9mj6P9M^Yd}b zy{cuSy9&zQn_rt~2NJnwDwUq{(6%{aM(jH=imQhO2W_8y+MqN+JF$=}GGe)opYv)x zy<0&E9&zTXx&{8p1+7)#lXUkH?3LB3rOA^G_L_;Wiu`O*|c=n0evP zKYW|u(%J>>xZV6zZhQp>>Ua6b7?ObwBfWvR)UiyMP@P$c+-KFlbCFl1BcOvV`AJTN zc8(4pZPZW=T*kB38o%f#KXy1DFj91^bf_@CA7r&$$2;5R z@Cy0ywqo@~?M`}(yK8;+@%3xuL_Sekhf<6f^gX8n%9y*nKK_|S+~C^5OF+anxM${4 zAcJBx62ozjTN4%`?L>C*v0RHbq4_q}Qx;b^$Wh^!3wg7%-ofu5KDw>7@`ok>Kj++D zHVFewQ(PRpW3N7Qf^C4QFw;@n=#lMtjbmOg{kg_sHx-JO%Qi7aL`@QD$2l?`kJgDs z$HaOJk5E;)Z>Il!;w$%$AIg4Nq!-Wvx@fC>SvfK^>Z{w2oONd9y{EE<1HSC60R1?2 z-xWS^XHSH;f^C~{P>!;&!Ki~UMr(-Cz`#ewX_}84E8D|HaZJJ3fDsSN^29ol#zT+i z@K+PpZpakGa&_i+Q!*7PHQuOTqh7pjBGiPT!`?QM#7$i_ z$XHUT+XUTzIM<>K)?>-`-F*cYux-4}QZbia@1b>QK#|sU{7ZjBr=*3A7Pi%^^B}q2 zY>nK&>xF|tC)at{c#lxxjKISD1SOLvK5g0ZpPb{(KmEn+SXrqicvsNvT4Utdt5GUs zHoiWRGVC~AaUsH7`+-JZ4wR6C8ofx19~z9Ru8aKQ!`cnJjl$abUc+-IV-V;!N6iap z4lkJ&7rwZyma}vDA5~&5bkrw#)(sk-9@jUD4jM0I=%Kb&PyJl=wu#7yMOOP@ z2_n$1Vbq2AyzpsAJlZSi6>~b=X^<*arp2N1Dc!1gKj%!c2Wd(Y(*zxK3RXVGavZyb`C%6CoHxr>%572n zNn2zzn2lg+X0;>u??Ym8xLi&-e4;&zi(T_*hFvDIs19jZt4|i|iHs&1yt7~$xCYJ| zUar9Sk--0vvY|Hhn)mdn6c~d=CSdWf3SCk3SOYQh*T?nEVLc6sRD&B1^$iv2h;n4e z*_ZPZwxp3$6W2#8Glsb*nn2kO^A$)VHbV!HV_aRTtvC&mA)elK$I$uoo0Gx2soZyV zOBE-td2?GpEHnOh)>=+p%?5P6_Y~A7IBwC#f~w?(wHwc@`q|&tE>8NY)=9r^^GzG~ zIsq{p^&7TM%Xp!0R1Z+UOeNh)A`Hn<;WJ~<7_U`VmTQns5prAUE+DfZl$jL7tM-&AR1BAy!_6>QHN`>sI{jX#4 z>&~=>9EyK1!fF@ZEBD3jmk#iO$9wQ%NPN={k@G>rOf_S|gGV%sutfZ7wGm?&d?E=) z_u(SPP|)le?4Vm^IYQ@blwWnk14c}z1AD?Tgyg1wV!DM@11-K0M!>ckEK0K5#U0g6 z3yvYND=}LEuC;xl3kgQp*z{g|VE9{S4{oGlEVM#vt8GKyF9{)yjn7923%dux8b*(# zkw;klBLvmgL*2|bqqxyb6%AJqXLrQUxBnU_Cai8Js5UXDjRN;KMWD5^)9Z!EZKB`G zhLTXKl=~om_@#^gbiuJK06j8fZbs_pYWB`lH_9zX_#(zXsHA6z+E}&Or2f$I%e12- z3@%svYI${p&T3DaK`h?fmd~}Y$9e^&M_IARHwZM%zSA#)iwjlm z-4Dq?A+`8H`(A6E00+%;@H7_fQNcVZG4R!_V+j)jgE5T0x4L!C8C`xwtWaX9n`3=3 z!?(%HHIP0sbdA#Jt%{|`el|IWm>(49p*DK+E~K?j!JO@SKBi=5WKrJ)>vnRhqY|f) z+nV6RrH{djU?cb?lpv=GoWz`*(~fvmgT05)37|wC*P$(1n2(2!R&E=sg+A>l8(LiI z%*U6xWHQ8Q2$hA)e&|Nn$(VRgAiuP0jsW7vCVf@xWwo~t0$`~*6JrsNs~H8*R?PSZ zwerZLgCZjov~1MmoR4)iaX)6VzW4f)1?b6uUF5lZcx`j}Ahnd^_@M|joh!~;_frIE zT-XLDEqDe(m_huP9;K`?HIju7GsJ~v+u)w0O>K(Euhx^=t>Kjj3L!*Ry5{}HvBvRh zaj)~=ou4K)?Jpm)V~z{!Dwjgq|2l^tg$j#>H88})4DfodA^3i6aM}l*9dDVmijDp% zLPgaKao|f(n-?1PR;66vFc{04SdIEt0vk2veIx||vlF-TzX~qpQtE-4FMaj|H1yVi zdX{m}z5T;9nN&?BXK4DYMN0$s0a@+QEPYcC8?CI{O9v8|651tl607Tn9f`f5a!-pA zI$WxwBy|=UE$l9i3=JN|A)Cm(V;1hye5VOgc@1__QrwjiIXKkc2zAn>j$GW9Ulwas z{Srn*)lGUVgtd6~S=jd}Z+lG<>g=`GXv#-mSm5iU1$8c!b=fK>p0xYUyJkG(X>Uyi zs;++cSWKTdV{sbe5IVaiNR*v8AgUV=4enG;uE8Qrof|OFV1}dC8$qv%&z$G65)0(O z#w*Y^Do&6vxIbEpI=1m#q)315!8(f!_}Q20g*Sq6IFXX_TqUdpWp2`U>>LNw4P-g5 z|J5OpYQW%^eM2uqX#fxg-wpU=ny|Xhus)aRote$oqcO#V4Zaw73(P3Wwi>h{yxZ}2 z(Wsm}6qN6ko_6p%A0V5`qxi#SZm&?j{!Jx%$n@4D4Avs?e5*1!x5hjxyThBJMZHEE zUw5z?8$UWC7>EHoZzfk zQqIz#t{e^&J9tkk(_`ib$CR-oQa>bX=YX&nJ{mmK9m0X-A|p(*)XF=)q_Lc+y^z>9 z7~hGJxcCR{h)BmM@Y2S;y$~JKk_=3UYZgw}XpfjLL2@(8yqK;xz71AEjm1+sW3vgQ zp&SgM3AK&?GPo0$A3yIwI#cJ)?MyB)coo) zwAaSm^7`~&RYYXM4E1&jr3nha6DECuGoVFd>3D%m_Xg~JQ2BL3g$?v7^wiyb)-05!pvY`czt?F5vG!u zRXf%Qwa-qe6w>PjIOY&uFVv{M7y~|NX4WlG{_voLaxNGWi(7!TV2AAB*U(yA8`Ik5 zPMWjrV+O;|kgJ=&7_+Ko_<$NI1zJPvei%x$SGlZ#0%zZP6xkGCF=HUytvqKF_nL;Z zWzj#Q$YHaq9lu)%lgM?J~9zq^)X z($NZy_b`DCpCa5+Vb^qF-AUzd^V}q4H{?U4#2iDxL8qfz1xr5jTUIF;`<^e zcwI}M?R;Q!0wN3tbMA4X3as>_O?{kQ%NdetYFF1nLUW#Pv%V<>nUR>?ODwA?<#Y%= zyj$hQoQ&o@`)5+TGpR4?4)cOlAVEY(lQOOvGh*&MNJ%4%lBQs|>1zW~RS|9a(~1t> zeO)n9QwXyobHJ*M!ckFto~Vj@d|T(NEMpJfkGZxXyPf9*<1tn4&mB7EkOcIqqFq@B zodDn#B|cts`qGkHgkI5)=}Z3}s`x`a{`luKtd{+qWI}{~wdBW1AaY@oq6v|Y ze)4x$lz8O3fMRKpn-DvlVVv@|$HFxCpA7RN@$WqHKYob#l0*H+f92%N|L`O&VLu+bFLz&Ro-)K{db9$RTW$H|}Pw zX-(xPybGU(D=3G`?(4c@*5H5ce^WeEIN_RM|KtF<=*|cK=Zn}s1xoIJTgjCF7bktl z(er$N#BwDy{Ll4DDPXNM2Y=!&oH>}RfckdlYHP|i{NcNn_;0VikIq^^atXr028nKx zG;yM{7)&WsR{@gDzjrXp>=$Z(Sk%You`_u)Bn%vk7A?xKKzuBH&!x&F#$-V>F1;1r zw$r*O5>A^fh_Z{D&L1ye5SEtEQnMrpT3SX$%88v@h)y1`QXQ-~Au(kAkRu1~|K*iU ztLZqW8#KM$^`dcGJfS$x?1gcSa|6twAEE+QPHkebSomUhD4U-!g5z+j39O-6y)c9) zm}c_C0a4CC%wQ51hOb%PlrR=d>YMlx|9*Z;KMBFroeV)O@k*$9E%Bi^4!oj?iXV(Z zVG~X@P#e)viSKR=j^SIt*nk4sI$ndoCy-Ga;O!H{*3-LuB(Ir!^^Z*%O5v4A8?Bjl<;y~mrC!M~9)D@f@~G(7&(wqH1R z*{VKL!gq`-@zvb#HguYF$#Ty33l1Sx4T$eaoKTYK0`nJ%H3TSl1IR8Zi2UoO?<=9nVP(`WUS(uwE4m9_DI=Z7_tczFW? zg5t!H7=N*ltBG7b%~f&H8@TW+E}Tn8tx!wq8{2jpb6Q59`4>JDa*H5r^J(%H*{BPB zcwN%UV!!`rBbfhlg?%3f$x8ZN9M{l9EfWY=x?`Ko_a}VNtV5csHLaa5i~Hpykt+IT zZ81uJ)pH}PkQTH}vyRw}_}Z$$;KD1Lq7uhgv!m+aFQQ{Zaa_0#G38Xl#(4z}g1XV- zyJQ)O9V1DPamlPli_i!caFIb~IYP~iRwaBA z6p9(!$rsHSOOKnc;TxV^eXrDFg2gp2rqyO55<>o_BoLtoK z)3i#TQVG!OCGe!(JET{XVC%}MRB$9W_PN#@{H&C^I&1v1s4w7t77Vf9pjTS?*dpAHsppx%VWv=nue3 zrwkTny7C>z6kU(nF_oIXpAArh$Ifr5DxKocWu~c*To^IeUD?fY#(9brA)_PV6DiBY z>fVHTnk&%J>oNeNpI&U$kQ~5HPee?UH({rkQ0OdAC?Zxkv~-)ZS0Ha%)Z5`lDMD}W zZ=W$hNFzv$Q6H!u5T1Em4!o>1Dsg}d0nfT~R`z|Ixhk$LlCuLV_;$iMAWG|;!P78I zSb}K-747G9B|N={KQ8GW`DRR7vCV4{fe|vl$~M_!5@(L1v(H#^yj;kMwdSCe?L%8Y z1MhbRR`A<{k1Zy8Zm-MwO6b^1OuC{v=YC&g*FrjU#>%7c4d<(HcQ?W}!SC~!hIneX zWZv4McXRL+(i;o!ssu;-Y){xazmtO#u@eZu&^_echtcBE*}x;0W2{&Eb6ts3^tmg= zzg&GU2p3G=n{{AMiEwd$28F$a#mxTUS2Bww+)3w0aLlj7qL$0IW4aMjU|`=nqN4xy zR7&o^N6?9WBuB-6eddv7KkwjmL!MJXHU(ujV#ocQV`fLk$NK?SFG#)t8K|-Z6x)BE zvrf%Y@TbB+rg5w_s)toaTyXY1IY{A2h6cc$`g!4@3PTeZK+}6~Wa?>eVnP>;ymIo2 z7L$!{k*F`Nz2h2&^3RxkGj*~qu)a2N0dJa|dA+;fS%GVhDpz$s_(HWz4qXj4525H{hMh+Uhzw>3M#)|Ci zV{Wd~Cc37h9~_Ha81?EqO0*;MBf^kL18_c!rW! zn@Gvul@XfL9Vacd%^#%uZoY}oBuc~!v83{rc4tc4nD;vkrV8}*n*EzHW_g6B7j=+X z-V`UqtUH6!G>}*=nDgP7)AsonJnBFU^x<3j>=J)d!NGIvW_dTo0YIs2H=VC?sx$#q z+yiL4+s;IjYRK%ww`6AWLSa1#mbM-v>amO5{#Q`lJuC59;&;5({>TK?b=bO^d z6^c+F_Qwi2xu#vxd+L_9rzD&OXI#?R1icZ}&HgvVnvySiKGDMFS<-=)p7g0BIOGaU zQpb~MBX|AA^?~R|B#iU`6T}r*=p#qYOs77VyjcJiBc$ar@6+*~OH31P$RXl}iMZBn zO=<~izoiQjT)it4vrbxypY@z-|JR0Ob90c<3v%|A#?_ds^V_MdaR!652}x#XtF3uN zsDko+U`98*Z3nD*NnH%?6_KBHNtyXl_e3f1@u92z1CkqN4b+53DKgXBn-I!=3`MmY z96lCoRERDgM>`jw*KIfmNZxXYNKKvXpTgIPu{ib@l~$+~-8>IWYEiWOD9H$mLlE8_ z@OkigEcpCbs@R85pq8?9am_zrUkkKda0nJNQ0Yk9MhOToKC_O%jMCPWxRMyzb;er; z#B&Qj-5cCJWaqO^WCh>p%C&A*t&}<^bfuxf*C~Ja;nv992JHjmeYJ1LQW4UxuhI$6 zc}6+YM;0s>3#{pRZ+_(kFht4~ycv8;+@nFT;Wg;(;TDlM`_g2I zU*^dY>a#SU8hqepESXZMEu^JWYB;0gm6eWblrJWnvZRi!oSB`y`DZ(LQdJuJ%T(f9 zNwc+x6^6>@`#PEQ) z%R-YJcKPecDs9?M z5v7cUzI`!=kXwSdKDY+aZi<>^sFxct3BP;d-I|@S*HhJtDWVg16?I*{jzoGaxC}Ur zjd=$vR6$s*sKki&PJ#AHhSF2OK>|%HEc)R{hwLPCbED%3{#dTfA;1FbuECzu(s8Ja z*>A4|!dRerOId~U-GE>+s)Qdf1XMx!znKS?CRXXz8u`OOHd|9=vROMR5jCx}ILw?X5Df!m&S=LRm!TboVQ>MI4DO=Nx?(kgtH z8MgmNR8&mnPkuEDe<9m*D%+tNtmUJm`k%lLOrA6X$>G&?sMV*vabLbwZoiVyHzsO~ z`%BTkNv3Ie!x}SFjk6Y<3v<3hrVEX&sbPQJOvl-9;E=+bfvXQQ1PQc>eN!OxV~mbl zTk<$9F`;3oNWdF6WTNyK0lZe{<|@tZ$9pWj6T)ONCi}&=4w<^21LcLEo*j?ccKU6c z+0d!si_>)xiN{5sm8`fwPPz+P(gxNvIEl=kJ7prqzYD3wP?wCU(oh6vE9^YYKIt)H zAqs7K1lMCS{lG~HdZ6doanqzFnYf;57t4IpL(9CGWK2ZGw0~}c;>2l__-*qxoVxjq zmV#gPv#0tisW23R)fSy(j(CrsO_A#OP>qir0Ham!rri5#U zI%nXV?UQh>A=VuDf-Jtx7{( z=N5GB*an;PCV)gqy%kz{hj!7g+ z6~q1l%;^ik1rG@F%hsl&8A_^#gvk_U5W7Cm)&?%NFzPdStRjmqfbu5uhN zy^b^Zleh=E=ehWUb&6k-uTGW51651?<`vtpik1!S)SkF6h-rhcB<}>UC+DHQ1Scdz z?GY5y@wxX-f88AN1SGP2N9H3qVpx)f8@D_&XqvMyJ_8gLX*oKSJq7ii8dX1bg$#_q zgr{n*`N@WctE~uI3h|39xKVFqCB6r;jv4`9gz-lMa18;-YYKQeMNg*DUXZ}^`N_an zMC{DkH*KWB5mY5)q*5|C0t0nx^-WelnD5`)8n60KFye*h_5UA&a{m)C_yKz;xX%)~ zn5uI2VqQA>X~WI&W(mu3n7*VfoS!f^2XGE30RQ*(?%|blKMOyXhv65GZx;-Q;y$boWRkk*ZrMfxN}vPzze?-9QZr>Mn#^-%U07mf4p zzU?`6+^hbEedVwvQIHI|TMCQ2DxjbQqW=M=tpih0L*43w-Q#9%uV}ydKHP&mOxr%0ajhaYoy=S@l(n%fQY=0OAIG70jvU)GuRW(Me38B@0=QT)e<37S9XB*i>QDn$i ztAgcziZw=lC2H3ThsjVCkq}? zG{#QJZJ95gEXfbO2*0;K;k>eWLbS=$hl7ssFv5ZoX%jTQ!|{DAQOpAVtp!r)6Y3mV zon&tAii#hDPo~Zms&>bJ9hRxN(8{qWas0wRP^v2ark_|TL6yW)6+SJeLMFn++hq7m zK%y2wTu*zSgbS*f`R5Hk5tqO*l$!raz6y{8KpB7uWlhfHckcM0 zA&v8IWDR=u@y2C)q>`10-_K5}l6!Qqn`%2M!^^=5sQ6X;y0>qbep8|D~ zL2a$>n7QjTlMF=(`>NuXNI7!aWPG|7x*5cVdu%}toZ0SG1EsCY}R-XUUK_q+kXm@izfXyj>=|@2wQfpYk#3Yi{CJnWPh} zC>pk5VC`|R7H(UQPn>e!Qb zQDr)H)yN`A_9)@ZYDV>CEJIS>Bx9-2ySo!cHIv@Gvbi^2( zw289+xVhP^bQOIJ&ZrG<-A29VT<%gF-n+F>+Pu7Uqu|kz@p07&LCW`{BZZ!;^OZpa zXoR>cOyb|yb7aGf?o*=qXi?(vy9Q2XZmZkvEX5C&m9y56&hf_+!}1VECCDuEm~)le zt}e}VO*$&U_U{G4F2q|h3anFHTNV}PWxzpHJcs2 zy5b#MOgI-oYDDcnVi5zue|5Y{;i=*4Bm(c~xnlg`qKOc0V&<*3B?F6;scAin?J!AAZZY*HfOM?_3L3-qX!J-$BumhxEmESy zEksF=4v_2HMI5GT*rkcsdHz%13W3>zzS$m>el9G=-6V9d0<4BQQc7rI6HUQZyD(hK z_BP65hVke_brL83Z8;^38C4f4=90F^G&D3}@k#46`uknOt&Z}Nv(lA}up-*ZkhSH= zask%IYJ%GxTY~Pa^wIUxs^#Dn{=?(%h)3@CLk*5r12qQHA4+!t9KCr`FrB495`&hX zmBps_ACI7SUGK`v)*pgZC&iB+^m!v?R)vlc!e`w5lcl0C>0S$Ik97ZGy8`7Ih}(`# zv&A3Aql6~sum{qc^)ekLEbZaOqrLHo^p5XyHu{@Y7n&f+Z)Do>?#_ef?vjK|()O^p zY1O`vB*~I=|6YhBz+~2b_Ace?K0APrDC!e#T>XJ8<7=7)7BDG+nyj&Rx($7Hez$*P zDxKdf8q-d?yfO!cC`iTFu;Pe5d2Nz7MDVE;Qnvn_%2;%t?c_tN?HAtKot5$ia4A{H zudS0W?rh%@hN76hPlv6}PTtz6etyDAewQqy7zHUL+Xh$sG>?`}`?hJ;Y_Y)0kpOgX z`ozHVNrSBTOG58WSju`1KB?axZ0t0cLsEtbV53j2wGLWjaDV9*pJWMU(puD^`TeCO z)W;<8yN$g^J+qZZRz6r;ILz;U|0KOSW^YeA1hryAW;*X%4cOCa)0v}Zlf}NHU|}*E z)nh)14U3Nwu2?R)_gu8>^Yj0-i9dltF*GztYHFVOg&Q+G(B<|8VrE`B?gDrAIlupV zf2oCDavqYC4n&JrF;(~d{=v*|iv<}t9OtC?8^!EY(&Q4F&8@5XU%6Vr;OB@j2y*B3 zPk%f*V{NSlcQTp&biCD^KdKfgWZ7yrFM_{6yncOX6RW-!+I+xr!=tIQf~e~~n_a!C zO_HwEd9l-nNs_^u#{4*wh4q^W0h{ZcEWQglrK zsGu_bz1=t&f>?n$oS%kB7Y}Ja*kh$Z0zS(7PM9RE>ietY0MZla$&<}&FYf52V3NW!U{Gh4-POA$>GlQBO9rqF zV|i#R2blftAqQd~!2%6BMHUBxB0&FVhK0jGLz!4v^8cXx2F?7%ABb z+XUQPuZ00iPW9qUL$i?=sx@P>4wvX{FsRgOZ7Hmdwwx9tgnj5oXY7GgZI_9A>jOXk zqFFL*l?*H5Da&KpX50C|iCj)tf{>$hE!r(sK9aUdFPn8Aw$0lw0VvtC>-y=wCbK=# z)t=TvXi0R!e&S*_?qb$3v$9FQ&e#JVc~*F`E8i57O~rcVtM?h)=Vne>kVQh^KeVL5h@q`;knxF zt2G5&5$M&oCNTxohmZ=^YKUmJD0a)_{9BD@*K^9+s)7Ca;H5*RWoXvLq33)G430=L zD@A1Z+^o}jcg(B@u;EiZOPQvj3Q~cBbO-Qpa_=T9i7zw)^WEA##V1A0W`^?)YCKa% zMVu=FT29nAJp+L)f}V@AU9F}-q1k3lEcK9H#Ha$D68(p{zum|JPI=~;B?`Hvo=ic> zuO{)1qc@|(uDH!x(}e7#S=!6DZ;was<<}Xbz(9J(s!9%CgS@ZE&Qx5x=YiMT68Uj5 z`pX=^!|PuwcRw?Ua7dVM7#XQHTK{q?>R1}+Sqmlz8R+C51n;f(XXi2L8xBXc)iZ;T zSb5HPJltx_UUP21Y^iwq5_I-?tj{;CLT0)W#O~K>S!x-~x#*g7rAl>JyZ!akuht68 z9=tuw1qw6ae*`-0%|CJN4p$Cr*yAfWlxK3)*Momn{+F}jVSm@m=MlkMl78clMnU5SbYYLy zsu>h~FOV)3d>0xwYhF6}?M451zThp`a<^}@Dq-TO%aK=Dpn&$V4?y`yTJB1-sU-=PhfnCe$1 zOLp?+qcT%pHfw%JtlyK^@x<|DinZ^hlY9lXXWd0CQJ9Up3vx}0lX*dvc7IlbLLgBf zqTk!$R?4Y+da9*QMua~Rk-uSk!~(a>2~YX8E?H%R?3YPinH|NIzMk{DyYk>(akEY1 z*$dNBF-f|&aA`hyk`*S+9|^X}$eLKVZEHWhbYL83l5a2Xg%DV2RJ6DtzunQe1UI;{ z7q+{{Wa&ZpCxgCLcIb+C!nTZCMQWz?rO!T21v&QTQd=1RivwtFup_!t&lpq{oYFb! zR&~HD`pf%~UH(6%PG&0?ntXe4=lwJP=h@eP!L#Z;9ba5y^ap^TCo!0C#bRW5m_KX^ zbmh}Q#Bk~B*RN^&ZY3aQ%9f+8j0WHq`|lGSL5=xy3*x6-wr zlort*y#3WE;rpK(9mjTBtJ`nAzU(S*?L5%~kcHN!aqhzRX|$J$4{tG7DMW3O4V>-w zpa3CnWct(5h{Kq|>#2eN7klp=)pXjmjrxpZ1;j#A1aufh5k#a4B#bf&iiiq`NQsDw zbP#C<5(`B^VH_2ZmO(^@-lUgk08vV!^o{``bP`$;(!Tv;p7*@?taH{`-&$vVf1LH^ z9~X;Ye!0uOuYFzD-Z!_qc2UC;^BgCKAmDgh3<4U&79JfBm-^ek$wBtHJLjXcyAqC2 z5?16gYob;Gq#Ami`n9~*KGCt4oS^d+vqV?zvWTQ=?c9s`q(5(dWq*#s?{+WchpI<( zfv6jUeK9oqy`WJd!~u@Zz!?Jn7`M51a9h&yyEJiP<6S8wKKd~4v+2dseQ3F1*V85a zzSi#95kvv2VxX*0t@&+Ryp+vECd;4mH3}#8F;d1_@0nCE}FNu-VB+yhpR%(k|Hyoi$V4?c49unY#62Ww!Pqiv*3s>;Jr#rxf~e zdH#wOin)rW>SF%;rwgUYDcKy5l=O*!*;N#T_ALh@+5QVL;JP<`a{tzrB@wjBC zBmObRkWs8coGK98stx{?i?(=ZqW_we)Du2C%NM&D{;x2p^N$g!klxc-{m)6OUxS@{ zazXWgrh8x45&LVMznu`)sO4quIi298KyEndH&cmVj@)rS_6)O9ApsCc-u2Ia0$Em) zh6dbzZtpue_<}V+=7>Xbxv+pewmglzKxcH%qW4UvUlQ}{l?+H}&_yA{SaZGHB z>oE*(!qQpI+v3_Ej>`)Ut@HcQL`8-lz7?b*6}5{;l9AuX8VpTD{7a6=b2-ewR_pV%ApYz zAvxB2PEDpAJDmPdj{jG^)x(S+cOq|zK4Do^&>OUZFFx*cd@Hmx$Vu``L+1uGXSTYY ztvE^xKIZfUFNng60=jf00i~DZ$sUQ(Xg++KzIQ{~o{vTPf&gduy@1(wF?6fl!jNRz zUt}UsjpMi=2%o|#_-^BxC_Hyq>;!}p!k<{CZNmMruAOQZ-yg)8T9>$s%my$kNWFql zH)_Qo`y49`zid;kuiEEB>f3Sg{CK49j8XE_bhEV43lpQwi7_PT`(X2`fkE3|k7B&p z(Mrkrx;Je1b~40gv6gb~-0jfJdcDznr_sM5%nm@IA zwW?L&8XrMf1*XI?bnyo!0_UcB=z(I84(yGO0EiyDs=F>|AhQG6AI53g|jAPGWhkK z@3rI2Dh1g?Q(i!j3lZ7Pxiu~OjKe!08K!n;56$imZ6Yh<1Q#%vL(+sF*h;Wt2Hlx& z)(YFHb~89&{v5I}E050B1{{p_Y;Ny-6EROg1G)4pP*}e9mECLYibi10`JU8PLek-` zsKWI!cf0JV(_mUVtVT3nE-)4TxoXZLceA98r~PJh9Xc)PwzL0|chd77>>SvK_EvsR zRS~h))w%foZ*NCO|3>RU3AicdCH6&On^NFXp_$aJucZ1nz5K0W|-i6 zMU`I%`+b-MX4V#0MF?vrHeY_HGyeT~3scNMM0LTdPCUXab}!kcJrVJf7S(sV3^8w$ zQ^=*Un*%?Ou4iEhSQQzrw z)1WJxU)Iu1h4&Zj()B&--#=;h55JL#;U5L0JGe;&+ud06%JJpDK4j*UALS*fRMN-C z^QG}o_$5btbO(mhgMULaOi@5H9*_G;IF_tH+jx)igO#HicyU=yY5j=o-u@2j0dDjV zPUhKiAG=;Zw3A4E>O@GYt*>vyFy_P_gi|5}2i!T_p<}nHttw5ZhCOXUb}Z5nM{&5=FH&E$v8uHojCt zZ{dpp^^ts(QSLs$vWno(Bn-oG;jLEHvC8H4+|#__VZXM&pB*giO#Dcj@ag3J5>h+l z?RARL^F?v}I!8&SKH3qqLrm&idRkJPo$hdxSNo*P|II3tmp%M_dhcXkiJiFbqOF}b zaD^cd#R+R4p>d} z+}9{*i=I9?TToSnszeM5g}?A>^zAB59Zjte1qUIc;bf$Heg?rsM_0F|cVIc%6L3~o zR1kNE$=>h}6N?^#&xZ-7UmXQAxt!gn|`yWxi94)2Goe+=?`tuKR}6!rbl<~)xG)+gb}&7-FMFEPOI;I zqeNC*XmUg!vcdBfshwH_u`U(idmn+C%-7Xh@`@6P3Yu~N8A1vSH&e9WRO6VCO#D)z zO$D>=>>!wILfbPf!;qwzej%Z5G-sr-24Ok&ZaZ=9mVXbM7M5-(CxhrGZ@S5Mx62V5 zEweTvIc&Me-jhK=IWy@Uoefe-Q`0|y-hmsZ-jMil+d#iCq4H+2nEXZ06-|pwPNXu4 z9NV~)GyrUOSS$tf&Mi7)e-)^WoIN#*v+T0r_VM|0{QO4Be)Ju|%yWV;k}t3jKIDi? zM^;~pMLQEY|4LayrXjB?#(FK0!<;l>kxBY$XlgP7C@s>n*R3REI8yg;{~%mT9Sjnf zHQb;e2`v85OZ(cbuYURT#K@q=!qQfJh2bBVd#e@ZXnW^EPIkp2C_%1v2zz2DN323w zaxzOg8?-CBB#HD8^pCI(`}4ESoI{V=fSIpes8b0wR^gq#TzJzYLl*%xW`yN;^f}AQ z6C0iWVE1(Lzi$Lv^Zxy> zkIcI;$A6XD{6k^HRe$G3C@uW&*FD+)1C<(_PsMJ%B#};x9G^dn-ibJBL(`I&FOU?r zBU(sBTfcHDRb>-~-H8`DWSP^1{a3{t9V!?QVb5kkfs%oWL4;DcB>lf%S23X7RuHiA2a}v(3vAWwk|F%LQ&e&@8~^5oSXLKRACLY z)xX_1Py)0$y%WC}hu|!mLIJR<@+&yrP%h|BPB*rCe%b?e1n=UKB@c2n?}IXPq+q?q9K@zsCdP6QQ%)TSp!*sn#McG93B zt84}sxG!kS-jk~4UI0p^?dIbw;Yk-#5NV|>q#BWGSwPc$aoG6ygEAi{7$=}5?N|?J zVTW={hwkx{W+&_CSBuu6AX-=LIj6WN;B$yIgO$_S_T2?H%8CWo-VcFSjX=-wtCkN@ z8H+~@V|{`1&1JRcx2+8TnF=EU`hh?pa0DZ;_-&PPv1ZE=_%FW!$1zAxH?`fZqoZ@X zIf)InR9V3I%uvWJM&go_v$K^UZTKZ-DN@^@*^f9cQ@B@TFDwFKyugnj3>54GP`U%( zVhSUsjT!7x_vvz*U9zVlcUvi?{P(3&$oN31iDJKx$F% zZ8^_)qkuZL8}Yro^W#osWRd{rSJ+(33#Sl_RjSl0zpDs-0g*|l1_*>^`d?Nbwv?(- zbPhGeYpJZR?~t1L`PtHM2~TN-1ooXP%1c zAD3BLdW8}M{EiY*Go&ak>r0TlOOJDm(w(XHOSWx=CYOoFH@X@<>;m0rs~xkab7fo5 zXZ)(vK;%$fyTmLD;w)9kYVZEEvTR6_)kmJ}RNKG0Oyx-5Q-A*hCS|P;y$A1FbhY~h zG}oCnSo7vbRDuoytRzrUbI5?5=+vmdUlAR+>}~gSNx#GZ7(zoa+ENS%WyZp;9y zEc^v(dU8N21HmxKWhoMox48900d^PB!rIyzFefyzV7-_ne*nLk45Ra-7R7SUY$atjd7-7N#d4dic(MttMI_ z$a&y*Oxi*o*0gFM;{SCs3OwSytvz#b zxbkI3OQzI`U0Uuo{_I0`UtKmH3|C9%b`wxqG3DXMBdqi5;}9+aFpcm`nxD3VyqrwEGr}<`!w_&X{_$HO-V_{jjFt<)IoT zQBY+wF|pGWe@dHCyJOY8vy+$ z{{apxkB!oruAfrx-{34wLpH^8kNVeB?dPp!rc)fsYZZi4A+_sstPZP+t$^>R9)V^o zf(Kq#Z`#RJ2<|QPZhWtP``#e&l0KUeRnwAc?48~Xh6ECKoe=3!^;svRli|N#@AH0n z^iJ9xPEUHh{=h5a<{{wDbp_lNb3kjwD>cUu$ir02+AM^H!N4$Grk=-LDj{yNRGLA* z5XVbUaAa>1HB1gxY~LIJkQM#+(wkE|_Ma6tdwcftzV#_A|A1O~*=>MoO+&#Fhp)kK zM=+s`;d)xf+Sv~qiRh0AUxU8a>saV6Pmy@## zA|Inl4_0aiPP7s>IqFSZz;f+Mb)Pq45z9 z$U%$$nnd{b2w_jlW)TsQkU=|qP=xhdQhe8#GiW(XMkL7An?sgQ` zDCjSadoFdGiYO~9JH4oAc&arZb(lY@WmeRcBD*-|*<~M=y3(TP-%mCA94;Ro7#Khx zU7B;gjN$agmoHzYU#T7)9rgUQw-^3yy3FOHORo6v@Gvz~u-Ja&$dNxzjq37QoRC(z zxj)ROE37@LGy=H}aza3#I{lhkS*fST8>egxlU3CFU^^LY?S9&DzP-IY?5VWYTj%NU z;~#|tG&~7`mFh<^!V9R;CN;BFi+xQ5%;^_5q9AB&eEc+gbusUSugtUU4Q-vBVanDe zZ=LgVa>yFuzb~^Xxm)zhhr-R9ONbSF>%O$6=`W^d#W$W14gB(uBu~+nxA6RCap_X< zMBIdVwk;U5j9DEe)h{#Zu4%mi*NXb;xyg%#x#2OQ@WKWL57Xmv^Yg(@orxWLN{w{#-$n1jExK<;I60;Tfdnz?fsJznRp2tt48jPb9I;a#3s|gi%T|BqMdeF zH`b>zxzFXlC@&!Ac|xAIW5%}}@tS+aj}wVKJv|qTG*@iKEyjmU+OMew19!_b`lqkM zKhK~9w=0JrT-BX-T_2yCB$t=#SR5+x8vb}5Gx$eFU1(@%%h!GdUxRWwNr>4cG7d<^ z4}fFq#UhVutO)}-Zl`BGK_ZM8d2BQmv~QI1i^bN*-2H{YJ zV;I`e(P5rFFwyJAVAYOit)&6?wK2x-?rGST?C)kI;80&Fu9}!G zwc~HZA5mk|)5pz~C3JU98ymh6kygCj8)}}7Vhj_%xnP8Bu^Sy^eA+HhFF@**vDAE0 zG6)qo0V!5%YXo6dL67>F`b16krD7@8#Kh#ExY60&y%T{GbijRRFhQvZi5}yPq z|AM5OPIb1k)-iUw+{?$`nm2d0v}{jey-^rfTDi~UpQn3Yu<@7d_qDaPcDixjb$4Y~ z%U=W_a_iPDqxNfwwu$3oGhUO~CBevcgXr?E)l?LCK$G@~{=1XeRvVqtY0I$=k)O-= zZaU|=r!KdS&#yMmwi8wkV(JclF8`G`FTi5QCVQFneeo<-zI4mQ`_;E-b?7}B}C?a!Y-$BOLDF&F+d2*lql6#Rg9jStjn?dlicmRmCmBF`G9XJl-K*!#qF zHI8oF`>3{{FMyT^@wxPXMZ|OzSrG|VYiIFz79_zhPThPN6B9<%nauJeZBlr%?XtkV zlo|?FOyc3mpNff3pF9c9O~m7tf{I=sNiCE2PHlByI1lZ#8*f7x7DkNe8KV(077$4d zLmC@geN>AV4pHI{0sZMtISU&0}UX#p&D63w8 z=K^38*5{3zLS(IhzxdMEm#}&q51iZj`1L76!x}KiP9H&`5>Jix$|YLlluu;P`OGSn zijEVyzEc}j0zMDkxUW#E3$9EmwVhVEzj7qoLj)mUYC|89!`Pgh9QC7z&@-8spmW+>dIilP z>=t5ULs$s^zG1%JR9~5zYj3gJO&2F85kO8GL2mpE&((?N;Yo&Ml!{H@=Tz!C6@UA` zb8}6j-Z=s{dAt-+X^T7{%0|-XLE&k?CW@m2kT)}Yv-%W^hE@S0uj1kw+>HHX%5{S# ztz!=F+#ZhPx=v}i)rDs;7>vXTq~5&sQ`X$v9Q|FIK57bVP3k{Q8Vm113D&7>1WJNN zg3^US_40R!A=SoSvWXk`V ze?(RFS;k8UTjV3!+7L7q6%|{)-ru2{87L@dyjau)e$hbf?|&FvEIRt*G9ATohY4Gg z*iDX`&gRX?;A*!~p(fb{v1{(K>Om~6LCdILckSG{DaP*h>DVMYoi_i4uZE!P=^p-J z#sVK0aW3HTcqwUV<92>Y&wEOB>1Z4#43Lo@vKN)^j@8KSQap61_0!z+K$R}oXbC_C z(~H!P4nCA!_>0~WQ>A2XVUfD+@*p^4==5;Q%A-Q+GoMYg`lZS%D$I&>v<3scOJ~X_ z;rk%|y12NwA7Xl=0>pGUu&MnvBpOAZU=^wFvTd$39g+*$<^5P4tsRTRH__b!+Sgjn!C?XkXDK2x+_4j-5y zF*!cI2{>iBi$yy6EI!k~($W(4=AfAZivGrYl|1;q0pjCtR#sNGTwTw?q4)a{J-vjC zmy>XNjA2B3XL|@D;!V6S1!juWZYj{Sh)DDwI-Q)7B5%>CrLHc9lu?AGr>7%W<$|6d zfFh!6>i@o=L?8QUoT{K-b`(Xr1`5tG<0Q$F2uP0KZJxPOR8#~W#MzjPx>Ki46_A}X z+dDfY4->ga1YS8Z0r>p@c@D`xdUwKbH|}?xE3Q{P_kgQcCjCm8?o8i&nX+X-f*AWSV3WVFYCCEQT&pwi0;$n@a(3+Y$(HSo*z?n=!B5OvSEbIM-8}{&Nr z89Y8d4&NM$tspDreY628-rm#mh{Zevkq}NF6P>=&1LdDjx%YC%?^lumS1G}iy>ZUZ z#N&K)uDq(QuJ-Jm#S=2>W_)t7NZ2&*Uj&R%?Aff*32%c*M_Wm4y8P<%=g)WEU7k|E zWLtRWOMWa1`-uX9-(1-j;GZz!RmoWOZLW^|{Or=-z>c^M;*2sRIMa)rj`#1qEFT$# z%K{OU6zJo#NQJmz+V94e_Tj_OV0~$-i__chk5)c?IGMbyYE(>LJY<$KuT5?KGIM& z;Cd+yG@*%{5-f9u&TBj@)Y{tWbiF#;x+HWsiipX$Hxj-V+*@24jP~%yr(kaZ(EsWX zK5#_V;1AU%|CYxJKLGSg5Zc7gp%&Ye{&@G|!-o%^pX*|-+b4~b!%;;V(dXI&UIA&Y zX0$nT^3Q@@wzjs^P-%BK`*kCA6yKEqs2`b_oUG{;4EC-Z3`92!w(g#QHO4GogRvWFGh4wj8L0@qW>(Ws)C-P!N2m0t|LR6}cm-;JcM}twoczJO z+0w#799hDtn>(VU)+`f*4sUc!T(qRV+2I#zhL|E3Qt@)&cdQCq?@(U=C`ShI-5bjv z^6U4&?XUx?CIpd)pDOu+DisRp^9PvuLH^P*9e~0?i->+En%O@*Yq@HG^K9&1Ri6=M z7wQWECs+lT0jb#lAV5@k^5n^zXLatCjE{7(A2i0Bm^dRpU$v;Wi_J3Vbhhzs*1%4^dzYVnaJTnV{txk@9pXi*)b_i}YDwDw__utz zCK)*GLKScq)kr5Xg1ZuT4?L2&gyvF3Lmc%dUs*{xnS!h@IJz6pWdH&R4JAXh8Of*9 zHU?7sVOk>Az1Y1B&L=3&m}Vz!Id&a;%iaB)c$TQ7?ZP6xXr6*Onzf_m1Z}k1)V*wE zRK4IG3&jN&@;<$h&!!FKiiuDwZe>^q*`-pJSl#*v^;vmiaiFCRs*@qsN-*f=wHInN|V5gVn?p+>&v z%?EF|-s?aKJj<#j3OIH(n?&zI!iq>5=PzA~J|zK;-d+;;kR!~MmC5x!jXs>|lCYVi zB-n#v_F*B*%gg2;dL$qE4-%(1*eNNoejLY*IzfQ2UKJ6wqe8LnoZ$+5P9bZ{CzQ?y zPhmOVH|QVG<5T1$feQB~?TfLoQNJfP-IXt&Fdv7v@p+$HQliB~;jpkJzJD<=Ff%jz zA=)kiuY26W!oq*N(N02^`)xzoGhWKpvj-$($0jF5YHDiIuUtupnv95X_S{_Zf+hN*E4iH0dkQ$cdpjXE_&+HloJ z=6S$JK7?=`0=eN@s#g@&=70*O-)t8}cRoK#M2-a-OxW(*M!Whef=iv@#ls5atb2FdLjNDvNmB6nNP}-U(xkZ2I zk$U;vPFuXK4y@-5CGNe^tJhGM79hFP!jhG2We<^A@PpJ`FqCNVd**R#Q;>rP)R}p1@8BTLp4Z@{?gkU-(0uHz`8dY z+WCZqwVL9Mw5JzZYoHlWTyyp%z~(Gw6kacISXwd!(ugmR<;u>-s?`j_R3`(KlKr4X z6NQqg#!*A4Y6RZdQuf>U6R;Mw8E>AGBJ37kgIl*g)dJhu-o6uex81bHG-vrV3jjeF znVjS53g{;LQ^b8zsf^FUS1O-bf!Br_YLb1JoGb$7H?Nxf%lIGEz%}ApMRjC_FVqjxDdgRZhN#i?6=8>P6!|M>PP$Nu3~YTqQM zFi17ZIk&mE2)THD)oUq5dc%Ga(YBMI8=jw7aAR7_(qm(8)$H3oM$dnAsN|excA5K6 zwkMXQjI8@(bVjc0%8sOB2ZtGdH$_wI)pga2*&ZQkWdG}|UYedlAC5EaB)0044)_Sz zy#q&3$6ogCx2z-%nLeb3Rx=iiTqxz6egTJp+)CE{dK$snX?pC_a1ikCNbTHtI@4Y- zJ~=6*62OQceHO)?F9jmD@gq`J9Xykhr0P zRu8XPWYr_gY$1;C+HAJtxxMpka`Ep$7hQZ<6VJA>z0cSOF4WHA30oZxMF|XS0^cO}Yt zWLxIC@F=BEO5W&&s#gyxG`X?V^aG!D2;#`L@_*9?6j4cNE^g#dw|4>d zuFliwq^{<%ObqV~3n~D&?fs!PjEsx|h8k2!)2kY* z<Tzfxn=7G_Tvg`me?=Db$i&3oa z&uikrZU>V5vt|Gs`kSGO+t62-bM4x-U%)~j@Ee<+hVp0MyV^@#4z0q>3IT6L)LS7T zK-+(FVb#MNa8ormAM}wj{e|3P9#0)k} zWPCz0fZ(tM+!cSC?!dMjB7d3wz0aXGzq4wl$jN6TP<@1gdOK}9B>Qmm_NrjT51vga zL@NF0qgqu5^@gaT@nr*zcFQevL>S4A6`!4kBK5JR`t6ixfz} zm%bni^<1&$-DVf^=Z-ptHgPw@VL1kj6nZoHj^sY99{-aeUs-6ZNt_U)Rmt~JW6I4Q z8o*RiNGP$|`k=YzNwL|7mTc;VAB0fs1Kr`1iK5^dz3p4YVnc$4kG({}of|>{1|~Ls zB%_$}#^|M_T1um7PUTUA9yJ`TmS||WCVY6-L5_E8Nn41}8p6a(p=pYNGPM-Eo<5Ej zG&CqcL7`_<;bd*Te}BlOxkZ^yScw?&=x{kJmNCB+=S}|nlVu3SG@q7TT&&4VNZ8iU z*tlZk%Y%|D*WIh;@r;%5_7Poalk3TExRqqGnQQf0@rBz-7fv}N(k3C1L zn~!Oz$Xd4n8j$BmJ&Bc;D&sBn))s)T?Z5t zass{zVYc#z_0f{$<>dwWK%5~}vU|C$`qldv7ME^1a2iu%Y_{`91zaCiPbZo3V9$lh zfg3SFDwW^CqGW07W1%S_J~Q11jSfd09)r)Z@W>a^y)Vvn*zn^o5w_3jNa`M046iV= zrmO4nrFz;l*lN!DFBK;3JX}d9z2ZbM#b;Fp94iMAUO{>ggLD^iq%>@)Z`u6dk{q=u@m zM$;Qg2z@%cauN!~CuXQ!UvKH0H92=P`SpqV6llrhf5|kYqdX(8?5076(D66@?5!== zH_MNZqb56EKm6s<9fUH$ae5~Uhp_|mvCzw5bV_^up#h%C>}Dc&MCF9Bu`zgK2c&Vg z0q`^N^cp%#L2s{+Ti{F~K}4VZ`DORA)OYrG1^s6s>ev1n|7;p?hD8t}$^u0tN{Sy? z82vIhNc_77m~o_T4m-#km{Nrvay!X_o^{j=0$(YRVT{=VQp=|e7tjkIUfnYlPOrs+ zvb!l4Un5=fQol^mS};h%E9=cYi)xyIB4+$=tR=r{X+CcUVI$~!-2t=y^}2;VUV7wN z6X8#lleV)>GY69d8J0vHkUI8(f1*+^kX0j)h}3a5yt0#o5Imj(0koTY<5PgU<4$hS ze}S@O9OFz9`T9uPj&2_A8*f$!lI`)VASSqPBD%p1Ic#7xSuiVT zc%TJRix38~w=I%5-fKknzd@^_hp03pg_R~U{x-bffc0LaFv?sy)9A+%?TKfH|Lx5O0ubyj$9)ugRpd(v`S+KtYLf4$lOWk~)OGsm26-THLm z2)s$Mkhjfn_p@x^ea#AKifBg_EV~gbIdzzuQJhu+UmcMVn z=Z|`jpq_`|I@4i|*V@t7Bbk5bg7Es2VRF8#%EQ);;xpx;UIhAnEBsMo!Q4ZyD z8BH{n2P_^s(q;}z9zLd8xsc_E(v7!1z*#=`;dN?twS%_nOeZtZukRIawCzim6tvgA zuZC%4aP|uV+&@o@gkyF<$xy$4>(lPl+42_W3WxpI$CbnFQ%+c>oZt9M>fzHBW?K)= z&^o+qlOtNp-LWk}#kBg)zu-I#PqepVH&_POqn4Unu?SO!oOYgroB^#s)*yO2@YS5O zmwSOY*B1rZ%<4StzUbZayP6~RM!8K-cQa=3%nBv{+dP0W&~!-YFUBV|@?|j{9eWx% zFNniuU;nuE%#?%}>f66WHzG8>ug#aQ1JC*$Dh2WGl?SCG?#GTn;f#Sle4sQ!s`g1b zFQ4fbovEBB(4O&h8uB;q)WyuUW+Yd;-T<}ODP9@a!@>j^2>%_fWTCpQ$#3yn9l zJG(hGFZJ8nb~CrG+Ecry_NTq|?rnP=)Z{N#E@$#IDoiwp*5lbx&({j%^z;@k3t0}l zX!p`D;eYYVZJzKSFq`S!R;=E1b6ZE;3bX-39dI?%CW5|&)uj+m$dV@ z*Y=`qnxB~+H^uif@y>n}vmskK5)yr6!l}=oTwa%&MO<#Aw-r)04?;Z-^Vs?A(>*?p zQoDD5ij2~ou~UKb|PRg&=oAQ5z`ALb{1LOKK^s%V#`ClQ~~_rE&Va z1xx2C#lqMH-Bq~Tn^-L;phd+q7k3b=iTLgt-GS6ePO@mwWrX>P4YI?7%OI4d$FZVP z-P=Fxi(tpY~^14VdkZ8Il1tb*ke%#^O~1HGo_zDLnIu(9}0k;QaN z1*OEVmk)K=Zao+pyb}H``QJ0>&w!jmn8K9IiZO?;cSf4=|e{yE!cZ!h}2Ibk~%t?pNydeeZF znP?bH#ImYdPIlz@^lm#CdH|6aL$xXyCdsL(`}z=TapEkC7GNI^FIOVcR_kk2kWzx6 zNGQ4w`f>Y_C+*aZXm3TteDmgAQjdoH-a4~4C%TM=fB54>eKO)E+c%q;hvMy|eCjx< zdKL=F^i%`K8!-T^n;Z*&JALQFI*bsY>CVF8_MW`tUrO9QMS7GiM!OOfiZqJUl3$^+ ztEQPmQ4|W*?Iql;RDY4u-oF<&U3-sme*uivs&{;RQk^@x#xBRkUhcc#3_-0P&1dW* z`VL7DtA!|dZk#ScOs1iEulhQ_#MBtbE#OA?#I~?b|o8 znp3Uz&N?N8a~yNZo!{ePgvv<%{+*Mvg%=b=<;2)(&TFq@ zsKPIM%`^@r6?!?C`Eogf&7mHzyHdv-Ed@#zg_<4%yJrF@4h6#){*WZK!+J@UYjq$L zJrhLW1QYS&jUM?ugn2^f9@tMgMVPQQvYrrEoQc*j>+|GSuhQ3%IIarZm@evTcJyrjzYWkV() zBiR%rD|uzSlL?ZxSJaAo;9ZH|b)QN;DVKfAgJNy(?mgqJr`3d99Q|Lf4Jpx~;qJNI-WKW#&MkICUs(;WbEk(*b05+=Z;bmCrV2Sr&1n^?|>UT_b z+0#_`b1DVz&r$h!++uq-s*X0#n{Ct|yfDQw_s0!+`!uPt*L2(_Wb#HF^?6SJSTy_? z!!EP8D3K99VLg@%7e6p8chmSFj$U4>Tx2pGW&RvRM+w#C&ax^$()4g{5}f5~ghoLV zLNpk6i7Yn7n}V;7=z@$lX3ANNP%@cIL|YUN4Rax+H$;l+PtkvHWNj!U-~UX{iW=CS z#QqxZ-OJ?_;iW|61n#ugj8gmvo{v^?mnq=y7CZh%YF7Z+o3A-pxx?TnG=FfHaD}o8 zWB(ETN=4}?`xvPPZRD^a?~vVk4vaq}Av-$PbL6Fd()dq19%`%Lzyvkv@M$Oov=mu> zURdagDFZc&^V3GK+|qQ|br)JV^=UniO>m^udDer_nm$#DWZ?8Fs05}jr0L6NC(P~@ z4KVT_ElheD@(5~s5P6C}#P$f7k1zbokje*C5K14CtU6M`B-PVD;CY=> zaY+5R|CoVXTz15aSCo9sHpB0_5DqDb(}h&Zy0JP6-9^MSYqP90N|t*E9+>uS$g$aIUd&ahubU?mDxG z0_JStHw$zBoGaGWmJ2r7m$(VLv94$v-(k4JBTaugz1!OlVGIDJ za0Mw+MwcXnS$M6~24`eYmw`Zu%N~}Mu7*_V#_g}=rwS(c`yj=|O<>$}M z%G~aLMOWkS&UYF9eWoVL?oSG3Wnj9;f_I$Th_tGIB_lve=H&!k^#!Ki$cehpn1`KC zMpFzP~AMEPJEbMcMjl)0dgbFKH;KPH?NXyVxTrFZu9mWSEN9L29~wRxuj#h=vfe0-LYp2ay2t!yqS3SE!1H;{>DC|w8fzCn#Gz)nal~8eO8u5+~EEj{Ci2sJ6 z^;?P&GW~ds6)Te`{9Dx&REtOH4L^BBQywt&G4b)O)MB_milU74@Pfl07k_GYmtzvU zi$23t;x7k)?kOh={i@ztL}Y)T)Wzv}9STeu(irNr5L$*}J3_zUiS${bidImHVM( z+v%;FmaZZ0AVWy%fdgR~uolwLuhu*geaFeoqUQ(e-_^bJaf4{xrSC{mU8 zg4~T45g+ry9s58&*W4X{AHh#Usi4|P6P3HB!hoIIv2$4`rY1VwK-F1p<((%+mb77)~c=g-rr{Af4nzI zEVXX+)T}xG;zx<%|93x|ch4l;sk~_mLpHwJN4n+=r3%bNckVE)B!9fi>)VV)($cCi zT(buI>wgU5e`qmc|GPh16zeL;6rK_h6%F&No|j2ZtI)0Fi+BjTxw$#*50(SF2UT9M zL^ThA0F72n@agDY?c-T#9aQ{Vx8I;@_4+LfY0mtpmG~f5K{jc#j7h?NbgxP`1Z) z;N8Il|DnfDzs@45X}@hhwVH`SKmG0oMhjNWbcy5q>H*6mf(6tbDUT?fP|)85mjhtZ zo>}$x_a|p51w$c$`ky7hFS^Rnetf=dzh6o5o$e7w&w0pgG4&sMegcg3yOa;Ff9~w! z@`HVI4F{SJ?^+}X7-e}5^^u+v>1l7bt$u=14m`ne40lNKgrBLY|G+%vk5kdPP&GR> zAVY$CR9b&n3RB>v*SOi4V~fCk34~V#at5UZwy2~eH^f-?rN3Xs4jOdcJf1409)3SX zO799J3YzbVi{JjRo0e>m)z-92qQ+45uLWpdrTVU@=*IojlIoFWXm@KWiu7T;@)E;D z7>)#QvdanZ5AIrBoN+HGMZQHxyv7KMMGz;HOKz2>bOfid+Rw^=!i=y#c=a`P?{TT{ z=KMVQi^q2hptRkw9x=j-=W@f4KD9SAR*%S(%75HYcVWb7wX1(kp5cGK;Xi-AQQ_Uf zhyyR5Wvcw@|M~z5u?iXb$;teO*4%N@@Yflg{NA=JMzyP_IxI=6JF!^tG@$t_40z4FS_d0?~;QJw!%KYPxkIXH62mzFbtSmBQFbTBMSHcf$JhVKq6n>@OGk?%v(d0vD9O&pI)7Fi!G8 z!vm8D15?#^9*CXspEQr(il#KC$@8ShRGc{Z&uh-)~UMdoE$#WqGYcX-Lk-Eo)cG%W1=gt9B9 z2-NP_%XYl(KGK$CV62+??#R#LOs{M1C>0}d+C{n|6H`o?c;)SI)w%evjkm8`btH#` zYPKcPxm=v)qat`(4KF!ETF&Fnf41#C)VALhy^wu1N%``{NJ6itC{sZQE^=a~y&6f+ z&fesfZIWE15gK*d+Sr?}11I^G7blJ!3{ARL?zI2Yixb8SOxC>1O@p&AHP;R(@`smP zWti;0EMABjG_TJ^<}759&9F&~j42O$Rn%P+z2#bSk{pwvx|v3sELG`iozj?d$djo1 z%N(b#|Cg9x=JLji;wMZQxzB|vu8Th~_kMVx(8Y1m6^(7`c4kWv-qI-Q_HbZ6A>WO{kw{s|!OZT`KcuDV6&=g@Rzpl;5V9cd^p@8IMcaOFx| zLEZ&x2|ee{&_>V+Dyd2<#Q07)&02NoO2sFVI_4v=3f^g0(`qiTd9G5|}t3M!VYml&-_73c)&NwCz*3W?@8<~ELHL*K+R|c6la4f)C?`WIax}d5C9LyTl(rG0S5@xj@7*gde7 z>=c7vMQ?EwhrRKHLkjQ;QZFIT(h~I5VxBf-3LVdY{k%SRXl+w=3|b#ljK2C$muMf6 zNw|k}C|FteUHVXgQIoT-Kl1I{w=J$-`MnohjLkO7f-%Ix+|{TMd3Te@LGj{%M-eK zj5luUp$>MC`__)XPn>shhpnDCJzTEz{)O)0?X_`C|L)5H?q9ikED|C{ZRHbpNK#<@ z@k>2kCY3Z&Pv5O#U(JM<7;9}UVvc8X2orgtH5(57*D;_|Rkc>_LyB!8%KqwA?PeuY zGqakr-wwE&tgQDnd1o1dp+u1bb-bewE~|N$DO<;5%(NAlzs*mK{G2a=Jmd^*L;C3Y z+&QL(b$w7^TbX^fzny)2P#+idoo`GVncdd$I^=lP$>cPpu6K7HIi-Iw!x78(bWC-% z$P^*rw=gPEgq%5y=Eq^5hRD&HP}g0Ci{@6M|F>^@ADIs!cGd9s*jV8T-^K3_4Q;EE zGc#4Bt#g3FhsMgguUKCzNeS#sX=n)lCr!-ixR{())}L~--tnOsM49;q=H2Do03_aM zL_9Qy8>b8tEGc@Ye6zU$Augj7Lbedoy!0lOONwsqcKANKm#9f@9x&*;nyn~tC430y z&P)&d=3Gpkb$oc4oo9yDwve*!vUhP0%jDuH$Fs^hyIN7#nY);3F2iUo0=B8lrXf3u**g+N@) zKb+Ovi5!{ToThA3pS}JTrGlzNeQ(q81kz=k8xECqvT>7gvk0m#M9APgo6*;!t;OW3 zYqlmke{iVPfEmk0R@w~lB#jm-fwJ5CNMn}!s>sWvn%r?ShJq|fVw5!UEx?(+g4+&g z@YWhwm85iyA6OrC7rUXQX--|Ut@(~lxNQ^^RmI+fH^Z&#ZdOO%y_f)?6`@p@cPV3@ zGhTN*3;ttQP3@PWXPZTj*STCb^PVV;n(MUl$MNIXLH2q?3fYv_l+)Z9Qp6sapWS=- zaGTe|BIo_JFMc|6A&VB8bo;r`iL(dW#3+=GrqHD5&DZLDymPlPL)@0U<|k>$!w!&K z6N$bvmhPC+Q&icZqS20S?sl3Xgj)zSi^u=HdNvfMkB=*Ps%!a!KR)SZOp4N^uh?2c zE7sqs$J*M=Q;+@g9Z&~?pA8+lK2-fh!^M8=VCMf~?yaM$+@iP9tsKPz0tO`rSacbb zq=JexY#IcV?vRp35fBhCC~2g-H%P05f;4P81f@fe&O2Z5DE_`X#vONjcYNdSasD_1 zVZZBLYsNF5IoF)|KhT1A!ORnD-M?1U6jQ2j!o)6usyXVKwW~SHfQX$dMt|~LXTQ@Y z#P4htKePbg`)Hd1n?qM~18wf-kWdqs*pq|qpJ!bn#x;1NaBZCZn1J5+*s3RT5M52! zg~)!lYqmSN)_sxS=xSDjqJ*x6RK|R`Ze^)2mBn`NT7>T|=s}LxFCRO6A4;uG&GmO) zJIy~eHz{+ipx4pfPjQ`5ukl&2)uv znj*`&$huEiiYoa_0>oH@%CQcKfp&oFO+Fs^fbY#|Xksm;Wh>_&yi+ z3l8qs0-hz})pk`=#`N~^o)-Cgd?2wa%$@6Xn!L|Q_8erT%qqvV5OolMfv!lWPuQfo z{`R`-tJEXp8Mm(lDI7yL60p|1PZX8}CCFuq)Jj>k+mVztwxB8;aqb-xxUAtM}=n==XO^_}B)D*$M08Y>D&AfZd zp5~&gQXo9EMf>!HJ37?!^+R=1-Chwx#)=Oavh4Io5QBd{MWt?`2A*bL``AH|n>an%&wgjrw6g4zRxXd$%q~5X4;j8P2Xs7}7zzz82Be7{24RQur z-JK+><*Fx)X!ZH1z896K4Fv2RHp*Qff=sRcu((wW5t{Y*%^F_1xE1nhwaZ*Z0ps7Y zgDc0t(|=h3K`6Km9jZEHu`lN#W&VWyCTWc=5{lM6msgYD!UHvp1Wl%<(PP;$Gs^0)^Y)ygxl6cT zV9DiYB-2|EQ{KB~AJ){|Wu;Y|++*^s4jaF*(R-UJNLxdGREqx)3b`(`XOxQhY;0Hc z;`WV_m)9LIN(H9o;!y$Nc}=1VG_rfp6s(dPQ(4(n8YSdhyu$Nb%vn~4KAckmS(1p- zN&!&mp|Jk0IEL`!N1eDzH-;smI{5{Ca)+!q(gc7E6U= z)V8*(-f)?fL;aquqMl)29-v0Oukj&cvYMJ95Z3N}Vr{B-i3IU!zhf#20{e!CE!A?> z^d#(LeK*0^7C=-2>Jg2oN9FPop>7;_3CF#)^DArrO!7|!oi;QvgI+SWNCdO@Q4ybs zxZN&0n_cz6>3G@`o%9fd|TXR5j+JIywz*+|Y4@>#3PKx54B1;=)2M zJ)K{#Ue(LR9ZOtFPclWW*-OUBsR)sTq-^T>K5mYVBogpew*PsnXS?^waYU~?>gepD zMB;z&R-Bx=kKnn$cuUx&#MW4VyDN8|34P(TT%gUUSOwi8TH%XQ1 z&HM>$`tSQcRt;ND z%*-^Jxu~L2lMT*ge5BNxD1`Lm$M}@1wsK=f*Wn!`P`6oL{(idZ?x4lj#ozTRt^0 z^`D@kIkpXBE#bnV5#f~WK)CFEsvdXs@m*$*RXD~7#gd8eh05xu!^0N`UgOG+8Xi8OCDGc&&2w5ZoDz-qU`UgW@3f@x7kgPSutIii9! zQvf%b|9Oq4o-sXb(vAng(Cd9e?_SzGG4Y6$cWPz^zm(TWSf=>~D3N4-O^sViZwc7d za1nKL=&T|BJKHiNuQL!L~PC`gq;$mjLuKKgt@hpbja;~`Xr{V(An zjGT+!Y3X@GL=C#;vh4wJA|5E2g_#katu5#8J%DMz6&V=&n>QFM3A~^cPJyv41?80f z6EV+Nw1|#IN@l7wGYW+j{Iw1C{<#Z2Z(8Ky`dS~Eo4$jN6C#@!L>o9x3;vgo9G<(z z!*Lb%lz@>ye;|0}wykZaxTs0axICy2Mb3tVO9pm_)>w{%@f`+xU^IfJ-2%1mfxO_QMDMQ-9!GZK{c;8JU z9eEe5YHD8Ih0Mb!o}B*#qQAOY7mG;$h#+Q^`pg-L{2GWgkIl|zBId!C&lpc{u;M?9 zI~;p@sNXKhsqF?-Gs>=Pymo=k&3u&}0Pd)Q;Law>Qu*{gzb1Qct1ia*M+!UQm*(%E zR{C*K!P;70t_9@e)2JJV!dl?OIlv^ zaRr4YL${A~`hE4iUjfIEW1=iGF#~`J0Jzc;5q~bNos*M9MZ28Dj9tfBF4G@@JpX+^ zG0b)6b9&uRF3kis{Atk2EN!KpA1^~qW^Nptg0gZFu=F**Y_Rx1Rh1>k-1C8e5|HDh z9 zFigpo0@;9uZF_u>xR`TYnDYd~&}>R_ve0n?|Ae0JFk7_2p3m5=_e7W2Lt^u7-dpV?>$Wdg6*3A6W0BkDgeV57eNlGz=otnoleZq&*Sg`>8&EwV z4r+pJhqg!2lXk?rSAOR=uzp}@EPU9+nH>lk!B)zzCR{%c#)r{P`7nym{J-z}oW)`j zL`1#3wBr5vad3IM#3lyYf`ya&UL^iU+IWunKM(L6jIPlLx??@M`8Fwu$yOR(A6{O^ zY{jbzT!9e@Dku8a`(x8zzRa~8&x&Sw)G;s+Q|{ET7yrTiS32n0;Drex=QYNYk|Ox6 zdZ<1BGBHc_Nz?E2N3jKe_n+qz-xp}xf&(^y^Xr7pTl3wXt9IhQJ^vJ)eDP1t<#UlQ^QeqjD8}a`KS#`eW~^1`>{s7=u8H3j8#nfWmkA!^?$RXyh7;(F;Bpj{WAHMi5!e(l7*uU??R=j~M& zfz%%G;AKWSzoHIUIMxHsYNpW-_o(;y)1adt!4iXB+7@!c?c@h^Da0Set|WA{$VLEu z*%aSLgOk(^gkOeAPw)0rY>=?Hzir%k^X0;xv#1>C>$A7<+eX^jS7*RMmG|(4K*vF_6XC2` zZ{J=poi~Kel91bI(ElTt?k|qKa@<^epHM+8>)ZG3n*yxeb54wsQb(52PA;vPm!T7@ zluUy9k2ZIAIk|g*#zPbsA>H{~ZGC(v_7xv0V7`=4nTfr>=;rV{FRP?&YI?zG041Noz ziMh#`f9Xhs#YaaGFI;`Ot)EalH-IW=YO2f*&)vg&f92=GqX(&gOZ_(rh%#n7zNs_E zJUl)Ea_%-RjxXng+O_Ki086O?3uu1ZMeOUfJBt#2%TE_SM`8W0JkXwhQ;EObSDgDkP$f)WMqC2x6 zQ}JLlnzJ^~bVk0sB9H)8?+pweao|%m&e|c)L*LINB^#fLDigvS`IWgpeV8*O?d^BJ zP>PZr23W)Fbb8V=Esbg1R@T@sr9pGFvqhE?AO^f=@idZdhl?^_b!Y_G`M1xwQ9+?g zUM{=q0{&O1M2IH4<9j|q#%1yJH670%ZO}6?63N-?oA{o*by#JWw{&C7mTzjBQu10u zzL|*x7)<#oaHLF3Tz>=y99~>p>rA0$Ilizs^sY0iF%D{+jx7Lq%~73M!3DPg5;##g z^Z&fW`jAUI!Zg#9b5M|NKov-eJ#r;y>A#fwLm>|0`TOUe{gYDxrK;Y1_RG5O;|BrR z76}0l+uJ*pQy$NXf3{{=ZVR9OKgB@VSNiyTW{K=*=i_0I<>2Rk1rFDFKqbzjt=6C5 z8id5$iHnPf(jl$UsMf1CheBtyHu6FZ1_ELKVaB)XX9<1YOSkb$FOfh=P7bC9TUH8A zeXgRV{q?+E!7HJXzFscR6*E@AJ&gD?M&jKa&A>xr19EeHGTK|Cq68rGB7pNiSC<3$0}YK}fL$gCFfca0`x_IW&OQgToku8M zzTlrFe%mEAI35 zdmHiMwAKY`K86~1v;`i0&5O3-;k#g0k+|9#>TGW^i}dna%$ zDhP$N)qwnpK|GYfJq@jx`EF!`jXo@DwIv_3b!*LAx!h6nhLH?x$clzD*)xqOB=KfR zynBj^hbMC1H*^oSlEU>8VqlW;PyD&^oWr)M}QKI}CR{ZAc%Cs_!} z0cofwIDXvVeLN%-TKf3Hjs()t(E<8xY=pxp=ftN1`oS|ieCiK+LQRX#gb-_qknu6r zAQ9F+3cjbR+9S!scr;jB6p3o%;`Z!nLSzQ70O*c70#))mBGA5Qyb)?a za_r^h+mSkOeqT3L2qKRj4cTQQgx+OP(8y`p*LzA$JzQAA{I`_`%nO&&CwwfH%47Z7 zAd~+ao}9;LteFFN0<++*q!4Rm<5p?NK(9pK$8Vw4)c~m20u7V|6+)JZ!RuuO%z)}y z`0(!giCc%mEG#WA0h4FD+W1eP(qhx`1$J&KDziA&X}gZd&GP@~WJDJj$jQ$(AqaH5 zarQ0DOihQv_?Ns4oKGQOF$GIbK=955h%mJyRXh8fgFBjZ_gH^nI=7A8vc6lKkGj_G z{cw%wfE8>@bRTlW0sBc05OiBy<~RnXD`*p+i? z9~m*wiipIkPNbxpVES6ccb=S5FE$5Aq~05zKMWllrT#!V)ErZJxku0Rjy8QFz^=!S z<2Xt|dpqM&PssXG1yShpF(Ns}bd<{7eLx2_?O7EtPCTMqMA$-Wj{UsAHpIvnGn0R3 z-?4fHU<%B{uH3LWJjQuw3s( zd&8#+@M3NDLxSP^SNN}To#q95xz>bx@m=oswCr?(*;&>H(;wR?%K*T{R4V;r`@;H=Wzl{Y>;P=Hd$h?Da}W5RN}9)muW?1dpE&HK|8MyxNA2b zEe#P-m7J54iJ_Spo>^vN95iii{BQL@FQ)^5nrUnTgjlh284G;C11(J@EilDLg2J_L zq~@}9bdB>da(-KZ;M9nu>iq){XKj_E?rof$h2Z)npT2DUe3^^u%pGe0oQoo&lw3jH zwO(nm%F1Vq)0iI$byys*;wqW5a=ZmceZTPxWkmfG#8w23y3)Gc103t+wUH*PF8`8h+%@1g zNJXgxukqF{to7CsD^SqH96!zcNMt!tLCO4Bry`}WUO!WP{tNU28XQTK#K~JD=42w8 zCSUPSGH3u8gvl1{Af=wsgL{zz!X-l@T5obC0Fz^;E`e+xCFS&QRtw}+1A#J2E61Nk zgHi0`KC!Xsoo8ljynH@!t>lwG<#aw0XmjYQo7vsd(0HSCsNZEDlUc?tuMm1cq{CuK z?DivIbB{poA8V9);3R5-lpYjdxV({S_ut48H9W_CofD3v#JaEF9q29i)J* zcKjD!25_Z|+3EK_n=psMWwY`WKQ!=Ym{qU&svWvLxb423%D(DhX<#rfnH(QBMiUcu zH^0WLw}YIwSEnc*Xw^bS6ZSu4iIzE(lo7`U7NmwoO)gujpN}OTB6clgVrJ4mEKa}} z24Mu45LEhpip9MX+W6s>@{Zf{O*NP`C~9g_W9$n&S5`t=5axtC=|EBS+qH+g&OAn! zk$|yc=RNc(KZ_ifZ>Nzdi;Zkr)W7r~uetGPXa%Zv1iF3i6&Zw>fSH@|9SCsT$Oo@u zCWIsa{Y)Ug0in*oDR_qWl<}Wf3WZWKK~g?%iM6`U3`th7+scJUM@xejhH#%o*7*7P z#FC8H=>EDKG{kReM}n^I$DAy*J17`6NyZC10+Q5)IFt}(y03h^y?MiOGj;_=uYc3y zpoRz$sjyPgj8GAXdMhm+UBZVZ#s-HHlUNcI$fl+Zz{}{w+U$q;=X__c>-=DlsHt0t z0^DR{!_r7f_Ii%0ukQmU6Pzh$r{V#raWA}JCp{%)A**$a5#e%sI*kB6+slQw-%J&p zF*PS4bazbsVb-@m4?u*fbx?Sel9!TW@* zh+ZOns-O|B>(}2XW!!_RnF@psi+YU*Kdk7D82nhWAEXTrbMy040MZtg*?ONtpVWo> zvE|2INPuG+`VnWJWG-r3*m-c-h>x3Ni3OuitmREn$^d9I=#? ztzj=Yj(Gmp1h0NUJ2d3R?xwp3pV}inbL^^V!r>6|pW4eR`yHTLB~BZQLd46*pMvs3>J9iGC^!SG2AgHTX!hqJ3?vX;BO#J31mGhW zcI|VF6>Qw*SAv4(6N0k$0*8T)w!nG)VVZjHEAW4eS0C=-PuJ5iddS2-N z`A+vIYZL>{s|k;RmFVIQI})UQ@o{HbRuH@4YE+IMrKAUicxJUy0UUt_y>;fgj; zswMJ8@fjrFZXj~+WNKm2_(T-EaSsvepRcZ}060x9jW7Y_0ywJqkH3Cx?xJq&>^OFF!M-kAaKr>0Z z_xDE*7P5Yxul0q+mkZ<0&rVMnw=t=d{(6T2z_E}*c^|(;L|FdLjCPic+uZaR)hz3~ zOyo=@*nh)cRMpM<_bqv#Vlfu&9AyQy%j94DGc{EWdsT!^i!(h926C-iF14(TCDWrc zbl@khj)3SOqWszPtMtb}P2!pYs6Z z$r6FzD$xFJY?A)5wszx<}+JT4xby*8?pOgv|#}QJ+?mIX^VV#+`9kLPg(F$4-whF#=%gdZbBr{rjlJ0}P zn%yVYn|(>O3`hxtE(1!NFoN4m@(=Qa!~hv33-J@N0fFrvxb}XzF-sc6#88qdNdJj= zY8DcXzOUb3C!rD)ImV^uTZ|EX1AGGx6QZs3^z?uG_GZR zAJ^6vcijhoO#z0rq>#426gzw1;)6=*2Ci3rmvnQP7jIEblXyDf?zzmLYXqTj6OY_X zL|DXE=zR;O5(u?{A_mGslEX;;U}=>ov1bHGE)fXTp|sb;gs|{0?*VYeH@h$(F2NZ$ z@qNZu5$DWha0h_NA%m`ZBUKOrikpcF%8Fp(;s1~_?rO&uw6@l6s9K@p_+R7KaKAl- z1B8IExUhgDQSP_mpxoO|YWY!Vg=&EL?cyW9qx_>}2BD?$1H_;r5>fzwJ-`>F^K|d4 zJ~kYf8(_1!H$_-usvEa&g1yl9^K%QcwJGqNrOJ%UG?PzR#r;)Njy$J|8dyVslkeXg zJ!K_?oRV@DOcZM}kQ`OT zP3#ClN@W_ez%194$)fwoc$qq#2G+ta>_Nz4=4GO9JC>78xB-yC$`>+JTJ)Ac@?(Ro zAx8p%a#(zL5QCwxX+RY@^8kH4^%*x<+t5hsEweu)Db6G8lUG5Y?d=+`0$-fld#*aS zQc_B0yp$@jN^VQ!;?CDAQIuK%aE~ASG>A$slE>MRJ+LG9xBXfnUijH9kjhu2SNF~g zk`_Rzf`f)q6Fgg}M^dZ#1$|XA4QepiQ6WD&Qs-BP1%bDzs=vMDJns5M2r6y4ggp4Fqf) zMbMy{+`So_j+cF4yLH9n4=lI)wa@3zz|fMH4WE1y*x|{WE9jz2s>G6c(7vKa#l$R({z}EP_i{TE-M>^`d1=d4v1rLHKP`v-VHsY-y=$pjOoQ9;E|9V z*1=AHgpqI|Vx20;@u-N!(2Z~ngsXld+xCG_+=^ygVt<`X0^qOW_@D-CTc5&1bb-5T zXD1GPI)w21B7rdDPe+#)|OP>2_9dwaS*P3-ww$c5m7v9PVQ;D19zIL-s@Oe@;H^d$jn3s zJrNgy3TnIW+WCRxchX|o0f_`tw7Hh=CwXy0fhu<{il5#P zK8!h`q9U#Z-suBJw{po&!Z-VKjDx?c@$tM3a_OG8vgiyV0bPl3Et);^*|x#OZ5aey z^eholdxI&)V5Ojc2$tnhfkS)kU){E5#GJQX1tWvzV~GQm7u9y2h!FKqP(R$*mM;|C zf9Yi%kmOZLh2zxA29>HcC^WVXM~0@wE~C-eA1);Dm{=FKKlp= zEx=rPv1l1Vddra}osR(*i;@+8Wjxd*-af8fZc9q<+|mkx7t9?f(4Gf6UszOB zos_p118d97ls*8dA=$Q{mML+9%B;qx{!qY0NkJ_J!KbnL7u-O&bdAA|{k2DyUHjEf z_T}BenS8d_A@0Nb8o%ex=aC6bw!Cmw|5AbILK^m36Ar><#f#b!pdGaNYHssV{T12h}4Hrw7AH4liOPw4cGaH!j0UIE$`a;K11 zF7(_uP_qDk?q0YbVq|_n0MIODC zBXFkX0!Lp0MT1U`fBeQ=6wD)RGd5(bC0F2Rpqg;QSkhnHRy7FQR$NGZD?Bo?-rIi+ zEYxf=Tu$&UPfttx!b@caY$M{sd6oZwQz&YCh&(9s$V<3;_VYnJ%cCHob4VhvXN1eb zyq=c|ayup_)&~(M>b@5E^5W8K&mcJrlEabQE_a+-N?JMz-U@;t8=C^XxOj5GwA9qU zRbs{h9yNF4=u2&b_?{{`H;|v>+uMljNC9(=gpWgmq<@o@s2{sU_VoAB3gaK#E8lxQ zuo9^{a*?k1pWE?o>5Ly<9K*Bf>MuS=M=@GqangR|6?1j5iGpQd@c?CLichQ$KHDnM zDW6+n#BWc?$=!I);CE~{@-2n;1AWJ%`d-m*R$Zc9)0!ryrrH~qzIG@tcOF88Ke?5l zl$CqxB`J#vIZfl1J=aG$ai01Rl0b(Tw`dEwQYahOy+)~5H6d3h>AF_VVd%cZyK2xk}nB-h}142q{-s=eE|bRkhUzN@a1gr+$% zIJ2wMn5xgy}$m5{u{!7IZ* zb;=~G^-A_1G8oF_5??>-sPE)Hd9Zu0J2q9S;(#kdp;BJnx^!^Ou?#+N_3zK;hTJK* z4)W*Y{`L}FnLO~hEp{+wgqtI;{^z~fzgB=^5Wj%Fw)z2|y*dtuP<89k@Z-(DPc!!G z-CM@B=u>S}MMI?HQEoT;1-7D1*S~#wsVZ>bxhRfHK6e{C3}ReJFNy{{8`xO!kA_wo zwnlI2Qw0V7x;9L38y?AN)Rqu-#pRCayYEU4jTZ(=%udWpzj^h4_nSJk&l#BgCi>r5 zYv$igmWC$Bjt6_#p(uQBC6Ln5(iNI?v9TZAj2jiLGtOpWCpd26bCa@oN{ zM1{oMO3-JbrAT}l4^pTIEqLC-#aoAi2lo4Sf`e~Ar(89L1u=ydnUGQO+I%uOxEuG^ z#cmlVmDo(48ro^HANl<9qR!UZf~tmEfTOv>S!c^#!=VZnr9bpH{4GJ8=>t#aDE*1Y zxO0I+0*iMsgV42&XZ!iJc!TC>)pu;Q&(EALcUo=wU6+D9P*%X_Zf4})LNoRD|Fu-< z;WK}mrZpKXb6BS!FzYY2%7uo>W3&ffNxU^JJu5srlc({*Nh6puz5XZZ55HC*h%Bv3 zDUxgbPx23b9($)z`_3hCkq7!|=ufdYhIktSv4vvW(Sk&Vtk0L-v3DwQ3%HPi}B)8CcI&@5cXwE6k}rt~wZtDM*RYnxL-&isF_L4UomY|!7Q@qa>v|6YJX z&j-A9-o{VfG_K^K_nhU<+F0&(!}PtMz3kHlU&3B?-8yT(^{<4fd?yZ3KTW06x0huF zh+>Uw;j=vlnH%Fg8RN2|di=~)9y;l;7hN3{^DxJp=}sVZR4A#~X8G`ko2`iwp&9oc z&BG*BLFwzu1sPeq>}5ZM``4x^ea&%YwLEtcV~vFrWo=7cRtC5U`G3Tg{nPTJjb{?Z zfBQYgX$G&+H(n?aIN)enwt((aP#Rdf%($d8S{E3|oV}*_C0c;bO<#=Df7RGg^7I+Yd44J!Eb#54O2btv1`<#zgyrkN|ZhnMKLqkZJb46KED!05o`*a_UQo)qAQ|GdUw$lxHrsw6DZf(EBjc~7kSrUZ-i(FS} zQzApc5PFRAOc>ey+ll7Q!QMNO@zMi3-c2$vD224#>ZMUMx^Hwz- z*QaM*hQC?DwV!Yo87YvLQDqvA(kG)wOy$f=Y&(siqlQ@tnYR=`p4E-+(%N2p?J~28Sf34=KD>Z<*L<4b>bA0lfzQXPfmBQ z;KOao8ZJ_q+X_=6^Tpd3p7|~OJhQe%FfM*8nW*Jp=@0@6n+IHj>CRto+$^~<9Djy} zbuQnFu#`4khQ7Pa#N-uW0-lS?SGi;L2_ESWiuy~cttVd|<~Cv}f@bLkeVqx5-T5s- zNgk>7Z8dnKwdLWVAzWamXM~TqdxdO-&SEwf9~G6jrdh@be;*y-peuu6W+Uw~LXAa- z4apfVN7Xt8%Y-RnU*wjjiQQG)d?&&Ft{D619$LdRyQIr!_7JnUE&S7VP&ajp0(xdH z<)RyfD2?s6Q)G=~9i)BfvupX7Zp~K#Rxvc3##U}&A*uH`?WJVXEworX{L?5DFePVFvxB%Vg5TkxW@&FFP==G$d<8P(}L*Y15UsjnV)M=Q#k&ciUgPa!qh zPRrNFj)WJLL>gpfT;37OE&5Ps;WS%lpP_h#Fr8oj>K%2#Q=n%-#}tMbk94WKZL`F) zZzo5%KBJGZ(GK~ptUO7yZQ-`5Zd$ZW=+KxaAvCshF^gs3_OyxCwA^S-D&wQ_g<63; z+#5O)^vk4d_c#=_(Z%;o8d!_!>yH5ZcroxbJL$Cts^P*BNw2NNMcTuxH8yko*P$c& zg2tJ)C{%ltayz-XY9dZ7hdwhGCE6CftD^Yz!qX`>Y1Xp}%d=hV*@q18O+MMS@$L}L zVLTGj=FiR4jCYU6E_3#SoBM{iP8kQ5Ig%wkUD%XegQb!sx7d0lFHwmmjef4@&f?tLLbbZaJd}6b-bmkRn`k*K0_K&s#U4obY9FdirIz3-H zKR6?_^1+>U`SIkX`@CmVRKL0>3$|Z5%;6Qz#>J45N|P=|;RZXj(d4CYS+Ab2=dt4V zuB=X@Or-C&{H%rwKCbH|+X<9Et5kZFd4XIQNkWp&h%hS6@~cpluL9@eyu6a?m9_;l z-X^KKQqNqK@NItoo~ejOny^vD5)U53E(F1bWWqdN)ps{ci5N%-PWDAyGq5Y%R+U;t zK!kWtUiC`aiaM$>YVB+b8mtaMYEr+C%~n_~n!ttXt_f8 zT~|L{v;y;;R~LJejBNpj`JYHF=-O4&mmqrHBqyuw#@CJM?DUlj-W;-b56z^t(~{2B zRyK0=ed9zCFmHQD&(TF~6v|5rGDi63ve~mp(r=?*(ZTy@oTD2^e9+BW#KuO?xc0C& zHJOFFF7b-C6dtZ1%xN{kWCRurab#t%`J~FkXyoH$DQh~=W~*ME6pO**2(g(_o7ipB zkWF8C$(cI)*3~_!?L=<*C9{|(vtTuKF;XSuP@Q=c%e+tqW|Mc49)p{43`EHq3%^#N zk*!%ivg5m*Ab3Trfzr)I#ICDzBjs#gy5mc)Zt9%3AVtop51q4&%cPtM4FjrI+`V1} zoNiyx&h7C}qr>BT+FNTF{PQAHOeO2{)+w0DhrW0+^@zm#5n|oJOp753oGXmaoLg^` z)eU@{|4c37J@BeC#(Je{ZPAzQuJFKmKwmj&uL!t)$>koBXbrY6KbOHpK zC>av)soIVZO>U=^emXA|6P6^$A{nZ3{gDP|H$jUm9+_2Q#ca4qc7yarA|pk+fWCANBAWcyqarZcNL1PnwN6bBS6Rn%C^AYkEyZPs{D1vPZ;sy6qn9eAutg*L| z=CF}tO#ZES-0m6Eq#SNt5CET3zGzV{*jX=Hx9~`5($yol$=>diF$7vz~gRn8^UGi=zB5gYoT0hjd>{ z<Q-_NkZxS1dlM{pj4AK*;j0rx($Y0 z@^QjH)TAC^WQZbkZaXBak?2Q*r&F$Ne?iiIG3N3EZR`$*m!!^TR!q0>Fs0$uR3gc3 zrErY|6;$bEMSE+aEmWht2xzBgoTpyN4Vz|x)%tp|DWdkMpY3AhwE?rN4U!S424MhE zY!nwUp|wWAIyR|p=@LR9m>l#Cr~2AO5A7+X8pxj1gZd!*yq`%8PE>a(;u9%vu{D!t z(tZ<#VDkaG#l9sLU#C`-M(@mr!XthruUzj21TQAw2r&wnLJNvwcMkNsdPh#V4EADvOt1@odqH zb~v7pj|fkCL&ZJUIZ21b zdgf}CT#n;4S~=mKq;MT$zs%Xib=NdIsk*+Sj`Ox@wjdeyFiUoQZh1#CskT#lvP^T) z+AGkr3mp2U*?G0kekzjnO}86#fxIQ1$KcBH0j#_Zu#!TYmzrgXR#DM@upqavW9yjD zUDhu-aoh$CL1!X&_l6ar=wbz~82w*Q8{$QxSAF}HM7ub_WS5P zKyZKRHJwzwNyYOwna?7W3OcTYL)e~hLQ?F|aQKsYqlniqj0MrijL5@-+(S0oRS(%j!Vs+7r*E5_-{qjOFr>+vnY*@^-M{*23dfr1-` znrh#2>!=&qx~KNg&qkchRn}z(qs>dKq5|AZgo4GDI25sBiTA~M8N_huIURuV7zHR= zQrs-AQ~ts6)m+I&sVKFo@!3$qvbIAiIx%4qW->aBOPVmkLs1jIg=enhXVVN%@wv<) zEi2PffR}y-XBhu^G*@o$2qQUn#?^jlqE+V|+i{!}L?FTgIHyndF+V@Exw7fXwc@z7 zP?z`cRqazi`lNk0;e{QzzTnWs06FpCsz>Sh%pwy7`~qFtA6b5S@xEsx+G#GBl@esB zB?xwQN(QVo8@NEKtHUiB_gFApFUGmu$5@vM7?VP@O~lSGBtM)JnbLU$9+FR;D=~!k z4iHa=2OuyTX*uN0vV8aPP=LQOK8=e0Y6Plw}U5{h}T}5%ppNt^Nehk1CHm_Z4=w za$PH$M_d2Wvk+S1a3uPirqk8I)VnA<9;dMRinf0zGxp_8dGW4zpiNij&!)=zsaE$& z{O&`EcV4cFjySH8(Y>B@W%g}`mWlel;5wt^=)7Vg$!T1wej&;sk_1%q5i-JhwjFlU z(1g+Z?j&(>+D@LQEsee`4}}s0jEnlKm1#)neDFF4#wIvi+bNWQ`U05e4B|fKNQ=xZ zmFVul=V#ii_>iD>(XbZVjGXS6e>1G#{FMkZnVC zUb*=HxMJ4+Z=YX}e!y=ElwfPsJtW~wlNNRF)y-C`t8+$pi%f`$pB7wF0 zEcc2pYdTKW@GK^aRyXm@l9v|^(Ajmnmh!BG>1b~(O|COjC^9)Vcts&R# zkq~vSn$IvjHoIcO7^n%l-1&;l8W_7f8z$gn=e)B%zMf8@1oeqq-=1C6{vNCxKxtlF zq3Tk1kSSZHJ?W!AxjrshlK?Lp>p>Wxny+8;j6V8Vr;<8rR_Tsc@z1Q%kqjH+BWP|1`pJ}BA{5KC411GO!>E8F|h0pXc-<;GJt%)&Wft5gTCPz7nW3rdt zn3pbNAFY3H%{7S;R8@c7v9i?r^5Pxc?@u@yTIFQ~&u9%8#!tX7@Se@&`B<0D6;*9n z#YrcrS#jvU>@@$qP+}*76w_1qmQ^O;>`9mb4Jk)T!L2z{OniEF1=HrL)biwz6&R!* zS4?VmoiUYix?#J#>VaBSR4nbQX9_a&Thm%rjh)JM&nMe;cDB~78dyJ$jQFwn+F~`h z*@}lhAU;Xw+ozLO3pHeQeHN8e@CL?PlYwr}8@Y%0HZIjt8C6 zttcD~=n*WjA7WS;u&?ZfUiR@&V3MA03{0%mq8NRR1bYQ}xue+|v&tG$bzL8!No&HA zA0O5%dkZG|vbAP5%I9kkK2V5;gMr%N+e>F6+t-54iJ_Vlj5Nlf8g@SHOcix7!l+h= zUOJ=OekdbT%-G5JW65-8XfQrnxLuuOXjExv?as=Z_V~>^lzL)!LN!)~7GT8sH+8Jm zMnuUuFp{{t>9#ORLqkd=v?S~724lB@eh%1P84_v|9PjV8 zZZ6L|<2F||8UU@_cV5!c5B!*>97R;BHo`o>4AVn5q&~pEP)(yf)17N2T~pD1vAnsN zy@bbcY2u`e;PtDuyDrXLlr3WPF=uh9Y%GBhUAUtA;{`HwK&R4WwP7W9oixH=J|;R_ zTAZ*10>HdCp{}m2w;`m7>sdjFIGeuv9y8YF#b3Rym`>yrFSTh^zc^p{TuWmoeWKf{ zuz0t^2~rnl)}wtT#Lz+;t$`y`CRsjON;9J=@c~WxcHwKyZnZrIF|P|b#mr>Px{cE_ z^B%sh+~K^QBojj&VOFB5WDXr>BOS(?wWl+Se6Fxpp2Z=Yq@j2FT z2l|Z8X;KP4H-b7jzRbGF;A&nzAy;Gey>@nU}R?Jm&dwklVKcik~PRJNt_xmn^o9~(ySU9%2V=Ha{wZ5O zU^h>Z-Q!_^6b!}gYMaDD`^A7~h$So6XB3}>p6gV3^K1fmVmg!g$o#s`*!CHTD86he z8t2QLn}e?jxVq1cDQ~GCbZ`XPOF8kBHG5T*KS`;f|Bn6WYYHT>x?{ zfMkcJgWa#W^cJkG*3r~am_VDM%L=Mrt?g0_Mf9MIG`H6{T`!+eDuzoSo0YBcoWi<5 z+bX>LM#`L%84L!SDH?KJ=pGF;_*V>Oy7&WRyQ1m5P~+@3k~U}mJ(#R8y>A0*`lQuoaJ~TduBnKc<#nj zdfnD~Or5^gkZJ1b+TdzMXyY@Rrt9OiG|}WIMYoocuM}x(g=+0IkPEpwSA>qB7p1}r z85_A23aLDs*C!2P^c$XZjL8VDUyAr{G}~mto|Qgl%~8-S6cbZe$m{tu0ZA2@G(SZ| zM!r(N)2hvH7Nn#! zE0E)oX!;p{hc!Bip^=)yaVaK$`BG!TYkgA3`Eq+^>UllepJR=F-1IEs(PBP#5rC_- z+N~3)*YIQyE7UV*SBuiP1O>|rxBW{WNxr)v4%e$lL zPa0h}&ApvHkw2ZaFjqQX3$3^*l{Kwy_dEZTLO3k#j+F7YT9xynUA9;snAViVvypO9 z2jb~bdT$z1Bm`T{VQ?@6gYx;6ZWG^Xq-lgspa5NM+1A5~+tt)gb7v4TaBCqodF01O z*R%G64x;yf=dn_#5gc0Ys?6&GUwSQHHxh7BoVAzCz+QY7*9#>2+{3k{g}s9DcibI&ozN%-5lIms1?e47(O|X zRXX?F)y2M{H@X+I>$+Jx8Yn~!e9yCr?Ts34`!#(olUBV@jgZ3Kpw}|KqBKq%PTPy( z^Sj`=ZjCoZ{XCe(M9g8^Lr`GFkuTTWNb9KFoP!jDyooCLkdUuC$7z*ksYL`y$HFz$ zE&GsL9CkC^k0xu#bh67=z&G`|wGuJ~1qav2iPBI3DDh*IPpU@HN;zhNWOH{Icb)Vk zqz?SFG_3Tt#?4Fh#3Z{kt)=*Pw^B@nhPJRpZ$$(Bbr6sKnU<_h;G=h4h`Jex@;wJV z(}GszQOcoiUUzpR`j`Kk_1mpfE_xxP;&(UZmuYv8aT8$eG+IJF^ zbZ5GiwYvmMZ-K*7owEAUDr%6A&q-!vm$D2*vlR zK4loA#Lv~{m9v;IAvf1Z%MU)S7_+{ugD4UasZ)(u7)LSiXyc86&b-TNqe(atK^*7b zoOv|tw!>WlU8etr`jUG1?FDSC{Xd*UznOGWwp42UZfLW&n+kRR=Y!9LJ6ujHGYG6h z;s^v5e5M9${YL2bt#f2)jUq_y`R^c+Gjgf0;>XrctL0AR8kmw1+{JeF(T^A1z#^9^ z+;iN9aElzGEOX6vOS>VRz~XPOBoJ(yovLBnAVwd3V!nJ;6aHr?%vLtM#bZ--excvG zx#r0c{KbPJii&l3{j4Aoo!1((yEV?Uo^X1!3WxAn9gQ1*#oCD9R*%=hS6rIfFK@2> zZ1WB7U4-c|A9a>cZ}rQ4)gU=*q`ePG63-22ln4lXEG;qI+8?`EN0 zeo*2;BqY+#7Fc}-vktE$NxKNSVHTV>CX?5DeU-({4#JSw$smM{C{p=2PxUfe(c;Fg z>$=*keq%U^LA2GK=hWNdW%@nGsrfJ2P4{uLlW?0(v=mP!QT}WT?Jb%=fee_{**2dZ z=UgtDLr+!7z+>9Pq}*`o-Zggv~JF6=H$oucl2``jRU!( z0eqZ~4!1>Kw;p*dBluZDLj2lg&f6d4Z~l+JPNId_qPNI`rgRp|omIS;hA87`n}pj* ztzF0FI}#t>fC7JcBS6p2nrc1H)*2_`UDmPoKNrsGb9cEVSEmmCK3)6Ai}Se+Y^Bvm zRgBO#)QW8)Kg~gPaW#rW}{oly! zk4sQu7--P+yeHpaJdrlDY_Wb_t)1b2NOl48TRqnLb!84e7u#NyWDc=vnNTEl{H-q` z|D!A=CC`&&ahcR)t^DF*;S|Bd5WAKMxlUchDT7E?$1joBuVt&Y4Zj!BE~;?(iJpx< zd;MyYpwoR#H8e1G+ThW1@4tUirvDOZ!&RJSn{pw!s=YaD|18R`myv5`P@ulPevvgq z>VKYt-kk(})0LSX3EG`YfQEb+BsT)w#WXJ=Ir@#h}$sr)Rdalw`$*J$9HS5+oNT6r{M6OWocLfglp-Xjx9Qu>|efK zzgG<0SU1m$iHqKRxc<{*iZawjingHC|b7N8X`W4)dK)lk|FR3Y@mnG%P&S zvge8gTJE|6Tz)5}ch+NyPy=YpAZ|0Lm0@zMUw-~{DgW5ppMJewk6O}twE~xDCIIgi z=>@K6u#LW!^2lEO*r8VL&q0q@W}}p68oI!Nz|ON~zpK^&rxGeNGw0WQ@&p#)>iVYZ zu1o{YG1%+tuGPGak{s>=XQEWYfYZP)E-lTDi@G)EW^od5{HJndAzER%LK<_4W>hCD zw^)eHz7yWw+WFyfz^-XgTviNPbi8r{E*dqg{q>~+Si^m~bP3d}1fG6)-n(}-TG9l& zC9d}Cdc)FJSN3e#@=m&}9~d8duIvbkzE}VMFHi_IvwL*|gGS-3!xvD)2~@?+Qr((= zUlFu?YPwW-?5#~dpUuV$OffyxKQ;yb{~G4q*|8@r6W9+Ztl7&cG!Z?b`hmq;+5NrW zj{$qYF^}Ik9tDjK0>?pq?RdK_`tz(;Utey{UIVIF8{hk^@9TyZ#EuJy0pa8F#X(|n(mI7#_7j^cOl9F*W(1slw4>m z{PD2;=#Ik2pVC){1NW}A%hpxoY&ghP>08))bDF$-S;StnQb99%#$*KsjcR5jD z%~qLv7A+7>Y>kz+I%$3cmVMuQ5A#{qw5tD`f?5l&04+gY2Hb?;XYuif#rr*t@OAF?qYvBvtIY1qaP`XF`Se<}_ac<4S45q8Nz2>4=j}em z|NnaU#f62=al!T4Yqtcw0bZh9_}JI{c<%Q5;41OY%wL&3+rGTnS@{oTLH^Qp;8m(Z zrup~w%&;g-0`*-$J#e3j&u3?tW{3IAHq*VIG;zv{&A@>gm+5-3N!_|tN55I;$Xmbp za2Axjw@1{WWrSIM=v5QOB2ucYdfuPRlgq%sc*xVmF$B`&0j_{1IBkL4IHJW8>`@1h d76O8T|K(-d4h8S6Uv(Z7H=eG3F6*2UngBrP@izbf literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-slow1.png b/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-slow1.png new file mode 100644 index 0000000000000000000000000000000000000000..bb3b53d49dc84a6bcdcf70d0868a37b65d1c09cb GIT binary patch literal 138607 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 z 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

v-HRImNF1JpW%T`F}@H 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 F@^9&VcbWhI literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-slow2.png b/accelerators/aks-sb-azmonitor-microservices/assets/dimensions-workbook-slow2.png new file mode 100644 index 0000000000000000000000000000000000000000..642b0001cdcdeaee74b57137d9ba6ba9a44f28b3 GIT binary patch literal 254207 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

8=08E9sgXmk;D^X5=yk?jfYJU8 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�N7J+5UH#%^#ZAV;mb*J%C57GeZgdb3$s93sjRd|xv9 zRPs524#{JB@y2ZZHFslo7^X#4#ykRRH7$F1p>4a*0iXt z{>3Dtjqh{ORf~FES_osI>3|-_`u0u0cKFYIPLK!^`zZ)fW~@mJr(E_cLeACk{Kx<( zvwYEBI=HEaFSnY|FUX8@oy0j5+$QzJA}B=9rs9P{+z!2H21?A^LTq(NCMaBIuCrcV0RD zPY_S+1CFiyRS+wz1^1|@H56$9iFzYYJnfHW7)fq4D_t^K&1nwMVI~_52^yt8kgbUR z$m=SPjrfSkkTK%fbN+lZoyX}v2_RpwO&9q7H=lhng=D5vc+uZ`)IQPMXtm`Ag=yCb zWV7#2s#OWA6LU}Q3M-pR-ZU9XMUs%zrU0fD*TTPmKSDb3yCJHPERH)8`mD{_e zkAg8^R~v(d1A4+!lScHGUwVCcDZZdkh;g4UwNCUO4()HHNQ%CC3GSDCpNq-pumzpD z$j~5gG~4vYzL%-RR8H8Ix1p9f070&i?#8T6RODh7PSUXNPzzD-B@!yxWvT>TG~j>o z$1Y;@x~)yM>Np}_%-#orCBc}`CaA{zOAS>o@OYM!@nl-jaOJ+Q3x?l3e8MNYm};^b z`g-Sq7nWpIy!x?A<@_chf|Xs9vti2V!zt!9ZfSI`fMUV>4zN5aWI+XTvSGb5XYl3_ zp42Y1>1hY`X%19@jx~?+<~${lJv}CylIAF9&9l|>{_V?!~FcA2S?^;OySER3Y~ zI*#it4%Kak<+c;g+>xzR7zFq-?EAM$Yt7WhmHST(ieFZV`&NZJMt2%DdvXXDXY1!% z^EUNFmj`deLla-(RQ${#IPpu?aLsJ0l2kb>n~`6&%go;==`u*a*zGB=-Vnh>$+Sz= zdl}$#|1@#OIjM>#AKcX&bxH5BbIldaU!}z#b~x)0u6W8B4Qg`9!<^6L58HrU(A>l>Qs!lBqrzXLjRI z;qA)HsWVn<=4TG!j)5seyu^f)=9-Top5r=Ub$Vfc(;KszbE!(SB#QI$L~K&J|G^S- zR@$OQ*U8yv|FWdWj>mALG{<+(h-1a#PhpnW-2yiyfoR*`@TKP0v?mvIBbWi3*5JBF z8NiHK()ytCg5!7Tz{(@lLOZVX%hRoERMpdDcwbDRtya3(y;gDLLY#FAC{TU(WIvAC z?e+T3&VKd@&xUwQM&STCFu(7-3(N=S5^;>cQ#GFa{?kLtvTQM`eCiThtl(X*t)wlior-yh-wuj-O4uCXPg8${d znW+?9YN%7!Wp?SY<1glCt~zw>)N6C(H?IiZemI|K{_|aB<0B(g23yPMf51|}p#AtE z-+$705HS7h`x4v%;1PGf|AxljPvhHR@qdN+`!B%cf1g%-m7z@kPaP=+Z*DE3g9z&jTQ!x*&3)5@H;|DgnSA1#$P#^uC_h zR(KevT?PY(CB{KSq%>GdA44)f=#J45{jEgiIJ5#1b+sU!4vJg#fy5AgrCWyFyxr>9 z7Rl;rBXs|f=Aks7HvlQWdi(9?`yC~`p99a*QS5enhLS_y77uL_S>eZ?Ji&6!0z&ob zNhcMj=SRUnI&YotAMfHpaW&l>G~iP11$WM`aU8znDtayP#i3V%i-h!{s=Fl*Sh&?qjP?=)0`YA#O|!;ltyY z+DP{281S_tA1fXjbO*c1))(C`8TqA{GKAhhKnpyv;q^mIHse6>M(}qv1FUBs?M0YR zeqeq~9d9IQI`z(}yQ;-`j{W8rtE?be6IhS^+Y$KFz*f-*_y^+pv?P#be-B0J5J0EC zdN;5k?%)Zpv<(G$mXIOfYY9N^GClv_@vOK^mjR-m|T1OK&^`hs=$8}5}0uWa&l019RPZ5wjYq_WhR~J zP2uz~b|miWA8LY2I1-_4BTq9RkJTQ@c1_kEGltB@Y>(t= zp7by;39+|*EKiBan`}pqEvhhCkqbHzm=bABCmQ%l{WnG_tkb-2?J_P#Xc|a5*Kn-H znBufB;fARaU|wkYVYWFZTUn4!aF}ge16@7@|G01=^!?f0nzGf)eufL&f>&2!j2O}* ztM4LkmLxF0c>LxgMR5OtWiS66xI}JOjAl3Za~?20F=>-oE&8ml4?;Fua1KSwqKD=) z2XHEwj)uah_IPpi(zDxzQgPIR&;g>ZY?Kc+Fnj4U#NQ{J|8hxBiCbtqaGd+aqC2)_ zN7VD~`OMEg9;xt9>o7wRd$Yvrx|Tx|XkNI_G%0Ba9RDLybcuG`OSpiVv8>Q%gR3k| zEEdTFZ9X*dL%(sjyJNrZ?x*=XEYDnWb{}!n`Le7nHTt>rK>iWq=F$?q!Xd2ZAMgB- z38Q9VS%ST(l_Y9`tD&vSYAYe8cHYfaG0MBJLs1}g5rAQ9*GtAi6SYASt+j&ei-{Sz zV9K-$mf?Le+MHnS@$g@RhYY%pW0)7)W#O&2A~}Q;X)S zXu_q4(;4xyYfBOPM)uh*fACoU%R}&zlZD-aD|yW+)TmM4nBa|6{sSR@ssUs$LqLtJ z&15kR0LR=~j@)Fzpv9aMILtOcXJ7fl`xx35tm&V)fPzr}{fzeu=q!Gg2SBa|^jv@y z!C2l%e+mJ==25GL>HHRg{DRKPOr&>Wp2s$6klu*_%_024nCHbRgfgfRvN&aH07IS_ zUNKC2p3Q1>Z%#&77y=m6Pg9mEn7>A^MJpK}^)_5sp`qF?DO}LCY1z?%1|>)R{Q7gE zKA?rIcLyw=T|U2EwDL(>oC%n7R7w06{sLH`W5*eYkG1Z49o_*;Rs`f&Oi|dVi}6_A zE92GFP`u7)+y!UAJ#X~mINHH_ErA}C@z1S^(*Z`TVTXKHs5Kz6-iE4andOCkRxz*Z0?u?+j?dxYUI`Thfe?{rQCW-_+MHYJW^U)Em^kG&+^t zF`)Ao#HsVEFK~tl7nlEnG~y1Nm(bbanez>FLD9iWdh4Qf&&KlhogKv+e21JS#~f2a z-?fg`S&>?F3(R#lL;H2uJ+#0fsoxaQ`E9s$1F&2qF1u#N1TUfxl*Yl}(-|b5aFwp$ zrA}jk2g510%aqMk952{-=5bqx_K8exF2QZoGDq%q^5Z{r7N|-NqXfT_PC9bB=A8N@ zRTOAh(UB_m5CZq0n-Qvp>$69(b{i}ix(a)9X__)`>fBW0m2N{q9IPyHGlrwtI=tfy`7Y?~jiUEq`%H-(QTBMd--A`q-MkO#6Z>3iyMK)+VE zWT@3p7C2$6eNmT;g?R%tQ817vl^8Qvghfr;V#~z{*m04NM*x{<6{k2xnp2Uw^#K*P z${kl;u1*HzpRqL(fAbm85y2#Gyy)PBI|19*ERZ+5*1o{Cr@NO&n~J0@usi3N`8WD6 zpW7#}$7FSaJMl)cYtxBW#oqj%`>>F&0J=S&z%Poz9=JGMo;CN{x44 zlyleaz!ZYl8|li1G?4lpf7+%$lN3}}-KQ&XTHY!R2f!}=eIwk9At_y2uO8J) z`#G@ma8t<#bH+vdPaokv-*)%lF0qHptt^^Z(ud`l%kYO$A8hYv2%Is|eHDd~cc{tx z0E~Pt{bVpkv_jzF@IIR{vuzJM)C8PMBQLNo&p)E?%4>To8uu(y4$=fe=5qanY4-^A zqHgm-xZ$sMxTvDl75=jqhUmI)qrg&BITF@3R35!L{xTZHAj#cmk$<$x0U$vkd4=Dk z4Wg#r8bdfCUUu*%w@(H0;&|C}?n(*8G@E=GwPDNdY<-jG8@aG7lX2-`c4kE9T4cM^ z_2%B@2~&*VO}ki1EG5%f3yzh2NK*b49F`@Mcf-Vs1vZNa)zO7*sT|VR3pI~E)Oe?{ z!U6M8e#Zo%asZJieLpoR{l*y~oOj<>c`r^_3xw8(EwDY zC;t=gIHf4>0rVNsZsd_i)W$r+BU$I!I!m6}xB0!1EThF^$q-aLHrX;tGN`38-)X=i zG$ubb-#rTzPQT8X?Vi!bar%ps-fXczjZvp2Y@4g?FMb52K>(GMX7j-j*Mq8-R2h+K zKY+xNqfxa7CJ3_W|7Zzvg0k4Mo43=N!R{lyk6TF4i}Hu_fv;$B?3zy;>{T z9#sRfIsu*8t-F!7p&c*$jF4Cz`fEr!jmI_M3L+AW=Gm;M!1)^P#*TzAatVHIB;qpLJM_^v&eRkS9DHKY zkArW8JYq!L-TVwOP;sy)c>Qhgsr`rFdQti^DO~aT2(FZAD&q8m$GrOcm468UfQ{Y>g4!`iz+4kstsBQ+QJD_5 z22F+eQ=rUZ3jFOTIU&tEcQ_&ccFo7Q9m3bnNz1IgPt22bdaL1+-v(l!TaQ2`W$^6J zTb>W_gTLJ$Tfcf0C-VQ&z4G6$VNXyVYd2v$+oAb~$ZsD^@xa;C2i)CL%}M=uHJlq* z+Z+r*VVDIfgQgn3Kq1gcLIuK8R8R=ie+Rh6ewj11dlFJw#@qg7jyWXvCO(A68p~Eh zM>iA_Pem;?IqLwl03?~_U67O{X0#s0S{E|NP4`lx%9mi&)Qdx7h7ucQ8=H9@<|O3X4Z_qH9_yOjA9}^{W-y z-MW%)fG#|NMmQ#|y$J(8##Qb<5zlkxnkn%o0OS6@DDl$I3l%^5RoAmSHSS`i_7!D{l%r5GnLXO9C1!Qj9=NSKb<3EqmBn6gK760P6X?Do<( zhQnEFEPLx)L0t5iWdJx;@|E06==_SM~GoEj$xEy^o zAbYz0rUsjOXRFYf1xna50qi@p5e^Q$5x_(R@g_O%i>`R|RZ&#>9uhDCt|Z2Amr5Ux zykUcEvyCgQ7Vb{-+^fERHkb&~1mo-HI)v}1TrVwlT@%uFU}w(TZho`PZ?1}X`G*xt zpYd=FGKlK~=tcn~>v1mVruP2CE|<~ia=nhT28nH$10IVRm&MOVw70=)JxiGnrxIVp zK*~yOt18VP@u6zlGo(A+6-Qf!b!81kq5U)OkXDzuxy+tuZ1Wl{oZKB*%hCnDkyDG2 z3pdy1mn)X_XjE+HQZq4+-CAUu6=oFW`dRw*YKq?^Xyt+jKJv*d`y`+wD4e!O7p9-z zt}3vrD4Nj=Bol@^-B6TS@Q&HQwOWV)McXnCh{}sE4ObtdU;Oiwzlj2O0)D8v=$LKI zI?`nm&!UWE!&LY3h8h@Or`f=gAO1F9{53$oPEb~Z@oLB3Q@2wt1Fef00fM2{`<}Gq zb%TV1PPs7m`H&RqW3>m*zZJ+WldblnweGHvBmiV-3g`TqSp#9+AFI-Brs$)gi0YzI-|nTVs*rGHA{m#`0+pRwi>|OxQq%J z_YuG>p>`G>I&)44DlI^V7+~O2IGt80ESqlAW(85EjqXBekL0#JM0`IFkkI@h-mrS@ z=WlIv{(Xmw{{V79^TY;FT>QcB{0hTH-y1dtMdTyY=hj1|0Oj+^Zl9-Dmy8^Lx`kM3 z7_D^*5@ImxrnG3UkxhD^TWU z*+JJ=Lk6rQQKJ66F*SgZwX5DPcPuT`I_D@um*{=;i84KS+G9f+L~Ht^K4ivF#dMsS zlNUAE4P;HK^b+{Xe(IqRDV92c~v z%;xv*#3H{R$ISI%%AWK$YuO&hlgTSvaM>NeWtr@;B6klGXy(#nsjYf8&g^SRf|!V; zd7>Mte_AS`%vId`RMStU=cMQNJc2A{^WQNd!e4|H2VG@Lom&`Yqf67}yPO&LZwF0s zz~anosp@*>-4`|uifCi1i=J|IeUS(I7M7Z#gsHybSxO?018aW%=U}B)Tc{g-Be|Ae zQ>5>Ufzv2{ZKBpWODd#Cwm(YS3Cq@Bh;k;kSXJ7k{iHSh$~=>s@n8p7>AK&qaTejn z3i#6}zReGHv)uC+MfOxWVE6~@4dh-oL~lCm6xjO0R|7yq>|Af1+PoYDbir*q%KKi= zD8UCGGuos^St3`d{ojTSjE+_ZaZyNWHKrvX(>FhmsE4pB)io)1+*g^Y>wm)=BD%;g zDi;2Fs~q~RYQM$dt_itc?I1SD`cRqE&dN&`Z=VJ^R0v+QAE^>+iu~)E`r_F;D$~qI zi*&#ej4GhXW>mW!2V2LQ?p#1=dUPFeJ*S(i@xqFyiOPIsp}t_lR9G%D`-L zlQZ_>R_z;ue$)hxFU))%@*mz>6S}qydm0`tzT?={gK34Vh|OUL$V%2oFxz<#5T)OK zK03T0a^#XyFS2aGgCo$fHoEs zLjCsi{KGt+iSA9&xXP{}$BBrfR1hdKbuhNn{bS-6`Slcw3tRSera}J=2Nvgbf}c5W zL(zM*=G;!cS4lL>ZtGxZLe{HQS#XpXV7|EKOajp7n<3qY^71)qEWPtH|j}`^-{3^r5qF_)=G| zG?iMI`Uh9c1DApJC!GSYA9Q6sW<@s=9Dkm-@OcdQ*U(`mt%9tBsK&_gH$dVvTQ+39 zpgSuqMjl~*_o#S-C*X#qba5Ts*KO~~W3;K`!2Ww#bWhdUJg_W24<48A?uqF?*%(wV zxGCB+q)*Ln4n*@1clBIgUB^#MP&hd=XvV|`kdMHrK$1>(Brlb%*dM@sBe-VPKmpq{7kN(UjFVOqO0;9 zIkR-y5c21)G7+1a@*k?qt3MmPd(+fGjR94L9X3%pv+MP z#jp~Djr*Wo)2aD|phW77mwJJfvvOMLm7Xjy8{em(girkkthNd~clebr?SM${4Gm|v zo9FdfKL5|Z=6m&+vLDb#Y>; z`ZzR^%x9oL2SgTJHNl%N=7{i5=WW^oj0HXND?H5p{5K)$zpoYjyTAR11>MRXLS#^v z(p=CeZ~|Oi#L;>rhmws4+;$%T#ILuKgZud|fWcmWJJsWQ=eEwa|6MYNHQkpDJl-AB z*Ig#*5HbhmUVuEGy8c_q(<3I6$A zCL4HoHJ;471!w9;b{+X)xIcm1bARy(fP!uyf(kQS`;eRk;=V0#seItz&XQUGxZ4MK z<0;=iCj+0_RRs8>bk{BU$UghW8GkkVK~0X4w5paq-cIH%tNZk2GyrpjmTW3%egdmy z#mm~#WUQRBVUgEEg&;o-@r~I6w#s3yl5`v0N@$4VQrZkLX?1;kl;Nfabf`pkOSW#qb3^Whw18fgO-8`>UBp{E z4nv3M)vTgiLm`MvlKnj%2fbiHW@^T~ZEPFpz*YjE`1seDCFfyNS@it8kOQouMg>|W zywuGquILIX+E>h!7dR|AP92neoGSM`^?`v9`yvbCku z;ns(z=a(ewN_rx=5Y1Mkfh0j#ixS|$owSQPEc*~5xAlR6wVwg(XW2iizI@`671jWj z>jsc9&I%pS@w&`NXM(TmCcUyDuYuRkXn!GIYjH$3Prq%h4F zv;*~OG7DZ!)`45SIY_kEbp~@s38`@t+VOtgk2yVh+Bj zDDzwLgb&M1Wh$EXJPAkv3*E}~uZLIUOR@$Dj`+nfpQdjpcTCIE3oXCKMsTk* z8_{C7{9EpzmbDh&SY8VgyAv1zYG!TRC!5`FsKx2h!?+hNT8XZf@0DL5ftX)j$<1JB_Yh_ve)Kwq|Dhd3(|VjLZ*f3 zHFpwr3`>mxMw%u|QpmfL-KSzjf12;(l!m@^{ZJYaJMA^Xu2sdi{$)lb!RfU!)9hz3 zvKhKqQlop9mNl?-Uxs1;{cMffDQj-`AZ3qm`_aSfL+7>MXC1oGc~|plgTd^&gZwN| z0;QX_4^1`!0vHcUu4!;YZ@&eh(^g22fm_D1#B)A+75O1|Q6`3Cw8GKmt>`eU6>@po zqmf(N4_85KIM{K{nt5**Q#xu-?bemEW(}{|J01792#ZF!6B$_*(y)umo2wChLowUs zu!GxJm9{YpaNIpZN`^y1ShM1x)aEwW#%S@j!TQWYCeCy1Qp+xzG>^?l=2{t83S7lE zK;+-&n%JFsv)wKO6`;Ox)ka(-F1+8SV-tL@xR0|6>%P|3^^4;K3UnI+VM$y46_X*Q zywGQD?3A&C9jb0qnNYfuWD+Mhorc-#S_$UY_Y7j8uY_u-u>eIvwBhZ^}DG3eXZAm~sJ z`7^k!plerRLd{E{@h7fkhE|ScEG?`w0yeqLnv~Cvsv=QXFIiK!S9%*Y39CnvPCtd` zx&bk2LE#!Zmk?bJpI7Vhmp4g!kDqG;!M47~+N5#)M6f?OL5(5ws~J{(xC7#A3XJCi z8hT4elGK(V?bTbzFd%;NkosW5kKjUjeo7Dj2Z>)NhU3gwV4csda5iu$y24>LY-H2$ z)oNHb>9q3#g36uFv{`>Hs^bK7 zBZ8(JB2~Dfs>s=0n)gNuyU;p!UNJZ3e! zEhwG)vMk}UnP#e_9yN#0q~_&Cy30Aqus!jD^pq%=v8GOThjyy$p+Vrk?ro(wGhJ|P zpu-^^c;Uteu=4B*J#Q1;)3zY4pzihdk*{GSJDb^y3{!bB%sx7@({N)YSsN3IQ(v?# zJ&tdHN4$LKc)X{RX}L)%Rt>R+AWi<*hjx857O@^gpHaQ4Zt+EVCc#m>id@-Sy6XcY zP{R66IB?+`i#k>l3j0%UcrQDHC6+N&WBheCtmuR0OQ*yW_?t|(onjc$Plw&7A<1uR zgHgXd{G?~wZpruWg8k2w(#pcrGGck%+&*3`SM6`*$U(2rexx}3mb~Bx6?oGNl$^)`djW`#5LRb5H)gIMEV&{m3};*?D~thmk6KP$HP>|MD?Cl>Vc2gkRl!O zGQ%xYm%kmvmJV77T`(D_Y)&rKd)Etiqm$3inE^UBh1IZexp~5I{)W{FdD(l8%Duck zM~sR?LcjT$vR!Hy8bFL(LBF0DB%x+h^tqg=K9kZxz;;=itVR&wEt=gJY8unR@7kKV&P8jlc_ZZi>YK3F6?uZ*Fg7~)om{&#dIJaB{%@4{mQzowvk_L0mBA*fg5l&CyA z&+T_LKb}a_w*+44(E;qV8F`{ciBJW$ua?%N)a|NBUvIITb#AI3&5Q<50$yz`2P5$; zaOw9Uhd=Ilb(yuxtDwki&m|@Rv^c?T2X|s3!f5LYZtdid)3^ZnPPI zTxw-e3hB|#?TF9*iH^FIfC>j84MbT@cu~c{3+4PLApBE)TqIpI;&h@hV> zcRXXBqX551-3nS~NQ~yao>o| zKyMCVgKO)`bBo%zyM0FB_&&YZ`cC)iQ(L8y^ErNjTf+;#%^#}HJToZUOsj1Na$5Kk zN^t2Z)b_n$m(#A8dq2k^YPmFLq}<^3Y=6qYI5AL~tP~<`Ma>(;ZokCiF>s)9)!R(Iygx@T0N%(p?0sclIOy`6l$A+Ra zNzcuvdv6HMqq-SWJsMhsd-@W!xQ#VmnN+G}(Iuo|V1PivNbJw*@`$WhqR3%9P6*0T zHo_807c!ZIP%Nx_G$jtkp6E2Fs^Lo?`wwKM7YB$=ocPlcVIf8U!N`4sc2WcH;Sq9y zBNMyI1>w8STQJU=pWzk5b$oVSSfh1wzhR{OF|aU42v*;@SbYbfqFlO^PhOw1qdMxo zALJaEH^~PbT$qu^28%BzXY)!w*QtOtB1YW2Dr4AR=F)2BzE@e2yABmUD6pmL$b&G7 zTa}w}5;@c6eUKjs>ZVZ;%7z7-&u6$d`u5lHS&+INpZ7LQHS#OB;R7<0KFp%#Iz(SS zBg)?h`FMMGb3liCtpWSFM`G}Rym2>zovkFB!hZ&suse&J3t|oZ1QrlG&I-iMGII&` z2``_~s2Z>xM_NhzxeIk#NHvGorG2Z&z3p8jvA5gaQbATpd{t@zl^lulx~Ot|qCaP$&VVNP84B7Ogf`ap}FsXtn2TfrPiJ+@xC!y+g% z%@p$Y$7Hdprze~smm7I=gPmU`DDkt$w?4I34wsHxGJ_(7h{e|+0smI)`cb*7FXQV( zpo}bd{HIjZBYen*1A4Lch6fETHjTk3!2bfLzP(@;FLhoyv-IG7!pTR4e4LKuNLHe))4#*Qioe_ zeWD&JnOx)l`Ff*2DyOYqf`9Z*{Pz<%4y0QS+{lNn&4Dgk6an;_akaqw-hu(x&oV0m z2x>1vB?3plo7Z_+>_Y@>82zns1s45((n5cKqPYL<5Vx3}E%rNpbw6L7X2-@`i6uap z$KCh*|4HvCl#I||Dj+SL%UIft4t50z8_J)1mtjfV5qCUgbKRTs5jR~Ky_^F@a#o^% zt@JAK-?Y6=A8;s7!~uKVRodyR1a^kQUSbIpMuDLivub_)n`|av$-Yj6D?vOFu;qYf zU)`8bJplcM3g`Wc!oCMomVR8t zL4Pai0e@tFOi#?DV{6iK7<_qyPYkV(*LW<4 zZzIe@zUb#58{`fgr0d@*J%HR0cYNt%EVGDFG7`Kue*JS7ZPFQhNMdpdDER*rwLR7{ z6=JD3=8*+8?O2-1Y60fYYzXFq1cU?ybZt@ri-}t+SihcD@> zeh9un;NEkG_2TH!R6Pn|W0BAYwblT!?-zcYw|C_9?jYXF>wggPD&5{)9??YlxEKbYa>y&;jXamvzVPH>T6sS!RdF! zFY94T)<0zjzX%ORE>l=rm*$cwIEi)L(ov_jr9d-IgMWVDZMfeA1jXTM^WK(aj~%hk zGEdgN{PbWhdqSxfeaI9}SO-1r^`D=+z}p{je8$Kgbi@Q0X1~?iCE-eH%FMNe&dB5; zsjBk!=Rx_QHc?q)p8O5gca(s+z;yyt?p)#E^st4mCrXy8okt0*clp|w;P;dquOua? zIBtX|5wU8l)2xGSY;6Yv0*UoBsxvk0ZOG=f@KcriX%7wo(KUoP=uwni`Tdj=a@Uxj zKO6ajyQnZ6WhVj zOOsUdERJ^xf$R9{YJ~PnXcTexp7_G(u=-k}9Y3Dw7aXyt9yN0=t_D6?OAp$*dYG6F z7>Qe}v^3?qI?gHl*XaXIo1#lA#nP^tZ9m*}$81vZX}mDw=cTQbbI9;TQxIm;mAWRN zJq4r+>wBNJ0;)bdQJd4nP>ifU8gxb-T*>-)Az0D9>ZTh=xAYqx=DzC;eFRC@fSD0? z)dEeu7$7*H#hlQR&06oz_#f51cT`jBzV2^fski_YD5d33!%u|?KF z_283|TlJOndsH$DhdHdwMjWKT(|yPkvHjlJZbxpsud4|^xzj29*9!uqFRFjfwUb&y z!D{6UN8<~#!Z{K59p9vzrYh`y3YO`0;6R=)AsHQ<{yjJ|qIL z1@s!zDYB*?j|7*_8t;7ZA2r_fHfgn6ACTR&aD^HEo%x4GYM>2t1@MT^1v4|WKNHW| zoZ=r%YM+N}O~B&7x$fni@ky)%dhYcA=@V=8*+d!Ug!{OSaZKnnqUa^;`3&Dt%`Q3R z4}zxE1@4KlaQVE4uZ^7A`<(DrHPO!3dzxkB0#^g;!FH5RVLx3(>DKfE{Z3StUBQK2L#&AE>BLGL z$D*(}CBV5YW#_U#y0W!v(FI5`cGYr1ItqjKH$XoZ#`v2!aF3dUyL9N80KH5OOs%v! zw&OGajIfzzKKlsf^yAe8V=P$Uu-9&>^Jnzeg{YQ8qz&nO7k^02P->>qC3IXtZ#KuL zEg5Qn=zXs;#`k+cb5W?+lXM+cEfdF>)u9u#KMQs?mm!Hoc|tASo8yaH7FFhvgzdcy zmF@wPY|7~N@t`2&(xPtBRlBD3MU`##-9v-hDAk4Y=fLCk9Xivu=2j5S6F9$qxOeVf z^>de=eb|t^Ls3QKnuFy$6e ztbWJ~v*n#Tf5?-Tfyv^O8?CtoKlXP!%-{aaKMO_hQvO%SoS!R&3KI)ZNGyS=e4Qtc z|IP*ucYW7&i+>REK>xVsj(-#HoLG*}+RRCjoZid1c13)*s4wkOMB-YTU;o(guC2i? zOYfM2vGTrasArES?1#Q>Q}$P?70qdtSlr2)n4~4bX%CD3dR!Q^K{V0>|c@CL6 z=lT1PZvTydGjwk9D?fXWVh87OgIf_U{cZp#ldALLS5GZWV-VZoGI)H3s zG}r9Y4OMo-1#qrSFHTX!!thB;+!e!WDz+q6DBF7~>^_ z4V6#RYNblW5K$oB*G>Tfc+U)oGD01}G!N2YD(ArJfYYxQo=jeEKy5U5fC(m}+yyX! zZ&D6*qP>LR2vxOEE?}Uw-vGuy9m0Sbz;9bx1d<1q(Ec0-|ACTP7Wmr4z0x1rC>Xm# z)|6DHW@ysynj#DA-jrJ{Nzb}^;2w}d$W`+^=;=0c4h-Y~D+w8xh1|`8e`pkZgVaQj zw^1C0Lu^PWJ^>#lspWX}GBD!RzM~`pp8W1+Qul$Ts`Gb|MqO>0`D%Ol2Q`3}(?~mF zJ*Qqh6?WQQ6(%J**f2KOZ2?HD#7i(D`uVA-<>flUN*^4s6rXka;yJxhg&itdDrlpS zD^|Lg`RM81N5FLADYz&4BHDy9nhk3>N;<`ifT7OcM+K zri<3VY(m&-s~jUO)Lb>^XRoGz1rJKWH8mp^J>C7wLBU-nodqAV&lumr*no}3^(KH4 z&Gd=EHKFg6XEph8`r*(ETM^LwxM?0cX}hsNC~T&%$pj4@EBqecp$PhOCo>HoP_jw= z+NOqUiV)bH3@vCOXp*b1<{nO}gxNcX&80~or651N432GEK)q+$&B zaABkCqSRY&Eq2ol2Q4^I-VD3@G=b{j8O>5&cUxTn*yDvj2M_eF1sGi74u4i zLg#_QMEMeXyu>qIJNZs=x@!W@ZvjHj7lTDmLS&@;^q5d{5qr2|y=btY3*G=!npfH( z7vo}F7uD!KTV2{BpYsZw*1xCP#ZJzHMhJ|7wk>};Oz<#|C@&Owt%)dyhHZt#wfR4z zaI??M8lW9=nEGPRQ~0vN1Cl(qOb}obbVx`6qU4~j)HQJc4YDgyuB&p40zB0Yp9zOt zn!$>z$yYnyw8wEt4((ZB7Ex%NdEO**aUKAPI>BceSM4CLY;U(Q*Xr{#yJZG|9Ytqt z7xrBv;-Y@L%FPuEKrB*QIFiCmqtczkr6mzeT^|WVlr01mj%~~o&vT3mXN=B{#f-em z=qiJpAM}1XMCC+F2M6qk`U&WfAGAXW!j+@}n;v!>jLc6R#BI~2 z;_cq1O!ua3IMd+QYf}MLjpGkPb=MgKE6z@x{0=-&c(G5;d$kZ&vL9`IN4yfK z;Nf=XX-T{#5wl#po{ z+c2VY`lNP8sol)RiR^gdNTOFw0AE*nfWnv2L>4zFFZXA!KMA!Q%hF|88C6}dVk+D0 z+L!N_vDPBQd&q%XPBZ5yD>Q_upCEW^GD9Vp={lF~atQaQQW7d`GGn#`k_~+G`tiPq zDc_r@4d0B#d+cJJzup&S<_T9P-6^PioNi@4909N3Kc|-;s+@U0(2u&k9+Qw&qEOLT zxlLYrN_MXfvgAxfx#QcoVokYtCL$ON56^zpNPJ`gJOd7pH*why;DEE(in z^B9m{FQ7h^W%x8Hd%`aSMqYyvm{-*t%o)XbOP)nWZ3de!q>`JzUab6>T;Z!eUD?9_B zpYhNdx=g`377kzauC^bg)AGn_AUd3*&h6WN z;h`*A@>$Xt#Jag^AZls2%|Joie0ZUD)Xljo*TSJpngUyr(-u8DUz7SaFH^y#D8Snv zl`ZpX0ifUN3=}l(R!HfB29BC9PcGzB(^Iyyi6yi{P*Y0tdi2jjxGD7N%mu|*xIm1= z8D{zjFm2fUn#?JiHu* zs+?E=-QssT`^?REOYIyl$v(rB%Ck)0Xp1#f&oMGlyB6I8r}zN1Ty1GfZWFG&N*~Xi zsQ${RqD`cpR3YVcE-_XX2)C6J6+M`wlhwj)8Dshj*-8ppSqqocyXyRfu^Rklda&yv z$eCBx?D;hhFTadph#zxW!n_!Tr$==b55kI$Ye)kS(*RWsCwF3J+Ke zX(O@XhLmW+a@&u-^EeT;1e@ut0;m0}YJ@{+7Zk%~*+_)TS??ez1$ALjjab!)SVW>@ z8nsWAZY&xkI@~By#^V5ZxXLNV;r;Y?c3^1-Uw!~Q{IS1VNwyw=S?Un6bQgFONnZSx z)o5T;x@A`tXsmRk5Z06U;u>tcK{+~Sc@qrV?PZKpiJZfdB-@Q2pZKL2TPsG> zYWcWNtI1vUO4cKgW$=a1P?8WArVjFL zyi7M(QnO1H?DVo-OIheX=XE(FwqF}lf?3=K*A892PLe-brq<1q_0T|MHd9CHLl5KO zvk5f*#_Uv={Lwe{#G>L75ARI!(T(z}cXClz;&zc} zZK5>mSp?OvXiq1S-L=W?8Ga*#)773-@}0#yb-%v1mbc|g#m5q}y0Xo+Rs}bLo&f8w#0|7uSG5{vd)z^mB}aHmIm zEroCOH;=r*!N7JsaJ|}_DcDsJ`kvq)#fewPFXkpdAUV5aN@LX~wKu=BsHR+E9x}!3 zGKEa1@S4U)C7&=<1JHy_ux@SPY~O5T}u$DKIVzEqO@gu7~dr@3CS^KNC#&-ULd#S;szv)bz8Wasbjc0$w`L?wIQXEDq^6AQ*u4@hf`Qrl!-} zg(0cMs2I}Vd51jIZPkLQ+^I|dk=z0PdT1S3ICTGQ+?8@_0HlQK*uYHeAy$aitOU81 zx9sa*U8pQt5bwinVR1F!iHQZ+T9j`fI9Zt3!uVQB;4$$|Y}i#7GfT`oQu$=0QDU~w z_+uEK)yP*njKsP*UlLl%pS-jS z;-wT`&zUt$Li1oSS1SsJpT%wv0UwtCLz^V|-Ash&Pz zF*~08W+IF&mDUIqJN;f^IK=`5mw14FBNB8 zbgBmkFi3*t3cvUwzSFr&y%5}kPU|*=vZ;``69i2w{?0rFV(I@1*wX{#u}Ee(vYhxD zuCQr+ln+V`>8nqQegg@dW+R`5s`X}`XZL#TMBAzW`c98@Mm8YJ5Qq;TNkJ1~eD_-ssHzA`@QmqGtz z46!l)rLusM3tZ0nNXknKpRQtDIeGUd9`r!y0N88DUy?N%St?O~<644FkyTJF;_gkX zuo!Gl2v!T>BB!KasFZ?zgr&$RI^#-r@CfZ1crmZaRL6n>|jN0PRjdl*DCei!j&_P+*SMgcT?1R&GPc z)oO^5P>w_uv_3XHZfiqG?&=&FPO)tB3HO_=+jb<%&5n=8mQ{@>`z?BALc^}*r|WI6 zJ(-$X2)iPUGhKZL?e3S-jTg~LFA2hcdVDmg2X6ugu7g8z$*oR6?)#-*M~)K>$Y{@R z$?v53C*roga^UL@4c7$V-}LPGgYcfWNsv<^$x5v#VrAb|KX&;*Cw(njeF%rDfscSl zGFnzSMpXsJMUj<_VH(Kt)?%~5Y;CeJ5s<1bAPp6I?>)E7q-dPunTTwI5_J|TJB77I z?{}3m1?ghYP3$qOYcu0$gz`=#A0Y{<=nJpVWFDHkKk@%$Rp9|t{?v(mg^4jv-4**L z#j>7R``j!SNG!Nbb8ics1uhE;^9+eS73|5LKlk=U%XBu3-xyENODJ32Q^|W=(@992R`AT%baS5RFjo}lGJ;)B471Jugb;E=00bQ>8UF8jk zvYITvL%q}y!*IjLe(uhXk{LuiAs9=i$`Vi=Fd7E8OHbW;Wu&_MRCy?Fo$*jSb)mvG zh56j|%fj>YIK1y@VAt8lQeY?b@`+K}1ui5I-a5{t%$a~%H@@{>V?}G_!44tkPG4S> zuOHf9(sgVQ+6mBhF!`oR$GqOehaPo$6seXN4V<9?j=r@zA7fz(aSQUro9q6K1CpNv zj!Sr0nAazP$=@N;+-K>)uq`;z@m2T;Yy98{hrgu#w8Df|-~97*e=orP zL<>N>Rud$=@TEQNo4~O9ALaW0{X*>jDC_>Gq4%GwJhP70<{$B^12Z(UE~EC>@ zXctVFfP96z(iKlI!B2t$!XT}K>+T`HU&;sxbjEexj9LNooNPmtOSQuqt%Qq- zDg__R!}O0g7xq)mp#s~=@E3r?$4shC3{+TJkjE#Hc!pDYuHs03yQy4`_hq+|hZWxE zm^@Cs3Ud&{OT4Z1{#Cvmv*^48Y_uL=`hKZ%i9rDj**hS!ksWmd%=zmVmx&YMoWjti zas&;84hGRMVgXGeGMXFG_UA)^eLL%36%f!_=^uy?ec811tr#y8L~fd11n|-IM@xrd zWJkNST>czdsw6ReRHT3%Ofs0t=Vgr2T>r3}8a!Fk3Skg7IaoF140QHE z0{QUw9MrU3Ux7ma^O=$g%yu+@?WEWTNO*EyA&__yuhYD-{0k_1Oo{ut+JAwq8mQ@0 z5Ntqr43oW5s@ucU3U$!aHG~AEC9mC(_jM| z$@3mT9$6l!RdDFpb7Dy)elf#=hma&6OebjuAx|_wv%J6*85Tp^lun2dQ_GNirVZ#v zM(gWVoJsle@ywyc=wVqD5?!=_qHjXaue*S*f)53tycd?;O>b!Lq^WjNjGM>)K+ghv zQYigdL*=B+flBMXE`6L?rdgHSxpPZj`$Q7iK%j2L>|)TW%h6-hg#(JQuQkqOhlz8S zA3dd(ZwuON0Rg{mI&yDZH!~Lr@{ELAMdLRiXzMh`M*!R$H!{q{ZLw*gZ0tE9+NrKCuODs{ znp@1?`tq7c-4)4)PGC46ziaewFw+^9WCx8*A)a>ef-q^x6DkdV$i;6$w(!b7Y(e%L z26`}1D|A8&Z1M@go4V70UR|vK1RBr>(|P3QUS<6VXtsQ_7k6@-vL)epn-NXk2%in7 zO>IzvpBHSrHryj z(4q=wt>5bnF;2^?78zVcAssf#tKqZ=X=+V6rikN0#?v3Pk}j1zR*68+<3Pq5g`?lI zZIvDljDAT3Sr7R`vfr=N1MBc7ID*U}3_!mDb2gmL+xFP&0j#f=V?Z4kR<@V7l_ycBSVq{Lpt5Ka>hKlTKUm;_yHdn|QF2rD28}I!{@Xun^`Wdzz;I(d1@@uBkTZB0X~aD1eQfZ|hoqz{0AGG1fBYa@+AHrX z_PCn(*EqSNi6?4j`1F-dLNtj!$;@RC1VKujcLqHCdfO7Gui2TZpf_7}RUV4u%cv>r zj}zc7K8Pp|W$ARLeC11xCRI~BKBZb^Y3SD9?%`8FAUSP3pzY{aSMUZl; z76BZBy~sPZh%46Vc+J6UrM!CiJz<9nm{rum$A=xVu(d16f%(X5wvQhm&E*F3wmoFo zvxeOTd~9TR6b`hSmfSyyd1Z= z_3b2TsBt0j$(b5GwVYR1VH$l@vRj=6g%_1S^&7kIY;hnIR4T_ztSmPjYONNC6`hp-ZB{!fW zu~~y~?fZ?I^bqU)A{|))6oM;h-_JKTuQ7IgO7z`k%T8kr$nR0*xOZQCs%={B(G&O{ zzFVSt`*ANc9UP0i0BB2GOVr*|M(RPkE101vCkFg144>csOFKaulezB<(%WQ8N}c(o z(0KTd7EwssaZ2hJasRqYSlZ7=F&NM2{`6TwzxID9*yw+zOwDWjk+&-0;`8r$Q-e#b z|8c}PI`Xsl+y{YBXxSOQawDK@v$`wzrx4}}IGXYQ+LY?TNV_Pb#!?4*86RwdxSC|t z#*dL{uLD5J^Y$x{jJ!7kU`G>x%b?DvDwwWu*-h zw5u`H?4)K}vO8Ar=n2r)z3cs{tG<5VKSP?*-XR&}9}q5D;$A3ZR8P_gTJN(1qD6ob z7HPKVuxzBFY)~sJVPLN_2&Hxc7%DWWJSs?=QzpG09`e3}UMi6~04aWHgqdGLURNya z&l;FQ0YYFWGyW{F=6k7awq6xS;aY5+9?M>D_C|X);u71>U@o1*8A|GGX~R**WZ$gw z;4oHb!clt$p)ud@yTMTQXJwkhss`)&-{WRnEG61r9<4^f1w?@84hrWy%Y(4fcypfO zstHXpJ9=|9J82OqE~x-QSV8lsN{>U{Rq(cP&QLB{$FW~L*D?fYZ6SEe{8*UiAOMP7 zUXg2_iqoX6@udWl=cfT~uzKNdb@kd$pdM77&FgTOn+e~lYTgV89PN&+Rk-!z=@PCP z<#oZ>oq3^7SuhYx=OJFBMvq5>5Y_G?u@`&kDhs9>f+(^(4H$by>$l#~#) z$KNUNd~s6wIT3kOnX7N7{-N@7l%Ne6{H*-$IEyB`ZGHT!Iwxh=ENSTnLr;%;18nn( z&w;1oo&_MV_DoGvrkSgbM6`<;W_akCFpq2Uq*u7pZ0S-DyBL=~g~O{nzrmuk00fH! zNe>Fujp>2CsE$NN4iz8p{xFZZbDkd>NyyN~ENnNlZuTi`_2rco`=Hnw!r2;5HZ2;~ zb~e{0z>nn%s5YUR{L1sk!)fwuWeUHck{C{|?w0BZWTBm2CvHWJlZrZ#^G%djB;dGp z-_GNaB@$j15sd2=o83Xu<@#_T$*a7^{}6H%GszojSog&n>xv{fm@GQfA^0|CeH4fU zJmAg=0*TUg#m1#1lC4MQMwS2)M25Nf5)mA0>W1HeJ+_~cHsn;YxcTbvH<}R z-cVk#3?-?=Z0~VHr4x|4Tc*zXaR|8D?Ko%#`yp6ypuxOLe0ey?);CQ1G5pHvcy@^o z#Nw0Do{D;>~twIm*v zjZK2j!~LP|i^H{ba_kc+#EosBK}!HZN2u9=u8n7R1dr=@G)pfcabUpGXugzG5|8!> z8!yD90{Y@RS`qdBKfK%-(p;10Mj9vxr#hsu|6f(bo?q3*d=xa3;!dY z=NArB%Jt1t_?uiFp^PSM^a6Zykg1lYN@0W~U-P}OQFaaR`~26B%--r+Pg%O~0|--y z;MBkW;fU%b_7KR#Tcy>%tnIJ@ro{#v_rE^K)BEtLpJ_SWY!l>UIaOti%w|L{&GENB z^-K5Tpuf>iJQ52&L}XdWElE>6YD%f8PP6-r^|)jK8$HF8B#$J-K6{JwayNWhNSQ6E z>T;@GtR3(y{^WT`%3EZ~g3M9w7Jo)X3SLp~p+jt%Gy1LV9`oIT0hn0&H6>26XCitY z)Y2DMV2P$QCKh4ysKsSSdPNm@@MLU~PNx#3_LghoOYN*x*}SwHte!+50icu1!kvX{ z;~2=GpPeykSXPdZhrFnV*t0eGDG-SxUDKA@=(`-Ypg6umtnSlx7Ptfy9W@vLjG2P6 z!Vj6NHi=+67^wlg=|@d6C#S|S-Rd>3H+m8QWpM7oMr69fmf&lff(QAaDysly;s-Bf zNk<iy9ULPa_2sxhivV+8@+?3`yhQ1KENG z#RnK^oG%HY4lJ#)D+nuWt;*ql1Z@X(IHQ{^esY6UleKH$1=j=^r%sMFDQnrT#i;E! zLkL;qdR8zwT+EzD_Nr%!UJLns_R2yLyMLj_v#tEw%5?%)c^z+r3qSuAxPXb(ZufIb zL9$1CH7wK*EPttV0@ycYf^o}9u+SMD6}WMAHGXSgS?w~2FM0i&H?byfS$^a3g0I1y zVy?lh zLEvk7J0*hzIfh3tqz=j?@Bqy{Z`O<@7zWytHP(2SsGX3N6>N@AeL8x0Ru~*J`;x&% zP~-i#V4z$q^c)k(R2p*0^(f z|5hUiYJu&JX!M!ATlS!!EOyTc2_TtogXcrKLv!ahubUlWqrV$Ss-KNxnCRW=8nB^^ zS_1yCue*a!*-NRJ%0dqj=JZ+C#jUnLIpCH}MZF?Rezl#k} z5f?Omugeptsw%Gc-KLR;v2lTSH1T{ zSDPEN3!Fi+M@gd@*y213HwyLL2Ofb|ZD&qo4}&J}^hPU)ZSINiTgE^(_r~i$l*_0qr`BNm zT~>+5aZC$tGk>`Z2%97ccrhwx9-JvItBG5;yao)FmFIJWFtN^RYO_QrC6cH7D6y?u zERB12>cTybFIel_ML))3T>L>LE175o?^t}kbbVglhV)&Zo*9pO2s>?zBG}5iQw0g` z@|@Tpg9BIZCJZaD!4DzLZ@J#zh4{Wt^ z4zjd%!=x=>uj_IUgk+}^EC+Mzjs^;P9D?Rq0DI@$1gg2PN2ffr=vg99xV6^|`kw|| z)YFm*fIQ1VKi>aD+%P)%*}I$aM{Qn1yg9{mR>yXU>F2{ic>&Q#)S6RGUyHSv=DgdUe{+th!zM#5wea2 z;~H07G7TCF6A|F&!Ph@`uN@GhAXFCEQx8cD9QhmJR5V?KTU4h&%{ZMBEkdvnW9Fb! zqy+>2V@d~)5SuF-bUm&9Q9uKngLnTm2K5x=6gJ1cRh63iVd-XOzP-@uoQAomcR$C6 z&6*~=843Wl#{$S;_HVFJfBrg&?-vJy)qG4)tN!wo2lg~{;t(95YZo1N#3Gsi>{=L# zm!pjnnP)RHvCb|1?j}E3a1dCD7AOp!AA%sj!_jP*}<$?3gUzP=#_tXPrMF&7Y z4hll~5cOX}fCL=Gblay1rU3;Hu#$P!l9q+hRp~lSnKU2{Xxis{89SFF5g=%GBx%B9 zp+4-EW-Z!_u{UM=mf<~82ts;Q%afK=brP56PmYF3;k`yU zd`n&L>;Js+(3%y>v9km08ave1sD)0Qcvx0D5RtS_6jN!=P<^B_TeapSYr6<#P8ZQ31D-Mf}e0PE?UX&~X= zfr$EFWZyM4l_2!xe|I)6Dcr84Q3J?vnv?bC*Gmqleo2jdUwVbX(DAW%kao2s_iOrCm!vmy##N0n}_K{fq*<1XwXVnHZ86JBS0tosg16 zR*D%}@F3zji1b;OL%+FSI25~Rl6d7>a|6IEmEzypa;)_F)5m zYL^5~&OVj_P92aGUn%QaKPbdS$gn=8QgkZLSsvVlX8K2%&JvwqoWcIaxb`+oY&~?Yc}^mj0Y$?Z&b_|@-fg? zz#pDUTaqhRjC0um(5a$L2on}wl)EB6NLU4pa9G&ucF&og3$faon7~PXo-jETQ^^rY z=#6+g$OR}4e&7lIzr*(q(?R(_eMb_{C?bw$zO)kKy^e6r&{a0i1Qb-db7ExSAYh#A z&_OK4dzXs!$7Wf(b-_p_FDG+6FJ{z4#;MO!NEeLyfFzJd)7amxsUCcD}y?6&ykq?r9SVwae z_CXPL%9&tm!9S+k!df3jCt9>1df0q8sIEhOHN$c=X2p4D9J~|eFpCCdwK<^P*P7ub zsVK=xdxxdXj0`pRvSe7PO{G`j3anqcP=3S&HTq^aNqH&w;*Pep6Y2r0{k3NnSk%3p z_F7zWNq%M^=VSGdPJr2s=0a_Dj@M#znKH?8*ugZf)>w13M71wVaD9?>uZr2+hzpWY zDPF&rN$?I4j3wx1`tBMvlbVaw;4oXZWF!rt~QdySsjTEKTVA z#-cafYDb{X6US+B_aW>g^r4L`XNu)@(&LnPOD3w4U=tK7G27ni@eoAfgApnq{ z9}R)goAaKEV;Z8<7AsMzvyq;N=~+$G)rA?0U%J5_$3>Zf;$-^j)5r}i?`?etHT`RW zMrIv5S|*5sIMl90-<--0$HkKjsR0a4NnJGn zRwy>$#AaR-r-sl1Nv5iL#eueI@O^y2cOiO?nd`0jE7u)tOZ{SZy``lLDnIU@%wtt& z^mn;lis;>dDQD$8Q3+wL$ri<=1;0&7SiWBK#H}W(3=*oDSQOjCT??58=PjqHTcZwU0qx(scBTWw!`IY)?@9Wm+!>D zE%LXZ@L6a@oVpqy>6H6y#)vm!>}fz4H)VUJPlt2Wq$|N@>LvgNuxnPlq{zfB-UTMJ z;G3EEd=c9tyOji#f)~E zH>#1tj4ga~0Sg2h!+Ajgxw&&rVJF`ocgtE!T+WMfsH5oP-{?p-p1C2aE5*l{3lGP3 zE4z~;45(`SUx5&2_;Y@IvG-x`hfMU2IZn!hi%gvH=U)b!&SsYxQxc0fZ^We8Nz7f0 z1JJ%i2zK#>WDwrgyi}*L-(i(~XJ>Uma%20vfsmltWWLJxo;<&yRH5h zHX`Nvkk$SA!F}uR3ksVZ`yaRS@@43$wp3e%y#4)>Risit+YH-pBe&Vv4~u@i%J#d_ zZ&$BgG5FB&g50pUon_+V-_=BrKS#-2-r|*^q;FNMj`(L)oiRaG8AUoC!DzA<^<}RZ z)A3zCnVm}q+m*t1R)q?QKI?Oxo%V-_^=B)*30oVGAy{kB5ue3O@9rST`ZoE!Cp^64 zQq(ut-!dcE|L}-BF-pE$-vpk-yuFJOPN?)*9RG%RG_z6~ed0ZVTZK7dBUy*N8pyuk z-@m^5CXsdIy?7wKnEHIkqE%Djt1DKag(*vmqPWsi5|6EhfJVd#XVd&JK!@7JeyCd2 zH*l>1sMto%=|xp=&Z}*ng&Vn=@#|#DzR+dik{qc$@QA_avTodZOYmb}^*He7lI$tw zJG&W-(bXp-J%Y2?N3syofl7Yg-lg^F@2pa=N&E;28KJe&r+trt)+&dRZ7wH??R)ZK zUxvkl8+5;TrvqiQtbUw zA*RLDa`JjeY$z1=&>a8s&Er+?)vZEotzQBvlO^+$%G^T1*54`fqsGmotmx?I{^4Ph zW)f!}qm@Py(LlIG!r)!CWMtfpfrAf{RTv^JeVW-1a?#Htwm5k>)aE}w`{R}XzqQ*) zg!da05znV3u!kkk{QXEU*O5Q2Aar}? zNLr~~h5qA@KZT5^{{G{8|F8P-w~yUX`ps?^*reR9gX{(btBkh`tF(u0eXX==^l5c} z%7PZOqDj4c?{>XWT+Zripw_$uJpD@j1Wp1N)TXi~( z|9J72HcKs0@?QX!Hvp6Cs>}`a{~8;s^A~Vr9aU9T;@q4dPCc$)o*_bwRe0%)8pmO3 zehp{t$?@%y`%wXDe_X(tJ<8l5d~+}dNTsFBL6qa2u{ZbdBhz!^O)^b@g>>hADE%x* zbUTmH`1QNEd2e6&<2}%8C_KqbRj1a?r{Dh;ap%M1BXPcM@^IS^cyHi@IWao>O6Julb1)+Ey|%%6xy{Q!v934RglpeDF8{G z4PNMhECi*|f+cL)ZxAXczj^W$N_;@=?Gc99^|ReCmGOfLx7kNisdW*7tcg5#zDuwj zw*K>~AZr;TL|G58??53Z^?bRwpp0GxL|pH3c;|84gam1u;#mJp=5)*JgqM>duW}Ci`Qsdp|+W&eT!Zg8PB;Hy|%A`oc&p zv}YYe+y)wfkGL@)gX;xb5#wg(NKqF3arN~dm)H)s*Zpy~>lHhVK2sYg$L$DW>nJzZ z*KXExw;+Rts6n$?bqrs+h=8AxGt-C!x~NWx(kRlDU%lJhNX-TI%XeSgFI`wmTn7oP z29a(@wB^YCoOZ{O9^AHNCUz_*=1kJ$1}D1t%&$BQ`u4Rt zNt51~KhFqWuZz5T>r*#1{Kv5=Oq}bDx0Y42=7v&g<#w{}1ZC_}mxI40=-V6QuMSl? z=(x_TH%B6RX5L)3L}WU#-yVr3CUD$iK)Kk%k9F8_T2wXFO?+o#SFOMJe*fa~`ln}` zH^PS$rZDlAs<-x%e9@AFJ=S$LtIDdSIimmU(#^rcTnp{doflz>srsE@v>V-CQv<}M9@+0|@ZH$*6{8yA4dP2QZM zTtrQ8`V~{SDFFR@f@}?EUM)=GBt)-I5sG~dO;SI|pN=6CVmXO=ChZ(YPB|ZO{dN7 z&Jc$nF1SEWYY+_o=H-D)!6+b%B~W11#i??_uvp^21LO^r=;)mp!TtEkLxjD`1o6)Z z_o7xIpch=jds$e*wz8{GFkS_6fw#+RVN^80l&|__DK$Aq!Sur4B7gh+M8YC6WFJ); zC>&NtBwi>`DtelB5hmA8Q$U?Bt!3%#{=D*$wmR(4vR??rWd}G|p7fYN%kP=N;`fJ=LHz|c@FSl% z0#|xoeRT+FCRP&LY?Mx3>oT#A+ywN!S!OOmIGCU~@%n)b4Na0Gn8Ywv`lY^yZ#_;N@ zjIE(8Jb2B*<2)S`B1<>;mL_k@Wa#@=yvn>B?L0j~uLk$_K7k+eBb9!XXF%&*2|0^W zxW}Qio9cU67}pHWhLvFlY|yOw8ux-~f-m6v^p{B}?S`j+NtdoNyTbEf>+Ah83Cojq z4}-5Ju#INBkr%ApDIw0KnIh2>EK7p>_hv_kGVZZEdZ1l(@x?e?7|OBy=r7N|$to{z zJSIN)AaISm4iKk$jSid(^yDu+*2ut(RX6rLI(2Pne8RWp@2Ri}puG`LV!6TDby6|r z(eEcuprsH(xU|jXd*FdQ*cJQqD-*^85cx4>5B!2{3M{u}eeEv}&{4jD9$Zj`JW+MY zZS2j+*2GQNT~dZ|@AngZ$R4Ak$0BrX=(-QYUX>X+V9hj=Cu`MvbdO^~yV8|VE49;| z&Ldq1azCy}RV$<`>jlbbU5t1Cqrk~AvRBLbHWXXlSGIFsW(&QH(riF%c*Fd@-vl;H zh4Xc*(OveiFSA$diSfi4M!Ex#E#(_|?Z;#vShPODyy%PAvbnSR<`z7JkfHu!Ib9px z{q8vGaoMX|9s3DSgXz8{_X|>WDUT-)?CHK2ec2nFejhEbZq0mu!c;@_RXTlg^w8*u!N+3>q6`GEcvFJs;w-2Wd=V=xTmfRr}J1Q<47&xhbXfgtKK5S3=swUihC$2 zx3Qa{N~a!$S?$Y+q+|P5FZQGrBFTrIAzD9q5Cf z%T8WDOetqo(O)$~Ot4+Y0xU)_In>CC>2 z<@DrkrJ5ELiZ~EMdh)%^>hX);>{Q+cYm38XQjbvT)?t`FITs^3-6hW{>rBpr?^smO zyE4)SoUQNlPe|YU_Tk%N7$e)03boL?9-)5c6jaCuWRoEo{sE^c!tMT86;w%#WvkRf zm_CR8*TW%&Cy!ZQJ-)hI@dyzHI+Br@v#%>G-6syocMgcsXW7X(=B~a)kv7dfB^VqL zNN2w%;&+{S0+gHGv!9GO%m92MR9vEW!J(``5%EJ`K%v`OTd2j{}i zF1GD?cW~8#EyMh)9Q$++{l{MYR)h|5K%|U6Yc)sV)n~iTq~l&Hk#UNxr`bKyW%5oG za_@R)z+Euz9LX+ITj)O|SeEGU_*~4oCp-0$$X-R&381>cm9{+ldOdRG-DC04=c%O% zSr0*pc2beysv~bJti!?S(cA4%mCH$mEUB|^b0*=yy?pKPBcz^vD55}w%oHG*ot^ld z5zR)YcylOgME#Ka+cbCY$AV6$^cYw_|$t(~gHqlK!)}>p18ILTh#mNUp z4{#p|XwNsBbw%z`VxtoqDz{)aQKd#!9q zDRc-Z!rX<&KpcpJmkP>u9ondha(?-_aWc`<9gD2-)?V0+`VT#*6>^`vgK_M03C~%`li$>Sef2=- z-L^0pgel$CqS0S1)Iii)QnfOhDVVR0)VW(y%YtAqn4W`!1J&(*c3%*1$A4Vmr{mct z_9~pWkbLo=N@Uod4Oq@ghplz;9U%I|Hwe43Fi`SnZw=X*kY?#j+x?WesFVSDk=;9LEg_SG^atC0T>$)aK& literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/full-trace-valid.png b/accelerators/aks-sb-azmonitor-microservices/assets/full-trace-valid.png new file mode 100644 index 0000000000000000000000000000000000000000..fc4d2fe0470069a2b1d593621046408899e077a8 GIT binary patch literal 95134 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℘V) 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¿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 literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/log-auto.png b/accelerators/aks-sb-azmonitor-microservices/assets/log-auto.png new file mode 100644 index 0000000000000000000000000000000000000000..4d7a01620bb38921cfb590e346447a5951d5fe02 GIT binary patch literal 16583 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 XX(Py~P5KjpD_3+ijWnv%UVQi;XG^~% literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/log-manual.png b/accelerators/aks-sb-azmonitor-microservices/assets/log-manual.png new file mode 100644 index 0000000000000000000000000000000000000000..958e3f58c79625ebd421ae2c4d5cf1f3faf58f50 GIT binary patch literal 15881 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 aX1bHFCd6N$D35Pn(9<%~ta|+N@Baaf>stT- literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/metric-auto-rus.png b/accelerators/aks-sb-azmonitor-microservices/assets/metric-auto-rus.png new file mode 100644 index 0000000000000000000000000000000000000000..356991dc5b1076bcbc7b034433430f12e6be4ea8 GIT binary patch literal 14517 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

u;zJD>y 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 U%4=0!55YfGMJ!u}^s;!;+NV__X zn$<{%t^Qde?RB$i4oyun>gzexsr(;a25P5UTu#UG{#l`&%Jd1aOd4HkA5krCh+$lG zhl97~x0aV0W6;NW(v`gs78=SB{war(5j*gI1WL`v{2=IG;xm>qe~s zfV^=vk_<^Wp!-z7lK6amG>>WQz9FbPU~?qTe+5%FPF^JO;(aF0RT=}9l!yiC&atk0 z9Y-cp$AtnB^ZMZ?GLA}-ay5WjsUqdb25>vpqmPLrSI)m$@z)m`tRY#CiO04xB0W!P z=K+x&wZaY!np*F`j8vK5y-S~@ooxAgV0q@MMz~M(1F!YtFHunqiJ}mBO=Z>M*c^b9 zTzvbkRH)sOr9bg;pEPH#U~z8og)Ux5nvd77HmF$NUg4SeI;IXTmqgFha9X*7Xcs4< zYw8$?zDqUp?eS8kY9BLmoeZj9xFTDLjgMRW@_^(iQ}w)=8bARKGg}Y{ zCyvFnRQS!+_Z)Zpq?>}r!;b|~hFPIw55~vid$=MO4|Yt~W~#%Rb`bH;fJH$3ya!?_ zLfWw-ta-ogb9DjKp}pbsS0A$_I9x7EK(+WRPCRs29B9vn(iTwVWM|I#T zhl)biz=&{3hbB!|G(k?UVzw4^k;$p@Z1KZ$gJ4{isoJLlw*M^G7Z2XJUkP2BhVny- zu%)J$)__gQm>;k^hrDcW4s@QX3U)i{BdC|dXnXz)psdfVjQmRME9|f}?|!|j)@Z2?KdqG(Qol{m;W=n**GI zQaB9xFB0?<86z$3wyF_ed2Xd*9c%shw+f+@`uQzRHF+{2em{>l{^SAa<%7BljPvHt zl)-|~d^y=nRkiP7dyD-tz7fScGc~R4_5KUTtyF%-J#nJQ-h@LfnkW(L>L+OOhwgdG z_>GepSSKkjA_m(G;`XZQc3@ID-z*3m8Ax}AfC5y90b-_Pg70G{t{=z5XnYqWs{Nyz zp7Lm-M4MXVl;L&-S@!0arN|Zc%3`nSZ87PoyT=hkCGW}dUf@I%SrhC#~cz>aB+dj0qjbla_k_`j3%R~?KeG1 zj7L@VdT&lnTVhsr7eoEKYgc^J?xG49onk*dx={8<$`FD6p}Shl^Q0eAz(G_2Rodb3 zK>i)`U}0M|$Io7Gcji7NiGxH;phnen%)+l4WS@;ZHzrk*NjtCm4$Y|Sovlvijc=oo zjrVRL)`xoR_FvzYW*A-`nsRK9C7p$DzTkwlt{{fT3ubIklUGQ4=W@0FPTYVo`okPi zveQymr#OwgQq70-%3$1&Duws@PJ5PJkNua^I(=vm1gCi5%c#9}Ph-?jOunHc)+J)z z9dz9K%AmU76~bjuDi1z;37vf?e~NW1)D8(DyY%$o#n2AQ8!!+ zoLLXfjJL0~{nQK78|K0m*ryokO{?v-9lM?#dvBJ$LL&E1aG@^tn`=%M&Q)vXRxy^g zB!ye*j)hk9r!Cz;EWx38%XEEzZ9VmRpTBZ$+}0tkbH8JFuM+JjXYm#F(K52-u3X?-HwkcZ7s+UFV^S@cxIXrFdji)%x2Lkh z6^Gxc+^Hylehi65D>JM8dbYGx)$y{18S3nq*+*zaJ(;<=Sf*zh`kfz?uPOqNi(HNZ zwXbI+c(g7>7)pwxQ6Oh2qSgH1RU_^nJUJqH)Ffiw&J-m7fO)7`qw5OUeDCpOyj-rl-kqBmPskz~`%>#5 z4^XBnZ1@L0+%;2SE%jJXW;an6BBBn;Zx7un2VD{}WfOZk@tP|N z47@yc({${9tzBzN<6hOD_kaFO8O^01$ZZ_+dBUTQ%Gz=cN{B*3Z*Rgn_r%_1@;|0n zvr#vX(PFm?Bs8n`3pD7U07#I%tCw!TdMDt4GPcd_r`%vVucuPjw%5@nMQJQu<#?KM zxF}nkG~f*M&o|&4|3#<>=wpCf3ys z{5l3TeoQ6Dv`7CrCyF=CQ7*UD0}90nJn`oT9_M{GjX)BPyITe{)4$qPaw?g5)q0P+ zuyQf$gCyvRs57+7Sfj z#*xkn)PQHX2q)kSgm;WG$wG?KPjwue_MY+|>@Dhhfs|9>V}EjEOd3^59nEr#o~aqx zk0U56V^Vl#&QG_%dBnX=L_}gT&K}!=f$hk$2H~EBw?Q+#zoy1uuZ{x)v6d%KX-+8$ zYILO1BOhZCek5AgF*G|aX!KN}i)9Yqk4yHLTxR*mOTS*Z+}UvSj{ntYxN3B6%0Px} zigjH89TSJ`6SKG7gb0yqCdDfKS8tj9kQWQx9C=V#7*btit_|!(ID|Hjil#7iPED&F zXxmE!0egeJQ*I(W0F!cuI#8t^UNksB`2ry3TxKudSn0$(r(l!we-u*O~KkJX2gYKEuIj``fUP_U$J7N>Zc3iY}uWqQS2NuuQyC$`t z<@=8Q)Z=osYx46pQTTaTIc?p(?oBJ{nsTo6n3szL{G6fD4c)ujI3DP?2JJJUylLCC-mY}E=agUIiI7{k@#x#(;&B}9R#m~nQ_E*WI30u`pi_js~OVr zkgxxt#|v!Qi9SW)<>U1o`IsDjq)r94{Q5|v;XUDal>;?h8xt8i1g%8AVBim;8j?qW zia@=MVps`5dT8e#{+}ip;HN*=)FT4li`p9WN9aLrV zx*(vtzeQP?Yy*s*DAj41(&WB6RKO|g;}>WZg>44BlHp22*220s^Lv%k3;pmnztIcM zLfvGV>yX8b(BEgnsOrDY2G*t<77k@n(iaF1#cmPz;ekp{5qZXd>SS!yuML=X0p=e|kBZhR?0?>DsWr+pQvdZOX{2yIlp*kiCC?(h z^wkIj%=xb<83z} zr}9i9#Mn%OsAzp3Day(RL(eY7l5p}7`A|m5Hog|OhnAMc(dWTa4|3Xk|NN5P#i$EE zkugkU^g;?^3-IRIFR?{R-kKK&+j$Dnn{fO-`@Tv2+R4r!c=s+<%L450vn;O|D`el^ zN=GIGq;`%&hGPo_Vq>{&^;dM=cr#b~&pvBjrDb)hs2{6%a##83YUVNfOp))-aiGzBqf z=8o&&gw988Yh_VHgMS03 z+KSl|mpaL;j?-#p^(JmkbX$-^XOrLgp<%(;w#j&OA4VO-4*{q~qh9Jq`PF6(@>(jaWm)sqsM}9xxi(Iqp{9?BsE)(D4+$* zKV$qZ`&G&;qROeyX`85**^BuNl@-Vu(;*Uu6x2wvwkVa<+{A!OVNkhIOE=Z*bB zL7d1!#OEk9aedUEbXEb%9wDp%ofU?3lC@dca)P}t+X*;Sl6w(sY)-dGKoSn&|4g~w zPL}w%@NS06q*}D=z-vKlHk*B)q&oTUyI<9va|7efKdi=X*DYg0#q|Pyh;gUsMa!f# z%FXGpdzX$sjNCtI21k<56)f2oiqz4fj%e5O5rWT}AY0 zy~x$$jagiNYXxe&@ZcVNbSj7Pd&&oOq?A zsyy1uic2*8vqRB!oJk!hjVL;DbENe_LaV!e#7z8-|fJF=bR7z;xI2Y^1xNkL@3=>4b&}j)GoV!yg&iU z3j}@~x`r&ZP5~YJ6?pGs5}{IJntpRcdR$BjEpAdfovgf>>*iNU9+h8t0{-MmhAh`; zR59jh55k12v*#nWgP=Q+3;rIPBb63g*z2K7&4@W@#E@MM5dXjva;a38B<6IS&-CrA zhH&OE{FYP3{}pT{_2=E)CT~-f2TN)(Od6+UblR%+`cWGc_3pm^^iTI=!J@DRN0_qc zavahB=!X__z9$$sP#AkC+%lm_GbN*8T*k{TY4-#?jPGTXoLkW|?|GQ{YvSx|Il2Z2 zE7WyUQw@c1rvn!c1`8;#c@8JUed>ZTkPaVW*-NBK(@Ymxi6f>%Z9lotiR9FgxurX8 z1lERTsiZ1nt;VH_$>&Ec-OyMwZaS(Vc-3L!P&++$Z2jZzbM+Rt;GIdtD3Gx1D+l4c zL~;6HyS1Isdu^l$WzNlw?^(MnYkFM4&%0u_CthaGHGCTS)yxeG9nqQf|8L*Oq7YM9<9A1HziR|3)MxqEY;8MjkC|U*fxL1@2}Ja znZ;WyoqsFKXehes11MIGgaK7gz9j9`vX!d~7TXRkKY`#CbAIN?ZMRRFOLJ49j4c#E zYfY9rV~@j;(B;qT6qE&Wj{Ytdi)}uhyhLFd$k*pe^=?*4hn%Pq=8iR@&MAO*enohn z-i!|>DFf@$CpG6yu0NMC9H)?V4N=8IGw2hiMvrFir#59DXITZan(mr-H@)?Bd3F|H zt$Rx*sN{5Ck1UJBuwNBZIFC$Oa2GN3;_ORVahruLoo~BF7VjC)00h(yQ%PeaLZ*n6 zf}!-A zRs-%f);bwEaY19}>&K99MmiGiNeGS`vnkTNkGw;W(6d^ONa@15L;6rhP@Lg(%!xiqhHXz+( zezUJJ0_JEDwP_GKBwSgJ;KKGYE+Dt8y;q$;V@0FC=^k}JTt%!Q@%~|V3|0-d6Z)!X z;N=SwzL=ECwQWV?f_#c!KBsX0eGoi1Zg2xZxLxJPP&@+S>(LsX> zMWHwzhiU27+BJ_PF{`+oErz`Emp=@&cqu~P*+A$AIsEMu?VZqm{O;9g*-b&@VK9Yx z8~N==%YO>PMC5qKIY~?NHVDuJWchc+PsA%OjsMZa zCQh)1wzwL)i-gFlP26vN5Z0$1F@zdyuM6B`Os{-P-Kcpaq(kDhxcO{`&$Gtx9Q&~8b1#9NRr;2j|ythyMP5w%A|xJ1p~0`Q|pF@Xs}+ z*5Gkl{g+4;^*Z5SoltE&p!*%i`KP=Yy!F5MaLxVwet=vB`QPD_C`d0P`V*cy@@A(&`M#ufOw4NZ&Jb+pTNWHlz@p{ zlb3m$0~ynJ-wwRsv8cq~Ru|xW&%3}5G`sVDkh{`!AqalpjAX`|nk}lO!FgQ=w~t!6 zn^n0}h$aGq<>9*i01P6EaUr8El&iI9HEPxnF%vvY8jlU&?7;w*x4C3}riJil$rJ62 z%Dj6Hw0(xzZ9$tUoMcwE7g7{_{zrha@N3_^v9g7_)!=?C=sj)UOSR#!1Z}>5*lkFpA=OWRwXYC<^)G+TvJ)5qKMQ&$a( zw#6SjUCr|>en40Z&75!Y&iYNBJZ=qGs*`9CGLv-fUZfa|L8s$7_yzJpx9%?rTHagg zWcQ#u+8k|Ujc<*m=nd(vXk5c^EQ3R)%Hbo|LDxkk+)}_&N1hyor9nx;&l_$l1i83A zF+^@sKqR)M$&V6i@igk)Ut zT)yDrNc1#Rr+4~83XhM+crkbMVqSooeaSlD7QhzK&hP>xbmmxNQ|osUv1N-`CP@_B zw?}Tp^rx{#*avhPNSmnQrjI9|%$Ms?=r4V^XvvWU#nANnNA4}o7u&OYQc*2r>`Ya% zLkJ>Aj?p_6$va&`krcK?e8d@N;iTyGqvTG`eH8zYv}1P};u$r~NWQFZ+D3(4Cb-r6 zF&C=V8HmeKq)~#(Z6jd-tl7BDQ$45Qu6b!-s4t=wh$vOpkQ^K z=J4{#g=slnVa41b_w5y@e++MYd$w2`rn#N)p2F$es*U+up(G%xnivyavO|4 z{d&{1iO8?NaGYtmQ0>^+g54N-f2nnrbL1JnH!lvbzZAD!r^{iSFY~>dKnt%4_gO-| zsH*4lxjddtOjp7KMSfxO$Ma=H8z$?1mGnO9jKEHUpXhGcy-a0b&X}!8e9_sGp$7O% zH~r}J3x7Aq>$^T5RVWeKQ3}WRWJPZx%5u?+>w1w}zp-pv@=J!s{w|0LgzOAkG#rdoh;27aEnu#T<^0T1bN*sg*YbM&^QQ7N#}(sP?r*vjLo z^J$b;e?@}-5WIBA3YFkYM}Mee)i$22U~gl^Ytv=xU4D6ZTuI(%m!im&T70)B1GQHU zFmw9hZh9CCK`UEQhss||m*3PR`t$eTXUp+}Mho6l*+oVRK{HP1v%pw$;HB=iZn}P8 z#a-BEE^Angd718+I+gxuT~*wN2zll z*O)}8uUihfTDi*l6x=|Zg74*0`?91LL<=qeS;8ASOu|_QaFdZZPPm&DX1c?1W2hy; zkXU)$@XYv)E(7$JIn<)!H(lW|aw|qHysLqgtK`#GaZG*&w=z=m(nVBo`UA>QGmf{o z5H4&N1|&|6rqa2$?byorSh^z3^^!9XOkBZNsyQF=*@0&o#HlZELG|{&U8cHDI$h1zD~6d(s@%R73Rjf(+K!;Oj&a;!CL@(u zoHt+buyaxpCbp*`dnos;)|W+`X=p23&;1>U{;0^Mxcsv%N=`g9>K&O=9Kdhot|yqA zl9FS54|erhw(RKTt+nUQV^+4^7iXAJN@zF`WL&5)@xrqUu_d8`Ayx|tt3A)@b5!}` zeL-I@(6$igexow&=3t+85xYK;8HkW{^R>5IE}{4Wk$VpI0kiwfJb*2hnSFL~JF7Mc zxLQqk_1JDJb=%piNjngvdPKZupNI+RMGx44hKLu0#4QOirs-kz$}?wgNXC@9`q?6I zg}am7x!TTH9Fr0zUC3B4lo_^+gCANu`l`Q1Birw9pCAO#pJ{}EaWOS(Pb`RTX12;q z&l+;{J3k*T)n8mg)&1U9erFun5mi^QbPR0-s#02_GO6WbiOZ6~c}K2jl4w9@$7{6W zUT7BqqkZEe;Uv8DKAMn*RL3Ua`{CF1h}FQ^hjA`?R+-IHA>@NR_6&q0Vwe`EVYs+e zLVvBa{+t}?QJJ?UCF{fH-m1qP5t^~=jG4gP;4Ni)B{s)Q90sxQsKSjw;IbwK!=_-h z(|uT8mEq8K?aF5j*I6NGL|q`cW8!tGt|05Phz0*vN^U~|EUB}`+!A)VvcUXr$k!jn z>*c*54h`<)(S!BDh5c;~bgSE7hWJ&G(tiG=j_bVfY3WcN>;sSR&#@xLeb>@nzeQPV zt<2uE7AO!v|C)2L#NRuOJJLwW!`~jP>@yesvdwqnW)VC2I-}iSgZpsW`7AqI#BrXK zw*OtR!jrsLaa*R~o8f9Y@Tul7%l++qArduJcD#ss8-u=u7DU~}@@{bqVb8H#tF}Db z`Hb5oI4YA4)e)=begzc;yZTrD3kzZeDqr=lT!66T@h~egUbR6Jg9zzLbiX-44t5VJ z5fd&HIp6sd3@e02r&YbKypQ2wDpjtQX?whnYaeRb%h0P8gmLk(uzjQE?H>fv?Y}*hgR-OVV2}7FF!U%{AIbume_)_{kH)FmR%-4 z<#%3O7JTX-w(OWoZ`NWkxm6BIn&~Opkzu zSWgBf#In98!yMWt)zlmgAPQKE^?~$8+?|=XR&0o?LDkId9hsA~f*;3nwXqf*S8R#w zyWb>*YwbzONM6+tJO5CQFXe=4!4p!I1b0}t=8S8oK9rg3hY?LCh4%8~QMfp{ISGEx z1fSeB#fk*q9kcpr`N5oBv~4kP+ zyvmL4)6BLH9p|Yk*&sA(zd??$N2V7+gIW{ zLm_c{zdF49-20pnWH2|bPCoBdD8+gK&uXyfNTorBVe>0M+g#%g2(ozikEZ<&6Ihnc zJ_!n)ehR6tx*l5ktHy1@aIg*-HduDFwnAGS?$vG&k`z%5NnWZC(>iu+1tyED_oXX= z?O=3<$(E67$K3w(RAy@JbXU6W6=X<&hvl;oP^oe$uV7(y^UC)H)yAcVJmzueLvGnN zA@%9h(8{QzO&t#tvu;T2#CVNWd&uI5PF#}3oYm9coATo+O1+DP*UB^))oirWYK{sL zx9l3PV|sdiuhvW z&uV8sgu7>Dpy#HaZcZxIO2ZtA!%Uhb_w2kJ^>Gi1)Qj}s#UIbA##-^CR~XfWhSbOP zdtvEgoxQOFuFM(-Iptll)kSm~^XA2Q6y>*8c{t(H87)WIapWhHh?4N?MKq{Cr?@SS zonVhTy2?Yv@EirNwy#nj>F30GRy$iBs9D06%Ry(U=Vxy&m}i@%Yo*gx#!D0E>;T@^ zc+3hwh6U4u<$AZA`{q4hFR`k?+cW#9fBIL%O6Tqw+fTliMx?;OgGYC`$-Gxz^YmpbAs3ENd#N#kS)Op7!he{m?yMw;0c zQ!muF${pRv7r7b4EybX$R>2;Sr({>U_6Bdx%@Gjv2r@OVQ=vEHA}zj~wr6!CJuzJw zoaZ1)rE$8pCp9}PdDO4kp=UL4RWwo!5~=yx45t-2b)nmt*NpoI_(C1(P&}$QTK<~XMtve`_Q6@Y zRe3>$AwoA&_$-MkTy-V(X!Ki;ER})oPDl&3HtvEA5pcC+_X$#>uA!iNYY@A3eB~Za zwyMh(rN<-@gq?S7f{Q3aKhkeB`W-qmu>eT@ykEFB(0{v5&$1%MZ&`aBfv^-D{{RSS`ZmYyE5EVb*WwJ%8w9uKNCAL%Xc=qTK(zl||pXdsw$Ock;%x>fHcu z^|mPbDSXAcclEvJ!`n>|oEd%Hog9&kJw=dyWRh0_1N)w0S+sD%58~w0jMUz2T{-B1 z^IeXzJ^Xjpj=heH8?&n$lBPG<=t{l1I^6DN4g4^IK^YPl8ev+xNq$@)r#4~!=B4_t z%Uiwiw&y=i4_5Rl^!9F%c7msWloNawt&KHD!L=d=Pdmj}P&S(}s?|g*F(qTNT9n zx=~XRnit<_-Xo3l4o>|)n)G_BOkRn6pIZ%(czSlm{q=ci}d?uGuU{KENu)i;W=pgo<8iPL|S zUHe&eU4}us2c?e*183fr9=Nckb;<+#dZjKvGPI^RI-XU(woWj-u02>AE*y%JUgT3> zC9-HZdK5KfYUW2Q!Pgyb*E^Mls<{ubbY8onMx#TlaSI~us@p$;2gfH}cfLNXx+UeE zT|ZW#`|uPF5Nv=%j)XlAxlzO!esQ+-7eGiwcu{e$LzGLXQ0On~^N^n=h)09y?KzTX zb6e03L-d(4g;~Bc+}zC<-`QP%zaY#w=a;B?B&{;Gvp215s61o1)^Z_euo508P(`x2 z74g&gcG}*Z;9$oULgru>vtj1(GWgIyl1X7ATMl+u-L~y{OG)zLsHJqQa@J8khwbD* zf5lu&fQqkG2yFS-AnK*zzRpf3T_N=2_7G=Jtk#Nou|?qk6UpY(Gsx##)n~mNb=1UA zq)ue;*Cj>Fp~z_J>Xvo&Q$>-xK1CPOrQxwk0wDGmzg0weh?|w7!*CdVvhSZvj0E%l zK$%(v9zk#Qu+MRh^1@7^;U*xMSNu{S3Fp&3X#s!zF%%YEFjmoB*3jbI0_f^x8hBLA zi7C8{c@~U1^c#ob&69f0*BNIA7az0%Sx9xd_W}C?OC!awx3HYCqHQ~LzEZ~+gCK+C z9+FB(S)%A#%WcJAY-U=SfnFIhojSYL2#LxWKT84@ma9?sN980tECSkRC6k1)zla=7 z=~WGlab-=tSKj9(#Aauct25Tuz*XIqaqRur@($aUY_O-LCriI~t3PS14g#j6?(Hd$2sq7o~gEO+vy5;efri5U2YzbILk*fSi45m9?RB3b~1Q2^Z4 zwkV(Cc9dAv(?{y*@G(gR5e3Z4(vJ(4yJ8kz+ynyh&M1k~SUK&x@iLBYGjxV?QmgLD zA~+by zYYKR1e$GnU`Ao&B zi2P}iK+@?8V#aVv-cH*4_7xH1V=$m*{b=~x8oKT*1FyL-B~`1nHC@q&?8e`%4&aLLEY!{! zeidrc9Jm&D^J8W^_@TyrwE}RC+qbEV!ugAa1HsIdOaCTAJ4c^({>I>%5hw-0i6Jo zDXf5>uxVzsw5~a6%HJM7)!ori?8ObssNO%tdfNp$INrC9BNi>Nx7IqCxn{ix^w(lZ zl?6WM)TVcMSdx`RK$mys8oGbw6S- zgWDJ$N4kLtbp09UJMfsr%rlEe`F_OioH(+i5Zf%cbon>OoUIKVQ806=($u}Hy9Nmq zyOw?k(CJdK{+z8k+%HSx^H&(59F7hXNF z@&W)j1%Cg|XdB&UP`q~j^7=1a+4iA1^4Inv=&zOmdsM&}>Z7<9-Ri5vR za)nvw(3L*^5@lOx6&gC(8ZLOZGVfL=ZN0^{TXU=A8sU>GrlBH|<~OV8Me1K1>}S!w zKNqYr4T75{FP*O9KgGy9b?1ccKNJ8EdP{xye^LN|#{0Z8|DfNq ztI_|1WET$q{o4O2ca6{f{uci!Muq3O{?k6K^PXIi{s*a=a0~PgGW3?lFkrZE97(NI z0@N!l+UF5((dZyoDOW+QJxEoY#>qLX__o9_G$CXp`~P&@f6VjWFEnCd8n>ew9k) zT{|}J_PYt01Ej`PAy0ss_Rx%!+|G_c$Egt7(X3lY1#Q)@CwK8ALn>=2dknoY5gx(7 z7r3P+zn`vxVwPxg7z#Q5rRBE*hb?xoDJOd%j|T0mfy%UFuj_vXHrsfQMB+s%bjf^5 zg;0D!?LwTQU)3F)d#i!xoW@n$LS6)G;<&lJ?ID@pVMv65CA9%#XN~tKh>?LR2tuXe z%t}*|*ATC8MD)dkJ&e7fInd8BLt&2#;kFC%c&8edQz%^(eEh3B)#Kj+wb-_|oCWnt z#ot*O{XymSXjY55$S0Z`xLv~oJO1T~r>y8U(X%Dff@mrv6F{)`NU#X@YuLn#F-}Y50I52+n&{ zf9YogTVpq;b$uF#g{7JTX<{k|M#P$>+6Vh(*vRxUwS4MLa_pacjV_0I$Ss#G&rfXkt$fThx7IYhosf3dUYdvOs zFby}j|r z?AT-z&S#_AYXO?)-=iSS@7!ltKO($VumxJ=P1)>|DQ7qs^{ag!>+0EOPkT-xHj$J) zmr^WxXeVj!#sW7HD~qcgTG}hNu$m=XpYasg-SCe6Mv;q7LzyYO##EdKvVp|68f;=u zKs$yYsQb9uE~Nu-JE5|*7Ce%FLLd-`K-y8>-Q~j>eruL1=zM>Z~=M*2t}@FG64 zZ#G~P(XCvC^y}KgSS#!*QDf}g>CQ7x#QIo19?%^*T&o*;_+q3TC^7!9$j2D6VI=mn ziNPp6u#37z>%1AWladbz_IthO9FlH?RMOSh@i$hoObZ~jlbr~7VDZu3Hk-<^Y7`s4 zQ!YlU+HIoo9_?ZNtm6Du*XPd$pH}F<_f^qy6kfg^4{PNe9^VF|eLyyRB88%CXo3@D zXQHhf^79a}k{e>+G~ll~VHdzFKlkQ}7%S;4IwOG-TOM&|Mh z8Du*U9S)U{HpuyHlo&iSs_QVhmw9K!S}`lvi5jG$ue}oIkY#O?Ws7c5GoHDl(=@jb zuOg0ftBZ9*Qup^WE0aPtO@jT8A%)&8{xggxP&DLVO(@rwv<$L!v?pf}D%&T}JTS<- zJsTL=vR_4zKIoj?;b50Gvhs`K2|2z{JArjY9sEi|6{W=`j$7Ez1juc?6FRxc{TUe+ z<0(=%ak^o?U$wnEeyT05+IlDO%(G@j^9Nh<1$pNLnMY4!&X!wywCgimytZo4KQ3z% zi8oV$_Jgb(Q_L0{aqej!BoN<}F*OTN$!GJAKU^Da-QrJ|!9hM!7f}+(WRH#$%^&u` zk<+ic;k5%3)~G#d{4V+0?yCSHUyd%;4#r?1u8)T2#32^TJxHekcD@;AK^538K zl4wPh3a_0_^)XbTCU3Np@!MP3S}&t{p?Ynsv8WfZMGzErxdJkaWe8re9eueo(DadQ z#>1_4O|Z6;f!jCtqR1lFX4DVgqblYIP;hx=fD+j|x0wRgPGNi|l*<5yE2 zNR^(BBciiNK4a8owOu>P&5B03UpMEnGMF-?LbEYYB6?3Xsxz+HnhPqD+Uhhs0=Y|n zR#eZwuce*XzWn*c)2f%4%pyBEY_Oq_Mym?m6JZt|zIiyLaO75Qx>n1oGJjsNdiMr- z?bRRMJOSAo)eCXP%jmyQGtRR?MAqQg;8VYaxM%|VdA3Apb*wDu;yre;D zxAl=$eFZFl0S%Jf@M>|VdQ=Zzz$Q4B-QSabxCKn{>l3EFM5-Kj-n)S3C)T}S<-C{>b#^1z z2*w@t6oq{er!;XdR-%13u}K>66ey>>-@Nd-W}&)^wXS6ixA|2AY=`!nsjsc1d`>Fw zcIhfi9qm~DWK9nW?v!L#C0zNeQlkBdk)SVz1(ot%bI$duY)}MKDlnr%4|igG9)MQD zQwL^RctLVy5BJ8B@-@|qh~_0ZP~bl6ZTlDK3+xfLiZD*zK?__Cw-+y0S~pYvzxGGP z46u?=ThF4Pe-pEuIVgwsRX0$eyi}}OMHKw?{Nv~4nU5uq{*YE$@YKloQA3g=N~|gQ z)G5Sk-g$QRay4$89m;AZ2|<|fyHI>B^QQo3SRrz%OsI~UWq zC2p%D264_wL9{~gZNQ^)bIWJv4Pj8>Yg>*8t5SVhLkfIpd!Z_X%AK*ZmAw)B3dlfKIs{pHwC`;oJaU8f6I6IT z-|~#Lx1Qs4(K_fAqG>><9IsmEFtEBPn4u9}S20c)9?0TvC-EFtHtdArj&obAyn1hO zE}DNEuV1XjF{E_#dGDR;;cnmtl4Jfw%^fYub-^d0>2j6RQfzoVk>;8fU0lSt^*CCLHupG*FVvL z-Z$ZcQQMs!!8_I@jx@OmP~bUMRn%yYcC28wyjL*`s@O5hJh0yLuY?F}`p==E;;S0K zL6@b~4-%3o1&=`2OB~^7hgR6EpH?v8o(b^Xd4C!;1m&C?ouvPC9z`KqY;nR?dOdn?kt zdq2ryukzHR6B*!dJw$;o_vZTY)hjl}yOm(G5O|RPRpTLbwv5HfdY zbM(GGkPM!&^H4CG@Td#)N3v9lYOgcvyLfCL=`bUd2Vs@NZKZ1G?1T3l8!uuUD;g$% z`yn4wt4=@Q;Resb$syP-gu1tJJSVa^ed%wB^H&}Ll;$Y0rCh44M6L;D_07^wV5FIs zAMEU3u3`PND%vf$G8M^}%B-7*!$nSgJV<~T5nK4j0N<&2Swj#h#KrOwg9b3eakL7x z(=LE00MpMBl*4=1mEWP>ND?%thNleqU~EM&Hd1D+#Bo&6i6G+VSLSwD=JFA#V@R_J zbndChdmsqBXm#_Ll~$7Luh43;OWGMy@nFPN$>I9#bkX^R--@l9$@uHCG3SQa6%?YE zZ^Prdv{adf6~G0Bns&;&!(E<-!#Wl<2O+XeiJBZP-?a;xsggP|{84 z_tpx5=ENnpOZ_g)8|_+I6E*Yn7m18_HNv~k-;)JSt&Of!8)a0m@%CL(U0CI1?i#%2 z6joKx9g~0~HIHtVg5DRN3d~nA{v$p1P4nT7ClTAbUFm*2(=_Wy zI5i?0>)reIo=OkwXK+nR=GInOLjskbSyJ0gst^+$B@pW_t(fYYsXpG}YojGoyqd4q z&i;}5x9}8*V&dKg?ay>CQ8kQBY#}V0Pa|!zTotof11irjC==a=34kJ#kC574!CJEN zQBOO0;9^Aq^eh0PhJ9U`S_s!cEhenw+?GHdzh}`>rfvpourBM2LN zi2c3Q0DxrT;iJ(*Pv#={7ME!WZ0YED7CTw4C>LFvqX=w?wP`AIcct-AMh#UETAP9C z9*P=1ME_8?*|MYh9O|qu_Dy*DT*0`d- zx0pmr{2g-J`G7P1_r~3Y+J%dXit<5CcW?;!{?RNAuW&phzv7l<(sk0Z0=zy3PuIlQ zMi-&O_rF~+{KzcPtm-t_HUw$1c3fR6nc7lN&G##&EPSL_c%o@Z(!_0;19RH%)TVgkgFLOS#(B!O2_&K?q@i= z@il7k2aR>`Yl(0uK;p$o$2)^{ev8sfJE!1=7*jwu9Ga-bm+=BMveT2bx93UTU7Mx? zM9)BsDEl~%my{)`+lFB3;nJI@4NM89rvcjoF)g3XdB27RXnWaG9+VRRqRy`m0f(pq z9w8#9U`nRXy}?{so2h>09ee-SQ0+Yj)Skl3jKdeASr#ERk7XO4*Z>C>0QXNdQR}VFlipVn3t2D(5m&KRQ7xI{v|EFVH{em5h?2yjL?F8$maPyyAU57o$=`ci?$U|=p0%7)J z!O?!oi+H6U=8so0M_9cpKCWe7KRl6l&V?|7t*rP*{B92N{P{>Tw#5{R3z8#QWEP)J z)hH#yvcm^=_Hy9yd}2tN@orf-b@ahrR!Ymz81s93KR0k>kUVuae=5Hmy)j$#K`%#A z1B&%?_FK(oTngVAN^>nX@R_xL_d!?sz1>?=^PFeuxh!0!&%)?~4tbW_ne${u@_R@f z0WG@^7Y!@7kWW|@N?WtN(Y@wjXvCz!!?imU-0WsketxlGmebIlPY?};b9eRPYd^vV zNIIy7SU63f_yRWO#N_c$we}h)WzwLk5M;3DcaAh10cZzC6oJ!EF($OM=ORMZ`^wTE z!@jtdhuGhE(XVd)riZ6+9zV`i|8Ef|z8se42|1Y4x(@wuee;lTGmG&LRl-$^5OaU2 zA5a`b2xA*i5%Z92<0{95&%12Fwokx!^M(Org9eC*)r@GqO zAj@Nq3dDIG;UBS;<$Hvi>IMynh&_g;58`b`IU$?!Rv}atrWV=R=O4t}Eay4QEuWrp z&StZD0V;pI)m7JZQv}XT`F6#io;AG|-(DE_6L3UbZdtet0!Q+!=%NjZsH%=Zhfkej zc-1R#)q2*!wDr3J>qV}EQyB53DlJ&n_{;aJ_VewT23nVlVkrh*8B#0HEXvx)nA&(@ z)4c&45L+rP<9xwBasVz3sAu`#1K~0t}+nD085Dvlfe^M#xJ@F zaY#whFtNnUBZJmT$&;mi!gU|X4(aNC^smj7Yf|@Wkr{1z90ujNsWHj3fqre?EP--h zC3WebPLd-(hqw&oPSMDPqT90y3~z!J4+0W`IDMrLlng;Q%_jYqyalKyvl3@Uh#P#i z-3-A40V=z|w@v&>aT(^fVf~I6p;oaMactJKt$@s`TAav!^H>lctY5xmIuIw?s$#rv zeGx~_myX=A@>YqO5SaDQL|;*EoR6QiOd!sbzTf~DJ(gTbvmdndOR&TYd&1UIZv&%# zVB)cHpecMJfxV*S<@(JFdjeJX;nhP106W6ST6b$iuo8EsurcLZql(j;4#N({)K6oL z=DC<X1damY0^@TYruh znZC3%J8^8LTFMU{Aydk^t#79Aeu5~i6PK46tf2ND*B2)rZ4 z8$8dt6`GndF_CE^C2x;=Wdt7^VoshrOy_ZHp9qe9rRcLst^dtv(FO?_0g|yn(*^yk zoG(_HVe|sddQ9GesXfDLOU8-;<`G{@2HORv;eeET_flIY+V zNBVBE)g|RQLM7*tMHmwlQ!*R9P9f$Wv62jEY+6dXsqz1Vw6C6 zKgn*l^;niyO&B}|u~f`^n8q4_yywy7v|A_O+`KgCg&MNH=FFvrVq8KxRArcOFnON$ z;BFccV(hp&Qwcs2NI43QRV-eoCzPt4@k^Vlh_)s*=2do>>);q04^VsVEINfjo$#H? zdAaZKEyh#+Y-TyAMlxLV&Yn@{Z0@rxBLj_OS5+f4xq8^|5}SVI$XZFaI~pq&n|@k8 zC}ZIl5ts>hvi5LBumj|OtJ{ubEQ}dq2hO=ww`cjE@+nkcrEe>8{v7?0ja7)|76qL^ z0{);gvDGhV`#|P7P0HTA)09%!pd#2LOb4<8Ln`=)RhE`L4F-=|8*EP{{aojchB=US zCNzAY^n5(Kk&(SiAigNuoja39IxltqExj_~329i_;(WS-#re0pt9-#SLPcKN4gO`s z%eGF%&+k=MqmW};l2R#?=#9>*zLq7nSNH!!f)f=^Oh99H;=W%;^fuXI@srXD0z}<9 z-gRhqGyJ}H07jF`R%ZBS@%??Ky|#jjzP#=EL71}W-M2)&0qKKOH{K?Q@xBiqON5k8 zVW1JhR6pji=Aqi1nYNXRbPYR$OJ%$hBShM%uDl21nVdN>Lkmei*7LphjwvnvvJd*j z1mp#2UX*CiQ`?)+BblrD9=Ce7!5GngM088`6?BnSw9%Jd?~ik)QJI=l=$x7x2=j4p z)iaJMz}9}h ziszp#WTzAi{*!d7LZ!$$kSRh8}#HoJBl_F*{WN`ikt;ec?XElVs~ zRE=JTp0U{6?JgUuiiRL^y?yd8mqHiI`r1{?67S}^`#lOrx8U#OHv!p}0!1w0^t(;- z^p_ITG6ZKm7$myDgaiC9GbEsf?`L%!FJ+r@s)2_5+I7n$IH|nqaAEdPO z7dp4IZnLzQ|9Z!A3vBD{`=ei)LxJPF&2@#Bi7W$!eq$M=|wp?Ve-yHlNG@I(T}TW&Pyj%KbsngX4j% zT0Kww+;BnIa{%xxL_n4M3T9&cSIH0yzKmz6m7>F+@1V>=cQ&f-s>&2=j9@Qg-VdZ^>0Vm>?G^;}P6F5FIGhZ0y|U+^na z?9?xkch*K~^Y^M1R3(Jr{3ROG^%ja{V>FmE3ZF=|PI8;y8uw${*IP*Ev>Blr*aXH+ zn{DXYIb}A__Dip0JC)T$Ym1+~aFXP{ev@mU1fCYja0Ap`CewHr=}}S7pM-+ez+#0i z=>HmiJYiI}lfGo1`<1Nw^UktNy4>gHH;8)yiFj|qj zA33wKZz=>u6>D*iw+H>f+ou_i(GFXvyOGK-N%`y@XI)bNs6YIIWNz-_gmPf?J6(H+ z)$+-k&D$WX{8_*-P(!P^rdA~2&xSWkni1PiQO+#h%)^p@8U?%X3QF%8n?@*v8m!&M z^IGG1Z97{UL{wz9Zs;!$CT=BLtG9cn=(CQ^ZtGL7=op?^>S(h46yY;ERu*!62yM{) zI02zs^4C%N)-3JRRHtj`=b%udId0-jjp$lmZol0vd_x~WwYlZkUKgNu=apN^uK3Qr zSN zz3Y3fT**x#Tw3?l@9oYzk+1;+I@8chC3<2FDio1f{NTU9KM`S!vm)Nk|Apy3BH zT#vC{#A~#8s73*@*?O||`kkZCs$zoTB=_CC>7iCzNs~XMv;FUV>gUSZ7<@{5E?dKw zSX{H0toKn<5U4!#DySn_8m#Kk;M)oB{NPzJ)T-g!k#@gbb?cg*(x4sJnNY{@)Cm9Xq>#$d=v3=XpYXy^PV_-z;-ddm6E!;In^)GZv8K(0*hDvH zhXqT3*NtIdBt4FsAx4PI4*;p+Snark{=!hSd8v{6t_qZGclBRO^#*Btv;1X2X3T}% zZdJD7312exlOh;W{lBPw?Zrn`xD02MrwqJ_uw>gN5{e#Hc1^a=zIr>n=m>O_L6?GH z3kQt8SP$70Ja6)SjR+n67xb@V( zzA5zi#}28*tGnxd!fX1h01EPRV7GelYX!Rx42Eu_b~>$#QRo3>H{=TGY-u@Lp*fNt z@nRI6#dWRbP3?-H1pL&COH6%eeg;qxsi}s8|CDtx%jmI@mdW&C_Ukw68p(8w=(x^r3!-&#OHY8*}$F4%T4IL*qD36LLcon{*w8)BFg4Z zTN(fQ+sR59&R;1R)6sZ2_DM61yTjlRzV$@T++zC#ru%++Dd)Pmd_vKmlJ+6y#cG1m z^C<%t)~LCv^nxz*d+K5zx?NieU^M|OPkyxtb6!RTS$M2o7A5nFlrQw{gMx54#^4s? z^_yU0f-uW!b%1-T;CRL5QFgmrhrBlvuWOIK#O0pu=i%a*CklgYq3Nn{UI4aOZ^6+? zhc5*j(mNvgq|ozKVJG`3JHaB_?jd?$le5FMr|MI^;5y+&SPWtQ+)eAykF7bv5FuMC zA^!RTJtje1!W#KlTtcpyv&Pkw)U<&W$)^ES6;y^?wp8=r0tow2?f%vQTZ2~rfEy4j zYsB(z4$CN#KaN(}aGjx-pL;g9JLmI2XvUWRy5~4w82!D6^-jwP!i$$T;|y(zHJeR! z-yx@owtaR?T7PxZid#WGW{cCcM^9$b&mqdL)#u9y++Kt0v6Ps+)zK|Lc~42#Cn+2A zhG^C6=jVAbIx6E{L)onUh+P!9G4lid(am>qayIrN>QlVKH#$o2##S* zIS`yZ=D1@K*^{@$>#UG#1I=2NFV3=9JlN$6UNR|RJkKXYWN4*cMkJx5I)SS!qlE2* z=Jz03I`^#oFrV>f>AHmq;K^14qLlj10n&Nr+0ulHS9BiDS{%M7um+21T&!UNfCMDr zoo38kvAMdY?$>yARBV(dpv?F(lKmTsqi*CF>}_)V#N?-0a)j)Rq`D6vXfdj$=^4p~ zPl47hUu0ad(^oX|p!{g zi;k@myCn`@Z0#o(sOCDSQP)?H-G}6YU)0QdN+el(dD~k=dWfpIP+q?WCy~>&r$_P& zKU5Hh!1Flyc0n8e%6D^NfTkRViA`BCpF&La?qbGdt+q7kv-4^7b8LTuP8Cy%AEHyr*R*1<~ie?2(tB2SX|`_{j%cP0NX&j$ZvER9by&h~*d ilSlmj=wxR}ps_XLE?P|MvW(q~NK&B)MU3obFt(XtY#~e8 zvdx$oW0LH~ZU)16ZY`hZ`}^bj9MAFmp6~BI4u`pCx$o<`?(00y*ZDeMXS9)l&H-*A zZVnEP1G=}h?s0JJg>!K1db@8g@J=(o^i|;BKR)+#Zg3QLotOen_Bdr*H1 zcr|N&xR?n-wHeKPnyz=_tiV7`EBx*^tKg+9jjgymo?R_@Vf6XX_0#!Mq&9BV{a5zL zZ-*d0On7@&DOK&)y)A=a&On3ak260^d zzDZ7YrrAM;>_P{jCr#Bk6t z*~V$KH4YaZ9&Ud?;_JrhOoV@RduQi?;Xgazw$oFMfwrZw_M%|s9HT|pbB~_im+o$y zWO3!`ag|RdoL$4brpTMZ3=lU=20wYadcKYoey+OXgL2;%ERc>Nh6Bd(>xdT^;d{Mj zV`a*rFIT_(ijie$nUmR(eMLFM>#djZ3A<7#$vDj zc>Z^mVUIAh?+p=fv6@!f-05`VtXub;oN`5AYarvP`{t z${gG6i>Eu^%e7Kf!GyxnCSKK!@y=A|ZjJ34X)A0;Oi>n8EOg}!eW66Zm0{=6g)%D|3RQaed0+5En*Z!*oCa1uRgv^DO4N-tUtcd=?L0eJ zItQC2mFG!YR^(drReoTi+B{0*PZUurA)wp%>_>+YC%jfUxVjs zC&(Cw*4Q>o`nABa+NH0O9yA1;U8Mjfbfn0;{)lA(&%PU~ou_D+rZO-b%Cte*)z<+g z&{(%IEy+}ds^x)m{9=yFwLmDvHmWF_YHYQcinE9nYx~DbSt$jD0bcbrd;i(#>6Jc1 ze>9v$p$&nvZpBzHoRO_r2xp1hJ0w4T8PnON~OTi3x93Ln$WTAn}Z+nYLi4udkEKhXf>Oxs$1){Zs zKNXsMK=j(6O#P;}xp5hUqR4z-GO6ei0xZfh!fzx}kSvWG`k{^<-3G4Bt!{iJQg(a2 z8*a_=tXaHO&6=yG25ye3{CqG6N>cok9yeCjYmOB{u*PE>?V|_0yhh?Mrf>w_u`f(fiZXx9`HpI->eeX@fA6FSR9kYwFG3D^hQ87Y+NuE8}2LZay z=#cBKT+sO#-K9;LAx|zNcOmCYV?bzIwf6RQpMQ@1U89oulbZ$4Rt{3kDQn_tYE(5} zCVvYs@ml8ajOdSG+;9*o7_=Hetn_j)=lsrG9TnRighB*r-2q48QNPryCtG#ddb7>} z5;1M487=X!zd2=M>@b#?Wyg7TRk=9J?W25Dw}{Rl?a61uJ}-^Iy-W&&s-%P~CQe(4X0{^k$i zw`!5W*co*FaAYiZwoL8HJysur{j*UBH0$D?YGR<=9C>28%fO~{svJ4IC{wrg(BE2P zJOz5;aLqIhwT6B+G** z>fhr(8qbPQxa7DaePvXN8;@gjnf|S@B2ck20eZ2uHfHN$6b4CZRJK(O8yIn(`-F?jP$$;4QnvVHMF7h<={u+hG z_QT1HneP7?ae1sZlcYx*W@?t2h(j*dUxpDi=Ze;4E0*8)LjTsU#eb?7wRgf&G(BTz0?Q@N?uV+NJg zI2Z0vd8apxXF&%FHgrv;nbV7G`Pb|*RwwTFLPWmvgLa}pg`#_Fp0<+mpIA)Z$XfQ z;pCIeK0^)2j;k*DJme+6_uu%|Lpmo$@VwS#kD_@Dx~`7?D@e{S(@vBE6N@p6qpj7f z>(r>J(9z~G}Q3ixu+X6TP@u7%RPT16O5V(d$U zyS`jcJk5Pl-Xm5*+dysAR50G9YVIFU!^MD}K@~jOv?pO7=b4So14={RTUw2i9muVz zo^?}rU&$D}ZeM7T%n1LUf{n=`pKhptx)9IpQ?a{*prAaDuD$;r`@XBN_tB$Al?dT9 zMB@h@naWS>%?XX_61^4Vi+mKijtm2WY4tQh*t4dm3qV}v5BdR6QoY5X*noP|jaK84 z&--DuNIh-P)zGz(C=c6)1mp&PrNnoMg3SGYuw3TA*Y0jK{!QDHvpF73{8F>h$ZzlE zoMT0NziAey=unFyCj=(*XB43RxyZwyXBRmR#T>~R;}Q+XuqvKw*P^Bs1S^18`S-LN zUf&RbCiwk)qk}IV>~GG%?=v;`nm#JM@owV-*7*6yX#vo(OBFd77)bRT^-h-21h9vo z)EaSLDH5Q{4B997svSDMZ33U|^KVv)_&!k$2B>&kEH>pzbW zi-vl1#OU~|AuByP^c^?G6XkoLf4ItLf?VO+=RSZ0c_5I_DSh?>sT%M){q$=jnAWGvJZ(wnhQZWU}DL?g5aO5;yM&ac1*)+Mc5}V&k)i6Ph!JQL-j9kCwbJa znhBoRT1ISVhqv3BHfMAy(e~&)?DHd=udoMT(NNL4(9+Lj z*ifZc1KDP?s@Za49UECM$Zs5wbujOHj(T%0lG}p+sJQ$Kb#}fTln48FM6)wU`Ay^e z$76}+jSX4SRr-m8s2y6;chNoDXd{F(W|Vy{3QgnrM~cK_vPIm0J?*ct(y>DMGf7U%1cU4 z7VJ2c6gB+886zVm@ZO-31#d|CJhb@ZE(*SSjKxyr8LHt+G(BXR0#U8QS*5cw2NzkJ zj%8MPeihrz)k(EiiJdwxi?9EIi5zDU5(nV?5+6dAz7WctyX~XzTUw@U0iGV<4G=d{ z{D%WuZ39LksW(0}L~tdGKjQ9F-pLei#h!5OR%3p!QgrLT=noTc{Fb3fD0$HIaHRX& z$D2ig%i|0nr=UFH5}Kil`V>bJpq z$70hswFO|xH{UP>m;mFV7FlqeTSR01&O0;xX;OLXwfop<#oBC7 zUmoLi?9WL>h6EwLm07&Yc`QjTTeXVt|Ibj}(N8tfZ)BXh`K+?I33>XpvBgJ^UViKT zv)m4_Z5FLMD^Pa<7n_lWRoT;lP3cuX=`f2XsSd_w9)zFR>;ix!eeg zk+>vR#KtCo16_|FKR$Og`WrKMOY-UsFX@#2auZdt6CDD^=8p&7-~+6-JN;D4c^nk} z?3(Lk`MnDh&4PAAkXK@yd>~TjAR4{}W(KVen9m=*TEHz%IHonw450lvWWY0C5h1C| z!tyS!0df|M^Lpbe`iq9Ez9STTd*lr=0`PL}rmLe7c^d4+xHmKT#2sQ_ZmVuOv2YCQ zHmb;K=Hv6RK}NTXD$l>WIm8O^_Qu_x8>c6V9xl4*ZdGL2+;lO9=@Y^_|HkX376j(; zeX-%h?=|7bIA74apySZ(@=7emar8p8XrIm~&3AsdcF=Fc>xsOF;R1hz9t+UiA2l?gSUj{IS)&|T>@I&_888SvNMiC0H_>HtoV4v;RT0OLl4 z2*#@zJ9_f8nPQCjbA(^2L8U znE%Hb$u0^O!t<9xzupP@{TSlA01jWUMzSIPi{dy{9IHh#ti}5ER@D|-Q8Gd2NS^gu z;r`74*Kc*})~!o_D=nax07hh0o?{gA!5&c#r!LJ^N9z5t>Cfl+(ZKj;%dwrI#9^xRx_B96j*FrB0s3bX7^MLvgF&USt`dKZiv@V+ z)XuH%HmPrfJN|%->jyN~cH4`+18MoHy=w_+U}yEJvsb7~W(Flr$INP6HLy7$<;WFt&$z| z3}Tj)!&JYHFBBd<_ocJ!<8GEEZM(Xa9Z2LPWZqYuVG#@01VpP4q`vxVq#$edg<#c& zZyb(&wV^jzHgQg7Mn?Qg9TrtAC@hq59?blHt=jK1cRQ6~Q&RED+j)@7B>K%KZx7V4cwo3_aO% ztkOv5l#vviWt<{imz4k++DH>&#YHMQfJhOQL+AAL=I5lz*mGFl{ZoH3w6K(qK(U2O z6daMB>VP5`lxVEpTr~bLK#9|UFWvKj{&n1H7_r8`0z2m*OY-d%}NbK3- zleRqA3|#Wv1KxDCg3;#sALm-EOUwLt+oq{&-aFy5hyi|VfY&%*7XoeHClvi`tN^gpaaGS zgqAP-OjTwyih24pbe9s<-OpSIc{r-G)dwTTa4lWb?s8@@21~I;P51p^-De(}`uwyc zB-EEuL_5oZoO#ROb(e?L1LrweCfg1XtNAYIZt^2YO24?z!kL&Ey0f4dsSULM&tv3x z(ciYg6C!>?+fY*nSitbFKYKu(2l`+{L}a88&cj*y#`5*cl<`4IRx5cW=)E6ozFZ2jZ69bc_b|1# za$%KAXV6P$c3P>#c2pj0zO*2BF>k1dmW-Ni1zV%B(xl2W@BU`R{T&`Od5ho$8Fvb{ zag4S{?)qDZ+=an>ua`w$-E{<|t}r8t-%)m4u8S(qe36Bc2m{};>JV4`_xCKM&~bJ@ zn9yi>!X-)08Lw|AC{+Q$PPda3Q@K{2ixYF}<-VT(Sy8?$dyRHOTdlcY^-`y0exvjF z36?v%*z1wE;9Z=uUifj-{FYTPV8I> z4UTjM9fK)Ft3AX~*%yR`_X`=n=^vwf)=rJ6Dhm!}X2R25V z7=0d2eRdl$Hi0m{8P&)6q4&^f&Ek`v)FG+TY}!R(Rg%-y0s}Cc4RIlu+{@zQOovM;9wAn9qbKNH7(TkY(wFN_?j2d-Gn#^4M;f}w1%Wa3f zFn6FxIk)(xZt1ImnGp^}X@&vbJKF~_xWZXwhF-o;U{$$yufmVrZ<`UO+%ttSHKj+W{3QJNr z9z*{j6En2b5B%6;#1?`1Vv9(dA4gPWgKjh!x+ZGu(BD&idDTRq5NxqL-dP0X;C{2E zt$1R*(fXfFo}mInek1x_>k1NdM$utFQE-oLY74Y5nDxxhE1AD~tu52&;-Pbq8VMH+ zv4w?&_8$H~R!1nZ!U3=T(vcj3iypw!UC3-ym#o5h7<9c^zQ-y%_%gR zC-oJthBTOIvT9BH?LuC^J1*z6Xa2PmfYM&~KLoLB78-f5PMsYy zRigh=&?@z%Oqpkr3}&yi6&bcVO(G1Sij0A*F_090PA~s7axZZ6l5TOmg)@%SKkzvJ z3;%}u+9r?H+7CUf{n}&Jk}Mo^K+dVsF>`%)ioDm1&v|`siYKY8xhU&JeozMRQ1872 ztuGVn*$M&4mA{JN)i(K?r0T!$GhYa~2br4UMw=g+Lc)bATn-hiykCW;k9iDx$R&@H z`N;BEPb|H{Cl2z!aMQmIqxSPt8*9srST-IrLqZ;~qO!o<>K$d{#pRL8sk6vAy8Dv( z%#b>a(G<&=eX8yEur-%K%8W5X&%p>)pchbOc?FjPhc(Ce!a@zoojSw)qs3jl+g-`}+xBo*6Gu}$TRkmmt zk5>p@a~oGHVqvN0L?@uUSnhJn!>;EYh~Xl*K5KN3#4L ztcJ~^;;;LDk6D>9=n(O1u@ur8MI+Uvd37-nDf0g&nR)67%9a-Eh-pv$HanyJrc+s^ zq4HgEEvy1iH8$8To%!QJkky1Dj%f3HHx1^J}zMnOAo2bPN^gXTX3Zl9x4 zy<@hsbVs-ER;?=Hq=GgP^L4T%xiP#YEW1=k4ETMpEJAwddy*^r{UQ&wY-|Qw>Db3j zbPe*EUTR~M*LB6XGgm4j|I7iJS{Ji3hu0HvN}KSPHm}bvoBhG#O{?q(xW7J%ROWe2;yM6>nk&I)GE$8_aS^BkqvLi2EaN_3)JGT7Wi)MtF zHk(X*x|O5^PgekxK0?sh$@IvA!%pPzRX+>MGn7rbK|85(pf{x-cMerwij6ukxeKu@ zXGtzUa#X+yHdiV=OPxX$nn{ zyFLx`%etT16t7P?%+Aiu9UR>b7)p{^CyTDNzqXhDqa*y3Zn4_Hg@tYW%W9CWF9GCI z_W?R)$QznRD0AISS*J3w=lxR^JgvKHZGG?I>GgIH3ffQFTyr#eX7!cWiHBkx))2d* zHXMOVsUlWd=zdgE%xq-zOM1pFE{pR1-R@ppN`7AoAhT(+i5^=o6Osn0$?Q+JLYFYA z9*6`!%;kjS`>cvvig3p|2yMNVCrReo$3#?@^4j+Zs^7&MfE8umS~G$DjfAZ8AoeUR z2$O(Mi+Mi} z#W|t|iv7a`Cf`$-wA3Gw^uWMoWQgsDiqCt~X3gO@pCL*KmXNd}xooLNg;9IyHJZia*v4OR{fi*92v?gRfNn%xlv zZRVFbPtBmKy}}gH)>9HsGEpHyq9yfeafkNb9XQ-vM>N+B>aEzepzpN-h<- zX6<%g+dg_^({$J0`6Z(_qn%0S?Xyph80;JWJ*k6+3Fl)X{I%=Y8(`IyZ#N^9`?X8~ z1+1GC=e5Q2zrXXgdu6Kc_{+R!z)%5nV6$G{xx)jU&$LxT3Dz9QT5_IGQT9o~c%*q0 z6ujm99aBut#w?b@BlcqLYJ<#59P-AxSYLTnrt=$_s_x4#1hDX?XK%b<0IB>Cz*Yy; zqo>0cfQwV4H@~DkaIjtfl=N17(-rJ&O=yo5x81t4R-XJ9#hIqZaq(8X(qQ)_#U6K1 zRSb223W>Pr$Egu`U4{mQFrJ=3O{VNtj1UP3FdjSAx&?7lLBJ&9Eq&J#R2^Qau^Qs- zWxOEWYtgGO?!foK88Uw$aTsz$;)#%A#nucF2bm#SQQz`Y(vt-X*gF76x`Xtn6|2$a zMl5z*o$kkeh@lj=f4qhxSpi<|lX{L9MUkLrCgyRjfJh)$#7MCIBpZxFF{=Jp0CNo{ z!`D&L$JB?8)~&@`VIA9#;%rYDI!!n+#(}T{_*+P$Ac}gW#wqxK7wZ@7?R*=60VT6k#EqLMZs{6o^fl!vRaI zl-YiHXDT<#g>-^Rnu$}R)MmN?CTfr9TYD!ro4uzUK8;cP()Ik%CP!(=wa2e({Q{h= z1D!?ow((0!y-kC~pv+qZ=z2SuxmEi+gg36V+ss9jy^y$kn>@ zzowfnZaTKye3OsVOSJPJ&_M1|$}#1#V;h^tCTh5@R2YbVuTEJAt=*=$%U`YcK;3Culz zbLIVldW9if)v|`s;-(Y8jhotG>w%nr1kCthJ&QUYp0g-^a*0(nTh{IlNX>xCX}2As z$9YS!=c7sHgq;W|Ir!obuYPHG?W98_+GoX|KfQ4xhdx)o4f`d+Q|r&t;lo`^@2z7^ zt}YfoSW!D18gp2A+YP;V*>CQ6nly}U(yfBr__{PV&vNIcrA;q=PkK zId`YqNY&i_xrxe}_T^J>AH1}rwhlhQd)-$W!zZ@6K2vzfh*$aN!C;`iewx0JKnAi% zCDo0|EUF)%V_^VAFA5+JoE_JTZ}UfQQN7!x-;7QPA=5@UZcnW52vnB|iuhY8e4Zxc zbt3<&3IaUg7b~*eKNIpS?U1w06}=*OSgqG`jvtXTZ;xIFY;g6GRhbOY32iMbrFl(U zMAeddUcc}G%FIkdx>E=PnXzRm*zmyN*coE?xEjkk$9&`Bcv zK=M2;dS~V%&iZi!=Nxpr8X`Upbx@Ma~V?b=|QET=4AyId*Wb`hbkh zO|cC9_g9)bX+Z7W!=7 z59=;s(i%@h-cS#_hk4Uw_aMa_c!XymJd`@C78A73h;pK-z@E>9TyxnO1?6_3+&ru0 zM%t;`Tmvuk10jlz!{(YyuX+vpnSG~B59Mj=p5B?k^ohZt3+a!kC|B-!K7ZU%>N%?b zjgit|d3Fr#yje1s+=7PZ+|;oW*$6#mxKTA>F;{pW>t)dMJ@&AAZ0?@^Vs4prGJpc`G_=fJ+00Tg!yha#2$q4pjq+3<;55ocV0))@QT?gxaR7x{Y{B1xz?Hr-bj&@tnHBU`h%EIa_K`{vJ zsQz=X)HNY=72#YsF_Tr~l`J!-fj0kW!^cRB3P6@xBk(XV^f6ntrOnU1r6l25P?p@cbX_&=gDi0 z3u(AmdV~nZu05`9)DH(2Y4t>9+&YX`jGV~z`PVZ`ci?t#0^8MvW>Pgz-&K0w*{ zxe2pKe5!b$=4DCI&=0RY$L$9kpBhmSfSJT4))84(0}arX!c-HGz=`(1JVczLob64 z0$SaEH8b5&%-ZyROtZ#!^J5uf$Q#k;Ha0<3S?h`ra%CVo``anPy1CB4x@d0@rX9ZR z7NIUir6T4oP|Zgq&KR5rbSrS=0@2Q#6;O(G-5wRIHcvDQ=2q%=eDCrq&B@r|OMa&IlNao!yDKSv zOT}L`45{Vo_SqgIiYnN=>)H+7mm}tVS(GCx&-lE4et-3^(#c2n&jvxxP9zj^Pk9#u z;KIykA#`MZq&57U5!ivt_ivnba5*VzL_=HbATEM}6?3^c^|nuyYgn#qwGvFF<<;NsHiIXvpKL((lidK2Hbc0GvEzO1N8 zw^UKA2B76?7R^ugV@Kx$D$U^UjGPV&%X> z3ryL1zg@|MRa@AQK#3I3dTOLjZ?!*y+LHMzvB*%lH)hx_*Igktw8Vq5VRA^Wv4i!t zN2)wR5CG<{D)m2FIP^%+Uk?{;SB#zK;hueaCWU0TUERoe`2&eklh4wxA7 z^S7png)jygvA34k6b#AIoKkqE8*nK|ZIZCtv&g);5omq6KPQ9X&vw~92Qq&eDOLks zqAxvpwYJ>X6bu!akhICJST@vhoe+bSpr-(&D@k}(o1;R#$^D#P$h8*R$Jk)6s3j#9 zJYbV>Ciby_ z*8Td*X3)iTY`%?S(dHYi;+S0-=~=h%V`Q`Qwmx)Qo-nQY(beEfa9Qjx7Z#>f(5M4< zzmM{xzXNFq1?%K?((G6H25EjU^Y6n-QXz1oEWAgWl4tXIO5JiWPW_GRII+s(VF*Ia z}WK6&4$8QE0AVYfxi<-gStXg=L)bG2eK7iWI`CZJ{Sd)V}TQjh4 zj15uW`lrn^N!@nL$4uy=3r)RpIiX9_7jZG42X2nHRmrWd&zyppLSNrdh*na6TU^^E zj+fMmR)-s>HbSHfp@$fv;fSvZy`@=WT`7*j6CGa5Li6KIGcW!B@oxi~ARvvSbEbPh z!yTbZ1@x8dzDrYWeoqB=vyp#DND{-`y(oORBsTk2yO9Xs_mLG&{4sC(e~UMi3o2cPaM;!u*`7=JNOl#^DA#!=0a9T zdBaxr=#Yy3+WO$N2?4V=*$(|rk=YXa;cvT|g(N@s-5h&7n4vpx6jt+L(xd9fA|H`y zTFCXCo3mnma{6B=F$dc$oP5E!=ZSvcXC4vXEy>K7U=#i7sE09pIV{}~UEj8>?_+Ie z;_l{$F0QeB44Z|;?l4U=2O#;RB+m|~l#fDQqbJODL^ih3; z`ItV@ZmU;X?`?QO!uF!Sxn_1~zA(l>qlz4JgdeLWE9-5LVoLR0%rl`@J#XRZJ*GYF z*X3zazu*t_>|{;}VP<=>2HE`ax~GY^&?$UqVx_i9T!1G3FF=2>%bfl5ZptGbyO1x^ z;GiL|YS4BF_HhJHko>u|gd7ex1k5T4g9vE;e3W7#-g>uh&YftLR>u z)uDhxPn)craMJ?a(-au2a5ZVj(2U^Tk?wKnadSI$yfa<^dNNABPvs#1s6L@_#CCh9 zQLj6&l<|?7Y#ZdNXX5@`aB36)n zo-Ck?MDUT56W(0+=jPUx?c?>dg^<$|V%-sZ>K2ayoiTsN)++Jx1keQ2628+wb5co( z*lErWmqsWTH{OYn{pv@s{lvNorI=YFQEPFB-UIQZcKJPqUbR?rJ|M)d7<8&K@|44I+|YL zzV=z0Q>@F9eqKZmjq<@&if;yLtoyn4PB5Db?nuB*r4Ncew@ujFW1eht?m&l_zJM~U z1YXZ~;Ir6p)O^dG(XqASdaYJ-Rnx%B!Hn59b@>7tLyaxp(yu(w)?By4w8(dO&SloZ z59laJR0Z2&U`%wZvzd;i@2I(bXA;}iQSGvr<&h{cKgy&^K95{|oK|-|zQBO_8tKq~ z;599ZFk`#lA98dn)J+)FrG-<-dn&X3^$xAH>s$zIqj-RKn@T{L%X-_U_#&FQM91&d$6;QDIjWjOzeyA`ghZvQhWu3+UaGlZ%P&lUn7ls=>Qhyz&ET4tV?2dhZ0QbaF{C zeQ3RQ?578YS6YY!!+=RIR;_F-B3>Au`z1DH;X69+T9w$>3Gjy)F8mrmJ|Sc*P6B4S zK8k_^JgqCu!@`s28J|B$Q`o8F@r=BpkuT^q(mO>_<&%C8+AEL%*&w8gnwuVwhm7pS zb;S*o%bHJ_?)}Tw3jP%}CN`O~3){Pfi;&J;cmYL+)x(s zMavCE?j9o>1aU5_ZibEk{oi2Do!^^sL>deAasKi-8M(`e8l}h}Z^a2RL4-!esp2Rv z^o6DTDNf*f=#K+vpRiOSm^dDVhm2pId;U(cj~j zQZwvq#TgA+%jy)^0q+RV8}0P=C^0ONcitVGdv`xJ{~CKxB^T%0aZGr4^C0dn-MCs^ z^y)ol)BJX9$YXFVxMhetQ8uq0#K-@49k)J5Ve;GSL^Z83C`C z3F7ulZBvM47k>@jx&{|<5RnWSPWgJoR?4QFM7Gg5U&dEUEOQxgXvVihKVPkFfra)a+53$*BWDDa;_;zoa==Gaa4Hg5+PZ{s>ir3#rAG>n#3e=U0dvG8rWzSu!}zZG4-0T7BJMlLw?Pxb3WPfNkDG%G2Gu)gFnddzD({ zK`QE7hu@pej+4mblm(zG8A5v?5wz`^Ltp^)Zh(r>_hl@DxKYfpSm<@1_s`8z&h-|X&tDyY zBu^^T1rAm`q$L&y2JSv7vb?@6jWy#^*q1b$IXZo<-w9rrID;b}xS6-t>aBrhj{tmq zuy}e{#=Gu9!Bd@k$@d5oGA#65e*4?WXH4( zG%XafMILuv zBAasL^V_e2Ib*8#g=0tC>I~BA`bl4)Mb#HS2BFIM3;&PmkGZ z^PyM6V2#PjZ@5;rLxR(x28N|pvU9WJn9k6xIP9X`Pc6|xJFg%stIbE~wx;BfBY{N7%)ObLd>T9$*i};!GBULTYzufcz8bvKmxBS+s zABeX0*of)c9x+|b?CBTfe8>&kgvxZDL3cyZ?COO6XV5~&z6}}oe&{#MzjlT@YkPeF z5bAJz&T&IbsIT{ewzHMQtyVc0b;UTUlbTM9ugxdS)IfWXeplJEsi_9?X`u)mhs8DV zYX*h^v!XHGqqv?cMLaz76N$VckX4=L>i%9YXb9#eVBh_9E`fo8gld1W8KcU$9gUAG z>FLe)lNlEdsqedr0$cuUz}$$bMr;o);bxy-^OcP&B}v*G%!pcvw#56D3-I%+4Ki1Z z;442Ji?5vXT#mJ$l2N}T0d{=WrQbjjPfO+0dm*}Fn1&m+NeFoIGF;Kv>PYDYqQ!&O z+#*$fRZp8EQ0=3|C%F3pCxe=~oBE$=PWXEh`^^QWK&LwO1%17j)5*ni-@j5oR)J`* z3ZO=f|8!fx9`Bd3V%uPL_3TQb+2X6zHx5O-#q;4`v?i}Q zgxk+_>QHXjr?{NVsO9Ngl+=T_jp3FUKTaubCI0v!+O|tO4S&Yz`@M9eSWi_!&`r<@ z^`AzGou8IfwZqS+*;Vek;{kUH8gX7e%-eFfs%1lFCGFzpUjMUh2}pl4e$fj(8M-Th z^b6LIBl?=r^JWIL#IE3xBZ7%j)i1OY?YUh;D&yM}44(2?@h?n~U3=FP6&|mJk$z%O&La=&@rWVz5)nnnOI zd-RrhSjaX1qTq{Y4~!|PU!tFC{*F)OA!zGq#6^u}GjK@D_a{cGB4Sj;mqN)@o_Kt)m>|3bBLXB7q)1PP34$X-J1rj!KhW1Zh6l2{$H%U zc{tSj|2M8WQlnDYI)qjv%V|N`hO&fgG4`QI_ASP4MkFC5p~$|EeP_mUP!uBT*oN%O zVC>r%ey_JW-_PfBeZTkbzVGY0=Z|w;I+mIDyyy9PJ|Elj@$q-x0th3gXY*7duwKn3 zfP#HCg0WxkI!kWM!To4hrC*Gj!3uB>ySiNAT{ev#x@`kKXkJ@&)%n`XYd(fY=18~f zN4mVr19qQ?y~5sFqang|2{--k?$zPbmu?`Ar@*-UPp!@@~05p5SL~ewlBYOsKd$ckeGRvK3q`%J+Pn zlb*$Hri1uy^*H(JG9eQvKo7+J8>i|M*k-!qNDD)Bd(%dT5{qmHHga=`CH-P)98CN& zH}5Wddyd6k#O z{qa<#m-QU}5*-Z0p12QKz515jBReybfscNq!r~p$f;O`3zSWPf%2K8WR}FO@2XYqk z6YjJo7%SQarjt?^XS~+ma?@S`<>I1>v#4`2m2_wFjL=s2iqW`5;o@ba=t3>OmLiK} z?^|5A=FfBKj)4=s!QyzGgR-$M4|*xy4sz4O=lOGcC%@fCmT-6tIf|HmJ(5Q%TUjCg zEdZb$(fq|RfZgQg?q$v+)fA14;@206O=8Y77J7Pmb)7+J0Yl)$srl_%?{e<{ZE!J+ z&%XZ9Lw8>;)J34IGou#*NTN={D)Mbs(f#qo%(y4mqZ;^>Xdb0V8R#&Yp1U65e9}30 zEQBl7uCcj`S@#lnff)O<*L{8nYkUBJpI*iDuWDFlFk1q*SmXm(l-IH3jZ9@>f2~on z5~+u%U*+hi1Vg9t6Z#S&aI|ZK9yPuXMk+H3 zW5(Y%y~5F0tU3Pq1&5}rj0X4#C}qHspo!jKv)_ENI3HY;IP~*UcAiXJ=Y2cL+hKV} zmk}3|>DE%{5*81$3T&Fzy~G=K`ME6Ir*!rSj8eDk%6A();p?0?zb%MXCCFM(mhOm) zGQ>`8FmgII2JpaG>RVcro+!F~;-I}S`u1Vd@i2`mb7g|sk2T-P<~h2(xr8+Jf7XHg zjQC?g?NIy{xwD+7_uReZnSmLPz{b{P!UIjW^BGX%<0Wc8I&J}?RJ{ z8&T``oM$y$?os;uIQLQWhMuG2$bIwO_YJZABl&H|rh+WyU@!S|@5XLGux-l*IS0s0=HYPCvo03f0(j_7r|oof zsm-I2@4s*-K!e6mjiI>29 z@{(z8cQY8V(P(SlS3*HsFrvE}pusBd{ElMkzKj2D_yaW*N%)$q`&Mp$xZ_K&4=W8R z`m$w~o(>HrPc$S9YKfMN(>aCZi!+O%-VWf^BnQ9?bhw33tLXlOkxv|6$un-zyVT3& zLtNzLg!rEWsTZ!#6WetL1g1F_%Z}5*{XATPytFAA>P$pqNpM4M{_~2X+_7vT*+7QI1deW z&x9WX=>o&*{GacZ5oNyc#jo|Z31|i(1du4JL6d2E&<|HDkGok)Js$a_20O7&C0m6)Dpr(a{tUHkF4$+^6dugzFaJ-4cF{ zy)-nBjb*nYo-$2Y?8X9>yWCR=4*yFS&*|&sh9u_HO!^A{Y|+Z~m1$9PR*m2L z-XFg=QvW!xa??0B=hF>m!4{iw-!xAn$|c=L-2%iJwdl&_7fN$zRb+!)Ibs^UPb&7k z3%xk#vBB{YF8sc+xT8X3)X@&)v+PpmPOz?7oaYjNlhnqEZesd^ut#=x$quYJTkU%n zBujP6?O}o4R}J0R?@lf~TP#h6K0$k{#ddj@zHzm?D!XdPXFtyFGbvqf+TZ%>!5PV7 zbI>Y*KlXP`%7GP=Ch_po1B0DLpS~EHHk#1-u{Z}sa#mJRITxWCa6Sq)WuujKQ~CG{tr8v`XeqVf%LzG znX*?IGcM8cNgwNP?Qg&1{7D(#DNspf(*5_Gh~S!O1D<8HII<0 z{-Zgm=I0^GXT5XW2u;S*??M@CbQ&nvW+^8U3}T<16i7qIJwDJLsvAKs;)DFt_QI@S z9sOeYG&l|2hMdP^DX%dTgQfgno2JYb+udr(`9jyJ%E@?6uT5}d9E~S@vrVyuAI#^A z?5|W&G7-Jjon`QC1MMq+gnQ;o@D)i7iv<1v^U%n%1%-uGh8Z<-=TI*LS!Z5%K&0C8 zh}Fwx=V4hzN&WY&`l@(^YKgr$P^p#R zu3d`)tVxe;=V!JuE9RWskKO3F0C6saD06&5Tk%cad5iv%nlzCdQ-u=2s#oiz3hW=` zpsqn2B)$?*D7CeT>(ZQG|AyyF-P_)fD4&NqCU;v;4%1K|BHt z$eZuTcze@g9h}+l!DK8NXIw**2nKP>xvKTWEvtYTyyo9G?BqjZh3IK7xx)7=iI|>_ z-npM+FA&319A(d`y(TgrYlWKcz4-Pn!-JV#m1%`ncezegFV9hNioa!KVYsHkz+)-z zbxle!F1^2r;gjjLlO{ToTjb>hPn<%YlcF;xECNjVg3sfV6GW*)vurys36;QkM(8RR z&;yX@v1l#Vt#AHP=3IJr8G1B?al*s|#QHKcsrDkEpWM9UzJp!yvZneDr`#Fvh`w!WU6g_Q>Pfvmed8y7P6U zr~$z1V^NU-hZ$%YU@T|T#%C|?|DMVFuAkEo_s%?>zJbNf0$WJ4^CD16yFT&Xe}nmv zzpCB$^V$cE((c4nalMo~N%s^tCfKeUs*9&&DLp`j`(Ll92XiWpo(Jt_*z)+BpqMc- zn@+wh$jc}a3458`0HO{fZ%!`w3U*iZjON?dZyOQ1EjWDb_fc+9se z`M!}(OR8jb&7C^5JuVlJ0$p04&rm3A&^P^xp=Y^<)_(2qezqR*3%Ws1Q`OBnUWfMr zxyXTd&i}|Ie?EPefry424a&xsGI}~esZYx!NL*)d7rkqDsAKHRWquNCdEfTRt!q1o?$?)X*Kepl-rLZ6!2Zo7qmQ6A~WU`DB2gs zvyGX!&upXM{!8w2V<92^gza3%rh!IhU>(~r=UwVGU;Rdj$ycVazoAH z#3imD*VeALNS=T$+=KJrp1g3$o>VUKbe_j$v?GpxwP1|-(gRiOj9zpcM{8tQ{YQs$ z-4m}b=KzsT-H;&cZ5!uu41Kg#X@tx3blY#=3OTj|;hCyhAP*Iq>E**X&9btx>N=ZK z0{Yo5%Mm@}5;UqVJ?)C(SiHFPqi}Udmp3}TlUuh~+@BT87KpG+30OwwFrlo|-(EJ1 zOQw-VTsat7D@2E{a|xmtw%30WQRB?!4%By8biK^`gnHX$XD?)Q``+_->gY-y2w)vB zdhv=}W~27rIfPk|m$$3X%Rre8FOT5HHFmssfA5Vh@x5GE>8xYBn`qu!u55)Duk*}5 z3uX)s&BmS&WUh~N4q;4k$?}FpI4|6Gc{gAjbt9;%sj;m*a5HWpFM-SNL8MxT zmSh?>ZRHjE;FjxzJI5-(htn=Os{4x?!|fI-|M520;a0* zrGg?gZx8=LdtB;5C)1*!a+79HvlAmLo^ExNj$Ctzw>9i8({+bqbQZ8n-qqX1Br1LnI$#OnT@#j9AZa7ms%wr}?iy(Jrcr;{-| z?xR(@`mG)FgpSMA@F{$*NCjEGKtDzcALIIw&7S8V{FVVxPsBxD-3p(vt38`!_k+pp zC4Qh2Z4%OxJc&&{9(GNW#VR_K^;BrLz;F=CAb0wP@%=DZP+n;UDTAb|E%q$uXVdisHXbG9 z=UKK_wHWUjjq1-$k5?`lI_tdZSQX2V#b!WnHjQT}7-D~>_QL-juGoHL@YhrIr_Fl{ zD3_-#&o(d_oa0jzv-4+cLY_K1$iE`R2Czd(no3MyaUsI&q+4AuR0-HLD3F6R%R#BvXm}#%gS40hC$() z&`|RA8zo%+^c_8tY;TMyLiVUvBMJE~%M4WJ&P)z$&~crUmXAu`)So~_vLNdY2H6k3 zTp`wsLO$xER#L6Y-7KZohKvwuvtDb}mcxjh+ty%EXAUu&m~|Vk{n{^(*(I#;H7#!^ z`MQk~Jvz0-`ur4rHkcWk1;F--lUB8D_opL{A-Vj6upTR$QAR2Flil7|uOieAI$ge_ z;8viaWJ1F8PDE^aN0XT@1?`O#R@YsPP%UaB80+MC-tpG%HZ#abFtiO;c=I}^#kizz zV4XDG8yy)+EK*>AM9r5d*VS~K5i&%xtVdT3Pmb|$ou9c_b+lcFRbM|3%OZJV^I{n1 z=j?iUFWSI_`ti?O()DWCdwPKFz0nZ-E|dKZA}Nz&AdIt3A%I>=LPK4vm+Co?ut93- z?^xGBDORxKf*uVBM=hO`gP}{jlVuF_WE0A{;d^R&p&4&wHzV_3u24EBn#Qs+t#e$q z9nrftv=Aax`)RpFdSW}8IP%q{TsYs^k`hueV(}=SKLiyCnTTdwu!8 zblCpY>#yK^}@1O3r=$EUOcXxLK*X3IfB~CDO%1uj4>j&YPEd0MGJ?tsKdHN8Y;Z-3AJQ*av z?%~_YYGaaLCu1TfCnhQ`9Q*ZjGp+vdNP(~aduEJF$_bz#^;`CgQ+L8b)D7r zQ>}WvI24ZEG()V@4Gum1T;0NY5L~9w*W3HsjzE+69GcGnzULWdcakB~bUzksfR;k=^2=(pvM~Gz+-W9 zZ|gk@!0}LZ0=jnT0_KhPSl?4(GZ#F8@WU2lSk*oHbzKuppjPP;(-QBD9#qC~BwtP6 z(o9~qBQx)mclw_Ma6ALo5jZ`5eLJ%sD11J!RJ);g47vimpL$kSRs|&$;AZK!&JQWb zL*j1={tn3HgPI8%=BGdk-CN*V_0 z1DTG}v|roWTo^VO8}fgy{B|j+y8Zs^vPr;u_51PvKEYAzE$}H7{id=D(@Y!tmZkzK zbh;(PS5|Ee6KX`#4bp9mYKCgOwno3Y8gy`f*EdzkXL}MYwH5v^`WkKQ)J|_aUp#FT zH|uHXN2d*68Ls%H3CBO6YJw?k2E3KMQzoOTps91Q^(h>~Y zR$VzsY2EpZtzV|OBgq zsxdu?F5zSzf0d+3Bn?bc20}HWA%=N=P4GLhNVdC#lJD4n>zzwHdXSFA#|Ylj#B=@< zFwduTZ)NP7aU^|Z`*&kePewWmP}VK6aQN9Zn@_izXr)nX!p~PT**uPk{~oW08tPUg zF8o2W{G{%skki=FQ#*01v%BlzBX^Iqlb%)wJRC4ToCxOW=D2dB>k;*O$Z3elOM(i( zuRHw9F1qy!sk7*#B2K<%*2feb~qzHRWP?5GGBC$&qP^>P?iRH;9f~ zn9{*)C8fo=#CRsmYkf;w&5wQeXda(yk#&-!+mgP%u%vx0y!LhP1lJ!s0e(6tdvn_u zQRfz##41jA?>tX$O8nxDBXqP9;6N;->~L{x$2pO{#N|491W{KP-0e8~7R_ZMeJ zYA@@v?y(!xhGzSM(kA@{`zs>q->ZxV6{g+Oel;wt#GrlQ8TDo;Sc#x^%e<|qH@8bb zSXdbNvod|BsOadvbh+Rmuau32h50l2dJSvNqGSTstu57-1o(&)X6a&i6|xrX(rkL4 z=!t5ILanw7taf1fcFhxtzg(8Dm{b^X#G|SgL^h3X5C4D|q}ByAe~4+ss$x`}!$`us zpY?uw=`2u9%)gnAFP-9vn~;L%JM1s)Y!vozVN7_W{`#Cge7CQ&U9#!fkZY}YP1!1C z#Wr%L>@_ZI)i(0JDv+JSSGfpZfC)pSgCI0yq(+$b%f^_D*bSZIzjn6fRhl=0*$oiu zNE$3pAOfGq#@2Wkt@8EIJ*9nscnmbJ8`zF{n>U^CS<~4`;SmD1bkB{bhxoCzvbv$g z!QuXL<-%G!f=A`7Z*uKgI~YMbV?`XAqJUV`zJ*}#NN(5_F*}~Q_O_p^LA+42%Y-2< zrTjP-Pw#Z~3^h|Z6%3Kj$yax(7@56W-ycQUto`hA&5n8P8p1p^%QoD<`M}d|%p_LK zzS>|Iu=$?rp_<@AcDQVUG~xgwC(m-DCusL8712w+S(V^65>mTgPpHR~n@JkwSZfVzo~{w8sXi-} zx8Hi4BUT=5XF^=>%QR9bmmX^&Sn5w^iyYLza62M z-q)sI*SYrtyXk+~hGksQTpbBP{ijvCq zep%inLSA1)7Dx&a7VeWp+u|pUgyEAQp1v$U!QtM-t>w0hI}%hhwP+@*#J0q6VYR7) z$y>Ffsn@(j4I^M`o1#bt*j~%+=M%@$DriNA-Ar58nQsW_Rc9qGpi<~J$kcmvGCDQ- zOLeWEJ`7TyZN2f0z)(kgLq=?Z@q7LZEOJxpMwAmm_=)z2p_?3PO+7UwY66>sTV?|Z z#@fA#(}_;Uxx{f)v6@iQG}SSsy~8+Rsir<+gVe6Dil!8mjTq;@lgdDix@@&?neFwB znstEpj(cco#_6>yHJQwSsakR|iz^wK*_iP>j$!Bkub}67Z9*qEW_X|+4(AvLUS`<9 zu5*dO6#2yxb*B6zmollrHgwN0XG1RGesaW!Yn4;a^U|wc)!m^>cV|AtY?7!_RP)`c zjqxzecd(xNiwH`vUF-&{x1kCgv(j}FnV`GS<$8WNU?YF^6j^h1)OPLT3`NWX zzNhQ?JRu;%jgp;7u2Z{OD&C7WwIvTSk+;Bymz1%(vYEDDxzZFAPe`?;R*yyB_~(I0 z2(%jk3M`vFmw=Gi>OQHeRi5-^H1}}F2n4BY)>0h{Xq&AebB5h#v5|sowhZ8Rm^bn+ zw=$|wO8a(3L3dmbX?Rs#w*of>Ocw-!{@zdLMY+THT=X|)G;%IYeZU{Z6P5~-ubXT2 z6q`*d4H{K2s3GHoA1D{=h3$0#T!l&0m?yL15$*TnGnbKR@A6|htf3(S5k4>mP$EUAw1`=U*d?kJg$Hj6+F6pHuwztqd_8xwX%Y3!em2vNwa0 z7gIdWM{185Pm;EFvYqyICTj%DlB`p)!49n29zDig*)dl;oH|{wN*%`aP1zsb%H|jH zA$DEn79WgQf538Sp?(hL8p=agW3n9XJEvmYOBcQoFQl=wqXPcC;YZeDkLPb0 zged2C09h6fO6tex67IybX-+SY*()mymSGQx;~kspq=@LId6;HP_B}aoh8~rQ&gsmu z5F$$F>f6sCL~aiv27KlMAjQ_hh9h%*KUdYtx_9U*w%53?LCBHKN;30-r2E8V`A$mM zJfs|gEXuccD&9OGm_A{%Z`AbZaO(a_#A$ThxgCEv+$f?rMI`>SEp024bgteT!_oBZ5zffT`J!zZ4k#V_Sc{7 zmnXLPhcPbpst#3l=PfjHpQV+8B{3QK&0h49>kBx-L&8hN|_S1`K~Ir!3;VJcYlI__A)#HD_Jg(A1A* ztZrn!C?TTt0hfY>#g;Aby4W$JLX;Wpy-uS-K9sxbL>s3Oo90ARN97S-I)Ry)o|0!q z6IBWK4}~?dXui!z)F8+c&+?sv!RNzj(yw-SpCfag)MT|7T|MQB=dSUFo$HaJzRB{I z4C`kOoi${7HhX>-?M1*mFx=XV&BLROyuMzYn-bhb&N7@?J7DU1px*34^16)Neg;Nv zk$ZDaK;OV?p6Pu;V?iZw%>l%7&P4N0NtVs%4_=K?b>671`156hcdr$|=mcS|yJG$l zY|%X0G)(sFAu_i&zh%sS5*>MMlQQ0zyrh^EdYF?IUK7-ueQKm3{)eAx2udT$>b&Ib zp8E*IgPD9PplpK>k&pV<)HN9VmFcgosp~R0^{9?KL$tmRz*_7|?P`U;h|-F-{`4SI z`;68{MyYaaMdQ_L%70yC%aJI}>@~Ru|rf;Vx;GKXVHB za*CfXh&=aDM)8i}N5}os1fm`=FrA2cFNibYj;T-d3lnd9cEbH{)S+lzWH3&K;JEz0 zEF?5z{MEJ~vA(X&u1<{>!|>Z^KM110{jNr;VYa3Af{9$8=Y%$Tu4*SEmolGcN<^L# zORtYDa+zgLr)#L`lvZM+A$GZwWE^krON(nqt4Z;8{hZpPNYErY&%fx6!MM8SjS{wr!EkAL{OAa|MyLI}4;rbLg*g;o=4G}V9E=RCY zLws((U*fj86aUDd0dYH7=R3u&do2#@nZLC8Cux{ZWsQ89nB9Sp?0{@(F#~BE#Py-+ zjop0~K(h+5VAOh_?wJz;CU7D^(}^h`;YlN6q!QN?lqWo2U+pD-a`O@3W+4mgK!0-Vtc;`!usMX^?F<#AJPPd{au$k6Y&)g&$8ub9+%`(|k|Uy6_UN;nR(3P*!e~I zR@c(inUhVdq)-K|!o+|weRBCa!`yCzravnh84OgFbX$|l5Rnv6S2LJX6e^QiMjFk* z4RlVg``p?Q+N1hCs}14Qg__B7{)Y^3VUah7Z(!_3147vvE_w08XAha_Wq!9x85rG6 zBFm42Ypnq~u7)&IHggED9h}z|2Cm#=SYH3xXAJkAhSl%(U3jDcfO@g=nZ@ee_WOE# zE=&$@IK6Q6y7dbJ?YjC!8E}TcVG^?pL2)w+9%UrVwdZ}7>fMMdS4tVrgthHUb$-yp zO@-Vuy|caSwJXv@o#SA4LpPZWy5Zyjs)w+V(~0@KBbkLwdE%#fqU^yNvWMDquIKQ+ z*Fp#^c_sk~w&Td=jPP6~VsP3!oV%60hF#=PT|&i`LiDu7K$lO(l?A^=>jW_KPfku& zLQ54M82;P9UiRj(;rq`25dUB6x!hOID;;#I^7dl;XY0I>ekwan;PRQ>cyEw6G63J^VslX=nW2# z|6T+o+4mMt_a8W{-$TNA^}5X6EHGHFh;6Knoq z?`f|5uNMqL5X|q#|HTpqAJ_^YQM!pt7i0bp9AQ8)6Hb_m6U#kn_cU^T6pKRM4O5N;(Ach>(gy>5Vd8|QQ!dCy_ z52;pLlqhnlGs2zAdSujewhy7$)I}Ddh7M|qvDOMY4|zcug2r^bTOZw($vPn1^!C4ui%po>3q zop*_0rD1T^DZY#_J(jzfTpny^?`*KkM0!#fCGA| zT3isw^18L5b0HW$^qBtDiJ*s!S zl^P*Pe(pI!{4W_i&>xjR_`q+KJl*#_nSyjc@|Oa}(s5$6&`7AlHJOq#@(c(IhW5NH zex$qKKaiSxl*%!DY)JCu9CN9qc$Z^rQ(S^K7Q&c`EGn)W3uC^2(V9FNe>R~zy~ZRC zPcbVl$|cHak{p`#*-u*DsU(z@W&05O{ok;J+@nlZt zvw3X8Jl#O%gr<38Ckk1nTp6ft-^pJqxYQf``DD+p1O6vv}NRw08vt+ZLq50 zI|;EmT3ZCi+L~_uEyg(#m9ITPr`#IPR{o<}%K3ZYB4U9PwA7HSzVTVUb4zm80*rf1 zvOqAu$gs8`zA3emu0xr?;t%&o%=H3BzfX2IGnL;uPTM5bQ+JHBh1G^~-?C0dLEVCu@A#OIU(MVU^j z4i^XiwZ+%H{7aiOw~7a_ z&eMbVi+Dh9njW(3^b`o5YWibk(A$lAvMvVsFPQn3j)(sn2D-J=eekND?D}X3 zcwsP=L(qEkp`ppd>-PR>-HQPkZ!c9Db65kB3qPjiRBSQ7i_hqh%b4@Vafx$BN)_s4 ziue3S6#m3V^R=wgcO9{zwScia-QE#c99;!MgGzVziS^1nqz5n8^@o9|ke186fUgnm zOjSzjoO!VgSpeu$w7!gPresMl{{?$mPYEPk)%zf&8Ks^rv1yU)_2nbOt^`qN)SA)T zXa`+SEcM5$D^E!E);Kf7^#}``ou6@nJzu|-;wcnP>C+)u?2CnlP7h8D=1}>b2G&H^ zJBO@`XQg_IbR^IL8BhbE31c4**YVC@KFs0oTqCCVWD00Q90N~uT1o}6c1cH%eO0yZ;~8Gq5|_1ml%q?&0YH=!GKzo6GwRq&&PK1z;iWWP9d>fai&oSnw3)|J?AP^(rTb{f3z%h{3|Y>`>m`p0 z(yg}euR$ z`gx_w-ai9`*i;tOce!SX?BuQ9_Qxl6mG<17MR$r3Q*dftI+(zrrkWVV9)VRdF<-L(Ay)+~ItUa{@n%nK4B9vPKR&v{~;3}?Va?ZnG7NJ&0F$+WiR z`G{%P%D86kK*DJSgBX;DTGV-tU?X%tYPxs(6*1epIptU0L$xH-bG!?h<~mA}spXsx zI?TNPa{%5=#yrD6x*xvu;Wmt}o^pov0*w7OOAzPn>rBUVZa&z0Q8thgP}9+KI+?B+ zE5AK2G~Lf77{=uwuS0zw$pFqbj&tu_s1p9Ly@5>e>)zZrrO`-+Xq>tN;+#ifUh^vp z;4i3V0B!{)>QZ%y^{1~#oZ`Z;q0XEjoMN=T`(y%cT+>18ksDwoSweco?_XX}CKxPe z$1+RsKJ21SY$kbbyv*EqnIFfE`pzO5`tZ`Gg(X2(Ch)NELQ{Si=ZHK-T{?CAGo`ZA z9s6DC#7dHZyUjpRgLe~_rOOpPd(GBYSnh0fm~ye@;3-e<=9LGJC-al?dHI4n(VWhb z%)48pX-p$L9^YGyU1;C8cPw0_ftsJh^b3%C=(c+YY*VR6t*04qwQQ+rm3&Dt(hP0u zf9Yaw3G1$)BLWFkCvk%6z&|*4R{Iu)EPA*4yH&@|rLULfyX!6UgIb>)aY4CX8BG zCiVw%_E7}e$F9w?MPD(bO(qlQ^kWQle9?p~?7{XC+J4duZJag6bJ1U-uaQ zB#jmu36q<4U*{PuCvPs`UqUCJ-xEaGds(D7SPNHSd-?+J&km{jNC}t#lhK+)x*OtU zzC@srk%kf;y*yLrTtN|w3-g6Ze%fUCUK*0;tvD)|GajvwV||{8)VD0jJ^b?BfI){6 z?6B5)5~U=SY_$1wuNTB*hjHH{mZJo#@&=5PwFDT6X7Pt(ihj5zT~I@o#w8S5R|y(( zr2K`g+H|~4gyX{Mk%NkQjmUS=7nSIGdi5o3kO=iy|ZwMDTS^4l?Jc0m-)_146jm}%rpo(9n9kK1Iafe)|QCy z+nY&YBees$wM#m&^_Wp|!!gtXLJzZTJg^?T`BuM2YgAonK~ub8Jko+)@~u!79tU7? z&ceJx&iHKanzIiMCE)sk6{gX3)r>@ngZ~HnXs(p>7ao#&;tUiKTzfSd zs9*-UW+!mjdc$-S-tl5)Gp$pjmm(aW5 zIUv6j@xU3x7`zh(6r52}joO{tGr~Blzs^KbDd(W;R(}w4euRck`k!SYX<6u6U*TSe zH*!Y6)sU+xk1f}4{k!76XC&sD=KQ}1nCC!v>(c1dt`CG3&sUA5b_=}se%@cCUd)KM zLLNO?@+ZS?f7@1jZSE5foIyOVq|N+qnkG_YF%097&v(4tb)PAC#0c|(Tpm~&wscM) zo^t}Us8o~4Lp8wy%M1&vD#{5$`V93m z-kdL)2uLN59MoE=bbO#!U#IcTr18uC$G>b$wAmOkqz=zpA+2Wt@3>t;4`t$zIa z9netuk69di!+%#ZKtBc^|2NYn^8`Rc<^cve2yO?P*$+2FswQV=C?!W$!7C&@W-hk8w!JOVb0H9&}2*~H$#{x?4I%`0*y+>b_ zS7pd-)Sse0RuI{0+j-?fHe181lTP`SmF%`_Ga6AbF>_PD=Hy>{gwDXwJ8*qT@O(0G3RY)-;X5A1uslQ+&b?4>nZS^fd)^Lt}=Vuh4k;eHT`*3Z!a5& z6a(eMsVVh$??X9|S3~%$<}%XsQp#+J)+mJN)h}!%HnV(Db2Hvg41NpMK@ckBN0gTJ zh+x7m&8TjW!=ClMp1*6?pPT>2>BWy89#_=r>wM59_gX)Xg66w_waPf-Rbqi<4oApw zCTqhBaF#G*a?_cWHFRqrPo+)>VZ0o&BV8t~e*|hKh@_owAlbjRVFb&eE~>R_T+Sug zmRD|TajK-;OylgI!d6SSbvC z+L-t&mNKDf$4;vn4FEU~Oq4B1!gM9=)-Y|%=QhVfAPXoa94>uNe&^BA9Nh8JH$X7n z_}=bDa+l2*2i3M0==FYi?31m|%zuQU=Ig@pk6A%+TLctXI*I}bYNH0P0r1BvFPDsf_8Xu;~=8L{8t!p{#xm{GR8*hR~pif~V6T4|)d z2>q10UcHQ}#N1dex8||;;o(o{Sp`r03dp2Mym=si(dW|AvRzpVxHXjhRKUX4Jo^6N7YOd~4f6mYUw;5vP+Ut(~DY>$efBgJTM(X;N| z3j1G=6TyKUi#>oDXnfdw4p3*jd)FN}$594U1lRs_9=+=EvikTfmvMPW=Vk*DBUgYA z`;GHzy4|3v=kpKHq!w-qxr@!i+`gk0v{?qGLDo=%b|@EDKcPa(+g3qpT=dr`?n?2m zRi{3%w{dX`xH6>^wZ1LZzXeQ?GE5l@N31@q9w+>BGQgr14YXvsYrMswjl2KIqcSa^ zC}AJIl%Lb31o=K70rS23>*EO-jzAmOoH?ct=@`H{(D;vd{8ub1jTRHw`sxD%r4Et8 z?Lq-mGxX4+{U?hVeDU8=vBblf>|%}izg~khO8QqJg?{jVaJoSM3<&JA|83#bm84(b zm@#{oK$nP+u^n{g{f@;|D)_RvYhJQ2yarGxK z@ywj@e=;eEtM#mqE5;f?XArvPTl&o!7-M?ZuxAzxoj{b5=Au`-iU(BtX{2vLeI8T9 zznK~BnydEVWnQL}5^M64SrP9{PIh+sR?f*JJu-X6Yo>wp6}0@X0%{1h3Fs>Mi2+id z33ly#knlC$M~}4_f8lCPaC_)a(7Zbd6-Ka;V?U!&cUAtR4J5n4fzsykZT#|aA9XV* zCJ`zdz`uVTDDQ5=XRqKVvMYO?x*xD+Ud2O#nggH>fJ!DjE>>3731rd~E4;r2m`%>v z{92`qy#*D`&lUZ_HlX@$P>eDFbOPCtg{`}Pa0}_5;g?Yf@2rUvw&?GiOHb7WKu#V` z7Qvlqv__rr?A)BZUUnNH-#2mnai~R{$-mS!-?*&&+e?27h<+Q&Xx?f32Xg%8&Eve= zJtUnaP^LG&;v*J71rVtImPc0)fXAp(``*usxS#LAnt&=m#mBOs&j! z!I%vdU|J`|a=B%9O?8~)n6UMS_{GK|JqZ)pg7gY#@XlH~P9Fa)e?dix#y1Lj zK$H38RIJVNSBf_v%)q3jUz`-lwhbNV^HXhk-9R}3QC>>zuIwQu#afdc|_of#-=?W zPXIPGGB(u{IW$w3F$fYp@a}39x5pDXAei;4h8u>>Z-xic@|-M3>{J26lFpMYl~_eQ@Pp`hu{uJY<%_Cr4-=KScE56Zn#YIKmMc8PhjHD>&|Pv`EwKF3 zoA9GBi#~D}En?gM1Tft8`xH$Ekd-#(n_!L!pB)a14IeM-D1!n&1iZ#Bl{26;Gx!o9 z6N&Y&WPHjc=#GDh_1=4~r{?KC$A6%klz-M<3c3#ZGU+1qJ4t^}eW-JlKOAOJSoTYK zAgp|+O5MK|H$M;H?`s9iN#VFcO;?wAoRVfAlT^lG= zsk-owZ~I%GsqCUCvbIqeeD4EDAu^stz`@(SI>(X0l8uFUch3ircOWQP!Tt`q-0Fe` z?=9zf305|L0vy6G*T*ZZiP?rd)o~mHIWxMDW-fzMZ+A0%AZcSuT`}JrrQ$?BsHJ^6 z&@mYFO@g0Tv(<32?D5wNqSWmDZM$s-Ja9>cpBKs3eF6fLwc)vI0TXk*(CKqY(^=FJ zX436#;3jSySS*^!cWr3cq1=X9!02rR9D`mGyqhIne&FC6%^R$eU!SX3Bq*J=uS&Yx z(yYy##+TyYS&#gF@b?RZptAVhVrX8j%%yAULA1kzQ`irM1EsdsAQ(&Usz$*$UU*d# z^h}o{`IBkB=C8{97(V9X+*+w7g~$PE3mI6D^m49BS!ym%04H7!>Li65dP5D_$kT0S80UMP@Rfq2ZzZ5&1;S%&xAEjk zca*8fa*Q=`>vlX&wd|t5X4;bfVhF(rE#LB3vELFiVDFA-vOaL#Nb4QEUzI?Fd}*92v9kCy z)=dF(K#j6|yEp3Jn4|}+?|IfGI%3WxP@o;CPpmc?vg6adG;H36@`ZWb-K8 zJr&YuLr%3-w#(Di^g=;4q-;N?zuy3Vs6f|_igJ`}89i6_Z5Wcxb@uG`d>^Oz;3&Ze z#PJKm%KGHSS8envJLB+W99;sp&OXmV>ZeQog9OJ8J=#WKz7OI zkkRqY6ieV~+yH3N@9O5` zWvZg1(ejy}w`uwM_1KiszbS;l9)qm9ch%XrQab5veuJ{sosETQH29$X<`uzMz;e)v z`25`>RBMxf-pN{@cX#>KocqK;A{Jm*sDe1bA4w^a%b)+EOhknJTkgCSC%C(SFn9Go z&CxVgHxK^(;12Y;@_)8J^uKj52S5FL4*cKbYdtXHVmQxqm++4|nGh89|Lf+Z2qGDf z(X2cI$D_2QkgiCKH_wh8pI=)B;0T9Y7uuIQ>EN*519`Q&H)w?amYTtt4;P*C3m5>$ zF;L>{dZ;K+?LL?Z7;@&wsA%wjp({0w)`=2zkl-Jg{f{`<&<1vtiRI<})Ba4h`Rtl$ z7sDC&OlU7l{m5)iOwVB|%M3wxdg;yXda3Ie{nPgRlCSr$f(B>)KGO#8kGoeUrLEOP zH;z1{g%@k*l?J-5mDAoo+8?GiZvywU<3Ds-T^05^KDMBu6RUBy12Acja`ZQ)b0Ufb zA#{>Myd6-ywmP4NMRfJOx8|@Q+GfxfgM2D3k6cWDf0ROIiH`%+O)l4PyA=B8dDdSm z<_d(sG~(m^c_n0f17fVyrxg@jk43R$_?QD*fD5UT$X~4(WFRt=GoHIp7qT$RU|!+g zeIDy$38JV$^Ir%C)Lgp=?%o1K_G8->Sb{aM{8)FF<$C6x2q;%7j8Y*PSb>e|jF$ea1-aoSI% zLs71tK%%j&CG1_k6S|Hhi4$D&50pPZ+42h9!W(B`PC)VB`5=?AC1^;ccgaVrH=@sE*5E9et&$R z=n{Z3_@=V<)Q9HHWM}Qd#3k{55X=f+SzN-(}CyOL^6sIebWP zrV<2@*aDTBOaE~s)c2NIvX83W)UYV}-6TO>b!_sHOSA%@>dk|GiRfXAUo379@|O(M zmoRy0Mjc}j$LvzeK^gh^F zO)=48X7;kr=k4VW-LEjX1=dK>F=B6am@_B7oU|Pt#k!P8X~2XQNthDJjW!8Nzo{m2 zvN@O4^;9p5|83SG@eUMX8n4Tav1cf+whznrYciX8JKVMr6JBiKb_u3>iqg*>?#;~> zl_?-b?&P!fx{%_XO~F}+#rI};JTTpOi3cj~yYQ5>xW23``dA4L42VV(S*lX?Olv-{ z+W1I9>3@CSXWFOq8@UpSAnF$DuXXa}M2Tg`B_OKjXl2d_iUrZPkacST8z5Wv0}9wa zr0(3KY6)#~f#y|^y`n6Bw~O{J*ynSb+&`TIH0yaL*H}u;i6xdUYx(5YB?@)wpl7s! zPUh{RudS^mwDePhGaV`XkQiS7E|dDF9^vnZp_kip?6fy)cI5N1jT%cok8nZW1E$oH zYP*N2XVbuGBlv@to|a=SXt9fyWcy&>G$p1>ZY6!u&BEFsQKJ5A?1u zSZh=s(FS7wQ;t&bI^UJo&fQPb_>pu$=}E}FSc}3&fwNrF?xR7U+>nVtVID!+5H!@# z)W!;8VX!Y+$0v`7p}Gi_OXt0L4_<+^3Uo5Pwg8ZbaHc^MVmGx{23%|!pN5x2H&%@_kLBep1i^&Y*0NfYJF;OJ_CSSY&II+S-$czUn|<3e6Qj&m2ZM4 zoUp5V4`%X+t=BOr-1luA6<2ZEvaLwMS_^|w7BJLdW_t5}U6%)CWd%j^;9dqVisapv zN`>i+YjI;F5O=%_pQd~lsOlYs@g5w3R%f9WP8RsDTuks$&@5=X-I!ck#wGS7hMlbN z;`F=0x)AnH|OdfF+>Q_Jxfcuco{TIRa zIQ`{A<_Lw?Rqd?-Aym-cvP!%o1{2^5YUF-5nDBAYNDkQw7CE4Twc|~%tvxEY$3Ek; zrkTJSlF*x!FL~|vQ_K}`HOlY#GFQqM3&N)JK(dEwlcs-HBxd_Fg8EnQ0fvy64w_{j z@0WaT|G2l-F;;JE`)e8&&)=x~ZVVDI>$IN%$5AKB6Oh(IDG zF5dM5>rKAk)Y!cZU(utqPF{gMg&Z22dq8m;Y|F?Q4UHj#AdQYF62mkGLW7DrrBd)o zo(oHDb~#*uJ)H2Xk8-s*GOdAzg;1_C=z>Z}FLYp{K~*e=m>_Gn6J?=`5pr@ZqBscm z|MB+TVNGt^zA)-i6a*|NOORqgkZPewjR=T}N|z3zBE1NN5}FGHL)+ zaSD`tI7f_B*7`gw{`w=_n04WqsPy~g3E_gFqNrS2l0|nr^vS=K8#4Wa(Sl{LbSG!y zdb#MP(r(`~Mj^e`$P5L!yGcxnz+S%;R?RaXYpQ4-YQOzoxl7Z(_KwT-?q(YL-I&=A z!1vAlSI|VGB0=s$7!eFFp>^aWHB!KUCEE4rAjnSkum27C^#7#zl2$ZGNx>(1w9>4T zmr7>-P<4&@A;G^u<5`D>LVI&{1Z$}~7yhHB&l=!~ukuO?VFwcxHJQtfK=FU5hN!;a z_!bivXAOGsnuCEkw243esKcbCV3%lZxoO=YX(oRk7nh)?R_u1MM*lvPEr77anMRu9Z&84bFjoa zXc)8}k4FK>b!y~@=VKiOdQO)QNH7UW!e?uJuU{3osq6nP$c^bbdi-m3E3MXvhE~>o z-J}K&)&+6Fek8d+(;IU|>%V;Y^6y*ebEa{t>VI{I#``6gm6cW1qiJKV0MDw2K^UK7 z+plvyL#r%*&2Z!C*V{HjRl%OruZO@?FEKmk*;G3tXdgHqbIqsrTP;~j{DX9rcKe%j zoqt68B5*BI3B!!;Iz5S0s;K;-Xr2Q~JWOVjr#`gu^lD#*pH)scD;OCvz?kB?c(A*} zHPVkWD^dCk!>aX3<()Hs4dk9UZZhDfr_JNnbl{}&Z4usUM>X&9r!0H6B%@nQf)X3= zw>`e~m(fV!Og~!6f&g6`u^=Ye)yn6WgRg!qP3z>kf2A=06XMBM{3oL%?!-T#r~l?7 z_dcF^-rQfx=29*PW`TlXyYZNsP|t#^y^rEwss=Kbrt$JB{G6LW2ZfEPYkZs{|Afxu zNrUF1dakY(HtnNA@zPLhb%xzrQYV8IcUw*jw#FDO_p0W%s27A^D%H|AcuIctjbWiO zQ73S+Q^xh^NDqX;jdhm4?|%BLyMc+raOK6E%`9s8~#UtYYj^8!Q0J&WfHbyf}k^#t({|9SwPp8joT zhm0DWiZSJi+>1<)s4G$2v8tf&xSPj%6Jp-zp;m#9n8nBuS^OwE&r2T5&o?!4= zaKZU!=S2EC1aq4={OJcrB^mPXKZ!1{Th-+F0*mq_ZM9p%dWLSt9pdvb;el|6wTMB& z3Qt2IVZ9Wn!6~Nd%<7;9ioVR$w=a@$WR(@_n@W6Z8TOj*!?Ep+=WEUDn|76h^}>d> zW8bBUrN;=f3A019=V?;g0T0If86^3Ljas{-onqi|s58m3jce}@*X9D-IOUG70XelC zQdkW|+n$LW)#m5Xm)oJNWk{(Fyp`kDFI*z`$K8)mW3XqGgf$ zW`R|6n8YNZK`&8htZi<2I^Lm%=c=HfApc%$$%fF@>J)7D`P+G&GbVRs-6&(-y2@$)vd< z5*7ufr-|t8MPYScnpSm6b8%&G%EoqiG0)EZab*f?k8=HEJ$Ly8rN;CqNz*Wvx6H(m z#1biJ=Zzaf*Sn7>1~He@R_dW6M$eI+rq(j9^GAFCX}P_QII)%BGnXhsPkbC&k(P4z zuh78Iyh4%c$y1n+Y<~M&yE-}D>rI-DrGBIyJy$-RdOtck)+$!l_)Mhs!}`Zf=G7Hr zOZxWmT%tZQIMT|}phNRCoq?oXTtVWE9wZz0iJYJhFa|4q*Vclyj^!zZP)&U*tiUc2 zg7rpS3=Ma{mu^$k*y|7_Vru9Q7ZinMYH5vu|H#<8&FteKPGs}F3-_}2=kjSP;d@;9 zv2>ZRXrW@)u%$aR(@|>b2z|E})3;(HSwr?oG+i~eJCrruwN0^GBKg~z;3e!&GR-}S zHR}=EGQw-y+(F= zbzp;-MSD3~)X6LY8xu{~*Z?;l=XP_iP;4{|q!=+XG)NK=dOS!4*C}BxSN&daA z2-)1Tw2`d1gw<6S88BqUwk@GrVNa&Hy}jF+9e18|ltL=>oq~;vTRKKRN`yVDyR>^3 zuWQ20uyj1%|6C)iW`{QZZCuYfBnKAq{0bpueSHoud)BsGeSLxw#@dg z?h7>KZ~uZGr5(0=*KJN3sJPAPQkMQL`Z(vy4R0p`h`a^yG;?=K9znlcAX{U_7LBg- zC>X4I-g6z_r~96hE&ovgN0v}!^rh)R8$7vBtI)1AP|=rYVk5wr6{g$lJ=$*3>(=nB za&~Xk-Ik@j`k=dLpL*JB-v}Vm^YX1jeSUh+9upieJ(aI)*Ktj57%X)^wQ|LYiDpmN zkhAq!IHge##3Zm2tPWx83ztrJVe_@fQyJfxG9D2TWa!4MR-`nKc?`a|NWPlul z%RqYabF0u(l9$mnQ+X90omG9EmrA2T6Ulsn^2=80hq4FT9EQJD$jkSIO?x*=K%{?^ z7-aTGkSA-<23%Xc0Sdb&P`cM~yHWNSX(YDPDN&dM(pfhkD8v6~p;b<%f5bm%ew6PG zr2G-AnVGhSLOZ*J{}I0>^bA*K`&`~H==C_ytrz1ZwS(*lVaX9qOvd5t0Wx;zN6v-f zI;B^bgiFnzW1i=DMBH6)FaP^leL2z`#s~;g&6J{|b|)t%Kee9;u_})BLCUVp2{H4i zBgSTp&NYWK__Q37!3HXTc8OswWnb|i50iQk#?j(7y+Zs_rPc#Wm(!&FiXL{#GdGI1 z;Wexn=-pT`_K0s4tpuCKv9ZY`&fkI%nN!bK%G?-ah*im~CC6o1Ohh>6n-`j_jjYZs zP{zn(c2+xFC~h!0Cf0Rlw7x!T7OXcy^h9$VnA09F;}$kGJ$=MRQ%&(JiBjLX7V!}| zAFo@%@<6R!RzZ?l!n6KDjs76C-tzLU752vZCAZ_l>Z~O@SVr&`YMkryr zX>r6xwUM&}CXA6s{csgF#vQysOas#leyC*Nne$B@D7}dCJYQ-gr-(qwHZi76Fk^IP zabXz98IOtyU>9%qt=U{U3~~GI)fz3|2a&j(;Kv2(41HLK-p^v{M~2GK-fPkM{dUHs zodif-Z;yAc>$LD7F7WfpU`LVjAA4IWC6{)<@Et=_y0V@d);?Q~KvbTU$a2t{xqn%wFD_zvE zW32|$aY(vam#UBTG#|F-kStP-y)gK0jWeugZ=>AO0fFE(Lul=0Nbk;<>9rW9LH|?T zd_nKt38B;wzioz_gw-tET;;q4@TH)iqStmxpKIBhpx1c?V)SYkiA4Tag>~d`zl(<< zqGuLLj45GySVX}Pti#bsZ6pF87;bZGm29u!z_S}&Ugy#zB<St|Lss~xsav~Z=c(ntqC@STwgr!^ zhzS`HMTG6TMHy@x+dlQFJ5Fg7rsPLk)n~PE+gJX*+b>904l>We4* z$aJq+`Gtha5)u+dwQk7z<>7|iFow0R`u5AzxRgvz7VEPlW=(Xm6!te%?yuagFisiU zzM`=ODY55GmlUqBVy%IziSfK9elI>;A}%>3E5!U&Z%Nxon4B zh>-gij8b;~Iz-}qd|+_i<2dTQ6&|^@zK4d@P614u(qj8L5so7eI8Rug_f>ZJgR^h< zdi`zpyY~L^KRM0zK0){2eFWOx@#&P|4VTXVW|S)`D_7VLhCIt0vJh>rev(koYvwS?bAV_j26zN(`l z7xyp$b*xa<+zP@uW^#H7zkS1EIIlkLbl|V#vxeABwlur`HPSwoR!;^8_iZ_Nk&4;l z_*G}20*%HLvFkm?NN7yCb==uVI&l>ctOr3V-48N>D{07necR$WwyL;dXK zmS&FzDwujN#&*5hVfJ$R!DUd~o^)>0n6eaO&+wpi;K>(El8-|Mqw{7WwlOLcx4}!n zJZ9^E-@t3n!QlR6zV9h@JA)(N8)!vsZ(5HSW}Q8^mM2M_mETR5UvJWy744#(idh85 zu+0rfi|_9Md5jD3L}ZEt4#Zdq9*4g;8Xn5MID*o6`lzJDuRKFcEN;5(n5a*c7{n`X z8ne{Gp(*SmGe)#*JO4YebOTJR!#>h(Mvs-cwrEo z`M8IFnNX`zNC|D%R5MGNAHOtdYBP z*M3fZ7o6}FJ{XhuTZ=brHmghhHM^A=G%J3YK2;nMaZ$`3F7t>euijdIYUd)K&>>N_ z51Z!hAL!t~ZYM#jJ+xz`cWQn9tTdS*Iya|0Um9d&A!Oce@>JWELA8kBIHuIi*0%@Gq|REukvY*#2`)}7 z^xd4eIr!)dJoxmfwU;@^18y>ye>po`qrbw%M}DF4=Y;=xrsPbs?zT6-@(@nVPUmwZhT*z~NlJ)R-Hw z&OR1Z)7Uh5yvWaRr#Vi-`h5Q0nMXPX);7<}O+klh%qv~r4kUa*y39GNAF^W>dh>?g zr`#3A%#91ZTSYeFQN-=EMb&0R>V&)xUf9MNZ0gXsspKxSvz%A=parRtuYWQRbuRz9 zWOqF552!;=FVm6)ad@f%ztB9Ca65^3a<3B>js+yVuhUE*4z~SPM8bfL6eP*K|8!QZ zuJ;aMS$tt-tKoFxi&R%FG=~gcNT$ToO3orWKc3-h%xl zJg)xz{L)`(p04-bcC z*w_bg(T{uY>0xMC@HI>k=`Hq0LZE-wm)qXlv0VH6BU|RrH6}XE_h#6~EZ`X4J3ddP z&HQJO$gtIlT1~<1|JeEuu*CPT{}EHD`Qq2-;@*^ceUS2JR6K7EOWEgnZz2C3d^^A7 zs!y{(J#CfmvyTWewcABL8Cx|)3$X>Z3$yjT`Ahu@KV!)YwfF+#S|OX>e0_Dzo2-D| z6RsSxK6mb%#6OZ3I>*g+04#7H0sb^x`!?5mW&6CUP4_i^IeipkTjlSFrti_pZo_(M ze#vnU&ANYlyktvW7#2CY_h9KBOVU6rAB~~-XIgJBF`|22Llf_J&nX0bxXE7Rq3brL zrP~pfZQM*OSyK(%ZDoEeA%5a-$5)c6U(TF4)9*<{vhA~mbXhDQPNlrpukj?+nr2D`QZbe;<|Hrx2 z#hWxrHZ&p1AqXO4eR>)-E+3w>-EbdTHo4^U4&tEIcL}4b$6Cp<) za;|Wh>->8)+zb789K86ScSPJJP_HrFmS|CG0nu1k0#@=KE>GL(C783&Ke!mW$DB0g z#hlM zo(j5yrPfg(G2JC)FuAw1wO;_@W*AQ9k7{u?`gkZvzO?T2S;L^gWjjie;@Vf@Nbx>Z z^M^Q{HvM+!oCBfhYU^{~AcMV0eJ5xQKDvR{iFyi7sllxVvj3-u4QT@>Zde0Y@PF8- zC#{BY`ngTX7-&AD5%tin%)`9m$qi9)r|u|AHRrT{xqr#V)81e)$BQ9=oq5~awqwS< z?)o4`BhB@*0~ir-I^f|FMJkHt0VTYK(^Rs9_+UB*Q}KN*jd#bbIhhSL>j`gvG-kL3 zL%j*V+5$acS}1_xGx3od9pw*Pn75^tR6#GC zSy*8B#@3TZLdaK*qq}|CcR_gymquUOwX8>*QqjHquO{Mv7%W%f(Rr(qb;vi*y!@V< z`7OD)7v}wdJRgFSvprZfe;HQv&?q4qH3S#|EZ4?Flb-tpYccK{bK)G7C=o;$uCCh3 zG`4ABFssm&Hbg*UINn!ZJ#%Th-of}!LsOGP{xVYnmbDW7xvKnMr0%6`d-Fql#(6#v_kKj(wM+a`v0;}eZOSz6}HBX)yI*ExiwAB@+X;cEBig1dIrMc&T%xF~xx@)bO&+reaL zwq<9+#(3DGM@JFaK*wE`T`WKJ6fz1wE-2;H{lvD9BQoJ3G>r4+V4WmvJ#E_xHGqP= z8!yB2Z`?r#uXBG+e3vX&S&#Iw zc)HBfM9n0-MXnv~k$SQSa%SZ8H`A5n^&+cD9nNRu;924$UpMKXI(ifLTH3CCZ3#ec zN|HJ{k#>%lv2Yz$!n+a5MaiIlQ_77tZrNMCT3Muwn1RuryrH~xDX%2JN^lFC+S_D3 zgs${h9%IRw4hmSoubP-A;gDjZ27`-z&+QjDgvZEnjLlu1QBjq`9gEIB$mqr5b!Z{h zwU%?Jn0a91P9#uqI3cp*blQn9rP7fJa71XDSWCZ_pk zkGejwRIh1{i43Z1kKei1A=T@~R#$wfxAA@<14k>qC(Z6H%UwA;RbRI{3tg{UyGr0& z+QECGbiyH{{wtMpz1DcWF}7IBSB%Q?IF!2yIKtxde^132(qt!qnX7qa%M3w3PL2DPIl*?z#pvea{3NI`vx`cA}^)ty$ zdp`PRSn`s5|3YZ?^18$fOPpa#`BQb$EkZ0QY1DuB&u`9ms9ge#P^xQ%GaBhCKNYYe_}zIB$0 z^IKL|May#EHhkM*d#T;$e-AZ`rleh<=dRlhF+V8ot*eN%Ix64Ofh3JR_dgYAFaL+m zQ|(yK-CEb(b0g(FEs@|Q+LdGYhHT@ADvjTAB-<555l5|4uFT%@`pmKUux3PJz`)ok z*pp}na|#2@CK1-+p6I}39u)Gt%Si7}uUvM*rSnJ1XM2Ai)-YoTm-gAl z7n66fX?WJxRtHr%*eb`noiBafi1#2b8vNoBL8C^0$B8pO$O~sL?cqVB79E+6B%E|w zT-0DId+2MG7SA%(R5wF!^EflmlfOBU@)gX?U?N9s% zUhBz&m_-EF*|DFbR*rXqCb!-$t9qpRS8V)Fj**8nAWh4**F9czYfWk&OnHY;)W(^^ zCxTh-2sqobT3$WB4(-twO`1wM%cH& zF9PB0zk^n-bYJ?Uu3uADb*~a4sF~F#m>U{TcvX!JlaDU1)O}<5en#}X(gv@FV%@aqqBbpQN;3ikLnCAJeH#S_?EnaZ$z*6oepNtn zh*94Y#m7Aj-ULDOY!@#Ln7B7=^LO_lJdDeHIfE=^tjjQtw$eVN#|-3Y4VDW5y3!TP zF!E*1s8N*}voQ`C0Xde3x&GWt=4ZKGl;tF6Dy^R}u}8M0PUK{T1eS)d;9SC35ti9? zEyug2uc~)DB$ZD#rhI!wY;42_b7zXm|LV9N!VBfSKSIw4%>-%;%>U4es-6-WNUwLe;-G#M{YON+s~@Um#3?Zma2HN4FpaZu zpXYbf2e}AF9pMDwd&lC@t&TY2yd-yT>r@h76a6Wl9LpQq?=1hkMY_}R3cP@XaP~Is zK=uu&i5JVK#bUv?Clb>ftM6Pr%&c+fif9XTaYn5fUbADQ+g+L=;KBu!7e5~dIRc@o zbw5>OMXYbcyX23p%=$(gjLNFRV2l+}g}9oeC5$x?;D)>jz7b){_3`Uq0YV|GDJ=4* zjkA=TFY=~Uf4Onv#(X0Sq)f_r`pBMyU-*BN5wgs0_-aD}Ohs8x^#N*fL?qC{UoYo0 zqknu%o2MCVC=0csd-C|vJtezax~>^Lbv5DnZUGIB*6Rga<#)m4Oq$Gsx1z+LzC5e0 zuHIwDUpE&y(0zDzoZnU{E!pSqxVY{D895=e-b z974=@3`FsE0dQt`eZzo^1d;u3I|hk1xvKjTuwhS@-G?-HvWp*op!S0hX-?cC6Lxj; z5}*Ru^oaeIu8>9^pwmpFC9X`|wna1t5U4XyH*mJYI{%=lq#$)0_uDH3q1*KU{fCku z@@r#PN09PXxoh0pg@k(n*idV711H?|H)gOYy-O2KV&`DuS7jf_?0A-S2lDJ$B~t2W zwp!T5Jmnf1Ye{C0I+!+tu`k1WLUX#wxV#m57T3mND?JHP)j68$DQbDTb!mnCW~M(l zxvLp{N&B3}%;8QS@5HQ9nL(A-7EbMIr2J6azG-g4kzCAAJO27C@GSqp~^5;Aj%dk+_ zd{|mTIhO5SJvw@W(e}q+0Al1(yre$R=~;S{OjvyIcO=!&(<=1(Pg=!1my?XhppEH- z+WClsafPIxpmQb?Xy=2#fWc^eIg4&49%5>CX%h-OF(F~~T8lSdblR*f5=`G0IC$E} z8IwnE9OT)(U-b!^a(W7mQNx*=K%;;#-6#*+CZ$ZSd+e+{lOc|W80%dE^ASs%e53Py zkrM7P(hQ$iw~WMI-HG*1e0T09S24|v1YAjg*Ht_4Te8rW+v^5?usn(}BzHUtTHDIx z5^IT>8sr!8`9GV+&`e z9XOGmQ93%Qe`U}V(t3lv?G+aSwwL3l@k_}y7q9@rf38nR9HFGL--=i(t96$pnNEr=D9T91?t4I|zZzS+ej!xv{`32?^%SirSto$D`u z>Cv2Jv>8JWakyPtF(qi#Hvchb_SFakc8F_W=Ef?0;pv zI%*x&Mp`L_pv(a6Xkee!{p+xQ$$-(T0D^IO3lbxH+swx#&jFJ?Hp0?xmN`k^;%`(3T3jUi2ng6Xkr0q_%#4_YL~&rtL4cBfog#w-my^--}g5l zOzo5RwSSHu&M;R`n=f+At%Oa;OP0mAls)eD&u+BaD7Lc%(_Hf8NXR;oqo;n8Rwm`D z5m_2lCh)N_dFlq*Fza!m?axoVPt?^kOuhkIXdoph`4xT}zIjgs`8;UUn9!bXX9%3Dz*h@12L#q?SzvwE z^2XC2LFZwGB}MyWWX#~(g1h$Ot`xgBjm*^HbwV`Ty^SU(Zxt+)*6{lC_PW9FHn+lY z6t~GKJHf5^vh^ky5jcrJoW&OX4rg|nDUsD^GgTf(5o6x9IV)4%YG%Qm=QDD{P%jxS zv_|AVUN_*C7X6efo#RL|jqPTJDe}AS3}EGLNZ7OTMsSRu*?JFn>4Nyo{^|P@LpR)3 zpBe&XU2b*!UCLSOcfBzt){cEP;LDiuqO9@1n!0 zx^C%}YpZ;4@yWXqJyMklwTZF+9Vg~ucDqW&kG($&Rn`%>YGnb=wT6_{b+UnEv1wS_ zG5ILXly=g(n?qfVf5Avq;Y0qVcs5A`D&tKfwR1~m;q0s4=mY zDz=}1%c-03rz5CPx+*51zXi6LrVgK4TJ;o}8|pl)DX-V=TAt{*m_D)IvxMc8PkN_4 zy`}SnW>_i*1lKM8tHa3+A2piMzXA0%R5#)Oi6072n9%OgSnn=dg7l+|yE+a#0-qB@ zZ^DU;$I9g77_hujP*TQ_Z6<-Y+CTI(h}UVG^!6~V>j_EeNr;P~3np}-T-LzNyHI2e z_=W+yvQzeA1K(zt~EQz)v%Do|lW0 zycaS(wd9ouicGf>HFy@cVN&d)dWqwbDv7KecEa zEe8CtNTfze@w4S}^E(Uyd@>OEXV_|ls`{tTEUb0Ce61q3*r9PBpAEaILT`a4#PLj4f zq)i#Tc3pvRtv}hAldp*C5yNy_FZmA52Ks2Zk8YR<3J8jRd8^6SBK26A)0l&FT=OVz z@Ig2~^wY5Kr+3owk*a0u8-KyOcaNNIQ<|W6L##4o*g737knyAJ~XB`<4x@0h~F-f69CdYIK7ZdCemFUvvfz?o&wtyU8ZI_ib z*;=&yd0zNxF(9mB`tRC(;D2*$<*z&L2p&>GyVsR5F5ack@kXaX{lRFfVy+ADucJT& zs2Lj(!?t~^wt1HNCcBO(+gZK|x|9Xp34=^;`EnYx-f zyfVH?KBa+Q1c{a3v_7O%gDLg!*LM`F0{n#nWXBdSK1k%BxupYjnP*5Yd(65xTN88$ z{sIag^3BQJ)yTi*(A5W+bDxg)al)3&3GJ15!HdxvK4SS?z&d56WWBgV`iyX zyvOw`kogg5TrIZseih$LF2n_QVV;`*vN?K!DzVPOJgSg4^S z{5bAv%25`^88#AgXAQxVnpDc?V>NF2S)ZCKW_x96KYYSV9bUbSonnrtxPxfR%k@UfIIXhQ!*JbyIiVIv%QS zxL~J<)LPb!Nm8_vd`Ky}xiBCFX5gFw6NmM>KcqR_3CFOWoPWUpfO`FkBH!h)*`<`^AE< zup}YUp-ILYy5wrO^Z6-hrJR-SyutZTZNksVuh|x$85wYCvw~9neGRe>T=7avlF$n!kJ(y_?q3*8cy3yQe?YM!9?U@dksifD?rtsz?1K+)Ri|MmSwel>J!Iv~{h-T!i@J3(2 zI~vvv-!k_A4fRdcuxF4J=dWW;3{lPAk9j$DvByFPUsKV3r?dkRp@=AizQBg(ZE{$& z68SxcoB5@VhzAHM9EZ7N3$H-4kgky~wa*_*w~! zK2_WC^#l?kRAcryc$MP4Q^pr0F zB?R;t!L+gwc^`@$P{va83a7T}{fBF=*bN#0nRtkTi|)DcyR(b^NV4@=@l~4APE-7T z$BQvMP|dl}E_ucJe)kDHhhK}$HSM&IR39(*DHI3F*gLEc&*86w`f@jmAFBC?k^qeF z936%JiP)O^>T&D?BfZV^gB@QS`aZ}L{5nhOJj^{SeOA)^hrFW&N~66jV}&^eza{{Y zQrqj2GrWkWAKDJ>A&~};N@`PxO%52MWSvGW$cM3>V|yqheAsY@GRE6c(SW+Iy0v|d zBn{$DPUiDMglAdJ7wxK6SAxv5G5_nUhd!!Abf{gKtqscBYw}cw| zOf+D{iaA~i@zCX_b^BY8TMpuZ_Qv@BL*F|lPc`e=B_=0^03gC2Q5K%FqPl1*jyXH9 z_Gjlw57b|xqDT5&dH97h0`n4mWo$iXn4Ph{>uaI|AMO`^uSh-OEUqoT+#Fhb1Bole zne?ZX3!b(!q_l&kxJvNu`{F3{`d!?>LktxVKWYqr^vuS3&s=1?xbFF^Uky=gDl~AS zn_s5`+D__`OTp(6@gwbWa8Knj)cs4MC7&*-5bFA=_!cFQ+_s&^$nam)>DcB2MKYyQ zg|@<#AD^)Hu2YN(894vXaHz+6LM|82&izCg$!y(+Eh_!i#D(&OatC4NwxKK{f~8D^ zED(6Z4j-g0l_PpOcjB7K9^A*5#A?*B6wRgTkwZyQ-Qw!bcKA^UPgF7`I zvD&N-tXQqzSShRfL4F_5z}*#pLa_$a;;8#K5uPH z`D5xn@K}>RX*k3-ojccC=Iu!~h!=mLR$2DzAto;;b%dKLXRs>YvtJHXW>4rW(2od2 zEahC;QZ*1?%~tseuuY5D>a6Lo1HXV&PU=eCh2hpeZq&WPP3OtzVJ1*BlA`vJC}>c z6VDYAJVJ#_l{d^3WeJ9Zo!8HDOXFJL^5GHpzk4VA2q47Q66#QC^N{rW-*3u*j9n*@ z9~}X9Xbts?cF%orD*2?(TF6di$c{__RXDB4=)f}p&p6-^)ILnxpQrVOJMB7*C2KG( zmc8q?nA4UM3#h}q{NaHQy3}oO3SFC>s&{J>yq;dEJ)I|oQ ze4ocS3^%m(;)N(?F$yyY{uih#|l!H409u=aCe( zM&aCgNsUW(7p=XXw5K0=wq0QDIk1qkqq+{LjU<%)8K&zxAKxu#6fi;rU6Ll|yxt^B z!jiL3Li&+hC{E!ew1^rx1mV37)18){-RU9K7I`zWP0l$hm&u903~FQ~4AOsqiQM0E z?u0;k)DbBUFp?TSvYnIj$+21394>ijdn%cY3k%$g@emCof z%Ywd?!A{hS+{d|A+)HSm4ytPhHBh5^q0z4NNOI>ksPzB9K!a+ZZ_KzA7Osrb_=PWHu}uxz%c4E$&2@p7H=&YqfI4#(86^ z7vR-myQ}j#VM%g1DNUV=C#-^}nKc%j0k>m2_D#?@5zsx6=i=^#TCt1p%jQQ$D=9=& z`5qgounniPQ*1t&Ve!c!LGwAB8q;8X{xtS8o4t$fp`t)~26FBRaiI+lfpIDn`G#Ym zOq8G%8aQTmIWHo6sb91%Ra&0sm}oG2uDGP1!_nhi@;!Qmf%S{m9--f(WV1B}vU6?b zf;>CnN9qSO@THX;KK2I|~l&E~KuW+pcQcoGDS zRotn$daalE-ibRX$}JpcG;0Fhes}5RhZF{ujx1&0PlFb%F1FS z+obKj?d9P4LST)bchvYu@TCGqbrn=KoCL+(+!8Lc?J1Ybz0y>-ik>WWpFoT@OO|Z- z26JI=pTWM4e#`!``!g%{2fL2fL?n0H{2&*v&MV<2p`j2rWD)w#*xRt4zHse z8xt*$vTv)dI6k*7k(RcgOf!jgta3~JJySMa$jH+W;71?In4JiZ#Z+*ddeh)RRe>V2zl1v{2)w9nV%dGUhws|P|Rk!pEC3PxvZ_8q@<=ib` z!Ozp)l(&YfO)E$dtP~ z>rJ!Cz-B1EY4ywof)1JCSZJUw8#6VsA4E&u26=?FkNunFD;?yOOWNsQe1CIe+r4sG ztFr42sduoF?tHkP>G(_&wkam2C_s>ez&OVhE6l11`F5>kH<)&$&yuXQZf6!L)SIo# zhdEILa_XPpS+7K?kn>>1-_Z1MP@u&jr}MKd83g$gDPORsbd<^2J9RyDNwd;HQM!Cv zUiVxJ@n1xMm&e?1R7sA-r471pnn{LN1L4m;-q@TUXgdrUJF>ZccL_3t!9-CUziNex zbxiIsgm^jdY1~dtZEP@0t>fl)bg!vAletBjST4*8)A#k<2qnyoMPU9mM9a0z)I<+r>R;YRdwH_L_>KfGY5 zC;iHq^_W&HS@b3b`E@xuKqzZ$Lv@V@(h+HGrd9OuJDIE^S8AFzw_%7jlNxdU`wz{& zAZk%TX(089v_=x&-(+ozbIJ|$yLbPHb}2@2L<`Wg zVIHzm9?o%!IV;&O<$Y^Q+x3s6LQG8(1Q;d!KgF5t*Ll#I6h)>-@9-AGcGd&=#TP8) znZ*Tkl$a*ZkVcl6f|fp!43?&rR?rWP*OP42mqWD}PI{%Jd}lF?%>GLQ+hug&QXy`X zeO#Hz%UWG0EuGuvK}1?!&>M#>j8q2F zeVk)K&ewR{^YrD~q#XDJBURA7@T zsa1^`Q+mp^6w4r{I@MGq>Hq|Cf1+|Ni>F0$6>l(S+K6{=V9GRbBQIeSXE(2$n%WAm zLa|F|_-2hQO0;+j{aol+2R+K$dU&`pS2D1i%*W1r4M^q$0Z++Ag!RF9t)toanPe6- zu$3IXGNa|vl^Z{OXUUt|z;XhX45M_Q%+GRrnBtB1!jWxE8TiF!4BR0GtBK2gj{^+y zB)#XuGGur9PcVOtkPA=CZt<3NHgX`#K9FFE4O8%qufyCENa`01H_dx7<4zetWu*fm ztT|%d1CCA3-=hHGvh;9yK^KA`Y)$vBg2G?s7H$<66ax)jaT1FGIoP(_t>Hf!b^M;V z>GY(Ib7wxA(RI~hb)L=7V0whI;p4M5BS~v+BO#k*Sai0B);0oE(hA>99|T5*`4UrV z%V7n0wGYDGD--E6NHE6*1O;hbn`}M9x?wh6W=BYq(DV;skLrG%=^N#_MBbUb(*7jv z(+mf`kqXoAZdGBjhabshuAFM_wdqh7u~u4xDlzGtAsJ|FP_E;(O|!S`GiARQmqOMG zl33BG>YG-a;$oSfDs(%Bj_zy)bNi^NR(0siT<}@o*v7k%))!HVOkF;SZ9!*|81c2x z;(^STEmWMYVugGV`3yGgKD4Kujk&Cw$IzsZQLQbbTx{J&Z|^LVJ=e*bG# zghDE7^{q&u#V#aUk)6m|$=+BR>x`uml29o^_MMDv?8X!&S;JVz+F~DLY%`4EcYTKL zbAQi$&iy;*@i?D9JRZf2@ma3xeZAhV*Yi@cux9!34W+y;FFfW0!@c~ls_a`|o#lER z|DD)uWwGX!IJ*&+rK{DeRc~da@;G!(bENC~*OcI1uoR8p`-hGf{*X^tHXxKT@g(9m zGkN{un2WGZG13rw)^{_9WE_yBr3@F#iC7^9gmKC1h(C?TTI$VtSaebN_f_>C7WH0( zRXH=gZ;G0geM2@6BQF0ac*_OG!TV%#+?@5E+w82TN-fFhsG;^nsW;T})Su)X>R06P zRW=fEd2Qhz_51>lsBrV)MU&Jk=UyjZy@k619MEsiy91Q&{5xe=woGv0LdX zAYMmA9LXPk`&zagwVp>c?^rz5ba^7jxcoF`Gj%XckNDFtbYV797$l6^Z`MOr}^vMf!D_KI7zFxJ6<;m#2}a`dw*7al z``E&-Z2#l`+8Yo*RX!;-Rn7-`DZrjqsY)~;fXL15`V?$Aqdz$UGH=NaM!QI9-{$`y zAqSWeGjey`VvAMKwZEUOt_-Zn7r~|vGw80pz?B%b;}%XK`8D6r`*dx*P!diZ1cOZG zlyx9?fO7}(?H3*ZJ1|LL4v_8whE=AXThI$EdYG^Y!$MADlae|_UPQ8N%}S(6$3?|<4>9Bc^}kdITdl3(46#@ z;*>IyJu*!;=q9AU#&QAW#4;D9Oj&ol;VvMUx0o>htMb7mPBc;93;Q~|Bz8EjIYU?)5-B+^@ z?H#{wYTMjUcCUUoIeh{5QFhxLfCiQZ*XE~p3L@O|r($B*0$ z;(5?LDeKaIt6baTPXsB7+xpzYKPe&W?qaXG3&1&(Q7SLh8gwr!io1+T8?~uUhd1{X zH3F?GY!4gM1quLPQW{(nyb=On6W@>zAv@cfN>;FpANHaVo;l&PRjAz?v}K&z6s3-= z1=@DF2Kel*SmPdo=hsx&wtrAI+wIAU3|Y)FVDCr}Pa~T7%DmLtYWkQ~2ol#_TY9GzL;dpdPs==VSo@)$ZM-_)`MOMFKv@yS#=Zt#qcQ%F%k|ry_!b4~Rx)C{F z3q3MOt71FpZUNj6N2(*ySN=JX)E$~dPc~r_WkvatA`F1^kXn{ty$bq*gEN5o0spGc zpD+^&@9k^MldWJldB~zfpvA(8Equ}j*6zgnCR$j*9S3A-{qg?MP1Fw~bb=u%<@rY2 z<#w%_NJH}wA+p;W+2P)``;}E|+9&lu^*s%ZInr>t&s>g;7k$P~3Jrvey{B!vtbCe- zl##6bqFu`S1myze@9?avJ(l>^R1A4z0*wnE7QFo(;@-GX9BkW0@5 zL#g!k9a6!Q#ACqDOGgx4UJ3m=2BJ0~uUtSK1Z*|u8-L=z^s>+}f?KZpQEr2V1b@Lh z-+XyWK67BH;0ylm-&pxq1AepK=43U;F;u~NMopBnv&k>HZ!Z^&bu#tH5U^=L&2cQT}So@Kdm%Vlr^9LZ>d7f*m|2VJeLQTOWxdQQ1FFAHhwp!~aGD4^t)R=i19djjD}q7s{;HN+c` zvgoW|;lFa9QSrojjx&>;CBJ{52d_d4#7+_cmg9VbckcC!JdoG42W_oh4cJaa0PE%( z$=f{yyad#N_`IR2cuALs^4_;Ls6$1M>;dkXZs&vLM3i{|G#AA3yLA>VYk?c>D~0_= z=s#Um(~vlBH&WRsvUX%;Y_GY*oa4UC`R}gNO20xtmzZryY*>}$!$4c#;{=PylOtCJ zbRNG&*aB4=$%Lp=uAeeWYG!@}=3@YPVrlem6k(yJr_B29s#M7_I5cvdu<3zqGXU+) z{v#!3Rr5C=tI&siqjt9|67Qw#UDsfKnx#i=W2765kV#ZdJ?B;{kT zW*Hw}OkIkNV&$0?Db&^OkUG7YQ&G7y2Y)M|S}>@IUMUUmx3pfFv{ zk{0GE)^Tczkxjq@ufHpI=UX0XqQD0b6E&jh75qiZLt1f-97P%LF<@f(!DF*5qgRmR zs$5Q#NnXyK2zeK#uWl$d`16J)We}8nL?7yeRng{#T6;431O4d`@<1oelg>C-1nHCmhu0Up;eTufRC}1wg{d(u7Hks#u5%D)D#b4bmR_ex~1ZNh<=bHWpKE9Vja)dS{B1D} z=m{w0fi!kyCV&5G-*7E{|5BFrDXuqh9^a&USxC|36~tF-11i}Fu&X^@T%(v`eC z!L4khTenHdRRCfrVPc@M2n6Ox0VeISPCF{O_qoq=@vrJ#4V#?t@V8ZV@Xa!gi3>nUO`o{#z!s76$AG-`_t<&p{0c&PlL7MC~a_owOsT-_6 zp%HKEeA*B_5~>ZRR3VFfvMn8UnprcdJ|OAh=n&2wJ;jnfHX^+8qHWUOBAQA`bxxlBvDmhw@p)UeHGa6`oC-n<{QJKiFkClZo-vG=VemvfwdVBJi5d)h_m` zk}bVa@jyJvhE4Q^93jot;VghW&dDuc3^@IcNK%6eZ4U|W+r04_`H*10m8TmJi*N>3eCe<){jo5&iw0@QQm|4pCwOpGT=L5 zvDoC6_eyb^lZH={E?PI30;te!fIQaK$Ka0V@?V+$W^fGHmng_-rSyP{M4mSi=qT=t zZi*Ryuf3@u`;1L;g8?m!>RRtqJgUBo6Url=cJl2$Xa+oy7H3T6IrpCB?9?^>9ds9z zfMfN0N1CtUJ0-ha3CJfZIUK*&Rdb?V0P7?-iFU!J3MCs8iqL(l{x$!^LS3)M*9_$M z&Ec(cX+ln$(_C&O0rSn;Y&pjW{Ce2VTLQ(o>MwV;&m)!-JBhIuK7>$b5o>72ALFI_ z$+t)WJWQY6&+CI*qk&V52g@?I@b-+}Xeb+Q48u9QM_x#TSC2;?@C4tMNN-@p$YO4!1Zn(yN!=2^S zMqJ3u=_(gU%yy*8MBm4E_<-$u{b{sZOM@}O=S}CFNq%i~0tLHgh=U{8qr9@Ytbb9F z^19kmZ~Ajmb>aNQjA_|Z)sd$)5-!Nkh_~zdv_~5NrYtLuF z*;@wnNmZGmA&OanY!L{ZRfpKIU!428Gsi}7CbH8<_DD`tS00vh-pRnecsFkRLGI0c z=EwfN;%;I|fbh}Dj&#e}XZxd-Y9gj4U=0YgL9NG;2-^#HWf%;@5f>aPq?b4JT(S%e z+LP>(5?thwE9kkQYDRkMESCo)ypDgFT!kZWWr>P2nOY^K2AO-4*t^!{#w?|~MLI49 zg+%OP7&WAfT_x5mYSS@M5K`vj6lBXit44wUb6)Hp>u|7S|Myf>@D|YVzgd=Feg5I7 zT-!D|wW(}k0$o&%U&+%(>>~I|syFF#~mZ=!-(bg$WiHF^F_r#NpKa*BeP;K=Hz+G8yv20&*$01Wn^WHBj`{ZU5F<6 zZx+TYLQ4)&{t+1xsXI6r*!8?unyQAN0>NoGU2iLSakX{JI$hFWhfl3`MpJ>==gm96 zN;^UP3TX$@rPq>t8}n%VgSlOELnOLjrODIgndpCzR(rVZ?wfS25Qfe<3NHWBXl_A+ zESU`omMh`Z`F)wcG8tCId}tssew=G(P#ggSNXwi?4uO=Ck*JCVL zxc{qdttHlPcV0|;WH`5dWkT_jPW?RsT>SvcQ@qLT9z-ucdU*eqFYyQoc0xi- zCf8;z@+u&G&T7IF(O~H`J^udBh~#WxvW;Oaq!F=6=!jqm4wmpTz@j5t${rAKhS*HL z!iNK{JOp@a0_37P=md3)B~>7X>yVST;($67Gc}(9J3CY7H^jYOjs#O^&w>lgE;|%k zh`T+>huEgXMGtnqtX`n;fNo1iGD)}vNop9Snp)``yx@=gp!(|&QwVLhUff9+2AD@c|!LBC#) z;vNAZPdAe0FcboTOaaGi7Hj@BHtm8(5mc>*Tk zXl=p#jhS^)?jWP0>{rMZ0E}5C4=~ZWyA`v->NsWM$SmdO{R*)nes<-|=TuI-Y&vW! z#0&XoKcLt=QgMf1i%x#U_hvZzgbtFv9%oVjrHYytZ|(5&Z@tk|`RRq@uVN(o@rs+z z%?fDRK;?LVN(ub5hF#YQ0IZd{CrN_DHV z@$-0YsuoSGr4VQg6|zirhM6NN7wmwG?jD|rQEJU^F~a4q8vmJ}fgF1kWkm__kE%*-|L)B58qPMP078_cJS-gx|im=N_0F(Twj8Ve0p>bl_YB}4-`-w0Obvq@%eQ3Al8 z-h+2wE!N}uXDM*OIz65vPy>KqoH5b^5hPG_( z$!F-HRS@WOi76=hR$qX6rCinRHSKe`z$3nI0mK*>o%A&^HVf2W4J(W8o^}90xp0TD zpS!b_@lyBHHg@+CR{qLv^W4dD`|GkDE#q)#KsO7_c}OKQJ)G zgkbL&RNF9FF9s+gCM2KH+nvX;Yy!K#FkY>-dx=n?i{rWmbcfuvc>`*;SHw6vbRy&y zGg~MZkkASN?Ku&*sIJ_WL)P-$>%(Y`NzxO5y zivcVc6psNcFP=AsSkP!cakpK7CBG~sJH6$lJt-BpzuIMGGkR(@Eu~HTSL~BRL8{$1 z;A}Y)I;s59Z!;M3el>PnudlkX?&_6#Tziqrp`uC!zQah(&8>*#*d-h&V9k`2l(y$E zM|!+c4~_ktXjR>TNxHCkxH(Z;zU%;katuJnbD#-%8%oeH9RVh0s%Wn9xRG(CjOY5i zo!BzAL9}9-%c&3T0NU0&nOh@EoTfVa4myyOV~h;dXQ~FTH0_b|w*W)F^IYPER_63! z>FMxaGY)!e8HSxCz~Jx{1~~d_fQkJardf|adp(LWHiv!?i~T4H2=jw(IB{;%o60YO zLKLZY>_TS_ap=e!i>pTjtDSS1EPg&M^j){`qR*$bzN+>le8o+%zxdk0z*3cXotwR_ z7xV;*nAP>qcIZAZ8j3+M<)|BYo3X9WCEUrcB#-$`mQR^a9=)>1HqOQVqv|oG8{L3E z-tw>LfONIL;SFVEK4sna-fi4nO+=M@5{k`t2{XKBmC`;-I7V)v;0{D)^DF+P9#Jee zS1~kKO|0F5!aXujr<=Hs?`Lr%k7xQh3so7CK(y|I zIy>~^KYPaO*~~;47?=;=P*F1cKVZK7cmDB+=r?_@Q|ci&H=nR@F(3h&%AViTa6;;hQz|UDu@b|`K^oG1XBC}=Y9KU3FP7&p!F`Z zXtdN0mPEm*lt-BIJoE%m9)+wB6Ky@&s?1Ihd7-VbFq439$0(8a9d z>7&t`XE{0#RF1M!T{oT07CXw4)8AZ+k*F^34+xkFPCg||%RCmOIg7`j%KRtDt~N{# z=zQbNHOuq%+}(?sHapJ;)G#Z0clkwBC3uHPVt)H~4aNAL{<9Sd)VE{M{{<>a*gVgk zo>S+VALRtK}bsn}SeL}+$QI0B#D8&0+#W0$%=@U&T2LBOka$-8dV zgVWw`Dyh19te^8#Xph!cp#!8^>#rf^M*XZ9U?Ky@Rbl$*zx+My+=G5b zJPc09ABRX4gIVPy3A%K_XG8HMI}t6YJ9FugDF= zAdWh;oe*F+`>gYV$B+OG#T-)AQh^t3n;h*qooZdPyn0OZ88>b5x;_e&c}04xoq{j>W*gOa~c zT?7aeIsa;XXqiIpK0*+Kf*ge)6ae-~fuh%Nb+)p=B;Po+wpJ{4Vw>9!Shpp~>CQ4h zN&rIECsybF9|}^0z7Ce<%w)UvT%(og?05p$K4(bQ0Wuf^(Mwc1_k56IeK1QoFe#L1 zEN&c#Rcvj=a1NKBTlDx7r1jrI=ggCJaek$7Z< z+^*o3)b6k(gS4IWYCdrIh}Fc1*s;lR;{HV?!;>2oX%7T>nN;_`qW^&muc1enGcRXM z$HJhue(N@5NY35PAVNR0wXfKyxCsC)gY73W>uiwz{<_-+iEP<_P*(rDZ2=%|gZ_&| z#jLMCzGwnKY4ys$j!$x1zdd;)89-5lPd3}GBh;VSFyW~ovE^(x1%Y|mgS91!@0He?c z?BR?_?7cbrxx_5*ZFW|NAU8V~1JIkRW1D^Tk+gw_qG#pFM3f~^J>))Owm;=G2UOF@ z(^H9ZL>*5MEC+NR>GGw<2fv%pZSfw>#?~{Sc#GqUqa$DI5&WQ9RDfL>5{ z07^1M&nIlmtbrD<)m;C#GC$vs!}wAufDfIXmG^FB_1B00xj+npU`S(V${1FF-$KDL z0geLzytH+&)B6SgG$!Xid95Eu76jEt^D5~)dDTv;d$tlDmnl_xE8nc&DZoc$d-7qJ z7K2hP)$Sv>5b=dTcTk|JP)=ihWp0RSHiI}Qu&g8greEgWEG_xoR1 zweQo|GR{0&gSH`@KCwp;Yf;;9h7CIq3>aP-96VmjM=XfR*av<5Z*Vs`YNa}s*ZV86 zjScJ6cYk2Q*#Yzh9Rzq|R9wYD-BF86Z7dp&iGimXVZ=nx&4Z**aOjTE&lun%s{6mO zl8uZ2+lp*|XOaG$e^=%!)If1{u+v9+HF@hr431_0HOBZ$SWF*wX%5=-qa4}b-y1w6 z-m=$n^RV&C-1M?1p>)?Ea_b$E6;kLoF_PB(du0PjG>d=H^S8^(;Fw=0#Y`v;qYl8* zoJ%&>iJR#6nyD)lTZI|Jv?w_5SMxIp0T%7tgNcpQKG*H5xux`Oe^A{JacNKUd47hM zJA;CPqN6xGC>QxZ8I^jIUXNO=qA;FU=eM@!VW97*29?U&uY7;wA1O<4{_Nh-HZ`jP V-)#_23_w3{LseS^b?wfR{|B&Djy(VX literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/verify-valid-cargo.png b/accelerators/aks-sb-azmonitor-microservices/assets/verify-valid-cargo.png new file mode 100644 index 0000000000000000000000000000000000000000..3caa3b67cb008ba20b9b9b1982a30219990fc425 GIT binary patch literal 66231 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 A+5i9m literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/workbook-aks-metric.png b/accelerators/aks-sb-azmonitor-microservices/assets/workbook-aks-metric.png new file mode 100644 index 0000000000000000000000000000000000000000..25fefc026ca662df8fdbddc31ebfc1d8a73caa9e GIT binary patch literal 30233 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 literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/workbook-key-vault-metric.png b/accelerators/aks-sb-azmonitor-microservices/assets/workbook-key-vault-metric.png new file mode 100644 index 0000000000000000000000000000000000000000..21c6ba9d380c79049da56b836ab98d7610529dc6 GIT binary patch literal 111505 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

Nfys7Y=zJJwM*hQM5w>ywso@I;3bRTz? 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 literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/deploy-bicep.sh b/accelerators/aks-sb-azmonitor-microservices/deploy-bicep.sh new file mode 100644 index 0000000..bc987c9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/deploy-bicep.sh @@ -0,0 +1,109 @@ +#!/bin/bash +set -e + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +function help() { + echo + echo "deploy-bicep.sh" + echo + echo "Deploy sample via Bicep" + echo + echo -e "\t--skip-helm-deploy\t(Optional)Skip Helm deployment of services to AKS" + echo -e "\t--aks-aad-auth\t(Optional)Enable AAD authentication for AKS" + echo +} + + +# Set default values here +SKIP_HELM_DEPLOY=false +AKS_AAD_AUTH=false + + +# Process switches: +SHORT=h +LONG=skip-helm-deploy,aks-aad-auth,help +OPTS=$(getopt -a -n files --options $SHORT --longoptions $LONG -- "$@") + +eval set -- "$OPTS" + +while : +do + case "$1" in + --skip-helm-deploy) + SKIP_HELM_DEPLOY=true + shift 1 + ;; + --aks-aad-auth ) + AKS_AAD_AUTH=true + shift 1 + ;; + -h | --help) + help + exit 0 + ;; + --) + shift; + break + ;; + *) + echo "Unexpected '$1'" + help + exit 1 + ;; + esac +done + +if [[ -z $IN_CD ]]; then # skip loading env vars if running in CD (as they are already set) + if [[ ! -f "$script_dir/.env" ]]; then + echo "Please create a .env file (using .env.sample as a starter)" 1>&2 + exit 1 + fi + source "$script_dir/.env" +fi + +if [[ -z "$USERNAME" ]]; then + echo 'USERNAME not set - ensure you have specifed a value for it in your .env file' 1>&2 + exit 6 +fi + +if [[ -z "$EMAIL_ADDRESS" ]]; then + echo 'EMAIL_ADDRESS not set - ensure you have specifed a value for it in your .env file' 1>&2 + exit 6 +fi + +deploy_args=() +if [[ "$AKS_AAD_AUTH" == "true" ]]; then + deploy_args+=(--aks-aad-auth) +fi + +# Set default values +LOCATION=${LOCATION:-eastus} + +figlet infra +echo "Starting Bicep deployment to $LOCATION" +echo "${deploy_args[@]}" | xargs "$script_dir/infrastructure/scripts/deploy-bicep-infrastructure.sh" --username "$USERNAME" --email-address "$EMAIL_ADDRESS" --location "$LOCATION" +echo "Bicep deployment completed" + +figlet images +echo "Building and pushing service images" +ACR_NAME=$(jq -r '.acr_name' < "$script_dir/output.json") +if [[ ${#ACR_NAME} -eq 0 ]]; then + echo 'ERROR: Missing output value acr_name' 1>&2 + exit 6 +fi +"$script_dir/infrastructure/scripts/build-and-push-images.sh" --acr-name "$ACR_NAME" --image-tag latest + +figlet env +echo "Creating env files" +"$script_dir/infrastructure/scripts/create-env-files-from-output.sh" + +if [[ "$SKIP_HELM_DEPLOY" == "true" ]]; then + echo "Skipping Helm deployment" +else + figlet services + echo "Deploying services" + echo "${deploy_args[@]}" | xargs "$script_dir/infrastructure/scripts/deploy-helm-charts.sh" +fi + +echo "Deployment completed" diff --git a/accelerators/aks-sb-azmonitor-microservices/deploy-terraform.sh b/accelerators/aks-sb-azmonitor-microservices/deploy-terraform.sh new file mode 100644 index 0000000..2ad5756 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/deploy-terraform.sh @@ -0,0 +1,109 @@ +#!/bin/bash +set -e + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +function help() { + echo + echo "deploy-terraform.sh" + echo + echo "Deploy sample via Terraform" + echo + echo -e "\t--skip-helm-deploy\t(Optional)Skip Helm deployment of services to AKS" + echo -e "\t--aks-aad-auth\t(Optional)Enable AAD authentication for AKS" + echo +} + + +# Set default values here +SKIP_HELM_DEPLOY=false +AKS_AAD_AUTH=false + + +# Process switches: +SHORT=h +LONG=skip-helm-deploy,aks-aad-auth,help +OPTS=$(getopt -a -n files --options $SHORT --longoptions $LONG -- "$@") + +eval set -- "$OPTS" + +while : +do + case "$1" in + --skip-helm-deploy) + SKIP_HELM_DEPLOY=true + shift 1 + ;; + --aks-aad-auth ) + AKS_AAD_AUTH=true + shift 1 + ;; + -h | --help) + help + exit 0 + ;; + --) + shift; + break + ;; + *) + echo "Unexpected '$1'" + help + exit 1 + ;; + esac +done + +if [[ -z $IN_CD ]]; then # skip loading env vars if running in CD (as they are already set) + if [[ ! -f "$script_dir/.env" ]]; then + echo "Please create a .env file (using .env.sample as a starter)" 1>&2 + exit 1 + fi + source "$script_dir/.env" +fi + +if [[ -z "$USERNAME" ]]; then + echo 'USERNAME not set - ensure you have specifed a value for it in your .env file' 1>&2 + exit 6 +fi + +if [[ -z "$EMAIL_ADDRESS" ]]; then + echo 'EMAIL_ADDRESS not set - ensure you have specifed a value for it in your .env file' 1>&2 + exit 6 +fi + +deploy_args=() +if [[ "$AKS_AAD_AUTH" == "true" ]]; then + deploy_args+=(--aks-aad-auth) +fi + +# Set default values +LOCATION=${LOCATION:-eastus} + +figlet infra +echo "Starting Terraform deployment to $LOCATION" +echo "${deploy_args[@]}" | xargs "$script_dir/infrastructure/scripts/deploy-terraform-infrastructure.sh" --username "$USERNAME" --email-address "$EMAIL_ADDRESS" --location "$LOCATION" +echo "Terraform deployment completed" + +figlet images +echo "Building and pushing service images" +ACR_NAME=$(jq -r '.acr_name' < "$script_dir/output.json") +if [[ ${#ACR_NAME} -eq 0 ]]; then + echo 'ERROR: Missing output value acr_name' 1>&2 + exit 6 +fi +"$script_dir/infrastructure/scripts/build-and-push-images.sh" --acr-name "$ACR_NAME" --image-tag latest + +figlet env +echo "Creating env files" +"$script_dir/infrastructure/scripts/create-env-files-from-output.sh" + +if [[ "$SKIP_HELM_DEPLOY" == "true" ]]; then + echo "Skipping Helm deployment" +else + figlet services + echo "Deploying services" + echo "${deploy_args[@]}" | xargs "$script_dir/infrastructure/scripts/deploy-helm-charts.sh" +fi + +echo "Deployment completed" diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/alerts.md b/accelerators/aks-sb-azmonitor-microservices/docs/alerts.md new file mode 100644 index 0000000..c74c122 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/alerts.md @@ -0,0 +1,57 @@ +# Alerts + +[Alerts](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-overview) proactively notify application administrators when the data ingested by Azure Monitor suggests the application is experiencing problems, or will in the near future. Visualization tooling like Workbooks highlight important indicators from the application and can illuminate issues, but require active, manual watching by administrators. Alerts can take those same indicators one step further by taking automated, prescriptive action when certain conditions are met. Rather than requiring active watching of a dashboard, alerts let application admins understand and resolve issues with the application _before_ they become problematic for most downstream users of the system. + +Azure alert rules are scoped to a specific resource. These resources emit different telemetry signals, defined by the resource type. Service Bus namespaces emit a numeric `DeadletteredMessages` metric, for instance, while AKS emits `node_cpu_usage_percentage`, among other metrics. The application relies on a number of metric alerts that utilize these signals. It also utilizes several log alerts that use KQL queries to pull the data evaluated in alert conditions. The `cargoProcessingAPIHealthCheckFailure` alert, for example, uses the following KQL query to pull failed health checks for the `cargo-processing-api` service: + +```sql +requests +| where cloud_RoleName == "cargo-processing-api" and name == "GET /actuator/health" and success == "False" +``` + +Alert conditions combine the signal and some numeric threshold that may be met over a defined window of time. If a signal exceeds some threshold over a time window defined in an alert rule, the alert fires and triggers an action group. Severity levels dictate the relative importance of the alert and mitigation steps. Certain alerts suggest with high likelihood that the application is already experiencing issues, like the microservice exceptions alert (`microserviceExceptions`). Immediate attention should be paid to uncover the underlying issue and resolve the alert. Others, like the Key Vault saturation rate (`keyVaultSaturation`) or number of invalid cargo objects saved (`cosmosInvalidCargo`), don't necessarily require immediate action but suggest that an administrator should take a closer look. + +We elected to create alert rules for signals that suggested issues with the underlying infrastructure or the service code deployed to AKS that utilizes it. Each of the microservices has average duration, health check failure, and health check not reporting alerts. A single microservice exceptions alert is split across the 5 services and alerts when any microservice throws a certain number of exceptions. The combination of these alerts proactively notifies when a service has experienced failure or become less performant. Service Bus exposes many message count metrics, like dead-lettered and abandoned messages, that are also important indicators of application issues and are used in rules. Deadlettered messages, for example, may suggest that the initial `cargo-processing-api` service is not properly validating the cargo object structure before sending the message to the `ingest-cargo` queue. The AKS and Log Analytics alerts include the pre-defined, [recommended alert rules](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-overview#recommended-alert-rules) that suggest impending failure for those resource types. The full list of alerts deployed alongside the application is as follows: + +| Alert Name | Description | Entity | Alert Type | Severity | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------- | ----------------- | ---------- | -------- | +| cosmosRUs | Alert when RUs exceed 400. | Cosmos DB | Metric | 1 | +| cosmosInvalidCargo | Alert when more than 10 documents have been saved to the invalid-cargo container. | Cosmos DB | Metric | 3 | +| serviceBusAbandonedMessages | Alert when a Service Bus entity has abandoned more than 10 messages. | Service Bus | Metric | 2 | +| serviceBusDeadLetteredMessages | Alert when a Service Bus entity has dead-lettered more than 10 messages. | Service Bus | Metric | 2 | +| serviceBusThrottledRequests | Alert when a Service Bus entity has throttled more than 10 requests. | Service Bus | Metric | 2 | +| aksCPUPercentage | Alert when Node CPU percentage exceeds 80. | AKS | Metric | 2 | +| aksMemoryPercentage | Alert when Node memory working set percentage exceeds 80. | AKS | Metric | 2 | +| aksPodRestarts | Alert when a microservice restarts more than once. | AKS | Log | 1 | +| keyVaultSaturation | Alert when Key Vault saturation falls outside the range of a dynamic threshold. | Key Vault | Metric | 3 | +| logAnalyticsDataIngestionDailyCap | Alert when the Log Analytics data ingestion daily cap has been reached. | Log Analytics | Log | 2 | +| logAnalyticsDataIngestionRate | Alert when the Log Analytics max data ingestion rate has been reached. | Log Analytics | Log | 2 | +| logAnalyticsOperationalIssues | Alert when the Log Analytics workspace has an operational issue. | Log Analytics | Log | 3 | +| microserviceExceptions | Alert when a microservice throws more than 5 exceptions. | App Insights/Code | Log | 1 | +| productQtyScheduledForDestinationPort | Alert when a single port/destination receives more than quantity 1000 of a given product. | App Insights/Code | Metric | 3 | +| e2eAverageDuration | Alert when the end to end average request duration exceeds 5 seconds. | App Insights/Code | Log | 1 | +| cargoProcessingAPIRequests | Alert when the cargo-processing-api microservice is not receiving any requests. | App Insights/Code | Log | 3 | +| cargoProcessingAPIAverageDuration | Alert when the cargo-processing-api microservice average request duration exceeds 2 seconds. | App Insights/Code | Log | 1 | +| cargoProcessingAPIHealthCheckFailure | Alert when a cargo-processing-api microservice health check fails. | App Insights/Code | Log | 1 | +| cargoProcessingAPIHealthCheckNotReporting | Alert when the cargo-processing-api microservice health check is not reporting. | App Insights/Code | Log | 1 | +| cargoProcessingValidatorAverageDuration | Alert when the cargo-processing-validator microservice average request duration exceeds 2 seconds. | App Insights/Code | Log | 1 | +| validCargoManagerAverageDuration | Alert when the valid-cargo-manager microservice average request duration exceeds 2 seconds. | App Insights/Code | Log | 1 | +| validCargoManagerHealthCheckFailure | Alert when a valid-cargo-manager microservice health check fails. | App Insights/Code | Log | 1 | +| validCargoManagerHealthCheckNotReporting | Alert when the valid-cargo-manager microservice health check is not reporting. | App Insights/Code | Log | 1 | +| invalidCargoManagerAverageDuration | Alert when the invalid-cargo-manager microservice average request duration exceeds 2 seconds. | App Insights/Code | Log | 1 | +| invalidCargoManagerHealthCheckFailure | Alert when an invalid-cargo-manager microservice health check fails. | App Insights/Code | Log | 1 | +| invalidCargoManagerHealthCheckNotReporting | Alert when the invalid-cargo-manager microservice health check is not reporting. | App Insights/Code | Log | 1 | +| operationsAPIAverageDuration | Alert when the operations-api microservice average request duration exceeds 1 second. | App Insights/Code | Log | 1 | +| operationsAPIHealthCheckFailure | Alert when an operations-api microservice health check fails. | App Insights/Code | Log | 1 | +| operationsAPIHealthCheckNotReporting | Alert when the operations-api microservice health check is not reporting. | App Insights/Code | Log | 1 | + +All alerts in the cargo processing application are [_stateful_](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-overview#alerts-and-state), meaning that they will fire when the condition is met, but _will not_ fire again until the condition is resolved. They all utilize the same action group, which notifies an administrator via email. [Action groups](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/action-groups) _can_ contain additional actions, like triggering webhooks, Logic Apps, Azure Functions, and more. The notification email address is set in the initial `.env`: + +```yaml +# Email address for alert notifications +EMAIL_ADDRESS=youremail@organization.com +``` + +Most alerts use static thresholds to evaluate the telemetry signals emitted from the application. These alert rules use specific threshold values for a signal pre-defined by the application team. The Cosmos DB RUs alert, for instance, defines a static threshold of 400 RUs that will trigger an alert when exceeded. The Key Vault saturation rate alert, however, uses a [dynamic threshold](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-dynamic-thresholds) that uses a machine learning algorithm to define it. The algorithm uses 10 days of recent data to evaluate patterns and calculate the correct threshold for the signal. The thresholds and windows defined in the alert conditions are easily configurable via [Bicep](../infrastructure/bicep/modules/alerts.bicep) or [Terraform](../infrastructure/terraform/modules/alerts/main.tf). + +No [alert processing rules](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-processing-rules?tabs=portal) are used, but could be easily added to modify or suppress certain alerts before they fire. diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/auto-vs-manually-instrumented-telemetry.md b/accelerators/aks-sb-azmonitor-microservices/docs/auto-vs-manually-instrumented-telemetry.md new file mode 100644 index 0000000..759ecdc --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/auto-vs-manually-instrumented-telemetry.md @@ -0,0 +1,26 @@ +# Auto vs Manually Instrumented Telemetry + +The telemetry data generated by the application can be separated into two distinct groups - automatically and manually instrumented data. + +Automatically instrumented logs, metrics, and traces are produced by the application without any addition of custom code. Each exporter or SDK auto-instruments a unique set of telemetry data. The Java-based API services that utilize OpenTelemetry exporters for Azure Monitor, for instance, instrument a significant amount of telemetry data, by default, while the Typescript-based `cargo-processing-validator` service uses Application Insights SDK setup methods to [define the level of auto-instrumentation](../src/cargo-processing-validator/src/index.ts). Each SDK/exporter defines its own set of [auto-collected items](https://opentelemetry.io/docs/instrumentation/java/automatic/) for review. + +Much of the telemetry we depend on for visualization or alert functionalities is generated out-of-the-box by the services in the application. Distributed tracing, for instance, depends on a number of spans produced automatically by these services. The Azure resources that support the application like Cosmos DB, Service Bus, Key Vault, etc. automatically export additional data that are used in Workbooks and Alert rules, like the number of dead-lettered messages in each queue and topic subscription. + +Manually instrumented data refers to the data generated via custom code added to one of the microservices. The exporters and SDKs expose various methods to produce telemetry data in order to augment the initial, automatically instrumented set. It fills in the gaps that auto-instrumented data fails to provide. The set of auto-instrumented data generated by the application was first examined before determinations were made about what additional data was required to support the proposed Workbooks tiles and Alert rules. We elected to manually instrument data that enabled distributed traces, additional logging for debugging purposes, health checks, tracking of specific business rules, and more. + +The following examples display automatically and manually instrumented logs, metrics, and trace data in Azure Monitor that was exported by the application: + +The `cargo-processing-api` service automatically instruments a log related to sending a batch of messages, while the "Validating cargo schema" log results from a `logger.info()` call within its [CargoController](../src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoController.java) class: +![Auto-Instrumented Log](../assets/log-auto.png) +![Manually-Instrumented Log](../assets/log-manual.png) + +The `jvm_memory_used` metric is automatically instrumented by the `cargo-processing-api` service, while the `port_product_qty` custom metric is [manually instrumented within](../src/valid-cargo-manager/Services/SubscriptionReceiver.cs) the `valid-cargo-manager` service: +![Auto-Instrumented Metric](../assets/metric-auto.png) +![Manually-Instrumented Metric](../assets/metric-manual.png) + +The `TotalRequestUnits` metric is automatically instrumented by the Cosmos DB resource: +![Auto-Instrumented Metric](../assets/metric-auto-rus.png) + +The span that represents the initial POST request to the `cargo-processing-api` is automatically instrumented. The message send dependency to the `validated-cargo` Service Bus topic is represented by a manually instrumented span [generated within](../src/cargo-processing-validator/src/services/ServiceBusWithTelemetry.ts) the `cargo-processing-validator` service: +![Auto-Instrumented Span](../assets/span-auto.png) +![Manually-Instrumented Span](../assets/span-manual.png) diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/custom-dimensions.md b/accelerators/aks-sb-azmonitor-microservices/docs/custom-dimensions.md new file mode 100644 index 0000000..65bb259 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/custom-dimensions.md @@ -0,0 +1,148 @@ +# Custom Dimensions + +When examining the behavior of a system, we often find aspects that we want to explore more deeply. For example, if we see that some requests in the system are taking longer than expected we may want to know more about the specific requests that are slow. Are all requests slow or just some of them? Are there common features to the slow requests? Do the requests all come from a particular system? In a multi-tenant system, are the slow requests distributed across all tenants or just a subset? + +As we explore these questions, we may find that we need to filter our telemetry data by additional properties. For example, we may want to filter our telemetry data by the request path, or by the tenant ID. Some of these properties will be available in the telemetry data by default, but others will not. For the properties that aren't part of the default data collected, we can use custom dimensions to add the additional information to our telemetry data. + +One place where we add custom dimensions in this project is in the `cargo-processing-validator` service. In the next couple of sections we will see what the custom dimensions look like from the monitoring dashboard and explore the implementation in code. + +## Custom Dimensions in Action + +In this section we will generate some test load on the system and then explore the telemetry dashboard to see the custom dimensions in action. + +To generate the test load, we will use the code in `src/cargo-test-scripts`. That folder contains a dev container for use with Visual Studio Code which makes it easy to run the scripts. If you are using Visual Studio Code, you can open the folder in a dev container by selecting the `Open Folder in Container` option from the `File` menu. The folder also contains a [README.md](../src/cargo-test-scripts/README.md) file with instructions for running the scripts from the command line. + +From the terminal in the dev container, run the following command to generate some test load: + +```bash +cat << EOF | node index.js -c - +{ + "tests": [ + { + "name": "Send cargo to cargo processing api", + "target": "cargo-processing-api", + "volume": 500, + "validateResults": false, + "delayBetweenCargoInMilliseconds": 1500, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0 + + } + } + ] +} +EOF +``` + +This command will generate 500 cargo messages and send them to the `cargo-processing-api` service. The cargo messages will be sent at a rate of one message every 1.5 seconds. The cargo messages will not be validated, so all of them will be sent to the `valid-cargo-manager` service. + +Now that we are sending load, we can open the Once you have this running, open the [Azure portal](https://portal.azure.com) and navigate to the resource group you deployed to. Next, select the `Service Processing` Workbook as shown below: + +![Resource Group List Showing Service Processing Workbook](../assets/dimensions-rg-list.png) + +Next, click the `Open Workbook` button. You should see a screen similar to the following (if you don't see any telemetry then ): + +![Service Processing Workbook With Initial Telemetry](../assets/dimensions-workbook-initial.png) + +The top chart in the diagram above shows the end-to-end processing time for a cargo message and the chart below it shows the number of requests. + +Now that we have some baseline load through the system, kill the previous load command by pressing `Ctrl+C`, and run the following command instead: + +```bash +cat << EOF | node index.js -c - +{ + "tests": [ + { + "name": "Send cargo to cargo processing api with 50% chance of slow port", + "target": "cargo-processing-api", + "volume": 500, + "validateResults": false, + "delayBetweenCargoInMilliseconds": 1500, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0, + "chaosSettings": [ + { + "target": "cargo-processing-api", + "type": "slow-port", + "chanceToCauseChaos": 2, + "isEnabled": true + } + ] + } + } + ] +} +EOF +``` + +This command will generate and send cargo messages as before, but this time with a 50% chance that the destination port will be set to `slow-port`. The code in the `cargo-processing-validator` service has code that simulates making a call to a service at the destination port. When the the port is `slow-port` the simulation adds an extra delay. + +Now that we have some load that includes the `slow-port`, we can go back to the `Service Processing` Workbook and refresh the data. You should see a screen similar to the following: + +![Service Processing Workbook With slow-port Telemetry (Overview)](../assets/dimensions-workbook-slow1.png) + +In the top chart we can see a slight increase in the overall processing time. The chart below shows that the number of requests hasn't increased. Continuing down the charts, the bottom chart shows that the increase in processing time is due to the `cargo-processing-validator` service. + +Further down the workbook we have the "Service Breakdown" section which allows us to drill into telemetry for each of the services. From the `cloud_RoleName` dropdown, select `cargo-processing-validator` and you should see a screen similar to the following: + +![Service Processing Workbook With slow-port Telemetry (Service Breakdown)](../assets/dimensions-workbook-slow2.png) + +The top chart in the "Service Breakdown" section shows the request breakdown for the selected service (mean, median, max and 95%th centile durations) and this confirms that the increase in processing time is due to the `cargo-processing-validator` service. The chart below shows the dependency breakdown for the selected service. Looking at this chart we can see that the dependency for the simulated call to the destination port service looks normal for all ports apart from the `slow-port`. +The final chart shows the end-to-end processing time broken out by destination port, and this also highlights the increase in processing time for the `slow-port`. + +## Implementing Custom Dimensions in cargo-processing-validator + +In this section we will look at the code in the `cargo-processing-validator` service to see how the custom dimensions are implemented. The code for the `cargo-processing-validator` service is in the `src/cargo-processing-validator/src` folder. + +When a message is received from Service Bus, a `request` telemetry item is started. The code that does this is unaware of the content of the messages, so it only attaches standard fields on the telemetry item. There are two steps to adding custom dimensions to the telemetry item. First, we obtain the telemetry correlation context and set the custom properties. Secondly, we use a telemetry processor to modify the telemetry items before they are sent to Application Insights. + +The code below (from `services/ServiceBusProcessingService.ts`) shows how we obtain the telemetry correlation context and set the custom properties when processing a message from Service Bus: + +```typescript +// get the correlation context +const correlationContext = appInsights.getCorrelationContext(); +// strip commas from the destination port value as they are not allowed +const destination = validatedCargo.port.destination.replaceAll(',', ';'); +// set the custom property +correlationContext.customProperties.setProperty( + CUSTOM_PROPERTY_CARGO_DESTINATION, + destination +); +``` + +Once the correlation context is updated, we need a telemetry processor that will modify the telemetry items before they are sent to Application Insights. The code below (from `index.ts`) shows how we add a telemetry processor to the Application Insights client and use it to update the telemetry items based on the values in the correlation context: + +```typescript +const client = appInsights.defaultClient; +client.addTelemetryProcessor((envelope, contextObjects) => { + // envelope is the telemetry item being processed + // Here we set a variable to point to the properties of the telemetry item for convenience + const envelopeProperties = envelope.data?.baseData?.properties; + + // Check whether we have the destination property set on contextObjects.correlationContext + // which is the correlation context associated with the telemetry item being processed (if set). + if ( + envelopeProperties && + customProperties?.getProperty(CUSTOM_PROPERTY_CARGO_DESTINATION) + ) { + // Assign the custom dimension value on the telemetry item + envelopeProperties['cargo-destination'] = customProperties.getProperty( + CUSTOM_PROPERTY_CARGO_DESTINATION + ); + } + + // return true to allow the telemetry item through (we could return false to discard it) + return true; +}); +``` + +With these pieces in place, we can now see the custom dimension in the telemetry items that are sent to Application Insights. For example, the following query will show the request telemetry items for the `cargo-processing-validator` service and add a `destinationPort` field using the value of the `cargo-destination` custom dimension: + +```kusto +requests +| where cloud_RoleName == "cargo-processing-validator" +| extend destinationPort = customDimensions["cargo-destination"] +| order by timestamp desc +``` diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/custom-metrics.md b/accelerators/aks-sb-azmonitor-microservices/docs/custom-metrics.md new file mode 100644 index 0000000..23cc1a1 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/custom-metrics.md @@ -0,0 +1,37 @@ +# Custom Metrics + +Metrics track key indicators over time and provide a neat, numeric value that can be displayed in a time series, used in alerts, and more. The application tracks a multitude of metrics automatically, like the `jvm_memory_used` metric that measures the number of bytes used by the Java based API services. + +Organizations often have additional indicators related to specific business rules or industry-wide ones that are meaningful to track and necessary to understand system health. Custom metrics enable generation of data points over time against these metrics that aren't tracked by default. The application tracks an additional metric, `port_product_qty`, that captures the total quantity of specific products scheduled for shipment to specific ports. Ports do not have unlimited capacity to accept shipping containers. Administrators need to be able to retrieve data on an ad-hoc basis that illuminates product velocity on each port and rely on alerts that proactively notify them when the total shipping container quantity of a given product scheduled for a specific destination port exceeds some value defined by the business. + +The `valid-cargo-manager` generates the custom metric as it is the last service to interact with a valid cargo object destined for shipment to a port (invalid cargo objects are simply stored for later processing). It generates a multi-dimensional custom metric, tracking the product quantity, while passing in `product`, `source`, and `destination` dimensions taken from the cargo. + +```c# +private void TrackMultiDimensionalMetrics(ValidCargo cargo) +{ + var metric = _telemetryClient.GetMetric("port_product_qty", "product", "source", "destination", _customMetricConfiguration); + + metric.TrackValue(cargo.Product.Quantity, + cargo.Product.Name, + cargo.Port.Source, + cargo.Port.Destination); +} +``` + +Importantly, the `GetMetric` and `TrackValue` methods pre-aggregate the metric before sending the values every minute. `TrackMetric`, also exposed by the SDK, sends a separate telemetry item every time the method is called and is no longer the preffered approach for generating custom metrics. Rather than generate a new record with a specific value every time the metric is tracked, the service exports an aggregated metric record every minute that includes properties like **value**, **valueCount**, **valueSum**, **valueMin**, and **valueMax**. **valueCount** defines the number of times the metric was tracked over that minute, **valueSum** is the total sum of each of the values, etc. + +The custom metric is exported each minute for every specific custom dimension combination. All metric data tracked that includes the same `product`, `source`, and `destination` within the same minute will be grouped together in Application Insights records. If `TrackValue` is called twice within the same minute with `product-Cars, source-New York City, destination-Miami` then they will be grouped together. If, in that same minute `TrackValue` is called with `product-Cars, source-Seattle, destination-Tacoma` then that metric data is exported separately: + +![Custom Metric Dimensions](../assets/custom-metric-dimensions.png) + +The custom metric is exported to Application Insights as both a [log-based and pre-aggregated](https://learn.microsoft.com/en-us/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics) metric. The pre-aggregated version is optimized for time series and enables faster, more performant queries. It _only_ maintains certain dimensions and other specific properties, in contrast with the log-based version that includes all relevant information attached to the record. To ensure that the pre-aggregated metric version has the dimensions we rely on, they must be [enabled via the App Insights resource in the Portal](https://learn.microsoft.com/en-us/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics#custom-metrics-dimensions-and-pre-aggregation) after deployment (currently in Preview and unsupported in ARM). + +The alert we employ relies on the `product` and `destination` dimensions within the custom metric, alerting when the total quantity of a given `product` exceeds 1000 for a given `destination` port over a single minute interval. The alert rule maintains different time series for each `product`/`destination` combination and alerts on each separately: + +![Custom Metric Alert](../assets/custom-metric-alert.png) + +The `source` port is irrelevant. Cars sent to Miami from New York and cars sent to Miami from Boston will roll up together and the total product quantity across both will be used. If `source` was added as a dimension to the alert, for instance, these would be split into two different time series and alerted on separately. The number of ports and products used could quickly inflate the number of time series Azure Monitor maintains, resulting in throttling, reduced system performance, increased cost, etc. By default, Azure Monitor limits metrics to 1000 total time series and 100 unique values per dimension. These values can be customized and set by the TelemetryClient that originally exports the metrics. The `valid-cargo-manager` that instruments the `port_product_qty` custom metric sets series count and values per dimension limits to 100 and 40 respectively, to guard against potential scale issues. The configuration allows for 40 unique destination ports and products, with no more than 100 time series maintained: + +```c# + _customMetricConfiguration = new MetricConfiguration(seriesCountLimit: 100, valuesPerDimensionLimit: 40, new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false)); +``` diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/distributed-tracing.md b/accelerators/aks-sb-azmonitor-microservices/docs/distributed-tracing.md new file mode 100644 index 0000000..89a6ac3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/distributed-tracing.md @@ -0,0 +1,42 @@ +# Distributed Tracing + +Distributed tracing depends on careful stitching together of auto and manually instrumented spans from both OpenTelemetry and Application Insights based tooling destined for export to Azure. + +## Azure Monitor and OpenTelemetry Data Models + +Azure Monitor splits the concept of a generic [OpenTelemetry span](https://opentelemetry.io/docs/concepts/signals/traces/#spans-in-opentelemetry) into a number of specific telemetry items like Requests and Dependencies. Rather than refer to these items as "spans", the term "operation" is heavily used in documentation and tooling. A trace is a distributed logical operation comprised of smaller sub-operations - the Requests, Dependencies, PageViews, etc. In Application Insights, all operations in a distributed trace will share the same `operation_Id` value, while ordering within the trace is defined by `operation_ParentId` values. An operation's `operation_ParentId` will point to the `Id` of another operation in the trace. + +OpenTelemetry-based tooling like the OpenTelemetry exporters for Java and the Application Insights SDK for Python (which relies on OpenCensus) use OpenTelemetry span terminology in exposed methods and classes. Spans in these tools encompass all telemetry types and generally expose a [SpanKind](https://opentelemetry.io/docs/concepts/signals/traces/#span-kind) property that dictates the type of item that surfaces in Application Insights. `SpanKind.SERVER` and `SpanKind.CLIENT` spans created in [`invalid-cargo-manager` instrumentation methods](../src/invalid-cargo-manager/src/service/message_receiver.py), for instance, result in export of Request and Dependency items in Application Insights. The `SpanId`, parent `SpanId`, and `TraceId` values in these OpenTelemetry-based libraries surface in Application Insights as `Id`, `operation_ParentId`, and `operation_Id`, respectively. + +## Instrumenting the Distributed Trace + +### Concepts + +The instrumentation process requires generation of operations (spans) with proper attachment of the `operation_Id` and `operation_ParentId` values to ensure they are connected to one another in the same trace, in the correct order. + +Each SDK/exporter exposes different methods that allow for creation of operations. The Application Insights SDK for Node [tracks specific operations](https://learn.microsoft.com/en-us/azure/azure-monitor/app/nodejs#telemetryclient-api) using methods like `trackDependency()` and `trackRequest()` on its `TelemetryClient` class. The .NET SDK uses `Activity` classes and [`StartOperation()` calls](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-end-to-end-tracing?tabs=net-standard-sdk-2#trace-message-processing) exposed by its own `TelemetryClient` class to do the same. The OpenCensus based Python OpenTelemetry exporter, on the other hand, enables [creation of spans](https://learn.microsoft.com/en-us/azure/azure-monitor/app/opentelemetry-enable?tabs=python#instrument-with-opentelemetry) via a Tracer. No spans are manually instrumented in either of the Java-based APIs, but the libraries do [expose the functionality](https://learn.microsoft.com/en-us/azure/azure-monitor/app/opentelemetry-enable?tabs=java#add-custom-spans) to generate them, if necessary. + +In order for one service's operations to be properly tied to an operation from an upstream service, a trace context must be passed between them. OpenTelemetry based tooling uses the widely recognized [W3C Trace Context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format) as a means to pass the required values and Application Insights is transitioning to use the same. W3C Trace Context defines a `traceparent` string that contains the Id values necessary to set a telemetry item's `operation_Id` and `operation_ParentId`. It uses the following syntax: + +`---` + +The `` value is uniquely generated by the first service in the distributed trace and becomes the `operation_Id` in Application Insights. The `` value refers to the `Id` of the most recent operation in the trace and becomes the `operation_ParentId` property for the next operation. When an upstream service makes a request or sends a message to a downstream service, it attaches the `traceparent` string in the manner dictated by the [communication protocol](https://www.w3.org/TR/trace-context-protocols-registry/#registry). Services that communicate via HTTP, like the inter-service communication between the `cargo-processing-api` and `operations-api` pass the string in the request headers, while services that communicate via message brokers, like all other inter-service communications in the application, pass the value in the message's application properties. + +### Implementation + +A distributed trace begins when a POST request is made to the `cargo-processing-api` service. The initial request is automatically instrumented and generates the `operation_Id` that will be attached to all subsequent telemetry items. The service makes a PUT request to the `operations-api` and automatically attaches the `traceparent` value in the headers, passing in the `operation_Id` and the `Id` of the last instrumented item. The last instrumented item in this case is the Dependency generated by the `cargo-processing-api` which refers to the PUT request. The `operations-api` similarly auto-instruments its own subsequent span data that is tied into the trace. It breaks open the `traceparent` string and uses the values to set trace context for the spans it will instrument. The initial span auto-instrumented by the `operations-api` when the PUT request is made surfaces as a Request, while other spans that refer to Cosmos DB interactions become Dependencies in Application Insights. + +When the `cargo-processing-api` receives a response back from the `operations-api`, it sends a message to the `ingest-cargo` Service Bus queue. The `traceparent` string is automatically passed by the service in the message's application properties and is received by the `cargo-processing-validator`. The `` value passed in the `traceparent` that becomes the `operation_ParentId` now refers to the message send Dependency item generated by the `cargo-processing-api`. The first operation produced by the `cargo-processing-validator` must be parented to this value. The service pulls the necessary `operation_Id` and `operation_ParentId` from the `traceparent` and uses the values in [pre-processor functionality](../src/cargo-processing-validator/src/index.ts) to attach the proper `operation_ParentId` to telemetry items prior to export. After manually instrumenting a request and a number of dependencies related to Service Bus operations and custom business logic, the `cargo-processing-validator` service sends a message to the `validated-cargo` Service Bus Topic. The `traceparent` string is again passed in the message's application properties. While the Java API services automatically attach the `traceparent` string, the `cargo-processing-validator` attaches the value [manually](../src/cargo-processing-validator/src/services/ServiceBusWithTelemetry.ts) in a `Diagnostic-Id` property. + +The `valid-cargo-manager` and `invalid-cargo-manager` are both prepared to pull the `operation_Id` and `operation_ParentId` values from the `Diagnostic-Id`. The `valid-cargo-manager` uses the values to [manually instrument a request](../src/valid-cargo-manager/Services/SubscriptionReceiver.cs), then begins automatically instrumenting Cosmos DB and Service Bus operations. The `invalid-cargo-manager` does the same to manually instrument a request, but follows with a [series of manually instrumented dependencies](../src/invalid-cargo-manager/src/service/message_receiver.py) that refer to the same Cosmos DB and Service Bus operations. + +## Visualization and Analysis + +The generated distributed traces through the valid and invalid flows are easily viewable in the Application Insights [Transaction Diagnostics window](https://learn.microsoft.com/en-us/azure/azure-monitor/app/transaction-diagnostics#transaction-diagnostics-experience): + +![Distributed Trace - Valid Flow](../assets/full-trace-valid.png) +![Distributed Trace - Invalid Flow](../assets/full-trace-invalid.png) + +Transaction Diagnostics displays a distributed trace's individual components with their timing and success properties. It is a visual representation of a KQL query that pulls all operation data associated with a specific `operation_Id`. The interface quickly reveals where issues arose within a specific trace. Inspecting individual traces is a helpful debugging tool, especially combined with correlated logs that provide some additional level of detail about why an operation may have failed. + +Aggregated trace data allows for construction of an application topology, visible within the [Application Map](https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-map?tabs=net), and supports a number of monitoring functionalities that the application relies on. Using operation timing and failure properties, performance data can be quickly retrieved and filtered by service, helping to identify which components in the application may be experiencing failure or performance issues. Combined, they enable retrieval of end to end transaction duration. KQL queries that pull end to end and per-service failure and performance data are heavily used in Workbooks and automated Alert rules. diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/getting-started.md b/accelerators/aks-sb-azmonitor-microservices/docs/getting-started.md new file mode 100644 index 0000000..97c8cf7 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/getting-started.md @@ -0,0 +1,108 @@ +# Getting Started + +## Prerequisites + +Visual Studio Code and dev containers are used to automatically install the required packages necessary to deploy and run the application. To get started, you will need to have the following installed: + +- Docker ([link](https://docs.docker.com/get-docker/)) +- Visual Studio Code ([link](https://code.visualstudio.com/download)) + - Dev Containers extension ([link](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)) + +Alternatively, you can deploy and run the application from your local machine but will need to have the following additionally installed: + +- Azure CLI ([link](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)) +- Azure Kubelogin ([link](https://github.com/Azure/Kubelogin)) +- Kubectl ([link](https://kubernetes.io/docs/reference/kubectl/)) +- Helm ([link](https://helm.sh/)) +- Various command line tools ([figlet](http://www.figlet.org/), [jq](https://stedolan.github.io/jq/)) + +## Running the Application + +Open the repository in Visual Studio Code. If you have the DevContainer extension installed, you will be prompted to "Reopen in Container" to work using the DevContainer. + +Copy the `.env.sample` file to `.env` and fill in the required values. + +The sample uses either Bicep or Terraform to provision the required infrastructure. Run `./deploy-bicep.sh` to deploy the application to Azure using Bicep, or `./deploy-terraform.sh` to do so using Terraform. The scripts will create the required resources in Azure, build the docker images, push them to Azure Container Registry and deploy the containers to Azure Kubernetes Service (AKS). + +> **_NOTE:_** By default, the AKS cluster is deployed without AAD integration. To enable AAD integration, pass the `--aks-aad-auth` switch to the deployment script. This will configure authentication for the current `az` user. To configure for a service principal, set the `ARM_CLIENT_ID` value to the client ID for the service principal. + +## Sending Requests + +After deploying the application, you can use the [`cargo-processing-api.http`](../http/cargo-processing-api.http) file to send requests to it. + +The file contains a number of requests that can be sent to the cargo-processing-api service. It uses an `.env` file generated by the deployment script that contains the IP address of the AKS NGINX ingress controller. + +Use the "Send Request" options in the file to send `POST`/`PUT` requests to the cargo-processing-api and see the responses. + +> **_NOTE:_** By default, the `cargo-processing-api.http` file is configured to use services deployed to AKS. If you are running the services locally, uncomment the lines that set the service address to `localhost`. + +## Verifying Successful Deployment + +A cargo object sent to the `cargo-processing-api` service can take one of two paths depending on the validation result from the `cargo-processing-validator` service. The first path, when the cargo is valid, incorporates the `cargo-processing-api`, `operations-api`, `cargo-processing-validator` , and `valid-cargo-manager` services and results in a record being stored in the `valid-cargo` Cosmos DB container. An invalid piece of cargo reaches the `invalid-cargo-manager` rather than the `valid-cargo-manager` service and is stored in the `invalid-cargo` Cosmos DB container. End to end functionality can be verified by sending a request through both flows and ensuring that the cargo objects are stored in the proper Cosmos DB containers. + +The [`cargo-processing-api.http`](../http/cargo-processing-api.http) file contains `createRequest` and `createRequest_invalid` requests that are used to send a valid and invalid cargo object to the `cargo-processing-api` service, respectively. Use the "Send Request" option on `createRequest` to send a valid request and note the ID returned in the right-hand window (`080f393d-893c-3d80-a267-350c6abef090` in the below example). + +```json +HTTP/1.1 202 +Date: Tue, 25 Apr 2023 21:46:07 GMT +Content-Type: application/json +Transfer-Encoding: chunked +Connection: close +operation-id: 49d8f01c-a284-44b4-8c97-605d224016af + +{ + "id": "080f393d-893c-3d80-a267-350c6abef090", + "timestamp": "2023-04-25T21:46:06.310Z", + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2023-05-05T09:45:52.548Z", + "end": "2023-05-10T09:45:52.548Z" + } +} +``` + +The subsequent request in the `.http` file can be used to retrieve the status of that request. Next, use the "Send Request" option on `createRequest_invalid` to send a invalid request and note the ID returned in the right-hand window (`8438307f-8303-3d9c-b958-9caf08f610b4` in the below example). + +```json +HTTP/1.1 202 +Date: Tue, 25 Apr 2023 21:48:16 GMT +Content-Type: application/json +Transfer-Encoding: chunked +Connection: close +operation-id: 9d3bdc2f-a4aa-45e5-8965-d9e53716c1e7 + +{ + "id": "8438307f-8303-3d9c-b958-9caf08f610b4", + "timestamp": "2023-04-25T21:48:16.438Z", + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2023-07-04T09:48:20.816Z", + "end": "2023-07-09T09:48:20.816Z" + } +} +``` + +Finally, navigate to the Cosmos DB instance's Data Explorer window and verify that a new record has been added to both the `valid-cargo` and `invalid-cargo` containers with IDs and other properties that match the ones copied earlier. + +![Valid cargo verification](../assets/verify-valid-cargo.png) +![Invalid cargo verification](../assets/verify-invalid-cargo.png) + +## Local Development + +To run the services locally, you still need to deploy the supporting infrastructure in Azure. You can run the deployment scripts described in the [Running the Application](#running-the-application) section, but pass the `--skip-helm-deploy` switch to skip the Helm deployment of services to AKS. This will ensure that the services you run locally will be the only services retrieving messages from the Service Bus queues etc. + +After the infrastructure deployment completes, run `run-local.sh` to start all of the services locally via `docker compose`. To run a service individually, open it in its dev container and follow the instructions provided in the service's README. diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/health-checks.md b/accelerators/aks-sb-azmonitor-microservices/docs/health-checks.md new file mode 100644 index 0000000..6db9391 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/health-checks.md @@ -0,0 +1,66 @@ +# Health Checks + +Monitoring and quickly responding to changes in service health is crucial for distributed applications deployed to an AKS environment. Health checks report the internal status of a microservice at regular intervals and are used by orchestrators, like Kubernetes, to determine if each service is functioning properly. Health checks should examine connections to databases and other dependencies and can report health based on memory usage, CPU utilization, network connectivity, or any other key performance indicators that are critical to the functioning of the microservice. Essentially, a health check should verify that the microservice is able to perform its intended function and that it is not experiencing any critical errors or failures. AKS automatically triggers these health checks and acts upon pods that report back unhealthy. + +Health check functionality is often exposed via HTTP endpoints, but Kubernetes supports consumption of TCP and gRPC endpoints as well and is also capable of running `exec` commands exposed by pods. Kubernetes consumes the endpoints or commands via [3 types of probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) - startup, readiness, and liveness probes. Startup probes run after deployment and make the kubelet agent aware that the containers in the pod have started. Kubernetes will not start readiness and liveness probes until the startup probe reports success. Readiness probes alert Kubernetes that the pod is ready to accept traffic and liveness probes are subsequently used to regularly check that the pod is healthy. Pods that fail liveness probes are automatically restarted by AKS to fix ephemeral issues. While different endpoints or commands can be used for each probe type, we elected to reuse the same health check endpoints in our services, declared via the helm charts that deploy the services to AKS. + +Services like the `cargo-processing-api` and `operations-api`, which are Spring Boot apps that already expose HTTP endpoints, are easy candidates to expose health checks via HTTP endpoint. `spring-boot-starter-actuator` used in these projects is capable of [exposing a `/health` endpoint](https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints) that reports internal application health using indicators like [dependency connections and disk space](https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.health.auto-configured-health-indicators). The endpoint is configured via the [application.properties](../src/cargo-processing-api/src/main/resources/application.properties) file: + +```java +management.endpoints.web.exposure.include=health,info +endpoints.health.sensitive=false +management.endpoint.health.show-details=always +``` + +The `/actuator/health` endpoint that Spring Boot spins up is declared within the helm charts for those services: + +```yaml +livenessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 20 + failureThreshold: 3 + timeoutSeconds: 10 +``` + +The `cargo-processing-validator`, `valid-cargo-manager`, and `invalid-cargo-manager` are background worker services that do not already expose HTTP endpoints. The `cargo-processing-validator` and `invalid-cargo-manager` do not include explicit health checks. Instead, they are designed to [self-destruct](../src/cargo-processing-validator/src/index.ts) when errors occur. These services restart via error when failed dependency connections arise, rather than failed liveness probes that would result from those same connections. In contrast, we elected to demonstrate TCP health check functionality on the `valid-cargo-manager`. A [HealthCheckController](../src/valid-cargo-manager/Controllers/HealthCheckController.cs) that starts a TCP server is added to the list of [services configured during startup](../src/valid-cargo-manager/Program.cs). The controller uses [CosmosDBHealthChecker](../src/valid-cargo-manager/HealthCheck/CosmosDbHealthChecker.cs) and [ServiceBusHealthChecker](../src/valid-cargo-manager/HealthCheck/ServiceBusHealthChecker.cs) classes to report status of connection to those dependent services. The exposed TCP port and other configuration details are set via the [appsettings.json file](../src/valid-cargo-manager/appsettings.sample.json): + +```json +"HealthCheck": { + "TcpServer": { + "Port": 3030 + }, + "CosmosDB": { + "MaxDurationMs": 200 + }, + "ServiceBus": { + "MaxDurationMs": 200 + } +} +``` + +The TCP socket that the service exposes is then declared within its helm chart: + +```yaml +livenessProbe: + tcpSocket: + port: 3030 + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 10 +``` + +Kubernetes automatically consumes these endpoints and will take action on a pod if a probe fails, like a pod restart if a liveness probe fails. The calls to these endpoints can be viewed in the Logs window, via the `requests` table: + +```sql +requests +| where cloud_RoleName == "cargo-processing-api" and url contains "/health" +``` + +![Health check logs](../assets/health-check-logs.png) + +While Kubernetes will automatically respond to these events, the application additionally includes alerts that proactively notifies admins about issues related to health checks so they can take additional action to debug, if necessary. Each microservice has a health check failure and health check not reporting alert that consumes the same logs used above, as well as a pod restart alert triggered when a service pod restarts more than once within 5 minutes. +Health checks often fail due to ephemeral issues that can be resolved by automatic Kubernetes actions, like a pod restart, but other underlying issues may require human intervention. Alerts offer an additional monitoring layer that serves to reduce the downtime to fix those more major issues surfaced by health check issues. diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/introducing-chaos.md b/accelerators/aks-sb-azmonitor-microservices/docs/introducing-chaos.md new file mode 100644 index 0000000..5c5333b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/introducing-chaos.md @@ -0,0 +1,25 @@ +# Introducing Chaos + +Chaos engineering involves intentionally introducing failures to assess resilience and identify potential weaknesses in an application. Controlled experiments are conducted to understand how the application behaves in unexpected situations. Development teams can identify proper mitigation techniques for real-world scenarios _before_ they occur in production. Chaos engineering is closely tied with the concepts of observability and monitoring - system behavior must be accurately measured over time to understand how it responds to various failure scenarios. Introduction of chaos into the cargo processing application allows us to test the alerting and visualization functionality included in the project, as well as use those same tools to determine best case mitigation techniques for a set of fault scenarios that the team expects the application to handle gracefully. + +Azure offers [Azure Chaos Studio](https://learn.microsoft.com/en-us/azure/chaos-studio/chaos-studio-overview) as a tool to inject common fault scenarios into the application, like CPU/memory pressure or downed nodes in a cluster. Rather than use Chaos Studio, we elected add chaos into the application code directly, in both the `cargo-processing-api` and `cargo-processing-validator` services, with built in integration with our existing load test scripts. + +The [cargo-test-scripts](../src/cargo-test-scripts/) folder includes a JavaScript based application used to send requests to the `cargo-processing-api` ingress endpoint or to downstream services directly. Tests are supplied via [json based test run configurations](../src/cargo-test-scripts/testConfigurations/valid_tests.json) that send a configurable number of requests to specific target services. Importantly, `properties.chaosSettings` is available on tests that target the `cargo-processing-api` and `cargo-processing-validator` services, with a set of available `type` options that cause specific fault scenarios in those services: + +| Target | Type | Description | +| -------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cargo-processing-api | operations-api-failure | Will cause a chaos exception to occur when the cargo-processing-api attempts to call the operations-api. | +| cargo-processing-api | process-ending | Will cause the cargo-processing-api to shut down. | +| cargo-processing-api | service-bus-failure | Will cause the service to close the service-bus connection right before it attempts to use it. | +| cargo-processing-api | invalid-schema | Will cause the test script to modify the cargo object being sent in a way that causes the cargo-processing-api to throw an invalid json schema exception. | +| cargo-processing-validator | service-bus-failure | Will cause the service to close the service-bus connection right before it attempts to use it. | +| cargo-processing-validator | process-killing | Will cause the cargo-processing-validator to shut down. | +| cargo-processing-validator | invalid-schema | Sends a message that is missing its demandDates directly to the ingest-cargo queue. | + +The test scripts use a [raiseChaos utility function](../src/cargo-test-scripts/dataBuilderUtils.js) that sets a cargo object's `source` port to the `target` and `destination` port to the `type` specified above in a chaos test. The services themselves are configured to execute fault scenarios when the source and destination ports match these known strings. The `cargo-processing-validator` service contains a [ChaosMonkey](../src/cargo-processing-validator/src/chaos/ChaosMonkey.ts) class that determines whether to cause chaos based on the source and destination ports. It includes [ProcessEnding](../src/cargo-processing-validator/src/chaos/ProcessEndingMonkey.ts) and [ServiceBusKilling](../src/cargo-processing-validator/src/chaos/ServiceBusKillingMonkey.ts) classes that exit the running process or close the existing service bus connection, respectively. If the `source` port for a cargo object is set to `cargo-processing-validator` and `destination` port is set to `process-killing`, the `ProcessEndingMonkey` will initialize and exit the current process, for example. The `cargo-processing-api` service has similar ChaosMonkey implementations. + +The chaos tests should cause internal exceptions, restarts, and health check issues that should immediately surface in alerts (detailed below). Workbook tiles (detailed below) should illuminate how the application performed over the test run, displaying increases in request duration, dead-lettered messages, and other indicators of application health. To run a chaos test, open the [cargo-test-scripts](../src/cargo-test-scripts/) folder in its dedicated dev container. The folder contains a number of [pre-defined test configurations](../src/cargo-test-scripts/testConfigurations/) that includes a [`cargo_processing_api_chaos_tests.json`](../src/cargo-test-scripts/testConfigurations/cargo_processing_api_chaos_tests.json) configuration. From the terminal in the dev container, run the following command to trigger each of the types of fault scenarios listed above: + +```bash +node ./index.js -c ./testConfigurations/cargo_processing_api_chaos_tests.json +``` diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/reducing-telemetry-volume.md b/accelerators/aks-sb-azmonitor-microservices/docs/reducing-telemetry-volume.md new file mode 100644 index 0000000..69576e2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/reducing-telemetry-volume.md @@ -0,0 +1,11 @@ +# Reducing Telemetry Volume + +The application does not have high scale requirements, though there are a variety of techniques that were used, or could be used, to mitigate storage and cost concerns. + +The `valid-cargo-manager` and both Java APIs [implement adaptive sampling by default](https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling?tabs=net-core-new#configuring-adaptive-sampling-for-aspnet-applications), limiting the number of requests sent to Application Insights. Both services target a specific number of items to export per minute - the actual sampling rate can vary depending on the number of requests the services handle. Given the low scale requirements for the application, sampling does not actually kick in for either of these services with the current test scripts provided. Implementing coordinated fixed-rate sampling across the service architecture would result in reduced storage costs and alleviate retention and rotation concerns. The Java services can implement explicit [fixed rate sampling and sampling overrides](https://learn.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-sampling-overrides#getting-started) via the [`applicationinsights.json`](../src/cargo-processing-api/applicationinsights.json) file, or by supplying specific environment variables that overwrite those properties. The `cargo-processing-validator` can do the same by [providing a percentage](https://github.com/microsoft/ApplicationInsights-node.js/blob/dd7c195f481acdaf39c4abc271424fb750aac81f/README.md#sampling) to the `applicationInsights.defaultClient` in the [`index.ts`](../src/cargo-processing-validator/src/index.ts) file. The `valid-cargo-manager` can [add a sampling rate](https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling?tabs=net-core-new#configuring-fixed-rate-sampling-for-aspnet-applications) to the [`CreateHostBuilder`](../src/valid-cargo-manager/Program.cs), while the `invalid-cargo-manager` could do so via a `ProbabilitySampler` that can be [passed to tracer classes](https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling?tabs=net-core-new#configuring-fixed-rate-sampling-for-opencensus-python-applications), rather than the `AlwaysOnSampler` that is [currently used](../src/invalid-cargo-manager/src/service/telemetry_publisher.py). + +Especially noisy libraries or specific telemetry items can be targeted with pre-processing functionality that serves to suppress or transform those items. The `valid-cargo-manager` suppresses items from the `Microsoft` namespace that do not meet or exceed the `Warning` severity level, for instance, via the [appsettings.json file](../src/valid-cargo-manager/appsettings.sample.json). The `cargo-processing-validator` includes a [code based pre-processor](../src/cargo-processing-validator/src/index.ts) used to transform outgoing telemetry items before export, as does the [`invalid-cargo-manager`](../src/invalid-cargo-manager/src/service/telemetry_publisher.py). The existing functionalities could be extended to suppress or remove unnecessary properties from additional items, and similar pre-processing functionality could be added to the [Java](https://learn.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-telemetry-processors#getting-started) services via configuration file. + +[Log levels](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel?view=dotnet-plat-ext-7.0) are used to accommodate the fact that certain services automatically instrument telemetry data that is not necessary to capture by default. The `cargo-processing-validator` and `invalid-cargo-manager` services do not emit nearly as much data as the other three services and are [configured to capture all logs](../src/invalid-cargo-manager/src/service/logging_config.py) using DEBUG. The Java based APIs, on the other hand, are configured to [capture all logs of level INFO and above](../src/cargo-processing-api/applicationinsights.json), automatically suppressing debug statements, by default. As mentioned, the `valid-cargo-manager` uses the appsettings.json file to [capture WARNING and above](../src/valid-cargo-manager/appsettings.sample.json) for logs from the Microsoft namespace and INFO for others. These configuration based log levels can be easily reduced to DEBUG to capture additional logs in a debugging scenario. The application uses the default retention policy for all Azure Monitor tables - generally 90 days but certain tables have a 30 day default retention policy, though these could be [set on the Log Analytics resource](https://learn.microsoft.com/en-us/azure/templates/microsoft.operationalinsights/workspaces?pivots=deployment-language-bicep#workspaceproperties) in Bicep or Terraform. + +Visit Azure documentation for additional information on [sampling](https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling?tabs=net-core-new), [pre-processing](https://learn.microsoft.com/en-us/azure/azure-monitor/app/api-filtering-sampling), log levels and [retention](https://learn.microsoft.com/en-us/azure/azure-monitor/app/data-retention-privacy), and more. diff --git a/accelerators/aks-sb-azmonitor-microservices/docs/workbooks.md b/accelerators/aks-sb-azmonitor-microservices/docs/workbooks.md new file mode 100644 index 0000000..0b8772a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/docs/workbooks.md @@ -0,0 +1,74 @@ +# Workbooks + +The application utilizes Azure Workbooks to visualize/analyze the extensive telemetry data that has been captured by the centralized Azure Monitor backend. Workbooks allow you to seamlessly display and track all relevant configured data within the Azure Portal, without the need to navigate away. + +Workbooks can be deployed using infrastructure as code tools, similar to other Azure services. In this scenario, the deployment creates three distinct workbooks, each focusing on specific categories that feature the following charts: + +| Workbook | Chart | Type | Description | +| ----------------- | -------------------------------- | --------- | ------------------------------------------------------------------------------------------------- | +| Index | servicesExceptionsQuery | KQL Query | Displays exceptions that ocurred while working with the system. | +| Index | servicesMonitoringQuery | KQL Query | Displays the big picture of resources per service. | +| Index | workbooksLinksText | Text | Includes the links to access to remaining workbooks. | +| Infrastructure | serviceBusCompletedTimesQuery | KQL Query | Displays statistics of service bus completed operations. | +| Infrastructure | serviceBusMessagingMetric | Metric | Displays the count of active, delivered and dead-lettered messages in a Queue or Topic. | +| Infrastructure | serviceBusThrottledMetric | Metric | Displays the number of throttled requests in Service Bus. | +| Infrastructure | cosmosDbLatencyOfReadsQuery | KQL Query | Displays the average time per read requests from Cosmos DB. | +| Infrastructure | cosmosDbOperationsQuery | KQL Query | Displays the number of valid, invalid, and operations writes into CosmosDB. | +| Infrastructure | keyVaultSaturationMetric | Metric | Displays the KeyVault saturation percentage. | +| Infrastructure | keyVaultLatencyMetric | Metric | Displays the latency when executing an operation to KeyVault. | +| Infrastructure | keyVaultResultsMetric | Metric | Displays the count of Key Vault API Results. | +| Infrastructure | aksCpuMetric | Metric | Displays the max count of CPU percentage of the cluster. | +| Infrastructure | aksRequestsMetric | Metric | Displays the average inflight requests to the cluster. | +| System processing | endpointsRequestsStatisticsQuery | KQL Query | Displays different measures for time per requests. | +| System processing | endpointsRequestsQuery | KQL Query | Extracts the last column from previous chart in order to gain more focus. | +| System processing | lastOperationsQuery | KQL Query | Shows the last 100 operations executed and their associated operation ID. | +| System processing | transactionSearchBladeText | Text | Link to a transaction search blade. | +| System processing | additionalTelemetryText | Text | Link to get more telemetry in sections like Application Map, Availability, Failures, Performance. | +| System processing | operationsParameters | KQL Query | Parameters designed to get more details in the following charts. | +| System processing | endToEndProcessingQuery | KQL Query | Displays the end to end processing time. | +| System processing | requestsCountQuery | KQL Query | Displays the request count. | +| System processing | servicesProcessingTimeQuery | KQL Query | Displays the processing time in the services. | +| System processing | serviceDependencyQuery | KQL Query | Displays the service dependency duration. | +| System processing | destinationPortBreakdownQuery | KQL Query | Displays the end to end processing time by destination port. | +| System processing | podRestartQuery | KQL Query | Displays the number of times each service pod has restarted. | + +No matter what infrastructure deployment tool is used, workbooks content is supplied via the same set of **json** templates, found in the [workbooks](../infrastructure/workbooks/) folder. The templates demonstrate proper workbook structure/syntax and include a variety of types of visualization items [available for use in workbooks](https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/workbooks-visualizations), like text and charts. The templates also illustrate how to pass required parameters from Bicep and Terraform to the workbooks json content, like the IDs of the source resources for log query and metric visualizations. In the following snippet, a metric chart receives the ID of the AKS cluster and uses it in the **resourcesIds** field. + +```json +{ + "type": 10, + "content": { + "chartId": "workbook171b383f-5043-41dd-9154-a1fa92367891", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "pink", + "resourceType": "microsoft.containerservice/managedclusters", + "metricScope": 0, + "resourceIds": ["${aks_id}"], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.containerservice/managedclusters", + "metric": "microsoft.containerservice/managedclusters-Nodes (PREVIEW)-node_cpu_usage_percentage", + "aggregation": 3, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "aksCpuMetric" +} +``` + +Development teams can adapt the workbook presentation according to how they want to visualize data. Chart colors, for instance, can be used to visually separate the tools they are monitoring, allowing for easy identification what resource and signal is being observed: + +![Workbooks Key Vault metric](../assets/workbook-key-vault-metric.png) +![Workbooks AKS metric](../assets/workbook-aks-metric.png) + +Azure Workbooks can provide a dynamic presentation that captures all relevant data in one single visualization tool, enabling creation of a single pane of glass for application administrators. Not all projects will look for the same telemetry, as each solution will focus on different metrics according to their specific needs. diff --git a/accelerators/aks-sb-azmonitor-microservices/http/.env.sample b/accelerators/aks-sb-azmonitor-microservices/http/.env.sample new file mode 100644 index 0000000..28a43c7 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/http/.env.sample @@ -0,0 +1,6 @@ +# Copy this file to .env and fill in the values. + + +# Run the following command to get the SERVICE_IP value: +# kubectl get svc --namespace default cargo-processing-api --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}" +SERVICE_IP= \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/http/cargo-processing-api.http b/accelerators/aks-sb-azmonitor-microservices/http/cargo-processing-api.http new file mode 100644 index 0000000..2b88fe4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/http/cargo-processing-api.http @@ -0,0 +1,122 @@ +# This file shows how to make requests against the deployed API +# The following lines load the IP address for the deployed services from a .env file +# This file is created for you when you deploy the services +@cargo_service=http://{{$dotenv SERVICE_IP}} +@operations_service=http://{{$dotenv SERVICE_IP}} + +# Uncomment the following lines to use locally running services +# @cargo_service=http://localhost:8080 +# @operations_service=http://localhost:8081 + + +# +# issue a POST request to create a valid cargo request +# +# @name createRequest +POST {{cargo_service}}/cargo/ +Content-Type: application/json +operation-id: {{$guid}} + +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 10 d}}Z", + "end": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 15 d}}Z" + } +} + +### +# issue a PUT request to update the previous cargo request +# + +PUT {{cargo_service}}/cargo/{{createRequest.response.body.id}} +Content-Type: application/json + +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Seattle" + }, + "demandDates": { + "start": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 10 d}}Z", + "end": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 15 d}}Z" + } +} + + +### +# issue a GET request to retrieve the status of the previous cargo request +# +GET {{operations_service}}/operations/{{createRequest.response.headers.operation-id}} + +############################################################### + +# +# issue a POST request to create a valid cargo request (start date cannot be more than 60 days in the future) +# + +# @name createRequest_invalid +POST {{cargo_service}}/cargo/ +Content-Type: application/json +operation-id: {{$guid}} + +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 70 d}}Z", + "end": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 75 d}}Z" + } +} + + + +### +# issue a GET request to retrieve the status of the previous cargo request +# + +GET {{operations_service}}/operations/{{createRequest_invalid.response.headers.operation-id}} + + +############################################################### +# Test degraded behaviour: + +### +# issue a POST request to create a cargo request with processing delays +# (destination port slow-port) +# +POST {{cargo_service}}/cargo/ +Content-Type: application/json +operation-id: {{$guid}} + +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "slow-port" + }, + "demandDates": { + "start": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 10 d}}Z", + "end": "{{$localDatetime "YYYY-MM-DDThh:mm:ss.ms" 15 d}}Z" + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/abbreviations.json b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/abbreviations.json new file mode 100644 index 0000000..a4fc9df --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/abbreviations.json @@ -0,0 +1,135 @@ +{ + "analysisServicesServers": "as", + "apiManagementService": "apim-", + "appConfigurationConfigurationStores": "appcs-", + "appManagedEnvironments": "cae-", + "appContainerApps": "ca-", + "authorizationPolicyDefinitions": "policy-", + "automationAutomationAccounts": "aa-", + "blueprintBlueprints": "bp-", + "blueprintBlueprintsArtifacts": "bpa-", + "cacheRedis": "redis-", + "cdnProfiles": "cdnp-", + "cdnProfilesEndpoints": "cdne-", + "cognitiveServicesAccounts": "cog-", + "cognitiveServicesFormRecognizer": "cog-fr-", + "cognitiveServicesTextAnalytics": "cog-ta-", + "computeAvailabilitySets": "avail-", + "computeCloudServices": "cld-", + "computeDiskEncryptionSets": "des", + "computeDisks": "disk", + "computeDisksOs": "osdisk", + "computeGalleries": "gal", + "computeSnapshots": "snap-", + "computeVirtualMachines": "vm", + "computeVirtualMachineScaleSets": "vmss-", + "containerInstanceContainerGroups": "ci", + "containerRegistryRegistries": "cr", + "containerServiceManagedClusters": "aks-", + "databricksWorkspaces": "dbw-", + "dataFactoryFactories": "adf-", + "dataLakeAnalyticsAccounts": "dla", + "dataLakeStoreAccounts": "dls", + "dataMigrationServices": "dms-", + "dBforMySQLServers": "mysql-", + "dBforPostgreSQLServers": "psql-", + "devicesIotHubs": "iot-", + "devicesProvisioningServices": "provs-", + "devicesProvisioningServicesCertificates": "pcert-", + "documentDBDatabaseAccounts": "cosmos-", + "eventGridDomains": "evgd-", + "eventGridDomainsTopics": "evgt-", + "eventGridEventSubscriptions": "evgs-", + "eventHubNamespaces": "evhns-", + "eventHubNamespacesEventHubs": "evh-", + "hdInsightClustersHadoop": "hadoop-", + "hdInsightClustersHbase": "hbase-", + "hdInsightClustersKafka": "kafka-", + "hdInsightClustersMl": "mls-", + "hdInsightClustersSpark": "spark-", + "hdInsightClustersStorm": "storm-", + "hybridComputeMachines": "arcs-", + "insightsActionGroups": "ag-", + "insightsComponents": "appi-", + "keyVaultVaults": "kv-", + "kubernetesConnectedClusters": "arck", + "kustoClusters": "dec", + "kustoClustersDatabases": "dedb", + "logicIntegrationAccounts": "ia-", + "logicWorkflows": "logic-", + "machineLearningServicesWorkspaces": "mlw-", + "managedIdentityUserAssignedIdentities": "id-", + "managementManagementGroups": "mg-", + "migrateAssessmentProjects": "migr-", + "networkApplicationGateways": "agw-", + "networkApplicationSecurityGroups": "asg-", + "networkAzureFirewalls": "afw-", + "networkBastionHosts": "bas-", + "networkConnections": "con-", + "networkDnsZones": "dnsz-", + "networkExpressRouteCircuits": "erc-", + "networkFirewallPolicies": "afwp-", + "networkFirewallPoliciesWebApplication": "waf", + "networkFirewallPoliciesRuleGroups": "wafrg", + "networkFrontDoors": "fd-", + "networkFrontdoorWebApplicationFirewallPolicies": "fdfp-", + "networkLoadBalancersExternal": "lbe-", + "networkLoadBalancersInternal": "lbi-", + "networkLoadBalancersInboundNatRules": "rule-", + "networkLocalNetworkGateways": "lgw-", + "networkNatGateways": "ng-", + "networkNetworkInterfaces": "nic-", + "networkNetworkSecurityGroups": "nsg-", + "networkNetworkSecurityGroupsSecurityRules": "nsgsr-", + "networkNetworkWatchers": "nw-", + "networkPrivateDnsZones": "pdnsz-", + "networkPrivateLinkServices": "pl-", + "networkPublicIPAddresses": "pip-", + "networkPublicIPPrefixes": "ippre-", + "networkRouteFilters": "rf-", + "networkRouteTables": "rt-", + "networkRouteTablesRoutes": "udr-", + "networkTrafficManagerProfiles": "traf-", + "networkVirtualNetworkGateways": "vgw-", + "networkVirtualNetworks": "vnet-", + "networkVirtualNetworksSubnets": "snet-", + "networkVirtualNetworksVirtualNetworkPeerings": "peer-", + "networkVirtualWans": "vwan-", + "networkVpnGateways": "vpng-", + "networkVpnGatewaysVpnConnections": "vcn-", + "networkVpnGatewaysVpnSites": "vst-", + "notificationHubsNamespaces": "ntfns-", + "notificationHubsNamespacesNotificationHubs": "ntf-", + "operationalInsightsWorkspaces": "log-", + "portalDashboards": "dash-", + "powerBIDedicatedCapacities": "pbi-", + "purviewAccounts": "pview-", + "recoveryServicesVaults": "rsv-", + "resourcesResourceGroups": "rg-", + "searchSearchServices": "srch-", + "serviceBusNamespaces": "sb-", + "serviceBusNamespacesQueues": "sbq-", + "serviceBusNamespacesTopics": "sbt-", + "serviceEndPointPolicies": "se-", + "serviceFabricClusters": "sf-", + "signalRServiceSignalR": "sigr", + "sqlManagedInstances": "sqlmi-", + "sqlServers": "sql-", + "sqlServersDataWarehouse": "sqldw-", + "sqlServersDatabases": "sqldb-", + "sqlServersDatabasesStretch": "sqlstrdb-", + "storageStorageAccounts": "st", + "storageStorageAccountsVm": "stvm", + "storSimpleManagers": "ssimp", + "streamAnalyticsCluster": "asa-", + "synapseWorkspaces": "syn", + "synapseWorkspacesAnalyticsWorkspaces": "synw", + "synapseWorkspacesSqlPoolsDedicated": "syndp", + "synapseWorkspacesSqlPoolsSpark": "synsp", + "timeSeriesInsightsEnvironments": "tsi-", + "webServerFarms": "plan-", + "webSitesAppService": "app-", + "webSitesAppServiceEnvironment": "ase-", + "webSitesFunctions": "func-", + "webStaticSites": "stapp-" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/azuredeploy.parameters.sample.json b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/azuredeploy.parameters.sample.json new file mode 100644 index 0000000..269e46c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/azuredeploy.parameters.sample.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "value": "eastus" + }, + "uniqueUserName": { + "value": "myusername" + }, + "cosmosDatabaseName": { + "value": "cargo" + }, + "cosmosContainer1Name": { + "value": "valid-cargo" + }, + "cosmosContainer2Name": { + "value": "invalid-cargo" + }, + "cosmosContainer3Name": { + "value": "operations" + }, + "serviceBusQueue1Name": { + "value": "ingest-cargo" + }, + "serviceBusQueue2Name": { + "value": "operation-state" + }, + "serviceBusTopicName": { + "value": "validated-cargo" + }, + "serviceBusSubscription1Name": { + "value": "valid-cargo" + }, + "serviceBusSubscription2Name": { + "value": "invalid-cargo" + }, + "serviceBusTopicRule1Name": { + "value": "valid" + }, + "serviceBusTopicRule2Name": { + "value": "invalid" + }, + "notificationEmailAddress": { + "value": "alias@microsoft.com" + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/main.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/main.bicep new file mode 100644 index 0000000..3b2cb59 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/main.bicep @@ -0,0 +1,219 @@ +targetScope = 'subscription' + +//parameters section +@description('Specifies the supported Azure location (region) where the resources will be deployed') +@minLength(1) +param location string + +@description('This value will explain who is the author of specific resources and will be reflected in every deployed tool') +@minLength(1) +param uniqueUserName string + +@description('Name for the Cosmos DB SQL database') +@minLength(1) +param cosmosDatabaseName string + +@description('Name for the first Cosmos DB SQL container') +@minLength(1) +param cosmosContainer1Name string + +@description('Name for the second Cosmos DB SQL container') +@minLength(1) +param cosmosContainer2Name string + +@description('Name for the third Cosmos DB SQL container') +@minLength(1) +param cosmosContainer3Name string + +@description('Name for the first Service Bus Queue') +@minLength(1) +param serviceBusQueue1Name string + +@description('Name for the second Service Bus Queue') +@minLength(1) +param serviceBusQueue2Name string + +@description('Name for the Service Bus Topic') +@minLength(1) +param serviceBusTopicName string + +@description('Name for the first Service Bus Subscription') +@minLength(1) +param serviceBusSubscription1Name string + +@description('Name for the second Service Bus Subscription') +@minLength(1) +param serviceBusSubscription2Name string + +@description('Name for the first Service Bus Subscriptions filter rule') +@minLength(1) +param serviceBusTopicRule1Name string + +@description('Name for the second Service Bus Subscriptions filter rule') +@minLength(1) +param serviceBusTopicRule2Name string + +@description('Tenant Id for the service principal that will be in charge of KeyVault access') +@minLength(1) +param kvTenantId string = tenant().tenantId + +@description('Definition Id for AcrPull role') +@minLength(1) +param roleAcrPull string = 'b24988ac-6180-42a0-ab88-20f7382dd24c' + +@description('Configure Azure Active Directory authentication for Kubernetes cluster') +param aksAadAuth bool = false + +@description('The object ID of the Azure Active Directory user to make cluster admin (only valid if aksAadAuth is true)') +param aksAadAdminUserObjectId string = '' + +@description('Email address for alert notifications') +@minLength(1) +param notificationEmailAddress string + +//load abbreviations for Azure features +var abbrs = loadJsonContent('abbreviations.json') + +//variables section +var toolName = 'bicep' +var resourceGroupName = '${abbrs.resourcesResourceGroups}${toolName}-${uniqueUserName}' +var acrName = '${abbrs.containerRegistryRegistries}${toolName}${uniqueUserName}' +var kvName = '${abbrs.keyVaultVaults}${toolName}-${uniqueUserName}' +var appInsightsName = '${abbrs.insightsComponents}${uniqueUserName}' +var logAnalyticsName = '${abbrs.operationalInsightsWorkspaces}${toolName}-${uniqueUserName}' +var aksName = '${abbrs.containerServiceManagedClusters}${toolName}-${uniqueUserName}' +var cosmosDBName = '${abbrs.documentDBDatabaseAccounts}${toolName}-${uniqueUserName}' +var serviceBusName = '${abbrs.serviceBusNamespaces}${toolName}-${uniqueUserName}' + +//resourceGroup section +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +resource contributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { + scope: subscription() + name: roleAcrPull +} + +//modules section +module acr 'modules/acr.bicep' = { + name: 'acrDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + acrName: acrName + aksPrincipalId: aks.outputs.clusterPrincipalID + roleDefinitionId: contributorRoleDefinition.id + } +} + +module kv 'modules/key-vault.bicep' = { + name: 'keyVaultDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + kvName: kvName + kvTenantId: kvTenantId + serviceBusNamespaceName: serviceBus.outputs.serviceBusNamespaceName + appInsightsConnectionString: appInsights.outputs.connectionString + logAnalyticsWorkspaceId: appInsights.outputs.workspaceId + clusterKeyVaultSecretProviderObjectId: aks.outputs.clusterKeyVaultSecretProviderObjectId + cosmosDBEndpoint: cosmos.outputs.cosmosDBEndpoint + cosmosDBAccountName: cosmos.outputs.cosmosDBAccountName + } +} + +module appInsights 'modules/app-insights.bicep' = { + name: 'appInsightsDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + appInsightsName: appInsightsName + logAnalyticsName: logAnalyticsName + } +} + +module workbook 'modules/workbooks.bicep' = { + name: 'workbookDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + workspaceId: appInsights.outputs.workspaceId + uniqueUserName: uniqueUserName + serviceBusNamespaceId: serviceBus.outputs.serviceBusNamespaceId + appInsightsId: appInsights.outputs.appInsightsId + keyVaultId: kv.outputs.kvId + aksId: aks.outputs.clusterId + } +} + +module aks 'modules/aks.bicep' = { + name: 'kubernetesDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + aksName: aksName + logAnalyticsWorkspaceId: appInsights.outputs.workspaceId + aksAadAuth: aksAadAuth + aksAadAdminUserObjectId: aksAadAdminUserObjectId + } +} + +module cosmos 'modules/cosmos.bicep' = { + name: 'cosmosDBDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + accountName: cosmosDBName + databaseName: cosmosDatabaseName + container1Name: cosmosContainer1Name + container2Name: cosmosContainer2Name + container3Name: cosmosContainer3Name + logAnalyticsWorkspaceId: appInsights.outputs.workspaceId + } +} + +module serviceBus 'modules/service-bus.bicep' = { + name: 'serviceBusDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + serviceBusName: serviceBusName + serviceBusQueue1Name: serviceBusQueue1Name + serviceBusQueue2Name: serviceBusQueue2Name + serviceBusTopicName: serviceBusTopicName + serviceBusSubscription1Name: serviceBusSubscription1Name + serviceBusSubscription2Name: serviceBusSubscription2Name + serviceBusTopicRule1Name: serviceBusTopicRule1Name + serviceBusTopicRule2Name: serviceBusTopicRule2Name + logAnalyticsWorkspaceId: appInsights.outputs.workspaceId + } +} + +module alerts 'modules/alerts.bicep' = { + name: 'alertsDeploy' + scope: resourceGroup + params: { + location: resourceGroup.location + actionGroupName: 'default-actiongroup' + notificationEmailAddress: notificationEmailAddress + cosmosDBId: cosmos.outputs.cosmosDBId + keyVaultId: kv.outputs.kvId + serviceBusNamespaceId: serviceBus.outputs.serviceBusNamespaceId + aksClusterId: aks.outputs.clusterId + appInsightsId: appInsights.outputs.appInsightsId + logAnalyticsWorkspaceId: appInsights.outputs.workspaceId + } +} + +//output section +output rg_name string = resourceGroup.name +output insights_name string = appInsights.outputs.insightsName +output sb_namespace_name string = serviceBus.outputs.serviceBusNamespaceName +output cosmosdb_name string = cosmos.outputs.cosmosDBAccountName +output kv_name string = kv.outputs.kvName +output acr_name string = acr.outputs.acrName +output aks_name string = aks.outputs.clusterName +output aks_key_vault_secret_provider_client_id string = aks.outputs.clusterKeyVaultSecretProviderClientId +output tenant_id string = subscription().tenantId diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/acr.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/acr.bicep new file mode 100644 index 0000000..a5af59b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/acr.bicep @@ -0,0 +1,45 @@ +@description('Default value obtained from resource group, it can be overwritten') +@minLength(1) +param location string = resourceGroup().location + +@description('Name for the ACR') +@minLength(1) +param acrName string + +@description('The principal ID of the AKS cluster') +@minLength(1) +param aksPrincipalId string + +@description('Built-in role for role assignment') +@minLength(1) +param roleDefinitionId string + +@description('Expected ACR sku') +@allowed([ + 'Basic' + 'Classic' + 'Premium' + 'Standard' +]) +param acrSku string = 'Standard' + +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' = { + name: acrName + location: location + sku: { + name: acrSku + } +} + +resource assignAcrPullToAks 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { + name: guid(resourceGroup().id, acrName, aksPrincipalId, 'AssignAcrPullToAks') + scope: containerRegistry + properties: { + description: 'Assign AcrPull role to AKS' + principalId: aksPrincipalId + principalType: 'ServicePrincipal' + roleDefinitionId: roleDefinitionId + } +} + +output acrName string = containerRegistry.name diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/aks.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/aks.bicep new file mode 100644 index 0000000..f4cb5cf --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/aks.bicep @@ -0,0 +1,100 @@ +@description('Default value obtained from resource group, it can be overwritten') +param location string = resourceGroup().location + +@description('The name of the AKS resource') +@minLength(1) +param aksName string + +@description('Disk size (in GB) to provision for each of the agent pool nodes. Specifying 0 will apply the default disk size for that agentVMSize') +@minValue(0) +@maxValue(1023) +param aksDiskSizeGB int = 30 + +@description('The number of nodes for the cluster') +@minValue(1) +@maxValue(50) +param aksNodeCount int = 3 + +@description('The size of the Virtual Machine') +param aksVMSize string = 'Standard_D2s_v3' + +@description('The name of the Log Analytics workspace linked to AKS') +@minLength(1) +param logAnalyticsWorkspaceId string + +@description('Configure Azure Active Directory authentication for Kubernetes cluster') +param aksAadAuth bool + +@description('The object ID of the Azure Active Directory user to make cluster admin (only valid if aksAadAuth is true)') +param aksAadAdminUserObjectId string = '' + +var aksAadProfile = { + managed: true + enableAzureRBAC: true + tenantId: subscription().tenantId +} + +resource aks 'Microsoft.ContainerService/managedClusters@2020-09-01' = { + name: aksName + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + dnsPrefix: 'aks' + aadProfile: aksAadAuth ? aksAadProfile : null + agentPoolProfiles: [ + { + name: 'agentpool' + osDiskSizeGB: aksDiskSizeGB + count: aksNodeCount + minCount: 1 + maxCount: aksNodeCount + vmSize: aksVMSize + osType: 'Linux' + mode: 'System' + enableAutoScaling: true + } + ] + addonProfiles: { + omsAgent: { + enabled: true + config: { + logAnalyticsWorkspaceResourceID: logAnalyticsWorkspaceId + } + } + azureKeyvaultSecretsProvider: { + enabled: true + config: { + enableSecretRotation: 'true' + rotationPollInterval: '2m' + } + } + } + } +} + +resource adminRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (aksAadAuth) { + name: guid(subscription().id, resourceGroup().id, 'aks-admin-${aksAadAdminUserObjectId}') + scope: aks + properties: { + // Azure Kubernetes Service Cluster Admin Role + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8') + principalId: aksAadAdminUserObjectId + } +} +resource userRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (aksAadAuth) { + name: guid(subscription().id, resourceGroup().id, 'aks-user-${aksAadAdminUserObjectId}') + scope: aks + properties: { + // Azure Kubernetes Service Cluster User Role + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '4abbcc35-e782-43d8-92c5-2d3f1bd2253f') + principalId: aksAadAdminUserObjectId + } +} + +output clusterName string = aks.name +output clusterId string = aks.id +output clusterPrincipalID string = aks.properties.identityProfile.kubeletidentity.objectId +output clusterKeyVaultSecretProviderClientId string = aks.properties.addonProfiles.azureKeyvaultSecretsProvider.identity.clientId +output clusterKeyVaultSecretProviderObjectId string = aks.properties.addonProfiles.azureKeyvaultSecretsProvider.identity.objectId diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/alerts.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/alerts.bicep new file mode 100644 index 0000000..b614152 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/alerts.bicep @@ -0,0 +1,953 @@ +@description('Default value obtained from resource group, it can be overwritten') +param location string = resourceGroup().location + +@description('Name for the default action group') +@minLength(1) +param actionGroupName string + +@description('Email address for alert notifications') +@minLength(1) +param notificationEmailAddress string + +@description('Cosmos DB resource id') +param cosmosDBId string + +@description('Service Bus namespace resource id') +param serviceBusNamespaceId string + +@description('AKS cluster resource id') +param aksClusterId string + +@description('Key Vault resource id') +param keyVaultId string + +@description('Application Insights resource id') +param appInsightsId string + +@description('Log Analytics workspace resource id') +param logAnalyticsWorkspaceId string + +var defaultMetricAlertActions = [ + { + actionGroupId: defaultActionGroup.id + } +] + +var defaultLogAlertActions = { + actionGroups: [ + defaultActionGroup.id + ] +} + +var serviceBusSplitByEntityDimensions = [ + { + name: 'EntityName' + operator: 'Include' + values: [ + '*' + ] + } +] + +resource defaultActionGroup 'Microsoft.Insights/actionGroups@2022-06-01' = { + name: actionGroupName + location: 'global' + properties: { + enabled: false + groupShortName: length(actionGroupName) <= 12 ? actionGroupName : substring(actionGroupName, 0, 12) + emailReceivers: [ + { + name: 'email-receiver' + emailAddress: notificationEmailAddress + useCommonAlertSchema: false + } + ] + } +} + +resource cosmosRusAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'cosmosRUs' + location: 'global' + properties: { + description: 'Alert when RUs exceed 400.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'TotalRequestUnits' + metricNamespace: 'Microsoft.DocumentDB/databaseAccounts' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Total' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 400 + } + ] + } + scopes: [ cosmosDBId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT1M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource cosmosInvalidCargoAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'cosmosInvalidCargo' + location: 'global' + properties: { + description: 'Alert when more than 10 documents have been saved to the invalid-cargo container.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'DocumentCount' + metricNamespace: 'Microsoft.DocumentDB/databaseAccounts' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Total' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 10 + dimensions: [ + { + name: 'CollectionName' + operator: 'Include' + values: [ + 'invalid-cargo' + ] + } + ] + } + ] + } + scopes: [ cosmosDBId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT1M' + windowSize: 'PT5M' + severity: 3 + enabled: false + } +} + +resource serviceBusAbandonedMessagesAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'serviceBusAbandonedMessages' + location: 'global' + properties: { + description: 'Alert when a Service Bus entity has abandoned more than 10 messages.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'AbandonMessage' + metricNamespace: 'Microsoft.ServiceBus/namespaces' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Total' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 10 + dimensions: serviceBusSplitByEntityDimensions + } + ] + } + scopes: [ serviceBusNamespaceId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT1M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource serviceBusDeadLetteredMessagesAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'serviceBusDeadLetteredMessages' + location: 'global' + properties: { + description: 'Alert when a Service Bus entity has dead-lettered more than 10 messages.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'DeadletteredMessages' + metricNamespace: 'Microsoft.ServiceBus/namespaces' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Average' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 10 + dimensions: serviceBusSplitByEntityDimensions + } + ] + } + scopes: [ serviceBusNamespaceId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT1M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource serviceBusThrottledRequestsAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'serviceBusThrottledRequests' + location: 'global' + properties: { + description: 'Alert when a Service Bus entity has throttled more than 10 requests.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'ThrottledRequests' + metricNamespace: 'Microsoft.ServiceBus/namespaces' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Total' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 10 + dimensions: serviceBusSplitByEntityDimensions + } + ] + } + scopes: [ serviceBusNamespaceId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT1M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource aksCPUPercentageAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'aksCPUPercentage' + location: 'global' + properties: { + description: 'Alert when Node CPU percentage exceeds 80.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'node_cpu_usage_percentage' + metricNamespace: 'Microsoft.ContainerService/managedClusters' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Average' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 80 + } + ] + } + scopes: [ aksClusterId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource aksMemoryPercentageAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'aksMemoryPercentage' + location: 'global' + properties: { + description: 'Alert when Node memory working set percentage exceeds 80.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'node_memory_working_set_percentage' + metricNamespace: 'Microsoft.ContainerService/managedClusters' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Average' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 80 + } + ] + } + scopes: [ aksClusterId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource keyVaultSaturationAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'keyVaultSaturation' + location: 'global' + properties: { + description: 'Alert when Key Vault saturation falls outside the range of a dynamic threshold.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'SaturationShoebox' + metricNamespace: 'Microsoft.KeyVault/vaults' + name: 'Metric1' + skipMetricValidation: false + timeAggregation: 'Average' + criterionType: 'DynamicThresholdCriterion' + operator: 'GreaterOrLessThan' + alertSensitivity: 'Medium' + failingPeriods: { + minFailingPeriodsToAlert: 4 + numberOfEvaluationPeriods: 4 + } + } + ] + } + scopes: [ keyVaultId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 3 + enabled: false + } +} + +// Tenant specific issues prevent deployment of custom metric alert +// +resource productQtyScheduledForDestinationPortAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { + name: 'productQtyScheduledForDestinationPort' + location: 'global' + properties: { + description: 'Alert when a single port/destination receives more than quantity 1000 of a given product.' + criteria: { + 'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria' + allOf: [ + { + metricName: 'port_product_qty' + metricNamespace: 'azure.applicationinsights' + name: 'Metric1' + skipMetricValidation: true + timeAggregation: 'Total' + criterionType: 'StaticThresholdCriterion' + operator: 'GreaterThan' + threshold: 1000 + dimensions: [ + { + name: 'destination' + operator: 'Include' + values: [ + '*' + ] + } + { + name: 'product' + operator: 'Include' + values: [ + '*' + ] + } + ] + } + ] + } + scopes: [ appInsightsId ] + actions: defaultMetricAlertActions + evaluationFrequency: 'PT1M' + windowSize: 'PT1M' + severity: 3 + enabled: false + } +} + +resource microserviceExceptionsAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'microserviceExceptions' + location: location + properties: { + description: 'Alert when a microservice throws more than 5 exceptions.' + criteria: { + allOf: [ + { + query: 'exceptions\n' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 5 + dimensions: [ + { + name: 'cloud_RoleName' + operator: 'Include' + values: [ + '*' + ] + } + ] + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource cargoProcessingAPIRequestsAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'cargoProcessingAPIRequests' + location: location + properties: { + description: 'Alert when the cargo-processing-api microservice is not receiving any requests.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "cargo-processing-api" and (name == "POST /cargo/" or name == "PUT /cargo/{cargoId}")' + timeAggregation: 'Count' + operator: 'Equal' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 3 + enabled: false + } +} + +resource e2eAverageDurationAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'e2eAverageDuration' + location: location + properties: { + description: 'Alert when the end to end average request duration exceeds 5 seconds.' + criteria: { + allOf: [ + { + query: 'let cargo_processing_api = requests\r\n| where cloud_RoleName == "cargo-processing-api" and (name == "POST /cargo/" or name == "PUT /cargo/{cargoId}")\r\n| project-rename ingest_timestamp = timestamp\r\n| project ingest_timestamp, operation_Id;\r\nlet operation_api_succeeded = requests\r\n| where cloud_RoleName == "operations-api" and name == "ServiceBus.process" and customDimensions["operation-state"] == "Succeeded"\r\n| extend operation_api_completed = timestamp + (duration*1ms)\r\n| project operation_Id, operation_api_completed;\r\ncargo_processing_api\r\n| join kind=inner operation_api_succeeded on $left.operation_Id == $right.operation_Id\r\n| extend end_to_end_Duration_ms = (operation_api_completed - ingest_timestamp) /1ms\r\n| summarize avg(end_to_end_Duration_ms)' + metricMeasureColumn: 'avg_end_to_end_Duration_ms' + timeAggregation: 'Average' + operator: 'GreaterThan' + threshold: 5000 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource cargoProcessingAPIAverageDurationAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'cargoProcessingAPIAverageDuration' + location: location + properties: { + description: 'Alert when the cargo-processing-api microservice average request duration exceeds 2 seconds.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "cargo-processing-api" and (name == "POST /cargo/" or name == "PUT /cargo/{cargoId}")\r\n| summarize avg(duration)' + metricMeasureColumn: 'avg_duration' + timeAggregation: 'Average' + operator: 'GreaterThan' + threshold: 2000 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource cargoProcessingValidatorAverageDurationAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'cargoProcessingValidatorAverageDuration' + location: location + properties: { + description: 'Alert when the cargo-processing-validator microservice average request duration exceeds 2 seconds.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "cargo-processing-validator" and (name == "ServiceBus.ProcessMessage" or name == "ServiceBusQueue.ProcessMessage")\r\n| summarize avg(duration)' + metricMeasureColumn: 'avg_duration' + timeAggregation: 'Average' + operator: 'GreaterThan' + threshold: 2000 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource validCargoManagerAverageDurationAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'validCargoManagerAverageDuration' + location: location + properties: { + description: 'Alert when the valid-cargo-manager microservice average request duration exceeds 2 seconds.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "valid-cargo-manager" and name == "ServiceBusTopic.ProcessMessage"\r\n| summarize avg(duration)' + metricMeasureColumn: 'avg_duration' + timeAggregation: 'Average' + operator: 'GreaterThan' + threshold: 2000 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource invalidCargoManagerAverageDurationAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'invalidCargoManagerAverageDuration' + location: location + properties: { + description: 'Alert when the invalid-cargo-manager microservice average request duration exceeds 2 seconds.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "invalid-cargo-manager" and name == "ServiceBusTopic.ProcessMessage"\r\n| summarize avg(duration)' + metricMeasureColumn: 'avg_duration' + timeAggregation: 'Average' + operator: 'GreaterThan' + threshold: 2000 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource operationsAPIAverageDurationAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'operationsAPIAverageDuration' + location: location + properties: { + description: 'Alert when the operations-api microservice average request duration exceeds 1 second.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "operations-api" and name == "ServiceBus.process"\r\n| summarize avg(duration)' + metricMeasureColumn: 'avg_duration' + timeAggregation: 'Average' + operator: 'GreaterThan' + threshold: 1000 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource logAnalyticsDataIngestionDailyCapAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'logAnalyticsDataIngestionDailyCap' + location: location + properties: { + description: 'Alert when the Log Analytics data ingestion daily cap has been reached.' + criteria: { + allOf: [ + { + query: '_LogOperation | where Category == "Ingestion" | where Operation has "Data collection"' + resourceIdColumn: '_ResourceId' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ logAnalyticsWorkspaceId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource logAnalyticsDataIngestionRateAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'logAnalyticsDataIngestionRate' + location: location + properties: { + description: 'Alert when the Log Analytics max data ingestion rate has been reached.' + criteria: { + allOf: [ + { + query: '_LogOperation | where Category == "Ingestion" | where Operation has "Ingestion rate"' + resourceIdColumn: '_ResourceId' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ logAnalyticsWorkspaceId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 2 + enabled: false + } +} + +resource logAnalyticsOperationalIssuesAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'logAnalyticsOperationalIssues' + location: location + properties: { + description: 'Alert when the Log Analytics workspace has an operational issue.' + criteria: { + allOf: [ + { + query: '_LogOperation | where Level == "Warning"' + resourceIdColumn: '_ResourceId' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ logAnalyticsWorkspaceId ] + actions: defaultLogAlertActions + evaluationFrequency: 'P1D' + windowSize: 'P1D' + severity: 3 + enabled: false + } +} + +resource cargoProcessingAPIHealthCheckFailureAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'cargoProcessingAPIHealthCheckFailure' + location: location + properties: { + description: 'Alert when a cargo-processing-api microservice health check fails.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "cargo-processing-api" and name == "GET /actuator/health" and success == "False"' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource cargoProcessingAPIHealthCheckNotReportingAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'cargoProcessingAPIHealthCheckNotReporting' + location: location + properties: { + description: 'Alert when the cargo-processing-api microservice health check is not reporting.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "cargo-processing-api" and name == "GET /actuator/health"' + timeAggregation: 'Count' + operator: 'Equal' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource validCargoManagerHealthCheckFailureAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'validCargoManagerHealthCheckFailureAlert' + location: location + properties: { + description: 'Alert when a valid-cargo-manager microservice health check fails.' + criteria: { + allOf: [ + { + query: 'customMetrics\r\n| where cloud_RoleName == "valid-cargo-manager" and name == "HeartbeatState" and value != 2' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT30M' + windowSize: 'PT30M' + severity: 1 + enabled: false + } +} + +resource validCargoManagerHealthCheckNotReportingAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'validCargoManagerHealthCheckNotReporting' + location: location + properties: { + description: 'Alert when the valid-cargo-manager microservice health check is not reporting.' + criteria: { + allOf: [ + { + query: 'customMetrics\r\n| where cloud_RoleName == "valid-cargo-manager" and name == "HeartbeatState"' + timeAggregation: 'Count' + operator: 'Equal' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT30M' + windowSize: 'PT30M' + severity: 1 + enabled: false + } +} + +resource invalidCargoManagerHealthCheckFailureAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'invalidCargoManagerHealthCheckFailure' + location: location + properties: { + description: 'Alert when an invalid-cargo-manager microservice health check fails.' + criteria: { + allOf: [ + { + query: 'traces\r\n| where cloud_RoleName == "invalid-cargo-manager" and message contains "peeked at messages for over"' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource invalidCargoManagerHealthCheckNotReportingAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'invalidCargoManagerHealthCheckNotReporting' + location: location + properties: { + description: 'Alert when the invalid-cargo-manager microservice health check is not reporting.' + criteria: { + allOf: [ + { + query: 'traces\r\n| where cloud_RoleName == "invalid-cargo-manager" and (message contains "since last peek" or message contains "peeked at messages for over")' + timeAggregation: 'Count' + operator: 'Equal' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource operationsAPIHealthCheckFailureAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'operationsAPIHealthCheckFailure' + location: location + properties: { + description: 'Alert when an operations-api microservice health check fails.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "operations-api" and name == "GET /actuator/health" and success == "False"' + timeAggregation: 'Count' + operator: 'GreaterThan' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource operationsAPIHealthCheckNotReportingAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'operationsAPIHealthCheckNotReporting' + location: location + properties: { + description: 'Alert when the operations-api microservice health check is not reporting.' + criteria: { + allOf: [ + { + query: 'requests\r\n| where cloud_RoleName == "operations-api" and name == "GET /actuator/health"' + timeAggregation: 'Count' + operator: 'Equal' + threshold: 0 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + } + ] + } + scopes: [ appInsightsId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} + +resource aksPodRestartsAlert 'Microsoft.Insights/scheduledQueryRules@2022-06-15' = { + name: 'aksPodRestarts' + location: location + properties: { + description: 'Alert when a microservice restarts more than once.' + criteria: { + allOf: [ + { + query: 'KubePodInventory\r\n| summarize numRestarts = sum(PodRestartCount) by ServiceName' + metricMeasureColumn: 'numRestarts' + timeAggregation: 'Total' + operator: 'GreaterThan' + threshold: 1 + failingPeriods: { + numberOfEvaluationPeriods: 1 + minFailingPeriodsToAlert: 1 + } + dimensions: [ + { + name: 'ServiceName' + operator: 'Include' + values: [ + 'cargo-processing-api' + 'cargo-processing-validator' + 'invalid-cargo-manager' + 'operations-api' + 'valid-cargo-manager' + ] + } + ] + } + ] + } + scopes: [ logAnalyticsWorkspaceId ] + actions: defaultLogAlertActions + evaluationFrequency: 'PT5M' + windowSize: 'PT5M' + severity: 1 + enabled: false + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/app-insights.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/app-insights.bicep new file mode 100644 index 0000000..ac1b57a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/app-insights.bicep @@ -0,0 +1,33 @@ +@description('Default value obtained from resource group, it can be overwritten') +param location string = resourceGroup().location + +@description('Name of the Application Insights instance') +param appInsightsName string + +@description('Name of the Log Analytics instance') +param logAnalyticsName string + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: logAnalyticsName + location: location + properties: { + sku: { + name: 'PerGB2018' + } + } +} + +resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { + name: appInsightsName + location: location + kind: 'web' + properties: { + Application_Type: 'web' + WorkspaceResourceId: logAnalyticsWorkspace.id + } +} + +output connectionString string = applicationInsights.properties.ConnectionString +output workspaceId string = logAnalyticsWorkspace.id +output insightsName string = applicationInsights.name +output appInsightsId string = applicationInsights.id diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/cosmos.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/cosmos.bicep new file mode 100644 index 0000000..dff8b70 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/cosmos.bicep @@ -0,0 +1,161 @@ +@description('Default value obtained from resource group, it can be overwriten') +param location string = resourceGroup().location + +@description('Cosmos DB account name, max length 44 characters, lowercase') +@minLength(1) +@maxLength(44) +param accountName string = 'sql-${uniqueString(resourceGroup().id)}' + +@description('The default consistency level of the Cosmos DB account.') +@allowed([ + 'Eventual' + 'ConsistentPrefix' + 'Session' + 'BoundedStaleness' + 'Strong' +]) +param defaultConsistencyLevel string = 'Session' + +@description('Enable automatic failover for regions') +param automaticFailover bool = true + +@description('The name for the database') +@minLength(1) +param databaseName string + +@description('The name for the container 1') +@minLength(1) +param container1Name string + +@description('The name for the container 2') +@minLength(1) +param container2Name string + +@description('The name for the container 3') +@minLength(1) +param container3Name string + +@description('Name for diagnostic settings') +@minLength(1) +param diagnosticSettingsName string = 'cosmosDbDiagnostics' + +@description('Log analytics workspace id') +@minLength(1) +param logAnalyticsWorkspaceId string + +var accountNameVar = toLower(accountName) +var locations = [ + { + locationName: location + failoverPriority: 0 + isZoneRedundant: false + } +] + +resource accountNameResource 'Microsoft.DocumentDB/databaseAccounts@2021-01-15' = { + name: accountNameVar + kind: 'GlobalDocumentDB' + location: location + properties: { + consistencyPolicy: { + defaultConsistencyLevel: defaultConsistencyLevel + } + locations: locations + databaseAccountOfferType: 'Standard' + enableAutomaticFailover: automaticFailover + } + + resource database 'sqlDatabases' = { + name: databaseName + properties: { + resource: { + id: databaseName + } + } + + resource container1 'containers' = { + name: container1Name + properties: { + resource: { + id: container1Name + partitionKey: { + paths: [ + '/id' + ] + kind: 'Hash' + } + } + } + } + + resource container2 'containers' = { + name: container2Name + properties: { + resource: { + id: container2Name + partitionKey: { + paths: [ + '/id' + ] + kind: 'Hash' + } + } + } + } + + resource container3 'containers' = { + name: container3Name + properties: { + resource: { + id: container3Name + partitionKey: { + paths: [ + '/id' + ] + kind: 'Hash' + } + } + } + } + } +} + +resource cosmosDbDiagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { + name: diagnosticSettingsName + scope: accountNameResource + properties: { + logs: [ + { + category: 'DataPlaneRequests' + enabled: true + } + { + category: 'QueryRuntimeStatistics' + enabled: true + } + { + category: 'PartitionKeyStatistics' + enabled: true + } + { + category: 'PartitionKeyRUConsumption' + enabled: true + } + { + category: 'ControlPlaneRequests' + enabled: true + } + ] + metrics: [ + { + category: 'Requests' + enabled: true + } + ] + workspaceId: logAnalyticsWorkspaceId + } +} + +output cosmosDBId string = accountNameResource.id +output cosmosDBEndpoint string = accountNameResource.properties.documentEndpoint +output cosmosDBAccountName string = accountNameResource.name diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/key-vault.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/key-vault.bicep new file mode 100644 index 0000000..58e4194 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/key-vault.bicep @@ -0,0 +1,125 @@ +@description('Location obtained from resource group') +param location string = resourceGroup().location + +@description('KeyVault name') +@minLength(1) +param kvName string + +@description('Expected KeyVault sku') +@allowed([ + 'premium' + 'standard' +]) +param kvSku string = 'standard' + +@description('Tenant Id for the service principal that will be in charge of KeyVault access') +@minLength(1) +param kvTenantId string = tenant().tenantId + +//secrets stored in KeyVault +@description('Service Bus Namespace name') +@minLength(1) +param serviceBusNamespaceName string + +@description('App Insights Connection String') +@minLength(1) +@secure() +param appInsightsConnectionString string + +@description('Cosmos DB endpoint') +@minLength(1) +param cosmosDBEndpoint string + +@description('Cosmos DB account name') +@minLength(1) +param cosmosDBAccountName string + +@description('Name for diagnostic settings') +@minLength(1) +param diagnosticSettingsName string = 'keyVaultDiagnostics' + +@description('Log analytics workspace id') +@minLength(1) +param logAnalyticsWorkspaceId string + +@description('The Object ID of the user-defined Managed Identity used by the AKS Secret Provider') +@minLength(1) +@secure() +param clusterKeyVaultSecretProviderObjectId string + +resource keyVault 'Microsoft.KeyVault/vaults@2021-11-01-preview' = { + name: kvName + location: location + properties: { + tenantId: kvTenantId + sku: { + family: 'A' + name: kvSku + } + createMode: 'default' + publicNetworkAccess: 'Enabled' + accessPolicies: [ + { + objectId: clusterKeyVaultSecretProviderObjectId + permissions: { + secrets: [ + 'get' + ] + } + tenantId: subscription().tenantId + } + ] + enabledForTemplateDeployment: true + } + + resource appInsightsStringSecret 'secrets' = { + name: 'AppInsightsConnectionString' + properties: { + value: appInsightsConnectionString + } + } + + resource serviceBusSecret 'secrets' = { + name: 'ServiceBusConnectionString' + properties: { + value: listKeys(resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', serviceBusNamespaceName, 'RootManageSharedAccessKey'), '2022-01-01-preview').primaryConnectionString + } + } + + resource cosmosDBEndpointSecret 'secrets' = { + name: 'CosmosDBEndpoint' + properties: { + value: cosmosDBEndpoint + } + } + + resource cosmosDBKeySecret 'secrets' = { + name: 'CosmosDBKey' + properties: { + value: listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', cosmosDBAccountName), '2022-05-15').primaryMasterKey + } + } +} + +resource keyVaultDiagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { + name: diagnosticSettingsName + scope: keyVault + properties: { + logs: [ + { + categoryGroup: 'allLogs' + enabled: true + } + ] + metrics: [ + { + category: 'AllMetrics' + enabled: true + } + ] + workspaceId: logAnalyticsWorkspaceId + } +} + +output kvName string = keyVault.name +output kvId string = keyVault.id diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/service-bus.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/service-bus.bicep new file mode 100644 index 0000000..0ff68a5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/service-bus.bicep @@ -0,0 +1,130 @@ +@description('Name for the Service Bus Namespace') +@minLength(1) +param serviceBusName string + +@description('Default value obtained from resource group, it can be overwritten') +@minLength(1) +param location string = resourceGroup().location + +@description('Name for the first Service Bus Queue') +@minLength(1) +param serviceBusQueue1Name string + +@description('Name for the second Service Bus Queue') +@minLength(1) +param serviceBusQueue2Name string + +@description('Name for the Service Bus Topic') +@minLength(1) +param serviceBusTopicName string + +@description('Name for the first Service Bus Subscription') +@minLength(1) +param serviceBusSubscription1Name string + +@description('Name for the second Service Bus Subscription') +@minLength(1) +param serviceBusSubscription2Name string + +@description('Name for the first Service Bus Subscriptions filter rule') +@minLength(1) +param serviceBusTopicRule1Name string + +@description('Name for the second Service Bus Subscriptions filter rule') +@minLength(1) +param serviceBusTopicRule2Name string + +@description('Name for diagnostic settings') +@minLength(1) +param diagnosticSettingsName string = 'serviceBusDiagnostics' + +@description('Log analytics workspace id') +@minLength(1) +param logAnalyticsWorkspaceId string + +resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' = { + name: serviceBusName + location: location + sku: { + capacity: 1 + name: 'Standard' + tier: 'Standard' + } + + properties: { + publicNetworkAccess: 'Enabled' + } + + resource serviceBusQueue 'queues' = { + name: serviceBusQueue1Name + } + + resource serviceBusQueue2 'queues' = { + name: serviceBusQueue2Name + } +} + +resource serviceBusTopic 'Microsoft.ServiceBus/namespaces/topics@2022-01-01-preview' = { + name: serviceBusTopicName + parent: serviceBusNamespace + properties: { + supportOrdering: true + } + + resource serviceBusSubscription1 'subscriptions' = { + name: serviceBusSubscription1Name + properties: { + maxDeliveryCount: 1 + } + + resource serviceBusTopicRule 'rules' = { + name: serviceBusTopicRule1Name + properties: { + filterType: 'SqlFilter' + sqlFilter: { + sqlExpression: 'valid = True' + } + } + } + } + + resource serviceBusSubscription2 'subscriptions' = { + name: serviceBusSubscription2Name + properties: { + maxDeliveryCount: 1 + } + + resource serviceBusTopicRule 'rules' = { + name: serviceBusTopicRule2Name + properties: { + filterType: 'SqlFilter' + sqlFilter: { + sqlExpression: 'valid = False' + } + } + } + } +} + +resource serviceBusDiagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { + name: diagnosticSettingsName + scope: serviceBusNamespace + properties: { + logs: [ + { + categoryGroup: 'allLogs' + enabled: true + } + ] + metrics: [ + { + category: 'AllMetrics' + enabled: true + } + ] + workspaceId: logAnalyticsWorkspaceId + } +} + +output serviceBusNamespaceName string = serviceBusNamespace.name +output serviceBusNamespaceId string = serviceBusNamespace.id diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/workbooks.bicep b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/workbooks.bicep new file mode 100644 index 0000000..5447e41 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/bicep/modules/workbooks.bicep @@ -0,0 +1,81 @@ +@description('Default value obtained from resource group, it can be overwritten') +param location string = resourceGroup().location + +@description('This value will explain who is the author of specific resources and will be reflected in every deployed tool') +@minLength(1) +param uniqueUserName string + +@description('Linked resource for Workook') +@minLength(1) +param workspaceId string + +@description('Id for monitored Service Bus Namespace') +@minLength(1) +param serviceBusNamespaceId string + +@description('Id for monitored Key Vault resource') +@minLength(1) +param keyVaultId string + +@description('Id for App Insights resource') +@minLength(1) +param appInsightsId string + +@description('Id for monitored AKS resource') +@minLength(1) +param aksId string + +var indexWorkbookName = guid(subscription().subscriptionId, resourceGroup().name, uniqueUserName, 'index') +var baseIndexWorkbookContent = loadTextContent('../../workbooks/index.json') +var indexInsightsWorkbookContent = replace(baseIndexWorkbookContent, '\${app_insights_id}', appInsightsId) +var indexWorkspaceWorkbookContent =replace(indexInsightsWorkbookContent, '\${logs_workspace_id}', uriComponent(workspaceId)) +var indexInfrastructureWorkbookContent = replace(indexWorkspaceWorkbookContent, '\${infrastructure_workbook_id}', uriComponent(infrastructureWorkbook.id)) +var indexFinalWorkbookContent = replace(indexInfrastructureWorkbookContent, '\${system_workbook_id}', uriComponent(serviceProcessingWorkbook.id)) +resource observabilityWorkbook 'Microsoft.Insights/workbooks@2022-04-01' = { + name: indexWorkbookName + location: location + kind: 'shared' + properties: { + category: 'workbook' + displayName: 'Index' + serializedData: string(indexFinalWorkbookContent) + version: '0.01' + sourceId: workspaceId + } +} + +var infrastructureWorkbookName = guid(subscription().subscriptionId, resourceGroup().name, uniqueUserName, 'infrastructure') +var baseInfrastructureWorkbookContent = loadTextContent('../../workbooks/infrastructure.json') +var baseInfrastructureSeviceBusWorkbookContent = replace(baseInfrastructureWorkbookContent, '\${servicebus_namespace_id}', serviceBusNamespaceId) +var baseInfrastructureKeyVaultWorkbookContent = replace(baseInfrastructureSeviceBusWorkbookContent, '\${key_vault_id}', keyVaultId) +var infrastructureUrlWorkbookContent =replace(baseInfrastructureKeyVaultWorkbookContent, '\${app_insights_id_url}', uriComponent(appInsightsId)) +var baseInfrastructureAksWorkbookContent = replace(infrastructureUrlWorkbookContent, '\${aks_id}', aksId) +var infrastructureFinalWorkbookContent = replace(baseInfrastructureAksWorkbookContent, '\${app_insights_id}', appInsightsId) +resource infrastructureWorkbook 'Microsoft.Insights/workbooks@2022-04-01' = { + name: infrastructureWorkbookName + location: location + kind: 'shared' + properties: { + category: 'workbook' + displayName: 'Infrastructure' + serializedData: string(infrastructureFinalWorkbookContent) + version: '0.01' + sourceId: workspaceId + } +} + +var serviceProcessingWorkbookName = guid(subscription().subscriptionId, resourceGroup().name, uniqueUserName, 'service-processing') +var baseServiceProcessingWorkbookContent = loadTextContent('../../workbooks/system-processing.json') +var serviceProcessingWorkbookContent = replace(baseServiceProcessingWorkbookContent, '\${app_insights_id}', appInsightsId) +resource serviceProcessingWorkbook 'Microsoft.Insights/workbooks@2022-04-01' = { + name: serviceProcessingWorkbookName + location: location + kind: 'shared' + properties: { + category: 'workbook' + displayName: 'System Processing' + serializedData: string(serviceProcessingWorkbookContent) + version: '0.01' + sourceId: workspaceId + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/build-and-push-images.sh b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/build-and-push-images.sh new file mode 100644 index 0000000..9aa7a86 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/build-and-push-images.sh @@ -0,0 +1,78 @@ +#!/bin/bash +set -e + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +function help() { + echo + echo "build-images.sh" + echo + echo "Build images" + echo + echo -e "\t--acr-name\t(Optional)The name of the Azure Container Registry to push to. If not provided, the images will be built but not pushed." + echo -e "\t--image-tag\t(Optional)The tag to build the image with (defaults to 'latest')" + echo +} + + +# Set default values here +acr_name="" +image_tag="latest" + + +# Process switches: +SHORT=h +LONG=acr-name:,image-tag:,help +OPTS=$(getopt -a -n files --options $SHORT --longoptions $LONG -- "$@") + +eval set -- "$OPTS" + +while : +do + case "$1" in + --acr-name) + acr_name=$2 + shift 2 + ;; + --image-tag) + image_tag=$2 + shift 2 + ;; + -h | --help) + help + ;; + --) + shift; + break + ;; + *) + echo "Unexpected '$1'" + help + exit 1 + ;; + esac +done + +image_base_name="" +if [[ -n $acr_name ]]; then + echo -e "**\n** Authenticating to container registry ($acr_name)...\n**" + az acr login --name "$acr_name" + + image_base_name="${acr_name}.azurecr.io/" +fi + + +services_to_build=("cargo-processing-api" "cargo-processing-validator" "invalid-cargo-manager" "operations-api" "valid-cargo-manager") +for service in "${services_to_build[@]}" +do + echo + echo "*******************************************************************************************************************" + echo -e "\n**\n** Building ${service}...\n**" + echo "*******************************************************************************************************************" + docker build --progress plain -t "${image_base_name}${service}:${image_tag}" "$script_dir/../../src/${service}" + + if [[ -n $acr_name ]]; then + echo -e "\n**\n** Pushing ${service}...\n**" + docker push "${image_base_name}${service}:${image_tag}" + fi +done diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/create-env-files-from-output.sh b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/create-env-files-from-output.sh new file mode 100644 index 0000000..a4b1053 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/create-env-files-from-output.sh @@ -0,0 +1,246 @@ +#!/bin/bash +set -e + +# +# This script expects to find an output.json in the project root with the values +# from the infrastructure deployment. +# It then creates the env files, settings files, and helm chart values files for each service +# + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +RESOURCE_GROUP=$(jq -r '.rg_name' < "$script_dir/../../output.json") +if [[ ${#RESOURCE_GROUP} -eq 0 ]]; then + echo 'ERROR: Missing output value rg_name' 1>&2 + exit 6 +fi + +APP_INSIGHTS=$(jq -r '.insights_name' < "$script_dir/../../output.json") +if [[ ${#APP_INSIGHTS} -eq 0 ]]; then + echo 'ERROR: Missing output value insights_name' 1>&2 + exit 6 +fi + +SERVICE_BUS_NAMESPACE=$(jq -r '.sb_namespace_name' < "$script_dir/../../output.json") +if [[ ${#SERVICE_BUS_NAMESPACE} -eq 0 ]]; then + echo 'ERROR: Missing output value sb_namespace_name' 1>&2 + exit 6 +fi + +COSMOSDB_NAME=$(jq -r '.cosmosdb_name' < "$script_dir/../../output.json") +if [[ ${#COSMOSDB_NAME} -eq 0 ]]; then + echo 'ERROR: Missing output value cosmosdb_name' 1>&2 + exit 6 +fi + +ACR_NAME=$(jq -r '.acr_name' < "$script_dir/../../output.json") +if [[ ${#ACR_NAME} -eq 0 ]]; then + echo 'ERROR: Missing output value acr_name' 1>&2 + exit 6 +fi + +KEYVAULT_NAME=$(jq -r '.kv_name' < "$script_dir/../../output.json") +if [[ ${#KEYVAULT_NAME} -eq 0 ]]; then + echo 'ERROR: Missing output value kv_name' 1>&2 + exit 6 +fi + +TENANT_ID=$(jq -r '.tenant_id' < "$script_dir/../../output.json") +if [[ ${#TENANT_ID} -eq 0 ]]; then + echo 'ERROR: Missing output value tenant_id' 1>&2 + exit 6 +fi + +AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID=$(jq -r '.aks_key_vault_secret_provider_client_id' < "$script_dir/../../output.json") +if [[ ${#AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID} -eq 0 ]]; then + echo 'ERROR: Missing output value aks_key_vault_secret_provider_client_id' 1>&2 + exit 6 +fi + +#get information from Application Insights +APP_INSIGHTS_KEY=$(az resource show -g "${RESOURCE_GROUP}" -n "${APP_INSIGHTS}" --resource-type "microsoft.insights/components" --query properties.ConnectionString --output tsv) + +#get information from Service Bus +SERVICE_BUS_CONNECTION_STRING=$(az servicebus namespace authorization-rule keys list --resource-group "${RESOURCE_GROUP}" --namespace-name "${SERVICE_BUS_NAMESPACE}" --name RootManageSharedAccessKey --query primaryConnectionString --output tsv) + +#get information from Cosmos DB +COSMOS_DB_ENDPOINT=$(az resource show -g "${RESOURCE_GROUP}" -n "${COSMOSDB_NAME}" --resource-type "microsoft.documentdb/databaseaccounts" --query properties.documentEndpoint --output tsv) +COSMOS_DB_KEY=$(az cosmosdb keys list -g "${RESOURCE_GROUP}" -n "${COSMOSDB_NAME}" --query primaryMasterKey --output tsv) + +#create env file for cargo-processing-api +cat << EOF > "$script_dir/../../src/cargo-processing-api/.env" +APPLICATIONINSIGHTS_CONNECTION_STRING=$APP_INSIGHTS_KEY +APPLICATIONINSIGHTS_VERSION=3.4.7 + +#Service Bus Information +servicebus_connection_string=$SERVICE_BUS_CONNECTION_STRING +accelerator_queue_name=ingest-cargo + +# Operation API +operations_api_url=http://operations-api:8081/ +EOF +echo "CREATED: env file for CARGO-PROCESSING-API" + +#create helm values file for cargo-processing-api +cat << EOF > "$script_dir/../../src/cargo-processing-api/helm/env.yaml" +image: + repository: $ACR_NAME.azurecr.io/cargo-processing-api + +keyVault: + name: $KEYVAULT_NAME + tenantId: $TENANT_ID + +aksKeyVaultSecretProviderIdentityId: $AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID +EOF +echo "CREATED: helm value file for CARGO-PROCESSING-API" + + +#create env file for cargo-processing-validator +cat < "$script_dir/../../src/cargo-processing-validator/.env" +APPLICATIONINSIGHTS_CONNECTION_STRING=$APP_INSIGHTS_KEY +SERVICE_BUS_CONNECTION_STRING=$SERVICE_BUS_CONNECTION_STRING +QUEUE_NAME="ingest-cargo" +TOPIC_NAME="validated-cargo" +MAX_WAIT_TIME_IN_MS=1000 +MAX_MESSAGE_DEQUEUE_COUNT=10 +OPERATION_QUEUE_NAME="operation-state" +EOF +echo "CREATED: env file for CARGO-PROCESSING-VALIDATOR" + +#create helm values file for cargo-processing-validator +cat << EOF > "$script_dir/../../src/cargo-processing-validator/helm/env.yaml" +image: + repository: $ACR_NAME.azurecr.io/cargo-processing-validator + +keyVault: + name: $KEYVAULT_NAME + tenantId: $TENANT_ID + +aksKeyVaultSecretProviderIdentityId: $AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID +EOF +echo "CREATED: helm value file for CARGO-PROCESSING-VALIDATOR" + + +#create env file for invalid-cargo-manager +cat << EOF > "$script_dir/../../src/invalid-cargo-manager/.env" +SERVICE_BUS_CONNECTION_STR=$SERVICE_BUS_CONNECTION_STRING +SERVICE_BUS_TOPIC_NAME=validated-cargo +SERVICE_BUS_SUBSCRIPTION_NAME=invalid-cargo +SERVICE_BUS_QUEUE_NAME=operation-state +SERVICE_BUS_MAX_MESSAGE_COUNT=1 +SERVICE_BUS_MAX_WAIT_TIME=30 + +COSMOS_DB_ENDPOINT=$COSMOS_DB_ENDPOINT +COSMOS_DB_KEY=$COSMOS_DB_KEY +COSMOS_DB_DATABASE_NAME=cargo +COSMOS_DB_CONTAINER_NAME=invalid-cargo + +APPLICATIONINSIGHTS_CONNECTION_STRING=$APP_INSIGHTS_KEY +CLOUD_LOGGING_LEVEL=INFO +CONSOLE_LOGGING_LEVEL=DEBUG + +HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS=30 +HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS=60 +EOF +echo "CREATED: env file for INVALID-CARGO-MANAGER" + +#create helm values file for invalid-cargo-manager +cat << EOF > "$script_dir/../../src/invalid-cargo-manager/helm/env.yaml" +image: + repository: $ACR_NAME.azurecr.io/invalid-cargo-manager + +keyVault: + name: $KEYVAULT_NAME + tenantId: $TENANT_ID + +aksKeyVaultSecretProviderIdentityId: $AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID +EOF +echo "CREATED: helm value file for INVALID-CARGO-MANAGER" + + +#create env file for operations-api +cat << EOF > "$script_dir/../../src/operations-api/.env" +APPLICATIONINSIGHTS_CONNECTION_STRING=$APP_INSIGHTS_KEY +APPLICATIONINSIGHTS_VERSION=3.4.7 + +# Service Bus Information +SERVICEBUS_CONNECTION_STRING=$SERVICE_BUS_CONNECTION_STRING +SERVICEBUS_PREFETCH_COUNT=10 +OPERATION_STATE_QUEUE_NAME=operation-state + +# Cosmos Db Information +COSMOS_DB_ENDPOINT=$COSMOS_DB_ENDPOINT +COSMOS_DB_KEY=$COSMOS_DB_KEY +COSMOS_DB_DATABASE_NAME=cargo +COSMOS_DB_CONTAINER_NAME=invalid-cargo +EOF +echo "CREATED: env file for OPERATIONS-API" + +#create helm values file for operations-api +cat << EOF > "$script_dir/../../src/operations-api/helm/env.yaml" +image: + repository: $ACR_NAME.azurecr.io/operations-api + +keyVault: + name: $KEYVAULT_NAME + tenantId: $TENANT_ID + +aksKeyVaultSecretProviderIdentityId: $AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID +EOF +echo "CREATED: helm value file for OPERATIONS-API" + + +#create appsettings.json file for valid-cargo-manager +cat < "$script_dir/../../src/valid-cargo-manager/appsettings.json" +{ + "ApplicationInsights": { + "ConnectionString": "$APP_INSIGHTS_KEY" + }, + "ServiceBus": { + "ConnectionString": "$SERVICE_BUS_CONNECTION_STRING", + "Topic": "validated-cargo", + "Queue": "operation-state", + "Subscription": "valid-cargo", + "PrefetchCount": 100, + "MaxConcurrentCalls": 10 + }, + "CosmosDB": { + "EndpointUri": "$COSMOS_DB_ENDPOINT", + "PrimaryKey": "$COSMOS_DB_KEY", + "Database": "cargo", + "Container": "valid-cargo" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "HealthCheck": { + "TcpServer": { + "Port": 3030 + }, + "CosmosDB": { + "MaxDurationMs": 200 + }, + "ServiceBus": { + "MaxDurationMs": 200 + } + } +} +EOF +echo "CREATED: appsettings.json file for VALID-CARGO-MANAGER" + +#create helm values file for valid-cargo-manager +cat << EOF > "$script_dir/../../src/valid-cargo-manager/helm/env.yaml" +image: + repository: $ACR_NAME.azurecr.io/valid-cargo-manager + +keyVault: + name: $KEYVAULT_NAME + tenantId: $TENANT_ID + +aksKeyVaultSecretProviderIdentityId: $AKS_KEY_VAULT_SECRET_PROVIDER_CLIENT_ID +EOF +echo "CREATED: helm value file for VALID-CARGO-MANAGER" diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-bicep-infrastructure.sh b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-bicep-infrastructure.sh new file mode 100644 index 0000000..9888ec9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-bicep-infrastructure.sh @@ -0,0 +1,169 @@ +#!/bin/bash +set -e + +# +# This script generates the bicep parameters file and then uses that to deploy the infrastructure +# An output.json file is generated in the project root containing the outputs from the deployment +# The output.json format is consistent between Terraform and Bicep deployments +# + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +help() +{ + echo "" + echo "" + echo "" + echo "Command" + echo " deploy-bicep-infrastructure.sh : Will deploy all required services services." + echo "" + echo "Arguments" + echo " --username, -u : REQUIRED: Unique name to assign in all deployed services, your high school hotmail alias is a great idea!" + echo " --email-address, -e : REQUIRED: Email address for alert notifications" + echo " --location, -l : REQUIRED: Azure region to deploy to" + echo " --aks-aad-auth : OPTIONAL Enable AAD authentication for AKS" + echo "" + exit 1 +} + +SHORT=u:,l:,h +LONG=username:,email-address:,location:,aks-aad-auth,help +OPTS=$(getopt -a -n files --options $SHORT --longoptions $LONG -- "$@") + +eval set -- "$OPTS" + +USERNAME='' +LOCATION='' +EMAIL_ADDRESS='' +AKS_AAD_AUTH=false +while : +do + case "$1" in + -u | --username ) + USERNAME="$2" + shift 2 + ;; + -e | --email-address ) + EMAIL_ADDRESS="$2" + shift 2 + ;; + -l | --location ) + LOCATION="$2" + shift 2 + ;; + --aks-aad-auth ) + AKS_AAD_AUTH=true + shift 1 + ;; + -h | --help) + help + ;; + --) + shift; + break + ;; + *) + echo "Unexpected option: $1" + ;; + esac +done + +if [[ ${#USERNAME} -eq 0 ]]; then + echo 'ERROR: Missing required parameter --username | -u' 1>&2 + exit 6 +fi + +if [[ ${#EMAIL_ADDRESS} -eq 0 ]]; then + echo 'ERROR: Missing required parameter --email-address | -e' 1>&2 + exit 6 +fi + +if [[ ${#LOCATION} -eq 0 ]]; then + echo 'ERROR: Missing required parameter --location | -l' 1>&2 + exit 6 +fi + + +if [[ "$AKS_AAD_AUTH" == true ]]; then + if [[ -z "$ARM_CLIENT_ID" ]]; then + # Get the ID of the currently signed in user + current_user_object_id=$(az ad signed-in-user show --query id -o tsv) + else + # Get the ID of the service principal for ARM_CLIENT_ID + current_user_object_id=$(az ad sp show --id "$ARM_CLIENT_ID" --query id -o tsv) + fi + echo "Enabling AKS AAD authentication (current user object ID: $current_user_object_id)" +fi + +cat << EOF > "$script_dir/../bicep/azuredeploy.parameters.json" +{ + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "value": "${LOCATION}" + }, + "uniqueUserName": { + "value": "${USERNAME}" + }, + "cosmosDatabaseName": { + "value": "cargo" + }, + "cosmosContainer1Name": { + "value": "valid-cargo" + }, + "cosmosContainer2Name": { + "value": "invalid-cargo" + }, + "cosmosContainer3Name": { + "value": "operations" + }, + "serviceBusQueue1Name": { + "value": "ingest-cargo" + }, + "serviceBusQueue2Name": { + "value": "operation-state" + }, + "serviceBusTopicName": { + "value": "validated-cargo" + }, + "serviceBusSubscription1Name": { + "value": "valid-cargo" + }, + "serviceBusSubscription2Name": { + "value": "invalid-cargo" + }, + "serviceBusTopicRule1Name": { + "value": "valid" + }, + "serviceBusTopicRule2Name": { + "value": "invalid" + }, + "aksAadAuth": { + "value": $AKS_AAD_AUTH + }, + "aksAadAdminUserObjectId" : { + "value": "$current_user_object_id" + }, + "notificationEmailAddress": { + "value": "${EMAIL_ADDRESS}" + } + } +} +EOF + +echo "Bicep parameters file created" + +cd "$script_dir/../bicep/" + +deployment_name="deployment-${USERNAME}-${LOCATION}" +echo "Starting Bicep deployment ($deployment_name)" +az deployment sub create \ + --location "$LOCATION" \ + --template-file main.bicep \ + --name "$deployment_name" \ + --parameters azuredeploy.parameters.json \ + --output json \ + | jq "[.properties.outputs | to_entries | .[] | {key:.key, value: .value.value}] | from_entries" > "$script_dir/../../output.json" + +echo "Bicep deployment completed" diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-helm-charts.sh b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-helm-charts.sh new file mode 100644 index 0000000..528c54f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-helm-charts.sh @@ -0,0 +1,205 @@ +#!/bin/bash +set -e + +# +# This script expects to find an output.json in the project root with the values +# from the infrastructure deployment. +# It deploys helm charts for each service to the AKS cluster +# + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + + +function help() { + echo + echo "deploy-helm-charts.sh" + echo + echo "Deploy solution into AKS using Helm" + echo + echo -e "\t--aks-aad-auth\t(Optional)Enable AAD authentication for AKS" + echo +} + + +# Set default values here +AKS_AAD_AUTH=false + + +# Process switches: +SHORT=h +LONG=aks-aad-auth,help +OPTS=$(getopt -a -n files --options $SHORT --longoptions $LONG -- "$@") + +eval set -- "$OPTS" + +while : +do + case "$1" in + --aks-aad-auth ) + AKS_AAD_AUTH=true + shift 1 + ;; + -h | --help) + help + exit 0 + ;; + --) + shift; + break + ;; + *) + echo "Unexpected '$1'" + help + exit 1 + ;; + esac +done + + +RESOURCE_GROUP=$(jq -r '.rg_name' < "$script_dir/../../output.json") +if [[ ${#RESOURCE_GROUP} -eq 0 ]]; then + echo 'ERROR: Missing output value rg_name' 1>&2 + exit 6 +fi + +AKS_NAME=$(jq -r '.aks_name' < "$script_dir/../../output.json") +if [[ ${#AKS_NAME} -eq 0 ]]; then + echo 'ERROR: Missing output value aks_name' 1>&2 + exit 6 +fi + + +if [[ "$AKS_AAD_AUTH" == "true" ]]; then + echo "Getting Admin AKS credentials" + # Temporarily get cluster admin credentials to set up user permisions for default namespace + + # Get kubeconfig for the AKS cluster + az aks get-credentials --resource-group "$RESOURCE_GROUP" --name "$AKS_NAME" --admin --overwrite-existing + # Update the kubeconfig to use https://github.com/azure/kubelogin + kubelogin convert-kubeconfig -l azurecli + + if [[ -z "$ARM_CLIENT_ID" ]]; then + # Get the UPN of the currently signed in user + current_user_object_id=$(az ad signed-in-user show --query id -o tsv) + else + # Get the ID of the service principal for ARM_CLIENT_ID + current_user_object_id=$(az ad sp show --id "$ARM_CLIENT_ID" --query id -o tsv) + fi + + echo "Adding user-full-access role & binding" +cat < "$script_dir/../../http/.env" +SERVICE_IP=$ingress_ip +EOF +echo "CREATED: env file for http docs" + + + +#get information from Service Bus +SERVICE_BUS_NAMESPACE=$(jq -r '.sb_namespace_name' < "$script_dir/../../output.json") +if [[ ${#SERVICE_BUS_NAMESPACE} -eq 0 ]]; then + echo 'ERROR: Missing output value sb_namespace_name' 1>&2 + exit 6 +fi +SERVICE_BUS_CONNECTION_STRING=$(az servicebus namespace authorization-rule keys list --resource-group "${RESOURCE_GROUP}" --namespace-name "${SERVICE_BUS_NAMESPACE}" --name RootManageSharedAccessKey --query primaryConnectionString --output tsv) + + + +#create env file for cargo-test-scripts +cat << EOF > "$script_dir/../../src/cargo-test-scripts/.env" +SERVICEBUS_CONNECTION_STRING=$SERVICE_BUS_CONNECTION_STRING +QUEUE_NAME=ingest-cargo +TOPIC_NAME=validated-cargo +CARGO_PROCESSING_API_URL=http://$ingress_ip/cargo +OPERATIONS_API_URL=http://$ingress_ip/cargo + +EOF +echo "CREATED: env file for CARGO-TEST-SCRIPTS" diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-terraform-infrastructure.sh b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-terraform-infrastructure.sh new file mode 100644 index 0000000..b608117 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/scripts/deploy-terraform-infrastructure.sh @@ -0,0 +1,152 @@ +#!/bin/bash +set -e + +# +# This script generates the terraform.tfvars file and then uses that to deploy the infrastructure +# An output.json file is generated in the project root containing the outputs from the deployment +# The output.json format is consistent between Terraform and Bicep deployments +# + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +help() +{ + echo "" + echo "" + echo "" + echo "Command" + echo " deploy-terraform-infrastructure.sh : Will deploy all required services." + echo "" + echo "Arguments" + echo " --username, -u : REQUIRED: Unique name to assign in all deployed services, your high school hotmail alias is a great idea!" + echo " --email-address, -e : REQUIRED: Email address for alert notifications" + echo " --location, -l : REQUIRED: Azure region to deploy to" + echo " --aks-aad-auth : OPTIONAL Enable AAD authentication for AKS" + echo "" + exit 1 +} + +SHORT=u:,l:,h +LONG=username:,email-address:,location:,aks-aad-auth,help +OPTS=$(getopt -a -n files --options $SHORT --longoptions $LONG -- "$@") + +eval set -- "$OPTS" + +USERNAME='' +LOCATION='' +EMAIL_ADDRESS='' +AKS_AAD_AUTH=false +while : +do + case "$1" in + -u | --username ) + USERNAME="$2" + shift 2 + ;; + -e | --email-address ) + EMAIL_ADDRESS="$2" + shift 2 + ;; + -l | --location ) + LOCATION="$2" + shift 2 + ;; + --aks-aad-auth ) + AKS_AAD_AUTH=true + shift 1 + ;; + -h | --help) + help + ;; + --) + shift; + break + ;; + *) + echo "Unexpected option: $1" + ;; + esac +done + +if [[ ${#USERNAME} -eq 0 ]]; then + echo 'ERROR: Missing required parameter --username | -u' 1>&2 + exit 6 +fi + +if [[ ${#EMAIL_ADDRESS} -eq 0 ]]; then + echo 'ERROR: Missing required parameter --email-address | -e' 1>&2 + exit 6 +fi + +if [[ ${#LOCATION} -eq 0 ]]; then + echo 'ERROR: Missing required parameter --location | -l' 1>&2 + exit 6 +fi + +current_user_object_id="" +if [[ "$AKS_AAD_AUTH" == true ]]; then + if [[ -z "$ARM_CLIENT_ID" ]]; then + # Get the ID of the currently signed in user + current_user_object_id=$(az ad signed-in-user show --query id -o tsv) + else + # Get the ID of the service principal for ARM_CLIENT_ID + current_user_object_id=$(az ad sp show --id "$ARM_CLIENT_ID" --query id -o tsv) + fi + echo "Enabling AKS AAD authentication (current user object ID: $current_user_object_id)" +fi + +cat << EOF > "$script_dir/../terraform/terraform.tfvars" +location = "${LOCATION}" +prefix = "dev" +unique_username = "${USERNAME}" +cosmosdb_database_name = "cargo" +cosmosdb_container1_name = "valid-cargo" +cosmosdb_container2_name = "invalid-cargo" +cosmosdb_container3_name = "operations" +service_bus_queue1_name = "ingest-cargo" +service_bus_queue2_name = "operation-state" +service_bus_topic_name = "validated-cargo" +service_bus_subscription1_name = "valid-cargo" +service_bus_subscription2_name = "invalid-cargo" +service_bus_topic_rule1_name = "valid" +service_bus_topic_rule2_name = "invalid" +aks_aad_auth = ${AKS_AAD_AUTH} +aks_aad_admin_user_object_id = "${current_user_object_id}" +notification_email_address = "${EMAIL_ADDRESS}" +EOF + +echo -e "\n*** Terraform parameters file created" + +cd "$script_dir"/../terraform/ + +if [[ -n "$TERRAFORM_STATE_STORAGE_ACCOUNT_NAME" ]]; then + # init with Azure backend + echo -e "\n*** Initializing Terraform (with Azure backend: $TERRAFORM_STATE_STORAGE_ACCOUNT_NAME)" +cat > backend.tf << EOF +terraform { + backend "azurerm" {} +} +EOF + terraform init -upgrade \ + -backend-config "resource_group_name=${TERRAFORM_STATE_RESOURCE_GROUP_NAME}" \ + -backend-config "storage_account_name=${TERRAFORM_STATE_STORAGE_ACCOUNT_NAME}" \ + -backend-config "container_name=${TERRAFORM_STATE_CONTAINER_NAME}" \ + -backend-config "key=${TERRAFORM_STATE_KEY}" +else + # init with local backend + echo -e "\n*** Initializing Terraform (with local backend)" + rm -rf backend.tf + terraform init -upgrade +fi + +echo -e "\n*** Planning Terraform resources" + +terraform plan -var-file=terraform.tfvars -out=plan.out + +echo -e "\n*** Deploying Terraform resources" + +terraform apply "plan.out" + +echo -e "\n*** Gathering required outputs" + +terraform output -json | jq "[. | to_entries | .[] | {key:.key, value: .value.value}] | from_entries" > "${script_dir}/../../output.json" diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/.gitignore b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/.gitignore new file mode 100644 index 0000000..d4951f9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/.gitignore @@ -0,0 +1,5 @@ +.terraform/* +.terraform* +*.tfstate +*.tfstate.backup +backend.tf \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/main.tf new file mode 100644 index 0000000..33bb716 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/main.tf @@ -0,0 +1,171 @@ +data "azurerm_client_config" "current_config" {} + +resource "azurerm_resource_group" "rg" { + name = "rg-${var.prefix}-tf-${var.unique_username}" + location = var.location +} + +//Cosmos DB module +resource "azurecaf_name" "cosmosdb" { + name = "accl" + resource_type = "azurerm_cosmosdb_account" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +module "cosmosdb" { + source = "./modules/cosmos" + account_name = azurecaf_name.cosmosdb.result + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + cosmosdb_database_name = var.cosmosdb_database_name + cosmosdb_valid_container_name = var.cosmosdb_container1_name + cosmosdb_invalid_container_name = var.cosmosdb_container2_name + cosmosdb_operations_container_name = var.cosmosdb_container3_name + log_analytics_workspace_id = module.app_insights.log_analytics_workspace_id +} + +//ACR module +resource "azurecaf_name" "acr" { + name = "accl" + resource_type = "azurerm_container_registry" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +module "acr" { + source = "./modules/acr" + name = azurecaf_name.acr.result + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name +} + +//AKS module +resource "azurecaf_name" "aks" { + name = "accl" + resource_type = "azurerm_kubernetes_cluster" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +module "aks" { + source = "./modules/aks" + name = azurecaf_name.aks.result + prefix = var.prefix + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + acr_id = module.acr.acr_id + log_analytics_workspace_id = module.app_insights.log_analytics_workspace_id + aks_aad_auth = var.aks_aad_auth + aks_aad_admin_user_object_id = var.aks_aad_admin_user_object_id +} + +//Application Insights module +resource "azurecaf_name" "appi" { + name = "accl" + resource_type = "azurerm_application_insights" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +resource "azurecaf_name" "log" { + name = "accl" + resource_type = "azurerm_log_analytics_workspace" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +module "app_insights" { + source = "./modules/app_insights" + app_insights_name = azurecaf_name.appi.result + log_analytics_workspace_name = azurecaf_name.log.result + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name +} + +module "workbooks" { + source = "./modules/workbooks" + workspace_id = module.app_insights.log_analytics_workspace_id + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + servicebus_namespace_id = module.service_bus.servicebus_namespace_id + app_insights_id = module.app_insights.app_insights_id + key_vault_id = module.key_vault.kv_id + aks_id = module.aks.aks_id +} + +module "alerts" { + source = "./modules/alerts" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + notification_email_address = var.notification_email_address + action_group_name = "default-actiongroup" + cosmosdb_id = module.cosmosdb.cosmosdb_id + servicebus_namespace_id = module.service_bus.servicebus_namespace_id + aks_id = module.aks.aks_id + kv_id = module.key_vault.kv_id + app_insights_id = module.app_insights.app_insights_id + log_analytics_workspace_id = module.app_insights.log_analytics_workspace_id +} + +//Service Bus module +resource "azurecaf_name" "service_bus" { + name = "accl" + resource_type = "azurerm_servicebus_namespace" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +module "service_bus" { + source = "./modules/service_bus" + services_bus_namespace_name = azurecaf_name.service_bus.result + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + log_analytics_workspace_id = module.app_insights.log_analytics_workspace_id + service_bus_queue1_name = var.service_bus_queue1_name + service_bus_queue2_name = var.service_bus_queue2_name + service_bus_topic_name = var.service_bus_topic_name + service_bus_valid_subscription = var.service_bus_subscription1_name + service_bus_invalid_subscription = var.service_bus_subscription2_name + service_bus_valid_rule = var.service_bus_topic_rule1_name + service_bus_invalid_rule = var.service_bus_topic_rule2_name +} + +//Key Vault module +resource "azurecaf_name" "kv_compute" { + name = "accl" + resource_type = "azurerm_key_vault" + prefixes = [var.prefix] + suffixes = [azurerm_resource_group.rg.location] + random_length = 3 + clean_input = true +} + +module "key_vault" { + source = "./modules/keyvault" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + kev_vault_name = azurecaf_name.kv_compute.result + log_analytics_workspace_id = module.app_insights.log_analytics_workspace_id + aks_key_vault_secret_provider_object_id = module.aks.aks_key_vault_secret_provider_object_id + key_vault_secrets = tomap( + { + "AppInsightsConnectionString" = module.app_insights.connection_string + "ServiceBusConnectionString" = module.service_bus.connection_string + "CosmosDBEndpoint" = module.cosmosdb.cosmosdb_endpoint + "CosmosDBKey" = module.cosmosdb.cosmosdb_key + } + ) +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/main.tf new file mode 100644 index 0000000..fbfd094 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/main.tf @@ -0,0 +1,7 @@ +resource "azurerm_container_registry" "acr" { + name = var.name + resource_group_name = var.resource_group_name + location = var.location + sku = "Standard" + admin_enabled = false +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/outputs.tf new file mode 100644 index 0000000..492dc93 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/outputs.tf @@ -0,0 +1,8 @@ +output "acr_id" { + value = azurerm_container_registry.acr.id + sensitive = true +} + +output "acr_name" { + value = azurerm_container_registry.acr.name +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/variables.tf new file mode 100644 index 0000000..c80de96 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/acr/variables.tf @@ -0,0 +1,14 @@ +variable "name" { + type = string + description = "resource name" +} + +variable "location" { + type = string + description = "The Azure region in which ACR should be provisioned" +} + +variable "resource_group_name" { + type = string + description = "The Azure Resource Group where the ACR should be provisioned" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/main.tf new file mode 100644 index 0000000..3949a23 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/main.tf @@ -0,0 +1,63 @@ +data "azurerm_client_config" "current_config" {} + +resource "azurerm_kubernetes_cluster" "aks" { + name = var.name + location = var.location + resource_group_name = var.resource_group_name + dns_prefix = var.kubernetes_dns_prefix + private_cluster_enabled = false + + + default_node_pool { + name = "agentpool" + min_count = 1 + max_count = var.kubernetes_node_count + enable_auto_scaling = true + type = "VirtualMachineScaleSets" + vm_size = var.kubernetes_vm_size + os_disk_size_gb = var.kubernetes_vm_disk_size + } + + // Use dynamic to conditionally set AAD auth block + dynamic "azure_active_directory_role_based_access_control" { + for_each = var.aks_aad_auth ? [1] : [] + content { + managed = true + tenant_id = data.azurerm_client_config.current_config.tenant_id + azure_rbac_enabled = true + } + } + + identity { + type = "SystemAssigned" + } + + key_vault_secrets_provider { + secret_rotation_enabled = true + secret_rotation_interval = "2m" + } + + oms_agent { + log_analytics_workspace_id = var.log_analytics_workspace_id + } +} + +resource "azurerm_role_assignment" "acrpull_role" { + scope = var.acr_id + role_definition_name = "AcrPull" + principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id + skip_service_principal_aad_check = true +} + +resource "azurerm_role_assignment" "aks_admin_role" { + count = var.aks_aad_auth ? 1 : 0 + scope = azurerm_kubernetes_cluster.aks.id + role_definition_name = "Azure Kubernetes Service Cluster Admin Role" + principal_id = var.aks_aad_admin_user_object_id +} +resource "azurerm_role_assignment" "aks_user_role" { + count = var.aks_aad_auth ? 1 : 0 + scope = azurerm_kubernetes_cluster.aks.id + role_definition_name = "Azure Kubernetes Service Cluster User Role" + principal_id = var.aks_aad_admin_user_object_id +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/outputs.tf new file mode 100644 index 0000000..594c2a4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/outputs.tf @@ -0,0 +1,17 @@ +output "aks_name" { + value = azurerm_kubernetes_cluster.aks.name +} + +output "aks_id" { + value = azurerm_kubernetes_cluster.aks.id +} + +output "aks_key_vault_secret_provider_client_id" { + value = azurerm_kubernetes_cluster.aks.key_vault_secrets_provider[0].secret_identity[0].client_id + sensitive = true +} + +output "aks_key_vault_secret_provider_object_id" { + value = azurerm_kubernetes_cluster.aks.key_vault_secrets_provider[0].secret_identity[0].object_id + sensitive = true +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/variables.tf new file mode 100644 index 0000000..15bf9af --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/aks/variables.tf @@ -0,0 +1,65 @@ +variable "name" { + type = string + description = "The AKS resource name" +} + +variable "location" { + type = string + description = "The Azure region in which AKS should be provisioned" +} + +variable "resource_group_name" { + type = string + description = "The Azure Resource Group where the AKS should be provisioned" +} + +variable "prefix" { + type = string + description = "Name prefix" +} + +variable "kubernetes_dns_prefix" { + type = string + description = "AKS DNS prefix" + default = "aks" +} + +variable "kubernetes_node_count" { + type = number + description = "The agent count" + default = 3 +} + +variable "kubernetes_vm_size" { + type = string + description = "Azure Kubernetes Cluster VM Size" + default = "Standard_D2s_v3" +} + +variable "kubernetes_vm_disk_size" { + type = string + description = "Azure Kubernetes Cluster VM Disk Size" + default = "30" +} + +variable "log_analytics_workspace_id" { + type = string + description = "The ID of the Log Analytics Workspace related to the cluster." +} + +variable "acr_id" { + type = string + description = "Id from ACR to get acrPull role assignment" +} + +variable "aks_aad_auth" { + type = bool + description = "Configure Azure Active Directory authentication for Kubernetes cluster" + default = false +} + +variable "aks_aad_admin_user_object_id" { + type = string + description = "Object ID of the AAD user to be added as an admin to the AKS cluster" + default = "" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/main.tf new file mode 100644 index 0000000..15003ae --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/main.tf @@ -0,0 +1,975 @@ +resource "azurerm_monitor_action_group" "default" { + name = var.action_group_name + resource_group_name = var.resource_group_name + short_name = length(var.action_group_name) <= 12 ? var.action_group_name : substr(var.action_group_name, 0, 12) + + email_receiver { + name = "email-receiver" + email_address = var.notification_email_address + use_common_alert_schema = false + } +} + +resource "azurerm_monitor_metric_alert" "cosmos_rus" { + name = "cosmos_rus" + resource_group_name = var.resource_group_name + scopes = [var.cosmosdb_id] + severity = 1 + description = "Alert when RUs exceed 400." + enabled = false + frequency = "PT1M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.DocumentDB/databaseAccounts" + metric_name = "TotalRequestUnits" + aggregation = "Total" + operator = "GreaterThan" + threshold = 400 + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "cosmos_invalid_cargo" { + name = "cosmos_invalid_cargo" + resource_group_name = var.resource_group_name + scopes = [var.cosmosdb_id] + severity = 3 + description = "Alert when more than 10 documents have been saved to the invalid-cargo container." + enabled = false + frequency = "PT1M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.DocumentDB/databaseAccounts" + metric_name = "DocumentCount" + aggregation = "Total" + operator = "GreaterThan" + threshold = 10 + dimension { + name = "CollectionName" + operator = "Include" + values = ["invalid_cargo"] + } + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "service_bus_abandoned_messages" { + name = "service_bus_abandoned_messages" + resource_group_name = var.resource_group_name + scopes = [var.servicebus_namespace_id] + severity = 2 + description = "Alert when a Service Bus entity has abandoned more than 10 messages." + enabled = false + frequency = "PT1M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.ServiceBus/namespaces" + metric_name = "AbandonMessage" + aggregation = "Total" + operator = "GreaterThan" + threshold = 10 + dimension { + name = "EntityName" + operator = "Include" + values = ["*"] + } + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "service_bus_dead_lettered_messages" { + name = "service_bus_dead_lettered_messages" + resource_group_name = var.resource_group_name + scopes = [var.servicebus_namespace_id] + severity = 2 + description = "Alert when a Service Bus entity has dead-lettered more than 10 messages." + enabled = false + frequency = "PT1M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.ServiceBus/namespaces" + metric_name = "DeadletteredMessages" + aggregation = "Average" + operator = "GreaterThan" + threshold = 10 + dimension { + name = "EntityName" + operator = "Include" + values = ["*"] + } + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "service_bus_throttled_requests" { + name = "service_bus_throttled_requests" + resource_group_name = var.resource_group_name + scopes = [var.servicebus_namespace_id] + severity = 2 + description = "Alert when a Service Bus entity has throttled more than 10 requests." + enabled = false + frequency = "PT1M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.ServiceBus/namespaces" + metric_name = "ThrottledRequests" + aggregation = "Total" + operator = "GreaterThan" + threshold = 10 + dimension { + name = "EntityName" + operator = "Include" + values = ["*"] + } + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "aks_cpu_percentage" { + name = "aks_cpu_percentage" + resource_group_name = var.resource_group_name + scopes = [var.aks_id] + severity = 2 + description = "Alert when Node CPU percentage exceeds 80." + enabled = false + frequency = "PT5M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.ContainerService/managedClusters" + metric_name = "node_cpu_usage_percentage" + aggregation = "Average" + operator = "GreaterThan" + threshold = 80 + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "aks_memory_percentage" { + name = "aks_memory_percentage" + resource_group_name = var.resource_group_name + scopes = [var.aks_id] + severity = 2 + description = "Alert when Node memory working set percentage exceeds 80." + enabled = false + frequency = "PT5M" + window_size = "PT5M" + + criteria { + metric_namespace = "Microsoft.ContainerService/managedClusters" + metric_name = "node_memory_working_set_percentage" + aggregation = "Average" + operator = "GreaterThan" + threshold = 80 + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +resource "azurerm_monitor_metric_alert" "key_vault_saturation_rate" { + name = "key_vault_saturation_rate" + resource_group_name = var.resource_group_name + scopes = [var.kv_id] + severity = 3 + description = "Alert when Key Vault saturation falls outside the range of a dynamic threshold." + enabled = false + frequency = "PT5M" + window_size = "PT5M" + + dynamic_criteria { + metric_namespace = "Microsoft.KeyVault/vaults" + metric_name = "SaturationShoebox" + aggregation = "Average" + operator = "GreaterOrLessThan" + alert_sensitivity = "Medium" + evaluation_total_count = 4 + evaluation_failure_count = 4 + } + + action { + action_group_id = azurerm_monitor_action_group.default.id + } +} + +# Tenant specific issues prevent deployment of custom metric alert +# +# resource "azurerm_monitor_metric_alert" "product_qty_scheduled_for_destination_port" { +# name = "product_qty_scheduled_for_destination_port" +# resource_group_name = var.resource_group_name +# scopes = [var.app_insights_id] +# severity = 3 +# description = "Alert when a single port/destination receives more than quantity 1000 of a given product." +# enabled = false +# frequency = "PT1M" +# window_size = "PT1M" + +# criteria { +# metric_namespace = "azure.applicationinsights" +# metric_name = "port_product_qty" +# aggregation = "Total" +# operator = "GreaterThan" +# threshold = 1000 +# skip_metric_validation = true + +# dimension { +# name = "destination" +# operator = "Include" +# values = ["*"] +# } + +# dimension { +# name = "product" +# operator = "Include" +# values = ["*"] +# } +# } + +# action { +# action_group_id = azurerm_monitor_action_group.default.id +# } +# } + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "microservice_exceptions" { + name = "microservice_exceptions" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when a microservice throws more than 5 exceptions." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + exceptions + QUERY + time_aggregation_method = "Count" + threshold = 5 + operator = "GreaterThan" + + dimension { + name = "cloud_RoleName" + operator = "Include" + values = ["*"] + } + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "cargo_processing_api_requests" { + name = "cargo_processing_api_requests" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 3 + description = "Alert when the cargo-processing-api microservice is not receiving any requests." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "cargo-processing-api" and (name == "POST /cargo/" or name == "PUT /cargo/{cargoId}") + QUERY + time_aggregation_method = "Count" + # usage of the "Equal" operator is currently blocked + # LessThan 1 should suffice as a workaround for Equal 0 until the bug is fixed is released in 3.36.0 + # please see discussion at https://github.com/hashicorp/terraform-provider-azurerm/issues/19581 + threshold = 1 + operator = "LessThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "e2e_average_duration" { + name = "e2e_average_duration" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the end to end average request duration exceeds 5 seconds." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + let cargo_processing_api = requests + | where cloud_RoleName == "cargo-processing-api" and (name == "POST /cargo/" or name == "PUT /cargo/{cargoId}") + | project-rename ingest_timestamp = timestamp + | project ingest_timestamp, operation_Id; + let operation_api_succeeded = requests + | where cloud_RoleName == "operations-api" and name == "ServiceBus.process" and customDimensions["operation-state"] == "Succeeded" + | extend operation_api_completed = timestamp + (duration*1ms) + | project operation_Id, operation_api_completed; + cargo_processing_api + | join kind=inner operation_api_succeeded on $left.operation_Id == $right.operation_Id + | extend end_to_end_Duration_ms = (operation_api_completed - ingest_timestamp) /1ms + | summarize avg(end_to_end_Duration_ms) + QUERY + time_aggregation_method = "Average" + threshold = 5000 + operator = "GreaterThan" + metric_measure_column = "avg_end_to_end_Duration_ms" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "cargo_processing_api_average_duration" { + name = "cargo_processing_api_average_duration" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the cargo-processing-api microservice average request duration exceeds 2 seconds." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "cargo-processing-api" and (name == "POST /cargo/" or name == "PUT /cargo/{cargoId}") + | summarize avg(duration) + QUERY + time_aggregation_method = "Average" + threshold = 2000 + operator = "GreaterThan" + metric_measure_column = "avg_duration" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "cargo_processing_validator_average_duration" { + name = "cargo_processing_validator_average_duration" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the cargo-processing-validator microservice average request duration exceeds 2 seconds." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "cargo-processing-validator" and (name == "ServiceBus.ProcessMessage" or name == "ServiceBusQueue.ProcessMessage") + | summarize avg(duration) + QUERY + time_aggregation_method = "Average" + threshold = 2000 + operator = "GreaterThan" + metric_measure_column = "avg_duration" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "valid_cargo_manager_average_duration" { + name = "valid_cargo_manager_average_duration" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the valid-cargo-manager microservice average request duration exceeds 2 seconds." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "valid-cargo-manager" and name == "ServiceBusTopic.ProcessMessage" + | summarize avg(duration) + QUERY + time_aggregation_method = "Average" + threshold = 2000 + operator = "GreaterThan" + metric_measure_column = "avg_duration" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "invalid_cargo_manager_average_duration" { + name = "invalid_cargo_manager_average_duration" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the invalid-cargo-manager microservice average request duration exceeds 2 seconds." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "invalid-cargo-manager" and name == "ServiceBusTopic.ProcessMessage" + | summarize avg(duration) + QUERY + time_aggregation_method = "Average" + threshold = 2000 + operator = "GreaterThan" + metric_measure_column = "avg_duration" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "operations_api_average_duration" { + name = "operations_api_average_duration" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the operations-api microservice average request duration exceeds 1 second." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "operations-api" and name == "ServiceBus.process" + | summarize avg(duration) + QUERY + time_aggregation_method = "Average" + threshold = 1000 + operator = "GreaterThan" + metric_measure_column = "avg_duration" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "log_analytics_data_ingestion_daily_cap" { + name = "log_analytics_data_ingestion_daily_cap" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.log_analytics_workspace_id] + severity = 2 + description = "Alert when the Log Analytics data ingestion daily cap has been reached." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + _LogOperation + | where Category == "Ingestion" + | where Operation has "Data collection" + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + resource_id_column = "_ResourceId" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "log_analytics_data_ingestion_rate" { + name = "log_analytics_data_ingestion_rate" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.log_analytics_workspace_id] + severity = 2 + description = "Alert when the Log Analytics max data ingestion rate has been reached." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + _LogOperation + | where Category == "Ingestion" + | where Operation has "Ingestion rate" + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + resource_id_column = "_ResourceId" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "log_analytics_operational_issues" { + name = "log_analytics_operational_issues" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "P1D" + window_duration = "P1D" + scopes = [var.log_analytics_workspace_id] + severity = 3 + description = "Alert when the Log Analytics workspace has an operational issue." + enabled = false + # tf stateful rules can not run in a frequency greater than 12 hours, auto_mitigation_enabled must be false + auto_mitigation_enabled = false + + criteria { + query = <<-QUERY + _LogOperation + | where Level == "Warning" + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + resource_id_column = "_ResourceId" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "cargo_processing_api_health_check_failure" { + name = "cargo_processing_api_health_check_failure" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when a cargo-processing-api microservice health check fails." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "cargo-processing-api" and name == "GET /actuator/health" and success == "False" + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "cargo_processing_api_health_check_not_reporting" { + name = "cargo_processing_api_health_check_not_reporting" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the cargo-processing-api microservice health check is not reporting." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "cargo-processing-api" and name == "GET /actuator/health" + QUERY + time_aggregation_method = "Count" + # usage of the "Equal" operator is currently blocked + # LessThan 1 should suffice as a workaround for Equal 0 until the bug is fixed is released in 3.36.0 + # please see discussion at https://github.com/hashicorp/terraform-provider-azurerm/issues/19581 + threshold = 1 + operator = "LessThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "valid_cargo_manager_health_check_failure" { + name = "valid_cargo_manager_health_check_failure" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT30M" + window_duration = "PT30M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when a valid-cargo-manager microservice health check fails." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + customMetrics + | where cloud_RoleName == "valid-cargo-manager" and name == "HeartbeatState" and value != 2 + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "valid_cargo_manager_health_check_not_reporting" { + name = "valid_cargo_manager_health_check_not_reporting" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT30M" + window_duration = "PT30M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the valid-cargo-manager microservice health check is not reporting." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + customMetrics + | where cloud_RoleName == "valid-cargo-manager" and name == "HeartbeatState" + QUERY + time_aggregation_method = "Count" + # usage of the "Equal" operator is currently blocked + # LessThan 1 should suffice as a workaround for Equal 0 until the bug is fixed is released in 3.36.0 + # please see discussion at https://github.com/hashicorp/terraform-provider-azurerm/issues/19581 + threshold = 1 + operator = "LessThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "invalid_cargo_manager_health_check_failure" { + name = "invalid_cargo_manager_health_check_failure" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when an invalid-cargo-manager microservice health check fails." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + traces + | where cloud_RoleName == "invalid-cargo-manager" and message contains "peeked at messages for over" + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "invalid_cargo_manager_health_check_not_reporting" { + name = "invalid_cargo_manager_health_check_not_reporting" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the invalid-cargo-manager microservice health check is not reporting." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + traces + | where cloud_RoleName == "invalid-cargo-manager" and (message contains "since last peek" or message contains "peeked at messages for over") + QUERY + time_aggregation_method = "Count" + # usage of the "Equal" operator is currently blocked + # LessThan 1 should suffice as a workaround for Equal 0 until the bug is fixed is released in 3.36.0 is released in 3.36.0 + # please see discussion at https://github.com/hashicorp/terraform-provider-azurerm/issues/19581 + threshold = 1 + operator = "LessThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "operations_api_health_check_failure" { + name = "operations_api_health_check_failure" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when an operations-api microservice health check fails." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "operations-api" and name == "GET /actuator/health" and success == "False" + QUERY + time_aggregation_method = "Count" + threshold = 0 + operator = "GreaterThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "operations_api_health_check_not_reporting" { + name = "operations_api_health_check_not_reporting" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.app_insights_id] + severity = 1 + description = "Alert when the operations-api microservice health check is not reporting." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + requests + | where cloud_RoleName == "operations-api" and name == "GET /actuator/health" + QUERY + time_aggregation_method = "Count" + # usage of the "Equal" operator is currently blocked + # LessThan 1 should suffice as a workaround for Equal 0 until the bug is fixed is released in 3.36.0 + # please see discussion at https://github.com/hashicorp/terraform-provider-azurerm/issues/19581 + threshold = 1 + operator = "LessThan" + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} + +resource "azurerm_monitor_scheduled_query_rules_alert_v2" "aks_pod_restarts" { + name = "aks_pod_restarts" + resource_group_name = var.resource_group_name + location = var.location + + evaluation_frequency = "PT5M" + window_duration = "PT5M" + scopes = [var.log_analytics_workspace_id] + severity = 1 + description = "Alert when a microservice restarts more than once." + enabled = false + auto_mitigation_enabled = true + + criteria { + query = <<-QUERY + KubePodInventory + | summarize numRestarts = sum(PodRestartCount) by ServiceName + QUERY + time_aggregation_method = "Total" + threshold = 1 + operator = "GreaterThan" + metric_measure_column = "numRestarts" + + dimension { + name = "ServiceName" + operator = "Include" + values = [ + "cargo-processing-api", + "cargo-processing-validator", + "invalid-cargo-manager", + "operations-api", + "valid-cargo-manager" + ] + } + + failing_periods { + minimum_failing_periods_to_trigger_alert = 1 + number_of_evaluation_periods = 1 + } + } + + action { + action_groups = [azurerm_monitor_action_group.default.id] + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/variables.tf new file mode 100644 index 0000000..9b5b153 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/alerts/variables.tf @@ -0,0 +1,49 @@ +variable "location" { + type = string + description = "Location for the Azure Workbook" +} + +variable "resource_group_name" { + type = string + description = "Resource group for the Azure Workbook" +} + +variable "action_group_name" { + type = string + description = "Name for the default action group" +} + +variable "notification_email_address" { + type = string + description = "Email address for alert notifications" +} + +variable "cosmosdb_id" { + type = string + description = "Id for monitored Cosmos DB" +} + +variable "servicebus_namespace_id" { + type = string + description = "Id for monitored Service Bus namespace" +} + +variable "aks_id" { + type = string + description = "Id for monitored AKS cluster" +} + +variable "kv_id" { + type = string + description = "Id for monitored Key Vault" +} + +variable "app_insights_id" { + type = string + description = "Id for monitored Application Insights" +} + +variable "log_analytics_workspace_id" { + type = string + description = "Id for monitored Log Analytics workspace" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/main.tf new file mode 100644 index 0000000..69b7e97 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/main.tf @@ -0,0 +1,28 @@ +resource "azurerm_application_insights" "app_insights" { + name = var.app_insights_name + location = var.location + resource_group_name = var.resource_group_name + application_type = var.application_type + workspace_id = azurerm_log_analytics_workspace.log_analytics.id +} + +resource "azurerm_log_analytics_workspace" "log_analytics" { + name = var.log_analytics_workspace_name + location = var.location + resource_group_name = var.resource_group_name + sku = var.log_analytics_workspace_sku + retention_in_days = 31 +} + +resource "azurerm_log_analytics_solution" "log_solution" { + solution_name = "ContainerInsights" + location = azurerm_log_analytics_workspace.log_analytics.location + resource_group_name = azurerm_log_analytics_workspace.log_analytics.resource_group_name + workspace_resource_id = azurerm_log_analytics_workspace.log_analytics.id + workspace_name = azurerm_log_analytics_workspace.log_analytics.name + + plan { + publisher = "Microsoft" + product = "OMSGallery/ContainerInsights" + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/outputs.tf new file mode 100644 index 0000000..5516376 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/outputs.tf @@ -0,0 +1,16 @@ +output "name" { + value = azurerm_application_insights.app_insights.name +} + +output "connection_string" { + value = azurerm_application_insights.app_insights.connection_string + sensitive = true +} + +output "log_analytics_workspace_id" { + value = azurerm_log_analytics_workspace.log_analytics.id +} + +output "app_insights_id" { + value = azurerm_application_insights.app_insights.id +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/variables.tf new file mode 100644 index 0000000..47dfbdb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/app_insights/variables.tf @@ -0,0 +1,31 @@ +variable "app_insights_name" { + type = string + description = "The name of the Application Insights resource" +} + +variable "location" { + type = string + description = "The Azure region in which AppInsights should be provisioned" +} + +variable "resource_group_name" { + type = string + description = "The Azure Resource Group where the AppInsights should be provisioned" +} + +variable "application_type" { + type = string + description = "The kind of application that will be sending the telemetry" + default = "web" +} + +variable "log_analytics_workspace_name" { + type = string + description = "The resource name for log analytics" +} + +variable "log_analytics_workspace_sku" { + type = string + description = "Specifies the SKU of the Log Analytics Workspace." + default = "PerGB2018" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/main.tf new file mode 100644 index 0000000..a1be6ba --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/main.tf @@ -0,0 +1,151 @@ +resource "azurerm_cosmosdb_account" "account" { + name = var.account_name + location = var.location + resource_group_name = var.resource_group_name + offer_type = "Standard" + kind = "GlobalDocumentDB" + enable_automatic_failover = true + + + consistency_policy { + consistency_level = "Session" + max_interval_in_seconds = 400 + } + + geo_location { + location = var.location + failover_priority = 0 + } +} + +resource "azurerm_cosmosdb_sql_database" "db" { + name = var.cosmosdb_database_name + resource_group_name = azurerm_cosmosdb_account.account.resource_group_name + account_name = azurerm_cosmosdb_account.account.name +} + +resource "azurerm_cosmosdb_sql_container" "valid_container" { + name = var.cosmosdb_valid_container_name + resource_group_name = azurerm_cosmosdb_account.account.resource_group_name + account_name = azurerm_cosmosdb_account.account.name + database_name = azurerm_cosmosdb_sql_database.db.name + partition_key_path = "/id" +} + +resource "azurerm_cosmosdb_sql_container" "invalid_container" { + name = var.cosmosdb_invalid_container_name + resource_group_name = azurerm_cosmosdb_account.account.resource_group_name + account_name = azurerm_cosmosdb_account.account.name + database_name = azurerm_cosmosdb_sql_database.db.name + partition_key_path = "/id" +} + +resource "azurerm_cosmosdb_sql_container" "operations_container" { + name = var.cosmosdb_operations_container_name + resource_group_name = azurerm_cosmosdb_account.account.resource_group_name + account_name = azurerm_cosmosdb_account.account.name + database_name = azurerm_cosmosdb_sql_database.db.name + partition_key_path = "/id" +} + + + +resource "azurerm_monitor_diagnostic_setting" "diagnostic_settings" { + name = var.cosmos_db_diagnostic_settings_name + target_resource_id = azurerm_cosmosdb_account.account.id + log_analytics_workspace_id = var.log_analytics_workspace_id + log_analytics_destination_type = "AzureDiagnostics" + + /* + category groups are still not allowed so we need to set all fields one by one + reference: https://github.com/hashicorp/terraform-provider-azurerm/issues/17349 + supported log categories per resource can be found here: + https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/resource-logs-categories + */ + + log { + category = "DataPlaneRequests" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "QueryRuntimeStatistics" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "PartitionKeyStatistics" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "PartitionKeyRUConsumption" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "ControlPlaneRequests" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "CassandraRequests" + enabled = false + + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "GremlinRequests" + enabled = false + + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "MongoRequests" + enabled = false + + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "TableApiRequests" + enabled = false + + retention_policy { + days = 0 + enabled = false + } + } + + metric { + category = "Requests" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/outputs.tf new file mode 100644 index 0000000..38b080c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/outputs.tf @@ -0,0 +1,17 @@ +output "name" { + value = azurerm_cosmosdb_account.account.name +} + +output "cosmosdb_id" { + value = azurerm_cosmosdb_account.account.id +} + +output "cosmosdb_endpoint" { + value = azurerm_cosmosdb_account.account.endpoint +} + +output "cosmosdb_key" { + value = azurerm_cosmosdb_account.account.primary_key + sensitive = true +} + diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/variables.tf new file mode 100644 index 0000000..3704ed2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/cosmos/variables.tf @@ -0,0 +1,41 @@ +variable "account_name" { + description = "CosmosDB account name" +} + +variable "location" { + type = string + description = "The Azure region in which CosmosDB should be provisioned" +} + +variable "resource_group_name" { + type = string + description = "The Azure Resource Group where the CosmosDB should be provisioned" +} + +variable "cosmosdb_database_name" { + type = string + description = "Name for the Cosmos DB SQL database" +} + +variable "cosmosdb_valid_container_name" { + description = "Name for the Cosmos DB SQL container that stores valid cargo" +} + +variable "cosmosdb_invalid_container_name" { + description = "Name for the Cosmos DB SQL container that stores invalid cargo" +} + +variable "cosmosdb_operations_container_name" { + description = "Name for the Cosmos DB SQL container that stores operations" +} + +variable "cosmos_db_diagnostic_settings_name" { + type = string + description = "Name for the diagnostic settings" + default = "cosmosDbDiagnostics" +} + +variable "log_analytics_workspace_id" { + type = string + description = "Id for the targeted log analytics workspace" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/main.tf new file mode 100644 index 0000000..44b3734 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/main.tf @@ -0,0 +1,97 @@ +data "azurerm_client_config" "current_config" {} + +resource "azurerm_key_vault" "akv" { + name = var.kev_vault_name + location = var.location + resource_group_name = var.resource_group_name + tenant_id = data.azurerm_client_config.current_config.tenant_id + sku_name = "standard" +} + +resource "azurerm_key_vault_access_policy" "admin" { + key_vault_id = azurerm_key_vault.akv.id + tenant_id = data.azurerm_client_config.current_config.tenant_id + object_id = data.azurerm_client_config.current_config.object_id + + key_permissions = [ + "Create", + "Get", + "List", + "Delete" + ] + + secret_permissions = [ + "List", + "Set", + "Get", + "Delete", + "Purge", + "Recover", + "Backup", + "Restore" + ] +} + +resource "azurerm_key_vault_access_policy" "aks" { + key_vault_id = azurerm_key_vault.akv.id + tenant_id = data.azurerm_client_config.current_config.tenant_id + object_id = var.aks_key_vault_secret_provider_object_id + + secret_permissions = [ + "Get" + ] +} + +resource "azurerm_key_vault_secret" "akvSecret" { + for_each = var.key_vault_secrets + + name = each.key + value = each.value + key_vault_id = azurerm_key_vault.akv.id + content_type = "text/plain" + expiration_date = var.secrets_expiration_date + + # explicitly depend on access policy so destroy works + depends_on = [ + azurerm_key_vault_access_policy.admin + ] +} + +resource "azurerm_monitor_diagnostic_setting" "diagnostic_settings" { + name = var.key_vault_diagnostic_settings_name + target_resource_id = azurerm_key_vault.akv.id + log_analytics_workspace_id = var.log_analytics_workspace_id + + /* + category groups are still not allowed so we need to set all fields one by one + reference: https://github.com/hashicorp/terraform-provider-azurerm/issues/17349 + supported log categories per resource can be found here: + https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/resource-logs-categories + */ + + log { + category = "AuditEvent" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "AzurePolicyEvaluationDetails" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + + metric { + category = "AllMetrics" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/outputs.tf new file mode 100644 index 0000000..c655101 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/outputs.tf @@ -0,0 +1,7 @@ +output "kv_name" { + value = azurerm_key_vault.akv.name +} + +output "kv_id" { + value = azurerm_key_vault.akv.id +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/variables.tf new file mode 100644 index 0000000..82d1e10 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/keyvault/variables.tf @@ -0,0 +1,41 @@ +variable "kev_vault_name" { + type = string + description = "Name of the Key Vault instance" +} + +variable "location" { + type = string + description = "The Azure region in which Key Vault should be provisioned" +} + +variable "resource_group_name" { + type = string + description = "The Azure Resource Group where the Key Vault should be provisioned" +} + +variable "key_vault_secrets" { + type = map(string) + description = "Map name/value of secrets for the AKV." +} + +variable "secrets_expiration_date" { + type = string + description = "Secrets expiration date." + default = "2022-12-30T20:00:00Z" +} + +variable "key_vault_diagnostic_settings_name" { + type = string + description = "Name for the diagnostic settings" + default = "keyVaultDiagnostics" +} + +variable "log_analytics_workspace_id" { + type = string + description = "Id for the targeted log analytics workspace" +} + +variable "aks_key_vault_secret_provider_object_id" { + type = string + description = "The Object ID of the user-defined Managed Identity used by the AKS Secret Provider" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/main.tf new file mode 100644 index 0000000..cab4c85 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/main.tf @@ -0,0 +1,103 @@ +resource "azurerm_servicebus_namespace" "bus_namespace" { + name = var.services_bus_namespace_name + location = var.location + resource_group_name = var.resource_group_name + capacity = var.service_bus_capacity + sku = var.service_bus_sku +} + +resource "azurerm_servicebus_queue" "bus_queue1" { + name = var.service_bus_queue1_name + namespace_id = azurerm_servicebus_namespace.bus_namespace.id +} + +resource "azurerm_servicebus_queue" "bus_queue2" { + name = var.service_bus_queue2_name + namespace_id = azurerm_servicebus_namespace.bus_namespace.id +} + +resource "azurerm_servicebus_topic" "validation_topic" { + name = var.service_bus_topic_name + namespace_id = azurerm_servicebus_namespace.bus_namespace.id +} + +resource "azurerm_servicebus_subscription" "valid_subscription" { + name = var.service_bus_valid_subscription + topic_id = azurerm_servicebus_topic.validation_topic.id + max_delivery_count = 1 +} + +resource "azurerm_servicebus_subscription" "invalid_subscription" { + name = var.service_bus_invalid_subscription + topic_id = azurerm_servicebus_topic.validation_topic.id + max_delivery_count = 1 +} + +resource "azurerm_servicebus_subscription_rule" "valid_rule" { + name = var.service_bus_valid_rule + subscription_id = azurerm_servicebus_subscription.valid_subscription.id + filter_type = "SqlFilter" + sql_filter = "valid = True" +} + +resource "azurerm_servicebus_subscription_rule" "invalid_rule" { + name = var.service_bus_invalid_rule + subscription_id = azurerm_servicebus_subscription.invalid_subscription.id + filter_type = "SqlFilter" + sql_filter = "valid = False" +} + +resource "azurerm_monitor_diagnostic_setting" "diagnostic_settings" { + name = var.service_bus_diagnostic_settings_name + target_resource_id = azurerm_servicebus_namespace.bus_namespace.id + log_analytics_workspace_id = var.log_analytics_workspace_id + + /* + category groups are still not allowed so we need to set all fields one by one + reference: https://github.com/hashicorp/terraform-provider-azurerm/issues/17349 + supported log categories per resource can be found here: + https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/resource-logs-categories + */ + + log { + category = "OperationalLogs" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "ApplicationMetricsLogs" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "RuntimeAuditLogs" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + log { + category = "VNetAndIPFilteringLogs" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } + + metric { + category = "AllMetrics" + enabled = true + retention_policy { + days = 0 + enabled = false + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/outputs.tf new file mode 100644 index 0000000..493e693 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/outputs.tf @@ -0,0 +1,12 @@ +output "name" { + value = azurerm_servicebus_namespace.bus_namespace.name +} + +output "connection_string" { + value = azurerm_servicebus_namespace.bus_namespace.default_primary_connection_string + sensitive = true +} + +output "servicebus_namespace_id" { + value = azurerm_servicebus_namespace.bus_namespace.id +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/variables.tf new file mode 100644 index 0000000..c74a99a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/service_bus/variables.tf @@ -0,0 +1,72 @@ +variable "services_bus_namespace_name" { + type = string + description = "Name for the service bus namespace" +} + +variable "location" { + type = string + description = "Location for the service bus namespace" +} + +variable "resource_group_name" { + type = string + description = "Resource group for the service bus namespace" +} + +variable "service_bus_capacity" { + type = number + description = "Capacity for the Service Bus namespace" + default = 0 +} + +variable "service_bus_sku" { + type = string + description = "Sku for the service bus namespace" + default = "Standard" +} + +variable "service_bus_queue1_name" { + type = string + description = "Name for the first service bus queue (ingest)" +} + +variable "service_bus_queue2_name" { + type = string + description = "Name for the second service bus queue (operations)" +} + +variable "service_bus_topic_name" { + type = string + description = "Name for the service bus topic" +} + +variable "service_bus_valid_subscription" { + type = string + description = "Name for the valid subscription" +} + +variable "service_bus_invalid_subscription" { + type = string + description = "Name for the valid subscription" +} + +variable "service_bus_valid_rule" { + type = string + description = "Name for the valid rule" +} + +variable "service_bus_invalid_rule" { + type = string + description = "Name for the invalid rule" +} + +variable "service_bus_diagnostic_settings_name" { + type = string + description = "Name for the diagnostic settings" + default = "serviceBusDiagnostics" +} + +variable "log_analytics_workspace_id" { + type = string + description = "Id for the targeted log analytics workspace" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/main.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/main.tf new file mode 100644 index 0000000..7c95160 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/main.tf @@ -0,0 +1,42 @@ +resource "random_uuid" "index_uuid" { +} +resource "random_uuid" "observability_uuid" { +} +resource "random_uuid" "service_processing_uuid" { +} + +resource "azurerm_application_insights_workbook" "index" { + name = random_uuid.index_uuid.result + resource_group_name = var.resource_group_name + location = var.location + display_name = "Index" + source_id = lower(var.workspace_id) + data_json = templatefile( + "${path.module}/../../../workbooks/index.json", + { app_insights_id = var.app_insights_id, logs_workspace_id = urlencode(var.workspace_id), infrastructure_workbook_id = urlencode(azurerm_application_insights_workbook.infrastructure.id), system_workbook_id = urlencode(azurerm_application_insights_workbook.system_processing.id)} + ) +} + +resource "azurerm_application_insights_workbook" "infrastructure" { + name = random_uuid.observability_uuid.result + resource_group_name = var.resource_group_name + location = var.location + display_name = "Infrastructure" + source_id = lower(var.workspace_id) + data_json = templatefile( + "${path.module}/../../../workbooks/infrastructure.json", + { servicebus_namespace_id = var.servicebus_namespace_id, key_vault_id = var.key_vault_id, app_insights_id = var.app_insights_id, app_insights_id_url = urlencode(var.app_insights_id), aks_id = var.aks_id } + ) +} + +resource "azurerm_application_insights_workbook" "system_processing" { + name = random_uuid.service_processing_uuid.result + resource_group_name = var.resource_group_name + location = var.location + display_name = "System Processing" + source_id = lower(var.workspace_id) + data_json = templatefile( + "${path.module}/../../../workbooks/system-processing.json", + { app_insights_id = var.app_insights_id, app_insights_id_url = urlencode(var.app_insights_id) } + ) +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/variables.tf new file mode 100644 index 0000000..e27467c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/modules/workbooks/variables.tf @@ -0,0 +1,34 @@ +variable "workspace_id" { + type = string + description = "Name for the Azure Workbook" +} + +variable "location" { + type = string + description = "Location for the Azure Workbook" +} + +variable "resource_group_name" { + type = string + description = "Resource group for the Azure Workbook" +} + +variable "servicebus_namespace_id" { + type = string + description = "Id for monitored Service Bus Namespace" +} + +variable "app_insights_id" { + type = string + description = "Id for Application Insights resource" +} + +variable "key_vault_id" { + type = string + description = "Id for Key Vault resource" +} + +variable "aks_id" { + type = string + description = "Id for AKS cluster resource" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/outputs.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/outputs.tf new file mode 100644 index 0000000..62d00e1 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/outputs.tf @@ -0,0 +1,36 @@ +output "rg_name" { + value = azurerm_resource_group.rg.name +} + +output "insights_name" { + value = module.app_insights.name +} + +output "sb_namespace_name" { + value = module.service_bus.name +} + +output "cosmosdb_name" { + value = module.cosmosdb.name +} + +output "kv_name" { + value = module.key_vault.kv_name +} + +output "acr_name" { + value = module.acr.acr_name +} + +output "aks_name" { + value = module.aks.aks_name +} + +output "aks_key_vault_secret_provider_client_id" { + value = module.aks.aks_key_vault_secret_provider_client_id + sensitive = true +} + +output "tenant_id" { + value = data.azurerm_client_config.current_config.tenant_id +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/provider.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/provider.tf new file mode 100644 index 0000000..8632878 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/provider.tf @@ -0,0 +1,28 @@ +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + +terraform { + required_providers { + azuread = { + source = "hashicorp/azuread" + version = "~> 2.0.0" + } + azurerm = { + source = "hashicorp/azurerm" + version = "3.31.0" + } + azurecaf = { + source = "aztfmod/azurecaf" + version = "~> 1.2.10" + } + azapi = { + source = "azure/azapi" + version = "1.0.0" + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/sample.tfvars b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/sample.tfvars new file mode 100644 index 0000000..c24e63b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/sample.tfvars @@ -0,0 +1,15 @@ +location = "eastus" +prefix = "dev" +unique_username = "myusername" +cosmosdb_database_name = "cargo" +cosmosdb_container1_name = "valid-cargo" +cosmosdb_container2_name = "invalid-cargo" +cosmosdb_container3_name = "operations" +service_bus_queue1_name = "ingest-cargo" +service_bus_queue2_name = "operation-state" +service_bus_topic_name = "validated-cargo" +service_bus_subscription1_name = "valid-cargo" +service_bus_subscription2_name = "invalid-cargo" +service_bus_topic_rule1_name = "valid" +service_bus_topic_rule2_name = "invalid" +notification_email_address = "alias@microsoft.com" \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/variables.tf b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/variables.tf new file mode 100644 index 0000000..320b41b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/terraform/variables.tf @@ -0,0 +1,85 @@ +variable "location" { + type = string + description = "Specifies the supported Azure location (region) where the resources will be deployed" +} + +variable "prefix" { + type = string + description = "Prefix for resource names" +} + +variable "unique_username" { + type = string + description = "This value will explain who is the author of specific resources and will be reflected in every deployed tool" +} + +variable "cosmosdb_database_name" { + type = string + description = "Name for the Cosmos DB SQL database" +} + +variable "cosmosdb_container1_name" { + type = string + description = "Name for the first Cosmos DB SQL container" +} + +variable "cosmosdb_container2_name" { + type = string + description = "Name for the second Cosmos DB SQL container" +} + +variable "cosmosdb_container3_name" { + description = "Name for the third Cosmos DB SQL container" +} + +variable "service_bus_queue1_name" { + type = string + description = "Name for the first service bus queue (ingest)" +} + +variable "service_bus_queue2_name" { + type = string + description = "Name for the second service bus queue (operations)" +} + +variable "service_bus_topic_name" { + type = string + description = "Name for the Service Bus Topic" +} + +variable "service_bus_subscription1_name" { + type = string + description = "Name for the first Service Bus Subscription" +} + +variable "service_bus_subscription2_name" { + type = string + description = "Name for the second Service Bus Subscription" +} + +variable "service_bus_topic_rule1_name" { + type = string + description = "Name for the first Service Bus Subscriptions filter rulee" +} + +variable "service_bus_topic_rule2_name" { + type = string + description = "Name for the second Service Bus Subscriptions filter rulee" +} + +variable "aks_aad_auth" { + type = bool + description = "Configure Azure Active Directory authentication for Kubernetes cluster" + default = false +} + +variable "aks_aad_admin_user_object_id" { + type = string + description = "Object ID of the AAD user to be added as an admin to the AKS cluster" + default = "" +} + +variable "notification_email_address" { + type = string + description = "Email address for alert notifications" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/index.json b/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/index.json new file mode 100644 index 0000000..fb94988 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/index.json @@ -0,0 +1,218 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "# Observability and Monitoring Main Dashboard\nThis workbook has been created to provide a consolidated view of microservices observability\n\nIt contains two main sections. The first one displays the Exceptions made from any of the components involved in the whole system.\n\nSecond section can redirect you to two more workbooks that are more focused on Infrastructure or System's behaviour to get a deeper insight of data collected." + }, + "name": "mainTitleText" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Exceptions" + }, + "name": "exceptionsText" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "${app_insights_id}" + ], + "parameters": [ + { + "id": "899fa4be-a565-4534-b537-6070e46fd44e", + "version": "KqlParameterItem/1.0", + "name": "Show", + "type": 2, + "isRequired": true, + "query": "datatable(x:string, y:string)[\r\n\"['New Failure Rate (%)'], ['Existing Failure Rate (%)']\", 'New and Existing Failures',\r\n\"['New Failure Rate (%)']\", 'Only New Failures',\r\n\"['Existing Failure Rate (%)']\", 'Only Existing Failures',\r\n]", + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": "['New Failure Rate (%)']" + }, + { + "id": "38721383-ec13-430d-8229-997332f57352", + "version": "KqlParameterItem/1.0", + "name": "OverTimeRange", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + } + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 43200000 + } + }, + { + "id": "8dc31735-b2c2-40a9-94a6-2b73f69a9303", + "version": "KqlParameterItem/1.0", + "name": "UseComparisonTimeRangeOf", + "type": 1, + "isRequired": true, + "query": "let t = {OverTimeRange:seconds};\r\nlet w = case(t <= 86400, '7d', t <= 259200, '14d', t <= 120960, '28d', '60d');\r\nrange i from 1 to 1 step 1\r\n| project x = w", + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + { + "id": "3d002cfd-8dca-4015-9f77-26b62fcc2564", + "version": "KqlParameterItem/1.0", + "name": "ProblemFilter", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "exceptions\r\n| where timestamp {OverTimeRange}\r\n| summarize Count = count() by problemId\r\n| order by Count desc\r\n| project v = problemId, t = problemId, s=false\r\n| union (datatable(v:string, t:string, s:boolean)[\r\n'*', 'All Exceptions', true\r\n])\r\n", + "crossComponentResources": [ + "${app_insights_id}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "queryType": 0, + "resourceType": "microsoft.insights/components" + }, + { + "id": "a4eb0f16-861b-4587-ad9a-774db54a0cc2", + "version": "KqlParameterItem/1.0", + "name": "Source", + "type": 2, + "isRequired": true, + "query": "datatable(x:string, y:string)[\r\n'1 == 1', 'Server and Client Exceptions',\r\n'client_Type <> \"Browser\"', 'Only Server Exceptions',\r\n'client_Type == \"Browser\"', 'Only Client Exceptions',\r\n]", + "crossComponentResources": [ + "${app_insights_id}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "value": "1 == 1" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.insights/components" + }, + "name": "displayExceptionsParameters" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let startTime = {OverTimeRange:start};\r\nlet grain = {OverTimeRange:grain};\r\nlet bigWindowTimeRange = {UseComparisonTimeRangeOf};\r\nlet bigWindow = exceptions\r\n| where timestamp >= ago(bigWindowTimeRange) and timestamp < bin(startTime, grain)\r\n| where {Source}\r\n| where problemId in ({ProblemFilter}) or '*' in ({ProblemFilter})\r\n| summarize makeset(problemId, 10000);\r\nexceptions\r\n| where timestamp {OverTimeRange}\r\n| where {Source}\r\n| summarize Count = count(), Users = dcount(user_Id) by problemId\r\n| where problemId in ({ProblemFilter}) or '*' in ({ProblemFilter})\r\n| extend IsNew = iff(problemId !in (bigWindow), true, false)\r\n| where \"{Show}\" == \"['New Failure Rate (%)'], ['Existing Failure Rate (%)']\" or IsNew\r\n| order by Users desc, Count desc, problemId asc\r\n| project Problem = iff(IsNew, strcat('🔸 ', problemId), strcat('🔹 ', problemId)), ['Exception Count'] = Count, ['Users Affected'] = Users", + "size": 0, + "showAnalytics": true, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Exception Count", + "formatter": 4, + "formatOptions": { + "min": 0, + "palette": "yellow" + } + }, + { + "columnMatch": "Users Affected", + "formatter": 4, + "formatOptions": { + "min": 0, + "palette": "green" + } + } + ] + } + }, + "name": "servicesExceptionsQuery" + } + ] + }, + "name": "exceptionsGroup" + }, + { + "type": 1, + "content": { + "json": "## Performance" + }, + "name": "performanceTitleText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let cpu = performanceCounters\r\n| where name == \"% Processor Time Normalized\"\r\n| summarize CPU=avg(value) by cloud_RoleName;\r\nlet ioRate = performanceCounters\r\n| where name == \"IO Data Bytes/sec\"\r\n| summarize ioRate=avg(value) by cloud_RoleName;\r\nlet memory = performanceCounters\r\n| where name == \"Available Bytes\"\r\n| summarize Memory=avg(value) by cloud_RoleName;\r\nlet requests = requests\r\n| summarize req_Duration=avg(duration), requestsCount = count() by cloud_RoleName;\r\nlet average = dependencies\r\n| summarize average = avg(duration), dependenciesCount = count() by cloud_RoleName;\r\naverage\r\n| join kind=fullouter requests on cloud_RoleName\r\n| join kind=fullouter memory on cloud_RoleName \r\n| join kind=fullouter ioRate on cloud_RoleName\r\n| join kind=fullouter cpu on cloud_RoleName\r\n| project Service_Name=cloud_RoleName, CPU=iff(isnull(CPU), \"N/A\", strcat(bin(CPU, 0.01), \" %\")), Memory=iff(isnull(Memory), \"N/A\", format_bytes(Memory, 2, \"GB\")), IO_Rate=iff(isnull(ioRate), \"N/A\", strcat(bin(ioRate, 0.01), \" B/s\")), Avg_Dependency=iff(isnull(average), \"N/A\", strcat(bin(average, 0.01), \" ms\")), Dependencies_Count=iff(isnull(dependenciesCount), \"N/A\", tostring(dependenciesCount)), Req_Duration=iff(isnull(req_Duration), \"N/A\", strcat(bin(req_Duration, 0.01), \" ms\")), Requests_Count=iff(isnull(requestsCount), \"N/A\", tostring(requestsCount))", + "size": 0, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ] + }, + "name": "servicesMonitoringQuery" + }, + { + "type": 1, + "content": { + "json": "## Additional workbooks\r\n\r\nThere are two workbooks made to keep track of the entire system's information.\r\n\r\n|Workbooks|Descriiption|Link|\r\n|---------|------------|----|\r\n|Infrastructure|Data related to infrastructure|[Link](https://portal.azure.com/#blade/AppInsightsExtension/UsageNotebookBlade/ComponentId/${logs_workspace_id}/ConfigurationId/${infrastructure_workbook_id}/Type/workbook/WorkbookTemplateName/Infrastructure)|\r\n|System|Data related to system functionality|[Link](https://portal.azure.com/#blade/AppInsightsExtension/UsageNotebookBlade/ComponentId/${logs_workspace_id}/ConfigurationId/${system_workbook_id}/Type/workbook/WorkbookTemplateName/System%20Processing)|" + }, + "name": "workbooksLinksText" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" + } \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/infrastructure.json b/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/infrastructure.json new file mode 100644 index 0000000..0662f4a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/infrastructure.json @@ -0,0 +1,477 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "# Infrastructure Dashboard\nThis workbook has been created to provide a consolidated view of the system infrastructure" + }, + "name": "mainTitleText" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Service Bus Telemetry\r\n\r\nThis section displays telemetry obtained from Service Bus operations." + }, + "name": "serviceBusTitleText" + }, + { + "type": 1, + "content": { + "json": "### Service Bus completed operations\r\nThese tiles display the following:\r\n* The fastest time an operation takes to be completed.\r\n* The average time all operations take to be completed.\r\n* The slowest time an operation takes to be completed.\r\n\r\nAll data is being displayed in milliseconds." + }, + "name": "serviceBusDescriptionText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "dependencies\r\n| where name == \"ServiceBus.complete\"\r\n| summarize Result = avg(duration), Name = \"Average\"\r\n| union (dependencies\r\n| where name == \"ServiceBus.complete\"\r\n| top 1 by duration asc \r\n| summarize count() by Result = duration, Name = \"Fastest\")\r\n| union ( dependencies\r\n| where name == \"ServiceBus.complete\"\r\n| top 1 by duration desc \r\n| summarize count() by Result = duration, Name = \"Slowest\")", + "size": 0, + "showAnalytics": true, + "title": "Statistics of service bus completed operations (ms)", + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "Name", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "Result", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal", + "maximumFractionDigits": 2, + "maximumSignificantDigits": 3 + } + } + }, + "showBorder": false, + "sortOrderField": 1 + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "id", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "duration", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "nodeIdField": "duration", + "sourceIdField": "timestamp", + "targetIdField": "name", + "graphOrientation": 3, + "showOrientationToggles": false, + "nodeSize": null, + "staticNodeSize": 100, + "colorSettings": null, + "hivesMargin": 5 + } + }, + "customWidth": "50", + "name": "serviceBusCompletedTimesQuery", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 1, + "content": { + "json": "### Count of Messages\r\n\r\nThis chart displays:\r\n* The count of active messages in a Queue/Topic\r\n* The count of delivered messages in a Queue/Topic\r\n* The count of dead-lettered messages in a Queue/Topic" + }, + "name": "serviceBusMessageCountText" + }, + { + "type": 10, + "content": { + "chartId": "workbook0f9894a2-554d-406d-b03e-c87fe7b37293", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "resourceType": "microsoft.servicebus/namespaces", + "metricScope": 0, + "resourceIds": [ + "${servicebus_namespace_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.servicebus/namespaces", + "metric": "microsoft.servicebus/namespaces--ActiveMessages", + "aggregation": 4, + "splitBy": null + }, + { + "namespace": "microsoft.servicebus/namespaces", + "metric": "microsoft.servicebus/namespaces--Messages", + "aggregation": 4 + }, + { + "namespace": "microsoft.servicebus/namespaces", + "metric": "microsoft.servicebus/namespaces--DeadletteredMessages", + "aggregation": 4 + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "serviceBusMessagingMetric" + }, + { + "type": 1, + "content": { + "json": "### Throttled Requests\r\n\r\nThis chart displays the number of throttled requests in Service Bus." + }, + "name": "serviceBusThrottledText" + }, + { + "type": 10, + "content": { + "chartId": "workbooke8c22d13-3c2a-4fc8-8722-0180737c45f4", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "blueDark", + "resourceType": "microsoft.servicebus/namespaces", + "metricScope": 0, + "resourceIds": [ + "${servicebus_namespace_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.servicebus/namespaces", + "metric": "microsoft.servicebus/namespaces--ThrottledRequests", + "aggregation": 1, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "serviceBusThrottledMetric" + } + ] + }, + "name": "serviceBusTelemetryGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Cosmos DB Telemetry\r\n\r\nThis section displays telemetry obtained from Cosmos DB operations." + }, + "name": "cosmosDbTitleText" + }, + { + "type": 1, + "content": { + "json": "### Average time for reads from Cosmos DB\r\n\r\nThis chart displays the average time per read requests from Cosmos DB." + }, + "name": "cosmosDbDescriptionText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "dependencies \r\n| where target == \"readDatabase.cargo\" \r\n| summarize Average = avg(duration) by bin(timestamp, 10m)\r\n| render timechart", + "size": 0, + "showAnalytics": true, + "aggregation": 3, + "color": "green", + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "visualization": "areachart" + }, + "name": "latencyOfReadsCosmosDbQuery" + }, + { + "type": 1, + "content": { + "json": "### Number of valid, invalid and operations saved.\r\n\r\nThis chart displays the total number of valid, invalid and operations writes into Cosmos DB." + }, + "name": "cosmosDbOperationsText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "dependencies\r\n| summarize dependencies = count() by name\r\n| where name == \"upsertItem.operations\" or name == \"upsertItem.invalid-cargo\" or name == \"upsertItem.valid-cargo\"", + "size": 0, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "visualization": "piechart" + }, + "name": "cosmosDbOperationsQuery" + } + ] + }, + "name": "cosmosDbTelemetryGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Key Vault\r\n\r\n### Key Vault Saturation\r\n\r\nThis metric displays the percentage of saturation Key Vault is having at the moment." + }, + "name": "keyVaultTitleText" + }, + { + "type": 10, + "content": { + "chartId": "workbook1dfaaa15-6964-4398-a9ab-4849c2e07653", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "turquoise", + "resourceType": "microsoft.keyvault/vaults", + "metricScope": 0, + "resourceIds": [ + "${key_vault_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.keyvault/vaults", + "metric": "microsoft.keyvault/vaults--SaturationShoebox", + "aggregation": 4, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "keyVaultSaturationMetric" + }, + { + "type": 1, + "content": { + "json": "### Key Vault Latency\r\n\r\nThis metric displays the latency when executing an operation to KeyVault. The metric displays an average time and it is being estimated in milliseconds." + }, + "name": "keyVaultLatencyText" + }, + { + "type": 10, + "content": { + "chartId": "workbook7000b67b-e89a-4481-99d3-779513f70214", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "turquoise", + "resourceType": "microsoft.keyvault/vaults", + "metricScope": 0, + "resourceIds": [ + "${key_vault_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.keyvault/vaults", + "metric": "microsoft.keyvault/vaults--ServiceApiLatency", + "aggregation": 4, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "keyVaultLatencyMetric" + }, + { + "type": 1, + "content": { + "json": "### Key Vault Results (Count)\r\n\r\nThis metric displays the count of Key Vault API Results." + }, + "name": "keyVaultResultsText" + }, + { + "type": 10, + "content": { + "chartId": "workbook93558986-b83b-4a80-8cbf-1d588fc01058", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "turquoise", + "resourceType": "microsoft.keyvault/vaults", + "metricScope": 0, + "resourceIds": [ + "${key_vault_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.keyvault/vaults", + "metric": "microsoft.keyvault/vaults--ServiceApiResult", + "aggregation": 7, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "keyVaultResultsMetric" + } + ] + }, + "name": "keyVaultTelemetryGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Kubernetes\r\n\r\n### CPU Percentage\r\n\r\nThis chart displays the max count of CPU percentage of the cluster." + }, + "name": "aksTitleText" + }, + { + "type": 10, + "content": { + "chartId": "workbook171b383f-5043-41dd-9154-a1fa92367891", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "pink", + "resourceType": "microsoft.containerservice/managedclusters", + "metricScope": 0, + "resourceIds": [ + "${aks_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.containerservice/managedclusters", + "metric": "microsoft.containerservice/managedclusters-Nodes (PREVIEW)-node_cpu_usage_percentage", + "aggregation": 3, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "aksCpuMetric" + }, + { + "type": 1, + "content": { + "json": "### Requests\r\n\r\nThis chart shows the average inflight requests to the cluster." + }, + "name": "aksRequestsText" + }, + { + "type": 10, + "content": { + "chartId": "workbook2e1c3664-7b39-433d-81b2-863ab1b9b307", + "version": "MetricsItem/2.0", + "size": 0, + "showAnalytics": true, + "chartType": 3, + "color": "pink", + "resourceType": "microsoft.containerservice/managedclusters", + "metricScope": 0, + "resourceIds": [ + "${aks_id}" + ], + "timeContext": { + "durationMs": 3600000 + }, + "metrics": [ + { + "namespace": "microsoft.containerservice/managedclusters", + "metric": "microsoft.containerservice/managedclusters-API Server (PREVIEW)-apiserver_current_inflight_requests", + "aggregation": 4, + "splitBy": null + } + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "name": "aksRequestsMetric" + } + ] + }, + "name": "aksTelemetryGroup" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/system-processing.json b/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/system-processing.json new file mode 100644 index 0000000..5990268 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/infrastructure/workbooks/system-processing.json @@ -0,0 +1,492 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "# System Processing Dashboard\n\nThis workbook shows data from system operation across services." + }, + "name": "mainTitleText" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Microservices" + }, + "name": "microservicesTitleText" + }, + { + "type": 1, + "content": { + "json": "### Statistics for endpoints requests\r\n\r\nThis chart displays different measures for time per requests. First measure is the mean per endpoint, second column goes for Median, columns 3, 4 ans 5 are for different percentiles ranges and finally last column displays the total amount of number requests per endpoint." + }, + "name": "endpointsStatisticsText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "requests\r\n| summarize Mean = avg(duration), (Median, p80, p95, p99) = percentiles(duration, 50, 80, 95, 99), Requests = count() by name\r\n| order by Requests desc", + "size": 0, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Mean", + "formatter": 8, + "formatOptions": { + "palette": "orange" + } + }, + { + "columnMatch": "Median", + "formatter": 8, + "formatOptions": { + "palette": "yellow" + } + }, + { + "columnMatch": "p80", + "formatter": 8, + "formatOptions": { + "palette": "green" + } + }, + { + "columnMatch": "p95", + "formatter": 8, + "formatOptions": { + "palette": "blue" + } + }, + { + "columnMatch": "p99", + "formatter": 8, + "formatOptions": { + "palette": "purple" + } + }, + { + "columnMatch": "Requests", + "formatter": 8, + "formatOptions": { + "palette": "pink" + } + } + ] + } + }, + "name": "endpointsRequestsStatisticsQuery" + }, + { + "type": 1, + "content": { + "json": "### Total request to endpoints\r\n\r\nThis chart extracts the last column from previous chart in order to gain more focus on this metric." + }, + "name": "endpointsRequestsText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let dataset=requests\r\n| where client_Type != \"Browser\";\r\n\r\ndataset\r\n| summarize\r\n Count=sum(itemCount),\r\n Average=sum(itemCount * duration) / sum(itemCount) \r\n| project operation_Name=\"Overall\", Count,Average\r\n| union(dataset\r\n | summarize\r\n Count=sum(itemCount),\r\n Average=sum(itemCount * duration) / sum(itemCount) \r\n by operation_Name\r\n | sort by Count desc, Average desc\r\n )", + "size": 0, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Average", + "formatter": 8, + "formatOptions": { + "palette": "turquoise" + } + }, + { + "columnMatch": "Count", + "formatter": 8, + "formatOptions": { + "palette": "orange" + } + } + ] + } + }, + "name": "endpointsRequestsQuery" + }, + { + "type": 1, + "content": { + "json": "### Last 100 operations executed\r\n\r\nThis list shows the last 100 of operations executed and their asociated operation ID. You can use this value to request more information from the link after the list that will redirect you to a **Transaction Search** tool." + }, + "name": "operationsText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "requests\r\n| top 100 by timestamp\r\n| distinct name, operation_Id", + "size": 0, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ] + }, + "name": "lastOperationsQuery" + }, + { + "type": 1, + "content": { + "json": "You can go and check the **Transaction Search** [here](https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/searchV1/ResourceId/%2Fsubscriptions%2F30a83aff-7a8b-4ca3-aa48-ab93268b5a8b%2FresourceGroups%2Frg-dev-tf-amines4%2Fproviders%2FMicrosoft.Insights%2Fcomponents%2Fdev-appi-accl-glc-eastus2/BladeInputs/%7B%22tables%22%3A%5B%22availabilityResults%22%2C%22requests%22%2C%22exceptions%22%2C%22pageViews%22%2C%22traces%22%2C%22customEvents%22%2C%22dependencies%22%5D%7D). \r\n\r\nAnd using the list above of the last 100 operation IDs start looking for an specific operation." + }, + "name": "transactionSearchBladeText" + }, + { + "type": 1, + "content": { + "json": "### Additional telemetry\r\n\r\nYou can find in these sections more information that you can use or add to this workbook.\r\n\r\n|Application map|Availability|Failures|Performance|\r\n|---------------|------------|--------|-----------|\r\n|[Link](https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/applicationMap/ResourceId/%2Fsubscriptions%2F30a83aff-7a8b-4ca3-aa48-ab93268b5a8b%2FresourceGroups%2Frg-dev-tf-amines4%2Fproviders%2FMicrosoft.Insights%2Fcomponents%2Fdev-appi-accl-glc-eastus2/BladeInputs/%7B%22MainResourceId%22%3A%22%2Fsubscriptions%2F30a83aff-7a8b-4ca3-aa48-ab93268b5a8b%2FresourceGroups%2Frg-dev-tf-amines4%2Fproviders%2FMicrosoft.Insights%2Fcomponents%2Fdev-appi-accl-glc-eastus2%22%2C%22TimeContext%22%3A%7B%22durationMs%22%3A3600000%2C%22createdTime%22%3A%222023-03-07T15%3A39%3A08.000Z%22%2C%22isInitialTime%22%3Afalse%2C%22grain%22%3A1%2C%22useDashboardTimeRange%22%3Afalse%7D%2C%22DataModel%22%3A%7B%22exclude4xxError%22%3Atrue%2C%22timeContext%22%3A%7B%22durationMs%22%3A3600000%2C%22createdTime%22%3A%222023-03-07T15%3A39%3A08.000Z%22%2C%22isInitialTime%22%3Afalse%2C%22grain%22%3A1%2C%22useDashboardTimeRange%22%3Afalse%7D%2C%22layoutOption%22%3A%22Organic%22%2C%22nodeContentFilter%22%3A%22%22%7D%7D)|[Link](https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/availability/ResourceId/%2Fsubscriptions%2F30a83aff-7a8b-4ca3-aa48-ab93268b5a8b%2FresourceGroups%2Frg-dev-tf-amines4%2Fproviders%2FMicrosoft.Insights%2Fcomponents%2Fdev-appi-accl-glc-eastus2/BladeInputs/%7B%22filters%22%3A%5B%5D%2C%22timeContext%22%3A%7B%22durationMs%22%3A86400000%2C%22createdTime%22%3A%222023-03-07T12%3A54%3A05.627Z%22%2C%22endTime%22%3A%222023-03-07T15%3A39%3A00.000Z%22%2C%22isInitialTime%22%3Afalse%2C%22grain%22%3A1%2C%22useDashboardTimeRange%22%3Afalse%7D%2C%22experience%22%3A5%2C%22roleSelectors%22%3A%5B%5D%7D)|[Link](https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/failures/ResourceId/%2Fsubscriptions%2F30a83aff-7a8b-4ca3-aa48-ab93268b5a8b%2FresourceGroups%2Frg-dev-tf-amines4%2Fproviders%2FMicrosoft.Insights%2Fcomponents%2Fdev-appi-accl-glc-eastus2/BladeInputs/%7B%22filters%22%3A%5B%5D%2C%22timeContext%22%3A%7B%22durationMs%22%3A86400000%2C%22createdTime%22%3A%222023-03-07T12%3A54%3A05.627Z%22%2C%22endTime%22%3A%222023-03-07T12%3A58%3A00.000Z%22%2C%22isInitialTime%22%3Afalse%2C%22grain%22%3A1%2C%22useDashboardTimeRange%22%3Afalse%7D%2C%22selectedOperation%22%3Anull%2C%22experience%22%3A4%2C%22roleSelectors%22%3A%5B%5D%2C%22clientTypeMode%22%3A%22Server%22%7D)|[Link](https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/performance/ResourceId/%2Fsubscriptions%2F30a83aff-7a8b-4ca3-aa48-ab93268b5a8b%2FresourceGroups%2Frg-dev-tf-amines4%2Fproviders%2FMicrosoft.Insights%2Fcomponents%2Fdev-appi-accl-glc-eastus2/BladeInputs/%7B%22filters%22%3A%5B%5D%2C%22timeContext%22%3A%7B%22durationMs%22%3A86400000%2C%22createdTime%22%3A%222023-03-07T12%3A54%3A05.627Z%22%2C%22endTime%22%3A%222023-03-07T15%3A41%3A00.000Z%22%2C%22isInitialTime%22%3Afalse%2C%22grain%22%3A1%2C%22useDashboardTimeRange%22%3Afalse%7D%2C%22selectedOperation%22%3Anull%2C%22experience%22%3A1%2C%22roleSelectors%22%3A%5B%5D%2C%22clientTypeMode%22%3A%22Server%22%7D)|" + }, + "name": "aditionalTelemetryText" + } + ] + }, + "name": "microservicesTelemetryGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Microservices operations telemetry\r\n\r\nSelect from the following parameters the options to display desired results:\r\nFirst parameter is for a time range and second one is for the service you want to monitor." + }, + "name": "operationsTitleText" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "8f9405b8-1cc0-419f-a465-f35464bb15c0", + "version": "KqlParameterItem/1.0", + "name": "param_time_range", + "label": "Time Range", + "type": 4, + "description": "Select the time range for queries", + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 1800000 + } + }, + { + "id": "5da2ece4-7e2b-4356-a8ce-795bf3e58bd2", + "version": "KqlParameterItem/1.0", + "name": "paramCloudRoleName", + "label": "Cloud Role", + "type": 2, + "query": "dependencies\r\n| distinct cloud_RoleName\r\n| order by cloud_RoleName asc", + "crossComponentResources": [ + "${app_insights_id}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components" + }, + { + "id": "0093df18-0e13-4eac-b50e-1afbc78a7b9c", + "version": "KqlParameterItem/1.0", + "name": "appinsights", + "type": 5, + "description": "Used as a single place to set the app insights resource to query", + "isHiddenWhenLocked": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\"/subscriptions/30a83aff-7a8b-4ca3-aa48-ab93268b5a8b/resourceGroups/rg-dev-tf-amines4/providers/Microsoft.Insights/components/dev-appi-accl-glc-eastus2\"]", + "value": "${app_insights_id}" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "operationsParameters" + }, + { + "type": 1, + "content": { + "json": "### End to end processing time\r\n\r\nThis chart displays the end to end processing time. This is measured in seconds and to be displayed requires the selection of parameters time range and cloud role." + }, + "name": "endToEndProcessingText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let put_name = strcat(\"PUT /cargo/{cargoId\", \"}\"); // TODO - determine how to escape curly braces!\r\nlet cargo_processing_api = requests\r\n| where cloud_RoleName == \"cargo-processing-api\" and (name == \"POST /cargo/\" or name == put_name) and timestamp {param_time_range}\r\n| project-rename ingest_timestamp = timestamp\r\n| project ingest_timestamp, operation_Id\r\n;\r\nlet operation_api_succeeded = requests\r\n| where cloud_RoleName == \"operations-api\" and name == \"ServiceBus.process\" and customDimensions[\"operation-state\"] == \"Succeeded\"\r\n| extend operation_api_completed = timestamp + (duration*1ms)\r\n| project operation_Id, operation_api_completed\r\n;\r\ncargo_processing_api\r\n| join kind=inner operation_api_succeeded on $left.operation_Id == $right.operation_Id\r\n| extend end_to_end_Duration_s = (operation_api_completed - ingest_timestamp) /1s\r\n| summarize avg(end_to_end_Duration_s), max(end_to_end_Duration_s) by bin(ingest_timestamp, {param_time_range:grain})\r\n| order by ingest_timestamp desc\r\n| project ingest_timestamp, avg_end_to_end_Duration_s, max_end_to_end_Duration_s\r\n| render timechart \r\n", + "size": 0, + "aggregation": 3, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "chartSettings": { + "seriesLabelSettings": [ + { + "seriesName": "avg_end_to_end_Duration_s", + "label": "Avg duration (s)", + "color": "blue" + }, + { + "seriesName": "max_end_to_end_Duration_s", + "label": "Max duration (s)", + "color": "lightBlue" + } + ] + } + }, + "name": "endToEndProcessingQuery" + }, + { + "type": 1, + "content": { + "json": "### Request count\r\n\r\nThis chart displays the count of ingest of requests. It required the selection of parameters time range and cloud role." + }, + "name": "requestsCountText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let put_name = strcat(\"PUT /cargo/{cargoId\", \"}\"); // TODO - determine how to escape curly braces!\r\nrequests\r\n| where cloud_RoleName == \"cargo-processing-api\" and (name == \"POST /cargo/\" or name == put_name) and timestamp {param_time_range}\r\n| summarize request_count=count() by bin(timestamp, {param_time_range:grain})\r\n| project timestamp, request_count\r\n| render timechart \r\n", + "size": 1, + "showAnalytics": true, + "color": "gray", + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ] + }, + "name": "requestsCountQuery" + }, + { + "type": 1, + "content": { + "json": "### Services processing time \r\n\r\nThis chart displays the processing time in the services. This is measured in seconds and to be displayed requires the selection of parameters time range and cloud role." + }, + "name": "servicesProcessingTimeText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let put_name = strcat(\"PUT /cargo/{cargoId\", \"}\"); // TODO - determine how to escape curly braces!\r\nlet cargo_processing_api = requests\n | where cloud_RoleName == \"cargo-processing-api\" and (name == \"POST /cargo/\" or name == put_name) and timestamp {param_time_range}\n | project-rename durationMs=duration\n | extend duration=durationMs * 1ms\n | project timestamp, cloud_RoleName, cloud_RoleInstance, duration, operation_Id\n;\nlet cargo_processing_validator = requests\n | where cloud_RoleName == \"cargo-processing-validator\" and (name == \"ServiceBus.ProcessMessage\" or name == \"ServiceBusQueue.ProcessMessage\")\n | project-rename durationMs=duration\n | extend duration=durationMs * 1ms\n | project timestamp, cloud_RoleName, cloud_RoleInstance, duration, operation_Id\n;\nlet valid_cargo_manager = requests\n | where cloud_RoleName == \"valid-cargo-manager\" and name == \"ServiceBusTopic.ProcessMessage\"\n | project-rename durationMs=duration\n | extend duration=durationMs * 1ms\n | project timestamp, cloud_RoleName, cloud_RoleInstance, name, duration, operation_Id\n;\nlet invalid_cargo_manager = requests\n | where cloud_RoleName == \"invalid-cargo-manager\" and name == \"ServiceBusTopic.ProcessMessage\"\n | project-rename durationMs=duration\n | extend duration=durationMs * 1ms\n | project timestamp, cloud_RoleName, cloud_RoleInstance, name, duration, operation_Id\n;\ncargo_processing_api\n| join kind=leftouter cargo_processing_validator on $left.operation_Id == $right.operation_Id\n| join kind=leftouter valid_cargo_manager on $left.operation_Id == $right.operation_Id\n| join kind=leftouter invalid_cargo_manager on $left.operation_Id == $right.operation_Id\n| project-rename\n cpa_timestamp=timestamp, cpa_duration=duration, \n cpv_timestamp=timestamp1, cpv_duration=duration1,\n vcm_timestamp=timestamp2, vcm_duration=duration2,\n icm_timestamp=timestamp3, icm_duration=duration3\n| extend\n time_to_cpv=cpv_timestamp - cpa_timestamp,\n time_to_vcm=vcm_timestamp - cpv_timestamp,\n time_to_icm=icm_timestamp - cpv_timestamp\n| extend\n in_cpa_s = cpa_duration / 1s,\n in_cpv_s = cpv_duration / 1s,\n in_vcm_s = vcm_duration / 1s,\n in_icm_s = icm_duration / 1s\n| summarize \n avg(in_cpa_s),\n avg(in_cpv_s),\n avg(in_vcm_s),\n avg(in_icm_s)\n by bin (cpa_timestamp, {param_time_range:grain})\n| order by cpa_timestamp desc\n| render areachart with(kind=stacked)\n", + "size": 0, + "aggregation": 3, + "showAnalytics": true, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ], + "chartSettings": { + "xAxis": "cpa_timestamp", + "seriesLabelSettings": [ + { + "seriesName": "avg_to_cpv_s", + "label": "Average time to cargo-processing_validator", + "color": "redBright" + }, + { + "seriesName": "avg_to_vcm_s", + "color": "green" + }, + { + "seriesName": "avg_to_icm_s", + "color": "lightBlue" + }, + { + "seriesName": "avg_in_cpa_s", + "color": "yellow" + }, + { + "seriesName": "avg_in_cpv_s", + "color": "red" + }, + { + "seriesName": "avg_in_vcm_s", + "color": "greenDark" + }, + { + "seriesName": "avg_in_icm_s", + "color": "blue" + } + ] + } + }, + "name": "servicesProcessingTimeQuery" + }, + { + "type": 1, + "content": { + "json": "### Service dependency\r\n\r\nThis chart displays the service dependency duration. This is measured in seconds and to be displayed requires the selection of parameters time range and cloud role." + }, + "name": "serviceDependencyText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let replace_guid = '[({]?[a-fA-F0-9]{8}[-]?([a-fA-F0-9]{4}[-]?){3}[a-fA-F0-9]{12}[})]?';\r\ndependencies\r\n| where cloud_RoleName == \"{paramCloudRoleName}\" and timestamp {param_time_range}\r\n| extend name_pattern = replace_regex(name, replace_guid, \"\")\r\n| extend duration_s = duration /1000\r\n| summarize avg(duration_s) by name_pattern, bin(timestamp, {param_time_range:grain})\r\n| project-reorder timestamp, avg_duration_s , name_pattern\r\n| render areachart with(kind=stacked)", + "size": 0, + "aggregation": 3, + "showAnalytics": true, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ] + }, + "name": "serviceDependencyQuery" + }, + { + "type": 1, + "content": { + "json": "### Breakdown by destination port\r\n\r\nThis chart displays the end to end processing time by destination port. This is measured in seconds and to be displayed requires the selection of parameters time range and cloud role." + }, + "name": "destinationPortBreakdownText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let put_name = strcat(\"PUT /cargo/{cargoId\", \"}\"); // TODO - determine how to escape curly braces!\r\nlet portMap = requests\r\n| where cloud_RoleName == \"cargo-processing-validator\"\r\n| extend destinationPort = customDimensions[\"cargo-destination\"]\r\n| project operation_Id, destinationPort;\r\nlet cargo_processing_api = requests\r\n| where cloud_RoleName == \"cargo-processing-api\" and (name == \"POST /cargo/\" or name == put_name) and timestamp {param_time_range}\r\n| project-rename ingest_timestamp = timestamp\r\n| project ingest_timestamp, operation_Id\r\n;\r\nlet operation_api_succeeded = requests\r\n| where cloud_RoleName == \"operations-api\" and name == \"ServiceBus.process\" and customDimensions[\"operation-state\"] == \"Succeeded\"\r\n| extend operation_api_completed = timestamp + (duration*1ms)\r\n| project operation_Id, operation_api_completed\r\n;\r\ncargo_processing_api\r\n| join kind=inner operation_api_succeeded on $left.operation_Id == $right.operation_Id\r\n| join kind=leftouter portMap on $left.operation_Id == $right.operation_Id\r\n| extend end_to_end_Duration_s = (operation_api_completed - ingest_timestamp) /1s\r\n| extend destinationPort=iif(destinationPort ==\"\", \"\", destinationPort)\r\n| summarize avg(end_to_end_Duration_s) by destinationPort, bin(ingest_timestamp, {param_time_range:grain})\r\n| project ingest_timestamp, avg_end_to_end_Duration_s, destinationPort\r\n| render timechart ", + "size": 0, + "aggregation": 3, + "showAnalytics": true, + "queryType": 0, + "resourceType": "microsoft.insights/components", + "crossComponentResources": [ + "${app_insights_id}" + ] + }, + "name": "destinationPortBreakdownQuery" + }, + { + "type": 1, + "content": { + "json": "### Pod Restarts\r\n\r\nThis chart shows the number of times each service pod has restarted." + }, + "name": "podRestartText" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "KubePodInventory\r\n| where ServiceName == \"{paramCloudRoleName}\"\r\n| summarize numRestarts = sum(PodRestartCount) by ServiceName, bin(TimeGenerated, 1m)\r\n| render timechart", + "size": 0, + "showAnalytics": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "podRestartQuery" + } + ] + }, + "name": "operationsTelemetryGroup" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/run-local.sh b/accelerators/aks-sb-azmonitor-microservices/run-local.sh new file mode 100644 index 0000000..7493e16 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/run-local.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +if [[ ! -f "$script_dir/.env" ]]; then + echo "Please create a .env file (using .env.sample as a starter)" 1>&2 + exit 1 +fi + +source "$script_dir/.env" + +if [[ -z "$USERNAME" ]]; then + echo 'USERNAME not set - ensure you have specifed a value for it in your .env file' 1>&2 + exit 6 +fi + +echo "Starting services locally (Ctrl+C to stop)" +cd "$script_dir/src" +docker compose up diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/Dockerfile new file mode 100644 index 0000000..32bfefa --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/Dockerfile @@ -0,0 +1,25 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java/.devcontainer/base.Dockerfile + +# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster +ARG VARIANT="17-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT} + +# [Option] Install Maven +ARG INSTALL_MAVEN="false" +ARG MAVEN_VERSION="" +# [Option] Install Gradle +ARG INSTALL_GRADLE="false" +ARG GRADLE_VERSION="" +RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \ + && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi + +# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 +ARG NODE_VERSION="none" +RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/devcontainer.json new file mode 100644 index 0000000..583e6d2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java +{ + "name": "Java", + "build": { + "dockerfile": "Dockerfile", + "args": { + // Update the VARIANT arg to pick a Java version: 11, 17 + // Append -bullseye or -buster to pin to an OS version. + // Use the -bullseye variants on local arm64/Apple Silicon. + "VARIANT": "17-bullseye", + // Options + "INSTALL_MAVEN": "true", + "INSTALL_GRADLE": "false", + "NODE_VERSION": "lts/*" + } + }, + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "java.jdt.ls.lombokSupport.enabled": true + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "vscjava.vscode-java-pack", + "redhat.fabric8-analytics" + ] + } + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "java -version", + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.dockerignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.dockerignore new file mode 100644 index 0000000..2ce5e1c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.dockerignore @@ -0,0 +1,2 @@ +.env +helm diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.env.sample b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.env.sample new file mode 100644 index 0000000..cb2518d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.env.sample @@ -0,0 +1,9 @@ +APPLICATIONINSIGHTS_CONNECTION_STRING= +APPLICATIONINSIGHTS_VERSION=3.4.7 + +# Service Bus Information +servicebus_connection_string= +accelerator_queue_name=ingest-cargo + +# Operation API +operations_api_url=http://operations-api:8081/ \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.gitignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.gitignore new file mode 100644 index 0000000..8977a26 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.gitignore @@ -0,0 +1,3 @@ +target + +.env \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/launch.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/launch.json new file mode 100644 index 0000000..52a4a37 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Launch Current File", + "request": "launch", + "mainClass": "${file}", + "envFile": "${workspaceFolder}/.env" + }, + { + "type": "java", + "name": "Launch Application", + "request": "launch", + "mainClass": "com.microsoft.cse.cargoprocessing.api.Application", + "projectName": "cargoprocessing.api", + "vmArgs": "-javaagent:${workspaceFolder}/target/dependency/applicationinsights-agent-3.4.7.jar", + "envFile": "${workspaceFolder}/.env" + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/settings.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/tasks.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/tasks.json new file mode 100644 index 0000000..b681057 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "verify", + "type": "shell", + "command": "mvn -B verify", + "group": "build" + }, + { + "label": "test", + "type": "shell", + "command": "mvn -B test", + "group": "test" + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/Dockerfile new file mode 100644 index 0000000..1487559 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/Dockerfile @@ -0,0 +1,27 @@ +FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu as base + + +FROM maven:3.8.5-openjdk-17-slim as build +WORKDIR /src + +RUN mvn -version + +COPY pom.xml . +RUN mvn -B dependency:resolve-plugins dependency:resolve +# RUN mvn -B dependency:go-offline + +COPY . . +RUN mvn package + +RUN ls -al target +RUN ls -al target/dependency + +FROM base as final +COPY applicationinsights.json applicationinsights.json + +ARG JAR_FILE=/src/target/*.jar +ARG DEPENDENCY=/src/target/dependency +COPY --from=build ${DEPENDENCY}/applicationinsights-agent-3.4.7.jar applicationinsights-agent-3.4.7.jar +COPY --from=build ${JAR_FILE} app.jar + +ENTRYPOINT ["java", "-javaagent:applicationinsights-agent-3.4.7.jar" ,"-jar","/app.jar" ] diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/README.md b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/README.md new file mode 100644 index 0000000..f8ec5e6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/README.md @@ -0,0 +1,72 @@ +# Running the service + +## Pre-Requisites + +1. Service Bus [namespace](https://docs.microsoft.com/en-us/cli/azure/servicebus/namespace?view=azure-cli-latest#az-servicebus-namespace-create) with [queue](https://docs.microsoft.com/en-us/cli/azure/servicebus/queue?view=azure-cli-latest#az-servicebus-queue-create) +1. Application Insights [account](https://docs.microsoft.com/en-us/azure/azure-monitor/app/create-new-resource#azure-cli-preview) + +## Debugging from VSCode Dev Container + +* Open the project in the dev container. + * Make sure to open in the devcontainer + * Ignore the alerts for Java on the initial load. The alerts move faster than the dev container builds. + * If you see an alert for Lombok asking to reload, please do reload. +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Build the Build task 2 options: + * From the command pallet `Tasks: Run Build Task` + * From the terminal `mvn -B verify` +* Configure debugger to use the "Launch Application" configuration. +* Run the Debugger. +* Post a message to ".../cargo/{GUID VALUE}" that conforms to the [Cargo API](../../api-spec/main.cadl) specification. + +## Docker Container + +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Run `docker compose up` to run the service. +* Post a message to ".../cargo/{GUID VALUE}" that conforms to the [Cargo API](../../api-spec/main.cadl) specification. + +## Samples + +Sample PUT request: + +``` bash +curl --request PUT \ + --url http://localhost:8080/cargo/2dfc711b-7335-4b17-aede-2d67fbf6866f \ + --header 'Content-Type: application/json' \ + --data '{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Seattle" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } +}' +``` + +Sample POST request: + +``` bash +curl --request POST \ + --url http://localhost:8080/cargo/ \ + --header 'Content-Type: application/json' \ + --data '{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } +}' +``` diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/applicationinsights.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/applicationinsights.json new file mode 100644 index 0000000..8efec15 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/applicationinsights.json @@ -0,0 +1,17 @@ +{ + "role": { + "name": "cargo-processing-api" + }, + "instrumentation": { + "logging": { + "level": "INFO" + } + }, + "preview": { + "instrumentation": { + "springIntegration": { + "enabled": true + } + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/docker-compose.yml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/docker-compose.yml new file mode 100644 index 0000000..47fdf30 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3.9" + +services: + cargo_processing_api: + env_file: + - .env + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:8080" \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/.helmignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/Chart.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/Chart.yaml new file mode 100644 index 0000000..83847e9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: cargo-processing-api +description: cargo-processing-api for aks-sb-azmonitor-microservices + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/cargo-processing-api.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/cargo-processing-api.yaml new file mode 100644 index 0000000..c5b1597 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/cargo-processing-api.yaml @@ -0,0 +1,36 @@ + +image: + pullPolicy: Always + tag: "latest" + +replicaCount: 1 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +podAnnotations: {} +podSecurityContext: {} +securityContext: {} +resources: {} +nodeSelector: {} +tolerations: [] +affinity: {} + + +# When running one of the deploy-*.sh scripts, an additional env.yaml +# values file is created containing values specific to the deployed environment +# with the following values: +# image: +# repository: + +# keyVault: +# name: +# tenantId: + +# aksKeyVaultSecretProviderIdentityId: diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/NOTES.txt b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/NOTES.txt new file mode 100644 index 0000000..0e7f6bf --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "aks-sb-azmonitor-microservices.fullname" . }}' +export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "aks-sb-azmonitor-microservices.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") +echo http://$SERVICE_IP:80 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/_helpers.tpl b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/_helpers.tpl new file mode 100644 index 0000000..1e34b64 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "aks-sb-azmonitor-microservices.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "aks-sb-azmonitor-microservices.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "aks-sb-azmonitor-microservices.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "aks-sb-azmonitor-microservices.labels" -}} +helm.sh/chart: {{ include "aks-sb-azmonitor-microservices.chart" . }} +{{ include "aks-sb-azmonitor-microservices.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "aks-sb-azmonitor-microservices.selectorLabels" -}} +app.kubernetes.io/name: {{ include "aks-sb-azmonitor-microservices.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/deployment.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/deployment.yaml new file mode 100644 index 0000000..feda6c3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/deployment.yaml @@ -0,0 +1,97 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: default + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: APPLICATIONINSIGHTS_VERSION + value: 3.4.7 + - name: accelerator_queue_name + value: ingest-cargo + - name: operations_api_url + value: http://operations-api/ + - name: APPLICATIONINSIGHTS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: cargo-processing-api-secrets + key: AppInsightsConnectionString + - name: servicebus_connection_string + valueFrom: + secretKeyRef: + name: cargo-processing-api-secrets + key: ServiceBusConnectionString + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 20 + failureThreshold: 3 + timeoutSeconds: 10 + + startupProbe: + httpGet: + path: /actuator/health + port: 8080 + periodSeconds: 10 + failureThreshold: 30 + timeoutSeconds: 10 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: secrets-store + mountPath: "/mnt/secrets-store" + readOnly: true + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: secrets-store + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: {{ include "aks-sb-azmonitor-microservices.fullname" . }} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/hpa.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/hpa.yaml new file mode 100644 index 0000000..0a3ca97 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/secretProviderClass.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/secretProviderClass.yaml new file mode 100644 index 0000000..983846c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/secretProviderClass.yaml @@ -0,0 +1,41 @@ +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + provider: azure + parameters: + usePodIdentity: "false" + useVMManagedIdentity: "true" + userAssignedIdentityID: {{ .Values.aksKeyVaultSecretProviderIdentityId }} + keyvaultName: {{ .Values.keyVault.name }} + cloudName: "" + objects: | + array: + - | + objectName: AppInsightsConnectionString + objectType: secret + - | + objectName: ServiceBusConnectionString + objectType: secret + - | + objectName: CosmosDBEndpoint + objectType: secret + - | + objectName: CosmosDBKey + objectType: secret + tenantId: {{ .Values.keyVault.tenantId }} + secretObjects: + - data: + - key: AppInsightsConnectionString + objectName: AppInsightsConnectionString + - key: ServiceBusConnectionString + objectName: ServiceBusConnectionString + - key: CosmosDBEndpoint + objectName: CosmosDBEndpoint + - key: CosmosDBKey + objectName: CosmosDBKey + secretName: cargo-processing-api-secrets + type: Opaque \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/service.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/service.yaml new file mode 100644 index 0000000..af3f13a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 4 }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/tests/test-connection.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5eb4bc4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "aks-sb-azmonitor-microservices.fullname" . }}-test-connection" + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "aks-sb-azmonitor-microservices.fullname" . }}:80'] + restartPolicy: Never diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw.cmd b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/pom.xml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/pom.xml new file mode 100644 index 0000000..0563da7 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/pom.xml @@ -0,0 +1,172 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + + com.microsoft.cse + cargoprocessing.api + 0.0.1-SNAPSHOT + cargoprocessing-api + Ingestion API for the Service Bus Messaging scenario + + + 17 + 3.12.0 + 5.8.2 + 3.4.7 + 3.4.7 + LATEST + 1.0.71 + 7.13.0 + 2.11.0 + 3.0.0-M5 + 3.3.0 + 4.4.0 + 2.7.3 + true + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-starter-actuator + + + + com.azure + azure-messaging-servicebus + ${servicebus.version} + + + + org.apache.commons + commons-lang3 + ${commons.lang.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + com.networknt + json-schema-validator + ${json.schema.validation.version} + + + + commons-io + commons-io + ${commons.io.version} + test + + + + io.opentelemetry + opentelemetry-api + + + + com.microsoft.azure + applicationinsights-web + ${applicationinsights.web.version} + + + + com.microsoft.azure + applicationinsights-agent + ${applicationinsights.agent.version} + + + + + + + io.opentelemetry + opentelemetry-bom + 1.22.0 + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + com.azure.spring + spring-cloud-azure-dependencies + ${spring.cloud.azure.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven.dependency.plugin.version} + + + + copy + compile + + copy + + + + + com.microsoft.azure + applicationinsights-agent + ${applicationinsights.agent.version} + applicationinsights-agent-${applicationinsights.agent.version}.jar + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + ${skipITs} + + + + + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Application.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Application.java new file mode 100644 index 0000000..dd885dc --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Application.java @@ -0,0 +1,13 @@ +package com.microsoft.cse.cargoprocessing.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Exceptions/JsonValidationException.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Exceptions/JsonValidationException.java new file mode 100644 index 0000000..c0074ee --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/Exceptions/JsonValidationException.java @@ -0,0 +1,33 @@ +package com.microsoft.cse.cargoprocessing.api.Exceptions; + +import java.util.Set; +import java.util.stream.Collectors; + +import com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling.ErrorCodes; +import com.networknt.schema.ValidationMessage; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper=false) +public class JsonValidationException extends RuntimeException { + private Set validationMessages; + private String failureCode; + + public JsonValidationException(Throwable cause) { + super(cause); + this.failureCode = ErrorCodes.FAILS_SERIALIZATION; + } + + public JsonValidationException(Set validationMessages) { + super(String.format("Json failed validation with the following errors:%n%n* %s", + validationMessages + .stream() + .map(v -> String.format("%s: {%s} %s", v.getCode(), v.getPath(), v.getMessage())) + .collect(Collectors.joining(String.format("%n* "))))); + + this.validationMessages = validationMessages; + this.failureCode = ErrorCodes.FAILS_SCHEMA_VALIDATION; + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/ChaosMonkey.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/ChaosMonkey.java new file mode 100644 index 0000000..36c0151 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/ChaosMonkey.java @@ -0,0 +1,15 @@ +package com.microsoft.cse.cargoprocessing.api.chaos; + +import java.util.Map; + +import com.microsoft.cse.cargoprocessing.api.models.Cargo; + +public interface ChaosMonkey { + boolean CanWakeTheMonkey(Cargo cargo); + + void WakeTheMonkey(Map parameters); + + void RattleTheCage(Cargo cargo, Map parameters); + + void RattleTheCage(Cargo cargo); +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/BaseMonkey.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/BaseMonkey.java new file mode 100644 index 0000000..baa8c87 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/BaseMonkey.java @@ -0,0 +1,41 @@ +package com.microsoft.cse.cargoprocessing.api.chaos.impl; + +import java.util.Map; + +import com.microsoft.cse.cargoprocessing.api.chaos.ChaosMonkey; +import com.microsoft.cse.cargoprocessing.api.models.Cargo; +import com.microsoft.cse.cargoprocessing.api.models.Port; + +abstract public class BaseMonkey implements ChaosMonkey { + private final String chaosTrigger; + private final String SERVICE_TRIGGER = "cargo-processing-api"; + + public BaseMonkey(String chaosTrigger) { + this.chaosTrigger = chaosTrigger; + } + + @Override + public boolean CanWakeTheMonkey(Cargo cargo) { + Port portInfo = cargo.getPort(); + return portInfo.getSource().equalsIgnoreCase(SERVICE_TRIGGER) && + portInfo.getDestination().equalsIgnoreCase(chaosTrigger); + } + + @SuppressWarnings("unchecked") + protected static T getParm(Map map, String key, T defaultValue) { + return (map.containsKey(key)) ? (T) map.get(key) : defaultValue; + } + + abstract public void WakeTheMonkey(Map parameters); + + @Override + public void RattleTheCage(Cargo cargo, Map parameters) { + if (CanWakeTheMonkey(cargo)) + WakeTheMonkey(parameters); + } + + @Override + public void RattleTheCage(Cargo cargo) { + RattleTheCage(cargo, null); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ChaosMonkeyException.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ChaosMonkeyException.java new file mode 100644 index 0000000..bdc02fa --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ChaosMonkeyException.java @@ -0,0 +1,7 @@ +package com.microsoft.cse.cargoprocessing.api.chaos.impl; + +public class ChaosMonkeyException extends RuntimeException { + public ChaosMonkeyException(String chaosType) { + super(String.format("%s Chaos Monkey reeking havoc.", chaosType)); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/DependantApiFailureMonkey.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/DependantApiFailureMonkey.java new file mode 100644 index 0000000..67d8b31 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/DependantApiFailureMonkey.java @@ -0,0 +1,17 @@ +package com.microsoft.cse.cargoprocessing.api.chaos.impl; + +import java.util.Map; + +import org.springframework.stereotype.Service; + +@Service +public class DependantApiFailureMonkey extends BaseMonkey { + public DependantApiFailureMonkey() { + super("operations-api-failure"); + } + + @Override + public void WakeTheMonkey(Map parameters) { + throw new ChaosMonkeyException("Dependant Api Failing"); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ProcessKillingMonkey.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ProcessKillingMonkey.java new file mode 100644 index 0000000..fa66bb8 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ProcessKillingMonkey.java @@ -0,0 +1,18 @@ +package com.microsoft.cse.cargoprocessing.api.chaos.impl; + +import java.util.Map; + +import org.springframework.stereotype.Service; + +@Service +public class ProcessKillingMonkey extends BaseMonkey { + public ProcessKillingMonkey() { + super("process-ending"); + } + + @Override + public void WakeTheMonkey(Map parameters) { + // Completely Kill the application + System.exit(-1); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusKillingMonkey.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusKillingMonkey.java new file mode 100644 index 0000000..b29517f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusKillingMonkey.java @@ -0,0 +1,22 @@ +package com.microsoft.cse.cargoprocessing.api.chaos.impl; + +import java.util.Map; + +import org.springframework.stereotype.Service; + +import com.azure.messaging.servicebus.ServiceBusSenderClient; + +@Service +public class ServiceBusKillingMonkey extends BaseMonkey { + public ServiceBusKillingMonkey() { + super("service-bus-failure"); + } + + @Override + public void WakeTheMonkey(Map parameters) { + // Oh, let's just close that sender before trying to use it, what could possibly + // go wrong? + ServiceBusSenderClient sender = getParm(parameters, "sender", null); + sender.close(); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusThrollingMonkey.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusThrollingMonkey.java new file mode 100644 index 0000000..5f6ab0c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/chaos/impl/ServiceBusThrollingMonkey.java @@ -0,0 +1,50 @@ +package com.microsoft.cse.cargoprocessing.api.chaos.impl; + +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusMessage; +import com.azure.messaging.servicebus.ServiceBusSenderClient; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +@Service +public class ServiceBusThrollingMonkey extends BaseMonkey { + public ServiceBusThrollingMonkey() { + super("service-bus-throttling"); + } + + @Value("${accelerator.queue-name:defaultValue}") + private String queueName; + @Value("${servicebus.connection-string:defaultValue}") + private String connectionString; + + @Override + public void WakeTheMonkey(Map parameters) { + ServiceBusSenderClient sender = new ServiceBusClientBuilder() + .connectionString(connectionString) + .sender() + .queueName(queueName) + .buildClient(); + + ServiceBusMessage message = getParm(parameters, "message", null); + + // Let's slam the service bus with that message ALOT, what could go wrong with + // that? + // TODO: Not able to get this to actually cause the service bus to throttle the + // requests. Need to revisit before calling this done. + Flux.just(1) + .repeat(10000) + .flatMap(i -> Mono.fromCallable(() -> { + sender.sendMessage(message); + return i; + })) + .subscribeOn(Schedulers.boundedElastic(), true) + .subscribe(); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoController.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoController.java new file mode 100644 index 0000000..f056ecc --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoController.java @@ -0,0 +1,143 @@ +package com.microsoft.cse.cargoprocessing.api.controllers; + +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.cse.cargoprocessing.api.Exceptions.JsonValidationException; +import com.microsoft.cse.cargoprocessing.api.chaos.impl.DependantApiFailureMonkey; +import com.microsoft.cse.cargoprocessing.api.chaos.impl.ProcessKillingMonkey; +import com.microsoft.cse.cargoprocessing.api.models.Cargo; +import com.microsoft.cse.cargoprocessing.api.models.MessageEnvelope; +import com.microsoft.cse.cargoprocessing.api.services.CargoPublisher; +import com.microsoft.cse.cargoprocessing.api.services.OperationPublisher; +import com.microsoft.cse.cargoprocessing.api.services.SchemaValidator; + +import lombok.SneakyThrows; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Timestamp; +import java.util.Map; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; + +@RestController +@RequestMapping("cargo") +public class CargoController { + @Autowired + private CargoPublisher publisher; + @Autowired + private SchemaValidator validator; + @Autowired + private OperationPublisher operationPublisher; + @Autowired + private DependantApiFailureMonkey apiFailingMonkey; + @Autowired + private ProcessKillingMonkey processKillingMonkey; + + private static final Logger logger = LoggerFactory.getLogger(CargoController.class); + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @PutMapping("/{cargoId}") + public ResponseEntity createCargo(@PathVariable String cargoId, @RequestBody String cargoBody, + @RequestHeader Map headers) { + Cargo cargo = getJsonCargo(cargoBody); + + // Let's see if we need to add a little chaos + processKillingMonkey.RattleTheCage(cargo); + + cargo.setId(cargoId); + logger.info("Cargo body loaded for cargo id: {}", cargoId); + + return processCargo(cargo, getOperationId(headers, cargo)); + } + + private String getOperationId(Map headers, Cargo cargo) { + String key = "operation-id"; + if (headers.containsKey(key)) { + return headers.get(key); + } + // If the client doesn't provide an operation-id, generate a + // deterministic UUID based on the cargo object provided + return generateId(cargo); + } + + @PostMapping("/") + public ResponseEntity createCargo(@RequestBody String cargoBody, @RequestHeader Map headers) { + Cargo cargo = getJsonCargo(cargoBody); + + // Let's see if we need to add a little chaos + processKillingMonkey.RattleTheCage(cargo); + + cargo.setId(generateId(cargo)); + logger.info("Cargo body loaded for cargo id: {}", cargo.getId()); + + // Take note that the cargo object's id has been set at this point, + // so the UUID that is generated for the operation id + // (when the client doesn't provide one) will be + // different then the UUID generated for the cargo object + return processCargo(cargo, getOperationId(headers, cargo)); + } + + @SneakyThrows + private String generateId(Cargo cargo) { + // Get a deterministic UUID based on the cargo object provided + String cargoString = objectMapper.writeValueAsString(cargo); + + return UUID.nameUUIDFromBytes(cargoString.getBytes()).toString(); + } + + private ResponseEntity processCargo(Cargo cargo, String operationId) { + // Let's see if we need to add a little chaos + apiFailingMonkey.RattleTheCage(cargo); + + Boolean isNewOperation = operationPublisher.isNewOperation(operationId).block(); + + // To ensure we don't have duplicate requests in play: + // If the operation was created in the previous call, then we haven't + // received this request before, so we will process it. + if (isNewOperation) { + logger.info("New Cargo request, processing cargo id: {}", cargo.getId()); + cargo.setTimestamp(new Timestamp(System.currentTimeMillis())); + publisher.publishCargo(new MessageEnvelope(cargo, operationId)); + + logger.info("Cargo id {} published", cargo.getId()); + } + + return ResponseEntity.accepted() + .headers(getHeaders(operationId)) + .body(cargo); + } + + private HttpHeaders getHeaders(String operationId) { + HttpHeaders headers = new HttpHeaders(); + headers.add("operation-id", operationId); + return headers; + } + + private Cargo getJsonCargo(String cargo) { + try { + logger.info("Validating cargo schema"); + JsonNode jsonCargo = objectMapper.readTree(cargo); + validator.validate("cargo", jsonCargo); + + return objectMapper.treeToValue(jsonCargo, Cargo.class); + + } catch (JsonProcessingException e) { + throw new JsonValidationException(e); + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/Error.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/Error.java new file mode 100644 index 0000000..49d5c81 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/Error.java @@ -0,0 +1,14 @@ +package com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class Error implements Serializable { + private ErrorDetail error; + + public Error(String code, String message, String target, InnerError innerError){ + error = new ErrorDetail(code, message, target, innerError); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorCodes.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorCodes.java new file mode 100644 index 0000000..d6e21be --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorCodes.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling; + +public class ErrorCodes { + private ErrorCodes() { throw new IllegalStateException("Utility class, should not be constructed"); } + + public static final String INVALID_JSON = "InvalidJson"; + public static final String FAILS_SCHEMA_VALIDATION = "InvalidJson-SchemaValidationFailure"; + public static final String FAILS_SERIALIZATION = "InvalidJson-UnableToSerialize"; + + public static final String INTERNAL_SERVER_ERROR = "InternalServerError"; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorDetail.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorDetail.java new file mode 100644 index 0000000..12cc31b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ErrorDetail.java @@ -0,0 +1,20 @@ +package com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class ErrorDetail implements Serializable { + private String code; + private String message; + private String target; + private InnerError innerError; + + public ErrorDetail(String code, String message, String target, InnerError innerError){ + this.code = code; + this.innerError = innerError; + this.target = target; + this.message = message; + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ExceptionAdvisor.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ExceptionAdvisor.java new file mode 100644 index 0000000..5d2a2f3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ExceptionAdvisor.java @@ -0,0 +1,52 @@ +package com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import com.microsoft.cse.cargoprocessing.api.Exceptions.JsonValidationException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ControllerAdvice +public class ExceptionAdvisor extends ResponseEntityExceptionHandler { + + private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvisor.class); + + @ExceptionHandler(JsonValidationException.class) + protected ResponseEntity handleJsonValidationException( + JsonValidationException ex, + WebRequest request) { + logger.error(ex.getMessage(), ex); + + InnerError innerError = ex.getFailureCode() == + ErrorCodes.FAILS_SCHEMA_VALIDATION + ? new ValidationError(ex.getFailureCode(), ex.getMessage(), ex.getValidationMessages()) + : new InnerError(ex.getFailureCode(), ex.getMessage()); + Error error = new Error( + ErrorCodes.INVALID_JSON, + "Invalid Json object, please see inner error for details", + request.getDescription(false), innerError); + + return new ResponseEntity<>(error, new HttpHeaders(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(Exception.class) + protected ResponseEntity handleDefaultExceptions( + Exception ex, + WebRequest request) { + logger.error(ex.getMessage(), ex); + + Error error = new Error(ErrorCodes.INTERNAL_SERVER_ERROR, + "Internal server error. Please see service logs for more information", + request.getDescription(false), null); + + return new ResponseEntity<>(error, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/InnerError.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/InnerError.java new file mode 100644 index 0000000..6459e90 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/InnerError.java @@ -0,0 +1,13 @@ +package com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class InnerError implements Serializable { + private String code; + private String message; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ValidationError.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ValidationError.java new file mode 100644 index 0000000..b718229 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/controllers/ExceptionHandling/ValidationError.java @@ -0,0 +1,19 @@ +package com.microsoft.cse.cargoprocessing.api.controllers.ExceptionHandling; + +import java.util.Set; + +import com.networknt.schema.ValidationMessage; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper=true) +public class ValidationError extends InnerError { + private Set validationMessages; + + public ValidationError (String code, String message, Set validationMessages) { + super(code, message); + this.validationMessages = validationMessages; + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Cargo.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Cargo.java new file mode 100644 index 0000000..8141e7f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Cargo.java @@ -0,0 +1,18 @@ +package com.microsoft.cse.cargoprocessing.api.models; + +import java.io.Serializable; +import java.sql.Timestamp; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Data; + +@Data +public class Cargo implements Serializable { + private String id; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Timestamp timestamp; + private Product product; + private Port port; + private DemandDates demandDates; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/DemandDates.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/DemandDates.java new file mode 100644 index 0000000..9ccc1c5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/DemandDates.java @@ -0,0 +1,16 @@ +package com.microsoft.cse.cargoprocessing.api.models; + +import java.io.Serializable; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Data; + +@Data +public class DemandDates implements Serializable { + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Date start; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Date end; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/MessageEnvelope.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/MessageEnvelope.java new file mode 100644 index 0000000..c0b5b8e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/MessageEnvelope.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.api.models; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class MessageEnvelope { + private Cargo data; + private String operationId; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Port.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Port.java new file mode 100644 index 0000000..6872497 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Port.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.api.models; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class Port implements Serializable { + private String source; + private String destination; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Product.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Product.java new file mode 100644 index 0000000..1f851c7 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/models/Product.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.api.models; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class Product implements Serializable { + private String name; + private int quantity; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/CargoPublisher.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/CargoPublisher.java new file mode 100644 index 0000000..c7d9cfe --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/CargoPublisher.java @@ -0,0 +1,7 @@ +package com.microsoft.cse.cargoprocessing.api.services; + +import com.microsoft.cse.cargoprocessing.api.models.MessageEnvelope; + +public interface CargoPublisher { + void publishCargo(MessageEnvelope envelope); +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/OperationPublisher.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/OperationPublisher.java new file mode 100644 index 0000000..f963fd1 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/OperationPublisher.java @@ -0,0 +1,7 @@ +package com.microsoft.cse.cargoprocessing.api.services; + +import reactor.core.publisher.Mono; + +public interface OperationPublisher { + Mono isNewOperation(String operationId); +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidator.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidator.java new file mode 100644 index 0000000..0e17153 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidator.java @@ -0,0 +1,7 @@ +package com.microsoft.cse.cargoprocessing.api.services; + +import com.fasterxml.jackson.databind.JsonNode; + +public interface SchemaValidator { + void validate(String schemaName, JsonNode json); +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/CargoPublisher.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/CargoPublisher.java new file mode 100644 index 0000000..9618c75 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/CargoPublisher.java @@ -0,0 +1,58 @@ +package com.microsoft.cse.cargoprocessing.api.services.impl; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusMessage; +import com.azure.messaging.servicebus.ServiceBusSenderClient; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.microsoft.cse.cargoprocessing.api.chaos.impl.ServiceBusKillingMonkey; +import com.microsoft.cse.cargoprocessing.api.chaos.impl.ServiceBusThrollingMonkey; +import com.microsoft.cse.cargoprocessing.api.models.MessageEnvelope; + +import lombok.SneakyThrows; + +@Service +public class CargoPublisher implements com.microsoft.cse.cargoprocessing.api.services.CargoPublisher { + + @Autowired + private ServiceBusKillingMonkey killingMonkey; + @Autowired + private ServiceBusThrollingMonkey throttlingMonkey; + + @Value("${accelerator.queue-name:defaultValue}") + private String queueName; + @Value("${servicebus.connection-string:defaultValue}") + private String connectionString; + + private JsonMapper mapper = new JsonMapper(); + + private static final Logger logger = LoggerFactory.getLogger(CargoPublisher.class); + + @SneakyThrows + public void publishCargo(MessageEnvelope envelope) { + ServiceBusSenderClient sender = new ServiceBusClientBuilder() + .connectionString(connectionString) + .sender() + .queueName(queueName) + .buildClient(); + + logger.info("Cargo being published"); + ServiceBusMessage message = new ServiceBusMessage(mapper.writeValueAsBytes(envelope)); + message.addContext(connectionString, message); + + // Maybe add a little chaos + Map chaosParameters = Map.of("sender", sender, "message", message); + killingMonkey.RattleTheCage(envelope.getData(), chaosParameters); + throttlingMonkey.RattleTheCage(envelope.getData(), chaosParameters); + + sender.sendMessage(message); + sender.close(); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/OperationPublisher.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/OperationPublisher.java new file mode 100644 index 0000000..344d21d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/OperationPublisher.java @@ -0,0 +1,37 @@ +package com.microsoft.cse.cargoprocessing.api.services.impl; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +@Service +public class OperationPublisher implements com.microsoft.cse.cargoprocessing.api.services.OperationPublisher { + private static final Logger logger = LoggerFactory.getLogger(OperationPublisher.class); + + @Value("${operations.api.url:defaultValue}") + private String operationApiUrl; + + @Override + public Mono isNewOperation(String operationId) { + logger.info("Starting operation {} to {}", operationId, operationApiUrl); + // Return a true when we're debugging the cargo processing only + if (operationApiUrl.equals("debug")) + return Mono.just(true); + return WebClient.create(operationApiUrl) + .put() + .uri("/operations/" + operationId) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .toBodilessEntity() + .map(response -> { + return response.getStatusCode() == HttpStatus.CREATED; + }); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/SchemaValidator.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/SchemaValidator.java new file mode 100644 index 0000000..dca6983 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/java/com/microsoft/cse/cargoprocessing/api/services/impl/SchemaValidator.java @@ -0,0 +1,48 @@ +package com.microsoft.cse.cargoprocessing.api.services.impl; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.microsoft.cse.cargoprocessing.api.Exceptions.JsonValidationException; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion; +import com.networknt.schema.ValidationMessage; + +@Service +public class SchemaValidator implements com.microsoft.cse.cargoprocessing.api.services.SchemaValidator { + private static final JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909); + private static final String JSON_SCHEMAS_PATH = "static/json-schemas/"; + private static final Map schemas = new HashMap<>(); + + public void validate(String schemaName, JsonNode json) { + JsonSchema jsonSchema = getSchema(schemaName); + + Set results = jsonSchema.validate(json); + if (!results.isEmpty()) { + throw new JsonValidationException(results); + } + } + + private JsonSchema getSchema(String schemaName) { + if (schemas.containsKey(schemaName)) { + return schemas.get(schemaName); + } + + StringBuilder sb = new StringBuilder(JSON_SCHEMAS_PATH); + sb.append(schemaName); + sb.append("-schema.json"); + + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + InputStream schemaStream = loader.getResourceAsStream(sb.toString()); + JsonSchema schema = schemaFactory.getSchema(schemaStream); + + schemas.put(schemaName, schema); + return schema; + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/application.properties b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/application.properties new file mode 100644 index 0000000..d41ac13 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/application.properties @@ -0,0 +1,16 @@ +APPLICATIONINSIGHTS_CONNECTION_STRING=${APPLICATIONINSIGHTS_CONNECTION_STRING} +APPLICATIONINSIGHTS_VERSION=${APPLICATIONINSIGHTS_VERSION} + +# Service Bus Information +servicebus.connection-string=${servicebus_connection_string} +accelerator.queue-name=${accelerator_queue_name} + +operations.api.url=${operations_api_url} + +server.port=8080 + +management.endpoints.web.exposure.include=health,info +endpoints.health.sensitive=false +management.endpoint.health.show-details=always + +otel.logs.exporter=logging diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-sample.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-sample.json new file mode 100644 index 0000000..43b8ce6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-sample.json @@ -0,0 +1,14 @@ +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-schema.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-schema.json new file mode 100644 index 0000000..400ee6b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/main/resources/static/json-schemas/cargo-schema.json @@ -0,0 +1,123 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "http://example.com/example.json", + "type": "object", + "default": {}, + "title": "Cargo Schema", + "required": [ + "product", + "port", + "demandDates" + ], + "properties": { + "product": { + "type": "object", + "default": {}, + "title": "The product in the cargo", + "required": [ + "name", + "quantity" + ], + "properties": { + "name": { + "type": "string", + "default": "", + "title": "The name of the product", + "examples": [ + "Toys" + ] + }, + "quantity": { + "type": "integer", + "default": 0, + "title": "The quantity of the product to be shipped", + "examples": [ + 100 + ] + } + }, + "examples": [{ + "name": "Toys", + "quantity": 100 + }] + }, + "port": { + "type": "object", + "default": {}, + "title": "The ports the cargo will use", + "required": [ + "source", + "destination" + ], + "properties": { + "source": { + "type": "string", + "default": "", + "title": "The source port for the cargo", + "examples": [ + "New York City" + ] + }, + "destination": { + "type": "string", + "default": "", + "title": "The destination port for the cargo", + "examples": [ + "Tacoma" + ] + } + }, + "examples": [{ + "source": "New York City", + "destination": "Tacoma" + }] + }, + "demandDates": { + "type": "object", + "default": {}, + "title": "The the dates the cargo is expected to be transported", + "required": [ + "start", + "end" + ], + "properties": { + "start": { + "type": "string", + "default": "", + "format": "date-time", + "title": "The start date", + "examples": [ + "2022-06-24T00:00:00.000Z" + ] + }, + "end": { + "type": "string", + "default": "", + "format": "date-time", + "title": "The end date", + "examples": [ + "2022-06-30T00:00:00.000Z" + ] + } + }, + "examples": [{ + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + }] + } + }, + "examples": [{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } + }] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/ApplicationTestsIT.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/ApplicationTestsIT.java new file mode 100644 index 0000000..8977bfa --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/ApplicationTestsIT.java @@ -0,0 +1,13 @@ +package com.microsoft.cse.cargoprocessing.api; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTestsIT { + + @Test + void contextLoads() { + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerIT.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerIT.java new file mode 100644 index 0000000..5206588 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerIT.java @@ -0,0 +1,56 @@ +package com.microsoft.cse.cargoprocessing.api.controllers; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.UUID; +import java.util.stream.Stream; + +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultMatcher; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microsoft.cse.cargoprocessing.api.services.CargoPublisher; + + +@SpringBootTest +@AutoConfigureMockMvc +public class CargoControllerIT { + @Autowired + private MockMvc mockMvc; + + @MockBean + private CargoPublisher publisher; + + @ParameterizedTest + @MethodSource("cargoToPublish") + void publishesCargo(String cargoSource, ResultMatcher matcher) throws JsonProcessingException, Exception{ + String cargo = IOUtils.toString( + this.getClass().getResourceAsStream(cargoSource), + "UTF-8"); + + String id = UUID.randomUUID().toString(); + + mockMvc.perform( + put("/cargo/{id}", id) + .contentType("application/json") + .content(cargo)) + .andExpect(matcher); + } + + private static Stream cargoToPublish() { + return Stream.of( + Arguments.of("/cargo-test-objects/basic-cargo.json", status().isOk()), + Arguments.of("/cargo-test-objects/invalid-cargo-object.json", status().isBadRequest()), + Arguments.of("/cargo-test-objects/invalid-syntax.json", status().isBadRequest()) + ); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerTest.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerTest.java new file mode 100644 index 0000000..d3ef805 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/controllers/CargoControllerTest.java @@ -0,0 +1,81 @@ +package com.microsoft.cse.cargoprocessing.api.controllers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.UUID; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + + +import com.microsoft.cse.cargoprocessing.api.models.Cargo; +import com.microsoft.cse.cargoprocessing.api.services.CargoPublisher; +import com.microsoft.cse.cargoprocessing.api.services.SchemaValidator; + +import reactor.core.publisher.Mono; + +import com.microsoft.cse.cargoprocessing.api.services.OperationPublisher; + +@SpringBootTest +@TestInstance(Lifecycle.PER_CLASS) +public class CargoControllerTest { + @MockBean + private CargoPublisher publisher; + + @MockBean + private SchemaValidator validator; + + @MockBean + private OperationPublisher operationPublisher; + + @Autowired + private CargoController controller; + + @BeforeEach + void configureMocks() { + when(operationPublisher.isNewOperation(any())).thenReturn(Mono.just(true)); + } + + @Test + void PutValidCargoHydratesAdditionContent() throws IOException { + String cargo = IOUtils.toString( + this.getClass().getResourceAsStream("/cargo-test-objects/basic-cargo.json"), + "UTF-8"); + + String id = UUID.randomUUID().toString(); + + Map headers = new HashMap<>(); + + Cargo results = controller.createCargo(id, cargo, headers).getBody(); + + assertEquals(id, results.getId()); + assertNotNull(results.getTimestamp()); + } + + @Test + void PostValidCargoHydratesAdditionContent() throws IOException { + String cargo = IOUtils.toString( + this.getClass().getResourceAsStream("/cargo-test-objects/basic-cargo.json"), + "UTF-8"); + + Map headers = new HashMap<>(); + + Cargo results = controller.createCargo(cargo, headers).getBody(); + + assertFalse(results.getId().isBlank()); + assertNotNull(results.getTimestamp()); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidatorTest.java b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidatorTest.java new file mode 100644 index 0000000..6014b39 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/java/com/microsoft/cse/cargoprocessing/api/services/SchemaValidatorTest.java @@ -0,0 +1,44 @@ +package com.microsoft.cse.cargoprocessing.api.services; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; + +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.cse.cargoprocessing.api.Exceptions.JsonValidationException; + +@SpringBootTest +public class SchemaValidatorTest { + @Autowired + private SchemaValidator validator; + + @Test + void UsingValidJsonAndSchema() throws IOException { + String cargo = IOUtils.toString( + this.getClass().getResourceAsStream("/cargo-test-objects/basic-cargo.json"), + "UTF-8"); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonCargo = mapper.readTree(cargo); + assertDoesNotThrow(() -> validator.validate("cargo", jsonCargo)); + + } + + @Test + void UsingInvalidSchema() throws IOException { + String cargo = IOUtils.toString( + this.getClass().getResourceAsStream("/cargo-test-objects/invalid-cargo-object.json"), + "UTF-8"); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonCargo = mapper.readTree(cargo); + + assertThrows(JsonValidationException.class, () -> validator.validate("cargo", jsonCargo)); + + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/application.properties b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/application.properties new file mode 100644 index 0000000..1382467 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/application.properties @@ -0,0 +1,7 @@ +APPLICATIONINSIGHTS_CONNECTION_STRING=$APPLICATIONINSIGHTS_CONNECTION_STRING +APPLICATIONINSIGHTS_VERSION=$APPLICATIONINSIGHTS_VERSION + +# Service Bus Information +spring.jms.servicebus.connection-string=Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=test-publisher;SharedAccessKey=not-a-real-value +spring.jms.servicebus.pricing-tier=basic +accelerator.queue-name=ingestor-queue \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/basic-cargo.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/basic-cargo.json new file mode 100644 index 0000000..43b8ce6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/basic-cargo.json @@ -0,0 +1,14 @@ +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-cargo-object.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-cargo-object.json new file mode 100644 index 0000000..074f012 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-cargo-object.json @@ -0,0 +1,14 @@ +{ + "product": { + "named": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-syntax.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-syntax.json new file mode 100644 index 0000000..02c07e9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-api/src/test/resources/cargo-test-objects/invalid-syntax.json @@ -0,0 +1,13 @@ +{ + "product": { + "name": "Toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000Z", + "end": "2022-06-30T00:00:00.000Z" + } diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/Dockerfile new file mode 100644 index 0000000..d821fc9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/Dockerfile @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16-bullseye + +RUN apt-get update && apt-get install -y \ + lsb-release \ + curl \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/devcontainer.json new file mode 100644 index 0000000..e576cbc --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "name": "cargo-processing-validator", + "build": { + "dockerfile": "Dockerfile" + }, + "extensions": [ + "dbaeumer.vscode-eslint", + "ms-vscode.vscode-typescript-tslint-plugin" + ], + "postCreateCommand": "npm install", + "remoteUser": "node" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore new file mode 100644 index 0000000..b2d59d1 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore @@ -0,0 +1,2 @@ +/node_modules +/dist \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore copy b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore copy new file mode 100644 index 0000000..2ce5e1c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.dockerignore copy @@ -0,0 +1,2 @@ +.env +helm diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.env.sample b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.env.sample new file mode 100644 index 0000000..3456a5a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.env.sample @@ -0,0 +1,6 @@ +SERVICE_BUS_CONNECTION_STRING="" +QUEUE_NAME="" +TOPIC_NAME="" +OPERATION_QUEUE_NAME="" +MAX_MESSAGE_DEQUEUE_COUNT=10 +APPLICATIONINSIGHTS_CONNECTION_STRING="" diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.gitignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.gitignore new file mode 100644 index 0000000..c7fb7a4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.gitignore @@ -0,0 +1,3 @@ +/node_modules +/dist +.env \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.vscode/launch.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.vscode/launch.json new file mode 100644 index 0000000..d25553b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "program": "${workspaceFolder}/src/index.ts", + "preLaunchTask": "tsc: build - tsconfig.json", + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/Dockerfile new file mode 100644 index 0000000..53072b4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/Dockerfile @@ -0,0 +1,12 @@ +FROM mcr.microsoft.com/cbl-mariner/base/nodejs:16 + +WORKDIR /usr/src/app + +COPY package*.json ./ +COPY tsconfig.json ./ +COPY . . + +RUN npm install +RUN npm run build + +CMD ["npm","run","start"] \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/README.md b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/README.md new file mode 100644 index 0000000..2bf75f8 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/README.md @@ -0,0 +1,48 @@ +# Running the service + +## Pre-Requisites + +1. Service Bus [namespace](https://docs.microsoft.com/cli/azure/servicebus/namespace?view=azure-cli-latest#az-servicebus-namespace-create) with [queue](https://docs.microsoft.com/cli/azure/servicebus/queue?view=azure-cli-latest#az-servicebus-queue-create) and [topic](https://docs.microsoft.com/cli/azure/servicebus/topic?view=azure-cli-latest#az-servicebus-topic-create) +1. Application Insights [account](https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource#azure-cli-preview) + +## Running from VSCode Dev Container + +* Open the project in the dev container. +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Transpile typescript - `npm run build`. If you want to have transpilation happen automatically when you save code changes, run `npm run watch-build` in a separate terminal window. +* Run javascript - `npm run start`. If you want to have the application restart on code changes, run `npm run watch` instead. +* Post a message to the the Service Bus Queue similar to the [sample message](#sample-message) + +## Docker Container + +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Run `docker compose up` to run the service. +* Post a message to the the Service Bus Queue similar to the [sample message](#sample-message) + +## Sample Message + +When posting a message to the service bus, also ensure a traceparent custom property has been set to a value that conforms pattern defined [by w3c](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format). + +For example a value like: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01 + +```json +{ + "operationId": "56bb0b4c-5c8c-4361-9771-25f997cf651b", + "data": { + "timestamp": "2022-07-29T00:00:00.000Z", + "id": "f725da7e-af18-4bf2-85f9-610504cc3d40", + "product": { + "name": "minerals", + "quantity": 2 + }, + "port": { + "source": "Boston", + "destination": "Charlotte" + }, + "demandDates": { + "start": "2022-07-28T00:00:00.000Z", + "end": "2022-07-29T00:00:00.000Z" + } + } +} +``` diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/docker-compose.yml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/docker-compose.yml new file mode 100644 index 0000000..e0c74ef --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/docker-compose.yml @@ -0,0 +1,9 @@ +version: "3.9" + +services: + cargo-processing-validator: + env_file: + - .env + build: + context: . + dockerfile: Dockerfile \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/.helmignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/Chart.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/Chart.yaml new file mode 100644 index 0000000..2051ee4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: cargo-processing-validator +description: cargo-processing-validator for aks-sb-azmonitor-microservices + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/cargo-processing-validator.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/cargo-processing-validator.yaml new file mode 100644 index 0000000..6389407 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/cargo-processing-validator.yaml @@ -0,0 +1,34 @@ +image: + pullPolicy: Always + tag: "latest" + +replicaCount: 1 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +podAnnotations: {} +podSecurityContext: {} +securityContext: {} +resources: {} +nodeSelector: {} +tolerations: [] +affinity: {} + +# When running one of the deploy-*.sh scripts, an additional env.yaml +# values file is created containing values specific to the deployed environment +# with the following values: +# image: +# repository: + +# keyVault: +# name: +# tenantId: + +# aksKeyVaultSecretProviderIdentityId: diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/NOTES.txt b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/NOTES.txt new file mode 100644 index 0000000..dd366ce --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aks-sb-azmonitor-microservices.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/_helpers.tpl b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/_helpers.tpl new file mode 100644 index 0000000..0172cb3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "aks-sb-azmonitor-microservices.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "aks-sb-azmonitor-microservices.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "aks-sb-azmonitor-microservices.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "aks-sb-azmonitor-microservices.labels" -}} +helm.sh/chart: {{ include "aks-sb-azmonitor-microservices.chart" . }} +{{ include "aks-sb-azmonitor-microservices.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "aks-sb-azmonitor-microservices.selectorLabels" -}} +app.kubernetes.io/name: {{ include "aks-sb-azmonitor-microservices.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "aks-sb-azmonitor-microservices.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "aks-sb-azmonitor-microservices.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/deployment.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/deployment.yaml new file mode 100644 index 0000000..0a2cb45 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: default + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: QUEUE_NAME + value: ingest-cargo + - name: TOPIC_NAME + value: validated-cargo + - name: OPERATION_QUEUE_NAME + value: operation-state + - name: MAX_MESSAGE_DEQUEUE_COUNT + value: "100" + - name: APPLICATIONINSIGHTS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: cargo-processing-validator-secrets + key: AppInsightsConnectionString + - name: SERVICE_BUS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: cargo-processing-validator-secrets + key: ServiceBusConnectionString + ports: + - name: http + containerPort: 8080 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: secrets-store + mountPath: "/mnt/secrets-store" + readOnly: true + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: secrets-store + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: {{ include "aks-sb-azmonitor-microservices.fullname" . }} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/hpa.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/hpa.yaml new file mode 100644 index 0000000..0a3ca97 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/secretProviderClass.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/secretProviderClass.yaml new file mode 100644 index 0000000..279d7c7 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/secretProviderClass.yaml @@ -0,0 +1,31 @@ +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + provider: azure + parameters: + usePodIdentity: "false" + useVMManagedIdentity: "true" + userAssignedIdentityID: {{ .Values.aksKeyVaultSecretProviderIdentityId }} + keyvaultName: {{ .Values.keyVault.name }} + cloudName: "" + objects: | + array: + - | + objectName: AppInsightsConnectionString + objectType: secret + - | + objectName: ServiceBusConnectionString + objectType: secret + tenantId: {{ .Values.keyVault.tenantId }} + secretObjects: + - data: + - key: AppInsightsConnectionString + objectName: AppInsightsConnectionString + - key: ServiceBusConnectionString + objectName: ServiceBusConnectionString + secretName: cargo-processing-validator-secrets + type: Opaque \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/service.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/service.yaml new file mode 100644 index 0000000..af3f13a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 4 }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/tests/test-connection.yaml b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5eb4bc4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "aks-sb-azmonitor-microservices.fullname" . }}-test-connection" + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "aks-sb-azmonitor-microservices.fullname" . }}:80'] + restartPolicy: Never diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json new file mode 100644 index 0000000..40c855d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json @@ -0,0 +1,4565 @@ +{ + "name": "cargo-processing-validator", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "cargo-processing-validator", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@azure/service-bus": "^7.5.1", + "ajv": "^8.11.0", + "applicationinsights": "^2.3.3", + "dotenv": "^16.0.1", + "luxon": "^2.4.0", + "typescript": "^4.7.4" + }, + "devDependencies": { + "@types/chai": "^4.3.1", + "@types/luxon": "^2.3.2", + "@types/mocha": "^9.1.1", + "chai": "^4.3.6", + "mocha": "^10.0.0", + "nodemon": "^2.0.20", + "ts-node": "^10.8.1" + } + }, + "node_modules/@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-amqp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-3.1.0.tgz", + "integrity": "sha512-TyI0WFNrVb0EkRg36UwdcqR/7n9YpcEw64O4xVrgzMAlXIciVZpabl05C/Q0iUvLkItmez2XSVDduncjr02oGw==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/logger": "^1.0.0", + "buffer": "^6.0.0", + "events": "^3.0.0", + "jssha": "^3.1.0", + "process": "^0.11.10", + "rhea": "^2.0.3", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0", + "url": "^0.11.0", + "util": "^0.12.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-asynciterator-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz", + "integrity": "sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.3.2.tgz", + "integrity": "sha512-7CU6DmCHIZp5ZPiZ9r3J17lTKMmYsm/zGvNkjArQwPkrLlZ1TZ+EUYfGgh2X31OLMVAQCTJZW4cXHJi02EbJnA==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-http": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.5.tgz", + "integrity": "sha512-kctMqSQ6zfnlFpuYzfUKadeTyOQYbIQ+3Rj7dzVC3Dk1dOnHroTwR9hLYKX8/n85iJpkyaksaXpuh5L7GJRYuQ==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tough-cookie": "^4.0.0", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.4.19" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-paging": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.3.0.tgz", + "integrity": "sha512-H6Tg9eBm0brHqLy0OSAGzxIh1t4UL8eZVrSUMJ60Ra9cwq2pOskFqVpz2pYoHDsBY1jZ4V/P8LRGb5D5pmC6rg==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", + "integrity": "sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/service-bus": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.5.1.tgz", + "integrity": "sha512-fIbI5aJDzN2HctcS+3i7rXY3L5jWG7/SuXOq0cMpwy+aH5aHOZVoxX8eeSnUnr2jUpUflU1wJ9yiYZ/sXqZvqw==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-amqp": "^3.1.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-http": "^2.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "@types/is-buffer": "^2.0.0", + "@types/long": "^4.0.1", + "buffer": "^6.0.0", + "is-buffer": "^2.0.3", + "jssha": "^3.1.0", + "long": "^4.0.0", + "process": "^0.11.10", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz", + "integrity": "sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.3.0.tgz", + "integrity": "sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.8.0.tgz", + "integrity": "sha512-6SDjwBML4Am0AQmy7z1j6HGrWDgeK8awBRUvl1PGw6HayViMk4QpnUXvv4HTHisecgVBy43NE/cstWprm8tIfw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.8.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.4.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.8.0.tgz", + "integrity": "sha512-KSyMH6Jvss/PFDy16z5qkCK0ERlpyqixb1xwb73wLMvVq+j7i89lobDjw3JkpCcd1Ws0J6jAI4fw28Zufj2ssg==", + "dependencies": { + "@opentelemetry/core": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.4.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.8.0.tgz", + "integrity": "sha512-iH41m0UTddnCKJzZx3M85vlhKzRcmT48pUeBbnzsGrq4nIay1oWVHKM5nhB5r8qRDGvd/n7f/YLCXClxwM0tvA==", + "dependencies": { + "@opentelemetry/core": "1.8.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.4.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.8.0.tgz", + "integrity": "sha512-TYh1MRcm4JnvpqtqOwT9WYaBYY4KERHdToxs/suDTLviGRsQkIjS5yYROTYTSJQUnYLOn/TuOh5GoMwfLSU+Ew==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "dev": true + }, + "node_modules/@types/is-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.0.tgz", + "integrity": "sha512-0f7N/e3BAz32qDYvgB4d2cqv1DqUwvGxHkXsrucICn8la1Vb6Yl6Eg8mPScGwUiqHJeE7diXlzaK+QMA9m4Gxw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/luxon": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.2.tgz", + "integrity": "sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" + }, + "node_modules/@types/node-fetch": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/tunnel": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", + "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/applicationinsights": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.3.3.tgz", + "integrity": "sha512-Q4o6gexNhzukgmzzWYzXLa2gdJ6DhM+c35tw0lRNNjc/qldWxGHVxV65DMRYrQIp4vetLdCK7Pyd/dmEsGO4qA==", + "dependencies": { + "@azure/core-http": "^2.2.3", + "@opentelemetry/api": "^1.0.4", + "@opentelemetry/core": "^1.0.1", + "@opentelemetry/sdk-trace-base": "^1.0.1", + "@opentelemetry/semantic-conventions": "^1.0.1", + "cls-hooked": "^4.2.2", + "continuation-local-storage": "^3.2.1", + "diagnostic-channel": "1.1.0", + "diagnostic-channel-publishers": "1.0.5" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "applicationinsights-native-metrics": "*" + }, + "peerDependenciesMeta": { + "applicationinsights-native-metrics": { + "optional": true + } + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/async-hook-jl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "dependencies": { + "stack-chain": "^1.3.7" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3" + } + }, + "node_modules/async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "dependencies": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "engines": { + "node": "<=0.11.8 || >0.11.10" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cls-hooked": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", + "dependencies": { + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "dependencies": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diagnostic-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz", + "integrity": "sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ==", + "dependencies": { + "semver": "^5.3.0" + } + }, + "node_modules/diagnostic-channel-publishers": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz", + "integrity": "sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg==", + "peerDependencies": { + "diagnostic-channel": "*" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", + "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "dependencies": { + "shimmer": "^1.2.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/jssha": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", + "integrity": "sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==", + "engines": { + "node": "*" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/luxon": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.4.0.tgz", + "integrity": "sha512-w+NAwWOUL5hO0SgwOHsMBAmZ15SoknmQXhSO0hIbJCAmPKSsGeK8MlmhYh2w6Iib38IxN2M+/ooXWLbeis7GuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rhea": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/rhea/-/rhea-2.0.8.tgz", + "integrity": "sha512-IgwlP4D2lzinBSll5f35tAWa30dGCZhG9Ujd1DiaB7MUGegIjAaLzqATCw3ha+h9oq9mXcitqayBbNIXYdvtFg==", + "dependencies": { + "debug": "0.8.0 - 3.5.0" + } + }, + "node_modules/rhea-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-2.1.0.tgz", + "integrity": "sha512-CRMwdJ/o4oO/xKcvAwAsd0AHy5fVvSlqso7AadRmaaLGzAzc9LCoW7FOFnucI8THasVmOeCnv5c/fH/n7FcNaA==", + "dependencies": { + "debug": "^3.1.0", + "rhea": "^2.0.3", + "tslib": "^2.2.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/stack-chain": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-node": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-amqp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-3.1.0.tgz", + "integrity": "sha512-TyI0WFNrVb0EkRg36UwdcqR/7n9YpcEw64O4xVrgzMAlXIciVZpabl05C/Q0iUvLkItmez2XSVDduncjr02oGw==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/logger": "^1.0.0", + "buffer": "^6.0.0", + "events": "^3.0.0", + "jssha": "^3.1.0", + "process": "^0.11.10", + "rhea": "^2.0.3", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0", + "url": "^0.11.0", + "util": "^0.12.1" + } + }, + "@azure/core-asynciterator-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz", + "integrity": "sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw==" + }, + "@azure/core-auth": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.3.2.tgz", + "integrity": "sha512-7CU6DmCHIZp5ZPiZ9r3J17lTKMmYsm/zGvNkjArQwPkrLlZ1TZ+EUYfGgh2X31OLMVAQCTJZW4cXHJi02EbJnA==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-http": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.5.tgz", + "integrity": "sha512-kctMqSQ6zfnlFpuYzfUKadeTyOQYbIQ+3Rj7dzVC3Dk1dOnHroTwR9hLYKX8/n85iJpkyaksaXpuh5L7GJRYuQ==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tough-cookie": "^4.0.0", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.4.19" + } + }, + "@azure/core-paging": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.3.0.tgz", + "integrity": "sha512-H6Tg9eBm0brHqLy0OSAGzxIh1t4UL8eZVrSUMJ60Ra9cwq2pOskFqVpz2pYoHDsBY1jZ4V/P8LRGb5D5pmC6rg==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "requires": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + } + }, + "@azure/logger": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", + "integrity": "sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/service-bus": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.5.1.tgz", + "integrity": "sha512-fIbI5aJDzN2HctcS+3i7rXY3L5jWG7/SuXOq0cMpwy+aH5aHOZVoxX8eeSnUnr2jUpUflU1wJ9yiYZ/sXqZvqw==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-amqp": "^3.1.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-http": "^2.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "@types/is-buffer": "^2.0.0", + "@types/long": "^4.0.1", + "buffer": "^6.0.0", + "is-buffer": "^2.0.3", + "jssha": "^3.1.0", + "long": "^4.0.0", + "process": "^0.11.10", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0" + } + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz", + "integrity": "sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@opentelemetry/api": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.3.0.tgz", + "integrity": "sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ==" + }, + "@opentelemetry/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.8.0.tgz", + "integrity": "sha512-6SDjwBML4Am0AQmy7z1j6HGrWDgeK8awBRUvl1PGw6HayViMk4QpnUXvv4HTHisecgVBy43NE/cstWprm8tIfw==", + "requires": { + "@opentelemetry/semantic-conventions": "1.8.0" + } + }, + "@opentelemetry/resources": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.8.0.tgz", + "integrity": "sha512-KSyMH6Jvss/PFDy16z5qkCK0ERlpyqixb1xwb73wLMvVq+j7i89lobDjw3JkpCcd1Ws0J6jAI4fw28Zufj2ssg==", + "requires": { + "@opentelemetry/core": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" + } + }, + "@opentelemetry/sdk-trace-base": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.8.0.tgz", + "integrity": "sha512-iH41m0UTddnCKJzZx3M85vlhKzRcmT48pUeBbnzsGrq4nIay1oWVHKM5nhB5r8qRDGvd/n7f/YLCXClxwM0tvA==", + "requires": { + "@opentelemetry/core": "1.8.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.8.0.tgz", + "integrity": "sha512-TYh1MRcm4JnvpqtqOwT9WYaBYY4KERHdToxs/suDTLviGRsQkIjS5yYROTYTSJQUnYLOn/TuOh5GoMwfLSU+Ew==" + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/chai": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "dev": true + }, + "@types/is-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.0.tgz", + "integrity": "sha512-0f7N/e3BAz32qDYvgB4d2cqv1DqUwvGxHkXsrucICn8la1Vb6Yl6Eg8mPScGwUiqHJeE7diXlzaK+QMA9m4Gxw==", + "requires": { + "@types/node": "*" + } + }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "@types/luxon": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.2.tgz", + "integrity": "sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA==", + "dev": true + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "@types/node": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" + }, + "@types/node-fetch": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "@types/tunnel": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", + "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", + "requires": { + "@types/node": "*" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "applicationinsights": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.3.3.tgz", + "integrity": "sha512-Q4o6gexNhzukgmzzWYzXLa2gdJ6DhM+c35tw0lRNNjc/qldWxGHVxV65DMRYrQIp4vetLdCK7Pyd/dmEsGO4qA==", + "requires": { + "@azure/core-http": "^2.2.3", + "@opentelemetry/api": "^1.0.4", + "@opentelemetry/core": "^1.0.1", + "@opentelemetry/sdk-trace-base": "^1.0.1", + "@opentelemetry/semantic-conventions": "^1.0.1", + "cls-hooked": "^4.2.2", + "continuation-local-storage": "^3.2.1", + "diagnostic-channel": "1.1.0", + "diagnostic-channel-publishers": "1.0.5" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async-hook-jl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "requires": { + "stack-chain": "^1.3.7" + } + }, + "async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "cls-hooked": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", + "requires": { + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "diagnostic-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz", + "integrity": "sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ==", + "requires": { + "semver": "^5.3.0" + } + }, + "diagnostic-channel-publishers": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz", + "integrity": "sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg==", + "requires": {} + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "dotenv": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", + "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==" + }, + "emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "requires": { + "shimmer": "^1.2.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "jssha": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", + "integrity": "sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==" + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "luxon": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.4.0.tgz", + "integrity": "sha512-w+NAwWOUL5hO0SgwOHsMBAmZ15SoknmQXhSO0hIbJCAmPKSsGeK8MlmhYh2w6Iib38IxN2M+/ooXWLbeis7GuA==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + } + } + }, + "mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "rhea": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/rhea/-/rhea-2.0.8.tgz", + "integrity": "sha512-IgwlP4D2lzinBSll5f35tAWa30dGCZhG9Ujd1DiaB7MUGegIjAaLzqATCw3ha+h9oq9mXcitqayBbNIXYdvtFg==", + "requires": { + "debug": "0.8.0 - 3.5.0" + } + }, + "rhea-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-2.1.0.tgz", + "integrity": "sha512-CRMwdJ/o4oO/xKcvAwAsd0AHy5fVvSlqso7AadRmaaLGzAzc9LCoW7FOFnucI8THasVmOeCnv5c/fH/n7FcNaA==", + "requires": { + "debug": "^3.1.0", + "rhea": "^2.0.3", + "tslib": "^2.2.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "stack-chain": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "ts-node": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + } + }, + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package.json new file mode 100644 index 0000000..ca40c2d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package.json @@ -0,0 +1,32 @@ +{ + "name": "cargo-processing-validator", + "version": "1.0.0", + "description": "node based microservice", + "main": "dist/index.js", + "scripts": { + "build": "tsc -p .", + "start": "node ./dist/index.js", + "watch": "nodemon ./dist/index.js", + "watch-build": "tsc -w -p .", + "test": "mocha -r ts-node/register src/tests/**/*.ts" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@azure/service-bus": "^7.5.1", + "ajv": "^8.11.0", + "applicationinsights": "^2.3.3", + "dotenv": "^16.0.1", + "luxon": "^2.4.0", + "typescript": "^4.7.4" + }, + "devDependencies": { + "@types/chai": "^4.3.1", + "@types/luxon": "^2.3.2", + "@types/mocha": "^9.1.1", + "chai": "^4.3.6", + "mocha": "^10.0.0", + "nodemon": "^2.0.20", + "ts-node": "^10.8.1" + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ChaosMonkey.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ChaosMonkey.ts new file mode 100644 index 0000000..963d90d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ChaosMonkey.ts @@ -0,0 +1,29 @@ +import { ServiceBusReceivedMessage } from '@azure/service-bus'; +import { Cargo } from '../models/Cargo'; +import { ServiceBusReceiverWithTelemetry } from '../services/ServiceBusWithTelemetry'; + +export abstract class ChaosMonkey { + chaosTrigger: string; + serviceTrigger: string = "cargo-processing-validator"; + private queueReceiver: ServiceBusReceiverWithTelemetry; + + constructor(chaosTrigger: string, queueReceiver: ServiceBusReceiverWithTelemetry) { + this.chaosTrigger = chaosTrigger; + this.queueReceiver = queueReceiver; + } + + canWakeTheMonkey(cargo: Cargo): boolean { + return cargo.port.source == this.serviceTrigger && cargo.port.destination == this.chaosTrigger; + } + + async rattleTheCage(message: ServiceBusReceivedMessage, cargo: Cargo, parameters?: Map): Promise { + if (this.canWakeTheMonkey(cargo)) { + // Need to make sure we complete the message, otherwise the chaos will not end until the + // message has been dequeued the maximum amount of times + await this.queueReceiver.completeMessage(message); + await this.wakeTheMonkey(parameters); + } + } + + abstract wakeTheMonkey(parameters?: Map): Promise; +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ProcessEndingMonkey.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ProcessEndingMonkey.ts new file mode 100644 index 0000000..c0bcc32 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ProcessEndingMonkey.ts @@ -0,0 +1,12 @@ +import { ServiceBusReceiverWithTelemetry } from "../services/ServiceBusWithTelemetry"; +import { ChaosMonkey } from "./ChaosMonkey"; + +export class ProcessEndingMonkey extends ChaosMonkey { + constructor(queueReceiver: ServiceBusReceiverWithTelemetry) { + super("process-ending", queueReceiver); + } + + wakeTheMonkey(parameters?: Map): Promise { + process.exit(); + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ServiceBusKillingMonkey.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ServiceBusKillingMonkey.ts new file mode 100644 index 0000000..5f0b646 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/chaos/ServiceBusKillingMonkey.ts @@ -0,0 +1,14 @@ +import { ServiceBusSender } from '@azure/service-bus'; +import { ServiceBusReceiverWithTelemetry } from '../services/ServiceBusWithTelemetry'; +import { ChaosMonkey } from "./ChaosMonkey"; + +export class ServiceBusKillingMonkey extends ChaosMonkey { + constructor(queueReceiver: ServiceBusReceiverWithTelemetry) { + super("service-bus-failure", queueReceiver); + } + + async wakeTheMonkey(parameters: Map): Promise { + const sender = parameters.get("sender") as ServiceBusSender; + await sender.close(); + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/index.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/index.ts new file mode 100644 index 0000000..075eb4e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/index.ts @@ -0,0 +1,98 @@ +import { config } from 'dotenv'; +import { CargoValidationService } from './services/CargoValidationService'; +import * as appInsights from 'applicationinsights'; +import { CUSTOM_PROPERTY_CARGO_DESTINATION, CUSTOM_PROPERTY_CARGO_ID, CUSTOM_PROPERTY_CARGO_OPERATION_ID, CUSTOM_PROPERTY_CARGO_VALID, ServiceBusProcessingService } from './services/ServiceBusProcessingService'; +import { CUSTOM_PROPERTY_REQUEST_PARENT_ID } from './services/ServiceBusWithTelemetry'; + +// load environment variables +config(); + + +// start application insights and allow console.log to export logs +// see configuration details at https://docs.microsoft.com/en-us/azure/azure-monitor/app/nodejs#sdk-configuration +appInsights + .setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING) + .setAutoDependencyCorrelation(true) + .setAutoCollectRequests(true) + // .setAutoCollectPerformance(true, true) // uncomment to send performance metrics (note this will increase the amount of data sent to Azure Monitor) + // .setSendLiveMetrics(true) + .setAutoCollectExceptions(true) + .setAutoCollectDependencies(true) + .setAutoCollectConsole(true, true) + .setUseDiskRetryCaching(true) + .setDistributedTracingMode(appInsights.DistributedTracingModes.AI_AND_W3C) + .start(); + + + +const client = appInsights.defaultClient; +client.context.tags[client.context.keys.cloudRole] = 'cargo-processing-validator'; + +// Automatically add tags for operationID/ParentID if set in correlation context +client.addTelemetryProcessor((envelope, contextObjects) => { + if (envelope?.data?.baseData?.properties) { + const azNamespace = envelope.data.baseData.properties["az.namespace"]; + if (azNamespace === "Microsoft.ServiceBus") { + // This is a telemetry item that was auto-generated by the Azure SDK + // Return false to suppress it as we are replacing with our own telemetry + // which contains additional metadata + return false; + // If you wish to suppress individual message types use conditions such as: + // envelope?.data?.baseData?.name === "Azure.ServiceBus.message" + } + } + + + // If we have the cargo-operation-id in the correlation context, add it to the telemetry + const customProperties = contextObjects?.correlationContext?.customProperties; + const operation = contextObjects?.correlationContext?.operation; + const envelopeProperties = envelope.data?.baseData?.properties; + const telemetryType = envelope.data?.baseType; + + if (envelopeProperties && customProperties?.getProperty(CUSTOM_PROPERTY_CARGO_ID)) { + envelopeProperties["cargo-id"] = customProperties.getProperty(CUSTOM_PROPERTY_CARGO_ID); + } + if (envelopeProperties && customProperties?.getProperty(CUSTOM_PROPERTY_CARGO_OPERATION_ID)) { + envelopeProperties["cargo-operation-id"] = customProperties.getProperty(CUSTOM_PROPERTY_CARGO_OPERATION_ID); + } + if (envelopeProperties && customProperties?.getProperty(CUSTOM_PROPERTY_CARGO_VALID)) { + envelopeProperties["cargo-valid"] = customProperties.getProperty(CUSTOM_PROPERTY_CARGO_VALID); + } + if (envelopeProperties && customProperties?.getProperty(CUSTOM_PROPERTY_CARGO_DESTINATION)) { + envelopeProperties["cargo-destination"] = customProperties.getProperty(CUSTOM_PROPERTY_CARGO_DESTINATION); + } + // ensure dependencies are children of the ServiceBus.ProcessMessage request + if (telemetryType && telemetryType == 'RemoteDependencyData' && operation && customProperties?.getProperty(CUSTOM_PROPERTY_REQUEST_PARENT_ID)) { + operation.parentId = customProperties?.getProperty(CUSTOM_PROPERTY_REQUEST_PARENT_ID); + envelope.tags['ai.operation.parentId'] = customProperties?.getProperty(CUSTOM_PROPERTY_REQUEST_PARENT_ID); + } + + return true; +}); + +const cargoValidationService: CargoValidationService = + new CargoValidationService(client); + +const serviceBusProcessingService: ServiceBusProcessingService = + new ServiceBusProcessingService( + process.env.SERVICE_BUS_CONNECTION_STRING as string, + process.env.QUEUE_NAME as string, + process.env.TOPIC_NAME as string, + process.env.OPERATION_QUEUE_NAME as string, + parseInt(process.env.MAX_MESSAGE_DEQUEUE_COUNT as string), + cargoValidationService, + client + ); + +(async function () { + try { + console.log("Queue processing starting..."); + await serviceBusProcessingService.startProcessingQueueMessages(); + console.log("Queue processing started"); + } catch (e: any) { + // throwing the error causes the container to self-destruct + // exceptions and other telemetry events from the original request are not logged to application insights + // code to log an explicit exception here would be: client.trackException({ exception: e, severity: SeverityLevel.Error }); + throw e; + } +})(); diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/Cargo.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/Cargo.ts new file mode 100644 index 0000000..fe3581f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/Cargo.ts @@ -0,0 +1,16 @@ +export interface Cargo { + timestamp: Date; + id: string; + product: { + name: string; + quantity: number; + }; + port: { + source: string; + destination: string; + }; + demandDates: { + start: Date; + end: Date; + }; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/MessageEnvelope.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/MessageEnvelope.ts new file mode 100644 index 0000000..398ac9d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/MessageEnvelope.ts @@ -0,0 +1,6 @@ +import { Cargo } from './Cargo'; + +export interface MessageEnvelope { + operationId: string; + data: Cargo; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/ValidatedCargo.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/ValidatedCargo.ts new file mode 100644 index 0000000..8faafea --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/models/ValidatedCargo.ts @@ -0,0 +1,6 @@ +import { Cargo } from './Cargo'; + +export interface ValidatedCargo extends Cargo { + valid: boolean; + errorMessage: string | null; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/schemas/cargo-envelope-schema.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/schemas/cargo-envelope-schema.json new file mode 100644 index 0000000..f42216a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/schemas/cargo-envelope-schema.json @@ -0,0 +1,186 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "title": "messageEnvelope", + "required": [ + "operationId", + "data" + ], + "properties": { + "operationId": { + "title": "The operationId Schema", + "type": "string", + "default": "", + "examples": [ + "f725da7e-af18-4bf2-85f9-610504cc3d40" + ] + }, + "data": { + "title": "The data Schema", + "type": "object", + "default": {}, + "required": [ + "timestamp", + "id", + "product", + "port", + "demandDates" + ], + "properties": { + "timestamp": { + "title": "The timestamp Schema", + "type": "string", + "default": "", + "examples": [ + "2022-07-29T00:00:00.000Z" + ] + }, + "id": { + "title": "The id Schema", + "type": "string", + "default": "", + "examples": [ + "f725da7e-af18-4bf2-85f9-610504cc3d40" + ] + }, + "product": { + "title": "The product Schema", + "type": "object", + "default": {}, + "required": [ + "name", + "quantity" + ], + "properties": { + "name": { + "title": "The name Schema", + "type": "string", + "default": "", + "examples": [ + "minerals" + ] + }, + "quantity": { + "title": "The quantity Schema", + "type": "integer", + "default": 0, + "examples": [ + 2 + ] + } + }, + "examples": [ + { + "name": "minerals", + "quantity": 2 + } + ] + }, + "port": { + "title": "The port Schema", + "type": "object", + "default": {}, + "required": [ + "source", + "destination" + ], + "properties": { + "source": { + "title": "The source Schema", + "type": "string", + "default": "", + "examples": [ + "Boston" + ] + }, + "destination": { + "title": "The destination Schema", + "type": "string", + "default": "", + "examples": [ + "Charlotte" + ] + } + }, + "examples": [ + { + "source": "Boston", + "destination": "Charlotte" + } + ] + }, + "demandDates": { + "title": "The demandDates Schema", + "type": "object", + "default": {}, + "required": [ + "start", + "end" + ], + "properties": { + "start": { + "title": "The start Schema", + "type": "string", + "default": "", + "examples": [ + "2022-07-28T00:00:00.000Z" + ] + }, + "end": { + "title": "The end Schema", + "type": "string", + "default": "", + "examples": [ + "2022-07-29T00:00:00.000Z" + ] + } + }, + "examples": [ + { + "start": "2022-07-28T00:00:00.000Z", + "end": "2022-07-29T00:00:00.000Z" + } + ] + } + }, + "examples": [ + { + "timestamp": "2022-07-29T00:00:00.000Z", + "id": "56bb0b4c-5c8c-4361-9771-25f997cf651b", + "product": { + "name": "minerals", + "quantity": 2 + }, + "port": { + "source": "Boston", + "destination": "Charlotte" + }, + "demandDates": { + "start": "2022-07-28T00:00:00.000Z", + "end": "2022-07-29T00:00:00.000Z" + } + } + ] + } + }, + "examples": [ + { + "operationId": "f725da7e-af18-4bf2-85f9-610504cc3d40", + "data": { + "timestamp": "2022-07-29T00:00:00.000Z", + "id": "f725da7e-af18-4bf2-85f9-610504cc3d40", + "product": { + "name": "minerals", + "quantity": 2 + }, + "port": { + "source": "Boston", + "destination": "Charlotte" + }, + "demandDates": { + "start": "2022-07-28T00:00:00.000Z", + "end": "2022-07-29T00:00:00.000Z" + } + } + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoSchemaValidation.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoSchemaValidation.ts new file mode 100644 index 0000000..8618d31 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoSchemaValidation.ts @@ -0,0 +1,25 @@ +import Ajv from 'ajv'; +import * as cargoEnvelopeSchema from '../schemas/cargo-envelope-schema.json'; + +export class CargoSchemaValidation { + private ajv: Ajv; + private validator; + + constructor() { + this.ajv = new Ajv(); + this.validator = this.ajv.compile(cargoEnvelopeSchema); + } + + validate(cargo: string) { + console.log('Validating cargo schema'); + const results = this.validator(cargo); + if (results) { + return { isValid: true }; + } else { + return { + isValid: false, + message: JSON.stringify(this.validator.errors), + }; + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoValidationService.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoValidationService.ts new file mode 100644 index 0000000..aed9a13 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/CargoValidationService.ts @@ -0,0 +1,149 @@ +import { Cargo } from '../models/Cargo'; +import { ValidatedCargo } from '../models/ValidatedCargo'; +import { DateTime, Duration } from 'luxon'; +import { TelemetryService } from './TelemetryService'; +import * as appInsights from 'applicationinsights'; + +export class CargoValidationService { + private telemetryClient: appInsights.TelemetryClient; + + constructor(telemetryClient : appInsights.TelemetryClient) { + this.telemetryClient = telemetryClient; + } + async validateCargo(cargo: Cargo): Promise { + console.log('Validating cargo properties'); + + let isValid: boolean = true; + let errorMessage: string | null = null; + + // start, end, and timestamp are epoch times on the incoming message + const start: DateTime = DateTime.fromJSDate( + new Date(cargo.demandDates.start) + ); + const end: DateTime = DateTime.fromJSDate(new Date(cargo.demandDates.end)); + const now: DateTime = DateTime.now(); + const diffBetweenStartAndNow: Duration = start.diff(now, 'days'); + const diffBetweenStartAndEnd: Duration = end.diff(start, 'days'); + + // validate start and end are in future + if (start <= now || end <= now) { + isValid = false; + errorMessage = 'Start and end dates must be in future.'; + } + + // validate start is not more than 60 days in future + if (diffBetweenStartAndNow.days > 60) { + isValid = false; + errorMessage = 'Start date cannot be more than 60 days in future.'; + } + + // validate range is not greater than 30 days + if (diffBetweenStartAndEnd.days > 30) { + isValid = false; + errorMessage = 'Range between start and end dates cannot exceed 30 days.'; + } + + // validate end date is after start date + if (diffBetweenStartAndEnd.days < 0) { + isValid = false; + errorMessage = 'End date must be after start date.'; + } + + // validate destination port + const destinationPortOk = await this.checkDestinationPort(cargo.port.destination); + if (!destinationPortOk) { + isValid = false; + errorMessage = 'Rejected by destination port.'; + } + + console.log(`Valid - ${isValid}, Error message - ${errorMessage}`); + const validatedMessageBody: ValidatedCargo = { + ...cargo, + valid: isValid, + errorMessage, + }; + return validatedMessageBody; + } + + private async executeDependency( + dependency: () => Promise, + dependencyTarget: string, + dependencyTypeName: string, + properties?: { [key: string]: any; } + ): Promise { + const dependencyId: string = TelemetryService.generateOpenTelemetryDependencyId(); + const dependencyStart: bigint = process.hrtime.bigint(); + + const dependencyName = `${dependencyTypeName} ${dependencyTarget}` + + try { + // Make the dependency call + const result = await (dependency()); + + // track dependencies in application insights, ensure they are properly parented + const dependencyEnd: bigint = process.hrtime.bigint(); + this.telemetryClient.trackDependency({ + target: dependencyTarget, + name: dependencyName, + data: '', + duration: TelemetryService.returnElapsedMillisecondsSinceStart( + dependencyStart, + dependencyEnd + ), + resultCode: 200, + success: true, + dependencyTypeName, + id: dependencyId, + properties, + }); + + return result; + } catch (error) { + const dependencyEnd: bigint = process.hrtime.bigint(); + + // track dependencies in application insights, ensure they are properly parented + this.telemetryClient.trackDependency({ + target: dependencyTarget, + name: dependencyName, + data: '', + duration: TelemetryService.returnElapsedMillisecondsSinceStart( + dependencyStart, + dependencyEnd + ), + resultCode: 500, + success: false, + dependencyTypeName, + id: dependencyId, + properties, + }); + + throw error; + } + } + + private async checkDestinationPort(name: string) : Promise { + const _internal = async (name : string) : Promise => { + // This method is used to mock out calling an HTTP service at the destination port + // The intent is to show how telemetry can be used to track variations in behavior + switch (name) { + case "slow-port": + // Simulate an issue with the port response times by adding a delay + await this.sleep(2000) + return true + + default: + await this.sleep(100) + return true; + } + } + return await this.executeDependency( + () => _internal(name), + name, + "destination-port-check", + ) + } + + private sleep(time: number) { + return new Promise(resolve => setTimeout(resolve, time)); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusProcessingService.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusProcessingService.ts new file mode 100644 index 0000000..5b1867d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusProcessingService.ts @@ -0,0 +1,192 @@ +import { Cargo } from '../models/Cargo'; +import { MessageEnvelope } from '../models/MessageEnvelope'; +import { ProcessEndingMonkey } from '../chaos/ProcessEndingMonkey'; +import { ServiceBusKillingMonkey } from '../chaos/ServiceBusKillingMonkey'; +import { + OperationOptionsBase, + ProcessErrorArgs, + ServiceBusClient, + ServiceBusMessage, + ServiceBusReceivedMessage, +} from '@azure/service-bus'; +import { CargoValidationService } from './CargoValidationService'; +import { CargoSchemaValidation } from './CargoSchemaValidation'; + +import { ServiceBusSenderWithTelemetry, ServiceBusReceiverWithTelemetry } from './ServiceBusWithTelemetry'; +import * as appInsights from 'applicationinsights'; + +export const CUSTOM_PROPERTY_CARGO_ID = 'cargo-id'; +export const CUSTOM_PROPERTY_CARGO_OPERATION_ID = 'cargo-operation-id'; +export const CUSTOM_PROPERTY_CARGO_VALID = 'cargo-valid'; +export const CUSTOM_PROPERTY_CARGO_DESTINATION = 'cargo-destination'; + +export class ServiceBusProcessingService { + private connectionString: string; + private queueName: string; + private topicName: string; + private operationQueueName: string; + private maxMessageDequeueCount: number; + private serviceBusClient: ServiceBusClient; + private cargoValidationService: CargoValidationService; + private telemetryClient: appInsights.TelemetryClient; + private cargoSchemaValidator: CargoSchemaValidation; + + private queueReceiver: ServiceBusReceiverWithTelemetry; + private operationStateSender: ServiceBusSenderWithTelemetry; + private topicSender: ServiceBusSenderWithTelemetry; + private processKillingMonkey: ProcessEndingMonkey; + private serviceBusKillingMonkey: ServiceBusKillingMonkey; + + constructor( + connectionString: string, + queueName: string, + topicName: string, + operationQueueName: string, + maxMessageDequeueCount: number, + cargoValidationService: CargoValidationService, + telemetryClient: appInsights.TelemetryClient + ) { + this.connectionString = connectionString; + this.queueName = queueName; + this.topicName = topicName; + this.operationQueueName = operationQueueName; + this.maxMessageDequeueCount = maxMessageDequeueCount; + this.cargoValidationService = cargoValidationService; + this.telemetryClient = telemetryClient; + this.serviceBusClient = new ServiceBusClient(this.connectionString); + + this.queueReceiver = new ServiceBusReceiverWithTelemetry( + this.serviceBusClient.createReceiver(this.queueName), + this.telemetryClient); + this.operationStateSender = new ServiceBusSenderWithTelemetry( + this.serviceBusClient.createSender(this.operationQueueName), + this.telemetryClient); + this.topicSender = new ServiceBusSenderWithTelemetry( + this.serviceBusClient.createSender(this.topicName), + this.telemetryClient); + + this.cargoSchemaValidator = new CargoSchemaValidation(); + + this.processKillingMonkey = new ProcessEndingMonkey(this.queueReceiver); + this.serviceBusKillingMonkey = new ServiceBusKillingMonkey(this.queueReceiver); + } + + startProcessingQueueMessages(): { close(): Promise } { + const response = this.queueReceiver.subscribe({ + processMessage: this.processMessageFromQueue.bind(this), + processError: async (args: ProcessErrorArgs) => { + console.log(args); // Write to console. The receiver already tracks the exception. + // exit the process and allow scheduler to restart + process.exit(1); + } + }, { + autoCompleteMessages: false, + maxConcurrentCalls: this.maxMessageDequeueCount, + }); + return response; + } + + private async processMessageFromQueue(message: ServiceBusReceivedMessage) { + // validate message schema + const validSchema = this.cargoSchemaValidator.validate( + message.body + ); + + if (!validSchema.isValid) { + console.log('Dead lettering message'); + await this.queueReceiver.deadLetterMessage( + message, + { + deadLetterReason: 'Invalid message structure', + deadLetterErrorDescription: validSchema.message!, + } + ); + // Can't update operation state if we can't be sure the message + // structure actually has an operationId, no try catch needed + } else { + await this.processValidCargoMessage(message); + } + } + + private async processValidCargoMessage(message: ServiceBusReceivedMessage) { + const messageEnvelope = message.body as MessageEnvelope; + const cargo: Cargo = messageEnvelope.data; + // Let's add a little chaos + await this.processKillingMonkey.rattleTheCage(message, cargo); + // Set the operation ID on the context for the telemetry processor to include in telemetry items + const correlationContext = appInsights.getCorrelationContext(); + if (correlationContext?.customProperties) { + correlationContext.customProperties.setProperty(CUSTOM_PROPERTY_CARGO_ID, cargo.id); + correlationContext.customProperties.setProperty(CUSTOM_PROPERTY_CARGO_OPERATION_ID, messageEnvelope.operationId); + } + const sendOptions: OperationOptionsBase = { + tracingOptions: { + spanOptions: { + attributes: { + [CUSTOM_PROPERTY_CARGO_ID]: cargo.id, + [CUSTOM_PROPERTY_CARGO_OPERATION_ID]: messageEnvelope.operationId + } + } + } + } + try { + // validate cargo object in message + const validatedCargo = await this.cargoValidationService.validateCargo(cargo); + const validatedMessage: ServiceBusMessage = { + body: { + operationId: messageEnvelope.operationId, + data: validatedCargo, + }, + }; + if (correlationContext?.customProperties) { + correlationContext.customProperties.setProperty(CUSTOM_PROPERTY_CARGO_VALID, validatedCargo.valid.toString()); + const destination = validatedCargo.port.destination.replaceAll(",", ";"); // can't have ',' in props + correlationContext.customProperties.setProperty(CUSTOM_PROPERTY_CARGO_DESTINATION, destination); + } + sendOptions.tracingOptions!.spanOptions!.attributes!["cargo-valid"] = validatedCargo.valid; + + // add valid property to message so it can be properly filtered + // add telemetry properties so the cargo manager services can tie child operations to dependency below + validatedMessage.applicationProperties = { + valid: validatedCargo.valid, + }; + + // send validated cargo with additional properties to service bus topic + console.log(`Sending message to ${this.topicName} topic (cargo ID: ${cargo.id}, opid:${messageEnvelope.operationId})`); + + // let's add a little chaos + await this.serviceBusKillingMonkey.rattleTheCage(message, validatedCargo, new Map([["sender", this.topicSender]])); + + await this.topicSender.sendMessages(validatedMessage, sendOptions); + + // send message to operations queue + console.log(`Sending message to ${this.operationQueueName} queue (cargo ID: ${cargo.id})`); + const operationStateMessage = { + body: { + operationId: messageEnvelope.operationId, + state: 'CargoValidated', + }, + }; + await this.operationStateSender.sendMessages(operationStateMessage, sendOptions); + + // complete original message + await this.queueReceiver.completeMessage(message); + } catch (e: any) { + // catching the exception to attempt to update the operation state to failed + const errorMessage = (e as Error).message; + + const operationStateMessage = { + body: { + operationId: messageEnvelope.operationId, + state: 'Failed', + error: errorMessage, + }, + }; + await this.operationStateSender.sendMessages(operationStateMessage, sendOptions); + + // make sure we still self destruct for the exception + throw e; + } + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusWithTelemetry.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusWithTelemetry.ts new file mode 100644 index 0000000..6169a02 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/ServiceBusWithTelemetry.ts @@ -0,0 +1,300 @@ +import { ServiceBusSender, ServiceBusMessage, OperationOptionsBase, DeadLetterOptions, GetMessageIteratorOptions, MessageHandlers, PeekMessagesOptions, ReceiveMessagesOptions, ServiceBusReceivedMessage, ServiceBusReceiver, SubscribeOptions } from '@azure/service-bus'; +import { TelemetryService } from './TelemetryService'; +import * as appInsights from 'applicationinsights'; + +export const CUSTOM_PROPERTY_REQUEST_PARENT_ID= 'parent-request-id'; + +function generateServiceBusDependency( + telemetryClient: appInsights.TelemetryClient, + dependencyId: string, + duration: number, + serviceBusEntity: string, + serviceBusAction: string, + success: boolean +): void { + telemetryClient.trackDependency({ + target: serviceBusEntity, + name: `${serviceBusEntity} ${serviceBusAction}`, + data: '', + duration: duration, + resultCode: 200, + success: success, + dependencyTypeName: `Azure Service Bus`, + id: dependencyId, + properties: { + "message_bus.destination": serviceBusEntity, + "ai.operation.name": serviceBusAction, + }, + }); +} +function retrieveParentContextOrGenerateNew(message: ServiceBusReceivedMessage): { operationId: string, operationParentId: string } { + return retrieveParentContext(message) ?? TelemetryService.generateNewContext(); +} +function retrieveParentContext(message: ServiceBusReceivedMessage): { operationId: string, operationParentId: string } | null { + // pull trace parent set automatically in cargo-processing-api + const traceParent: any = message.applicationProperties?.traceparent; + if (!traceParent) { + return null + } + // syntax is --- + const parts = traceParent.split('-'); + return { + operationId: parts[1], + operationParentId: parts[2], + }; +} + +export class ServiceBusSenderWithTelemetry { + // Wraps a ServiceBusSender and adds telemetry + // Note that this is a simple example and doesn't support all the features of ServiceBusSender: + // - it only supports the sendMessages function + // - it only supports ServiceBusMessage types (not AmqpAnnotatedMessage etc) + + private sender: ServiceBusSender; + private telemetryClient: appInsights.TelemetryClient; + constructor( + sender: ServiceBusSender, + telemetryClient: appInsights.TelemetryClient, + ) { + this.sender = sender; + this.telemetryClient = telemetryClient; + } + + public get entityPath(): string { + return this.sender.entityPath; + } + public get isClosed(): boolean { + return this.sender.isClosed; + } + async sendMessages(messages: ServiceBusMessage | ServiceBusMessage[], options?: OperationOptionsBase | undefined): Promise { + const correlationContext = appInsights.getCorrelationContext(); + const dependencyId: string = TelemetryService.generateOpenTelemetryDependencyId(); + const dependencyStart: bigint = process.hrtime.bigint(); + + if (!Array.isArray(messages)) { + messages = [messages]; + } + const messagesWithTelemetry: ServiceBusMessage[] = messages.map((message: ServiceBusMessage) => { + const messageForTopic: ServiceBusMessage = { + ...message, + applicationProperties: { + ...message.applicationProperties, + 'Diagnostic-Id': `00-${correlationContext.operation.id}-${dependencyId}-01` + } + }; + return messageForTopic; + }); + + await this.sender.sendMessages(messagesWithTelemetry, options); + + const dependencyEnd: bigint = process.hrtime.bigint(); + + // track dependencies in application insights, ensure they are properly parented + generateServiceBusDependency( + this.telemetryClient, + dependencyId, + TelemetryService.returnElapsedMillisecondsSinceStart( + dependencyStart, + dependencyEnd + ), + this.entityPath, + 'SendMessage', + true + ); + } + async close(): Promise { + await this.sender.close(); + } +} + +export class ServiceBusReceiverWithTelemetry implements ServiceBusReceiver { + // Wraps a ServiceBusReceiver and adds telemetry + // Note that this is a simple example and doesn't support all the features of ServiceBusReceiver: + + private receiver: ServiceBusReceiver; + private telemetryClient: appInsights.TelemetryClient; + constructor( + receiver: ServiceBusReceiver, + telemetryClient: appInsights.TelemetryClient, + ) { + this.receiver = receiver; + this.telemetryClient = telemetryClient; + } + + public get entityPath(): string { + return this.receiver.entityPath; + } + public get receiveMode(): 'peekLock' | 'receiveAndDelete' { + return this.receiver.receiveMode; + } + public get isClosed(): boolean { + return this.receiver.isClosed; + } + private wrapHandler(handler: MessageHandlers): MessageHandlers { + // wrap the user's handler so that we can add telemetry for message processing + return { + processMessage: async (message: ServiceBusReceivedMessage) => { + // track time so telemetry operation duration can be calculated + const requestStart: bigint = process.hrtime.bigint(); + + // pull trace and span ids from traceparent so that telemetry can be correlated back + // to the original API request + const { operationId, operationParentId } = retrieveParentContextOrGenerateNew(message); + const requestId: string = TelemetryService.generateOpenTelemetryRequestId(); + + // wrap the processing in a correlation context so that any telemetry is associated with it + // and can be updated in the telemetry processor + const spanContext = { + traceId: operationId, + spanId: operationParentId, + traceFlags: 1 + } + const correlationContext = appInsights.startOperation(spanContext, "ServiceBus.ProcessMessage") ?? undefined; + correlationContext?.customProperties.setProperty(CUSTOM_PROPERTY_REQUEST_PARENT_ID, requestId) + await appInsights.wrapWithCorrelationContext(async () => { + let success = false; + try { + // invoke handler's processMessage function + await handler.processMessage(message); + success = true; + } catch (error: any) { + // track exception + this.telemetryClient.trackException({ + exception: error, + properties: { + "message_bus.destination": this.receiver.entityPath, + "message_bus.delivery_count": (message.deliveryCount ?? -1).toString(), + }, + tagOverrides: { + "ai.operation.id": operationId, + "ai.operation.parentId": operationParentId, + } + }) + + // track failure request in application insights, ensure parent is set to dependency from inbound message + const requestEnd: bigint = process.hrtime.bigint(); + this.telemetryClient.trackRequest({ + name: 'ServiceBus.ProcessMessage', + url: `sb://${this.receiver.entityPath}`, + duration: TelemetryService.returnElapsedMillisecondsSinceStart( + requestStart, + requestEnd + ), + resultCode: 500, + // unsuccessful requests cause exceptions and self destruction, in which case the request isn't logged at all + // no need to handle sending unsuccessful requests + success: false, + id: requestId, + properties: { + "message_bus.destination": this.receiver.entityPath, + "message_bus.delivery_count": (message.deliveryCount ?? -1).toString(), + }, + tagOverrides: { + "ai.operation.id": operationId, + "ai.operation.parentId": operationParentId, + } + }); + + // rethrow so that Service Bus subscribe sees the exception and calls processError + throw error; + } + + // track successful request in application insights, ensure parent is set to dependency from inbound message + const requestEnd: bigint = process.hrtime.bigint(); + this.telemetryClient.trackRequest({ + name: 'ServiceBus.ProcessMessage', + url: `sb://${this.receiver.entityPath}`, + duration: TelemetryService.returnElapsedMillisecondsSinceStart( + requestStart, + requestEnd + ), + resultCode: 200, + // unsuccessful requests cause exceptions and self destruction, in which case the request isn't logged at all + // no need to handle sending unsuccessful requests + success: true, + id: requestId, + properties: { + "message_bus.destination": this.receiver.entityPath, + "message_bus.delivery_count": (message.deliveryCount ?? -1).toString(), + }, + tagOverrides: { + "ai.operation.id": operationId, + "ai.operation.parentId": operationParentId, + } + }); + }, correlationContext)(); + }, + processError: handler.processError, + }; + } + subscribe(handlers: MessageHandlers, options?: SubscribeOptions | undefined): { close(): Promise; } { + return this.receiver.subscribe(this.wrapHandler(handlers), options); + } + getMessageIterator(options?: GetMessageIteratorOptions | undefined): AsyncIterableIterator { + throw new Error('Method not implemented.'); + } + receiveMessages(maxMessageCount: number, options?: ReceiveMessagesOptions | undefined): Promise { + throw new Error('Method not implemented.'); + } + receiveDeferredMessages(sequenceNumbers: Long | Long[], options?: OperationOptionsBase | undefined): Promise { + throw new Error('Method not implemented.'); + } + peekMessages(maxMessageCount: number, options?: PeekMessagesOptions | undefined): Promise { + throw new Error('Method not implemented.'); + } + async close(): Promise { + await this.receiver.close(); + } + async completeMessage(message: ServiceBusReceivedMessage): Promise { + const queueCompleteDependencyId: string = TelemetryService.generateOpenTelemetryDependencyId(); + + const queueCompleteDependencyStart: bigint = process.hrtime.bigint(); + await this.receiver.completeMessage(message); + const queueCompleteDependencyEnd: bigint = process.hrtime.bigint(); + + generateServiceBusDependency( + this.telemetryClient, + queueCompleteDependencyId, + TelemetryService.returnElapsedMillisecondsSinceStart( + queueCompleteDependencyStart, + queueCompleteDependencyEnd + ), + this.entityPath, + 'CompleteMessage', + true + ); + } + abandonMessage(message: ServiceBusReceivedMessage, propertiesToModify?: { [key: string]: any; } | undefined): Promise { + throw new Error('Method not implemented.'); + } + deferMessage(message: ServiceBusReceivedMessage, propertiesToModify?: { [key: string]: any; } | undefined): Promise { + throw new Error('Method not implemented.'); + } + async deadLetterMessage(message: ServiceBusReceivedMessage, options?: (DeadLetterOptions & { [key: string]: any; }) | undefined): Promise { + // generate id for dependency + const dependencyId: string = TelemetryService.generateOpenTelemetryDependencyId(); + + // deadletter invalid message structures + const dependencyStart: bigint = process.hrtime.bigint(); + await this.receiver.deadLetterMessage(message, options); + const dependencyEnd: bigint = process.hrtime.bigint(); + + // track dependency in application insights, ensure it is properly parented + generateServiceBusDependency( + this.telemetryClient, + dependencyId, + TelemetryService.returnElapsedMillisecondsSinceStart( + dependencyStart, + dependencyEnd + ), + this.entityPath, + 'DeadLetterMessage', + true + ); + } + renewMessageLock(message: ServiceBusReceivedMessage): Promise { + throw new Error('Method not implemented.'); + } +} + + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/TelemetryService.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/TelemetryService.ts new file mode 100644 index 0000000..09162e5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/services/TelemetryService.ts @@ -0,0 +1,32 @@ +export class TelemetryService { + public static generateNewContext(): { operationId: string, operationParentId: string } { + return { + operationId: TelemetryService.generateOpenTelemetryRequestId(), + operationParentId: TelemetryService.generateOpenTelemetryDependencyId(), + }; + } + + public static generateOpenTelemetryId(length: number): string { + // must satisfy regex for ids - https://github.com/open-telemetry/opentelemetry-js/blob/0f178d1e2e9b3aed81789820944452c153543198/api/src/trace/spancontext-utils.ts#L22 + const chars: string = 'abcdef1234567890'; + const randomArray: string[] = Array.from( + { length: length }, + () => chars[Math.floor(Math.random() * chars.length)] + ); + return randomArray.join(''); + } + + public static generateOpenTelemetryRequestId(): string { + return TelemetryService.generateOpenTelemetryId(32); + } + + public static generateOpenTelemetryDependencyId(): string { + return TelemetryService.generateOpenTelemetryId(16); + } + + public static returnElapsedMillisecondsSinceStart(start: bigint, end: bigint): number { + const elapsedNanoSeconds: number = Number(end - start); + const elapsedMilliseconds = elapsedNanoSeconds / 1000000; + return elapsedMilliseconds; + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/tests/CargoValidationServiceTests.ts b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/tests/CargoValidationServiceTests.ts new file mode 100644 index 0000000..6841e70 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/src/tests/CargoValidationServiceTests.ts @@ -0,0 +1,124 @@ +import { expect } from 'chai'; +import { CargoValidationService } from '../services/CargoValidationService'; +import { Cargo } from '../models/Cargo'; +import 'mocha'; +import { ValidatedCargo } from '../models/ValidatedCargo'; + +describe('validation tests', () => { + let cargo: Cargo; + + beforeEach(() => { + cargo = { + timestamp: new Date(), + id: '', + product: { + name: 'product', + quantity: 1, + }, + port: { + source: 'sourcePort', + destination: 'destinationPort', + }, + // initialize demand dates as today + demandDates: { + start: new Date(), + end: new Date(), + }, + }; + }); + + it('should return valid', () => { + // arrange + const cargoValidationService: CargoValidationService = + new CargoValidationService(); + + // ensure demand dates are valid + cargo.demandDates.start.setDate(cargo.demandDates.start.getDate() + 1); + cargo.demandDates.end.setDate(cargo.demandDates.end.getDate() + 2); + + // act + const result: ValidatedCargo = + cargoValidationService.validateCargo(cargo); + + // assert + expect(result.valid).to.be.true; + expect(result.errorMessage).to.be.null; + }); + + it('should return invalid - dates must be in future', () => { + // arrange + const cargoValidationService: CargoValidationService = + new CargoValidationService(); + + // ensure demand dates are valid + cargo.demandDates.start.setDate(cargo.demandDates.start.getDate() - 2); + cargo.demandDates.end.setDate(cargo.demandDates.end.getDate() - 1); + + // act + const result: ValidatedCargo = + cargoValidationService.validateCargo(cargo); + + // assert + expect(result.valid).to.be.false; + expect(result.errorMessage).to.equal( + 'Start and end dates must be in future.' + ); + }); + it('should return invalid - start date cannot be 60 days in future', () => { + // arrange + const cargoValidationService: CargoValidationService = + new CargoValidationService(); + + // ensure demand dates are invalid + cargo.demandDates.start.setDate(cargo.demandDates.start.getDate() + 65); + cargo.demandDates.end.setDate(cargo.demandDates.end.getDate() + 68); + + // act + const result: ValidatedCargo = + cargoValidationService.validateCargo(cargo); + + // assert + expect(result.valid).to.be.false; + expect(result.errorMessage).to.equal( + 'Start date cannot be more than 60 days in future.' + ); + }); + it('should return invalid - date range cannot exceed 30 days', () => { + // arrange + const cargoValidationService: CargoValidationService = + new CargoValidationService(); + + // ensure demand dates are invalid + cargo.demandDates.start.setDate(cargo.demandDates.start.getDate() + 30); + cargo.demandDates.end.setDate(cargo.demandDates.end.getDate() + 90); + + // act + const result: ValidatedCargo = + cargoValidationService.validateCargo(cargo); + + // assert + expect(result.valid).to.be.false; + expect(result.errorMessage).to.equal( + 'Range between start and end dates cannot exceed 30 days.' + ); + }); + it('should return invalid - end date must be after start date', () => { + // arrange + const cargoValidationService: CargoValidationService = + new CargoValidationService(); + + // ensure demand dates are invalid + cargo.demandDates.start.setDate(cargo.demandDates.start.getDate() + 2); + cargo.demandDates.end.setDate(cargo.demandDates.end.getDate() + 1); + + // act + const result: ValidatedCargo = + cargoValidationService.validateCargo(cargo); + + // assert + expect(result.valid).to.be.false; + expect(result.errorMessage).to.equal( + 'End date must be after start date.' + ); + }); +}); diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/tsconfig.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/tsconfig.json new file mode 100644 index 0000000..d200f45 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/tsconfig.json @@ -0,0 +1,66 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "resolveJsonModule": true, + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + }, + "exclude": [ + "src/tests/**/*.ts" + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/Dockerfile new file mode 100644 index 0000000..828de1f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/Dockerfile @@ -0,0 +1,11 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu/.devcontainer/base.Dockerfile + +# [Choice] Ubuntu version (use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon): ubuntu-22.04, ubuntu-20.04, ubuntu-18.04 +ARG VARIANT="jammy" +FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/devcontainer.json new file mode 100644 index 0000000..b2d5886 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu +{ + "name": "cargo-test-scripts", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Ubuntu version: jammy / ubuntu-22.04, focal / ubuntu-20.04, bionic /ubuntu-18.04 + // Use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon. + "args": { + "VARIANT": "ubuntu-22.04" + } + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.js-debug", + "nwhatt.chai-snippets" + ], + "settings": { + "editor.formatOnType": true, + "editor.formatOnSave": true + } + } + }, + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "node": "lts", + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.env.sample b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.env.sample new file mode 100644 index 0000000..f05400f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.env.sample @@ -0,0 +1,5 @@ +SERVICE_BUS_CONNECTION_STRING="{Enter Connection String to the Service Bus}" +QUEUE_NAME="{Enter the name of the queue to feed for generated cargo items}" +TOPIC_NAME="{Enter the name of the topic to feed generated cargo items to}" +CARGO_PROCESSING_API_URL="http://localhost:8080/" +OPERATIONS_API_URL="http://localhost:8081/" \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.gitignore b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.gitignore new file mode 100644 index 0000000..6ee4b04 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.gitignore @@ -0,0 +1,3 @@ +node_modules +.env +testResults \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.vscode/launch.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.vscode/launch.json new file mode 100644 index 0000000..e8f8fd1 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Default Test Scripts", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/index.js", + }, + { + "type": "node", + "request": "launch", + "name": "Chaos Testing", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/index.js", + "args": [ + "-c", + "./testConfigurations/cargo_processing_api_chaos_tests.json" + ] + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/README.md b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/README.md new file mode 100644 index 0000000..b694a3c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/README.md @@ -0,0 +1,224 @@ +# Cargo Processing Tests Scripts + +This set of scrips is used to exercise the different features of the Cargo Processing system. It has the following capabilities: + +* Generate realistic looking cargo records based on data configured within the ./seed.json file +* Make the cargo data that is generated invalid based on the different validation tests that exist within the cargo-processing-validator logic +* Send large volumes of generated data at the system, that can be configured to randomly invalidate the cargo +* Ensure that the cargo was processed correctly based on the data stored within the operations-api +* Target different entry points within the system (helpful when trying to isolate a specific service for testing of new functionality) +* Trigger chaos within the system TBD + * Configure the target for the chaos TBD + * Inject random chaos within a high load test TBD + * Configure the type of chaos to trigger based on what the target of the chaos is TBD + +## Targets + +There are 4 different targets for the test cases. As each target needs to have access to different environment specific settings, you may not need to configure all of the settings used by the test scripts. The following describes the different targets the test generators can hit, along with the relevant environment settings for them. + +* cargo-processing-api: The only end-to-end test target as it represents sending messages to the ingestion point of the system. As such it has the ability to perform validation tests. The environment settings required to run tests targetting this test generator are: + * CARGO_PROCESSING_API_URL: The host path for the cargo-processing-api, it is where cargo will be posted to. + * OPERATIONS_API_URL: The host path for the operation-api, it is where the validation tests will look for the operations detail. This is only required if you've configured the tests to validate the results. +* cargo-processing-validator: This target will post cargo object directly into the ingestion queue that the cargo-processing-validator will read from to process cargo. Based on configuration settings within the test run, this generator will randomly create invalid cargo along with valid cargo. The environment settings required to run tests targeting this test generator are: + * SERVICE_BUS_CONNECTION_STRING: The connection string to the service bus that the cargo-processing-validator service is listening to + * QUEUE_NAME: The name of the ingestion queue that the cargo-processing-validator service is listening to +* valid-cargo-manager: This will target just the valid-cargo-manager, bypassing both the cargo-processing-api and the cargo-processing-validator. The cargo objects generated from this step, would pass the validation tests performed by the cargo-processing-validator. The environment settings required to run tests targeting this test generator are: + * SERVICE_BUS_CONNECTION_STRING: The connection string to the service bus that the valid-cargo-manager service is listening to + * TOPIC_NAME: The name of the topic that the valid-cargo-manager service is listening to +* invalid-cargo-manager: This will target just the valid-cargo-manager, bypassing both the cargo-processing-api and the cargo-processing-validator. . The cargo objects generated from this step, would pass the validation tests performed by the cargo-processing-validator. The environment settings required to run tests targeting this test generator are: + * SERVICE_BUS_CONNECTION_STRING: The connection string to the service bus that the valid-cargo-manager service is listening to + * TOPIC_NAME: The name of the topic that the valid-cargo-manager service is listening to + +## Configuration + +There are quite a number of toggles that can be used to create the tests. Enough that providing via command lines args can be quite cumbersume. Instead, you have the ability to configure either a single test run, or a suite of test runs, within a single configuration file. The current set of configurations can be found within the ./testConfigurations directory. The details of the structure of the configuration are as follows: + +At the top level is a single object named "tests" which is an array of test objects to run. The test object structure is: + +* name(string): Used when writing to the console, and constructing the test report. +* target(string): Defines which of the above targets the test will run for +* volume(number): the number of cargo objects to generate for the tests +* validateResults(boolean): instructs the scripts to validate the results of the test (only available when targeting the cargo-processing-api) +* validationDelayInMilliseconds(number): the number of milliseconds the script will delay before validating the test results +* delayBetweenCargoInMilliseconds(number): the number of milliseconds the script will delay between sending each cargo object to the target. No delay is applied if this is set to `0` (the default) +* maxRetries(number): the number of times the scripts will retry a failed validation test +* startingRetryBufferInMilliseconds(number): the number of milliseconds the scripts will delay before retrying the validation. Each retry will double this value, providing a growing backoff period between retries. +* properties(object): key/value properties provided to the generators to assist with their processing. Each generator has the ability to have their own relevant properties. Current properties available are: + +| property name | datatype | targets using | implemented | description | +| ------------- | -------- | ------------- | ----------- | ----------- | +| chanceToInvalidate | number | cargo-processing-api, cargo-processing-validator | Yes | Indicates the chance that a generated cargo object will be made invalid. It acts as a 1 in N chance for the cargo to be made invalid. e.g. a value of 0, guarantees none of the cargo will be made invalid, a value of 1 guarantees that all of the cargo will be made invalid, a value of 50 means that there is a 1 in 50 chance that any single cargo object will be made invalid | +| chaosSettings | Array | None | No | Will house the configuration of how the tests will create chaos within the system | + +For example the default test that are run when no configuration file is provided when run is this: + +``` json +{ + "tests": [ + { + "name": "End to End Validation of valid cargo", + "target": "cargo-processing-api", + "volume": 5, + "validateResults": true, + "validationDelayInMilliseconds": 20000, + "maxRetries": 5, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0 + } + }, + { + "name": "End to End Validation of invalid cargo", + "target": "cargo-processing-api", + "volume": 5, + "validateResults": true, + "validationDelayInMilliseconds": 10000, + "maxRetries": 5, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 1 + } + } + ] +} +``` + +## Running the tests + +Once configure you can either run the default tests simply by running the + +``` bash +node ./index.js +``` + +from the command line. You can override this default behavior by by providing an alternative configuration file for your tests. Like so: + +``` bash +node ./index.js -c ./testConfigurations/scale.json +``` + +The console output will provide status of what the scripts are doing while they and provide a summary of each tests results for example: + +``` bash +Starting End to End Validation of invalid cargo test. +index.js:23 +5 cargo objects generated +generators/cargoProcessingApi.js:15 +Sending cargo to: http://20.106.116.247/cargo/a2e5fd80-6c0a-43ba-908c-ea6fad23bb24 +generators/cargoProcessingApi.js:41 +Sending cargo to: http://20.106.116.247/cargo/42e6c004-f9ad-4f48-97e0-962d9492303f +generators/cargoProcessingApi.js:41 +Sending cargo to: http://20.106.116.247/cargo/9863bff4-028c-4e90-84a9-c0e8b5bd5efb +generators/cargoProcessingApi.js:41 +Sending cargo to: http://20.106.116.247/cargo/67ee24ed-880a-43cb-ad6c-6f9c43df4465 +generators/cargoProcessingApi.js:41 +Sending cargo to: http://20.106.116.247/cargo/8732fda3-1f36-444f-bbd7-7ff5ce4c174a +generators/cargoProcessingApi.js:41 +2 +Giving system time to process the cargo before validating the results +index.js:45 +Getting operation details from: http://20.106.116.247/operations/fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 +cargoValidation.js:55 +Operation id: fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 failed validation. 5 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 +cargoValidation.js:55 +Operation id: fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 failed validation. 4 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 +cargoValidation.js:55 +Operation id: fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 failed validation. 3 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 +cargoValidation.js:55 +Operation id: fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 failed validation. 2 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/fc8dd636-d8b2-3fcf-88d5-77a1e34f77e2 +cargoValidation.js:55 +Getting operation details from: http://20.106.116.247/operations/f74b33e7-b7df-3519-97bf-37ae07d8a9db +cargoValidation.js:55 +Getting operation details from: http://20.106.116.247/operations/d80c3a68-dc69-3607-bc1d-4f5eb22106bf +cargoValidation.js:55 +Operation id: d80c3a68-dc69-3607-bc1d-4f5eb22106bf failed validation. 5 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/d80c3a68-dc69-3607-bc1d-4f5eb22106bf +cargoValidation.js:55 +Operation id: d80c3a68-dc69-3607-bc1d-4f5eb22106bf failed validation. 4 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/d80c3a68-dc69-3607-bc1d-4f5eb22106bf +cargoValidation.js:55 +Operation id: d80c3a68-dc69-3607-bc1d-4f5eb22106bf failed validation. 3 retries remaining +cargoValidation.js:44 +Getting operation details from: http://20.106.116.247/operations/d80c3a68-dc69-3607-bc1d-4f5eb22106bf +cargoValidation.js:55 +Getting operation details from: http://20.106.116.247/operations/0f6d7a74-563d-399d-bb56-49423a5655cf +cargoValidation.js:55 +Getting operation details from: http://20.106.116.247/operations/5774754b-7dcf-3503-9d6a-fda7d542c947 +cargoValidation.js:55 +********************************************************************************** +outputTestResults.js:23 +End to End Validation of invalid cargo results: 5 test; 0 failed; 5 succeeded; +outputTestResults.js:24 +********************************************************************************** +Detailed Test Results can be viewed at ./testResults/EndtoEndValidationofinvalidcargo-43bff096-5255-4b87-bb82-1f34ede460de.txt +``` + +For more detailed results of the tests, a test report is provided. The final output line from the test run will provide the file name for the test report. + +The test report will contain the same summary information provided in the console, but also what cargo objects were sent, the final operation state for the cargo sent, and a break down of which validation tests passed/failed. + +### Experimenting with test configuration + +As well as loading the test configuration from a file, you can also specify the test configuration via stdin. +This is useful when you want to experiment with different test configurations without having to modify the test configuration file. + +The command below shows an example of how to specify the test configuration via stdin: + +```bash +cat << EOF | node index.js -c - +{ + "tests": [ + { + "name": "Send cargo to cargo processing api", + "target": "cargo-processing-api", + "volume": 50, + "validateResults": false, + "delayBetweenCargoInMilliseconds": 5000, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0 + } + } + ] +} +EOF +``` + +## Creating Chaos + +Built into the tests is the ability to trigger chaos within the services. This is functionality intended to ensure our observability and monitoring solutions are capable of finding and potentially guarding against known failures that could occur. To create a chaos within a test run, you will need to add chaosSettings within the properties of the test. + +A chaos setting is made up of the following values: + +* Target: The service that will end up causing chaos. In the context of this solution space, the values map to the names of the different services. cargo-processing-api, cargo-processing-validator, invalid-cargo-manager, valid-cargo-manager and operations-api. +* Type: Each service has it's own types and variety of chaos that can be let lose on it. Below is a table describing what types of chaos are available. +* isEnabled: indicates if the chaosSetting will actually stand a chance of being triggered. +* chanceToCauseChaos: Works similarly to the chanceToInvalidate variable fo the test configuration. It acts as a 1 in N chance for the chaos to be triggered. e.g. a value of 0, guarantees none of the cargo will trigger chaos, a value of 1 guarantees that all of the cargo will trigger this type of chaos, a value of 50 means that there is a 1 in 50 chance that any single cargo object will trigger the chaos + +### Types of chaos + +The below table defines the different types of chaos that can be created within these services. + +| Target | Type | Description | Notes | +| -------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cargo-processing-api | operations-api-failure | Will cause a chaos exception to occur when the cargo-processing-api attempts to call the operations-api. | This will cause the put/post request to receive a INTERNAL SERVER ERROR response, but the api should continue to function. | +| cargo-processing-api | process-ending | Will cause the cargo-processing-api to shut down | | +| cargo-processing-api | service-bus-failure | Will cause the service to close the service-bus connection right before it attempts to use it. | | +| cargo-processing-api | invalid-schema | Will cause the test script to modify the cargo object being sent in away that causes the cargo-processing-api to throw an invalid json schema exception. | | +| cargo-processing-validator | service-bus-failure | Will cause the service to close the service-bus connection right before it attempts to use it. | | +| cargo-processing-validator | process-killing | Will cause the cargo-processing-validator to shut down | | +| cargo-processing-validator | invalid-schema | Sends a message that is missing it's demandDates directly to the ingest-cargo queue | In order to bypass the APIs validation checks, the message must be injected directly into the queue to trigger the dead letter effect of an invalid schema being sent to the validator | + +### Sample Chaos + +The [cargo_processing_api_chaos_tests](./testConfigurations/cargo_processing_api_chaos_tests.json) file has settings that allow you to create specific chaos events. Each chaos type has been configured to always trigger, when enabled. By default all of the chaos settings have been disabled. Changing the isEnabled to true on one of them will test that specific chaos type. The launch.json has been configured with a debug options for running the test scripts with that specific configuration. diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/cargoValidation.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/cargoValidation.js new file mode 100644 index 0000000..f22d0a6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/cargoValidation.js @@ -0,0 +1,75 @@ +const dataBuilderUtil = require('./dataBuilderUtils.js'); +const config = require('./config.js'); +const axios = require('axios'); +const path = require('path'); +const URL = require('node:url').URL; + +class CargoValidation { + async validate(cargoSent, retries, buffer) { + const operation = await this.getOperationInformation(cargoSent.operationId); + const validationResults = { testDetails: { cargo: { ...cargoSent }, operation: { ...operation } } }; + + if (operation == undefined) { + validationResults.operationFound = false; + // Giving the services more time to populate the operation + return await this.retryValidation(cargoSent, validationResults, retries, buffer); + } + + validationResults.operationFound = true; + validationResults.stateCorrect = operation.state != undefined && operation.state == cargoSent.resultDetails.state; + + if (!validationResults.stateCorrect) { + // State isn't correct + // Giving the services more time to finish processing the operation + return await this.retryValidation(cargoSent, validationResults, retries, buffer); + } + + // State is what is expected, no more retries, services have processed to the expected state, + // Any incorrect values from here due to services not processing he cargo the way the tests expected them to + validationResults.resultPopulated = !(operation.result == null || operation.result == undefined); + validationResults.correctCargoId = cargoSent.cargo.id == operation.result.id; + validationResults.validFieldIsCorrect = cargoSent.resultDetails.isValid == operation.result.valid; + if (cargoSent.resultDetails.isValid == false) { + validationResults.correctErrorMessage = + operation.result.errorMessage == cargoSent.resultDetails.failureReason + } + + return validationResults; + } + + async retryValidation(cargoSent, validationResults, retries, buffer) { + if (retries <= 0) { + return validationResults; + } + console.log(`Operation id: ${cargoSent.operationId} failed validation. ${retries} retries remaining`); + + await dataBuilderUtil.delay(buffer); + + return await this.validate(cargoSent, retries - 1, buffer * 2); + } + + async getOperationInformation(id, retries = 3, backoff = 300) { + const retryCodes = [408, 500, 502, 503, 504, 522, 524] /* 2 */ + try { + const route = new URL(path.join('operations', id), config.operationsApiUrl).toString(); + console.log(`Getting operation details from: ${route}`); + const res = await axios.get(route); + const statusCode = res.status; + if (statusCode < 200 || statusCode > 299) { + if (retries > 0 && retryCodes.includes(statusCode)) { + //Non-blocking sleep + await dataBuilderUtil.delay(backoff); + return await this.getOperationInformation(id, retries - 1, backoff * 2); + } else { + throw (Error(res)); + } + } + return res.data; + + } catch (ex) { + console.error(ex); + } + } +} + +module.exports = { default: CargoValidation }; diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/config.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/config.js new file mode 100644 index 0000000..59bdba2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/config.js @@ -0,0 +1,11 @@ +require('dotenv').config(); + +serviceBusConnectionString = process.env.SERVICE_BUS_CONNECTION_STRING; +queueName = process.env.QUEUE_NAME; +topicName = process.env.TOPIC_NAME; +cargoProcessingApiUrl = process.env.CARGO_PROCESSING_API_URL; +operationsApiUrl = process.env.OPERATIONS_API_URL; + +module.exports = { + serviceBusConnectionString, queueName, topicName, cargoProcessingApiUrl, operationsApiUrl +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/dataBuilderUtils.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/dataBuilderUtils.js new file mode 100644 index 0000000..563f73b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/dataBuilderUtils.js @@ -0,0 +1,170 @@ +const seedData = require('./seed.json'); +const crypto = require('crypto'); +const addDays = require('date-fns/addDays'); + +generateBaseCargoObject = function () { + return { + id: crypto.randomUUID(), + product: getProduct(), + demandDates: getDemandDates(), + port: getPorts() + } +} + +getProduct = function () { + return { + name: getRandomValue(seedData.products), + quantity: getRandomNumber(10000) + 1 + }; +} + +getPorts = function () { + const source = getRandomValue(seedData.ports); + let destination = getRandomValue(seedData.ports); + while (destination == source) { + destination = getRandomValue(seedData.ports); + } + return { + source, destination + } +} + +getDemandDates = function () { + const today = new Date(); + + // Random day within the next 2 weeks + const startDaysFromToday = getRandomNumber(14) + 1; + // Random day, after the start date, within 60 days of today, and no more than 30 days from start + let endDaysFromStart = getRandomNumber(60 - startDaysFromToday) + 1; + endDaysFromStart = endDaysFromStart >= 30 ? 29 : endDaysFromStart; + + const start = addDays(today, startDaysFromToday); + const end = addDays(start, endDaysFromStart); + + return { start, end }; +} + +getRandomValue = function (from) { + return from[getRandomNumber(from.length)]; +} + +getRandomNumber = function (max) { + //Will return a random number between 0 and (max - 1) + return Math.floor(Math.random() * max); +} + +randomYesOrNo = function (chance) { + // No point in any of the rest of the processing if there is no chance of returning a true result + if (chance == 0) return false; + // No point in any of the rest of the processing if there is a guarentee in return a true + if (chance == 1) return true; + return (getRandomNumber(chance) + 1) % chance == 0; +} + +makeInvalid = function (cargo, includeValidationObject, failureReason) { + if (failureReason === undefined) { + failureReason = getRandomNumber(4) + 1; + } + let failureMessage = ''; + switch (failureReason) { + case 1: + // Make the dates occurr in the past + failureMessage = 'Start and end dates must be in future.'; + const reduceBy = -70; + cargo.demandDates.start = addDays(cargo.demandDates.start, reduceBy); + cargo.demandDates.end = addDays(cargo.demandDates.end, reduceBy); + if (includeValidationObject) { + cargo.valid = false; + cargo.errorMessage = failureMessage; + } + + break; + case 2: + // Make the dates occurr way in the future + failureMessage = 'Start date cannot be more than 60 days in future.'; + const increaseBy = 70; + cargo.demandDates.start = addDays(cargo.demandDates.start, increaseBy); + cargo.demandDates.end = addDays(cargo.demandDates.end, increaseBy); + if (includeValidationObject) { + cargo.valid = false; + cargo.errorMessage = failureMessage; + } + break; + case 3: + // Make the gap between the dates greater than 30 days + failureMessage = 'Range between start and end dates cannot exceed 30 days.'; + cargo.demandDates.end = addDays(cargo.demandDates.end, 30); + if (includeValidationObject) { + cargo.valid = false; + cargo.errorMessage = failureMessage; + } + break; + case 4: + // Flip the dates + failureMessage = 'End date must be after start date.'; + const tempDate = cargo.demandDates.start; + cargo.demandDates.start = cargo.demandDates.end; + cargo.demandDates.end = tempDate; + if (includeValidationObject) { + cargo.valid = false; + cargo.errorMessage = failureMessage; + } + break; + } + + return failureMessage; +} + +addToEnvelope = function (cargo) { + cargo.timestamp = new Date(); + return { + operationId: crypto.randomUUID(), + data: cargo + } +} + +toServiceBusMessage = function (envelope, isValid) { + const message = { + body: envelope, + applicationProperties: { + 'Diagnostic-Id': `00-${generateOpenTelemetryId(32)}-${generateOpenTelemetryId(16)}-01` + } + } + + if (isValid !== undefined) { + message.applicationProperties.valid = isValid; + } + return message; +} + +function generateOpenTelemetryId(length) { + // must satisfy regex for ids - https://github.com/open-telemetry/opentelemetry-js/blob/0f178d1e2e9b3aed81789820944452c153543198/api/src/trace/spancontext-utils.ts#L22 + const chars = 'abcdef1234567890'; + const randomArray = Array.from( + { length: length }, + () => chars[getRandomNumber(chars.length)] + ); + return randomArray.join(''); +} + +function raiseChaos(resultDetails, cargo, chaosSetting) { + if (resultDetails.chaosSetting !== undefined) { + // Chaos already set for this cargo, no need to get CRAZY here + return; + } + resultDetails.chaosSetting = chaosSetting; + cargo.port.source = chaosSetting.target; + cargo.port.destination = chaosSetting.type; + if (chaosSetting.type == "invalid-schema") { + cargo.demandDates = undefined; + } +} + +async function delay(milliseconds) { + await new Promise(resolve => setTimeout(resolve, milliseconds)); +} + +module.exports = { + generateBaseCargoObject, makeInvalid, addToEnvelope, toServiceBusMessage, + getRandomNumber, getDemandDates, getPorts, randomYesOrNo, delay, raiseChaos +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingApi.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingApi.js new file mode 100644 index 0000000..3f40dd3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingApi.js @@ -0,0 +1,87 @@ +const dataBuilderUtil = require('../dataBuilderUtils.js'); +const config = require('../config.js'); +const axios = require('axios'); +const path = require('path'); +const URL = require('node:url').URL; + +class CargoProcessingApiGenerator { + constructor(properties) { + this.properties = properties; + this.canValidateResults = true; + } + + async run(count, delay) { + const cargo = this.generateCargoToSend(count); + console.log(`${cargo.length} cargo objects generated`); + if (delay === 0) { + return await Promise.all(cargo.map(this.putCargo)); + } else { + const result = [] + for (const cargoToSend of cargo) { + await this.putCargo(cargoToSend); + result.push(await dataBuilderUtil.delay(delay)); + } + return result; + } + } + + generateCargoToSend(count) { + return [...Array(count).keys()].map(() => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + const resultDetails = { isValid: true, state: "Succeeded" }; + this.randomlyMakeInvalid(resultDetails, cargo); + this.addSomeChaos(resultDetails, cargo) + + return { + cargo, + resultDetails + }; + }); + } + + randomlyMakeInvalid(resultDetails, cargo) { + if (dataBuilderUtil.randomYesOrNo(this.properties.chanceToInvalidate)) { + resultDetails.failureReason = dataBuilderUtil.makeInvalid(cargo, false); + resultDetails.isValid = false; + } + } + + addSomeChaos(resultDetails, cargo) { + if (this.properties.chaosSettings === undefined) return; + var activeChaos = this.properties.chaosSettings.filter(chaosSetting => chaosSetting.isEnabled); + activeChaos.forEach(chaosSetting => { + if (dataBuilderUtil.randomYesOrNo(chaosSetting.chanceToCauseChaos)) { + dataBuilderUtil.raiseChaos(resultDetails, cargo, chaosSetting); + } + }); + } + + async putCargo(cargoToSend, retries = 3, backoff = 300) { + const retryCodes = [408, 500, 502, 503, 504, 522, 524] /* 2 */ + const cargo = cargoToSend.cargo; + try { + const route = new URL(path.join('cargo', cargo.id), config.cargoProcessingApiUrl); + console.log(`Sending cargo to: ${route} (dest port: ${cargo.port.destination})`); + const res = await axios.put(route, cargo); + const statusCode = res.status; + if (statusCode < 200 || statusCode > 299) { + if (retries > 0 && retryCodes.includes(statusCode)) { + //Non-blocking sleep + await dataBuilderUtil.delay(backoff); + return await this.putCargo(cargoToSend, retries - 1, backoff * 2); + } else { + throw (Error(res)); + } + } + return { + operationId: res.headers.get('operation-id'), + cargo, + resultDetails: cargoToSend.resultDetails + } + } catch (ex) { + console.error(ex); + } + } +} + +module.exports = { default: CargoProcessingApiGenerator }; diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingValidator.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingValidator.js new file mode 100644 index 0000000..d7e0b45 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/cargoProcessingValidator.js @@ -0,0 +1,85 @@ +const dataBuilderUtil = require('../dataBuilderUtils.js'); +const ServiceBusClient = require('@azure/service-bus').ServiceBusClient; +const config = require('../config.js'); + +class CargoProcessingValidatorGenerator { + constructor(properties) { + this.properties = properties; + this.canValidateResults = false; + } + + async run(count) { + const cargoMessageBodies = this.generateCargoToSend(count); + console.log(`${cargoMessageBodies.length} cargo objects created`); + const sbClient = new ServiceBusClient(config.serviceBusConnectionString); + const sender = sbClient.createSender(config.queueName); + const cargoSent = []; + try { + let batch = await sender.createMessageBatch(); + for (let i = 0; i < cargoMessageBodies.length; i++) { + const cargoToSend = cargoMessageBodies[i]; + const message = { body: cargoToSend.cargo }; + // try to add the message to the batch + if (!batch.tryAddMessage(message)) { + // Couldn't add more to the batch, sending what we have, then starting a new batch + console.log(`Sending batch of ${batch.count} cargo objects`); + await sender.sendMessages(batch); + + // create a new batch + batch = await sender.createMessageBatch(); + + // now, add the message failed to be added to the previous batch to this batch + if (!batch.tryAddMessage(message)) { + // if it still can't be added to the batch, the message is to big + throw new Error("Message too big to fit in a batch"); + } + } + cargoSent.push({ + id: cargoToSend.cargo.id, + resultDetails: cargoToSend.resultDetails + }); + } + console.log(`Sending batch of ${batch.count} cargo objects`); + await sender.sendMessages(batch); + } + finally { + sender.close(); + sbClient.close(); + } + return cargoSent; + } + + generateCargoToSend(count) { + return [...Array(count).keys()].map(() => { + let cargo = dataBuilderUtil.generateBaseCargoObject(); + const resultDetails = { isValid: true }; + //Randomly make the cargo invalid + this.randomlyMakeInvalid(resultDetails, cargo); + this.addSomeChaos(resultDetails, cargo) + + return { + cargo: dataBuilderUtil.addToEnvelope(cargo), + resultDetails + }; + }); + } + + randomlyMakeInvalid(resultDetails, cargo) { + if (dataBuilderUtil.randomYesOrNo(this.properties.chanceToInvalidate)) { + resultDetails.failureReason = dataBuilderUtil.makeInvalid(cargo, false); + resultDetails.isValid = false; + } + } + + addSomeChaos(resultDetails, cargo) { + if (this.properties.chaosSettings === undefined) return; + var activeChaos = this.properties.chaosSettings.filter(chaosSetting => chaosSetting.isEnabled); + activeChaos.forEach(chaosSetting => { + if (dataBuilderUtil.randomYesOrNo(chaosSetting.chanceToCauseChaos)) { + dataBuilderUtil.raiseChaos(resultDetails, cargo, chaosSetting); + } + }); + } +} + +module.exports = { default: CargoProcessingValidatorGenerator }; diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/validatedCargoManagers.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/validatedCargoManagers.js new file mode 100644 index 0000000..dbd79e1 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/generators/validatedCargoManagers.js @@ -0,0 +1,73 @@ +const dataBuilderUtil = require('../dataBuilderUtils.js'); +const ServiceBusClient = require('@azure/service-bus').ServiceBusClient; +const config = require('../config.js'); + +class ValidatedCargoManagerGenerator { + constructor(isValid, properties) { + this.isValid = isValid; + this.properties = properties; + this.canValidateResults = false; + } + + async run(count) { + const cargoMessageBodies = this.generateCargoToSend(count); + console.log(`${cargoMessageBodies.length} cargo objects created`); + const sbClient = new ServiceBusClient(config.serviceBusConnectionString); + const sender = sbClient.createSender(config.topicName); + const cargoSent = []; + try { + let batch = await sender.createMessageBatch(); + for (let i = 0; i < cargoMessageBodies.length; i++) { + const cargoToSend = cargoMessageBodies[i]; + // try to add the message to the batch + if (!batch.tryAddMessage(cargoToSend.cargo)) { + // Couldn't add more to the batch, sending what we have, then starting a new batch + console.log(`Sending batch of ${batch.count} cargo objects`); + await sender.sendMessages(batch); + + // create a new batch + batch = await sender.createMessageBatch(); + + // now, add the message failed to be added to the previous batch to this batch + if (!batch.tryAddMessage(cargoToSend.cargo)) { + // if it still can't be added to the batch, the message is probably too big to fit in a batch + throw new Error("Message too big to fit in a batch"); + } + } + cargoSent.push({ + id: cargoToSend.cargo.id, + resultDetails: cargoToSend.resultDetails + }); + } + + console.log(`Sending batch of ${batch.count} cargo objects`); + await sender.sendMessages(batch); + } + finally { + sender.close(); + sbClient.close(); + } + return cargoSent; + } + + generateCargoToSend(count) { + return [...Array(count).keys()].map(() => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + const resultDetails = { + isValid + } + if (this.isValid) { + cargo.valid = true; + cargo.errorMessage = null; + } else { + resultDetails.failureReason = dataBuilderUtil.makeInvalid(cargo, true); + } + return { + cargo: dataBuilderUtil.toServiceBusMessage(addToEnvelope(cargo), this.isValid), + resultDetails + }; + }); + } +} + +module.exports = { default: ValidatedCargoManagerGenerator }; diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/index.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/index.js new file mode 100644 index 0000000..a58c85b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/index.js @@ -0,0 +1,68 @@ +const dataBuilderUtil = require('./dataBuilderUtils.js'); +const parseArgs = require('node:util').parseArgs; +const CargoProcessingApiGenerator = require('./generators/cargoProcessingApi.js').default; +const CargoProcessingValidatorGenerator = require('./generators/cargoProcessingValidator.js').default; +const ValidatedCargoManagerGenerator = require('./generators/validatedCargoManagers.js').default; +const CargoValidation = require('./cargoValidation.js').default +const displayTestResults = require('./outputTestResults.js').displayTestResults; +const { v4: uuidv4 } = require('uuid'); +const fs = require('node:fs'); +const runId = uuidv4(); + +const options = { + 'config': { type: 'string', short: 'c', default: "./testConfigurations/valid_tests.json" }, +}; + +const { values } = parseArgs({ options, tokens: false }); + +const configSource = values.config === "-" ? 0 : values.config; // Read from stdin if config is "-" +const config = JSON.parse(fs.readFileSync(configSource, 'utf8')); + +let testsFailed = false; + +for (const test of config.tests) { + console.log(`Starting ${test.name} test.`) + let generator = null; + switch (test.target) { + case 'cargo-processing-api': + generator = new CargoProcessingApiGenerator(test.properties); + break; + case 'cargo-processing-validator': + generator = new CargoProcessingValidatorGenerator(test.properties); + break; + case 'valid-cargo-manager': + generator = new ValidatedCargoManagerGenerator(true, test.properties); + break; + case 'invalid-cargo-manager': + generator = new ValidatedCargoManagerGenerator(false, test.properties); + break; + } + + (async function () { + const testVolume = parseInt(test.volume); + if (testVolume == 0) { + console.log("Volume configured for 0 tests, exiting test"); + return; + } + + const cargoSent = [...await generator.run(parseInt(test.volume), parseInt(test.delayBetweenCargoInMilliseconds ?? 0))]; + if (test.validateResults && generator.canValidateResults) { + const validationResults = []; + const cargoValidator = new CargoValidation(); + console.log('Giving system time to process the cargo before validating the results'); + + await dataBuilderUtil.delay(test.validationDelayInMilliseconds); + for (const cargo of cargoSent) { + validationResults.push( + await cargoValidator.validate(cargo, test.maxRetries, test.startingRetryBufferInMilliseconds) + ); + } + await displayTestResults(validationResults, test.name, runId); + } + + })(); +}; + +if (testsFailed) { + process.exit(1); +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/outputTestResults.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/outputTestResults.js new file mode 100644 index 0000000..c743249 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/outputTestResults.js @@ -0,0 +1,65 @@ +const fs = require('fs/promises'); + +async function displayTestResults(validationResults, testName, runId) { + const successfulResults = []; + const failedResults = []; + for (const result of validationResults) { + var failed = false; + for (const key of Object.keys(result)) { + if (key == "testDetails") { + continue; + } + if (result[key] == false) { + failedResults.push(result); + failed = true; + continue; + } + } + if (!failed) { + successfulResults.push(result); + } + } + + console.log(`**********************************************************************************`); + console.log(`${testName} results: ${validationResults.length} test; \x1b[31m${failedResults.length} failed\x1b[0m; ${successfulResults.length} succeeded; `); + console.log(`**********************************************************************************`); + + await saveTestReport(testName, validationResults, failedResults, successfulResults, runId) +} + +async function saveTestReport(testName, validationResults, failedResults, successfulResults, runId) { + const testReportDirectory = "testResults"; + await createDirectory(testReportDirectory); + + const fileName = `./${testReportDirectory}/${testName.replaceAll(' ', '')}-${runId}.txt`; + await fs.writeFile(fileName, ""); + await fs.appendFile(fileName, `**********************************************************************************\n`); + await fs.appendFile(fileName, `${testName} results: ${validationResults.length} test; ${failedResults.length} failed; ${successfulResults.length} succeeded;\n`); + await fs.appendFile(fileName, `**********************************************************************************\n`); + + if (failedResults.length > 0) { + testsFailed = true; + await fs.appendFile(fileName, `\nFailed Results\n`); + await fs.appendFile(fileName, `----------------------------------------------------------------------------------\n`); + await fs.appendFile(fileName, `${JSON.stringify(failedResults, null, 2)}\n`); + } + if (successfulResults.length > 0) { + await fs.appendFile(fileName, `\nSuccessful Results:\n`); + await fs.appendFile(fileName, `----------------------------------------------------------------------------------\n`); + await fs.appendFile(fileName, JSON.stringify(successfulResults, null, 2)); + } + console.log(`Detailed Test Results can be viewed at ${fileName}`) +} + +async function createDirectory(path) { + try { + await fs.access(path); + } catch (error) { + console.log(error); + await fs.mkdir(path); + } +} + +module.exports = { + displayTestResults +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package-lock.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package-lock.json new file mode 100644 index 0000000..88ecc4e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package-lock.json @@ -0,0 +1,2943 @@ +{ + "name": "cargo-test-scripts", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "cargo-test-scripts", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@azure/service-bus": "^7.7.2", + "axios": "^1.1.3", + "date-fns": "^2.29.3", + "dotenv": "^16.0.3", + "uuid": "^9.0.0" + }, + "devDependencies": { + "chai": "^4.3.7", + "mocha": "^10.1.0" + } + }, + "node_modules/@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-amqp": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-3.1.1.tgz", + "integrity": "sha512-mQp19Z7uw/OaDw6v4ASLCMCuy3CPs/o2F45n3yOImnTjS2KrfMxVhrvxD7UL/+fRqhGJZwBpDqCXnlAiKNanrA==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-util": "^1.1.0", + "@azure/logger": "^1.0.0", + "buffer": "^6.0.0", + "events": "^3.0.0", + "jssha": "^3.1.0", + "process": "^0.11.10", + "rhea": "^2.0.3", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0", + "url": "^0.11.0", + "util": "^0.12.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.4.0.tgz", + "integrity": "sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.6.1.tgz", + "integrity": "sha512-mZ1MSKhZBYoV8GAWceA+PEJFWV2VpdNSpxxcj1wjIAOi00ykRuIQChT99xlQGZWLY3/NApWhSImlFwsmCEs4vA==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-paging": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.3.0.tgz", + "integrity": "sha512-H6Tg9eBm0brHqLy0OSAGzxIh1t4UL8eZVrSUMJ60Ra9cwq2pOskFqVpz2pYoHDsBY1jZ4V/P8LRGb5D5pmC6rg==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.9.2.tgz", + "integrity": "sha512-8rXI6ircjenaLp+PkOFpo37tQ1PQfztZkfVj97BIF3RPxHAsoVSgkJtu3IK/bUEWcb7HzXSoyBe06M7ODRkRyw==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.1.tgz", + "integrity": "sha512-A4TBYVQCtHOigFb2ETiiKFDocBoI1Zk2Ui1KpI42aJSIDexF7DHQFpnjonltXAIU/ceH+1fsZAWWgvX6/AKzog==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-xml": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", + "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", + "dependencies": { + "fast-xml-parser": "^4.0.8", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", + "integrity": "sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/service-bus": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.7.2.tgz", + "integrity": "sha512-acHI/ghFz6wRJgE1LucAZkdpWTEzfWt2moxD7RTo0/9nQoVsriE6GWI/lkyt56m+WiUbUh8Dms1srjF0G3AdyA==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-amqp": "^3.1.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.1.1", + "@azure/core-xml": "^1.0.0", + "@azure/logger": "^1.0.0", + "@types/is-buffer": "^2.0.0", + "buffer": "^6.0.0", + "is-buffer": "^2.0.3", + "jssha": "^3.1.0", + "long": "^5.2.0", + "process": "^0.11.10", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/is-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.0.tgz", + "integrity": "sha512-0f7N/e3BAz32qDYvgB4d2cqv1DqUwvGxHkXsrucICn8la1Vb6Yl6Eg8mPScGwUiqHJeE7diXlzaK+QMA9m4Gxw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", + "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", + "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-xml-parser": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", + "integrity": "sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA==", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jssha": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.0.tgz", + "integrity": "sha512-w9OtT4ALL+fbbwG3gw7erAO0jvS5nfvrukGPMWIAoea359B26ALXGpzy4YJSp9yGnpUvuvOw1nSjSoHDfWSr1w==", + "engines": { + "node": "*" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + }, + "node_modules/loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", + "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rhea": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/rhea/-/rhea-2.0.8.tgz", + "integrity": "sha512-IgwlP4D2lzinBSll5f35tAWa30dGCZhG9Ujd1DiaB7MUGegIjAaLzqATCw3ha+h9oq9mXcitqayBbNIXYdvtFg==", + "dependencies": { + "debug": "0.8.0 - 3.5.0" + } + }, + "node_modules/rhea-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-2.1.0.tgz", + "integrity": "sha512-CRMwdJ/o4oO/xKcvAwAsd0AHy5fVvSlqso7AadRmaaLGzAzc9LCoW7FOFnucI8THasVmOeCnv5c/fH/n7FcNaA==", + "dependencies": { + "debug": "^3.1.0", + "rhea": "^2.0.3", + "tslib": "^2.2.0" + } + }, + "node_modules/rhea-promise/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/rhea/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-amqp": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-3.1.1.tgz", + "integrity": "sha512-mQp19Z7uw/OaDw6v4ASLCMCuy3CPs/o2F45n3yOImnTjS2KrfMxVhrvxD7UL/+fRqhGJZwBpDqCXnlAiKNanrA==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-util": "^1.1.0", + "@azure/logger": "^1.0.0", + "buffer": "^6.0.0", + "events": "^3.0.0", + "jssha": "^3.1.0", + "process": "^0.11.10", + "rhea": "^2.0.3", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0", + "url": "^0.11.0", + "util": "^0.12.1" + } + }, + "@azure/core-auth": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.4.0.tgz", + "integrity": "sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.6.1.tgz", + "integrity": "sha512-mZ1MSKhZBYoV8GAWceA+PEJFWV2VpdNSpxxcj1wjIAOi00ykRuIQChT99xlQGZWLY3/NApWhSImlFwsmCEs4vA==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-paging": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.3.0.tgz", + "integrity": "sha512-H6Tg9eBm0brHqLy0OSAGzxIh1t4UL8eZVrSUMJ60Ra9cwq2pOskFqVpz2pYoHDsBY1jZ4V/P8LRGb5D5pmC6rg==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-rest-pipeline": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.9.2.tgz", + "integrity": "sha512-8rXI6ircjenaLp+PkOFpo37tQ1PQfztZkfVj97BIF3RPxHAsoVSgkJtu3IK/bUEWcb7HzXSoyBe06M7ODRkRyw==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-util": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.1.tgz", + "integrity": "sha512-A4TBYVQCtHOigFb2ETiiKFDocBoI1Zk2Ui1KpI42aJSIDexF7DHQFpnjonltXAIU/ceH+1fsZAWWgvX6/AKzog==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-xml": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", + "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", + "requires": { + "fast-xml-parser": "^4.0.8", + "tslib": "^2.2.0" + } + }, + "@azure/logger": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", + "integrity": "sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/service-bus": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.7.2.tgz", + "integrity": "sha512-acHI/ghFz6wRJgE1LucAZkdpWTEzfWt2moxD7RTo0/9nQoVsriE6GWI/lkyt56m+WiUbUh8Dms1srjF0G3AdyA==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-amqp": "^3.1.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.1.1", + "@azure/core-xml": "^1.0.0", + "@azure/logger": "^1.0.0", + "@types/is-buffer": "^2.0.0", + "buffer": "^6.0.0", + "is-buffer": "^2.0.3", + "jssha": "^3.1.0", + "long": "^5.2.0", + "process": "^0.11.10", + "rhea-promise": "^2.1.0", + "tslib": "^2.2.0" + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + }, + "@types/is-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.0.tgz", + "integrity": "sha512-0f7N/e3BAz32qDYvgB4d2cqv1DqUwvGxHkXsrucICn8la1Vb6Yl6Eg8mPScGwUiqHJeE7diXlzaK+QMA9m4Gxw==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + }, + "axios": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", + "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-eql": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", + "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "fast-xml-parser": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", + "integrity": "sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA==", + "requires": { + "strnum": "^1.0.5" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jssha": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.0.tgz", + "integrity": "sha512-w9OtT4ALL+fbbwG3gw7erAO0jvS5nfvrukGPMWIAoea359B26ALXGpzy4YJSp9yGnpUvuvOw1nSjSoHDfWSr1w==" + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + }, + "loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "mocha": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", + "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "dev": true, + "requires": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "rhea": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/rhea/-/rhea-2.0.8.tgz", + "integrity": "sha512-IgwlP4D2lzinBSll5f35tAWa30dGCZhG9Ujd1DiaB7MUGegIjAaLzqATCw3ha+h9oq9mXcitqayBbNIXYdvtFg==", + "requires": { + "debug": "0.8.0 - 3.5.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "rhea-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-2.1.0.tgz", + "integrity": "sha512-CRMwdJ/o4oO/xKcvAwAsd0AHy5fVvSlqso7AadRmaaLGzAzc9LCoW7FOFnucI8THasVmOeCnv5c/fH/n7FcNaA==", + "requires": { + "debug": "^3.1.0", + "rhea": "^2.0.3", + "tslib": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package.json new file mode 100644 index 0000000..ab77261 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/package.json @@ -0,0 +1,22 @@ +{ + "name": "cargo-test-scripts", + "version": "1.0.0", + "description": "Command utility to execute test scripts from", + "main": "index.js", + "scripts": { + "test": "mocha" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@azure/service-bus": "^7.7.2", + "axios": "^1.1.3", + "date-fns": "^2.29.3", + "dotenv": "^16.0.3", + "uuid": "^9.0.0" + }, + "devDependencies": { + "chai": "^4.3.7", + "mocha": "^10.1.0" + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/seed.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/seed.json new file mode 100644 index 0000000..d3dbb98 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/seed.json @@ -0,0 +1,177 @@ +{ + "ports": [ + "Shanghai, China", + "Singapore", + "Ningbo-Zhoushan, China", + "Shenzhen, China", + "Guangzhou Harbor, China", + "Busan, South Korea", + "Qingdao, China", + "Hong Kong, S.A.R, China", + "Tianjin, China", + "Rotterdam, The Netherlands", + "Jebel Ali, Dubai, United Arab Emirates", + "Port Klang, Malaysia", + "Xiamen, China", + "Antwerp, Belgium", + "Kaohsiung, Taiwan, China", + "Dalian, China", + "Los Angeles, U.S.A", + "Hamburg, Germany", + "Tanjung Pelepas, Malaysia", + "Laem Chabang, Thailand", + "Keihin Ports, Japan", + "Long Beach, U.S.A.", + "Tanjung Priok, Jakarta, Indonesia", + "New York-New Jersey, U.S.A.", + "Colombo, Sri Lanka", + "Ho Chi Minh City, Vietnam", + "Suzhou, China", + "Piraeus, Greece", + "Yingkou, China", + "Valencia, Spain", + "Manila, Philippines", + "Taicang, China", + "Algeciras, Spain", + "Jawarharlal Nehru Port (Nhava Sheva), India", + "Bremen/Bremerhaven, Germany", + "Tanger Med, Morocco", + "Lianyungang, China", + "Mundra, India", + "Savannah, U.S.A", + "Tokyo, Japan", + "English Chinese Korean Japanese", + "Rizhao, China", + "English Chinese", + "Foshan, China", + "Jeddah, Saudi Arabia", + "Colon, Panama", + "Santos, Brazil", + "Salalah, Oman", + "Dongguan, China", + "Guangxi Beibu, China" + ], + "products": [ + "Tracksuits", + "Silk pajamas", + "Backpacks", + "Slides", + "Knitted dress", + "Flannel shirts", + "Leggings", + "Silicone rings", + "Boho clothes", + "Mom jeans", + "Loose jeans", + "Balaclava", + "Tote bags", + "Scrunchies", + "Couple unisex T-shirts", + "Essential short sleeve tees", + "Sandals", + "Floral-print kimonos", + "Quick-dry running shorts", + "Wirefree bras", + "Cargo shorts", + "Loafers", + "Tank tops", + "Smart locks", + "Cordless electric drills", + "Repair tool kit", + "Digital micrometer", + "Electric scissors", + "Electric crimping tools", + "Welding tips", + "Desoldering pumps", + "Ceramic coating", + "Socket wrenches", + "Digital tire-pressure gauge", + "Portable power stations", + "Car jump starters", + "Portable air compressor", + "Decorative lamp", + "Sheet metal tools", + "Tire repair & Installation tools", + "Code readers & Scan tools", + "Hand sanitizer", + "Bamboo toothbrushes", + "Sleep eye masks", + "Sleep gummies", + "Yoga mats", + "Massage guns", + "Vitamin C serum", + "Jade rollers", + "Acne patches", + "Electric toothbrushes", + "Lip masks", + "Blue light glasses", + "Posture corrector", + "Oral irrigators", + "Scalp massager", + "Hair growth oil", + "Yoga socks", + "Makeup remover facial wipes", + "Cruelty-free mascara", + "Pimple patches", + "Sunscreen", + "Skin care oil", + "Eyeliner pencil", + "Facial moisturizing lotion", + "Hydrating eye gel", + "Baby monitor", + "Baby carrier", + "Smart bassinet", + "Nipple breastmilk storage bags", + "Baby stroller & accessories", + "Toilet training", + "Car seats & accessories", + "Hypoallergenic baby diaper wipes", + "Water-based wipes", + "Diapers", + "Stroller fans", + "Blue light glasses", + "Pencil cases", + "Mechanical pencils", + "Podcast microphones", + "Mechanical keycaps", + "Wall clock", + "Drawing tablet", + "Laser acupuncture pen", + "Gaming monitors", + "Ergonomic chairs", + "Gaming mouse pads", + "Gaming headsets", + "Smart plugs", + "Smart lights", + "Soap dispensers", + "Smart locks", + "Wireless security cameras", + "Foldable picnic table", + "Air purifiers", + "Rice cooker", + "Rugs", + "Reusable silicone food covers", + "Vacuum packing machine", + "Thermos/Flask", + "Biometric locks", + "Portable blenders", + "Water shower filter", + "Electric kettles", + "Oat milk", + "Fasting tea", + "Wine fridges", + "Doormats", + "Air-purifying plants", + "Ceiling fans", + "Blackout curtains", + "Blankets", + "Orthopedic pillows", + "Duvet covers", + "Bedside lamps", + "Air fryers", + "Electric kettles", + "Portable blenders", + "Coffee pods", + "Latte mixers" + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/test/dataBuilderUtils.test.js b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/test/dataBuilderUtils.test.js new file mode 100644 index 0000000..a3b8e7f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/test/dataBuilderUtils.test.js @@ -0,0 +1,60 @@ +const expect = require('chai').expect; +const dataBuilderUtil = require('../dataBuilderUtils'); +const addDays = require('date-fns/addDays'); + +describe('Make Invalid Functionality', () => { + it('Should make the dates occur in the past', () => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + //Make sure the values are populated + dataBuilderUtil.makeInvalid(cargo, false, 1); + expect(cargo.demandDates.start).to.not.be.undefined; + expect(cargo.demandDates.end).to.not.be.undefined; + //Make sure the start date occurs before the end date + expect(cargo.demandDates.end).to.be.above(cargo.demandDates.start); + //Make sure the dates occur in the past + expect(new Date()).to.be.above(cargo.demandDates.end); + }); + + it('Should make the dates occur to far in the future', () => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + dataBuilderUtil.makeInvalid(cargo, false, 2); + //Make sure the values are populated + expect(cargo.demandDates.start).to.not.be.undefined; + expect(cargo.demandDates.end).to.not.be.undefined; + //Make sure the start date occurs before the end date + expect(cargo.demandDates.end).to.be.above(cargo.demandDates.start); + //Make sure the dates occur to far into the future + expect(addDays(new Date(), 60)).to.be.below(cargo.demandDates.start); + }); + + it('Should make the dates to far apart', () => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + dataBuilderUtil.makeInvalid(cargo, false, 3); + //Make sure the values are populated + expect(cargo.demandDates.start).to.not.be.undefined; + expect(cargo.demandDates.end).to.not.be.undefined; + //Make sure the start date occurs before the end date + expect(cargo.demandDates.end).to.be.above(cargo.demandDates.start); + //Make sure the dates occur to far apart + expect(cargo.demandDates.end - cargo.demandDates.start).to.be.above(30); + }); + + it('Should make the end date occur before the start date', () => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + dataBuilderUtil.makeInvalid(cargo, false, 4); + //Make sure the values are populated + expect(cargo.demandDates.start).to.not.be.undefined; + expect(cargo.demandDates.end).to.not.be.undefined; + //Make sure the start date occurs after the end date + expect(cargo.demandDates.end).to.be.below(cargo.demandDates.start); + }); + + it('Should populate the error details on the cargo object', () => { + const cargo = dataBuilderUtil.generateBaseCargoObject(); + dataBuilderUtil.makeInvalid(cargo, true, 1); + //Make sure the values are populated + expect(cargo.valid).to.be.false; + expect(cargo.errorMessage).to.not.be.undefined; + }); +}); + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/cargo_processing_api_chaos_tests.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/cargo_processing_api_chaos_tests.json new file mode 100644 index 0000000..53f30c4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/cargo_processing_api_chaos_tests.json @@ -0,0 +1,24 @@ +{ + "tests": [ + { + "name": "CHAOS: Cargo Processing Validator Starting", + "target": "cargo-processing-api", + "volume": 1, + "validateResults": false, + "validationDelayInMilliseconds": 10000, + "delayBetweenCargoInMilliseconds": 1000, + "maxRetries": 5, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0, + "chaosSettings": [ + { + "target": "cargo-processing-api", + "type": "operations-api-failure", + "chanceToCauseChaos": 1 + } + ] + } + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/scale.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/scale.json new file mode 100644 index 0000000..c99c2ef --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/scale.json @@ -0,0 +1,30 @@ +{ + "tests": [ + { + "name": "End to End Validation at scale", + "target": "cargo-processing-api", + "volume": 10000, + "validateResults": true, + "validationDelayInMilliseconds": 60000, + "maxRetries": 5, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 10, + "chaosSettings": [ + { + "target": "operations-api", + "type": "service-failure", + "chanceToCauseChaos": 4, + "isEnabled": false + }, + { + "target": "cargo-processing-api", + "type": "duplicate", + "chanceToCauseChaos": 4, + "isEnabled": false + } + ] + } + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-normal.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-normal.json new file mode 100644 index 0000000..7894a9c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-normal.json @@ -0,0 +1,15 @@ +{ + "tests": [ + { + "name": "End to End Validation of valid cargo with normal ports", + "target": "cargo-processing-api", + "volume": 50, + "validateResults": false, + "delayBetweenCargoInMilliseconds": 1000, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0 + } + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-slow-port.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-slow-port.json new file mode 100644 index 0000000..85ac953 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid-cargo-slow-port.json @@ -0,0 +1,23 @@ +{ + "tests": [ + { + "name": "End to End Validation of valid cargo with 50% chance of slow port", + "target": "cargo-processing-api", + "volume": 50, + "validateResults": false, + "delayBetweenCargoInMilliseconds": 1000, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0, + "chaosSettings": [ + { + "target": "cargo-processing-api", + "type": "slow-port", + "chanceToCauseChaos": 2, + "isEnabled": true + } + ] + } + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid_tests.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid_tests.json new file mode 100644 index 0000000..7e63c70 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-test-scripts/testConfigurations/valid_tests.json @@ -0,0 +1,28 @@ +{ + "tests": [ + { + "name": "End to End Validation of valid cargo", + "target": "cargo-processing-api", + "volume": 5, + "validateResults": true, + "validationDelayInMilliseconds": 10000, + "maxRetries": 5, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 0 + } + }, + { + "name": "End to End Validation of invalid cargo", + "target": "cargo-processing-api", + "volume": 5, + "validateResults": true, + "validationDelayInMilliseconds": 10000, + "maxRetries": 5, + "startingRetryBufferInMilliseconds": 300, + "properties": { + "chanceToInvalidate": 1 + } + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/docker-compose.yml b/accelerators/aks-sb-azmonitor-microservices/src/docker-compose.yml new file mode 100644 index 0000000..5603371 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/docker-compose.yml @@ -0,0 +1,36 @@ +version: "3.9" + +services: + operations-api: + env_file: + - ./operations-api/.env + build: + context: ./operations-api + dockerfile: Dockerfile + ports: + - "8081:8081" + cargo-processing-api: + env_file: + - ./cargo-processing-api/.env + build: + context: ./cargo-processing-api + dockerfile: Dockerfile + ports: + - "8080:8080" + cargo-processing-validator: + env_file: + - ./cargo-processing-validator/.env + build: + context: ./cargo-processing-validator + dockerfile: Dockerfile + valid-cargo-manager: + build: + context: ./valid-cargo-manager + dockerfile: Dockerfile + invalid-cargo-manager: + env_file: + - ./invalid-cargo-manager/.env + build: + context: ./invalid-cargo-manager + dockerfile: Dockerfile + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/Dockerfile new file mode 100644 index 0000000..f90d80d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/Dockerfile @@ -0,0 +1,22 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.241.1/containers/python-3/.devcontainer/base.Dockerfile + +# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster +ARG VARIANT="3.10-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} + +# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 +ARG NODE_VERSION="none" +RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image. +# COPY requirements.txt /tmp/pip-tmp/ +# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ +# && rm -rf /tmp/pip-tmp + +# [Optional] Uncomment this section to install additional OS packages. +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && python -m pip install --upgrade pip \ + && apt-get -y install --no-install-recommends cmake + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/devcontainer.json new file mode 100644 index 0000000..84a5fc5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.devcontainer/devcontainer.json @@ -0,0 +1,59 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.241.1/containers/python-3 +{ + "name": "Python 3", + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "args": { + // Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6 + // Append -bullseye or -buster to pin to an OS version. + // Use -bullseye variants on local on arm64/Apple Silicon. + "VARIANT": "3.10-bullseye", + // Options + "NODE_VERSION": "lts/*" + } + }, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "python.defaultInterpreterPath": "/usr/local/bin/python", + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", + "python.formatting.blackPath": "/usr/local/py-utils/bin/black", + "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", + "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", + "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", + "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", + "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", + "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", + "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint", + "autoDocstring.docstringFormat": "numpy" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "njpwerner.autodocstring" + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "git": "latest", + "github-cli": "latest", + "azure-cli": "latest" + }, + "postCreateCommand": "pip install -r requirements.txt" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.dockerignore b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.dockerignore new file mode 100644 index 0000000..2ce5e1c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.dockerignore @@ -0,0 +1,2 @@ +.env +helm diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.env.sample b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.env.sample new file mode 100644 index 0000000..04d04a5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.env.sample @@ -0,0 +1,18 @@ +SERVICE_BUS_CONNECTION_STR= +SERVICE_BUS_TOPIC_NAME= +SERVICE_BUS_SUBSCRIPTION_NAME= +SERVICE_BUS_QUEUE_NAME= +SERVICE_BUS_MAX_MESSAGE_COUNT= +SERVICE_BUS_MAX_WAIT_TIME= + +COSMOS_DB_ENDPOINT= +COSMOS_DB_KEY= +COSMOS_DB_DATABASE_NAME= +COSMOS_DB_CONTAINER_NAME= + +APPLICATIONINSIGHTS_CONNECTION_STRING= +CLOUD_LOGGING_LEVEL=INFO +CONSOLE_LOGGING_LEVEL=DEBUG + +HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS=30 +HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS=60 \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.gitignore b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.gitignore new file mode 100644 index 0000000..972165c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.gitignore @@ -0,0 +1,3 @@ +.env +__pycache__/ +error.json \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.vscode/launch.json b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.vscode/launch.json new file mode 100644 index 0000000..7675091 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true, + "envFile": "${workspaceFolder}/.env" + }, + { + "name": "Python: Service", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/src/service/app.py", + "justMyCode": true, + "envFile": "${workspaceFolder}/.env" + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/Dockerfile new file mode 100644 index 0000000..5f41734 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/Dockerfile @@ -0,0 +1,13 @@ +FROM mcr.microsoft.com/mirror/docker/library/python:3.10-buster +WORKDIR /code +COPY ./requirements.txt /code/requirements.txt + +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && python -m pip install --upgrade pip \ + && apt-get -y install --no-install-recommends cmake + +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +COPY ./src/service /code/service + +CMD ["python", "/code/service/app.py", "--host", "0.0.0.0", "--port", "3100", "--proxy-headers"] diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/README.md b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/README.md new file mode 100644 index 0000000..413ccbe --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/README.md @@ -0,0 +1,45 @@ +# Running the service + +## Pre-Requisites + +1. Service Bus [namespace](https://docs.microsoft.com/cli/azure/servicebus/namespace?view=azure-cli-latest#az-servicebus-namespace-create) with [topic](https://docs.microsoft.com/cli/azure/servicebus/topic?view=azure-cli-latest#az-servicebus-topic-create) and [subscription](https://docs.microsoft.com/cli/azure/servicebus/topic/subscription?view=azure-cli-latest#az-servicebus-topic-subscription-create) +1. Application Insights [account](https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource#azure-cli-preview) +1. Cosmos DB [account](https://docs.microsoft.com/cli/azure/cosmosdb?view=azure-cli-latest#az-cosmosdb-create) with [database](https://docs.microsoft.com/cli/azure/cosmosdb/sql/database?view=azure-cli-latest#az-cosmosdb-sql-database-create) and [container](https://docs.microsoft.com/cli/azure/cosmosdb/sql/container?view=azure-cli-latest) + +## Debugging from VSCode Dev Container + +* Open the project in the dev container. + * Make sure to open in the devcontainer +* Rename `.env.sample` to `.env` and add connection strings for Service Bus, Cosmos DB and Application Insights. +* Configure debugger to use the "Python: Service" configuration. +* Run the Debugger. +* Post a message to the the Service Bus Topic similar to the [sample message](#sample-message). + +## Docker Container + +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Run `docker compose up` to run the service. +* Post a message to the the Service Bus Topic similar to the [sample message](#sample-message). + +## Sample Message + +``` json +{ + "id": "08e222e4-5180-4f35-a8d6-e41b47b6447c", + "timestamp": "2022-06-24T17:10:28.000+00:00", + "product": { + "name": "toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-06-24T00:00:00.000+00:00", + "end": "2022-06-30T00:00:00.000+00:00" + }, + "valid": false, + "errorMessage": "Bad stuff happened when it was validated" +} +``` diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/docker-compose.yml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/docker-compose.yml new file mode 100644 index 0000000..4f3bd00 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/docker-compose.yml @@ -0,0 +1,9 @@ +version: "3.9" + +services: + invalid_cargo_manager: + env_file: + - .env + build: + context: . + dockerfile: Dockerfile diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/.helmignore b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/Chart.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/Chart.yaml new file mode 100644 index 0000000..1c01e1f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: invalid-cargo-manager +description: invalid-cargo-manager for aks-sb-azmonitor-microservices + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/invalid-cargo-manager.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/invalid-cargo-manager.yaml new file mode 100644 index 0000000..3d7bf17 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/invalid-cargo-manager.yaml @@ -0,0 +1,35 @@ +image: + pullPolicy: Always + tag: "latest" + +replicaCount: 1 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +podAnnotations: {} +podSecurityContext: {} +securityContext: {} +resources: {} +nodeSelector: {} +tolerations: [] +affinity: {} + + +# When running one of the deploy-*.sh scripts, an additional env.yaml +# values file is created containing values specific to the deployed environment +# with the following values: +# image: +# repository: + +# keyVault: +# name: +# tenantId: + +# aksKeyVaultSecretProviderIdentityId: diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/NOTES.txt b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/NOTES.txt new file mode 100644 index 0000000..dd366ce --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aks-sb-azmonitor-microservices.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/_helpers.tpl b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/_helpers.tpl new file mode 100644 index 0000000..0172cb3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "aks-sb-azmonitor-microservices.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "aks-sb-azmonitor-microservices.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "aks-sb-azmonitor-microservices.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "aks-sb-azmonitor-microservices.labels" -}} +helm.sh/chart: {{ include "aks-sb-azmonitor-microservices.chart" . }} +{{ include "aks-sb-azmonitor-microservices.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "aks-sb-azmonitor-microservices.selectorLabels" -}} +app.kubernetes.io/name: {{ include "aks-sb-azmonitor-microservices.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "aks-sb-azmonitor-microservices.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "aks-sb-azmonitor-microservices.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/deployment.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/deployment.yaml new file mode 100644 index 0000000..ea831b2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/deployment.yaml @@ -0,0 +1,115 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: default + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: SERVICE_BUS_TOPIC_NAME + value: validated-cargo + - name: SERVICE_BUS_SUBSCRIPTION_NAME + value: invalid-cargo + - name: SERVICE_BUS_QUEUE_NAME + value: operation-state + - name: SERVICE_BUS_MAX_MESSAGE_COUNT + value: "1" + - name: SERVICE_BUS_MAX_WAIT_TIME + value: "5" + - name: COSMOS_DB_DATABASE_NAME + value: cargo + - name: COSMOS_DB_CONTAINER_NAME + value: invalid-cargo + - name: CLOUD_LOGGING_LEVEL + value: INFO + - name: CONSOLE_LOGGING_LEVEL + value: DEBUG + - name: HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS + value: "30" + - name: HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS + value: "60" + - name: APPLICATIONINSIGHTS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: invalid-cargo-manager-secrets + key: AppInsightsConnectionString + - name: SERVICE_BUS_CONNECTION_STR + valueFrom: + secretKeyRef: + name: invalid-cargo-manager-secrets + key: ServiceBusConnectionString + - name: COSMOS_DB_ENDPOINT + valueFrom: + secretKeyRef: + name: invalid-cargo-manager-secrets + key: CosmosDBEndpoint + - name: COSMOS_DB_KEY + valueFrom: + secretKeyRef: + name: invalid-cargo-manager-secrets + key: CosmosDBKey + ports: + - name: http + containerPort: 8080 + protocol: TCP + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: secrets-store + mountPath: "/mnt/secrets-store" + readOnly: true + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: secrets-store + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: {{ include "aks-sb-azmonitor-microservices.fullname" . }} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/hpa.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/hpa.yaml new file mode 100644 index 0000000..0a3ca97 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/secretProviderClass.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/secretProviderClass.yaml new file mode 100644 index 0000000..8edb248 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/secretProviderClass.yaml @@ -0,0 +1,41 @@ +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + provider: azure + parameters: + usePodIdentity: "false" + useVMManagedIdentity: "true" + userAssignedIdentityID: {{ .Values.aksKeyVaultSecretProviderIdentityId }} + keyvaultName: {{ .Values.keyVault.name }} + cloudName: "" + objects: | + array: + - | + objectName: AppInsightsConnectionString + objectType: secret + - | + objectName: ServiceBusConnectionString + objectType: secret + - | + objectName: CosmosDBEndpoint + objectType: secret + - | + objectName: CosmosDBKey + objectType: secret + tenantId: {{ .Values.keyVault.tenantId }} + secretObjects: + - data: + - key: AppInsightsConnectionString + objectName: AppInsightsConnectionString + - key: ServiceBusConnectionString + objectName: ServiceBusConnectionString + - key: CosmosDBEndpoint + objectName: CosmosDBEndpoint + - key: CosmosDBKey + objectName: CosmosDBKey + secretName: invalid-cargo-manager-secrets + type: Opaque \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/service.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/service.yaml new file mode 100644 index 0000000..af3f13a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 4 }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/tests/test-connection.yaml b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5eb4bc4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "aks-sb-azmonitor-microservices.fullname" . }}-test-connection" + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "aks-sb-azmonitor-microservices.fullname" . }}:80'] + restartPolicy: Never diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/requirements.txt b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/requirements.txt new file mode 100644 index 0000000..c8374b4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/requirements.txt @@ -0,0 +1,6 @@ +azure-servicebus +azure-cosmos +asyncio +opencensus-ext-azure +jsons +py-healthcheck diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app.py new file mode 100644 index 0000000..09e1970 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +"""Defines the applications processing loop +""" + +import asyncio +from app_context import ApplicationContext + +if __name__ == "__main__": + application_context = ApplicationContext() + + loop = asyncio.get_event_loop() + loop.run_until_complete(application_context.start()) diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_config.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_config.py new file mode 100644 index 0000000..f3a6b6f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_config.py @@ -0,0 +1,25 @@ +"""Centralized location for application setting to be loaded +""" +import os + +COSMOS_ENDPOINT = os.environ['COSMOS_DB_ENDPOINT'] +COSMOS_KEY = os.environ['COSMOS_DB_KEY'] +COSMOS_DATABASE_NAME = os.environ['COSMOS_DB_DATABASE_NAME'] +COSMOS_CONTAINER_NAME = os.environ['COSMOS_DB_CONTAINER_NAME'] + +LOGGING_APP_NAME = 'invalid-cargo-manager' +LOGGING_CLOUD_LOGGING_LEVEL = os.environ['CLOUD_LOGGING_LEVEL'].upper() +LOGGING_CONSOLE_LOGGING_LEVEL = os.environ['CONSOLE_LOGGING_LEVEL'].upper() + +SERVICE_BUS_CONNECTION_STR = os.environ['SERVICE_BUS_CONNECTION_STR'] +SERVICE_BUS_TOPIC_NAME = os.environ["SERVICE_BUS_TOPIC_NAME"] +SERVICE_BUS_QUEUE_NAME = os.environ["SERVICE_BUS_QUEUE_NAME"] +SERVICE_BUS_SUBSCRIPTION_NAME = os.environ["SERVICE_BUS_SUBSCRIPTION_NAME"] +SERVICE_BUS_MAX_MESSAGE_COUNT = int( + os.environ["SERVICE_BUS_MAX_MESSAGE_COUNT"]) +SERVICE_BUS_MAX_WAIT_TIME = int(os.environ["SERVICE_BUS_MAX_WAIT_TIME"]) + +HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS = int( + os.environ["HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS"]) +HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS = int( + os.environ["HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS"]) diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_context.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_context.py new file mode 100644 index 0000000..68c2f78 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/app_context.py @@ -0,0 +1,36 @@ +"""Contains the primary objects that make up the applications context +""" +from logging_config import logger +from state_processor import send_operation_state +from message_receiver import MessageReceiver +from cargo_repo import CargoRepo +from healthcheck import EnvironmentDump +from telemetry_publisher import TelemetryPublisher + +#pylint: disable=too-few-public-methods + + +class ApplicationContext: + """Class defining the context of the application + """ + + def __init__(self): + self._telemetry_publisher: TelemetryPublisher = TelemetryPublisher() + self._cargo_repo: CargoRepo = CargoRepo() + self._message_receiver: MessageReceiver = MessageReceiver( + telemetry_publisher=self._telemetry_publisher) + self._environment_dump = EnvironmentDump() + + async def start(self): + """Entry point for the application + """ + env_dump = self._environment_dump.run()[0] + logger.info("Environment Dump: %s", env_dump) + logger.info("Entering listening loop") + try: + while True: + await self._message_receiver.listen( + self._cargo_repo.store_cargo, send_operation_state) + except BaseException as err: # pylint: disable=broad-except + # Want to ensure the exception is logged on our way out + logger.exception(err) diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/cargo_repo.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/cargo_repo.py new file mode 100644 index 0000000..ea18377 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/cargo_repo.py @@ -0,0 +1,31 @@ +"""Class used to communicate with the Cosmos Db +""" + +import jsons +from logging_config import logger +from azure.cosmos import CosmosClient +from models import InvalidCargo +from app_config import COSMOS_CONTAINER_NAME, COSMOS_DATABASE_NAME, \ + COSMOS_ENDPOINT, COSMOS_KEY + +class CargoRepo: #pylint: disable=too-few-public-methods + """Class used to communicate with the Cosmos Db + """ + def __init__(self): + client = CosmosClient(COSMOS_ENDPOINT, COSMOS_KEY) + database = client.get_database_client(database=COSMOS_DATABASE_NAME) + self.container = database.get_container_client( + container=COSMOS_CONTAINER_NAME + ) + + def store_cargo(self, invalid_cargo: InvalidCargo): + """Store the cargo object provided in the cosmos db + + Parameters + ---------- + invalid_cargo : InvalidCargo + cargo object to store + """ + logger.info("Storing invalid cargo in database") + self.container.upsert_item(body=jsons.dump(invalid_cargo)) + \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/logging_config.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/logging_config.py new file mode 100644 index 0000000..996e5e8 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/logging_config.py @@ -0,0 +1,31 @@ +"""Creates the logger for the application +""" + +import logging +import sys +from opencensus.ext.azure.log_exporter import AzureLogHandler +from app_config import LOGGING_APP_NAME, LOGGING_CLOUD_LOGGING_LEVEL, \ + LOGGING_CONSOLE_LOGGING_LEVEL + +logger = logging.getLogger(LOGGING_APP_NAME) + # Set the root level for logging, no handler will be able to report anything lower than this value +logger.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') + +consoleHandler = logging.StreamHandler() +consoleHandler.setLevel(LOGGING_CONSOLE_LOGGING_LEVEL) +consoleHandler.setFormatter(formatter) +consoleHandler.setStream(sys.stdout) + +logger.addHandler(consoleHandler) + +def callback_add_role_name(envelope): + """ Callback function for opencensus """ + envelope.tags["ai.cloud.role"] = LOGGING_APP_NAME + return True + +azureHandler = AzureLogHandler() +azureHandler.setLevel(LOGGING_CLOUD_LOGGING_LEVEL) +azureHandler.add_telemetry_processor(callback_add_role_name) + +logger.addHandler(azureHandler) diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/message_receiver.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/message_receiver.py new file mode 100644 index 0000000..1cb1712 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/message_receiver.py @@ -0,0 +1,129 @@ +"""Used to listen for messages from the service bus topic containing +invalid cargo messages +""" +import time +from typing import Awaitable, Callable +from logging_config import logger +import jsons +from azure.servicebus.aio import ServiceBusClient +from models import MessageEnvelope, OperationState +from app_config import SERVICE_BUS_CONNECTION_STR, SERVICE_BUS_MAX_MESSAGE_COUNT, \ + SERVICE_BUS_MAX_WAIT_TIME, SERVICE_BUS_SUBSCRIPTION_NAME, SERVICE_BUS_TOPIC_NAME, \ + HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS, \ + HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS +from telemetry_publisher import TelemetryPublisher +from opencensus.trace.status import Status + +#pylint: disable=too-many-instance-attributes + +class MessageReceiver: + """Class used to receive messages from the service bus topic + """ + + def __init__(self, telemetry_publisher: TelemetryPublisher): + self._telemetry_publisher = telemetry_publisher + self._configure_service_bus_receiver() + self._max_message_count = SERVICE_BUS_MAX_MESSAGE_COUNT + self._max_wait_time = SERVICE_BUS_MAX_WAIT_TIME + self._last_peeked = 0 + self._degraded_threshold = HEALTH_CHECK_SERVICE_BUS_DEGRADED_THRESHOLD_SECONDS + self._unhealthy_threshold = HEALTH_CHECK_SERVICE_BUS_UNHEALTHY_THRESHOLD_SECONDS + + def _configure_service_bus_receiver(self): + logger.info('Creating service bus client') + servicebus_client = ServiceBusClient.from_connection_string( + conn_str=SERVICE_BUS_CONNECTION_STR) + logger.info('Creating receiver') + self._servicebus_receiver = servicebus_client.get_subscription_receiver( + topic_name=SERVICE_BUS_TOPIC_NAME, + subscription_name=SERVICE_BUS_SUBSCRIPTION_NAME + ) + + def _retrieve_value_from_message_application_properties(self, msg, key): + # Keys and values are byte strings + byte_key = key.encode() + byte_value = msg.application_properties[byte_key] + return byte_value.decode() + + async def listen( + self, message_processor: Callable, + state_publisher: Callable[[OperationState, str, str], Awaitable[None]]): + """Listens for messages from the service bus topic + + Parameters + ---------- + message_processor : Callable + Function to call when a message is received + state_publisher : Callable[[OperationState, str, str], Awaitable[None]] + Awaitable function to call to update operation state + """ + + logger.info('Retrieving messages') + + if not self.is_healthy(): + # We want to fail hard if the health check returns a false + raise Exception("Service is not healthy") + self._last_peeked = time.time() + received_msgs = await self._servicebus_receiver.receive_messages( + max_message_count=self._max_message_count, + max_wait_time=self._max_wait_time) + + for msg in received_msgs: + logger.info('Processing message') + # Pull operation and operation parent id from application properties on incoming message + diagnostic_id = self._retrieve_value_from_message_application_properties(msg, "Diagnostic-Id") + telemetry_operation_id = diagnostic_id.split("-")[1] + telemetry_operation_parent_id = diagnostic_id.split("-")[2] + tracer = self._telemetry_publisher.create_tracer(telemetry_operation_id, telemetry_operation_parent_id) + # Create request in application insights with parent dependency from cargo-processing-validator + with self._telemetry_publisher.create_process_message_request_span(tracer, "ServiceBusTopic.ProcessMessage", SERVICE_BUS_SUBSCRIPTION_NAME) as process_message_request: + try: + message = jsons.loads(str(msg), MessageEnvelope) + with self._telemetry_publisher.create_cosmos_db_store_dependency_span(tracer, "upsertItem.invalid-cargo") as cosmos_db_store_dependency: + message_processor(message.data) + with self._telemetry_publisher.create_operations_queue_send_dependency_span(tracer, "operations send") as operations_queue_send_dependency: + await state_publisher(OperationState( + operationId=message.operationId, + state="Succeeded", + result=message.data), + telemetry_operation_id, operations_queue_send_dependency.span_id) + with self._telemetry_publisher.create_validated_cargo_topic_dependency_span(tracer, "validated-cargo complete") as validated_cargo_topic_complete_dependency: + await self._servicebus_receiver.complete_message(msg) + except jsons.DecodeError as err: + with self._telemetry_publisher.create_validated_cargo_topic_dependency_span(tracer, "validated-cargo deadletter") as validated_cargo_topic_deadletter_dependency: + logger.exception(err) + # set request success field to false using open census status code mapping - https://opencensus.io/tracing/span/status/ + process_message_request.set_status(Status(code=3)) + await self._servicebus_receiver.dead_letter_message(message=msg, reason=str(err)) + # Can't update operation state if we can't be sure the message structure actually has an operationId + + def is_healthy(self) -> bool: + """Performs tests to determine if the message receiver is healthy + + Returns + ------- + bool + indicates if the MessageReceiver is healthy + """ + if self._last_peeked == 0: + logger.info("First pass of the messaging loop. So far so good.") + return True + + time_since_last_peek = time.time() - self._last_peeked + seconds_since_last_peek = str(round(time_since_last_peek, 2)) + + if time_since_last_peek > self._unhealthy_threshold: + logger.critical( + "Service bus hasn't peeked at messages for over %s seconds", + seconds_since_last_peek) + return False + + if time_since_last_peek > self._degraded_threshold: + logger.warning( + "Performance degraded: Service bus hasn't peeked at messages for over %s seconds", + seconds_since_last_peek) + return True + + logger.info( + "Message receiver is healthy. %s seconds since last peek.", seconds_since_last_peek) + return True diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/models.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/models.py new file mode 100644 index 0000000..510d8c8 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/models.py @@ -0,0 +1,59 @@ +"""Module containing the models used by the service implementation +""" + +#pylint: disable=too-few-public-methods +#pylint: disable=invalid-name +class Product: + """Defines the structure for products + """ + name: str + quantity: int + +class Port: + """Defines the structure for which ports are defined for cargo + """ + source: str + destination: str + +class DemandDates: + """Defines the structure for the demand dates of the cargo + """ + start: str + end: str + +class Cargo: + """Defines the structure of a cargo object""" + id: str + timestamp: str + product: Product + port: Port + demandDates: DemandDates + +class InvalidCargo(Cargo): + """Extends the cargo base class with information about why the cargo is invalid + + Parameters + ---------- + Cargo : _type_ + Base class being extended + """ + valid: bool + errorMessage: str + +class OperationState: + """Defines the state for operational state messages""" + result: Cargo + state: str + operationId: str + error: str + def __init__(self, operationId: str, state: str, result: Cargo=None, error: str=""): + self.operationId = operationId + self.state = state + self.result = result + self.error = error + +class MessageEnvelope: + """Defines the structure of the messages received from + the service bus topic""" + operationId: str + data: InvalidCargo diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/state_processor.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/state_processor.py new file mode 100644 index 0000000..1c7e931 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/state_processor.py @@ -0,0 +1,29 @@ +"""Used to send messages to the Operation State Queue""" + +import jsons +from azure.servicebus.aio import ServiceBusClient +from azure.servicebus import ServiceBusMessage +from app_config import SERVICE_BUS_CONNECTION_STR, SERVICE_BUS_QUEUE_NAME +from logging_config import logger + +from models import OperationState + + +async def send_operation_state(operation_state: OperationState, telemetry_operation_id: str, telemetry_operation_parent_id: str): + """Send OperationState to the service bus queue defined in the app settings + + Parameters + ---------- + operation_state : OperationState + The Operation State to send + telemetry_operation_id : str + The operation id for the trace + telemetry_operation_parent_id : str + The id of the current operation in the trace + """ + servicebus_client = ServiceBusClient.from_connection_string(conn_str=SERVICE_BUS_CONNECTION_STR) + logger.info("Sending operation state message to % s queue" % SERVICE_BUS_QUEUE_NAME) + async with servicebus_client: + sender = servicebus_client.get_queue_sender(queue_name=SERVICE_BUS_QUEUE_NAME) + async with sender: + await sender.send_messages(ServiceBusMessage(jsons.dumps(operation_state), application_properties={"Diagnostic-Id": "00-{}-{}-01".format(telemetry_operation_id, telemetry_operation_parent_id)})) diff --git a/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/telemetry_publisher.py b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/telemetry_publisher.py new file mode 100644 index 0000000..894f790 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/invalid-cargo-manager/src/service/telemetry_publisher.py @@ -0,0 +1,71 @@ +"""Class used to create and publish telemetry entities +""" + +from app_config import LOGGING_APP_NAME +from opencensus.ext.azure.trace_exporter import AzureExporter +from opencensus.trace.samplers import AlwaysOnSampler +from opencensus.trace.tracer import Tracer +from opencensus.trace.span import SpanKind +from opencensus.trace.propagation.text_format import TextFormatPropagator + + +class TelemetryPublisher: #pylint: disable=too-few-public-methods + """Class used to create and publish telemetry entities + """ + + def callback_function(self, envelope): + envelope.tags['ai.cloud.role'] = LOGGING_APP_NAME + + # Check to see if the private.name attribute is set + # And use it to set the name field of the telemetry item + base_data = envelope.data['baseData'] + private_name = base_data['properties'].get('private.name') + if private_name: + # Remove the callback.name property from the telemetry item + base_data['properties']['private.name']=None + if base_data.name == '': + base_data.name = private_name + return True + + def create_tracer(self, telemetry_operation_id, telemetry_operation_parent_id): + # Create tracer with parent set to the incoming item from cargo-processing-validator + extracted_context = TextFormatPropagator().from_carrier(carrier={"opencensus-trace-traceid": telemetry_operation_id, "opencensus-trace-spanid": telemetry_operation_parent_id}) + app_insights_exporter=AzureExporter() + tracer = Tracer(exporter=app_insights_exporter, sampler=AlwaysOnSampler(), span_context=extracted_context) + app_insights_exporter.add_telemetry_processor(self.callback_function) + return tracer + + def create_process_message_request_span(self, tracer, span_name, subscription_name): + request_span = tracer.start_span(name=span_name) + # Setting span kind to server causes the span to generate a request + request_span.span_kind = SpanKind.SERVER + request_span.add_attribute("http.url", "sb://{}".format(subscription_name)) + # AzureExporter doesn't only sets the name field for HTTP spans + # Pass the span name as an attribute so that the callback function can set the name field + request_span.add_attribute("private.name", span_name) + return request_span + + def create_dependency_span(self, tracer, span_name): + dependency_span = tracer.start_span(name=span_name) + # Setting span kind to client causes the span to generate a dependency + dependency_span.span_kind = SpanKind.CLIENT + return dependency_span + + def create_operations_queue_send_dependency_span(self, tracer, span_name): + dependency_span = self.create_dependency_span(tracer, span_name) + # Set dependency type property + dependency_span.add_attribute("component", "Queue Message | servicebus") + # Set dependency target property (xxx:///xx) + dependency_span.add_attribute("http.url", "sb://operations") + return dependency_span + + def create_validated_cargo_topic_dependency_span(self, tracer, span_name): + dependency_span = self.create_dependency_span(tracer, span_name) + dependency_span.add_attribute("component", "Azure Service Bus") + dependency_span.add_attribute("http.url", "sb://validated-cargo") + return dependency_span + + def create_cosmos_db_store_dependency_span(self, tracer, span_name): + dependency_span = self.create_dependency_span(tracer, span_name) + dependency_span.add_attribute("component", "Azure DocumentDB") + return dependency_span \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/Dockerfile new file mode 100644 index 0000000..32bfefa --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/Dockerfile @@ -0,0 +1,25 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java/.devcontainer/base.Dockerfile + +# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster +ARG VARIANT="17-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT} + +# [Option] Install Maven +ARG INSTALL_MAVEN="false" +ARG MAVEN_VERSION="" +# [Option] Install Gradle +ARG INSTALL_GRADLE="false" +ARG GRADLE_VERSION="" +RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \ + && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi + +# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 +ARG NODE_VERSION="none" +RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/devcontainer.json new file mode 100644 index 0000000..583e6d2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java +{ + "name": "Java", + "build": { + "dockerfile": "Dockerfile", + "args": { + // Update the VARIANT arg to pick a Java version: 11, 17 + // Append -bullseye or -buster to pin to an OS version. + // Use the -bullseye variants on local arm64/Apple Silicon. + "VARIANT": "17-bullseye", + // Options + "INSTALL_MAVEN": "true", + "INSTALL_GRADLE": "false", + "NODE_VERSION": "lts/*" + } + }, + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "java.jdt.ls.lombokSupport.enabled": true + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "vscjava.vscode-java-pack", + "redhat.fabric8-analytics" + ] + } + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "java -version", + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.dockerignore b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.dockerignore new file mode 100644 index 0000000..2ce5e1c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.dockerignore @@ -0,0 +1,2 @@ +.env +helm diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.env.sample b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.env.sample new file mode 100644 index 0000000..74909f6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.env.sample @@ -0,0 +1,13 @@ +APPLICATIONINSIGHTS_CONNECTION_STRING= +APPLICATIONINSIGHTS_VERSION=3.4.7 + +# Service Bus Information +SERVICEBUS_CONNECTION_STRING= +SERVICEBUS_PREFETCH_COUNT=10 +OPERATION_STATE_QUEUE_NAME=cargo-operations + +# Cosmos Db Information +COSMOS_DB_ENDPOINT= +COSMOS_DB_KEY= +COSMOS_DB_DATABASE_NAME= +COSMOS_DB_CONTAINER_NAME= diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.gitignore b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.gitignore new file mode 100644 index 0000000..8977a26 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.gitignore @@ -0,0 +1,3 @@ +target + +.env \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.jar b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c1dd12f17644411d6e840bd5a10c6ecda0175f18 GIT binary patch literal 58727 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%0ANsA|A3-jj|r`KAo%oTajX3>^E` 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 YM{}PByk10KD_nuQ4E7Du?}+~TKh4V)`~Uy| literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.properties b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..b74bf7f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/launch.json b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/launch.json new file mode 100644 index 0000000..d118949 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Launch Current File", + "request": "launch", + "mainClass": "${file}", + "envFile": "${workspaceFolder}/.env" + }, + { + "type": "java", + "name": "Launch Application", + "request": "launch", + "mainClass": "com.microsoft.cse.cargoprocessing.operations.api.Application", + "projectName": "operations.api", + "vmArgs": "-javaagent:${workspaceFolder}/target/dependency/applicationinsights-agent-3.4.7.jar", + "envFile": "${workspaceFolder}/.env" + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/settings.json b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/tasks.json b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/tasks.json new file mode 100644 index 0000000..b681057 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "verify", + "type": "shell", + "command": "mvn -B verify", + "group": "build" + }, + { + "label": "test", + "type": "shell", + "command": "mvn -B test", + "group": "test" + } + ] +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/Dockerfile new file mode 100644 index 0000000..1487559 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/Dockerfile @@ -0,0 +1,27 @@ +FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu as base + + +FROM maven:3.8.5-openjdk-17-slim as build +WORKDIR /src + +RUN mvn -version + +COPY pom.xml . +RUN mvn -B dependency:resolve-plugins dependency:resolve +# RUN mvn -B dependency:go-offline + +COPY . . +RUN mvn package + +RUN ls -al target +RUN ls -al target/dependency + +FROM base as final +COPY applicationinsights.json applicationinsights.json + +ARG JAR_FILE=/src/target/*.jar +ARG DEPENDENCY=/src/target/dependency +COPY --from=build ${DEPENDENCY}/applicationinsights-agent-3.4.7.jar applicationinsights-agent-3.4.7.jar +COPY --from=build ${JAR_FILE} app.jar + +ENTRYPOINT ["java", "-javaagent:applicationinsights-agent-3.4.7.jar" ,"-jar","/app.jar" ] diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/README.md b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/README.md new file mode 100644 index 0000000..37fde20 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/README.md @@ -0,0 +1,24 @@ +# Running the service + +## Pre-Requisites + +1. Service Bus [namespace](https://docs.microsoft.com/en-us/cli/azure/servicebus/namespace?view=azure-cli-latest#az-servicebus-namespace-create) with [queue](https://docs.microsoft.com/en-us/cli/azure/servicebus/queue?view=azure-cli-latest#az-servicebus-queue-create) +1. Application Insights [account](https://docs.microsoft.com/en-us/azure/azure-monitor/app/create-new-resource#azure-cli-preview) + +## Debugging from VSCode Dev Container + +* Open the project in the dev container. + * Make sure to open in the devcontainer + * Ignore the alerts for Java on the initial load. The alerts move faster than the dev container builds. + * If you see an alert for Lombok asking to reload, please do reload. +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Build the Build task 2 options: + * From the command pallet `Tasks: Run Build Task` + * From the terminal `mvn -B verify` +* Configure debugger to use the "Launch Application" configuration. +* Run the Debugger. + +## Docker Container + +* Rename `.env.sample` to `.env` and add connection strings for Service Bus and Application Insights. +* Run `docker compose up` to run the service. \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/applicationinsights.json b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/applicationinsights.json new file mode 100644 index 0000000..35d4544 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/applicationinsights.json @@ -0,0 +1,17 @@ +{ + "role": { + "name": "operations-api" + }, + "instrumentation": { + "logging": { + "level": "INFO" + } + }, + "preview": { + "instrumentation": { + "springIntegration": { + "enabled": true + } + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/docker-compose.yml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/docker-compose.yml new file mode 100644 index 0000000..a973747 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3.9" + +services: + operations-api: + env_file: + - .env + build: + context: . + dockerfile: Dockerfile + ports: + - "8081:8081" diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/.helmignore b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/Chart.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/Chart.yaml new file mode 100644 index 0000000..b39af23 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 + +name: operations-api +description: operations-api for aks-sb-azmonitor-microservices + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/operations-api.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/operations-api.yaml new file mode 100644 index 0000000..6389407 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/operations-api.yaml @@ -0,0 +1,34 @@ +image: + pullPolicy: Always + tag: "latest" + +replicaCount: 1 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +podAnnotations: {} +podSecurityContext: {} +securityContext: {} +resources: {} +nodeSelector: {} +tolerations: [] +affinity: {} + +# When running one of the deploy-*.sh scripts, an additional env.yaml +# values file is created containing values specific to the deployed environment +# with the following values: +# image: +# repository: + +# keyVault: +# name: +# tenantId: + +# aksKeyVaultSecretProviderIdentityId: diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/NOTES.txt b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/NOTES.txt new file mode 100644 index 0000000..d9dd7b7 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: +export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aks-sb-azmonitor-microservices.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") +export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") +echo "Visit http://127.0.0.1:8080 to use your application" +kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/_helpers.tpl b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/_helpers.tpl new file mode 100644 index 0000000..0172cb3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "aks-sb-azmonitor-microservices.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "aks-sb-azmonitor-microservices.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "aks-sb-azmonitor-microservices.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "aks-sb-azmonitor-microservices.labels" -}} +helm.sh/chart: {{ include "aks-sb-azmonitor-microservices.chart" . }} +{{ include "aks-sb-azmonitor-microservices.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "aks-sb-azmonitor-microservices.selectorLabels" -}} +app.kubernetes.io/name: {{ include "aks-sb-azmonitor-microservices.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "aks-sb-azmonitor-microservices.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "aks-sb-azmonitor-microservices.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/deployment.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/deployment.yaml new file mode 100644 index 0000000..a9baa12 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/deployment.yaml @@ -0,0 +1,111 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: default + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: APPLICATIONINSIGHTS_VERSION + value: 3.4.7 + - name: OPERATION_STATE_QUEUE_NAME + value: operation-state + - name: COSMOS_DB_DATABASE_NAME + value: cargo + - name: COSMOS_DB_CONTAINER_NAME + value: operations + - name: APPLICATIONINSIGHTS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: operations-api-secrets + key: AppInsightsConnectionString + - name: SERVICEBUS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: operations-api-secrets + key: ServiceBusConnectionString + - name: SERVICEBUS_PREFETCH_COUNT + value: "10" + - name: COSMOS_DB_ENDPOINT + valueFrom: + secretKeyRef: + name: operations-api-secrets + key: CosmosDBEndpoint + - name: COSMOS_DB_KEY + valueFrom: + secretKeyRef: + name: operations-api-secrets + key: CosmosDBKey + ports: + - name: http + containerPort: 8081 + protocol: TCP + livenessProbe: + httpGet: + path: /actuator/health + port: 8081 + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 10 + + startupProbe: + httpGet: + path: /actuator/health + port: 8081 + periodSeconds: 10 + failureThreshold: 30 + timeoutSeconds: 10 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: secrets-store + mountPath: "/mnt/secrets-store" + readOnly: true + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: secrets-store + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: {{ include "aks-sb-azmonitor-microservices.fullname" . }} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/hpa.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/hpa.yaml new file mode 100644 index 0000000..0a3ca97 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/secretProviderClass.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/secretProviderClass.yaml new file mode 100644 index 0000000..0057293 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/secretProviderClass.yaml @@ -0,0 +1,41 @@ +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + provider: azure + parameters: + usePodIdentity: "false" + useVMManagedIdentity: "true" + userAssignedIdentityID: {{ .Values.aksKeyVaultSecretProviderIdentityId }} + keyvaultName: {{ .Values.keyVault.name }} + cloudName: "" + objects: | + array: + - | + objectName: AppInsightsConnectionString + objectType: secret + - | + objectName: ServiceBusConnectionString + objectType: secret + - | + objectName: CosmosDBEndpoint + objectType: secret + - | + objectName: CosmosDBKey + objectType: secret + tenantId: {{ .Values.keyVault.tenantId }} + secretObjects: + - data: + - objectName: AppInsightsConnectionString + key: AppInsightsConnectionString + - objectName: ServiceBusConnectionString + key: ServiceBusConnectionString + - objectName: CosmosDBEndpoint + key: CosmosDBEndpoint + - objectName: CosmosDBKey + key: CosmosDBKey + secretName: operations-api-secrets + type: Opaque \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/service.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/service.yaml new file mode 100644 index 0000000..af3f13a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 4 }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/tests/test-connection.yaml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5eb4bc4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "aks-sb-azmonitor-microservices.fullname" . }}-test-connection" + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "aks-sb-azmonitor-microservices.fullname" . }}:80'] + restartPolicy: Never diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw.cmd b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/pom.xml b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/pom.xml new file mode 100644 index 0000000..50d2851 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/pom.xml @@ -0,0 +1,170 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.3 + + + com.microsoft.cse + operations.api + 0.0.1-SNAPSHOT + operations-api + API used to maintain the state of the cargo processing operations + + 17 + 3.12.0 + 2.7.3 + 3.4.7 + 3.4.7 + LATEST + 7.13.0 + 1.0.71 + 2.11.0 + 3.0.0-M5 + 3.3.0 + 4.4.0 + true + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.azure + azure-messaging-servicebus + ${servicebus.version} + + + + com.azure.spring + spring-cloud-azure-starter-actuator + + + + com.azure.spring + spring-cloud-azure-starter-data-cosmos + + + + org.apache.commons + commons-lang3 + ${commons.lang.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + com.networknt + json-schema-validator + ${json.schema.validation.version} + + + + commons-io + commons-io + ${commons.io.version} + test + + + + io.opentelemetry + opentelemetry-api + + + + com.microsoft.azure + applicationinsights-web + ${applicationinsights.web.version} + + + + com.microsoft.azure + applicationinsights-agent + ${applicationinsights.agent.version} + + + + + + + io.opentelemetry + opentelemetry-bom + 1.22.0 + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + com.azure.spring + spring-cloud-azure-dependencies + ${spring.cloud.azure.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven.dependency.plugin.version} + + + + copy + compile + + copy + + + + + com.microsoft.azure + applicationinsights-agent + ${applicationinsights.agent.version} + applicationinsights-agent-${applicationinsights.agent.version}.jar + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + ${skipITs} + + + + + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/Application.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/Application.java new file mode 100644 index 0000000..00f3bae --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/Application.java @@ -0,0 +1,29 @@ +package com.microsoft.cse.cargoprocessing.operations.api; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; + +import com.microsoft.cse.cargoprocessing.operations.api.services.StateProcessor; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @EventListener + @Async + public void StartListening(ApplicationReadyEvent event) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + StateProcessor runnable = event.getApplicationContext().getBean(StateProcessor.class); + executor.execute(runnable); + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/Error.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/Error.java new file mode 100644 index 0000000..0170250 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/Error.java @@ -0,0 +1,14 @@ +package com.microsoft.cse.cargoprocessing.operations.api.ExceptionHandling; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class Error implements Serializable { + private ErrorDetail error; + + public Error(String code, String message, String target, InnerError innerError){ + error = new ErrorDetail(code, message, target, innerError); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorCodes.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorCodes.java new file mode 100644 index 0000000..dc516a9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorCodes.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.operations.api.ExceptionHandling; + +public class ErrorCodes { + private ErrorCodes() { throw new IllegalStateException("Utility class, should not be constructed"); } + + public static final String INVALID_JSON = "InvalidJson"; + public static final String FAILS_SCHEMA_VALIDATION = "InvalidJson-SchemaValidationFailure"; + public static final String FAILS_SERIALIZATION = "InvalidJson-UnableToSerialize"; + + public static final String INTERNAL_SERVER_ERROR = "InternalServerError"; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorDetail.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorDetail.java new file mode 100644 index 0000000..9f3da9c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ErrorDetail.java @@ -0,0 +1,20 @@ +package com.microsoft.cse.cargoprocessing.operations.api.ExceptionHandling; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class ErrorDetail implements Serializable { + private String code; + private String message; + private String target; + private InnerError innerError; + + public ErrorDetail(String code, String message, String target, InnerError innerError){ + this.code = code; + this.innerError = innerError; + this.target = target; + this.message = message; + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ExceptionAdvisor.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ExceptionAdvisor.java new file mode 100644 index 0000000..de24266 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/ExceptionAdvisor.java @@ -0,0 +1,32 @@ +package com.microsoft.cse.cargoprocessing.operations.api.ExceptionHandling; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ControllerAdvice +public class ExceptionAdvisor extends ResponseEntityExceptionHandler { + + private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvisor.class); + + @ExceptionHandler(Exception.class) + protected ResponseEntity handleDefaultExceptions( + Exception ex, + WebRequest request) { + logger.error(ex.getMessage(), ex); + + Error error = new Error(ErrorCodes.INTERNAL_SERVER_ERROR, + "Internal server error. Please see service logs for more information", + request.getDescription(false), null); + + return new ResponseEntity<>(error, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/InnerError.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/InnerError.java new file mode 100644 index 0000000..cc613e5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/ExceptionHandling/InnerError.java @@ -0,0 +1,13 @@ +package com.microsoft.cse.cargoprocessing.operations.api.ExceptionHandling; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class InnerError implements Serializable { + private String code; + private String message; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosConfiguration.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosConfiguration.java new file mode 100644 index 0000000..483f992 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosConfiguration.java @@ -0,0 +1,42 @@ +package com.microsoft.cse.cargoprocessing.operations.api.configuration; + +import com.azure.cosmos.CosmosClientBuilder; + +import com.azure.spring.data.cosmos.config.AbstractCosmosConfiguration; +import com.azure.spring.data.cosmos.config.CosmosConfig; +import com.azure.spring.data.cosmos.repository.config.EnableCosmosRepositories; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + + +@Configuration +@EnableConfigurationProperties(CosmosProperties.class) +@EnableCosmosRepositories(basePackages = "com.microsoft.cse.cargoprocessing.operations.api") +@PropertySource("classpath:application.properties") +public class CosmosConfiguration extends AbstractCosmosConfiguration { + @Autowired + private CosmosProperties properties; + + @Bean + public CosmosClientBuilder getCosmosClientBuilder() { + return new CosmosClientBuilder() + .endpoint(properties.getUri()) + .key(properties.getKey()); + } + + @Bean + public CosmosConfig cosmosConfig() { + return CosmosConfig.builder() + .enableQueryMetrics(true) + .build(); + } + + @Override + protected String getDatabaseName() { + return properties.getDbName(); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosProperties.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosProperties.java new file mode 100644 index 0000000..379d43e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/CosmosProperties.java @@ -0,0 +1,19 @@ +package com.microsoft.cse.cargoprocessing.operations.api.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.Data; + +@ConfigurationProperties +@Data +public class CosmosProperties { + @Value("${COSMOS_DB_ENDPOINT:defaultValue}") + private String uri; + + @Value("${COSMOS_DB_KEY:defaultValue}") + private String key; + + @Value("${COSMOS_DB_DATABASE_NAME:defaultValue}") + private String dbName; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/ServiceBusProperties.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/ServiceBusProperties.java new file mode 100644 index 0000000..6c8bbf5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/configuration/ServiceBusProperties.java @@ -0,0 +1,19 @@ +package com.microsoft.cse.cargoprocessing.operations.api.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import lombok.Data; + +@Data +@ConfigurationProperties +@Component +public class ServiceBusProperties { + @Value("${accelerator.queue-name:defaultValue}") + private String queueName; + @Value("${servicebus.connection-string:defaultValue}") + private String connectionString; + @Value("${servicebus.prefetch-count:defaultValue}") + private int prefetchCount; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/OperationController.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/OperationController.java new file mode 100644 index 0000000..d3b5837 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/OperationController.java @@ -0,0 +1,10 @@ +package com.microsoft.cse.cargoprocessing.operations.api.controllers; + +import org.springframework.http.ResponseEntity; + +import com.microsoft.cse.cargoprocessing.operations.api.models.Operation; + +public interface OperationController { + ResponseEntity getOperation(String operationId); + ResponseEntity putOperation(String operationId); +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/impl/HttpOperationController.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/impl/HttpOperationController.java new file mode 100644 index 0000000..b5af998 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/controllers/impl/HttpOperationController.java @@ -0,0 +1,58 @@ +package com.microsoft.cse.cargoprocessing.operations.api.controllers.impl; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.azure.cosmos.models.PartitionKey; +import com.microsoft.cse.cargoprocessing.operations.api.controllers.OperationController; +import com.microsoft.cse.cargoprocessing.operations.api.models.Operation; +import com.microsoft.cse.cargoprocessing.operations.api.repositories.OperationRepo; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RestController +@RequestMapping("operations") +public class HttpOperationController implements OperationController { + @Autowired + private OperationRepo repo; + + private final Logger logger = LoggerFactory.getLogger(HttpOperationController.class); + + @Override + @GetMapping("/{operationId}") + public ResponseEntity getOperation(@PathVariable String operationId) { + Optional operation = repo.findById(operationId, new PartitionKey(operationId)); + + if (operation.isPresent()) { + logger.info("Operation {} was found in database.", operationId); + return new ResponseEntity<>(operation.get(), HttpStatus.OK); + } + + logger.info("Operation {} was not found in database.", operationId); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + @Override + @PutMapping("/{operationId}") + public ResponseEntity putOperation(@PathVariable String operationId) { + Operation operation = new Operation(operationId); + Optional stored = repo.findById(operation.getId(), new PartitionKey(operation.getId())); + + if (!stored.isPresent()) { + logger.info("Operation {} was not found in database. Saving now", operation.getId()); + repo.save(operation); + return new ResponseEntity<>(operation, HttpStatus.CREATED); + } + + return new ResponseEntity<>(stored.get(), HttpStatus.OK); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Cargo.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Cargo.java new file mode 100644 index 0000000..98a2626 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Cargo.java @@ -0,0 +1,20 @@ +package com.microsoft.cse.cargoprocessing.operations.api.models; + +import java.io.Serializable; +import java.sql.Timestamp; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Data; + +@Data +public class Cargo implements Serializable { + private String id; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Timestamp timestamp; + private Product product; + private Port port; + private DemandDates demandDates; + private Boolean valid; + private String errorMessage; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/DemandDates.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/DemandDates.java new file mode 100644 index 0000000..1bbd91c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/DemandDates.java @@ -0,0 +1,16 @@ +package com.microsoft.cse.cargoprocessing.operations.api.models; + +import java.io.Serializable; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Data; + +@Data +public class DemandDates implements Serializable { + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Date start; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Date end; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Operation.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Operation.java new file mode 100644 index 0000000..c7a598a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Operation.java @@ -0,0 +1,33 @@ +package com.microsoft.cse.cargoprocessing.operations.api.models; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.data.annotation.Id; + +import com.azure.spring.data.cosmos.core.mapping.Container; +import com.azure.spring.data.cosmos.core.mapping.PartitionKey; +import com.fasterxml.jackson.annotation.JsonFormat; + +@Data +@Container(containerName = "operations", autoCreateContainer = false) +@NoArgsConstructor +public class Operation implements Serializable { + @PartitionKey + @Id + private String id; + private String state; + private Cargo result; + private String error; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT") + private Date updatedAt; + + public Operation(String operationId) { + id = operationId; + state = "New"; + updatedAt = new Date(); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/OperationState.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/OperationState.java new file mode 100644 index 0000000..d3fba9d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/OperationState.java @@ -0,0 +1,13 @@ +package com.microsoft.cse.cargoprocessing.operations.api.models; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class OperationState implements Serializable { + private String operationId; + private String state; + private Cargo result; + private String error; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Port.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Port.java new file mode 100644 index 0000000..215782b --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Port.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.operations.api.models; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class Port implements Serializable { + private String source; + private String destination; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Product.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Product.java new file mode 100644 index 0000000..48a5726 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/models/Product.java @@ -0,0 +1,11 @@ +package com.microsoft.cse.cargoprocessing.operations.api.models; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class Product implements Serializable { + private String name; + private int quantity; +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/repositories/OperationRepo.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/repositories/OperationRepo.java new file mode 100644 index 0000000..48cee57 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/repositories/OperationRepo.java @@ -0,0 +1,10 @@ +package com.microsoft.cse.cargoprocessing.operations.api.repositories; + +import com.microsoft.cse.cargoprocessing.operations.api.models.Operation; +import com.azure.spring.data.cosmos.repository.CosmosRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface OperationRepo extends CosmosRepository { + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/services/StateProcessor.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/services/StateProcessor.java new file mode 100644 index 0000000..5fdfce9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/java/com/microsoft/cse/cargoprocessing/operations/api/services/StateProcessor.java @@ -0,0 +1,154 @@ +package com.microsoft.cse.cargoprocessing.operations.api.services; + +import java.util.Date; +import java.util.Optional; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.azure.cosmos.models.PartitionKey; +import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusErrorContext; +import com.azure.messaging.servicebus.ServiceBusException; +import com.azure.messaging.servicebus.ServiceBusFailureReason; +import com.azure.messaging.servicebus.ServiceBusProcessorClient; +import com.azure.messaging.servicebus.ServiceBusReceivedMessage; +import com.azure.messaging.servicebus.ServiceBusReceivedMessageContext; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.cse.cargoprocessing.operations.api.configuration.ServiceBusProperties; +import com.microsoft.cse.cargoprocessing.operations.api.models.Operation; +import com.microsoft.cse.cargoprocessing.operations.api.models.OperationState; +import com.microsoft.cse.cargoprocessing.operations.api.repositories.OperationRepo; +import io.opentelemetry.api.trace.Span; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import lombok.SneakyThrows; + +@Component +@Scope("application") +public class StateProcessor implements Runnable { + @Autowired + private OperationRepo repo; + @Autowired + ServiceBusProperties serviceBusProperties; + + private final Logger logger = LoggerFactory.getLogger(StateProcessor.class); + + private ObjectMapper mapper = new ObjectMapper(); + + @Override + public void run() { + try { + CountDownLatch countdownLatch = new CountDownLatch(1); + + ServiceBusProcessorClient processor = new ServiceBusClientBuilder() + .connectionString(serviceBusProperties.getConnectionString()) + .processor() + .queueName(serviceBusProperties.getQueueName()) + .disableAutoComplete() + .prefetchCount(serviceBusProperties.getPrefetchCount()) + .receiveMode(ServiceBusReceiveMode.PEEK_LOCK) + .processMessage(context -> processMessage(context)) + .processError(context -> processError(context, countdownLatch)) + .buildProcessorClient(); + + processor.start(); + logger.info("Stopped processing operation state messages"); + } catch (Exception e) { + logger.error("Error while reading from the operation state service bus", e); + } + } + + @SneakyThrows + private void processMessage(ServiceBusReceivedMessageContext context) { + ServiceBusReceivedMessage message = context.getMessage(); + OperationState state = mapper.readValue(message.getBody().toBytes(), OperationState.class); + Optional result = repo.findById(state.getOperationId(), + new PartitionKey(state.getOperationId())); + + Operation operation = null; + + if (result.isPresent()) { + operation = result.get(); + } else { + operation = new Operation(state.getOperationId()); + } + + if (validStateTransition(operation.getState(), state.getState())) { + Date messageEnqueue = Date.from(context.getMessage().getEnqueuedTime().toInstant()); + logger.info("Updating state for operation id: {} from {} to {}", state.getOperationId(), + operation.getState(), state.getState()); + operation.setState(state.getState()); + operation.setResult(state.getResult()); + operation.setUpdatedAt(messageEnqueue); + operation.setError(state.getError()); + + Span span = Span.current(); + span.setAttribute("operation-state", operation.getState()); + + repo.save(operation); + context.complete(); + } else { + logger.info( + "State transition for Operation Id {} from {} to {} is invalid, putting message back enqueue for processing.", + state.getOperationId(), operation.getState(), state.getState()); + + context.abandon(); + } + } + + private boolean validStateTransition(String from, String to) { + logger.info("Validating state transition from {} to {}", from, to); + + if (from.equals("New") && to.equals("CargoValidated")) { + return true; + } + if (from.equals("CargoValidated") && to.equals("Succeeded")) { + return true; + } + if (to.equals("Failed")) { + return true; + } + + return false; + } + + private void processError(ServiceBusErrorContext context, CountDownLatch countdownLatch) { + logger.error("Error when receiving messages from namespace: '%s'. Entity: '%s'%n", + context.getFullyQualifiedNamespace(), context.getEntityPath()); + + if (!(context.getException() instanceof ServiceBusException)) { + logger.error("Non-ServiceBusException occurred: %s%n", context.getException()); + return; + } + + ServiceBusException exception = (ServiceBusException) context.getException(); + ServiceBusFailureReason reason = exception.getReason(); + + if (reason == ServiceBusFailureReason.MESSAGING_ENTITY_DISABLED + || reason == ServiceBusFailureReason.MESSAGING_ENTITY_NOT_FOUND + || reason == ServiceBusFailureReason.UNAUTHORIZED) { + logger.error("An unrecoverable error occurred. Stopping processing with reason %s: %s%n", + reason, exception.getMessage()); + + countdownLatch.countDown(); + } else if (reason == ServiceBusFailureReason.MESSAGE_LOCK_LOST) { + logger.error("Message lock lost for message: %s%n", context.getException()); + } else if (reason == ServiceBusFailureReason.SERVICE_BUSY) { + try { + // Choosing an arbitrary amount of time to wait until trying again. + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + logger.error("Unable to sleep for period of time"); + } + } else { + logger.error("Error source %s, reason %s, message: %s%n", context.getErrorSource(), + reason, context.getException()); + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/resources/application.properties b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/resources/application.properties new file mode 100644 index 0000000..42cd8f6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/main/resources/application.properties @@ -0,0 +1,19 @@ +APPLICATIONINSIGHTS_CONNECTION_STRING=${APPLICATIONINSIGHTS_CONNECTION_STRING} +APPLICATIONINSIGHTS_VERSION=${APPLICATIONINSIGHTS_VERSION} + +# Service Bus Information +servicebus.connection-string=${servicebus_connection_string} +servicebus.prefetch-count=${servicebus_prefetch_count} +accelerator.queue-name=${operation_state_queue_name} + +# Cosmos Db Information +spring.cloud.azure.cosmos.endpoint=${COSMOS_DB_ENDPOINT} +spring.cloud.azure.cosmos.key=${COSMOS_DB_KEY} +spring.cloud.azure.cosmos.database=${COSMOS_DB_DATABASE_NAME} + +server.port=8081 + +management.endpoints.web.exposure.include=health,info +endpoints.health.sensitive=false +management.endpoint.health.show-details=always +management.health.azure-cosmos.enabled=true diff --git a/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/test/java/com/microsoft/cse/cargoprocessing/operations/api/ApplicationTestsIT.java b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/test/java/com/microsoft/cse/cargoprocessing/operations/api/ApplicationTestsIT.java new file mode 100644 index 0000000..72db9a5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/operations-api/src/test/java/com/microsoft/cse/cargoprocessing/operations/api/ApplicationTestsIT.java @@ -0,0 +1,13 @@ +package com.microsoft.cse.cargoprocessing.operations.api; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTestsIT { + + @Test + void contextLoads() { + } + +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/solution/README.md b/accelerators/aks-sb-azmonitor-microservices/src/solution/README.md new file mode 100644 index 0000000..a5720f9 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/solution/README.md @@ -0,0 +1,5 @@ +# README + +This folder contains a helm chart for solution-level components. + +Currently, this deploys the ingress to provide access to the cargo-processing-api and operations-api. diff --git a/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/Chart.yaml b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/Chart.yaml new file mode 100644 index 0000000..a84495c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: aks-sb-azmonitor-microservices +description: solution-level components for aks-sb-azmonitor-microservices + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/NOTES.txt b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/NOTES.txt new file mode 100644 index 0000000..036956a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: + + export INGRESS_IP=$(kubectl get ingress --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aks-sb-azmonitor-microservices.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}') + + curl http://$INGRESS_IP/ \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/_helpers.tpl b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/_helpers.tpl new file mode 100644 index 0000000..0172cb3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "aks-sb-azmonitor-microservices.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "aks-sb-azmonitor-microservices.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "aks-sb-azmonitor-microservices.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "aks-sb-azmonitor-microservices.labels" -}} +helm.sh/chart: {{ include "aks-sb-azmonitor-microservices.chart" . }} +{{ include "aks-sb-azmonitor-microservices.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "aks-sb-azmonitor-microservices.selectorLabels" -}} +app.kubernetes.io/name: {{ include "aks-sb-azmonitor-microservices.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "aks-sb-azmonitor-microservices.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "aks-sb-azmonitor-microservices.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/ingress.yaml b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/ingress.yaml new file mode 100644 index 0000000..15732ab --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/solution/helm/templates/ingress.yaml @@ -0,0 +1,35 @@ +{{- $fullName := include "aks-sb-azmonitor-microservices.fullname" . -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + annotations: + nginx.ingress.kubernetes.io/use-regex: "true" + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + ingressClassName: nginx + rules: + - http: + paths: + - path: /cargo + pathType: Prefix + backend: + service: + name: cargo-processing-api + port: + number: 80 + - path: /actuator/health + pathType: Prefix + backend: + service: + name: cargo-processing-api + port: + number: 80 + - path: /operations + pathType: Prefix + backend: + service: + name: operations-api + port: + number: 80 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/Dockerfile new file mode 100644 index 0000000..efa6649 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/Dockerfile @@ -0,0 +1,8 @@ +ARG VARIANT="6.0" +FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT} + +ARG USERNAME=vscode + +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install telnet -y diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/devcontainer.json b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/devcontainer.json new file mode 100644 index 0000000..94e90bb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.devcontainer/devcontainer.json @@ -0,0 +1,21 @@ +{ + "name": "valid-cargo-manager", + "build": { + "dockerfile": "Dockerfile", + "args": { + "VARIANT": "6.0" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csharp" + ], + "settings": { + "editor.formatOnType": true, + "editor.formatOnSave": true + } + } + }, + "remoteUser": "vscode" +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.dockerignore b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.dockerignore new file mode 100644 index 0000000..ebe6989 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.dockerignore @@ -0,0 +1,28 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md + +.env +helm diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.gitignore b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.gitignore new file mode 100644 index 0000000..d2e6b7d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/.gitignore @@ -0,0 +1,38 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code +.vscode + +# Rider +.idea + +# User-specific files +appsettings.json +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +msbuild.log +msbuild.err +msbuild.wrn + +# Visual Studio 2015 +.vs/ \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Controllers/HealthCheckController.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Controllers/HealthCheckController.cs new file mode 100644 index 0000000..9bc8bb6 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Controllers/HealthCheckController.cs @@ -0,0 +1,81 @@ +namespace ValidCargoProcessor.Services +{ + using System.Net.Sockets; + using System.Threading; + using System.Text.Json; + using Microsoft.Extensions.Diagnostics.HealthChecks; + + public class HealthCheckController : IHostedService + { + private readonly HealthCheckService _healthCheckService; + private readonly ILogger _logger; + private readonly TcpListener _tcpServer; + + public HealthCheckController( + TcpListener tcpServer, + HealthCheckService healthCheckService, + IConfiguration configuration, + ILogger logger) + { + _healthCheckService = healthCheckService; + _logger = logger; + _tcpServer = tcpServer; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("Starting Tcp Health Check Listener at {}", _tcpServer.LocalEndpoint); + _tcpServer.Start(); + while (!cancellationToken.IsCancellationRequested) + { + _logger.LogInformation("Performing health check"); + HealthReport report = await _healthCheckService.CheckHealthAsync().ConfigureAwait(false); + + if (report == null || report.Status == HealthStatus.Unhealthy) + { + // default log level for service is set to Debug in appsettings.json + _logger.LogDebug("Service is unhealthy, stopping health service", report); + _tcpServer.Stop(); + return; + } + + await ReportHealthCheckResult(report); + } + } + catch (SocketException e) + { + _logger.LogError("Tcp Socket Exception", e); + } + finally + { + _tcpServer.Stop(); + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _logger.LogDebug("Stopping Tcp Listener"); + return Task.FromResult(_tcpServer.Stop); + } + + private async Task ReportHealthCheckResult(HealthReport report) + { + TcpClient client = await _tcpServer.AcceptTcpClientAsync().ConfigureAwait(false); + try + { + NetworkStream stream = client.GetStream(); + String output = JsonSerializer.Serialize(report); + Byte[] results = System.Text.Encoding.UTF8.GetBytes(output); + await stream.WriteAsync(results); + client.Close(); + } + catch (Exception ex) + { + _logger.LogError("Exception occurred while attempting to provide health report", ex); + client.Close(); + } + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Dockerfile b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Dockerfile new file mode 100644 index 0000000..a27168e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Dockerfile @@ -0,0 +1,20 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["valid-cargo-manager.csproj", "."] +RUN dotnet restore "./valid-cargo-manager.csproj" +COPY . . +WORKDIR "/src/." +RUN dotnet build "valid-cargo-manager.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "valid-cargo-manager.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "valid-cargo-manager.dll"] \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/CosmosDbHealthChecker.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/CosmosDbHealthChecker.cs new file mode 100644 index 0000000..4df2f4c --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/CosmosDbHealthChecker.cs @@ -0,0 +1,152 @@ +namespace ValidCargoProcessor.HealthCheck +{ + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos; + using ValidCargoProcessor.HealthCheck.Models; + using Microsoft.Extensions.Diagnostics.HealthChecks; + public class CosmosDbHealthChecker : IHealthCheck + { + private readonly CosmosClient _cosmosClient; + private readonly IConfiguration _configuration; + private readonly string _description = "CosmosDb:HealthCheck"; + private readonly ILogger _logger; + private readonly int _maxDurationMs; + public CosmosDbHealthChecker( + CosmosClient cosmosClient, IConfiguration configuration, ILogger logger) + { + _cosmosClient = cosmosClient; + _configuration = configuration; + _logger = logger; + _maxDurationMs = int.Parse(configuration["HealthCheck:CosmosDb:MaxDurationMs"]); + } + + public async Task CheckHealthAsync( + HealthCheckContext context, CancellationToken cancellationToken = default) + { + Dictionary data = new(); + + try + { + data.Add("CosmosDb:Account", await this.CheckClientAccountAsync().ConfigureAwait(false)); + + var database = _cosmosClient.GetDatabase(_configuration["CosmosDb:Database"]); + data.Add("CosmosDb:Database", await CheckDatabaseAsync(database, cancellationToken).ConfigureAwait(false)); + + var container = database.GetContainer(_configuration["CosmosDb:Container"]); + data.Add("CosmosDb:Container", await CheckContainerAsync(container, cancellationToken).ConfigureAwait(false)); + + return ToHealthCheckResult(data); + } + catch (CosmosException ce) + { + // log and return Unhealthy + _logger.LogError($"CosmosException:Healthz:{ce.StatusCode}:{ce.ActivityId}:{ce.Message}"); + + data.Add("CosmosException", ce.Message); + + return new HealthCheckResult(HealthStatus.Unhealthy, _description, ce, data); + } + catch (Exception ex) + { + // log and return unhealthy + _logger.LogError($"Exception:Health:{ex.Message}"); + + data.Add("Exception", ex.Message); + + return new HealthCheckResult(HealthStatus.Unhealthy, _description, ex, data); + } + } + + private HealthCheckResult ToHealthCheckResult(Dictionary data) + { + _logger.LogDebug("Converting data to HealthCheckResult"); + HealthStatus status = HealthStatus.Healthy; + + //Make sure we're reporting the least healthy result that was observed + foreach (object d in data.Values) + { + if (d is HealthCheck h && h.Status != HealthStatus.Healthy) + { + status = h.Status; + } + + if (status == HealthStatus.Unhealthy) + { + break; + } + } + + return new HealthCheckResult(status, this._description, data: data); + } + + private async Task CheckClientAccountAsync() + { + _logger.LogDebug("Checking that we can read the cosmos db account information"); + HealthCheckResultBuilder builder = new HealthCheckResultBuilder() + .ComponentId("CosmosDb") + .ComponentType("Data Store") + .Endpoint(this._configuration["CosmosDb:EndpointUri"]) + .TargetDurationMs(this._maxDurationMs); + + try + { + var account = await _cosmosClient.ReadAccountAsync().ConfigureAwait(false); + + return builder.build(); + } + catch (CosmosException ce) + { + _logger.LogError($"CosmosException:Health:{ce.StatusCode}:{ce.ActivityId}:{ce.Message}"); + builder.Exception(ce); + return builder.build(); + } + } + + private async Task CheckDatabaseAsync(Database database, CancellationToken cancellationToken = default) + { + _logger.LogDebug("Checking that we can read the cosmos db database information"); + HealthCheckResultBuilder builder = new HealthCheckResultBuilder() + .ComponentId("CosmosDb") + .ComponentType("Data Store") + .Endpoint(this._configuration["CosmosDb:Database"]) + .TargetDurationMs(this._maxDurationMs); + + try + { + var dbData = await database.ReadAsync(null, cancellationToken).ConfigureAwait(false); + + return builder.build(); + } + catch (CosmosException ce) + { + _logger.LogError($"CosmosException:Health:{ce.StatusCode}:{ce.ActivityId}:{ce.Message}"); + builder.Exception(ce); + return builder.build(); + } + } + + private async Task CheckContainerAsync(Container container, CancellationToken cancellationToken = default) + { + _logger.LogDebug("Checking that we can read the cosmos db container information"); + HealthCheckResultBuilder builder = new HealthCheckResultBuilder() + .ComponentId("CosmosDb") + .ComponentType("Data Store") + .Endpoint(this._configuration["CosmosDb:Container"]) + .TargetDurationMs(this._maxDurationMs); + + try + { + var containerData = await container.ReadContainerAsync(null, cancellationToken).ConfigureAwait(false); + + return builder.build(); + } + catch (CosmosException ce) + { + _logger.LogError($"CosmosException:Health:{ce.StatusCode}:{ce.ActivityId}:{ce.Message}"); + builder.Exception(ce); + return builder.build(); + } + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/HealthCheckResultBuilder.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/HealthCheckResultBuilder.cs new file mode 100644 index 0000000..0926054 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/HealthCheckResultBuilder.cs @@ -0,0 +1,115 @@ +namespace ValidCargoProcessor.HealthCheck +{ + using System.Diagnostics; + using System.Globalization; + using Microsoft.Extensions.Diagnostics.HealthChecks; + using ValidCargoProcessor.HealthCheck.Models; + + public class HealthCheckResultBuilder + { + private string TimeoutMessage = "Request exceeded expected duration"; + private HealthStatus _status = HealthStatus.Healthy; + private string _componentId = string.Empty; + private string _componentType = string.Empty; + private TimeSpan _duration; + private TimeSpan _targetDuration; + private string _time = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture); + private string _endpoint = String.Empty; + private string _message = String.Empty; + private Stopwatch stopwatch = new(); + + public HealthCheckResultBuilder() + { + stopwatch.Start(); + } + + public HealthCheck build() + { + if (stopwatch.IsRunning) + { + stopwatch.Stop(); + } + + this._duration = stopwatch.Elapsed; + + HealthCheck result = new() + { + Endpoint = this._endpoint, + Status = this._status, + Duration = stopwatch.Elapsed, + TargetDuration = this._targetDuration, + ComponentId = this._componentId, + ComponentType = this._componentType, + }; + + // check duration + if (result.Duration.TotalMilliseconds > this._targetDuration.TotalMilliseconds) + { + result.Status = HealthStatus.Degraded; + result.Message = this.TimeoutMessage; + } + + return result; + } + + public HealthCheckResultBuilder StartTimer() + { + this.stopwatch.Restart(); + return this; + } + + public HealthCheckResultBuilder StopTimer() + { + this.stopwatch.Stop(); + return this; + } + + public HealthCheckResultBuilder Endpoint(string endpoint) + { + this._endpoint = endpoint; + return this; + } + + public HealthCheckResultBuilder Message(string message) + { + this._message = message; + return this; + } + + public HealthCheckResultBuilder ComponentId(string componentId) + { + this._componentId = componentId; + return this; + } + + public HealthCheckResultBuilder ComponentType(string componentType) + { + this._componentType = componentType; + return this; + } + + public HealthCheckResultBuilder Status(HealthStatus status) + { + this._status = status; + return this; + } + + public HealthCheckResultBuilder TargetDurationMs(int targetDurationMs) + { + this._targetDuration = new System.TimeSpan(0, 0, 0, 0, (int)targetDurationMs); + return this; + } + + public HealthCheckResultBuilder Exception(Exception ex) + { + if (ex != null) + { + this._status = HealthStatus.Unhealthy; + this._message = ex.Message; + this.StopTimer(); + } + return this; + } + } + +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/HealthCheck.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/HealthCheck.cs new file mode 100644 index 0000000..3d2b271 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/HealthCheck.cs @@ -0,0 +1,26 @@ +namespace ValidCargoProcessor.HealthCheck.Models +{ + using System; + using System.Globalization; + using System.Text.Json.Serialization; + using Microsoft.Extensions.Diagnostics.HealthChecks; + + + /// + /// Class used to define Health Checks that are performed and their results, + /// in the format supported by .NET's IHealthCheck + /// + public class HealthCheck + { + public const string TimeoutMessage = "Request exceeded expected duration"; + [JsonConverter(typeof(JsonStringEnumConverter))] + public HealthStatus Status { get; set; } + public string ComponentId { get; set; } = String.Empty; + public string ComponentType { get; set; } = String.Empty; + public TimeSpan Duration { get; set; } + public TimeSpan TargetDuration { get; set; } + public string Time { get; set; } = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture); + public string Endpoint { get; set; } = String.Empty; + public string Message { get; set; } = String.Empty; + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/IetfHealthCheck.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/IetfHealthCheck.cs new file mode 100644 index 0000000..6e80705 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/Models/IetfHealthCheck.cs @@ -0,0 +1,62 @@ +namespace ValidCargoProcessor.HealthCheck.Models +{ + using System; + using System.Collections.Generic; + using Microsoft.Extensions.Diagnostics.HealthChecks; + + /// + /// Class used to define Health Checks that are performed and their results, + /// in the format documented by the Internet Engineering Task Force (IETF) + /// https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06 + /// + public class IetfHealthCheck + { + public string Status { get; set; } = String.Empty; + public string ComponentId { get; set; } = String.Empty; + public string ComponentType { get; set; } = String.Empty; + public string ObservedUnit { get; set; } = String.Empty; + public double ObservedValue { get; set; } + public double TargetValue { get; set; } + public string Time { get; set; } = String.Empty; + public List AffectedEndpoints { get; } = new List(); + public string Message { get; set; } = String.Empty; + + public IetfHealthCheck(HealthCheck healthCheck) + { + if (healthCheck == null) + { + throw new ArgumentNullException(nameof(healthCheck)); + } + + Status = ToIetfStatus(healthCheck.Status); + ComponentId = healthCheck.ComponentId; + ComponentType = healthCheck.ComponentType; + ObservedValue = Math.Round(healthCheck.Duration.TotalMilliseconds, 2); + TargetValue = Math.Round(healthCheck.TargetDuration.TotalMilliseconds, 0); + ObservedUnit = "ms"; + Time = healthCheck.Time; + Message = healthCheck.Message; + + if (healthCheck.Status != HealthStatus.Healthy && !string.IsNullOrEmpty(healthCheck.Endpoint)) + { + AffectedEndpoints = new List { healthCheck.Endpoint }; + } + + } + + /// + /// Convert the dotnet HealthStatus to the IETF Status + /// + /// HealthStatus (dotnet) + /// string + public static string ToIetfStatus(HealthStatus status) + { + return status switch + { + HealthStatus.Healthy => "pass", + HealthStatus.Degraded => "warn", + _ => "fail" + }; + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/ServiceBusHealthChecker.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/ServiceBusHealthChecker.cs new file mode 100644 index 0000000..777cdea --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/HealthCheck/ServiceBusHealthChecker.cs @@ -0,0 +1,133 @@ +namespace ValidCargoProcessor.HealthCheck +{ + using System.Diagnostics; + using ValidCargoProcessor.HealthCheck.Models; + using System.Threading; + using System.Threading.Tasks; + using Azure.Messaging.ServiceBus; + using Microsoft.Extensions.Diagnostics.HealthChecks; + using System.Reflection; + + public class ServiceBusHealthChecker : IHealthCheck + { + private Stopwatch _stopwatch = new(); + private readonly IConfiguration _configuration; + private readonly ILogger _logger; + private readonly ServiceBusClient _serviceBusClient; + private readonly int _maxDurationMs; + private readonly string _description = "ServiceBus:HealthCheck"; + + public ServiceBusHealthChecker(IConfiguration configuration, + ILogger logger, ServiceBusClient serviceBusClient) + { + _configuration = configuration; + _logger = logger; + _serviceBusClient = serviceBusClient; + _maxDurationMs = int.Parse(configuration["HealthCheck:ServiceBus:MaxDurationMs"]); + } + + public void Heartbeat() + { + _stopwatch.Restart(); + } + + public Task CheckHealthAsync( + HealthCheckContext context, + CancellationToken cancellationToken = default) + { + return Task.Run(() => + { + Dictionary data = new(); + + try + { + data.Add("ServiceBus:IsClosed", CheckServiceBusConnectionIsClosed()); + return ToHealthCheckResult(data); + } + catch (ServiceBusException sbe) + { + // log and return Unhealthy + _logger.LogError($"ServiceBusException:Health:{sbe.Reason}:{sbe.Source}:{sbe.Message}"); + + data.Add("ServiceBusException", sbe.Message); + + return new HealthCheckResult(HealthStatus.Unhealthy, _description, sbe, data); + } + catch (Exception ex) + { + // log and return unhealthy + _logger.LogError($"Exception:Health:{ex.Message}"); + + data.Add("Exception", ex.Message); + + return new HealthCheckResult(HealthStatus.Unhealthy, _description, ex, data); + } + }); + } + + private HealthCheckResult ToHealthCheckResult(Dictionary data) + { + _logger.LogDebug("Converting data to HealthCheckResult"); + HealthStatus status = HealthStatus.Healthy; + + //Make sure we're reporting the least healthy result that was observed + foreach (object d in data.Values) + { + if (d is HealthCheck h && h.Status != HealthStatus.Healthy) + { + status = h.Status; + } + + if (status == HealthStatus.Unhealthy) + { + break; + } + } + + return new HealthCheckResult(status, this._description, data: data); + } + + private HealthCheck CheckServiceBusConnectionIsClosed() + { + _logger.LogDebug("Checking that we can read the cosmos db account information"); + HealthCheckResultBuilder builder = new HealthCheckResultBuilder() + .ComponentId("ServiceBus") + .ComponentType("PubSub") + .Endpoint("ServiceBus:EndpointUri") + .TargetDurationMs(this._maxDurationMs); + + try + { + // Using this approach until the SDK provides an alternative to testing the state of the service bus connection + // The ServiceBusConnection object is an internally scoped property and class to the ServiceBus SDK, + // so will need to use reflection to get access to it. + + // First we're getting the Connection value + Type sbcType = typeof(ServiceBusClient); + PropertyInfo? connectionProperty = sbcType.GetProperty("Connection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + if (connectionProperty == null) throw new NullReferenceException("Unable to get service bus connection property info"); + var connection = connectionProperty.GetValue(_serviceBusClient); + if (connection == null) throw new NullReferenceException("Unable to get service bus connection property"); + + // Next we need to get the value of the IsClosed property of the connection + PropertyInfo? isClosedProperty = connection.GetType() + .GetProperty("IsClosed", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + if (isClosedProperty == null) throw new NullReferenceException("Unable to get service bus connection IsClosed property info"); + + var isClosed = isClosedProperty.GetValue(connection); + if (isClosed == null) throw new NullReferenceException("Unable to get service bus connection IsClosed property"); + + // If the connection is closed, we have an unhealthy connection + builder.Status((Boolean)isClosed ? HealthStatus.Unhealthy : HealthStatus.Healthy); + + return builder.build(); + } + catch (Exception e) + { + _logger.LogError($"ServiceBusException:Health:{e.Message}"); + builder.Exception(e); + return builder.build(); + } + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Interfaces/ISubscriptionReceiver.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Interfaces/ISubscriptionReceiver.cs new file mode 100644 index 0000000..fe51dc5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Interfaces/ISubscriptionReceiver.cs @@ -0,0 +1,12 @@ +namespace ValidCargoProcessor +{ + + public interface ISubscriptionReceiver + { + Task ProcessMessagesAsync(); + + Task StopProcessingAsync(); + + Task AddItemToContainerAsync(ValidCargo cargo); + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/OperationState.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/OperationState.cs new file mode 100644 index 0000000..1ef3c4e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/OperationState.cs @@ -0,0 +1,15 @@ +namespace ValidCargoProcessor +{ + using Newtonsoft.Json; + public class OperationState + { + [JsonProperty(PropertyName = "operationId")] + public string? OperationId { get; set; } + [JsonProperty(PropertyName = "state")] + public string? State { get; set; } + [JsonProperty(PropertyName = "result")] + public ValidCargo? Result { get; set; } + [JsonProperty(PropertyName = "error")] + public string? Error { get; set; } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/ValidCargo.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/ValidCargo.cs new file mode 100644 index 0000000..373fe4f --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Models/ValidCargo.cs @@ -0,0 +1,54 @@ +namespace ValidCargoProcessor +{ + using Newtonsoft.Json; + + public class ValidCargo + { + [JsonProperty(PropertyName = "timestamp")] + public string Timestamp { get; set; } = String.Empty; + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } = String.Empty; + [JsonProperty(PropertyName = "product")] + public Product Product { get; set; } = new Product(); + [JsonProperty(PropertyName = "port")] + public Port Port { get; set; } = new Port(); + [JsonProperty(PropertyName = "demandDates")] + public DemandDates DemandDates { get; set; } = new DemandDates(); + [JsonProperty(PropertyName = "valid")] + public bool Valid { get; set; } + [JsonProperty(PropertyName = "errorMessage")] + public string ErrorMessage { get; set; } = String.Empty; + } + + public class DemandDates + { + [JsonProperty(PropertyName = "start")] + public string Start { get; set; } = String.Empty; + [JsonProperty(PropertyName = "end")] + public string End { get; set; } = String.Empty; + } + + public class Port + { + [JsonProperty(PropertyName = "source")] + public string Source { get; set; } = String.Empty; + [JsonProperty(PropertyName = "destination")] + public string Destination { get; set; } = String.Empty; + } + + public class Product + { + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } = String.Empty; + [JsonProperty(PropertyName = "quantity")] + public int Quantity { get; set; } + } + + public class MessageEnvelope + { + [JsonProperty(PropertyName = "operationId")] + public string? OperationId { get; set; } + [JsonProperty(PropertyName = "data")] + public ValidCargo Data { get; set; } = new ValidCargo(); + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Program.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Program.cs new file mode 100644 index 0000000..7787191 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Program.cs @@ -0,0 +1,89 @@ +using System.Net; +using System.Net.Sockets; +using Microsoft.ApplicationInsights.Extensibility; +using Microsoft.Azure.Cosmos; +using Microsoft.Extensions.Azure; +using Microsoft.Extensions.Configuration.Json; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using ValidCargoProcessor.HealthCheck; +using ValidCargoProcessor.Services; +using ValidCargoProcessor.Telemetry; + +namespace ValidCargoProcessor +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((_, builder) => + { + builder + .Sources.OfType() + .First(x => x.Path == "appsettings.json") + .Optional = true; // config specified via environment variables when deployed + }) + .ConfigureServices((hostContext, services) => + { + IConfiguration configuration = hostContext.Configuration; + services.AddHostedService() + .AddSingleton() + .AddSingleton(s => CreateCosmosClient(s, configuration)) + .AddSingleton(s => CreateTcpServer(s, configuration)) + .AddSingleton() + .AddHostedService() + .AddAzureClients(builder => CreateServiceBusClient(builder, configuration)); + services.AddHealthChecks() + .AddCheck("CosmosDb", failureStatus: HealthStatus.Unhealthy) + .AddCheck("ServiceBus", failureStatus: HealthStatus.Unhealthy); + services.AddApplicationInsightsTelemetryWorkerService(); + }); + + public static CosmosClient CreateCosmosClient(IServiceProvider s, IConfiguration configuration) + { + var endpointUri = configuration["CosmosDB:EndpointUri"]; + var authKey = configuration["CosmosDB:PrimaryKey"]; + + if (string.IsNullOrEmpty(endpointUri)) + { + throw new ArgumentException("CosmosDB endpoint URI is missing"); + } + + if (string.IsNullOrEmpty(authKey)) + { + throw new ArgumentException("CosmosDB authentication key is missing"); + } + + return new CosmosClient(endpointUri, authKey); + } + + public static void CreateServiceBusClient(AzureClientFactoryBuilder builder, IConfiguration configuration) + { + var serviceBusConnectionString = configuration["ServiceBus:ConnectionString"]; + + if (string.IsNullOrEmpty(serviceBusConnectionString)) + { + throw new ArgumentException("Service Bus connection string is missing"); + } + + builder.AddServiceBusClient(serviceBusConnectionString) + .ConfigureOptions(options => + { + + }); + } + + public static TcpListener CreateTcpServer(IServiceProvider s, IConfiguration configuration) + { + int port = int.Parse(configuration["HealthCheck:TcpServer:Port"]); + string hostName = Dns.GetHostName(); + + IPAddress localAddress = Dns.GetHostEntry(hostName).AddressList[0]; + return new TcpListener(localAddress, port); + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Properties/launchSettings.json b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Properties/launchSettings.json new file mode 100644 index 0000000..3b62c91 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "profiles": { + "service_3": { + "commandName": "Project", + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "Docker": { + "commandName": "Docker" + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/README.md b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/README.md new file mode 100644 index 0000000..88a8844 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/README.md @@ -0,0 +1,56 @@ +# Running the service + +## Pre-Requisites + +1. Service Bus [namespace](https://docs.microsoft.com/cli/azure/servicebus/namespace?view=azure-cli-latest#az-servicebus-namespace-create) with [topic](https://docs.microsoft.com/cli/azure/servicebus/topic?view=azure-cli-latest#az-servicebus-topic-create) and [subscription](https://docs.microsoft.com/cli/azure/servicebus/topic/subscription?view=azure-cli-latest#az-servicebus-topic-subscription-create) +1. Application Insights [account](https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource#azure-cli-preview) +1. Cosmos DB [account](https://docs.microsoft.com/cli/azure/cosmosdb?view=azure-cli-latest#az-cosmosdb-create) with [database](https://docs.microsoft.com/cli/azure/cosmosdb/sql/database?view=azure-cli-latest#az-cosmosdb-sql-database-create) and [container](https://docs.microsoft.com/cli/azure/cosmosdb/sql/container?view=azure-cli-latest) + +## Running from VSCode Dev Container + +* Open the project in the dev container. +* Rename `appsettings.json.sample` to `appsettings.json` and add connection information for Service Bus, Cosmos DB, and Application Insights. +* Run the application - `dotnet run --project .\valid-cargo-manager.csproj` +* Post a message to the the Service Bus Topic similar to the [sample message](#sample-message) + +## Docker Container + +* Rename `appsettings.json.sample` to `appsettings.json` and add connection information for Service Bus, Cosmos DB, and Application Insights. +* Run `docker compose up` to run the service. +* Post a message to the the Service Bus Topic similar to the [sample message](#sample-message) + +## Sample Message + +```json +{ + "operationId": "4be3aab6-0f8f-4d5e-9330-3c0d89950cfa", + "data": { + "id": "08e222e4-5180-4f35-a8d6-e41b47b6447c", + "timestamp": "2022-06-24T17:10:28.000+00:00", + "product": { + "name": "toys", + "quantity": 100 + }, + "port": { + "source": "New York City", + "destination": "Tacoma" + }, + "demandDates": { + "start": "2022-11-24T00:00:00.000+00:00", + "end": "2022-11-30T00:00:00.000+00:00" + }, + "valid": true, + "errorMessage": null + } +} +``` + +### Custom Properties + +Ensure the following custom properties are also set for the messages posted to the Service Bus topic: + +* Diagnostic-Id: When posting a message to the service bus, also ensure a traceparent custom property has been set to a value that conforms pattern defined [by w3c](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format). + + For example a value like: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01 + +* valid: boolean property identifying whether the cargo object passed validation. For this service to respond to the message the value should be set to True. diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Services/SubscriptionReceiver.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Services/SubscriptionReceiver.cs new file mode 100644 index 0000000..66eac7e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Services/SubscriptionReceiver.cs @@ -0,0 +1,159 @@ +namespace ValidCargoProcessor +{ + using System.Threading.Tasks; + using Azure.Messaging.ServiceBus; + using Newtonsoft.Json; + using System.Net; + using Microsoft.Azure.Cosmos; + using Microsoft.ApplicationInsights.DataContracts; + using Microsoft.ApplicationInsights; + using Microsoft.ApplicationInsights.Extensibility; + using System.Diagnostics; + using Microsoft.ApplicationInsights.Metrics; + + public class SubscriptionReceiver : ISubscriptionReceiver + { + private readonly IConfiguration _configuration; + private readonly ILogger _logger; + private readonly ServiceBusClient _serviceBusClient; + private readonly ServiceBusProcessor _processor; + private readonly ServiceBusSender _sender; + private readonly CosmosClient _cosmosClient; + private readonly TelemetryClient _telemetryClient; + private readonly MetricConfiguration _customMetricConfiguration; + + private readonly Container _container; + public SubscriptionReceiver(IConfiguration configuration, + ILogger logger, + CosmosClient cosmosClient, ServiceBusClient serviceBusClient, TelemetryClient telemetryClient) + { + _configuration = configuration; + _logger = logger; + _cosmosClient = cosmosClient; + _serviceBusClient = serviceBusClient; + _container = _cosmosClient.GetDatabase(_configuration["CosmosDB:Database"]).GetContainer(_configuration["CosmosDB:Container"]); + var prefetchCount = _configuration["ServiceBus:PrefetchCount"] == string.Empty ? 10 : int.Parse(_configuration["ServiceBus:PrefetchCount"]); + var maxConcurrentCalls = _configuration["ServiceBus:MaxConcurrentCalls"] == string.Empty ? 10 : int.Parse(_configuration["ServiceBus:MaxConcurrentCalls"]); + _processor = _serviceBusClient.CreateProcessor(_configuration["ServiceBus:Topic"], _configuration["ServiceBus:Subscription"], new ServiceBusProcessorOptions + { + PrefetchCount = prefetchCount, + MaxConcurrentCalls = maxConcurrentCalls + }); + _sender = _serviceBusClient.CreateSender(_configuration["ServiceBus:Queue"]); + _telemetryClient = telemetryClient; + _customMetricConfiguration = new MetricConfiguration(seriesCountLimit: 100, valuesPerDimensionLimit: 40, new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false)); + } + + private async Task MessageHandler(ProcessMessageEventArgs args) + { + ServiceBusReceivedMessage receivedMessage = args.Message; + string body = receivedMessage.Body.ToString(); + _logger.LogInformation($"Received: {body} from subscription"); + + if (receivedMessage.ApplicationProperties.TryGetValue("Diagnostic-Id", out var objectId) && objectId is string diagnosticId) + { + string traceId = diagnosticId.Split('-')[1]; + string parentId = diagnosticId.Split('-')[2]; + using (var operation = _telemetryClient.StartOperation("ServiceBusTopic.ProcessMessage", traceId, parentId)) + { + operation.Telemetry.Url = new Uri($"sb://{_configuration["ServiceBus:Subscription"]}"); + await ProcessMessagesAsync(args, body, operation); + } + } + else + { + _logger.LogError("Message is missing telemetry tracking information."); + await args.DeadLetterMessageAsync(args.Message, "Missing telemetry tracking information"); + } + } + + private async Task ProcessMessagesAsync(ProcessMessageEventArgs args, string body, IOperationHolder operation) + { + try + { + MessageEnvelope? message = JsonConvert.DeserializeObject(body); + if (message != null) + { + ValidCargo cargo = message.Data; + await AddItemToContainerAsync(cargo); + + await SendOperationState(new OperationState + { + OperationId = message.OperationId, + State = "Succeeded", + Result = cargo + }); + + TrackMultiDimensionalMetrics(cargo); + + await args.CompleteMessageAsync(args.Message); + } + else + { + await args.DeadLetterMessageAsync(args.Message, "Null cargo."); + _logger.LogError($"Cargo object is null. Message deadlettered"); + } + } + catch (Exception ex) + { + _telemetryClient.TrackException(ex); + operation.Telemetry.Success = false; + _logger.LogError($"Exception encountered - ${ex.Message}. Message deadlettered."); + //Making sure our dead letter reason isn't larger than the max length ServiceBus will allow + await args.DeadLetterMessageAsync(args.Message, + ex.Message.Substring(0, Math.Min(4096, ex.Message.Length))); + } + } + + private void TrackMultiDimensionalMetrics(ValidCargo cargo) + { + var metric = _telemetryClient.GetMetric("port_product_qty", "product", "source", "destination", _customMetricConfiguration); + + metric.TrackValue(cargo.Product.Quantity, + cargo.Product.Name, + cargo.Port.Source, + cargo.Port.Destination); + } + + private async Task SendOperationState(OperationState operationState) + { + _logger.LogInformation($"Sending operation state {operationState.OperationId} message to {_configuration["ServiceBus:Queue"]} queue"); + var message = new ServiceBusMessage(JsonConvert.SerializeObject(operationState)); + await _sender.SendMessageAsync(message); + } + + private Task ErrorHandler(ProcessErrorEventArgs args) + { + _logger.LogError(args.Exception.ToString()); + return Task.CompletedTask; + } + + public async Task ProcessMessagesAsync() + { + _processor.ProcessMessageAsync += MessageHandler; + _processor.ProcessErrorAsync += ErrorHandler; + await _processor.StartProcessingAsync(); + } + + public async Task StopProcessingAsync() + { + await _processor.StopProcessingAsync(); + await _processor.DisposeAsync(); + await _serviceBusClient.DisposeAsync(); + } + + public async Task AddItemToContainerAsync(ValidCargo cargo) + { + try + { + ItemResponse cargoResponse = await _container.ReadItemAsync(cargo.Id, new PartitionKey(cargo.Id)); + _logger.LogInformation($"Item in database with id: {cargoResponse.Resource.Id} already exists."); + } + catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound) + { + ItemResponse cargoResponse = await _container.CreateItemAsync(cargo, new PartitionKey(cargo.Id)); + _logger.LogInformation($"Created item in database with id: {cargoResponse.Resource.Id} Operation consumed {cargoResponse.RequestCharge} RUs."); + } + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Telemetry/TelemetryInitializer.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Telemetry/TelemetryInitializer.cs new file mode 100644 index 0000000..98105bf --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Telemetry/TelemetryInitializer.cs @@ -0,0 +1,16 @@ +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.Extensibility; + +namespace ValidCargoProcessor.Telemetry +{ + public class TelemetryInitializer : ITelemetryInitializer + { + public void Initialize(ITelemetry telemetry) + { + if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName)) + { + telemetry.Context.Cloud.RoleName = "valid-cargo-manager"; + } + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Worker.cs b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Worker.cs new file mode 100644 index 0000000..197fb56 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/Worker.cs @@ -0,0 +1,30 @@ +using Microsoft.ApplicationInsights; + +namespace ValidCargoProcessor +{ + public class Worker : BackgroundService + { + private readonly ILogger _logger; + private readonly TelemetryClient _telemetryClient; + private readonly ISubscriptionReceiver _subscriptionReceiver; + + public Worker(ILogger logger, TelemetryClient tc, ISubscriptionReceiver subscriptionReceiver) + { + _logger = logger; + _telemetryClient = tc; + _subscriptionReceiver = subscriptionReceiver; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("Starting processing"); + await _subscriptionReceiver.ProcessMessagesAsync(); + } + + public override async Task StopAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("Stopping processing"); + await _subscriptionReceiver.StopProcessingAsync(); + } + } +} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/appsettings.sample.json b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/appsettings.sample.json new file mode 100644 index 0000000..e9a24a2 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/appsettings.sample.json @@ -0,0 +1,37 @@ +{ + "ApplicationInsights": { + "ConnectionString": "InstrumentationKey=00000000-0000-0000-0000-000000000000;" + }, + "ServiceBus": { + "ConnectionString": "Endpoint=00000000=", + "Topic": "topicName", + "Queue": "queueName", + "Subscription": "subscriptionName", + "PrefetchCount": 100, + "MaxConcurrentCalls": 10 + }, + "CosmosDB": { + "EndpointUri": "https://00000000.documents.azure.com:443/", + "PrimaryKey": "00000000==", + "Database": "databaseName", + "Container": "containerName" + }, + "Logging": { + "LogLevel": { + "Default": "Debug", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "HealthCheck": { + "TcpServer": { + "Port": 3030 + }, + "CosmosDB": { + "MaxDurationMs": 200 + }, + "ServiceBus": { + "MaxDurationMs": 200 + } + } +} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/docker-compose.yml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/docker-compose.yml new file mode 100644 index 0000000..620df46 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/docker-compose.yml @@ -0,0 +1,7 @@ +version: "3.9" + +services: + valid_cargo_manager: + build: + context: . + dockerfile: Dockerfile \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/.helmignore b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/Chart.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/Chart.yaml new file mode 100644 index 0000000..0d3287e --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: valid-cargo-manager +description: valid-cargo-manager for aks-sb-azmonitor-microservices + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/NOTES.txt b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/NOTES.txt new file mode 100644 index 0000000..dd366ce --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aks-sb-azmonitor-microservices.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/_helpers.tpl b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/_helpers.tpl new file mode 100644 index 0000000..0172cb3 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "aks-sb-azmonitor-microservices.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "aks-sb-azmonitor-microservices.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "aks-sb-azmonitor-microservices.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "aks-sb-azmonitor-microservices.labels" -}} +helm.sh/chart: {{ include "aks-sb-azmonitor-microservices.chart" . }} +{{ include "aks-sb-azmonitor-microservices.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "aks-sb-azmonitor-microservices.selectorLabels" -}} +app.kubernetes.io/name: {{ include "aks-sb-azmonitor-microservices.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "aks-sb-azmonitor-microservices.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "aks-sb-azmonitor-microservices.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/deployment.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/deployment.yaml new file mode 100644 index 0000000..8f5eaab --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/deployment.yaml @@ -0,0 +1,118 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: default + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: ServiceBus__Topic + value: "validated-cargo" + - name: ServiceBus__Subscription + value: "valid-cargo" + - name: ServiceBus__Queue + value: "operation-state" + - name: ServiceBus__PrefetchCount + value: "100" + - name: ServiceBus__MaxConcurrentCalls + value: "10" + - name: CosmosDB__Database + value: "cargo" + - name: CosmosDB__Container + value: "valid-cargo" + - name: Logging__LogLevel__Default + value: "Information" + - name: Logging__LogLevel__Microsoft + value: "Warning" + - name: Logging__LogLevel__Microsoft.Hosting.Lifetime + value: "Information" + - name: HealthCheck__TcpServer__Port + value: "3030" + - name: HealthCheck__CosmosDB__MaxDurationMS + value: "1000" + - name: HealthCheck__ServiceBus__MaxDurationMS + value: "1000" + - name: ApplicationInsights__ConnectionString + valueFrom: + secretKeyRef: + name: valid-cargo-manager-secrets + key: AppInsightsConnectionString + - name: ServiceBus__ConnectionString + valueFrom: + secretKeyRef: + name: valid-cargo-manager-secrets + key: ServiceBusConnectionString + - name: CosmosDB__EndpointUri + valueFrom: + secretKeyRef: + name: valid-cargo-manager-secrets + key: CosmosDBEndpoint + - name: CosmosDB__PrimaryKey + valueFrom: + secretKeyRef: + name: valid-cargo-manager-secrets + key: CosmosDBKey + ports: + - name: http + containerPort: 3030 + protocol: TCP + livenessProbe: + tcpSocket: + port: 3030 + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 10 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: secrets-store + mountPath: "/mnt/secrets-store" + readOnly: true + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: secrets-store + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: {{ include "aks-sb-azmonitor-microservices.fullname" . }} \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/hpa.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/hpa.yaml new file mode 100644 index 0000000..0a3ca97 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/secretProviderClass.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/secretProviderClass.yaml new file mode 100644 index 0000000..15cceb5 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/secretProviderClass.yaml @@ -0,0 +1,41 @@ +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + provider: azure + parameters: + usePodIdentity: "false" + useVMManagedIdentity: "true" + userAssignedIdentityID: {{ .Values.aksKeyVaultSecretProviderIdentityId }} + keyvaultName: {{ .Values.keyVault.name }} + cloudName: "" + objects: | + array: + - | + objectName: AppInsightsConnectionString + objectType: secret + - | + objectName: ServiceBusConnectionString + objectType: secret + - | + objectName: CosmosDBEndpoint + objectType: secret + - | + objectName: CosmosDBKey + objectType: secret + tenantId: {{ .Values.keyVault.tenantId }} + secretObjects: + - data: + - key: AppInsightsConnectionString + objectName: AppInsightsConnectionString + - key: ServiceBusConnectionString + objectName: ServiceBusConnectionString + - key: CosmosDBEndpoint + objectName: CosmosDBEndpoint + - key: CosmosDBKey + objectName: CosmosDBKey + secretName: valid-cargo-manager-secrets + type: Opaque \ No newline at end of file diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/service.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/service.yaml new file mode 100644 index 0000000..af3f13a --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "aks-sb-azmonitor-microservices.fullname" . }} + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "aks-sb-azmonitor-microservices.selectorLabels" . | nindent 4 }} diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/tests/test-connection.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5eb4bc4 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "aks-sb-azmonitor-microservices.fullname" . }}-test-connection" + labels: + {{- include "aks-sb-azmonitor-microservices.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "aks-sb-azmonitor-microservices.fullname" . }}:80'] + restartPolicy: Never diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/valid-cargo-manager.yaml b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/valid-cargo-manager.yaml new file mode 100644 index 0000000..3d7bf17 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/helm/valid-cargo-manager.yaml @@ -0,0 +1,35 @@ +image: + pullPolicy: Always + tag: "latest" + +replicaCount: 1 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +podAnnotations: {} +podSecurityContext: {} +securityContext: {} +resources: {} +nodeSelector: {} +tolerations: [] +affinity: {} + + +# When running one of the deploy-*.sh scripts, an additional env.yaml +# values file is created containing values specific to the deployed environment +# with the following values: +# image: +# repository: + +# keyVault: +# name: +# tenantId: + +# aksKeyVaultSecretProviderIdentityId: diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.csproj b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.csproj new file mode 100644 index 0000000..b726c16 --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + enable + enable + dotnet-service_3-ED6CA571-2254-4C5F-9683-8520F235A2C9 + ValidCargoProcessor + Linux + . + + + + + + + + + + + + + + + diff --git a/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.sln b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.sln new file mode 100644 index 0000000..2e4b28d --- /dev/null +++ b/accelerators/aks-sb-azmonitor-microservices/src/valid-cargo-manager/valid-cargo-manager.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32616.157 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "valid-cargo-manager", "valid-cargo-manager.csproj", "{D909D249-A340-4C52-8CE0-6F7BEEBA000B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{47F598B3-9435-4ADA-A2D7-0933D138468E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D909D249-A340-4C52-8CE0-6F7BEEBA000B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D909D249-A340-4C52-8CE0-6F7BEEBA000B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D909D249-A340-4C52-8CE0-6F7BEEBA000B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D909D249-A340-4C52-8CE0-6F7BEEBA000B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {92C81030-3C75-4F2B-A795-616979C0ABCF} + EndGlobalSection +EndGlobal From d12a46b8264ef61d28c0cfb6e41f8b406d7e7401 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 14:41:14 +0000 Subject: [PATCH 2/2] Bump xml2js and @azure/core-http Bumps [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) and [@azure/core-http](https://github.com/Azure/azure-sdk-for-js). These dependencies needed to be updated together. Updates `xml2js` from 0.4.23 to 0.5.0 - [Commits](https://github.com/Leonidas-from-XIV/node-xml2js/commits/0.5.0) Updates `@azure/core-http` from 2.2.5 to 2.3.2 - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/core-http_2.2.5...@azure/core-http_2.3.2) --- updated-dependencies: - dependency-name: xml2js dependency-type: indirect - dependency-name: "@azure/core-http" dependency-type: indirect ... Signed-off-by: dependabot[bot] --- .../package-lock.json | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json index 40c855d..1d4e41e 100644 --- a/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json +++ b/accelerators/aks-sb-azmonitor-microservices/src/cargo-processing-validator/package-lock.json @@ -80,13 +80,14 @@ } }, "node_modules/@azure/core-http": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.5.tgz", - "integrity": "sha512-kctMqSQ6zfnlFpuYzfUKadeTyOQYbIQ+3Rj7dzVC3Dk1dOnHroTwR9hLYKX8/n85iJpkyaksaXpuh5L7GJRYuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.3.2.tgz", + "integrity": "sha512-Z4dfbglV9kNZO177CNx4bo5ekFuYwwsvjLiKdZI4r84bYGv3irrbQz7JC3/rUfFH2l4T/W6OFleJaa2X0IaQqw==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", "@types/node-fetch": "^2.5.0", "@types/tunnel": "^0.0.3", @@ -97,10 +98,10 @@ "tslib": "^2.2.0", "tunnel": "^0.0.6", "uuid": "^8.3.0", - "xml2js": "^0.4.19" + "xml2js": "^0.5.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/core-paging": { @@ -126,6 +127,18 @@ "node": ">=12.0.0" } }, + "node_modules/@azure/core-util": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", + "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@azure/logger": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", @@ -2575,9 +2588,9 @@ "dev": true }, "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -2710,13 +2723,14 @@ } }, "@azure/core-http": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.5.tgz", - "integrity": "sha512-kctMqSQ6zfnlFpuYzfUKadeTyOQYbIQ+3Rj7dzVC3Dk1dOnHroTwR9hLYKX8/n85iJpkyaksaXpuh5L7GJRYuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.3.2.tgz", + "integrity": "sha512-Z4dfbglV9kNZO177CNx4bo5ekFuYwwsvjLiKdZI4r84bYGv3irrbQz7JC3/rUfFH2l4T/W6OFleJaa2X0IaQqw==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", "@types/node-fetch": "^2.5.0", "@types/tunnel": "^0.0.3", @@ -2727,7 +2741,7 @@ "tslib": "^2.2.0", "tunnel": "^0.0.6", "uuid": "^8.3.0", - "xml2js": "^0.4.19" + "xml2js": "^0.5.0" } }, "@azure/core-paging": { @@ -2747,6 +2761,15 @@ "tslib": "^2.2.0" } }, + "@azure/core-util": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", + "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + }, "@azure/logger": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", @@ -4497,9 +4520,9 @@ "dev": true }, "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", "requires": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0"

SF_MtG6Wr z5~aFYru}ZV1y1kf-?&=n`hNs=Z%@3)M>Nw8+}QZ~N56A@ZfRklm1w*%{TK!M1aIEf z99oHir@YNcnNv0eR2Q!Aio`S?EHTc+0l0b++k6lk{3TDFyBjH8hCTR?4Bbs5?tIPb z{jbI5rH|hlEV)Sf8fR%sw-bDwJgys#VF5eX3>&I1+$Tsui59S)gPG(0v+Ano}C}Mdjy9a0axJnBf{7Jz=cNLKWm)|s&;%s?nxcK z&pQ1vlKz{IYIX3p&Q95%#HyP3`8CDfB@Lf-aMj^t}x9~_o}D&9ORw@qQ6?TR~OxD zNr1FIkv*yV@~sIy=(g9F3RPsEbg(bl+L2JpjqXjqB%xEHv^;Yf_du_f*act@7Kd#g zq|d({m~G3sRsF9OLYl0)=y5rG5f&|;5uU#)W7r~fUF_S4)>f7r{zP}+KElQ>bB*S1 zt$g?dU7?!R)DI&X?0K8&_I_XRC|x$}~jmLRAY z9SogxR@6h2Q(9JDfpY1_wvyx+ZNHOPHZQKVw!|GsEv4X>5QjjS;c^=Llw}Em3PM8o zw%v+emQd(;%Z+7Rk@{l14zNAY&fk<)rs89U`RZ+4@a}oVNAs0E!<7&p?=Xeg+QT6I zaV6COzSEAN*Y;-><4t zEUWvDT3_ebN*f~I5Ed!%&QYE%rhFzLTwmlSw$fN~%AQqG{c|%0nQ6o8{8@7SZsLs( zyfV7lC$WWq8M_aG08N$xy(KYu`zBgvz%%*PSr|W226}=N&r6D{aaS@X~EYdvk~ z^ze?Z@zvtDQ<~2&mC`D6s!fxTo3AWpRen}fja-ohir7EnLwuR<> z8?WtC348N3h7Ej7@^;Vf2Czoq#wo4#_wE75w6k=Oh@0lxv*zM4T1|n<+Y*U++sdUD zN1cn)J_%dG^VVL6v?WAx$KXOFcW#k_co3IY-8k?^9}EQtuJ-Xo=j6*FdJ1&yls@Rw0RzeqR~wUCJ(&;jmQwo1jh~{b}9d7IjU| zOg=O2Ys)KUA*FMkAm01Jz6)do7p0)lL&QVQ>9>08W9q%Sxuk#jMB z(LQZrah&RlQtGl)(bJd=p)6?gg2dvM+#C?8wd0gmGb}cGY_$-L!rAI7 zh9wJkbi=#ZnIpnezm-%t$#-Y!tS81_Gf~wol2A)Xve;&_R8|_JLEPqR+0t0!Fa6Y^ ze>ZHK32D&U>n7Xex)9stq>y6QOS?P3zKF?YLmQ`r=r`Obh)PLvWsQ%Qej0i$!qa_UgP1rZ88Vi{B$A<1;Ea3O}~4 zKKpgy#6yr_SLh-&hGn=V*h!;?PR4uI-^YG|CVdHsDg>n4<;%qVG^UN^UQUVVug`M0 zv^#ww6~f7yw_dcpj>oc}ITov!C_ZtKc#n}?Xvk!~^!JCV&YZkyfv)w3)o>=wcYHfU z;)0NmSfKP&>wT#9r(SEpv~}?^7N)s&UeEbb`e)a0*;ttVNVu9P1hueTV*p4B-+wk& zj{_OJ9uIzQjyX%&diTL`DKHu_DRogDKr@7S>mE}(1|T?Zg3jPZarL}jcg(QL(OBZ%0E8OdEJ9 z1=~L6=32hN0H=*agLm!hnhhMAozo3F)D@W3M@b6`!0Zc6-%XD|uME})LP&bGko)&< zoTRzimXvL+cK8O9Z2a`+9jo{-A8IqkIF&u$O&DtT(<4`1yZpXu_6pysa@;SO3}G zNxAxWPS^j)0DJW${*r2&Ew+gS?sVHc^u8@28`EtHpI7S92wNN-A3weHT)8t)= z8n`B}9C#m`2=bBI8q^zZr(&A~ch3uYIAlg|e_M+9^uLL)QrPhS1u%-IHxQ$(gq?ysQQq80iKkW~4fkC~j za@*Yw|Nd=I^i+u6K+-YN=-*5?iCpjTlAq_}qgRD>^y_zGpI-mB)ho&W8k$$g@nV$B z$O8$z2h3dm9{H~?TmH0?zh%cqR|WqbN|M*Px_>9qy}JH?jP(EOaHu9f?D$Lvv-sC7 mNcKF9?R_u*kKv0T_Q78z>MKEJN0>HZc=6i53gmwe&i@70{B0os literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/metric-auto.png b/accelerators/aks-sb-azmonitor-microservices/assets/metric-auto.png new file mode 100644 index 0000000000000000000000000000000000000000..daa31b2e0bb0dec85c3e6845af8871a93fcf5117 GIT binary patch literal 11792 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 ZI?5C4j>ad4p<7>m_ip^p=YNgwe*uP#B%A;M literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/metric-manual.png b/accelerators/aks-sb-azmonitor-microservices/assets/metric-manual.png new file mode 100644 index 0000000000000000000000000000000000000000..e4690f10605125c184e708995c955426c8fb5ee8 GIT binary patch literal 11970 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 literal 0 HcmV?d00001 diff --git a/accelerators/aks-sb-azmonitor-microservices/assets/sb-microservice-accelerator-arch-diagram.drawio.png b/accelerators/aks-sb-azmonitor-microservices/assets/sb-microservice-accelerator-arch-diagram.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..cc7e73c16737a99465767644965ccbfa79f6f087 GIT binary patch literal 128297 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