├── .github └── workflows │ ├── appsignals-e2e-eks-test.yml │ └── release-build.yml ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── THIRD_PARTY_LICENSES ├── application-signals-demo.sln ├── cdk ├── ec2 │ ├── .gitignore │ ├── .npmignore │ ├── bin │ │ └── ec2.ts │ ├── cdk.json │ ├── ec2-cdk.sh │ ├── jest.config.js │ ├── lib │ │ ├── compute-stack.ts │ │ ├── database-stack.ts │ │ ├── iam-stack.ts │ │ ├── load-balancer-stack.ts │ │ ├── network-stack.ts │ │ └── user-data │ │ │ ├── billings-user-data.sh │ │ │ ├── customers-user-data.sh │ │ │ ├── insurances-user-data.sh │ │ │ ├── payments-user-data.sh │ │ │ ├── pet-clinic-frontend-user-data.sh │ │ │ ├── setup-user-data.sh │ │ │ ├── vets-user-data.sh │ │ │ └── visits-user-data.sh │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json ├── ecs │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── cdk.json │ ├── ecs-cdk.sh │ ├── jest.config.js │ ├── lib │ │ ├── app.ts │ │ ├── stacks │ │ │ ├── databaseStack.ts │ │ │ ├── ecsStack.ts │ │ │ ├── iamRolesStack.ts │ │ │ ├── loadbalancerStack.ts │ │ │ ├── logStack.ts │ │ │ ├── petClinicNetworkStack.ts │ │ │ └── servicediscoveryStack.ts │ │ └── utils.ts │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json └── eks │ ├── .gitignore │ ├── .npmignore │ ├── bin │ └── eks.ts │ ├── cdk.json │ ├── eks-cdk.sh │ ├── jest.config.js │ ├── lib │ ├── canaries │ │ ├── pc-add-visit-error-rum │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-add-visit-error-rum.js │ │ ├── pc-add-visit-rum │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-add-visit-rum.js │ │ ├── pc-add-visit │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-add-visit.js │ │ ├── pc-create-owners │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-create-owners.js │ │ ├── pc-visit-billings │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-visit-billings.js │ │ ├── pc-visit-insurances │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-visit-insurances.js │ │ ├── pc-visit-pet │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-visit-pet.js │ │ ├── pc-visit-vet │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pc-visit-vet.js │ │ ├── pet-clinic-rum │ │ │ └── nodejs │ │ │ │ └── node_modules │ │ │ │ └── pet-clinic-rum.js │ │ └── pet-clinic-traffic │ │ │ └── nodejs │ │ │ └── node_modules │ │ │ └── pet-clinic-traffic.js │ ├── manifests │ │ ├── alb-ingress │ │ │ └── petclinic-ingress.yaml │ │ ├── db │ │ │ ├── db-deployment.yaml │ │ │ ├── db-pvc.yaml │ │ │ ├── db-service.yaml │ │ │ └── storageclass.yaml │ │ ├── k8s-nginx-ingress │ │ │ ├── nginx-alb.yaml │ │ │ ├── nginx-ingress.yaml │ │ │ └── petclinc-nginx-ingress.yaml │ │ ├── mongodb │ │ │ ├── mongodb-deployment.yaml │ │ │ ├── mongodb-pvc.yaml │ │ │ ├── mongodb-service.yaml │ │ │ └── mongodb-storageclass.yaml │ │ ├── sample-app │ │ │ ├── admin-server-deployment.yaml │ │ │ ├── admin-server-service.yaml │ │ │ ├── api-gateway-deployment.yaml │ │ │ ├── api-gateway-service.yaml │ │ │ ├── billing-service-deployment.yaml │ │ │ ├── billing-service-service.yaml │ │ │ ├── config-server-deployment.yaml │ │ │ ├── config-server-service.yaml │ │ │ ├── customers-service-deployment.yaml │ │ │ ├── customers-service-service.yaml │ │ │ ├── data-persistentvolumeclaim.yaml │ │ │ ├── discovery-server-deployment.yaml │ │ │ ├── discovery-server-service.yaml │ │ │ ├── insurance-service-deployment.yaml │ │ │ ├── insurance-service-service.yaml │ │ │ ├── nutrition-service-deployment.yaml │ │ │ ├── nutrition-service-service.yaml │ │ │ ├── otel-collector-deployment.yaml │ │ │ ├── otel-collector-service.yaml │ │ │ ├── payment-service-deployment.yaml │ │ │ ├── payment-service-service.yaml │ │ │ ├── vets-service-deployment.yaml │ │ │ ├── vets-service-service.yaml │ │ │ ├── visits-service-deployment.yaml │ │ │ └── visits-service-service.yaml │ │ └── traffic-generator │ │ │ └── traffic-generator.yaml │ ├── stacks │ │ ├── canary-stack.ts │ │ ├── eks-stack.ts │ │ ├── iam-stack.ts │ │ ├── my-application-stack.ts │ │ ├── network-stack.ts │ │ ├── rds-stack.ts │ │ ├── rum-stack.ts │ │ └── slo-stack.ts │ └── utils │ │ └── utils.ts │ ├── package-lock.json │ ├── package.json │ ├── tsconfig.json │ └── vets-service-deployment-otlp.yaml ├── data_test ├── Readme.md ├── deploy │ ├── create_composite_alarms.py │ ├── create_test_cases_alarms.py │ ├── deploy_lambda.sh │ ├── remove_alarms.sh │ └── remove_lambda.sh ├── lambda │ ├── lambda_function.py │ ├── logs_tester.py │ ├── metrics_tester.py │ └── traces_tester.py ├── run_logs_tests.py ├── run_metrics_tests.py ├── run_trace_tests.py └── test_cases │ ├── logs_test_cases.json │ ├── metrics_test_cases.json │ └── traces_test_cases.json ├── doc ├── bedrock_demo.md ├── exclusion_window_demo.md ├── img.png ├── imgs │ ├── exclusion_window_img_1.png │ ├── exclusion_window_img_2.png │ ├── exclusion_window_img_3.png │ ├── genai_0.png │ ├── genai_1.png │ ├── genai_2.png │ ├── genai_3.png │ ├── lambda_0.png │ ├── lambda_1.png │ ├── lambda_2.png │ ├── lambda_3.png │ ├── my_app_0.png │ ├── my_app_1.png │ ├── my_app_2.png │ ├── rds_0.png │ ├── rds_1.png │ ├── rds_2.png │ ├── rds_3.png │ └── rds_4.png ├── lambda_demo.md ├── my_application_demo.md └── rds_demo.md ├── docker └── Dockerfile ├── dotnet-petclinic-payment ├── .gitignore └── PetClinic.PaymentService │ ├── .dockerignore │ ├── Dockerfile │ ├── EurekaConfigExtension.cs │ ├── Payment.cs │ ├── Pet.cs │ ├── PetClinic.PaymentService.csproj │ ├── PetClinicContext.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ └── ec2-setup.sh ├── lambda-petclinic ├── installDemo.sh ├── sample-apps │ ├── function │ │ ├── lambda_function.py │ │ └── requirements.txt │ ├── function2 │ │ ├── lambda_function.py │ │ └── requirements.txt │ ├── function3 │ │ ├── lambda_function.py │ │ └── requirements.txt │ ├── function4 │ │ ├── lambda_function.py │ │ └── requirements.txt │ └── package-lambda-function.sh └── terraform │ └── main.tf ├── mvnw ├── mvnw.cmd ├── otel-collector ├── Dockerfile ├── builder-config.yaml ├── customconfig.yaml └── ocb.sh ├── pet-nutrition-service ├── .gitignore ├── Dockerfile ├── db-seed.js ├── eureka-client.js ├── nutrition-fact.js ├── nutrition-service-update.sh ├── package-lock.json ├── package.json └── server.js ├── pet_clinic_billing_service ├── Dockerfile ├── billing-service-update.sh ├── billing_service │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_checklist.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ └── views.py ├── db.sqlite3 ├── ec2-setup.sh ├── manage.py ├── pet_clinic_billing_service │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── requirements.txt ├── pet_clinic_insurance_service ├── Dockerfile ├── db.sqlite3 ├── ec2-setup.sh ├── init.sh ├── insurance-service-update.sh ├── manage.py ├── pet_clinic_insurance_service │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── readme.md ├── requirements.txt └── service │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── fixtures │ └── initial_data.json │ ├── migrations │ ├── 0001_initial.py │ ├── 0002_alter_petinsurance_pet_id.py │ └── __init__.py │ ├── models.py │ ├── rest.py │ ├── serializers.py │ ├── tests.py │ └── views.py ├── pom.xml ├── push-ecr.sh ├── push-public-ecr.sh ├── scripts ├── ec2 │ └── appsignals │ │ └── setup-ec2-demo.sh ├── ecs │ └── appsignals │ │ └── setup-ecs-demo.sh ├── eks │ └── appsignals │ │ ├── canaries │ │ ├── policies │ │ │ ├── canary_policy.json │ │ │ └── canary_role.json │ │ └── scripts │ │ │ ├── pc-add-visit.js │ │ │ ├── pc-create-owners.js │ │ │ ├── pc-visit-billings.js │ │ │ ├── pc-visit-insurances.js │ │ │ ├── pc-visit-pet.js │ │ │ ├── pc-visit-vet.js │ │ │ └── pet-clinic-traffic.js │ │ ├── clean-app-signals.sh │ │ ├── cleanup-rds.sh │ │ ├── cleanup-slo.sh │ │ ├── create-canaries.sh │ │ ├── create-cluster.sh │ │ ├── create-rds.sh │ │ ├── create-slo.sh │ │ ├── deploy-sample-app.sh │ │ ├── deploy-traffic-generator.sh │ │ ├── enable-app-signals.sh │ │ ├── enable-ebs-csi-driver.sh │ │ ├── one-step │ │ ├── cleanup.sh │ │ └── setup.sh │ │ ├── sample-app │ │ ├── admin-server-deployment.yaml │ │ ├── admin-server-service.yaml │ │ ├── alb-ingress │ │ │ └── petclinic-ingress.yaml │ │ ├── api-gateway-deployment.yaml │ │ ├── api-gateway-service.yaml │ │ ├── billing-service-deployment.yaml │ │ ├── billing-service-service.yaml │ │ ├── config-server-deployment.yaml │ │ ├── config-server-service.yaml │ │ ├── customers-service-deployment.yaml │ │ ├── customers-service-service.yaml │ │ ├── data-persistentvolumeclaim.yaml │ │ ├── db │ │ │ ├── db-deployment.yaml │ │ │ ├── db-pvc.yaml │ │ │ ├── db-service.yaml │ │ │ └── storageclass.yaml │ │ ├── discovery-server-deployment.yaml │ │ ├── discovery-server-service.yaml │ │ ├── insurance-service-deployment.yaml │ │ ├── insurance-service-service.yaml │ │ ├── k8s-nginx-ingress │ │ │ ├── namespace.yaml │ │ │ ├── nginx-alb.yaml │ │ │ ├── nginx-ingress.yaml │ │ │ └── petclinc-nginx-ingress.yaml │ │ ├── mongodb │ │ │ ├── mongodb-deployment.yaml │ │ │ ├── mongodb-pvc.yaml │ │ │ ├── mongodb-service.yaml │ │ │ └── mongodb-storageclass.yaml │ │ ├── nutrition-service-deployment.yaml │ │ ├── nutrition-service-service.yaml │ │ ├── otel-collector-deployment.yaml │ │ ├── otel-collector-service.yaml │ │ ├── payment-service-deployment.yaml │ │ ├── payment-service-service.yaml │ │ ├── traffic-generator │ │ │ └── traffic-generator.yaml │ │ ├── vets-service-deployment.yaml │ │ ├── vets-service-service.yaml │ │ ├── visits-service-deployment.yaml │ │ └── visits-service-service.yaml │ │ ├── setup-eks-demo.sh │ │ ├── slo │ │ ├── application-signals-2024-04-15.normal.json │ │ ├── inputRequest │ │ │ ├── CreateServiceLevelObjective │ │ │ │ ├── getOwner99Availability.json │ │ │ │ ├── getOwnerP99Latency.json │ │ │ │ ├── postOwner99Availability.json │ │ │ │ └── postOwnerP99Latency.json │ │ │ ├── DeleteServiceLevelObjective │ │ │ │ ├── deleteSlo1.json │ │ │ │ ├── deleteSlo2.json │ │ │ │ ├── deleteSlo3.json │ │ │ │ └── deleteSlo4.json │ │ │ └── ListServices │ │ │ │ └── listServices.json │ │ └── monitoring-2010-08-01.normal.json │ │ └── tf-deploy-k8s-res.sh ├── k8s │ └── appsignals │ │ ├── allow-ecr-access.json │ │ ├── deploy-sample-app.sh │ │ ├── sample-app │ │ ├── admin-server-deployment.yaml │ │ ├── admin-server-service.yaml │ │ ├── api-gateway-deployment.yaml │ │ ├── api-gateway-service.yaml │ │ ├── billing-service-deployment.yaml │ │ ├── billing-service-service.yaml │ │ ├── config-server-deployment.yaml │ │ ├── config-server-service.yaml │ │ ├── customers-service-deployment.yaml │ │ ├── customers-service-service.yaml │ │ ├── db │ │ │ ├── db-deployment.yaml │ │ │ ├── db-pvc.yaml │ │ │ ├── db-service.yaml │ │ │ └── storageclass.yaml │ │ ├── discovery-server-deployment.yaml │ │ ├── discovery-server-service.yaml │ │ ├── insurance-service-deployment.yaml │ │ ├── insurance-service-service.yaml │ │ ├── k8s-nginx-ingress │ │ │ ├── namespace.yaml │ │ │ ├── nginx-alb.yaml │ │ │ ├── nginx-ingress.yaml │ │ │ └── petclinc-nginx-ingress.yaml │ │ ├── mongodb │ │ │ ├── mongodb-deployment.yaml │ │ │ ├── mongodb-pvc.yaml │ │ │ ├── mongodb-service.yaml │ │ │ └── mongodb-storageclass.yaml │ │ ├── nutrition-service-deployment.yaml │ │ ├── nutrition-service-service.yaml │ │ ├── payment-service-deployment.yaml │ │ ├── payment-service-service.yaml │ │ ├── vets-service-deployment.yaml │ │ ├── vets-service-service.yaml │ │ ├── visits-service-deployment.yaml │ │ └── visits-service-service.yaml │ │ ├── setup-k8s-demo.sh │ │ ├── traffic-generator.yaml │ │ └── trust-policy.json └── opentelemetry │ ├── appsignals_custom_otel_setup │ └── custom-opentelemetry.yaml │ ├── otel-custom-builder │ ├── Dockerfile │ └── builder-config.yaml │ └── otel_simple_setup │ └── opentelemetry.yaml ├── spring-petclinic-admin-server ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── springframework │ │ └── samples │ │ └── petclinic │ │ └── admin │ │ └── SpringBootAdminApplication.java │ └── resources │ ├── application.yml │ └── logback-spring.xml ├── spring-petclinic-api-gateway ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── api │ │ │ ├── ApiGatewayApplication.java │ │ │ ├── TracingRouteGatewayFilterFactory.java │ │ │ ├── application │ │ │ ├── BillingServiceClient.java │ │ │ ├── CustomersServiceClient.java │ │ │ ├── InsuranceServiceClient.java │ │ │ ├── NutritionServiceClient.java │ │ │ ├── PaymentClient.java │ │ │ ├── VetsServiceClient.java │ │ │ └── VisitsServiceClient.java │ │ │ ├── boundary │ │ │ └── web │ │ │ │ ├── ApiController.java │ │ │ │ └── ApiGatewayController.java │ │ │ ├── dto │ │ │ ├── BillingDetail.java │ │ │ ├── InsuranceDetail.java │ │ │ ├── OwnerDetails.java │ │ │ ├── OwnerRequest.java │ │ │ ├── PaymentAdd.java │ │ │ ├── PaymentDetail.java │ │ │ ├── PetDetails.java │ │ │ ├── PetFull.java │ │ │ ├── PetInsurance.java │ │ │ ├── PetNutrition.java │ │ │ ├── PetRequest.java │ │ │ ├── PetType.java │ │ │ ├── SpecialtyDetails.java │ │ │ ├── VetDetails.java │ │ │ ├── VisitDetails.java │ │ │ └── Visits.java │ │ │ ├── filter │ │ │ └── RumConfigFilter.java │ │ │ └── utils │ │ │ └── WellKnownAttributes.java │ ├── less │ │ ├── header.less │ │ ├── petclinic.less │ │ ├── responsive.less │ │ └── typography.less │ ├── resources │ │ ├── application.yml │ │ ├── logback-spring.xml │ │ ├── messages │ │ │ ├── messages.properties │ │ │ ├── messages_de.properties │ │ │ └── messages_en.properties │ │ └── static │ │ │ ├── fonts │ │ │ ├── montserrat-webfont.eot │ │ │ ├── montserrat-webfont.svg │ │ │ ├── montserrat-webfont.ttf │ │ │ ├── montserrat-webfont.woff │ │ │ ├── varela_round-webfont.eot │ │ │ ├── varela_round-webfont.svg │ │ │ ├── varela_round-webfont.ttf │ │ │ └── varela_round-webfont.woff │ │ │ ├── images │ │ │ ├── favicon.png │ │ │ ├── pets.png │ │ │ ├── platform-bg.png │ │ │ ├── spring-logo-dataflow-mobile.png │ │ │ ├── spring-logo-dataflow.png │ │ │ └── spring-pivotal-logo.png │ │ │ ├── index.html │ │ │ └── scripts │ │ │ ├── app.js │ │ │ ├── billing-list │ │ │ ├── billing-list.component.js │ │ │ ├── billing-list.controller.js │ │ │ ├── billing-list.js │ │ │ └── billing-list.template.html │ │ │ ├── fragments │ │ │ ├── footer.html │ │ │ ├── nav.html │ │ │ └── welcome.html │ │ │ ├── infrastructure │ │ │ ├── httpErrorHandlingInterceptor.js │ │ │ └── infrastructure.js │ │ │ ├── insurance-list │ │ │ ├── insurance-list.component.js │ │ │ ├── insurance-list.controller.js │ │ │ ├── insurance-list.js │ │ │ └── insurance-list.template.html │ │ │ ├── owner-details │ │ │ ├── owner-details.component.js │ │ │ ├── owner-details.controller.js │ │ │ ├── owner-details.js │ │ │ └── owner-details.template.html │ │ │ ├── owner-form │ │ │ ├── owner-form.component.js │ │ │ ├── owner-form.controller.js │ │ │ ├── owner-form.js │ │ │ └── owner-form.template.html │ │ │ ├── owner-list │ │ │ ├── owner-list.component.js │ │ │ ├── owner-list.controller.js │ │ │ ├── owner-list.js │ │ │ └── owner-list.template.html │ │ │ ├── payment-form │ │ │ ├── payment-form.component.js │ │ │ ├── payment-form.controller.js │ │ │ ├── payment-form.js │ │ │ └── payment-form.template.html │ │ │ ├── pet-form │ │ │ ├── pet-form.component.js │ │ │ ├── pet-form.controller.js │ │ │ ├── pet-form.js │ │ │ └── pet-form.template.html │ │ │ ├── vet-list │ │ │ ├── vet-list.component.js │ │ │ ├── vet-list.controller.js │ │ │ ├── vet-list.js │ │ │ └── vet-list.template.html │ │ │ └── visits │ │ │ ├── visits.component.js │ │ │ ├── visits.controller.js │ │ │ ├── visits.js │ │ │ └── visits.template.html │ └── wro │ │ ├── wro.properties │ │ └── wro.xml │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── samples │ │ └── petclinic │ │ └── api │ │ ├── ApiGatewayApplicationTests.java │ │ ├── application │ │ └── VisitsServiceClientIntegrationTest.java │ │ └── boundary │ │ └── web │ │ ├── ApiGatewayControllerTest.java │ │ └── CircuitBreakerConfiguration.java │ ├── jmeter │ └── petclinic_test_plan.jmx │ └── resources │ └── application-test.yml ├── spring-petclinic-config-server ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── config │ │ │ └── ConfigServerApplication.java │ └── resources │ │ ├── application.yml │ │ └── static │ │ └── index.html │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── samples │ │ └── petclinic │ │ └── config │ │ └── PetclinicConfigServerApplicationTests.java │ └── resources │ └── application.yml ├── spring-petclinic-customers-service ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── customers │ │ │ ├── Config.java │ │ │ ├── CustomersServiceApplication.java │ │ │ ├── Util.java │ │ │ ├── aws │ │ │ ├── BedrockAgentV1Service.java │ │ │ ├── BedrockAgentV2Service.java │ │ │ ├── BedrockRuntimeV1Service.java │ │ │ ├── BedrockRuntimeV2Service.java │ │ │ ├── BedrockV1Service.java │ │ │ ├── BedrockV2Service.java │ │ │ ├── KinesisService.java │ │ │ └── SqsService.java │ │ │ ├── model │ │ │ ├── Owner.java │ │ │ ├── OwnerRepository.java │ │ │ ├── Pet.java │ │ │ ├── PetRepository.java │ │ │ └── PetType.java │ │ │ └── web │ │ │ ├── OwnerResource.java │ │ │ ├── PetDetails.java │ │ │ ├── PetInsurance.java │ │ │ ├── PetNutrition.java │ │ │ ├── PetRequest.java │ │ │ ├── PetResource.java │ │ │ └── ResourceNotFoundException.java │ └── resources │ │ ├── application.yml │ │ ├── db │ │ ├── hsqldb │ │ │ ├── data.sql │ │ │ └── schema.sql │ │ └── mysql │ │ │ ├── data.sql │ │ │ └── schema.sql │ │ └── logback-spring.xml │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── samples │ │ └── petclinic │ │ └── customers │ │ └── web │ │ └── PetResourceTest.java │ └── resources │ └── application-test.yml ├── spring-petclinic-discovery-server ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── discovery │ │ │ └── DiscoveryServerApplication.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── org │ └── springframework │ └── samples │ └── petclinic │ └── discovery │ └── DiscoveryServerApplicationTests.java ├── spring-petclinic-vets-service ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── vets │ │ │ ├── VetsServiceApplication.java │ │ │ ├── aws │ │ │ └── S3Service.java │ │ │ ├── model │ │ │ ├── Specialty.java │ │ │ ├── Vet.java │ │ │ └── VetRepository.java │ │ │ ├── system │ │ │ ├── CacheConfig.java │ │ │ └── VetsProperties.java │ │ │ └── web │ │ │ └── VetResource.java │ └── resources │ │ ├── application.yml │ │ ├── db │ │ ├── hsqldb │ │ │ ├── data.sql │ │ │ └── schema.sql │ │ └── mysql │ │ │ ├── data.sql │ │ │ └── schema.sql │ │ └── logback-spring.xml │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── samples │ │ └── petclinic │ │ └── vets │ │ └── web │ │ └── VetResourceTest.java │ └── resources │ └── application-test.yml ├── spring-petclinic-visits-service ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── visits │ │ │ ├── Util.java │ │ │ ├── VisitsServiceApplication.java │ │ │ ├── aws │ │ │ └── DdbService.java │ │ │ ├── model │ │ │ ├── Visit.java │ │ │ └── VisitRepository.java │ │ │ └── web │ │ │ ├── InvalidDateException.java │ │ │ └── VisitResource.java │ └── resources │ │ ├── application.yml │ │ ├── db │ │ ├── hsqldb │ │ │ ├── data.sql │ │ │ └── schema.sql │ │ └── mysql │ │ │ ├── data.sql │ │ │ └── schema.sql │ │ └── logback-spring.xml │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── samples │ │ └── petclinic │ │ └── visits │ │ └── web │ │ └── VisitResourceTest.java │ └── resources │ └── application-test.yml ├── terraform └── eks │ ├── alb-controller.tf │ ├── data.tf │ ├── database.tf │ ├── main.tf │ ├── observability.tf │ ├── outputs.tf │ ├── provider.tf │ ├── repo.tf │ ├── variables.tf │ └── versions.tf └── traffic-generator ├── Dockerfile ├── index.js └── package.json /.github/workflows/release-build.yml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT 3 | 4 | name: Release Testing 5 | on: 6 | workflow_dispatch: 7 | 8 | concurrency: 9 | group: ${{ github.workflow }} 10 | cancel-in-progress: false 11 | 12 | permissions: 13 | id-token: write 14 | contents: read 15 | 16 | jobs: 17 | e2e-test: 18 | uses: ./.github/workflows/appsignals-e2e-eks-test.yml 19 | secrets: inherit 20 | with: 21 | aws-region: 'us-east-1' 22 | test-cluster-name: 'e2e-enablement-script-test' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # test 3 | **petclinic_test_plan.jmx 4 | 5 | # terraform 6 | **/.terraform/ 7 | **/terraform.tfstate 8 | **/terraform.tfstate.backup 9 | **/.external_modules/ 10 | **/.terraform.lock.hcl 11 | 12 | # python 13 | **/__pycache__/ 14 | 15 | # Maven 16 | target/ 17 | !.mvn/wrapper/maven-wrapper.jar 18 | 19 | # Jenv 20 | .java-version 21 | 22 | # Eclipse 23 | .settings/ 24 | .classpath 25 | .project 26 | 27 | # IntelliJ IDEA 28 | .idea 29 | *.iml 30 | 31 | # Visual Studio Code 32 | .factorypath 33 | .vscode/ 34 | 35 | # Branch switching 36 | generated/ 37 | 38 | # Mac OS 39 | *.DS_Store 40 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.4/maven-wrapper-0.5.4.jar 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /cdk/ec2/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | -------------------------------------------------------------------------------- /cdk/ec2/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /cdk/ec2/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | roots: ['/test'], 4 | testMatch: ['**/*.test.ts'], 5 | transform: { 6 | '^.+\\.tsx?$': 'ts-jest' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /cdk/ec2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ec2", 3 | "version": "0.1.0", 4 | "bin": { 5 | "ec2": "bin/ec2.js" 6 | }, 7 | "engines": { 8 | "node": ">=18.0.0" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "watch": "tsc -w", 13 | "test": "jest", 14 | "cdk": "cdk" 15 | }, 16 | "devDependencies": { 17 | "@types/jest": "^29.5.14", 18 | "@types/node": "22.7.9", 19 | "jest": "^29.7.0", 20 | "ts-jest": "^29.2.5", 21 | "aws-cdk": "2.166.0", 22 | "ts-node": "^10.9.2", 23 | "typescript": "~5.6.3" 24 | }, 25 | "dependencies": { 26 | "aws-cdk-lib": "2.166.0", 27 | "constructs": "^10.0.0", 28 | "source-map-support": "^0.5.21" 29 | } 30 | } -------------------------------------------------------------------------------- /cdk/ec2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2020", 7 | "dom" 8 | ], 9 | "declaration": true, 10 | "strict": true, 11 | "noImplicitAny": true, 12 | "strictNullChecks": true, 13 | "noImplicitThis": true, 14 | "alwaysStrict": true, 15 | "noUnusedLocals": false, 16 | "noUnusedParameters": false, 17 | "noImplicitReturns": true, 18 | "noFallthroughCasesInSwitch": false, 19 | "inlineSourceMap": true, 20 | "inlineSources": true, 21 | "experimentalDecorators": true, 22 | "strictPropertyInitialization": false, 23 | "typeRoots": [ 24 | "./node_modules/@types" 25 | ] 26 | }, 27 | "exclude": [ 28 | "node_modules", 29 | "cdk.out" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /cdk/ecs/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | -------------------------------------------------------------------------------- /cdk/ecs/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /cdk/ecs/.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore artifacts: 2 | build 3 | coverage 4 | -------------------------------------------------------------------------------- /cdk/ecs/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | roots: ['/test'], 4 | testMatch: ['**/*.test.ts'], 5 | transform: { 6 | '^.+\\.tsx?$': 'ts-jest', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /cdk/ecs/lib/stacks/logStack.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import { LogGroup } from 'aws-cdk-lib/aws-logs'; 3 | import { RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; 4 | 5 | export class LogStack extends Stack { 6 | constructor(scope: Construct, id: string, props?: StackProps) { 7 | super(scope, id, props); 8 | } 9 | 10 | public createLogGroup(serviceName: string) { 11 | return new LogGroup(this, `${serviceName}-log-group`, { 12 | logGroupName: `/ecs/${serviceName}`, 13 | removalPolicy: RemovalPolicy.DESTROY, 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /cdk/ecs/lib/utils.ts: -------------------------------------------------------------------------------- 1 | async function getLatestAdotJavaTag(): Promise { 2 | const response = await fetch('https://github.com/aws-observability/aws-otel-java-instrumentation/releases/latest', { 3 | method: 'HEAD', 4 | redirect: 'follow', 5 | }); 6 | 7 | // Get the final URL after redirects 8 | const finalUrl = response.url; 9 | 10 | // Extract the tag from the URL 11 | return finalUrl.split('/').pop() || ''; 12 | } 13 | 14 | async function getLatestAdotPythonTag(): Promise { 15 | const response = await fetch( 16 | 'https://github.com/aws-observability/aws-otel-python-instrumentation/releases/latest', 17 | { 18 | method: 'HEAD', 19 | redirect: 'follow', 20 | }, 21 | ); 22 | 23 | // Get the final URL after redirects 24 | const finalUrl = response.url; 25 | 26 | // Extract the tag from the URL 27 | return finalUrl.split('/').pop() || ''; 28 | } 29 | 30 | export { getLatestAdotJavaTag, getLatestAdotPythonTag }; 31 | -------------------------------------------------------------------------------- /cdk/ecs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cdk-ecs", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "build": "npm install && tsc && cdk synth", 6 | "watch": "tsc -w", 7 | "test": "jest", 8 | "cdk": "cdk", 9 | "clean": "rm -rf node_modules && rm -rf ./cdk.out" 10 | }, 11 | "engines": { 12 | "node": ">=18.0.0" 13 | }, 14 | "devDependencies": { 15 | "@types/jest": "^29.5.14", 16 | "@types/node": "22.7.9", 17 | "aws-cdk": "2.166.0", 18 | "jest": "^29.7.0", 19 | "prettier": "3.3.3", 20 | "ts-jest": "^29.2.5", 21 | "ts-node": "^10.9.2", 22 | "typescript": "~5.6.3" 23 | }, 24 | "dependencies": { 25 | "aws-cdk-lib": "2.166.0", 26 | "constructs": "^10.0.0", 27 | "source-map-support": "^0.5.21" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cdk/ecs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["es2020", "dom"], 6 | "declaration": true, 7 | "strict": true, 8 | "noImplicitAny": true, 9 | "strictNullChecks": true, 10 | "noImplicitThis": true, 11 | "alwaysStrict": true, 12 | "noUnusedLocals": false, 13 | "noUnusedParameters": false, 14 | "noImplicitReturns": true, 15 | "noFallthroughCasesInSwitch": false, 16 | "inlineSourceMap": true, 17 | "inlineSources": true, 18 | "experimentalDecorators": true, 19 | "strictPropertyInitialization": false, 20 | "typeRoots": ["./node_modules/@types"] 21 | }, 22 | "exclude": ["node_modules", "cdk.out"] 23 | } 24 | -------------------------------------------------------------------------------- /cdk/eks/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | 10 | !lib/canaries/** -------------------------------------------------------------------------------- /cdk/eks/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /cdk/eks/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | roots: ['/test'], 4 | testMatch: ['**/*.test.ts'], 5 | transform: { 6 | '^.+\\.tsx?$': 'ts-jest', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /cdk/eks/lib/canaries/pc-visit-billings/nodejs/node_modules/pc-visit-billings.js: -------------------------------------------------------------------------------- 1 | const synthetics = require('Synthetics'); 2 | const log = require('SyntheticsLogger'); 3 | const syntheticsConfiguration = synthetics.getConfiguration(); 4 | 5 | const flowBuilderBlueprint = async function () { 6 | let url = process.env.URL + "/#!/billings"; 7 | 8 | syntheticsConfiguration.setConfig({ 9 | includeRequestHeaders: true, // Enable if headers should be displayed in HAR 10 | includeResponseHeaders: true, // Enable if headers should be displayed in HAR 11 | restrictedHeaders: [], // Value of these headers will be redacted from logs and reports 12 | restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports 13 | }); 14 | let page = await synthetics.getPage(); 15 | 16 | // Navigate to the initial url 17 | await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 120000) { 18 | await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); 19 | }); 20 | }; 21 | 22 | exports.handler = async () => { 23 | return await flowBuilderBlueprint(); 24 | }; -------------------------------------------------------------------------------- /cdk/eks/lib/canaries/pc-visit-insurances/nodejs/node_modules/pc-visit-insurances.js: -------------------------------------------------------------------------------- 1 | const synthetics = require('Synthetics'); 2 | const log = require('SyntheticsLogger'); 3 | const syntheticsConfiguration = synthetics.getConfiguration(); 4 | 5 | const flowBuilderBlueprint = async function () { 6 | let url = process.env.URL + "/#!/insurances"; 7 | 8 | syntheticsConfiguration.setConfig({ 9 | includeRequestHeaders: true, // Enable if headers should be displayed in HAR 10 | includeResponseHeaders: true, // Enable if headers should be displayed in HAR 11 | restrictedHeaders: [], // Value of these headers will be redacted from logs and reports 12 | restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports 13 | }); 14 | let page = await synthetics.getPage(); 15 | 16 | // Navigate to the initial url 17 | await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 120000) { 18 | await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); 19 | }); 20 | }; 21 | 22 | exports.handler = async () => { 23 | return await flowBuilderBlueprint(); 24 | }; -------------------------------------------------------------------------------- /cdk/eks/lib/canaries/pc-visit-vet/nodejs/node_modules/pc-visit-vet.js: -------------------------------------------------------------------------------- 1 | const synthetics = require('Synthetics'); 2 | const log = require('SyntheticsLogger'); 3 | const syntheticsConfiguration = synthetics.getConfiguration(); 4 | 5 | const flowBuilderBlueprint = async function () { 6 | let url = process.env.URL + "/#!/vets"; 7 | 8 | syntheticsConfiguration.setConfig({ 9 | includeRequestHeaders: true, // Enable if headers should be displayed in HAR 10 | includeResponseHeaders: true, // Enable if headers should be displayed in HAR 11 | restrictedHeaders: [], // Value of these headers will be redacted from logs and reports 12 | restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports 13 | }); 14 | let page = await synthetics.getPage(); 15 | 16 | // Navigate to the initial url 17 | await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 120000) { 18 | await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); 19 | }); 20 | }; 21 | 22 | exports.handler = async () => { 23 | return await flowBuilderBlueprint(); 24 | }; -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/alb-ingress/petclinic-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: petclinic-ingress 5 | annotations: 6 | alb.ingress.kubernetes.io/scheme: internet-facing 7 | alb.ingress.kubernetes.io/target-type: ip 8 | 9 | spec: 10 | ingressClassName: alb 11 | rules: 12 | - http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: pet-clinic-frontend-java 19 | port: 20 | number: 8080 21 | - path: / 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: customers-service-java 26 | port: 27 | number: 8081 28 | - path: / 29 | pathType: Prefix 30 | backend: 31 | service: 32 | name: vets-service-java 33 | port: 34 | number: 8083 35 | - path: / 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: visits-service-java 40 | port: 41 | number: 8082 42 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/db/db-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: ebs-claim 5 | namespace: namespace 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | storageClassName: ebs-sc 10 | resources: 11 | requests: 12 | storage: 100Mi 13 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/db/db-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | annotations: 7 | kompose.cmd: kompose convert -f docker-compose.yaml 8 | kompose.version: 1.31.2 (HEAD) 9 | labels: 10 | io.kompose.service: db 11 | name: db 12 | namespace: namespace 13 | spec: 14 | ports: 15 | - port: 5432 16 | selector: 17 | io.kompose.service: db 18 | status: 19 | loadBalancer: {} -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/db/storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ebs-sc 5 | namespace: namespace 6 | provisioner: ebs.csi.aws.com 7 | volumeBindingMode: WaitForFirstConsumer 8 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/k8s-nginx-ingress/nginx-alb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ingress-nginx 5 | namespace: ingress-nginx 6 | annotations: 7 | prometheus.io/port: '9113' 8 | prometheus.io/scrape: 'true' 9 | prometheus.io/scheme: http 10 | spec: 11 | type: LoadBalancer 12 | ports: 13 | - name: http 14 | port: 80 15 | targetPort: 80 16 | nodePort: 32080 17 | protocol: TCP 18 | - name: https 19 | port: 443 20 | targetPort: 443 21 | nodePort: 32081 22 | protocol: TCP 23 | - name: prometheus 24 | port: 9113 25 | targetPort: 9113 26 | selector: 27 | app: ingress-nginx 28 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/k8s-nginx-ingress/petclinc-nginx-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: petclinic-nginx-ingress 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 8 | nginx.ingress.kubernetes.io/enable-opentelemetry: "true" 9 | namespace: namespace 10 | spec: 11 | rules: 12 | - http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: pet-clinic-frontend-java 19 | port: 20 | number: 8080 21 | - path: / 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: customers-service-java 26 | port: 27 | number: 8081 28 | - path: / 29 | pathType: Prefix 30 | backend: 31 | service: 32 | name: vets-service-java 33 | port: 34 | number: 8083 35 | - path: / 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: visits-service-java 40 | port: 41 | number: 8082 42 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/mongodb/mongodb-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: mongodb-pvc-data 5 | namespace: namespace 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | storageClassName: ebs-sc-mongodb 10 | resources: 11 | requests: 12 | storage: 100Mi -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/mongodb/mongodb-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | annotations: 7 | kompose.cmd: kompose convert -f docker-compose.yaml 8 | kompose.version: 1.31.2 (HEAD) 9 | labels: 10 | io.kompose.service: mongodb 11 | name: mongodb 12 | namespace: namespace 13 | spec: 14 | ports: 15 | - port: 27017 16 | selector: 17 | io.kompose.service: mongodb 18 | status: 19 | loadBalancer: {} 20 | 21 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/mongodb/mongodb-storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ebs-sc-mongodb 5 | namespace: namespace 6 | provisioner: ebs.csi.aws.com 7 | volumeBindingMode: WaitForFirstConsumer -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/admin-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: admin-server-java 9 | name: admin-server-java 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "9090" 14 | port: 9090 15 | targetPort: 9090 16 | selector: 17 | io.kompose.service: admin-server-java 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/api-gateway-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: pet-clinic-frontend-java 9 | name: pet-clinic-frontend-java 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "8080" 14 | port: 8080 15 | targetPort: 8080 16 | selector: 17 | io.kompose.service: pet-clinic-frontend-java 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/billing-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: billing-service-python 6 | name: billing-service-python 7 | namespace: namespace 8 | spec: 9 | ports: 10 | - name: '80' 11 | port: 80 12 | targetPort: 8800 13 | selector: 14 | io.kompose.service: billing-service-python 15 | status: 16 | loadBalancer: {} 17 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/config-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: config-server 9 | name: config-server 10 | namespace: namespace 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | io.kompose.service: config-server 16 | strategy: {} 17 | template: 18 | metadata: 19 | annotations: 20 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 21 | kompose.version: 1.27.0 (b0ed6a2c9) 22 | labels: 23 | io.kompose.service: config-server 24 | spec: 25 | containers: 26 | - image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-config-server:latest 27 | securityContext: 28 | runAsNonRoot: true 29 | allowPrivilegeEscalation: false 30 | name: config-server 31 | ports: 32 | - containerPort: 8888 33 | restartPolicy: Always 34 | status: {} 35 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/config-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: config-server 9 | name: config-server 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "8888" 14 | port: 8888 15 | targetPort: 8888 16 | selector: 17 | io.kompose.service: config-server 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/customers-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: customers-service-java 9 | name: customers-service-java 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "8081" 14 | port: 8081 15 | targetPort: 8081 16 | selector: 17 | io.kompose.service: customers-service-java 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/data-persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: PersistentVolumeClaim 5 | metadata: 6 | labels: 7 | io.kompose.service: data 8 | name: data 9 | namespace: namespace 10 | spec: 11 | accessModes: 12 | - ReadWriteOnce 13 | resources: 14 | requests: 15 | storage: 100Mi 16 | status: {} -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/discovery-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: discovery-server 9 | name: discovery-server 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "8761" 14 | port: 8761 15 | targetPort: 8761 16 | selector: 17 | io.kompose.service: discovery-server 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/insurance-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: insurance-service-python 6 | name: insurance-service-python 7 | namespace: namespace 8 | spec: 9 | ports: 10 | - name: '80' 11 | port: 80 12 | targetPort: 8000 13 | selector: 14 | io.kompose.service: insurance-service-python 15 | status: 16 | loadBalancer: {} 17 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/nutrition-service-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nutrition-service-nodejs 5 | namespace: namespace 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | io.kompose.service: nutrition-service-nodejs 11 | template: 12 | metadata: 13 | labels: 14 | io.kompose.service: nutrition-service-nodejs 15 | annotations: 16 | instrumentation.opentelemetry.io/inject-nodejs: 'true' 17 | spec: 18 | serviceAccountName: visits-service-account 19 | containers: 20 | - image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/nodejs-petclinic-nutrition-service:latest 21 | name: nutrition-service-nodejs 22 | env: 23 | - name: EUREKA_SERVER_URL 24 | value: http://discovery-server:8761/eureka 25 | - name: MONGO_URI 26 | value: mongodb://admin:admin@mongodb:27017/ 27 | ports: 28 | - containerPort: 3000 29 | imagePullPolicy: Always 30 | livenessProbe: 31 | httpGet: 32 | path: /nutrition 33 | port: 3000 34 | initialDelaySeconds: 3 35 | periodSeconds: 60 36 | restartPolicy: Always 37 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/nutrition-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: nutrition-service-nodejs 6 | name: nutrition-service-nodejs 7 | namespace: namespace 8 | spec: 9 | ports: 10 | - name: '80' 11 | port: 80 12 | targetPort: 3000 13 | selector: 14 | io.kompose.service: nutrition-service-nodejs 15 | status: 16 | loadBalancer: {} 17 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/otel-collector-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: otel-collector 5 | namespace: namespace # Change to your namespace 6 | labels: 7 | app: otel-collector 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: otel-collector 13 | template: 14 | metadata: 15 | labels: 16 | app: otel-collector 17 | spec: 18 | serviceAccountName: otel-collector-service-account 19 | containers: 20 | - name: otel-collector 21 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/otel-collector:latest # Replace with your actual image 22 | imagePullPolicy: Always 23 | command: 24 | - "/otelcol" 25 | args: 26 | - "--config=/config.yaml" # Start otelcol with the config file 27 | ports: 28 | - containerPort: 4317 29 | name: otel-grpc 30 | - containerPort: 4318 31 | name: otel-http 32 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/otel-collector-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: otel-collector 5 | namespace: namespace # Ensure this matches your namespace 6 | spec: 7 | ports: 8 | - name: grpc 9 | port: 4317 10 | targetPort: 4317 11 | - name: http 12 | port: 4318 13 | targetPort: 4318 14 | selector: 15 | app: otel-collector 16 | type: ClusterIP 17 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/payment-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: payment-service-dotnet 6 | name: payment-service-dotnet 7 | namespace: namespace 8 | spec: 9 | ports: 10 | - name: "80" 11 | port: 80 12 | targetPort: 8089 13 | selector: 14 | io.kompose.service: payment-service-dotnet 15 | status: 16 | loadBalancer: {} 17 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/vets-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: vets-service-java 9 | name: vets-service-java 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "8083" 14 | port: 8083 15 | targetPort: 8083 16 | selector: 17 | io.kompose.service: vets-service-java 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/sample-app/visits-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: visits-service-java 9 | name: visits-service-java 10 | namespace: namespace 11 | spec: 12 | ports: 13 | - name: "8082" 14 | port: 8082 15 | targetPort: 8082 16 | selector: 17 | io.kompose.service: visits-service-java 18 | status: 19 | loadBalancer: {} 20 | -------------------------------------------------------------------------------- /cdk/eks/lib/manifests/traffic-generator/traffic-generator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: traffic-generator 5 | labels: 6 | app: traffic-generator 7 | namespace: namespace 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: traffic-generator 13 | template: 14 | metadata: 15 | labels: 16 | app: traffic-generator 17 | spec: 18 | containers: 19 | - name: traffic-generator 20 | image: public.ecr.aws/u8q5x3l1/traffic-generator:latest 21 | env: 22 | - name: URL 23 | value: "http://SAMPLE_APP_END_POINT" 24 | - name: HIGH_LOAD_MAX 25 | value: "1600" 26 | - name: HIGH_LOAD_MIN 27 | value: "800" 28 | - name: BURST_DELAY_MAX 29 | value: "80" 30 | - name: BURST_DELAY_MIN 31 | value: "60" 32 | - name: LOW_LOAD_MAX 33 | value: "60" 34 | - name: LOW_LOAD_MIN 35 | value: "30" 36 | -------------------------------------------------------------------------------- /cdk/eks/lib/stacks/my-application-stack.ts: -------------------------------------------------------------------------------- 1 | import { Stack } from "aws-cdk-lib"; 2 | import { Construct } from "constructs"; 3 | import { CfnApplication } from 'aws-cdk-lib/aws-servicecatalogappregistry'; 4 | 5 | export class MyApplicationStack extends Stack { 6 | public application: CfnApplication 7 | constructor(scope: Construct, id: string) { 8 | super(scope, id, {}); 9 | 10 | // Create a new Application using the L1 construct 11 | this.application = new CfnApplication(this, `PetClinic_Application`, { 12 | description: 'Created by CDK', 13 | name: `PetClinic_Application`, 14 | }); 15 | 16 | // Empty myApplication to display multiple applications 17 | new CfnApplication(this, `CustomerFeedbackApp`, { 18 | description: 'Created by CDK', 19 | name: `CustomerFeedbackApp`, 20 | }); 21 | } 22 | } -------------------------------------------------------------------------------- /cdk/eks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ec2", 3 | "version": "0.1.0", 4 | "bin": { 5 | "ec2": "bin/ec2.js" 6 | }, 7 | "engines": { 8 | "node": ">=18.0.0" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "watch": "tsc -w", 13 | "test": "jest", 14 | "cdk": "cdk" 15 | }, 16 | "devDependencies": { 17 | "@types/jest": "^29.5.14", 18 | "@types/js-yaml": "^4.0.9", 19 | "@types/node": "22.7.9", 20 | "aws-cdk": "^2.179.0", 21 | "jest": "^29.7.0", 22 | "ts-jest": "^29.2.5", 23 | "ts-node": "^10.9.2", 24 | "typescript": "~5.6.3", 25 | "@aws-cdk/lambda-layer-kubectl-v31": "^2.0.0" 26 | }, 27 | "dependencies": { 28 | "aws-cdk-lib": "2.186.0", 29 | "@aws-cdk/aws-servicecatalogappregistry": "^1.204.0", 30 | "constructs": "^10.0.0", 31 | "js-yaml": "^4.1.0", 32 | "source-map-support": "^0.5.21" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cdk/eks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["es2020", "dom"], 6 | "declaration": true, 7 | "strict": true, 8 | "noImplicitAny": true, 9 | "strictNullChecks": true, 10 | "noImplicitThis": true, 11 | "alwaysStrict": true, 12 | "noUnusedLocals": false, 13 | "noUnusedParameters": false, 14 | "noImplicitReturns": true, 15 | "noFallthroughCasesInSwitch": false, 16 | "inlineSourceMap": true, 17 | "inlineSources": true, 18 | "experimentalDecorators": true, 19 | "strictPropertyInitialization": false, 20 | "typeRoots": ["./node_modules/@types"] 21 | }, 22 | "exclude": ["node_modules", "cdk.out"] 23 | } 24 | -------------------------------------------------------------------------------- /data_test/deploy/remove_alarms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set default region 4 | REGION=${1:-us-east-1} 5 | 6 | # Delete all alarms in the region starts with APMDemoTest 7 | 8 | # Get all alarms in the region 9 | alarms=$(aws cloudwatch describe-alarms --region $REGION --alarm-name-prefix APMDemoTest --query 'MetricAlarms[].AlarmName' --output text) 10 | 11 | echo "Alarms to delete in region $REGION:" 12 | echo $alarms 13 | 14 | # Delete all alarms in the region starts with APMDemoTest 15 | aws cloudwatch delete-alarms --region $REGION --alarm-names $alarms 16 | -------------------------------------------------------------------------------- /data_test/deploy/remove_lambda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set variables 4 | LAMBDA_FUNCTION_NAME="APM_Demo_Test_Runner" 5 | AWS_REGION=${1:-us-east-1} 6 | 7 | # Ask for confirmation before deletion 8 | read -p "Are you sure you want to delete the Lambda function '$LAMBDA_FUNCTION_NAME' in region $AWS_REGION? (y/n) " -n 1 -r 9 | echo 10 | if [[ $REPLY =~ ^[Yy]$ ]] 11 | then 12 | echo "Deleting Lambda function..." 13 | aws lambda delete-function \ 14 | --function-name $LAMBDA_FUNCTION_NAME \ 15 | --region $AWS_REGION | cat 16 | 17 | if [ $? -eq 0 ]; then 18 | echo "Lambda function '$LAMBDA_FUNCTION_NAME' has been successfully deleted in region $AWS_REGION." 19 | else 20 | echo "Failed to delete Lambda function. Please check the error message above." 21 | exit 1 22 | fi 23 | else 24 | echo "Operation cancelled." 25 | fi -------------------------------------------------------------------------------- /doc/exclusion_window_demo.md: -------------------------------------------------------------------------------- 1 | # Feature Name: Application Signals SLO with exclusion windows 2 | 3 | ## Overview 4 | This demo will illustrate the new [exclusion window feature](https://aws.amazon.com/about-aws/whats-new/2025/03/slo-exclusion-time-windows-cloudwatch-application-signals/) for SLO 5 | 6 | ### Problem Solved 7 | - Allows customers to exclude planned maintenance/downtime from impacting their SLO performance 8 | 9 | ## Setup Requirements 10 | Follow the EKS setup in main [README](https://github.com/aws-observability/application-signals-demo?tab=readme-ov-file#eks-demo). 11 | 12 | ## Demo Steps 13 | 1. Go to Service and scroll down to the list of services deployed in the account. Select the `payment-service-dotnet` service. 14 | 15 | ![img.png](./imgs/exclusion_window_img_1.png) 16 | 17 | 2. Click into the selected service. View all SLOs on the `GET /owners/{ownerId:int}/pets/{petId:int}/payments` operation. 18 | 19 | ![img.png](./imgs/exclusion_window_img_2.png) 20 | 21 | 3. Adjust the time picker to include 5 PM PST to 9 AM PST and observe the demo exclusion window. Exclusion windows can be added or modified on the Edit SLO page. 22 | 23 | ![img.png](./imgs/exclusion_window_img_3.png) 24 | -------------------------------------------------------------------------------- /doc/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/img.png -------------------------------------------------------------------------------- /doc/imgs/exclusion_window_img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/exclusion_window_img_1.png -------------------------------------------------------------------------------- /doc/imgs/exclusion_window_img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/exclusion_window_img_2.png -------------------------------------------------------------------------------- /doc/imgs/exclusion_window_img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/exclusion_window_img_3.png -------------------------------------------------------------------------------- /doc/imgs/genai_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/genai_0.png -------------------------------------------------------------------------------- /doc/imgs/genai_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/genai_1.png -------------------------------------------------------------------------------- /doc/imgs/genai_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/genai_2.png -------------------------------------------------------------------------------- /doc/imgs/genai_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/genai_3.png -------------------------------------------------------------------------------- /doc/imgs/lambda_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/lambda_0.png -------------------------------------------------------------------------------- /doc/imgs/lambda_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/lambda_1.png -------------------------------------------------------------------------------- /doc/imgs/lambda_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/lambda_2.png -------------------------------------------------------------------------------- /doc/imgs/lambda_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/lambda_3.png -------------------------------------------------------------------------------- /doc/imgs/my_app_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/my_app_0.png -------------------------------------------------------------------------------- /doc/imgs/my_app_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/my_app_1.png -------------------------------------------------------------------------------- /doc/imgs/my_app_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/my_app_2.png -------------------------------------------------------------------------------- /doc/imgs/rds_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/rds_0.png -------------------------------------------------------------------------------- /doc/imgs/rds_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/rds_1.png -------------------------------------------------------------------------------- /doc/imgs/rds_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/rds_2.png -------------------------------------------------------------------------------- /doc/imgs/rds_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/rds_3.png -------------------------------------------------------------------------------- /doc/imgs/rds_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/doc/imgs/rds_4.png -------------------------------------------------------------------------------- /doc/my_application_demo.md: -------------------------------------------------------------------------------- 1 | # Feature Name: Application Signals integration with myApplications 2 | 3 | ## Overview 4 | This setup will demonstrate the integration of Application Signals with [myApplications](https://docs.aws.amazon.com/awsconsolehelpdocs/latest/gsg/aws-myApplications.html). 5 | 6 | ### Problem Solved 7 | - Provides a high level view of all resources of a customer defined application. 8 | 9 | ## Setup Requirements 10 | Follow the EKS setup in main [README](https://github.com/aws-observability/application-signals-demo?tab=readme-ov-file#eks-demo). 11 | 12 | ## Demo Steps 13 | 1. Go to Service and scroll down to the list of services deployed in the account. You will see that under the Application column, there is a link to `EksJavaDemoApp`. These services are all linked to `EksJavaDemoApp` as they are deployed to the same EKS cluster. 14 | 2. ![img.png](imgs/my_app_0.png) 15 | 2. Go to Service Level Objectives and see the list of SLOs in the account. You will now see that the SLOs are tagged to the same `EksJavaDemoApp`. 16 | 3. ![img.png](imgs/my_app_1.png) 17 | 3. When you click on the hyperlink of the `EksJavaDemoApp`, you will be taken to myApplications directly. Here, if you go into manage resources, you will see all the resources that belong under `EksJavaDemoApp`. 18 | 4. ![img.png](imgs/my_app_2.png) -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 public.ecr.aws/amazoncorretto/amazoncorretto:11 as builder 2 | WORKDIR /application 3 | ARG ARTIFACT_NAME 4 | COPY ${ARTIFACT_NAME}.jar application.jar 5 | RUN java -Djarmode=layertools -jar application.jar extract 6 | 7 | # Install wget 8 | RUN yum install -y wget tar gzip && yum clean all 9 | 10 | # Download dockerize and cache that layer 11 | ARG DOCKERIZE_VERSION 12 | RUN wget -O dockerize.tar.gz https://github.com/jwilder/dockerize/releases/download/${DOCKERIZE_VERSION}/dockerize-alpine-linux-amd64-${DOCKERIZE_VERSION}.tar.gz 13 | RUN tar xzf dockerize.tar.gz 14 | RUN chmod +x dockerize 15 | 16 | 17 | FROM public.ecr.aws/amazoncorretto/amazoncorretto:11 18 | USER 1000 19 | 20 | WORKDIR /application 21 | 22 | # Dockerize 23 | COPY --from=builder /application/dockerize ./ 24 | 25 | ARG EXPOSED_PORT 26 | EXPOSE ${EXPOSED_PORT} 27 | 28 | ENV SPRING_PROFILES_ACTIVE docker 29 | 30 | COPY --from=builder /application/dependencies/ ./ 31 | COPY --from=builder /application/spring-boot-loader/ ./ 32 | COPY --from=builder /application/snapshot-dependencies/ ./ 33 | COPY --from=builder /application/application/ ./ 34 | ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] 35 | -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:8.0 2 | WORKDIR /app 3 | 4 | COPY . . 5 | 6 | RUN dotnet restore 7 | RUN dotnet build 8 | RUN dotnet publish -c Release -o out 9 | 10 | ENV ASPNETCORE_ENVIRONMENT=Development 11 | 12 | EXPOSE 8080 13 | 14 | ENTRYPOINT [ "dotnet", "./out/PetClinic.PaymentService.dll" ] -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/Payment.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | 3 | namespace PetClinic.PaymentService; 4 | 5 | [DynamoDBTable("PetClinicPayment")] 6 | public record Payment 7 | { 8 | [DynamoDBHashKey] 9 | [DynamoDBProperty("id")] 10 | public string? Id { get; set; } 11 | 12 | [DynamoDBProperty] 13 | public int? PetId { get; set; } 14 | 15 | [DynamoDBProperty] 16 | public DateTime PaymentDate { get; set; } = DateTime.UtcNow; 17 | 18 | [DynamoDBProperty] 19 | public required double Amount { get; set; } 20 | 21 | [DynamoDBProperty] 22 | public string? Notes { get; set; } 23 | } -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/Pet.cs: -------------------------------------------------------------------------------- 1 | namespace PetClinic.PaymentService; 2 | 3 | public record Pet(int id, string name, DateTime birthDate); -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/PetClinic.PaymentService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | Linux 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:54692", 8 | "sslPort": 44357 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5279", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7047;http://localhost:5279", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "spring": { 10 | "application": { 11 | "name": "payment-service" 12 | } 13 | }, 14 | "eureka": { 15 | "client": { 16 | "serviceUrl": "http://localhost:8761/eureka/", 17 | "shouldFetchRegistry": true, 18 | "shouldRegisterWithEureka": true, 19 | "validateCertificates": false 20 | }, 21 | "instance": { 22 | "port": "8080", 23 | "ipAddress": "localhost,127.0.0.1", 24 | "preferIpAddress": true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dotnet-petclinic-payment/PetClinic.PaymentService/ec2-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | private_setup_ip_address=$1 3 | service_name=$2 4 | 5 | sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc 6 | sudo wget -O /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/37/prod.repo 7 | sudo dnf install -y dotnet-sdk-8.0 8 | dotnet --version > /tmp/dotnet-version 9 | 10 | export OTEL_RESOURCE_ATTRIBUTES=service.name=${service_name} 11 | export eureka__client__serviceUrl=http://${private_setup_ip_address}:8761/eureka/ 12 | export eureka__instance__port=8080 13 | export ASPNETCORE_URLS="http://+:8080" 14 | export ASPNETCORE_ENVIRONMENT=Development 15 | 16 | dotnet add package AWS.Distro.OpenTelemetry.AutoInstrumentation 17 | 18 | dotnet build --runtime linux-x64 19 | 20 | sed -i -e 's/\r$//' bin/Debug/net8.0/linux-x64/adot-launch.sh 21 | sh bin/Debug/net8.0/linux-x64/adot-launch.sh dotnet bin/Debug/net8.0/linux-x64/PetClinic.PaymentService.dll -v n -------------------------------------------------------------------------------- /lambda-petclinic/installDemo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | pushd sample-apps || exit 4 | rm -rf build* 5 | ./package-lambda-function.sh 6 | popd || exit 7 | 8 | pushd terraform || exit 9 | terraform init 10 | terraform apply -auto-approve 11 | popd || exit -------------------------------------------------------------------------------- /lambda-petclinic/sample-apps/function/requirements.txt: -------------------------------------------------------------------------------- 1 | requests -------------------------------------------------------------------------------- /lambda-petclinic/sample-apps/function2/requirements.txt: -------------------------------------------------------------------------------- 1 | requests -------------------------------------------------------------------------------- /lambda-petclinic/sample-apps/function3/requirements.txt: -------------------------------------------------------------------------------- 1 | requests -------------------------------------------------------------------------------- /lambda-petclinic/sample-apps/function4/requirements.txt: -------------------------------------------------------------------------------- 1 | requests -------------------------------------------------------------------------------- /lambda-petclinic/sample-apps/package-lambda-function.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p build/python 5 | python3 -m pip install -r function/requirements.txt -t build/python 6 | cp function/lambda_function.py build/python 7 | cd build/python 8 | zip -r ../function.zip ./* 9 | 10 | cd ../.. 11 | mkdir -p build2/python 12 | python3 -m pip install -r function2/requirements.txt -t build2/python 13 | cp function2/lambda_function.py build2/python 14 | cd build2/python 15 | zip -r ../function.zip ./* 16 | 17 | cd ../.. 18 | mkdir -p build3/python 19 | python3 -m pip install -r function3/requirements.txt -t build3/python 20 | cp function3/lambda_function.py build3/python 21 | cd build3/python 22 | zip -r ../function.zip ./* 23 | 24 | cd ../.. 25 | mkdir -p build4/python 26 | python3 -m pip install -r function3/requirements.txt -t build4/python 27 | cp function4/lambda_function.py build4/python 28 | cd build4/python 29 | zip -r ../function.zip ./* -------------------------------------------------------------------------------- /otel-collector/Dockerfile: -------------------------------------------------------------------------------- 1 | # Base image 2 | FROM --platform=linux/amd64 public.ecr.aws/docker/library/python:3.10 3 | 4 | # Define the build argument with a default value 5 | ARG REGION=us-east-1 6 | 7 | # Export the ARG to ENV to make it persist 8 | ENV REGION=${REGION} 9 | 10 | WORKDIR / 11 | 12 | # Debug: Print the REGION to verify it is set 13 | RUN echo "Build-time REGION=${REGION}" 14 | 15 | # Copy the built collector binary 16 | COPY otelcol-dev/otelcol-dev /otelcol 17 | 18 | # Copy the configuration file 19 | COPY customconfig.yaml /config.yaml 20 | 21 | # Update the configuration file dynamically with the region 22 | RUN sed -i "s/region: \".*\"/region: \"${REGION}\"/g" /config.yaml && \ 23 | sed -i "s|https://xray\..*\.amazonaws\.com|https://xray.${REGION}.amazonaws.com|g" /config.yaml 24 | 25 | # Debug: Verify the configuration file content 26 | RUN cat /config.yaml 27 | 28 | # Ensure the collector binary exists and is executable 29 | RUN ls -lah /otelcol && chmod +x /otelcol 30 | 31 | # Expose ports for gRPC and HTTP 32 | EXPOSE 4317 4318 33 | 34 | # Entry point for the collector 35 | ENTRYPOINT ["/otelcol"] 36 | CMD ["--config=/config.yaml"] 37 | -------------------------------------------------------------------------------- /otel-collector/builder-config.yaml: -------------------------------------------------------------------------------- 1 | dist: 2 | name: otelcol-dev 3 | description: Basic OTel Collector distribution for Developers 4 | output_path: ./otelcol-dev 5 | otelcol_version: 0.111.0 6 | 7 | extensions: 8 | - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/sigv4authextension v0.111.0 9 | 10 | exporters: 11 | - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.111.0 12 | - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.111.0 13 | - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.111.0 14 | 15 | processors: 16 | - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.111.0 17 | 18 | receivers: 19 | - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.111.0 -------------------------------------------------------------------------------- /otel-collector/customconfig.yaml: -------------------------------------------------------------------------------- 1 | receivers: 2 | otlp: 3 | protocols: 4 | grpc: 5 | endpoint: 0.0.0.0:4317 6 | http: 7 | endpoint: 0.0.0.0:4318 8 | processors: 9 | batch: 10 | 11 | exporters: 12 | debug: 13 | verbosity: detailed 14 | sampling_initial: 10 15 | sampling_thereafter: 1000 16 | otlphttp: 17 | traces_endpoint: https://xray.${REGION}.amazonaws.com/v1/traces 18 | compression: gzip 19 | auth: 20 | authenticator: sigv4auth 21 | extensions: 22 | sigv4auth: 23 | region: "${REGION}" 24 | service: "xray" 25 | 26 | service: 27 | telemetry: 28 | logs: 29 | level: "debug" 30 | extensions: [sigv4auth] 31 | pipelines: 32 | traces: 33 | receivers: [otlp] 34 | processors: [batch] 35 | exporters: [otlphttp, debug] -------------------------------------------------------------------------------- /otel-collector/ocb.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | # Variables 6 | BUILDER_CONFIG="builder-config.yaml" 7 | OCB_BINARY="ocb" 8 | OCB_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/cmd%2Fbuilder%2Fv0.111.0/ocb_0.111.0_linux_amd64" 9 | 10 | # Ensure the script is running in the correct directory 11 | if [[ ! -f "${BUILDER_CONFIG}" ]]; then 12 | echo "Error: ${BUILDER_CONFIG} not found in $(pwd)" 13 | exit 1 14 | fi 15 | 16 | # Download the OCB binary if not present 17 | if [[ ! -f "${OCB_BINARY}" ]]; then 18 | echo "Downloading OpenTelemetry Collector Builder..." 19 | wget "${OCB_URL}" -O "${OCB_BINARY}" 20 | chmod +x "${OCB_BINARY}" 21 | fi 22 | 23 | # Build the collector 24 | echo "Building OpenTelemetry Collector..." 25 | ./"${OCB_BINARY}" --config "${BUILDER_CONFIG}" 26 | 27 | echo "Collector built successfully. Output is in the 'bin' directory." 28 | -------------------------------------------------------------------------------- /pet-nutrition-service/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /pet-nutrition-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/eks-distro-build-tooling/nodejs:16 2 | 3 | WORKDIR /app 4 | COPY package*.json ./ 5 | RUN npm install --production 6 | COPY . . 7 | 8 | EXPOSE 3000 9 | ENV PORT=3000 10 | 11 | CMD ["node", "server.js"] 12 | -------------------------------------------------------------------------------- /pet-nutrition-service/db-seed.js: -------------------------------------------------------------------------------- 1 | const NutritionFact = require('./nutrition-fact'); 2 | const logger = require('pino')(); 3 | 4 | /** 5 | * Loads the nutrutionfact collection with static data. Yes this will drop 6 | * the collection if it already exists. This is just for demo purposes. 7 | */ 8 | 9 | module.exports = function(){ 10 | NutritionFact.collection.drop() 11 | .then(() => logger.info('collection dropped')) 12 | .catch(err => logger.error('error dropping collection:', err)); 13 | 14 | NutritionFact.insertMany([ 15 | { pet_type: 'cat', facts: 'High-protein, grain-free dry or wet food with real meat as the main ingredient' }, 16 | { pet_type: 'dog', facts: 'Balanced dog food with quality proteins, fats, and carbohydrates' }, 17 | { pet_type: 'lizard', facts: 'Insects, leafy greens, and calcium supplements' }, 18 | { pet_type: 'snake', facts: 'Whole prey (mice/rats) based on size' }, 19 | { pet_type: 'bird', facts: 'High-quality seeds, pellets, and fresh fruits/veggies' }, 20 | { pet_type: 'hamster', facts: 'Pellets, grains, fresh vegetables, and occasional fruits' } 21 | ]) 22 | .then(() => logger.info('collection populated')) 23 | .catch(err => logger.error('error populating collection:', err)); 24 | }; 25 | -------------------------------------------------------------------------------- /pet-nutrition-service/nutrition-fact.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const NutritionFactSchema = new mongoose.Schema({ 4 | pet_type: { type: String, required: true }, 5 | facts: { type: String, required: true } 6 | }); 7 | 8 | 9 | module.exports = mongoose.model('NutritionFact', NutritionFactSchema); 10 | 11 | -------------------------------------------------------------------------------- /pet-nutrition-service/nutrition-service-update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ ! -z "$1" ] 4 | then 5 | echo "REGION is NOT empty - $1" 6 | export REGION="$1" 7 | else 8 | echo "REGION is empty" 9 | export REGION="us-east-1" 10 | fi 11 | 12 | export ACCOUNT_ID=`aws sts get-caller-identity | jq .Account -r` 13 | export ECR_URL=${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com 14 | aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_URL} 15 | 16 | docker build -t nutrition-service . --no-cache 17 | docker tag nutrition-service:latest ${ECR_URL}/nodejs-petclinic-nutrition-service:latest 18 | docker push ${ECR_URL}/nodejs-petclinic-nutrition-service:latest 19 | 20 | kubectl delete pods -l io.kompose.service=nutrition-service-nodejs -------------------------------------------------------------------------------- /pet-nutrition-service/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pet-nutrition-service", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "Apache License", 12 | "dependencies": { 13 | "axios": "^1.7.5", 14 | "axios-retry": "^4.5.0", 15 | "dotenv": "^16.4.5", 16 | "express": "^4.21.1", 17 | "ip": "^2.0.1", 18 | "mongoose": "^8.5.3", 19 | "pino": "^9.3.2", 20 | "pino-http": "^10.2.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 public.ecr.aws/docker/library/python:3.10 2 | 3 | WORKDIR /app 4 | RUN mkdir -p /app/tmp && \ 5 | export TMPDIR=/app/tmp && \ 6 | pip install --no-cache-dir django djangorestframework boto3 py_eureka_client psycopg2 requests 7 | 8 | COPY . /app 9 | EXPOSE 8800 10 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing-service-update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ ! -z "$1" ] 4 | then 5 | echo "REGION is NOT empty - $1" 6 | export REGION="$1" 7 | else 8 | echo "REGION is empty" 9 | export REGION="us-east-1" 10 | fi 11 | 12 | export ACCOUNT_ID=`aws sts get-caller-identity | jq .Account -r` 13 | export ECR_URL=${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com 14 | aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_URL} 15 | 16 | docker build -t billing-service . --no-cache 17 | docker tag billing-service:latest ${ECR_URL}/python-petclinic-billing-service:latest 18 | docker push ${ECR_URL}/python-petclinic-billing-service:latest 19 | 20 | kubectl delete pods -l io.kompose.service=billing-service-python -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/pet_clinic_billing_service/billing_service/__init__.py -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BillingServiceConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "billing_service" 7 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.0.3 on 2024-03-30 16:05 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | initial = True 8 | 9 | dependencies = [] 10 | 11 | operations = [ 12 | migrations.CreateModel( 13 | name="Billing", 14 | fields=[ 15 | ( 16 | "id", 17 | models.BigAutoField( 18 | auto_created=True, 19 | primary_key=True, 20 | serialize=False, 21 | verbose_name="ID", 22 | ), 23 | ), 24 | ("owner_id", models.IntegerField()), 25 | ("type", models.CharField(max_length=200)), 26 | ("type_name", models.CharField(max_length=200)), 27 | ("pet_id", models.IntegerField()), 28 | ("payment", models.DecimalField(decimal_places=2, max_digits=10)), 29 | ("status", models.CharField(max_length=20)), 30 | ], 31 | options={ 32 | "unique_together": {("owner_id", "pet_id", "type")}, 33 | }, 34 | ), 35 | ] 36 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/pet_clinic_billing_service/billing_service/migrations/__init__.py -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | class Billing(models.Model): 5 | owner_id = models.IntegerField() 6 | type = models.CharField(max_length=200) 7 | type_name = models.CharField(max_length=200) 8 | pet_id = models.IntegerField() 9 | payment = models.DecimalField(max_digits=10, decimal_places=2) 10 | status = models.CharField(max_length=20) 11 | 12 | class Meta: 13 | unique_together = ('owner_id', 'pet_id', 'type') 14 | 15 | def __str__(self): 16 | return self.owner_id 17 | 18 | class CheckList(models.Model): 19 | invalid_name = models.CharField(max_length=200) 20 | 21 | class Meta: 22 | db_table = 'check_list' 23 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | from .models import Billing 3 | 4 | class BillingSerializer(serializers.ModelSerializer): 5 | class Meta: 6 | model = Billing 7 | fields = '__all__' 8 | 9 | class HealthSerializer(serializers.ModelSerializer): 10 | class Meta: 11 | fields = ['message'] -------------------------------------------------------------------------------- /pet_clinic_billing_service/billing_service/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/pet_clinic_billing_service/db.sqlite3 -------------------------------------------------------------------------------- /pet_clinic_billing_service/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault( 10 | "DJANGO_SETTINGS_MODULE", "pet_clinic_billing_service.settings" 11 | ) 12 | try: 13 | from django.core.management import execute_from_command_line 14 | except ImportError as exc: 15 | raise ImportError( 16 | "Couldn't import Django. Are you sure it's installed and " 17 | "available on your PYTHONPATH environment variable? Did you " 18 | "forget to activate a virtual environment?" 19 | ) from exc 20 | execute_from_command_line(sys.argv) 21 | 22 | 23 | if __name__ == "__main__": 24 | main() 25 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/pet_clinic_billing_service/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for pet_clinic_billing_service project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pet_clinic_billing_service.settings") 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/pet_clinic_billing_service/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for pet_clinic_billing_service project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pet_clinic_billing_service.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /pet_clinic_billing_service/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | django 3 | psycopg2 4 | djangorestframework 5 | py_eureka_client 6 | requests -------------------------------------------------------------------------------- /pet_clinic_insurance_service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 public.ecr.aws/docker/library/python:3.10 2 | 3 | WORKDIR /app 4 | RUN mkdir -p /app/tmp && \ 5 | export TMPDIR=/app/tmp && \ 6 | pip install --no-cache-dir django djangorestframework boto3 py_eureka_client psycopg2 requests opentelemetry-api 7 | 8 | COPY . /app 9 | EXPOSE 8000 10 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/pet_clinic_insurance_service/db.sqlite3 -------------------------------------------------------------------------------- /pet_clinic_insurance_service/init.sh: -------------------------------------------------------------------------------- 1 | python manage.py migrate 2 | python manage.py loaddata initial_data.json --database=default -------------------------------------------------------------------------------- /pet_clinic_insurance_service/insurance-service-update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ ! -z "$1" ] 4 | then 5 | echo "REGION is NOT empty - $1" 6 | export REGION="$1" 7 | else 8 | echo "REGION is empty" 9 | export REGION="us-east-1" 10 | fi 11 | 12 | export ACCOUNT_ID=`aws sts get-caller-identity | jq .Account -r` 13 | export ECR_URL=${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com 14 | aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_URL} 15 | 16 | docker build -t insurance-service . --no-cache 17 | docker tag insurance-service:latest ${ECR_URL}/python-petclinic-insurance-service:latest 18 | docker push ${ECR_URL}/python-petclinic-insurance-service:latest 19 | 20 | kubectl delete pods -l io.kompose.service=insurance-service-python -------------------------------------------------------------------------------- /pet_clinic_insurance_service/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault( 10 | "DJANGO_SETTINGS_MODULE", "pet_clinic_insurance_service.settings" 11 | ) 12 | try: 13 | from django.core.management import execute_from_command_line 14 | except ImportError as exc: 15 | raise ImportError( 16 | "Couldn't import Django. Are you sure it's installed and " 17 | "available on your PYTHONPATH environment variable? Did you " 18 | "forget to activate a virtual environment?" 19 | ) from exc 20 | execute_from_command_line(sys.argv) 21 | 22 | 23 | if __name__ == "__main__": 24 | main() 25 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/pet_clinic_insurance_service/__init__.py: -------------------------------------------------------------------------------- 1 | import socket 2 | from py_eureka_client import eureka_client 3 | import os 4 | 5 | # Get the local IP address 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | s.connect(("8.8.8.8", 80)) 8 | local_ip = s.getsockname()[0] 9 | s.close() 10 | insurance_service_ip = os.environ.get('INSURANCE_SERVICE_IP', local_ip) 11 | 12 | eureka_server_url = os.environ.get('EUREKA_SERVER_URL', 'localhost') 13 | # Register with Eureka 14 | eureka_client.init( 15 | eureka_server=f"http://{eureka_server_url}:8761/eureka", 16 | instance_host=insurance_service_ip, 17 | app_name="insurance-service", 18 | instance_port=8000, # Django's default port 19 | # ... other configuration options 20 | ) 21 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/pet_clinic_insurance_service/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for pet_clinic_insurance_service project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pet_clinic_insurance_service.settings") 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/pet_clinic_insurance_service/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for pet_clinic_insurance_service project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pet_clinic_insurance_service.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/readme.md: -------------------------------------------------------------------------------- 1 | 2 | ``` shell 3 | python manage.py migrate --database=postgresql 4 | python manage.py loaddata initial_data.json --database=default 5 | python manage.py loaddata initial_data.json --database=postgresql 6 | ``` -------------------------------------------------------------------------------- /pet_clinic_insurance_service/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | django 3 | psycopg2 4 | djangorestframework 5 | py_eureka_client 6 | requests -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/pet_clinic_insurance_service/service/__init__.py -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from .models import Insurance 5 | 6 | admin.site.register(Insurance) -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ServiceConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "service" 7 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/migrations/0002_alter_petinsurance_pet_id.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.0.3 on 2024-03-29 23:47 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("service", "0001_initial"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AlterField( 13 | model_name="petinsurance", 14 | name="pet_id", 15 | field=models.IntegerField(unique=True), 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/pet_clinic_insurance_service/service/migrations/__init__.py -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | class Insurance(models.Model): 5 | id = models.IntegerField 6 | name = models.CharField(max_length=200) 7 | description = models.TextField() 8 | price = models.DecimalField(max_digits=10, decimal_places=2) 9 | 10 | def __str__(self): 11 | return self.name 12 | 13 | class PetInsurance(models.Model): 14 | id = models.IntegerField 15 | pet_id = models.IntegerField(unique=True) 16 | insurance_id = models.IntegerField() 17 | insurance_name = models.CharField(max_length=200) 18 | price = models.DecimalField(max_digits=10, decimal_places=2) 19 | 20 | def __str__(self): 21 | return self.id -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | from .models import Insurance, PetInsurance 3 | 4 | class InsuranceSerializer(serializers.ModelSerializer): 5 | class Meta: 6 | model = Insurance 7 | fields = ['id', 'name', 'description', 'price'] 8 | 9 | class PetInsuranceSerializer(serializers.ModelSerializer): 10 | class Meta: 11 | model = PetInsurance 12 | fields = ['id', 'pet_id', 'insurance_id', 'insurance_name', 'price'] -------------------------------------------------------------------------------- /pet_clinic_insurance_service/service/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/canaries/policies/canary_role.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Principal": { 7 | "Service": "lambda.amazonaws.com" 8 | }, 9 | "Action": "sts:AssumeRole" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /scripts/eks/appsignals/canaries/scripts/pc-visit-billings.js: -------------------------------------------------------------------------------- 1 | const synthetics = require('Synthetics'); 2 | const log = require('SyntheticsLogger'); 3 | const syntheticsConfiguration = synthetics.getConfiguration(); 4 | 5 | const flowBuilderBlueprint = async function () { 6 | let url = process.env.URL + "/#!/billings"; 7 | 8 | syntheticsConfiguration.setConfig({ 9 | includeRequestHeaders: true, // Enable if headers should be displayed in HAR 10 | includeResponseHeaders: true, // Enable if headers should be displayed in HAR 11 | restrictedHeaders: [], // Value of these headers will be redacted from logs and reports 12 | restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports 13 | }); 14 | let page = await synthetics.getPage(); 15 | 16 | // Navigate to the initial url 17 | await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 120000) { 18 | await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); 19 | }); 20 | }; 21 | 22 | exports.handler = async () => { 23 | return await flowBuilderBlueprint(); 24 | }; -------------------------------------------------------------------------------- /scripts/eks/appsignals/canaries/scripts/pc-visit-insurances.js: -------------------------------------------------------------------------------- 1 | const synthetics = require('Synthetics'); 2 | const log = require('SyntheticsLogger'); 3 | const syntheticsConfiguration = synthetics.getConfiguration(); 4 | 5 | const flowBuilderBlueprint = async function () { 6 | let url = process.env.URL + "/#!/insurances"; 7 | 8 | syntheticsConfiguration.setConfig({ 9 | includeRequestHeaders: true, // Enable if headers should be displayed in HAR 10 | includeResponseHeaders: true, // Enable if headers should be displayed in HAR 11 | restrictedHeaders: [], // Value of these headers will be redacted from logs and reports 12 | restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports 13 | }); 14 | let page = await synthetics.getPage(); 15 | 16 | // Navigate to the initial url 17 | await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 120000) { 18 | await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); 19 | }); 20 | }; 21 | 22 | exports.handler = async () => { 23 | return await flowBuilderBlueprint(); 24 | }; -------------------------------------------------------------------------------- /scripts/eks/appsignals/canaries/scripts/pc-visit-vet.js: -------------------------------------------------------------------------------- 1 | const synthetics = require('Synthetics'); 2 | const log = require('SyntheticsLogger'); 3 | const syntheticsConfiguration = synthetics.getConfiguration(); 4 | 5 | const flowBuilderBlueprint = async function () { 6 | let url = process.env.URL + "/#!/vets"; 7 | 8 | syntheticsConfiguration.setConfig({ 9 | includeRequestHeaders: true, // Enable if headers should be displayed in HAR 10 | includeResponseHeaders: true, // Enable if headers should be displayed in HAR 11 | restrictedHeaders: [], // Value of these headers will be redacted from logs and reports 12 | restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports 13 | }); 14 | let page = await synthetics.getPage(); 15 | 16 | // Navigate to the initial url 17 | await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 120000) { 18 | await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis}); 19 | }); 20 | }; 21 | 22 | exports.handler = async () => { 23 | return await flowBuilderBlueprint(); 24 | }; -------------------------------------------------------------------------------- /scripts/eks/appsignals/clean-app-signals.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set -x 3 | 4 | # change the directory to the script location so that the relative path can work 5 | cd "$(dirname "$0")" 6 | 7 | # Set variables with provided arguments 8 | CLUSTER_NAME=$1 9 | REGION=$2 10 | NAMESPACE=${3:-default} 11 | 12 | # Check if the current context points to the new cluster in the correct region 13 | kub_config=$(kubectl config current-context) 14 | if [[ $kub_config != *"$CLUSTER_NAME"* ]] || [[ $kub_config != *"$REGION"* ]]; then 15 | echo "Your current cluster context is not set to $CLUSTER_NAME $REGION. Please switch to the correct context first before running this script" 16 | exit 1 17 | fi 18 | 19 | echo "Deleting amazon-cloudwatch-observability addon" 20 | aws eks delete-addon --cluster-name $CLUSTER_NAME --addon-name amazon-cloudwatch-observability --region $REGION 21 | 22 | echo "Deleting ServiceAccount" 23 | eksctl delete iamserviceaccount --cluster $CLUSTER_NAME --region $REGION --name cloudwatch-agent --namespace amazon-cloudwatch 24 | 25 | aws logs delete-log-group --log-group-name '/aws/application-signals/data' --region $REGION 26 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/cleanup-slo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # change the directory to the script location so that the relative path can work 4 | cd "$(dirname "$0")" 5 | 6 | REGION=$1 7 | ENDPOINT="https://application-signals.$REGION.api.aws" 8 | 9 | echo "Deleting Service Level Objectives" 10 | 11 | err=0 12 | trap 'err=1' ERR 13 | 14 | aws application-signals delete-service-level-objective --cli-input-json file://slo/inputRequest/DeleteServiceLevelObjective/deleteSlo1.json --region $REGION --endpoint $ENDPOINT --no-cli-pager 15 | aws application-signals delete-service-level-objective --cli-input-json file://slo/inputRequest/DeleteServiceLevelObjective/deleteSlo2.json --region $REGION --endpoint $ENDPOINT --no-cli-pager 16 | aws application-signals delete-service-level-objective --cli-input-json file://slo/inputRequest/DeleteServiceLevelObjective/deleteSlo3.json --region $REGION --endpoint $ENDPOINT --no-cli-pager 17 | aws application-signals delete-service-level-objective --cli-input-json file://slo/inputRequest/DeleteServiceLevelObjective/deleteSlo4.json --region $REGION --endpoint $ENDPOINT --no-cli-pager 18 | 19 | exit $err 20 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/admin-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: admin-server-java 9 | name: admin-server-java 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | io.kompose.service: admin-server-java 15 | strategy: {} 16 | template: 17 | metadata: 18 | annotations: 19 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 20 | kompose.version: 1.27.0 (b0ed6a2c9) 21 | labels: 22 | io.kompose.service: admin-server-java 23 | spec: 24 | containers: 25 | - command: 26 | - ./dockerize 27 | - -wait=tcp://discovery-server:8761 28 | - -timeout=60s 29 | - -- 30 | - java 31 | - org.springframework.boot.loader.JarLauncher 32 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-admin-server:latest 33 | securityContext: 34 | runAsNonRoot: true 35 | allowPrivilegeEscalation: false 36 | name: admin-server-java 37 | ports: 38 | - containerPort: 9090 39 | restartPolicy: Always 40 | status: {} 41 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/admin-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: admin-server-java 9 | name: admin-server-java 10 | spec: 11 | ports: 12 | - name: "9090" 13 | port: 9090 14 | targetPort: 9090 15 | selector: 16 | io.kompose.service: admin-server-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/alb-ingress/petclinic-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: petclinic-ingress 5 | annotations: 6 | alb.ingress.kubernetes.io/scheme: internet-facing 7 | alb.ingress.kubernetes.io/target-type: ip 8 | 9 | spec: 10 | ingressClassName: alb 11 | rules: 12 | - http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: pet-clinic-frontend-java 19 | port: 20 | number: 8080 21 | - path: / 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: customers-service-java 26 | port: 27 | number: 8081 28 | - path: / 29 | pathType: Prefix 30 | backend: 31 | service: 32 | name: vets-service-java 33 | port: 34 | number: 8083 35 | - path: / 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: visits-service-java 40 | port: 41 | number: 8082 42 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/api-gateway-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: pet-clinic-frontend-java 9 | name: pet-clinic-frontend-java 10 | spec: 11 | ports: 12 | - name: "8080" 13 | port: 8080 14 | targetPort: 8080 15 | selector: 16 | io.kompose.service: pet-clinic-frontend-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/billing-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: billing-service-python 6 | name: billing-service-python 7 | spec: 8 | ports: 9 | - name: '80' 10 | port: 80 11 | targetPort: 8800 12 | selector: 13 | io.kompose.service: billing-service-python 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/config-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: config-server 9 | name: config-server 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | io.kompose.service: config-server 15 | strategy: {} 16 | template: 17 | metadata: 18 | annotations: 19 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 20 | kompose.version: 1.27.0 (b0ed6a2c9) 21 | labels: 22 | io.kompose.service: config-server 23 | spec: 24 | containers: 25 | - image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-config-server:latest 26 | securityContext: 27 | runAsNonRoot: true 28 | allowPrivilegeEscalation: false 29 | name: config-server 30 | ports: 31 | - containerPort: 8888 32 | restartPolicy: Always 33 | status: {} 34 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/config-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: config-server 9 | name: config-server 10 | spec: 11 | ports: 12 | - name: "8888" 13 | port: 8888 14 | targetPort: 8888 15 | selector: 16 | io.kompose.service: config-server 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/customers-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: customers-service-java 9 | name: customers-service-java 10 | spec: 11 | ports: 12 | - name: "8081" 13 | port: 8081 14 | targetPort: 8081 15 | selector: 16 | io.kompose.service: customers-service-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/data-persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: PersistentVolumeClaim 5 | metadata: 6 | labels: 7 | io.kompose.service: data 8 | name: data 9 | spec: 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: 100Mi 15 | status: {} -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/db/db-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: ebs-claim 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: ebs-sc 9 | resources: 10 | requests: 11 | storage: 100Mi 12 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/db/db-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | annotations: 7 | kompose.cmd: kompose convert -f docker-compose.yaml 8 | kompose.version: 1.31.2 (HEAD) 9 | labels: 10 | io.kompose.service: db 11 | name: db 12 | spec: 13 | ports: 14 | - port: 5432 15 | selector: 16 | io.kompose.service: db 17 | status: 18 | loadBalancer: {} 19 | 20 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/db/storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ebs-sc 5 | provisioner: ebs.csi.aws.com 6 | volumeBindingMode: WaitForFirstConsumer 7 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/discovery-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: discovery-server 9 | name: discovery-server 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | io.kompose.service: discovery-server 15 | strategy: {} 16 | template: 17 | metadata: 18 | annotations: 19 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 20 | kompose.version: 1.27.0 (b0ed6a2c9) 21 | labels: 22 | io.kompose.service: discovery-server 23 | spec: 24 | containers: 25 | - command: 26 | - ./dockerize 27 | - -wait=tcp://config-server:8888 28 | - -timeout=60s 29 | - -- 30 | - java 31 | - org.springframework.boot.loader.JarLauncher 32 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-discovery-server:latest 33 | securityContext: 34 | runAsNonRoot: true 35 | allowPrivilegeEscalation: false 36 | name: discovery-server 37 | ports: 38 | - containerPort: 8761 39 | restartPolicy: Always 40 | status: {} 41 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/discovery-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: discovery-server 9 | name: discovery-server 10 | spec: 11 | ports: 12 | - name: "8761" 13 | port: 8761 14 | targetPort: 8761 15 | selector: 16 | io.kompose.service: discovery-server 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/insurance-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: insurance-service-python 6 | name: insurance-service-python 7 | spec: 8 | ports: 9 | - name: '80' 10 | port: 80 11 | targetPort: 8000 12 | selector: 13 | io.kompose.service: insurance-service-python 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/k8s-nginx-ingress/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ingress-nginx -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/k8s-nginx-ingress/nginx-alb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ingress-nginx 5 | namespace: ingress-nginx 6 | annotations: 7 | prometheus.io/port: '9113' 8 | prometheus.io/scrape: 'true' 9 | prometheus.io/scheme: http 10 | spec: 11 | type: LoadBalancer 12 | ports: 13 | - name: http 14 | port: 80 15 | targetPort: 80 16 | nodePort: 32080 17 | protocol: TCP 18 | - name: https 19 | port: 443 20 | targetPort: 443 21 | nodePort: 32081 22 | protocol: TCP 23 | - name: prometheus 24 | port: 9113 25 | targetPort: 9113 26 | selector: 27 | app: ingress-nginx 28 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/k8s-nginx-ingress/petclinc-nginx-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: petclinic-nginx-ingress 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 8 | nginx.ingress.kubernetes.io/enable-opentelemetry: "true" 9 | spec: 10 | rules: 11 | - http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: pet-clinic-frontend-java 18 | port: 19 | number: 8080 20 | - path: / 21 | pathType: Prefix 22 | backend: 23 | service: 24 | name: customers-service-java 25 | port: 26 | number: 8081 27 | - path: / 28 | pathType: Prefix 29 | backend: 30 | service: 31 | name: vets-service-java 32 | port: 33 | number: 8083 34 | - path: / 35 | pathType: Prefix 36 | backend: 37 | service: 38 | name: visits-service-java 39 | port: 40 | number: 8082 41 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/mongodb/mongodb-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: mongodb-pvc-data 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: ebs-sc-mongodb 9 | resources: 10 | requests: 11 | storage: 100Mi -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/mongodb/mongodb-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | annotations: 7 | kompose.cmd: kompose convert -f docker-compose.yaml 8 | kompose.version: 1.31.2 (HEAD) 9 | labels: 10 | io.kompose.service: mongodb 11 | name: mongodb 12 | spec: 13 | ports: 14 | - port: 27017 15 | selector: 16 | io.kompose.service: mongodb 17 | status: 18 | loadBalancer: {} 19 | 20 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/mongodb/mongodb-storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ebs-sc-mongodb 5 | provisioner: ebs.csi.aws.com 6 | volumeBindingMode: WaitForFirstConsumer -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/nutrition-service-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nutrition-service-nodejs 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | io.kompose.service: nutrition-service-nodejs 10 | template: 11 | metadata: 12 | labels: 13 | io.kompose.service: nutrition-service-nodejs 14 | annotations: 15 | instrumentation.opentelemetry.io/inject-nodejs: 'true' 16 | spec: 17 | serviceAccountName: visits-service-account 18 | containers: 19 | - image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/nodejs-petclinic-nutrition-service:latest 20 | name: nutrition-service-nodejs 21 | env: 22 | - name: EUREKA_SERVER_URL 23 | value: http://discovery-server:8761/eureka 24 | - name: MONGO_URI 25 | value: mongodb://admin:admin@mongodb:27017/ 26 | ports: 27 | - containerPort: 3000 28 | imagePullPolicy: Always 29 | livenessProbe: 30 | httpGet: 31 | path: /nutrition 32 | port: 3000 33 | initialDelaySeconds: 3 34 | periodSeconds: 60 35 | restartPolicy: Always 36 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/nutrition-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: nutrition-service-nodejs 6 | name: nutrition-service-nodejs 7 | spec: 8 | ports: 9 | - name: '80' 10 | port: 80 11 | targetPort: 3000 12 | selector: 13 | io.kompose.service: nutrition-service-nodejs 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/otel-collector-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: otel-collector 5 | labels: 6 | app: otel-collector 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: otel-collector 12 | template: 13 | metadata: 14 | labels: 15 | app: otel-collector 16 | spec: 17 | containers: 18 | - name: otel-collector 19 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/otel-collector:latest # Replace with your actual image 20 | imagePullPolicy: Always 21 | command: 22 | - "/otelcol" 23 | args: 24 | - "--config=/config.yaml" # Start otelcol with the config file 25 | ports: 26 | - containerPort: 4317 27 | name: otel-grpc 28 | - containerPort: 4318 29 | name: otel-http 30 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/otel-collector-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: otel-collector 5 | spec: 6 | ports: 7 | - name: grpc 8 | port: 4317 9 | targetPort: 4317 10 | - name: http 11 | port: 4318 12 | targetPort: 4318 13 | selector: 14 | app: otel-collector 15 | type: ClusterIP 16 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/payment-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: payment-service-dotnet 6 | name: payment-service-dotnet 7 | spec: 8 | ports: 9 | - name: "80" 10 | port: 80 11 | targetPort: 8089 12 | selector: 13 | io.kompose.service: payment-service-dotnet 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/traffic-generator/traffic-generator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: traffic-generator 5 | labels: 6 | app: traffic-generator 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: traffic-generator 12 | template: 13 | metadata: 14 | labels: 15 | app: traffic-generator 16 | spec: 17 | containers: 18 | - name: traffic-generator 19 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/traffic-generator:latest 20 | env: 21 | - name: URL 22 | value: "http://SAMPLE_APP_END_POINT" 23 | - name: HIGH_LOAD_MAX 24 | value: "1600" 25 | - name: HIGH_LOAD_MIN 26 | value: "800" 27 | - name: BURST_DELAY_MAX 28 | value: "80" 29 | - name: BURST_DELAY_MIN 30 | value: "60" 31 | - name: LOW_LOAD_MAX 32 | value: "60" 33 | - name: LOW_LOAD_MIN 34 | value: "30" 35 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/vets-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: vets-service-java 9 | name: vets-service-java 10 | spec: 11 | ports: 12 | - name: "8083" 13 | port: 8083 14 | targetPort: 8083 15 | selector: 16 | io.kompose.service: vets-service-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/sample-app/visits-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: visits-service-java 9 | name: visits-service-java 10 | spec: 11 | ports: 12 | - name: "8082" 13 | port: 8082 14 | targetPort: 8082 15 | selector: 16 | io.kompose.service: visits-service-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/CreateServiceLevelObjective/getOwner99Availability.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Availability for Searching an Owner", 3 | "Description": "Availability larger than 99 for Get Owner operation", 4 | "SliConfig": { 5 | "SliMetricConfig": { 6 | "KeyAttributes": "", 7 | "OperationName": "GET /api/customer/owners", 8 | "MetricType": "AVAILABILITY", 9 | "PeriodSeconds": 60 10 | }, 11 | "MetricThreshold": 99.0, 12 | "ComparisonOperator": "GreaterThan" 13 | }, 14 | "Goal": { 15 | "Interval": { 16 | "RollingInterval": { 17 | "Duration": 1, 18 | "DurationUnit": "DAY" 19 | } 20 | }, 21 | "AttainmentGoal": 99.9, 22 | "WarningThreshold": 60.0 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/CreateServiceLevelObjective/getOwnerP99Latency.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Latency for Searching an Owner", 3 | "Description": "Latency P99 less than 200 ms for Get Owner operation", 4 | "SliConfig": { 5 | "SliMetricConfig": { 6 | "KeyAttributes": "", 7 | "OperationName": "GET /api/customer/owners", 8 | "MetricType": "LATENCY", 9 | "Statistic": "p99", 10 | "PeriodSeconds": 60 11 | }, 12 | "MetricThreshold": 200.0, 13 | "ComparisonOperator": "LessThan" 14 | }, 15 | "Goal": { 16 | "Interval": { 17 | "RollingInterval": { 18 | "Duration": 1, 19 | "DurationUnit": "DAY" 20 | } 21 | }, 22 | "AttainmentGoal": 99.9, 23 | "WarningThreshold": 60.0 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/CreateServiceLevelObjective/postOwner99Availability.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Availability for Registering an Owner", 3 | "Description": "Availability larger than 99 for Post Owner operation", 4 | "SliConfig": { 5 | "SliMetricConfig": { 6 | "KeyAttributes": "", 7 | "OperationName": "POST /api/customer/owners", 8 | "MetricType": "AVAILABILITY", 9 | "PeriodSeconds": 60 10 | }, 11 | "MetricThreshold": 99.0, 12 | "ComparisonOperator": "GreaterThan" 13 | }, 14 | "Goal": { 15 | "Interval": { 16 | "RollingInterval": { 17 | "Duration": 1, 18 | "DurationUnit": "DAY" 19 | } 20 | }, 21 | "AttainmentGoal": 99.9, 22 | "WarningThreshold": 60.0 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/CreateServiceLevelObjective/postOwnerP99Latency.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Latency for Registering an Owner", 3 | "Description": "Latency P99 less than 2000 ms for Post Owner operation", 4 | "SliConfig": { 5 | "SliMetricConfig": { 6 | "KeyAttributes": "", 7 | "OperationName": "POST /api/customer/owners", 8 | "MetricType": "LATENCY", 9 | "Statistic": "p99", 10 | "PeriodSeconds": 60 11 | }, 12 | "MetricThreshold": 2000.0, 13 | "ComparisonOperator": "LessThan" 14 | }, 15 | "Goal": { 16 | "Interval": { 17 | "RollingInterval": { 18 | "Duration": 1, 19 | "DurationUnit": "DAY" 20 | } 21 | }, 22 | "AttainmentGoal": 99.9, 23 | "WarningThreshold": 60.0 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/DeleteServiceLevelObjective/deleteSlo1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": "Availability for Searching an Owner" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/DeleteServiceLevelObjective/deleteSlo2.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": "Latency for Searching an Owner" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/DeleteServiceLevelObjective/deleteSlo3.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": "Availability for Registering an Owner" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/DeleteServiceLevelObjective/deleteSlo4.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": "Latency for Registering an Owner" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/eks/appsignals/slo/inputRequest/ListServices/listServices.json: -------------------------------------------------------------------------------- 1 | { 2 | "StartTime": 1, 3 | "EndTime": 1 4 | } -------------------------------------------------------------------------------- /scripts/k8s/appsignals/allow-ecr-access.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "ecr:GetAuthorizationToken", 8 | "ecr:GetDownloadUrlForLayer", 9 | "ecr:BatchGetImage", 10 | "ecr:BatchCheckLayerAvailability", 11 | "ecr-public:DescribeRepositories" 12 | ], 13 | "Resource": "*" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/admin-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: admin-server-java 9 | name: admin-server-java 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | io.kompose.service: admin-server-java 15 | strategy: {} 16 | template: 17 | metadata: 18 | annotations: 19 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 20 | kompose.version: 1.27.0 (b0ed6a2c9) 21 | labels: 22 | io.kompose.service: admin-server-java 23 | spec: 24 | containers: 25 | - command: 26 | - ./dockerize 27 | - -wait=tcp://discovery-server:8761 28 | - -timeout=60s 29 | - -- 30 | - java 31 | - org.springframework.boot.loader.JarLauncher 32 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-admin-server:latest 33 | securityContext: 34 | runAsNonRoot: true 35 | allowPrivilegeEscalation: false 36 | name: admin-server-java 37 | ports: 38 | - containerPort: 9090 39 | restartPolicy: Always 40 | status: {} 41 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/admin-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: admin-server-java 9 | name: admin-server-java 10 | spec: 11 | ports: 12 | - name: "9090" 13 | port: 9090 14 | targetPort: 9090 15 | selector: 16 | io.kompose.service: admin-server-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/api-gateway-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: pet-clinic-frontend-java 9 | name: pet-clinic-frontend-java 10 | spec: 11 | ports: 12 | - name: "8080" 13 | port: 8080 14 | targetPort: 8080 15 | selector: 16 | io.kompose.service: pet-clinic-frontend-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/billing-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: billing-service-python 6 | name: billing-service-python 7 | spec: 8 | ports: 9 | - name: '80' 10 | port: 80 11 | targetPort: 8800 12 | selector: 13 | io.kompose.service: billing-service-python 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/config-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: config-server 9 | name: config-server 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | io.kompose.service: config-server 15 | strategy: {} 16 | template: 17 | metadata: 18 | annotations: 19 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 20 | kompose.version: 1.27.0 (b0ed6a2c9) 21 | labels: 22 | io.kompose.service: config-server 23 | spec: 24 | containers: 25 | - image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-config-server:latest 26 | securityContext: 27 | runAsNonRoot: true 28 | allowPrivilegeEscalation: false 29 | name: config-server 30 | ports: 31 | - containerPort: 8888 32 | restartPolicy: Always 33 | status: {} 34 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/config-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: config-server 9 | name: config-server 10 | spec: 11 | ports: 12 | - name: "8888" 13 | port: 8888 14 | targetPort: 8888 15 | selector: 16 | io.kompose.service: config-server 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/customers-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: customers-service-java 9 | name: customers-service-java 10 | spec: 11 | ports: 12 | - name: "8081" 13 | port: 8081 14 | targetPort: 8081 15 | selector: 16 | io.kompose.service: customers-service-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/db/db-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: data 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: ebs-sc 9 | resources: 10 | requests: 11 | storage: 1Gi -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/db/db-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | annotations: 7 | kompose.cmd: kompose convert -f docker-compose.yaml 8 | kompose.version: 1.31.2 (HEAD) 9 | labels: 10 | io.kompose.service: db 11 | name: db 12 | spec: 13 | ports: 14 | - port: 5432 15 | selector: 16 | io.kompose.service: db 17 | status: 18 | loadBalancer: {} 19 | 20 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/db/storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ebs-sc 5 | provisioner: ebs.csi.aws.com -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/discovery-server-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: discovery-server 9 | name: discovery-server 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | io.kompose.service: discovery-server 15 | strategy: {} 16 | template: 17 | metadata: 18 | annotations: 19 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 20 | kompose.version: 1.27.0 (b0ed6a2c9) 21 | labels: 22 | io.kompose.service: discovery-server 23 | spec: 24 | containers: 25 | - command: 26 | - ./dockerize 27 | - -wait=tcp://config-server:8888 28 | - -timeout=60s 29 | - -- 30 | - java 31 | - org.springframework.boot.loader.JarLauncher 32 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/springcommunity/spring-petclinic-discovery-server:latest 33 | securityContext: 34 | runAsNonRoot: true 35 | allowPrivilegeEscalation: false 36 | name: discovery-server 37 | ports: 38 | - containerPort: 8761 39 | restartPolicy: Always 40 | status: {} 41 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/discovery-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: discovery-server 9 | name: discovery-server 10 | spec: 11 | ports: 12 | - name: "8761" 13 | port: 8761 14 | targetPort: 8761 15 | selector: 16 | io.kompose.service: discovery-server 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/insurance-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: insurance-service-python 6 | name: insurance-service-python 7 | spec: 8 | ports: 9 | - name: '80' 10 | port: 80 11 | targetPort: 8000 12 | selector: 13 | io.kompose.service: insurance-service-python 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/k8s-nginx-ingress/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ingress-nginx -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/k8s-nginx-ingress/nginx-alb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ingress-nginx 5 | namespace: ingress-nginx 6 | annotations: 7 | prometheus.io/port: '9113' 8 | prometheus.io/scrape: 'true' 9 | prometheus.io/scheme: http 10 | spec: 11 | type: LoadBalancer 12 | ports: 13 | - name: http 14 | port: 80 15 | targetPort: 80 16 | nodePort: 32080 17 | protocol: TCP 18 | - name: https 19 | port: 443 20 | targetPort: 443 21 | nodePort: 32081 22 | protocol: TCP 23 | - name: prometheus 24 | port: 9113 25 | targetPort: 9113 26 | selector: 27 | app: ingress-nginx 28 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/k8s-nginx-ingress/petclinc-nginx-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: petclinic-nginx-ingress 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 8 | nginx.ingress.kubernetes.io/enable-opentelemetry: "true" 9 | spec: 10 | rules: 11 | - http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: pet-clinic-frontend-java 18 | port: 19 | number: 8080 20 | - path: / 21 | pathType: Prefix 22 | backend: 23 | service: 24 | name: customers-service-java 25 | port: 26 | number: 8081 27 | - path: / 28 | pathType: Prefix 29 | backend: 30 | service: 31 | name: vets-service-java 32 | port: 33 | number: 8083 34 | - path: / 35 | pathType: Prefix 36 | backend: 37 | service: 38 | name: visits-service-java 39 | port: 40 | number: 8082 41 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/mongodb/mongodb-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: mongodb-pvc-data 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: ebs-sc-mongodb 9 | resources: 10 | requests: 11 | storage: 100Mi -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/mongodb/mongodb-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | annotations: 7 | kompose.cmd: kompose convert -f docker-compose.yaml 8 | kompose.version: 1.31.2 (HEAD) 9 | labels: 10 | io.kompose.service: mongodb 11 | name: mongodb 12 | spec: 13 | ports: 14 | - port: 27017 15 | selector: 16 | io.kompose.service: mongodb 17 | status: 18 | loadBalancer: {} 19 | 20 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/mongodb/mongodb-storageclass.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ebs-sc-mongodb 5 | provisioner: ebs.csi.aws.com 6 | volumeBindingMode: WaitForFirstConsumer -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/nutrition-service-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nutrition-service-nodejs 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | io.kompose.service: nutrition-service-nodejs 10 | template: 11 | metadata: 12 | labels: 13 | io.kompose.service: nutrition-service-nodejs 14 | annotations: 15 | instrumentation.opentelemetry.io/inject-nodejs: 'true' 16 | spec: 17 | containers: 18 | - image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/nodejs-petclinic-nutrition-service:latest 19 | name: nutrition-service-nodejs 20 | env: 21 | - name: EUREKA_SERVER_URL 22 | value: http://discovery-server:8761/eureka 23 | - name: MONGO_URI 24 | value: mongodb://admin:admin@mongodb:27017/ 25 | ports: 26 | - containerPort: 3000 27 | imagePullPolicy: Always 28 | livenessProbe: 29 | httpGet: 30 | path: /nutrition 31 | port: 3000 32 | initialDelaySeconds: 3 33 | periodSeconds: 60 34 | restartPolicy: Always 35 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/nutrition-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: nutrition-service-nodejs 6 | name: nutrition-service-nodejs 7 | spec: 8 | ports: 9 | - name: '80' 10 | port: 80 11 | targetPort: 3000 12 | selector: 13 | io.kompose.service: nutrition-service-nodejs 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/payment-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | io.kompose.service: payment-service-dotnet 6 | name: payment-service-dotnet 7 | spec: 8 | ports: 9 | - name: "80" 10 | port: 80 11 | targetPort: 8089 12 | selector: 13 | io.kompose.service: payment-service-dotnet 14 | status: 15 | loadBalancer: {} 16 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/vets-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: vets-service-java 9 | name: vets-service-java 10 | spec: 11 | ports: 12 | - name: "8083" 13 | port: 8083 14 | targetPort: 8083 15 | selector: 16 | io.kompose.service: vets-service-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/sample-app/visits-service-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | kompose.cmd: kompose convert -f ../docker-compose-eks.yml 6 | kompose.version: 1.27.0 (b0ed6a2c9) 7 | labels: 8 | io.kompose.service: visits-service-java 9 | name: visits-service-java 10 | spec: 11 | ports: 12 | - name: "8082" 13 | port: 8082 14 | targetPort: 8082 15 | selector: 16 | io.kompose.service: visits-service-java 17 | status: 18 | loadBalancer: {} 19 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/traffic-generator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: traffic-generator 5 | labels: 6 | app: traffic-generator 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: traffic-generator 12 | template: 13 | metadata: 14 | labels: 15 | app: traffic-generator 16 | spec: 17 | containers: 18 | - name: traffic-generator 19 | image: 111122223333.dkr.ecr.us-west-2.amazonaws.com/traffic-generator:latest 20 | env: 21 | - name: URL 22 | value: "http://SAMPLE_APP_END_POINT" 23 | - name: HIGH_LOAD_MAX 24 | value: "1600" 25 | - name: HIGH_LOAD_MIN 26 | value: "800" 27 | - name: BURST_DELAY_MAX 28 | value: "80" 29 | - name: BURST_DELAY_MIN 30 | value: "60" 31 | - name: LOW_LOAD_MAX 32 | value: "60" 33 | - name: LOW_LOAD_MIN 34 | value: "30" 35 | -------------------------------------------------------------------------------- /scripts/k8s/appsignals/trust-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Principal": { 7 | "Service": "ec2.amazonaws.com" 8 | }, 9 | "Action": "sts:AssumeRole" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /scripts/opentelemetry/otel-custom-builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest AS prep 2 | RUN apk --update add ca-certificates 3 | FROM public.ecr.aws/docker/library/golang:1.23.2 AS build 4 | WORKDIR /tmp/build/ 5 | RUN go env -w GOPROXY=direct 6 | RUN curl --proto '=https' --tlsv1.2 -fL -o ocb https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/cmd%2Fbuilder%2Fv0.113.0/ocb_0.113.0_linux_amd64 7 | RUN chmod +x ocb 8 | COPY builder-config.yaml . 9 | RUN --mount=type=cache,target=/go/pkg/mod ./ocb --config builder-config.yaml 10 | FROM amazonlinux 11 | ARG USER_UID=10001 12 | USER ${USER_UID} 13 | COPY --from=prep /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 14 | COPY --from=build /tmp/build/otelcol-appsignals/otelcol-appsignals / 15 | WORKDIR / 16 | EXPOSE 4317 4318 13133 2000 4316 4315 55680 55679 17 | ENTRYPOINT ["/otelcol-appsignals"] 18 | CMD ["--config", "/etc/otel/config.yaml"] -------------------------------------------------------------------------------- /spring-petclinic-admin-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: admin-server 4 | config: 5 | import: optional:configserver:${CONFIG_SERVER_URL:http://localhost:8888/} 6 | 7 | eureka: 8 | instance: 9 | preferIpAddress: true 10 | --- 11 | spring: 12 | config: 13 | activate: 14 | on-profile: docker 15 | import: configserver:http://config-server:8888 16 | 17 | --- 18 | # Prod profile 19 | spring: 20 | config: 21 | activate: 22 | on-profile: ecs 23 | 24 | eureka: 25 | instance: 26 | ipAddress: ${ADMIN_IP:admin-server} 27 | client: 28 | serviceUrl: 29 | defaultZone: ${DISCOVERY_SERVER_URL:http://discover-server:8761/eureka/} 30 | -------------------------------------------------------------------------------- /spring-petclinic-admin-server/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/.gitignore: -------------------------------------------------------------------------------- 1 | /.apt_generated/ 2 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VetsServiceClient.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.api.application; 4 | 5 | import io.opentelemetry.api.trace.Span; 6 | import io.opentelemetry.instrumentation.annotations.WithSpan; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.samples.petclinic.api.dto.VetDetails; 9 | import org.springframework.samples.petclinic.api.utils.WellKnownAttributes; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.web.reactive.function.client.WebClient; 12 | import reactor.core.publisher.Flux; 13 | 14 | @Component 15 | @RequiredArgsConstructor 16 | public class VetsServiceClient { 17 | 18 | private final WebClient.Builder webClientBuilder; 19 | 20 | @WithSpan 21 | public Flux getVets() { 22 | return webClientBuilder.build().get() 23 | .uri("lb://vets-service/vets") 24 | .retrieve() 25 | .bodyToFlux(VetDetails.class); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/BillingDetail.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | import lombok.Data; 3 | 4 | @Data 5 | public class BillingDetail { 6 | 7 | private int id; 8 | 9 | private int owner_id; 10 | 11 | private String first_name; 12 | 13 | private String last_name; 14 | 15 | private String type; 16 | 17 | private String type_name; 18 | 19 | private int pet_id; 20 | 21 | private Float payment; 22 | 23 | private String status; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/InsuranceDetail.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | import lombok.Data; 3 | 4 | @Data 5 | public class InsuranceDetail { 6 | 7 | private int id; 8 | 9 | private String name; 10 | 11 | private String description; 12 | 13 | private float price; 14 | } 15 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/OwnerRequest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.api.dto; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class OwnerRequest { 9 | 10 | private String firstName; 11 | 12 | private String lastName; 13 | 14 | private String address; 15 | 16 | private String city; 17 | 18 | private String telephone; 19 | } 20 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PaymentAdd.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class PaymentAdd { 7 | 8 | private String id; 9 | 10 | private Double amount; 11 | 12 | private String notes; 13 | } 14 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PaymentDetail.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | 3 | import java.util.Date; 4 | import lombok.Data; 5 | 6 | import com.fasterxml.jackson.annotation.JsonFormat; 7 | 8 | @Data 9 | public class PaymentDetail { 10 | 11 | private String id; 12 | 13 | private int petId; 14 | 15 | @JsonFormat(pattern = "yyyy-MM-dd") 16 | private Date paymentDate; 17 | 18 | private Double amount; 19 | 20 | private String notes; 21 | } 22 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PetDetails.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.api.dto; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import lombok.Data; 22 | 23 | /** 24 | * @author Maciej Szarlinski 25 | */ 26 | @Data 27 | public class PetDetails { 28 | 29 | private int id; 30 | 31 | private String name; 32 | 33 | private String birthDate; 34 | 35 | private PetType type; 36 | 37 | private final List visits = new ArrayList<>(); 38 | } 39 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PetFull.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | @Data 9 | public class PetFull { 10 | private int id; 11 | 12 | private String name; 13 | 14 | private String birthDate; 15 | 16 | private PetType type; 17 | 18 | private Integer insurance_id; 19 | 20 | private String insurance_name; 21 | 22 | private Float price; 23 | 24 | private String nutritionFacts; 25 | 26 | private final List visits = new ArrayList<>(); 27 | } 28 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PetInsurance.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class 7 | PetInsurance { 8 | 9 | private Integer id; 10 | 11 | private Integer pet_id; 12 | 13 | private Integer owner_id; 14 | 15 | private Integer insurance_id; 16 | 17 | private String insurance_name; 18 | 19 | private Float price; 20 | } 21 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PetNutrition.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.api.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class 7 | PetNutrition { 8 | private String pet_type; 9 | 10 | private String facts; 11 | } 12 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PetRequest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.api.dto; 4 | 5 | import com.fasterxml.jackson.annotation.JsonFormat; 6 | import lombok.Data; 7 | 8 | import javax.validation.constraints.Size; 9 | import java.util.Date; 10 | 11 | @Data 12 | public class PetRequest { 13 | 14 | private int id; 15 | 16 | @JsonFormat(pattern = "yyyy-MM-dd") 17 | private Date birthDate; 18 | 19 | @Size(min = 1) 20 | private String name; 21 | 22 | private int typeId; 23 | } 24 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/PetType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * Modifications Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 17 | * SPDX-License-Identifier: Apache-2.0 18 | */ 19 | package org.springframework.samples.petclinic.api.dto; 20 | 21 | import lombok.Data; 22 | 23 | /** 24 | * @author Maciej Szarlinski 25 | */ 26 | @Data 27 | public class PetType { 28 | 29 | private String id; 30 | 31 | private String name; 32 | } 33 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/SpecialtyDetails.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.api.dto; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class SpecialtyDetails { 9 | 10 | private Integer id; 11 | 12 | private String name; 13 | } 14 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/VetDetails.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.api.dto; 4 | 5 | import lombok.Data; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Set; 10 | 11 | @Data 12 | public class VetDetails { 13 | 14 | private Integer id; 15 | 16 | private String firstName; 17 | 18 | private String lastName; 19 | 20 | private Set specialties; 21 | 22 | private final List pets = new ArrayList<>(); 23 | } 24 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/VisitDetails.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.api.dto; 17 | 18 | import lombok.Data; 19 | import lombok.NoArgsConstructor; 20 | 21 | /** 22 | * @author Maciej Szarlinski 23 | */ 24 | @Data 25 | @NoArgsConstructor 26 | public class VisitDetails { 27 | 28 | private Integer id = null; 29 | 30 | private Integer petId = null; 31 | 32 | private String date = null; 33 | 34 | private String description = null; 35 | } 36 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/dto/Visits.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.api.dto; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import lombok.NoArgsConstructor; 22 | import lombok.Value; 23 | 24 | /** 25 | * @author Maciej Szarlinski 26 | */ 27 | @Value 28 | public class Visits { 29 | 30 | private List items = new ArrayList<>(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/utils/WellKnownAttributes.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.api.utils; 4 | 5 | public final class WellKnownAttributes { 6 | public static final String REMOTE_APPLICATION = "aws.remote.application"; 7 | public static final String REMOTE_OPERATION = "aws.remote.operation"; 8 | 9 | public static final String OWNER_ID = "owner.id"; 10 | public static final String PET_ID = "pet.id"; 11 | public static final String ORDER_ID = "order.id"; 12 | } 13 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/less/responsive.less: -------------------------------------------------------------------------------- 1 | @media (max-width: 768px) { 2 | .navbar-toggle { 3 | position:absolute; 4 | z-index: 9999; 5 | left:0px; 6 | top:0px; 7 | } 8 | 9 | .navbar a.navbar-brand { 10 | display: block; 11 | margin: 0 auto 0 auto; 12 | width: 148px; 13 | height: 50px; 14 | float: none; 15 | background: url("../images/spring-logo-dataflow-mobile.png") 0 center no-repeat; 16 | } 17 | 18 | .homepage-billboard .homepage-subtitle { 19 | font-size: 21px; 20 | line-height: 21px; 21 | } 22 | 23 | .navbar a.navbar-brand span { 24 | display: none; 25 | } 26 | 27 | .navbar { 28 | border-top-width: 0; 29 | } 30 | 31 | .xd-container { 32 | margin-top: 20px; 33 | margin-bottom: 30px; 34 | } 35 | 36 | .index-page--subtitle { 37 | margin-top: 10px; 38 | margin-bottom: 30px; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/messages/messages.properties: -------------------------------------------------------------------------------- 1 | required=is required 2 | notFound=has not been found 3 | duplicate=is already in use 4 | nonNumeric=must be all numeric 5 | duplicateFormSubmission=Duplicate form submission is not allowed 6 | typeMismatch.date=invalid date 7 | typeMismatch.birthDate=invalid date 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/messages/messages_de.properties: -------------------------------------------------------------------------------- 1 | required=muss angegeben werden 2 | notFound=wurde nicht gefunden 3 | duplicate=ist bereits vergeben 4 | nonNumeric=darf nur numerisch sein 5 | duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt 6 | typeMismatch.date=ung�ltiges Datum 7 | typeMismatch.birthDate=ung�ltiges Datum 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/messages/messages_en.properties: -------------------------------------------------------------------------------- 1 | # This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file. -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/fonts/montserrat-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/fonts/montserrat-webfont.eot -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/fonts/montserrat-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/fonts/montserrat-webfont.ttf -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/fonts/montserrat-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/fonts/montserrat-webfont.woff -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/fonts/varela_round-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/fonts/varela_round-webfont.eot -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/fonts/varela_round-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/fonts/varela_round-webfont.ttf -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/fonts/varela_round-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/fonts/varela_round-webfont.woff -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/images/favicon.png -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/images/pets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/images/pets.png -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/images/platform-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/images/platform-bg.png -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/images/spring-logo-dataflow-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/images/spring-logo-dataflow-mobile.png -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/images/spring-logo-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/images/spring-logo-dataflow.png -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/images/spring-pivotal-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-observability/application-signals-demo/4e47a0dc0ff33d17aeaea0664492237c2430baac/spring-petclinic-api-gateway/src/main/resources/static/images/spring-pivotal-logo.png -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/billing-list/billing-list.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("billingList").component("billingList", { 4 | templateUrl: "scripts/billing-list/billing-list.template.html", 5 | controller: "BillingListController", 6 | }); 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/billing-list/billing-list.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("billingList").controller("BillingListController", [ 4 | "$http", 5 | function ($http) { 6 | var self = this; 7 | 8 | $http.get("api/billing/billings").then(function (resp) { 9 | self.billingList = resp.data; 10 | $http.get("api/customer/owners/").then(function (response){ 11 | var owners = response.data 12 | self.owners = {} 13 | for(var i = 0; i < owners.length; i++) { 14 | self.owners["" + owners[i].id] = owners[i]; 15 | } 16 | for(var i = 0; i < self.billingList.length; i++){ 17 | self.billingList[i].first_name = self.owners["" + self.billingList[i].owner_id].firstName 18 | self.billingList[i].last_name = self.owners["" + self.billingList[i].owner_id].lastName 19 | } 20 | }) 21 | 22 | }); 23 | }, 24 | ]); 25 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/billing-list/billing-list.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("billingList", ["ui.router"]).config([ 4 | "$stateProvider", 5 | function ($stateProvider) { 6 | $stateProvider.state("billings", { 7 | parent: "app", 8 | url: "/billings", 9 | template: "", 10 | }); 11 | }, 12 | ]); 13 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/billing-list/billing-list.template.html: -------------------------------------------------------------------------------- 1 |

Billing

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
NameTypeItem NamePaymentStatus
{{billing.first_name}} {{billing.last_name}}{{billing.type}}{{billing.type_name}}{{billing.payment}}{{billing.status}}
21 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/fragments/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Sponsored by Pivotal
5 |
6 |
-------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/fragments/welcome.html: -------------------------------------------------------------------------------- 1 |

Welcome to Petclinic

2 | 3 |
4 |
5 | 6 |
7 |
8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/infrastructure/httpErrorHandlingInterceptor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Global HTTP errors handler. 5 | */ 6 | angular.module('infrastructure') 7 | .factory('HttpErrorHandlingInterceptor', function () { 8 | return { 9 | responseError: function (response) { 10 | var error = response.data; 11 | if(error) { 12 | var errorAlert = document.getElementById("http-error-alert"); 13 | var errorMessage = document.getElementById("http-error-message"); 14 | var errorDescription = error.message ? error.message : error.error; 15 | errorAlert.removeAttribute("style"); 16 | errorMessage.innerHTML = `${error.status}: ${errorDescription}`; 17 | } 18 | return response; 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/infrastructure/infrastructure.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('infrastructure', []); 4 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/insurance-list/insurance-list.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("insuranceList").component("insuranceList", { 4 | templateUrl: "scripts/insurance-list/insurance-list.template.html", 5 | controller: "InsuranceListController", 6 | }); 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/insurance-list/insurance-list.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("insuranceList").controller("InsuranceListController", [ 4 | "$http", 5 | function ($http) { 6 | var self = this; 7 | 8 | $http.get("api/insurance/insurances").then(function (resp) { 9 | self.insuranceList = resp.data; 10 | }); 11 | }, 12 | ]); 13 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/insurance-list/insurance-list.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("insuranceList", ["ui.router"]).config([ 4 | "$stateProvider", 5 | function ($stateProvider) { 6 | $stateProvider.state("insurances", { 7 | parent: "app", 8 | url: "/insurances", 9 | template: "", 10 | }); 11 | }, 12 | ]); 13 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/insurance-list/insurance-list.template.html: -------------------------------------------------------------------------------- 1 |

Insurance

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
NameDescriptionCost (Per Month)
{{insurance.name}}{{insurance.description}}{{insurance.price + ' per month'}}
17 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-details/owner-details.component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerDetails') 4 | .component('ownerDetails', { 5 | templateUrl: 'scripts/owner-details/owner-details.template.html', 6 | controller: 'OwnerDetailsController' 7 | }); 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-details/owner-details.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerDetails') 4 | .controller('OwnerDetailsController', ['$http', '$stateParams', function ($http, $stateParams) { 5 | var self = this; 6 | $http.get('api/gateway/owners/' + $stateParams.ownerId).then(function (resp) { 7 | self.owner = resp.data; 8 | }).then(function (){ 9 | self.owner.pets.forEach(function(pet){ 10 | $http.get('api/insurance/pet-insurances/' + pet.id + '/').then(function(res){ 11 | pet.insurance_name = res.data.insurance_name; 12 | }).catch(function (err) { 13 | pet.insurance_name = ""; 14 | }); 15 | 16 | $http.get('api/nutrition/facts/' + pet.type.name + '/').then(function(res){ 17 | pet.nutritionFacts = res.data.facts; 18 | }).catch(function (err) { 19 | pet.nutritionFacts = ""; 20 | }); 21 | }); 22 | }); 23 | }]); 24 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-details/owner-details.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerDetails', ['ui.router']) 4 | .config(['$stateProvider', function ($stateProvider) { 5 | $stateProvider 6 | .state('ownerDetails', { 7 | parent: 'app', 8 | url: '/owners/details/:ownerId', 9 | template: '' 10 | }) 11 | }]); -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-form/owner-form.component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerForm') 4 | .component('ownerForm', { 5 | templateUrl: 'scripts/owner-form/owner-form.template.html', 6 | controller: 'OwnerFormController' 7 | }); 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-form/owner-form.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerForm') 4 | .controller('OwnerFormController', ["$http", '$state', '$stateParams', function ($http, $state, $stateParams) { 5 | var self = this; 6 | 7 | var ownerId = $stateParams.ownerId || 0; 8 | 9 | if (!ownerId) { 10 | self.owner = {}; 11 | } else { 12 | $http.get("api/customer/owners/" + ownerId).then(function (resp) { 13 | self.owner = resp.data; 14 | }); 15 | } 16 | 17 | self.submitOwnerForm = function () { 18 | var id = self.owner.id; 19 | 20 | if (id) { 21 | $http.put('api/customer/owners/' + id, self.owner).then(function () { 22 | $state.go('ownerDetails', {ownerId: ownerId}); 23 | }); 24 | } else { 25 | $http.post('api/customer/owners', self.owner).then(function () { 26 | $state.go('owners'); 27 | }); 28 | } 29 | }; 30 | }]); 31 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-form/owner-form.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerForm', ['ui.router']) 4 | .config(['$stateProvider', function ($stateProvider) { 5 | $stateProvider 6 | .state('ownerNew', { 7 | parent: 'app', 8 | url: '/owners/new', 9 | template: '' 10 | }) 11 | .state('ownerEdit', { 12 | parent: 'app', 13 | url: '/owners/:ownerId/edit', 14 | template: '' 15 | }) 16 | }]); 17 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-list/owner-list.component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerList') 4 | .component('ownerList', { 5 | templateUrl: 'scripts/owner-list/owner-list.template.html', 6 | controller: 'OwnerListController' 7 | }); 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-list/owner-list.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerList') 4 | .controller('OwnerListController', ['$http', function ($http) { 5 | var self = this; 6 | 7 | $http.get('api/customer/owners').then(function (resp) { 8 | self.owners = resp.data; 9 | }); 10 | }]); 11 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-list/owner-list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ownerList', ['ui.router']) 4 | .config(['$stateProvider', function ($stateProvider) { 5 | $stateProvider 6 | .state('owners', { 7 | parent: 'app', 8 | url: '/owners', 9 | template: '' 10 | }) 11 | }]); -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/owner-list/owner-list.template.html: -------------------------------------------------------------------------------- 1 |

Owners

2 | 3 |
4 |
5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 27 | 28 | 29 | 30 | 31 |
NameCityTelephone
22 | 23 | {{owner.firstName}} {{owner.lastName}} 24 | 25 | {{owner.city}}{{owner.telephone}}
32 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/payment-form/payment-form.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("paymentForm").component("paymentForm", { 4 | templateUrl: "scripts/payment-form/payment-form.template.html", 5 | controller: "paymentFormController", 6 | }); 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/payment-form/payment-form.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("paymentForm", ["ui.router"]).config([ 4 | "$stateProvider", 5 | function ($stateProvider) { 6 | $stateProvider.state("addPayment", { 7 | parent: "app", 8 | url: "/owners/:ownerId/pets/:petId/payments", 9 | template: "", 10 | }); 11 | $stateProvider.state("editPayment", { 12 | parent: "app", 13 | url: "/owners/:ownerId/pets/:petId/payments/:paymentId", 14 | template: "", 15 | }); 16 | }, 17 | ]); 18 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/payment-form/payment-form.template.html: -------------------------------------------------------------------------------- 1 |

Payment

2 | 3 |
4 | 5 |
6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
-------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/pet-form/pet-form.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("petForm").component("petForm", { 4 | templateUrl: "scripts/pet-form/pet-form.template.html", 5 | controller: "PetFormController", 6 | }); 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/pet-form/pet-form.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | angular.module("petForm", ["ui.router"]).config([ 4 | "$stateProvider", 5 | function ($stateProvider) { 6 | $stateProvider 7 | .state("petNew", { 8 | parent: "app", 9 | url: "/owners/:ownerId/new-pet", 10 | template: "", 11 | }) 12 | .state("petEdit", { 13 | parent: "app", 14 | url: "/owners/:ownerId/pets/:petId", 15 | template: "", 16 | }); 17 | }, 18 | ]); 19 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/vet-list/vet-list.component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('vetList') 4 | .component('vetList', { 5 | templateUrl: 'scripts/vet-list/vet-list.template.html', 6 | controller: 'VetListController' 7 | }); 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/vet-list/vet-list.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('vetList') 4 | .controller('VetListController', ['$http', function ($http) { 5 | var self = this; 6 | 7 | $http.get('api/vet/vets').then(function (resp) { 8 | self.vetList = resp.data; 9 | }); 10 | }]); 11 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/vet-list/vet-list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('vetList', ['ui.router']) 4 | .config(['$stateProvider', function ($stateProvider) { 5 | $stateProvider 6 | .state('vets', { 7 | parent: 'app', 8 | url: '/vets', 9 | template: '' 10 | }) 11 | }]); -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/vet-list/vet-list.template.html: -------------------------------------------------------------------------------- 1 |

Veterinarians

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
NameSpecialties
{{vet.firstName}} {{vet.lastName}}{{specialty.name + ' '}}
16 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/visits/visits.component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('visits') 4 | .component('visits', { 5 | templateUrl: 'scripts/visits/visits.template.html', 6 | controller: 'VisitsController' 7 | }); 8 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/visits/visits.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('visits') 4 | .controller('VisitsController', ['$http', '$state', '$stateParams', '$filter', function ($http, $state, $stateParams, $filter) { 5 | var self = this; 6 | var petId = $stateParams.petId || 0; 7 | var url = "api/visit/owners/" + ($stateParams.ownerId || 0) + "/pets/" + petId + "/visits"; 8 | self.date = new Date(); 9 | self.desc = ""; 10 | 11 | $http.get(url).then(function (resp) { 12 | self.visits = resp.data; 13 | }); 14 | 15 | self.submit = function () { 16 | var data = { 17 | date: $filter('date')(self.date, "yyyy-MM-dd"), 18 | description: self.desc 19 | }; 20 | 21 | $http.post(url, data).then(function () { 22 | $state.go('ownerDetails', { ownerId: $stateParams.ownerId }); 23 | }); 24 | }; 25 | }]); 26 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/visits/visits.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('visits', ['ui.router']) 4 | .config(['$stateProvider', function ($stateProvider) { 5 | $stateProvider 6 | .state('visits', { 7 | parent: 'app', 8 | url: '/owners/:ownerId/pets/:petId/visits', 9 | template: '' 10 | }) 11 | }]); 12 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/resources/static/scripts/visits/visits.template.html: -------------------------------------------------------------------------------- 1 |

Visits

2 | 3 |
4 | 5 |
6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 | 21 |

Previous Visits

22 | 23 | 24 | 25 | 26 | 27 |
{{v.date}}{{v.description}}
-------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/wro/wro.properties: -------------------------------------------------------------------------------- 1 | #List of preProcessors 2 | preProcessors=lessCssImport 3 | #List of postProcessors 4 | postProcessors=less4j -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/main/wro/wro.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | classpath:META-INF/resources/webjars/bootstrap/3.3.7-1/less/bootstrap.less 4 | /petclinic.less 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/test/java/org/springframework/samples/petclinic/api/ApiGatewayApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.api; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.springframework.boot.test.context.SpringBootTest; 20 | import org.springframework.test.context.ActiveProfiles; 21 | 22 | @ActiveProfiles("test") 23 | @SpringBootTest 24 | class ApiGatewayApplicationTests { 25 | 26 | @Test 27 | void contextLoads() { 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /spring-petclinic-api-gateway/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring.cloud.config.enabled: false 2 | eureka.client.enabled: false 3 | -------------------------------------------------------------------------------- /spring-petclinic-config-server/src/main/java/org/springframework/samples/petclinic/config/ConfigServerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.config; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | import org.springframework.cloud.config.server.EnableConfigServer; 21 | 22 | /** 23 | * @author Maciej Szarlinski 24 | */ 25 | @EnableConfigServer 26 | @SpringBootApplication 27 | public class ConfigServerApplication { 28 | 29 | public static void main(String[] args) { 30 | SpringApplication.run(ConfigServerApplication.class, args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-petclinic-config-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 8888 2 | spring: 3 | cloud: 4 | config: 5 | server: 6 | git: 7 | uri: https://github.com/spring-petclinic/spring-petclinic-microservices-config 8 | default-label: main 9 | # Use the File System Backend to avoid git pulling. Enable "native" profile in the Config Server. 10 | native: 11 | searchLocations: file:///${GIT_REPO} 12 | 13 | -------------------------------------------------------------------------------- /spring-petclinic-config-server/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Spring Cloud Config Server

5 |

The Spring Cloud Config Server provides an HTTP resource-based API for external yaml configuration for all the Spring Petclinic microservices

6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-petclinic-config-server/src/test/java/org/springframework/samples/petclinic/config/PetclinicConfigServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.config; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.springframework.boot.test.context.SpringBootTest; 20 | 21 | @SpringBootTest 22 | class PetclinicConfigServerApplicationTests { 23 | 24 | @Test 25 | void contextLoads() { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-petclinic-config-server/src/test/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | server: 5 | git: 6 | uri: https://github.com/spring-petclinic/spring-petclinic-microservices-config 7 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/Config.java: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.customers; 2 | 3 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.http.client.SimpleClientHttpRequestFactory; 7 | import org.springframework.web.client.RestTemplate; 8 | 9 | @Configuration 10 | public class Config { 11 | 12 | @Bean 13 | @LoadBalanced 14 | public RestTemplate getRestTemplate() { 15 | SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); 16 | factory.setConnectTimeout(2000); 17 | factory.setReadTimeout(2000); 18 | return new RestTemplate(factory); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/Util.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.customers; 4 | 5 | import com.amazonaws.util.EC2MetadataUtils; 6 | 7 | public class Util { 8 | public static final String REGION_FROM_EKS = System.getProperty("AWS_REGION") != null ? System.getProperty("AWS_REGION") 9 | : System.getenv("AWS_REGION") != null ? System.getenv("AWS_REGION") 10 | : "us-west-2"; 11 | 12 | public static final String REGION_FROM_EC2 = EC2MetadataUtils.getEC2InstanceRegion() != null ? EC2MetadataUtils.getEC2InstanceRegion() : "us-west-2"; 13 | 14 | public static class WellKnownAttributes { 15 | public static final String OWNER_ID = "owner.id"; 16 | public static final String PET_ID = "pet.id"; 17 | public static final String ORDER_ID = "order.id"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/PetNutrition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.customers.web; 17 | 18 | import lombok.Data; 19 | import org.springframework.core.style.ToStringCreator; 20 | 21 | @Data 22 | public class PetNutrition{ 23 | private String pet_type; 24 | private String facts; 25 | @Override 26 | public String toString() { 27 | return new ToStringCreator(this) 28 | .append("pet_type", this.getPet_type()) 29 | .append("facts", this.getFacts()) 30 | .toString(); 31 | } 32 | } -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/ResourceNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.customers.web; 17 | 18 | import org.springframework.http.HttpStatus; 19 | import org.springframework.web.bind.annotation.ResponseStatus; 20 | 21 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 22 | public class ResourceNotFoundException extends RuntimeException { 23 | 24 | public ResourceNotFoundException(String message) { 25 | super(message); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: customers-service 4 | config: 5 | import: optional:configserver:${CONFIG_SERVER_URL:http://localhost:8888/} 6 | 7 | eureka: 8 | instance: 9 | preferIpAddress: true 10 | client: 11 | service-url: 12 | defaultZone: ${DISCOVERY_SERVER_URL:http://localhost:8761/eureka} 13 | 14 | logging: 15 | level: 16 | root: OFF 17 | org.springframework.samples.petclinic.customers.web.PetResource: INFO 18 | org.springframework.samples.petclinic.customers.aws.SqsService: FATAL 19 | pattern: 20 | level: trace_id=%mdc{trace_id} span_id=%mdc{span_id} trace_flags=%mdc{trace_flags} %5p 21 | 22 | --- 23 | spring: 24 | config: 25 | activate: 26 | on-profile: docker 27 | import: configserver:http://config-server:8888 28 | 29 | --- 30 | # Prod profile 31 | spring: 32 | config: 33 | activate: 34 | on-profile: ecs 35 | 36 | eureka: 37 | instance: 38 | ipAddress: ${CUSTOMER_SERVICE_IP:customer-service} 39 | 40 | --- 41 | # EC2 profile 42 | spring: 43 | config: 44 | activate: 45 | on-profile: ec2 46 | 47 | eureka: 48 | instance: 49 | hostName: ${CUSTOMERS_SERVICE_IP:http://customers.demo.local} -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/resources/db/hsqldb/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE pets IF EXISTS; 2 | DROP TABLE types IF EXISTS; 3 | DROP TABLE owners IF EXISTS; 4 | 5 | CREATE TABLE types ( 6 | id INTEGER IDENTITY PRIMARY KEY, 7 | name VARCHAR(80) 8 | ); 9 | CREATE INDEX types_name ON types (name); 10 | 11 | CREATE TABLE owners ( 12 | id INTEGER IDENTITY PRIMARY KEY, 13 | first_name VARCHAR(30), 14 | last_name VARCHAR(30), 15 | address VARCHAR(255), 16 | city VARCHAR(80), 17 | telephone VARCHAR(12) 18 | ); 19 | CREATE INDEX owners_last_name ON owners (last_name); 20 | 21 | CREATE TABLE pets ( 22 | id INTEGER IDENTITY PRIMARY KEY, 23 | name VARCHAR(30), 24 | birth_date DATE, 25 | type_id INTEGER NOT NULL, 26 | owner_id INTEGER NOT NULL 27 | ); 28 | ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id); 29 | ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id); 30 | CREATE INDEX pets_name ON pets (name); 31 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/resources/db/mysql/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS petclinic; 2 | GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; 3 | 4 | USE petclinic; 5 | 6 | CREATE TABLE IF NOT EXISTS types ( 7 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 8 | name VARCHAR(80), 9 | INDEX(name) 10 | ) engine=InnoDB; 11 | 12 | CREATE TABLE IF NOT EXISTS owners ( 13 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 14 | first_name VARCHAR(30), 15 | last_name VARCHAR(30), 16 | address VARCHAR(255), 17 | city VARCHAR(80), 18 | telephone VARCHAR(20), 19 | INDEX(last_name) 20 | ) engine=InnoDB; 21 | 22 | CREATE TABLE IF NOT EXISTS pets ( 23 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 24 | name VARCHAR(30), 25 | birth_date DATE, 26 | type_id INT(4) UNSIGNED NOT NULL, 27 | owner_id INT(4) UNSIGNED NOT NULL, 28 | INDEX(name), 29 | FOREIGN KEY (owner_id) REFERENCES owners(id), 30 | FOREIGN KEY (type_id) REFERENCES types(id) 31 | ) engine=InnoDB; 32 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-petclinic-customers-service/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | enabled: false 5 | sql: 6 | init: 7 | schema-locations: classpath*:db/hsqldb/schema.sql 8 | data-locations: classpath*:db/hsqldb/data.sql 9 | jpa: 10 | hibernate: 11 | ddl-auto: none 12 | 13 | eureka: 14 | client: 15 | enabled: false 16 | 17 | logging.level.org.springframework: INFO 18 | 19 | -------------------------------------------------------------------------------- /spring-petclinic-discovery-server/src/main/java/org/springframework/samples/petclinic/discovery/DiscoveryServerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.discovery; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 21 | 22 | /** 23 | * @author Maciej Szarlinski 24 | */ 25 | @SpringBootApplication 26 | @EnableEurekaServer 27 | public class DiscoveryServerApplication { 28 | 29 | public static void main(String[] args) { 30 | SpringApplication.run(DiscoveryServerApplication.class, args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-petclinic-discovery-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: discovery-server 4 | config: 5 | import: optional:configserver:${CONFIG_SERVER_URL:http://localhost:8888/} 6 | eureka: 7 | server: 8 | enableSelfPreservation: false 9 | # Avoid some debugging logs at startup 10 | logging: 11 | level: 12 | org: 13 | springframework: 14 | boot: INFO 15 | web: INFO 16 | 17 | --- 18 | spring: 19 | config: 20 | activate: 21 | on-profile: docker 22 | import: configserver:http://config-server:8888 23 | 24 | --- 25 | # Prod profile 26 | spring: 27 | config: 28 | activate: 29 | on-profile: ecs 30 | import: configserver:${CONFIG_SERVER_URL:http://config-server:8888} -------------------------------------------------------------------------------- /spring-petclinic-discovery-server/src/test/java/org/springframework/samples/petclinic/discovery/DiscoveryServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.discovery; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.springframework.boot.test.context.SpringBootTest; 20 | 21 | @SpringBootTest 22 | class DiscoveryServerApplicationTests { 23 | 24 | @Test 25 | void contextLoads() { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/.gitignore: -------------------------------------------------------------------------------- 1 | /.apt_generated/ 2 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/java/org/springframework/samples/petclinic/vets/system/CacheConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.vets.system; 17 | 18 | import org.springframework.cache.annotation.EnableCaching; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.context.annotation.Profile; 21 | 22 | /** 23 | * Cache could be disable in unit test. 24 | * @author Maciej Szarlinski 25 | */ 26 | @Configuration 27 | @EnableCaching 28 | @Profile("production") 29 | class CacheConfig { 30 | } 31 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/java/org/springframework/samples/petclinic/vets/system/VetsProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.samples.petclinic.vets.system; 17 | 18 | import lombok.Data; 19 | 20 | import org.springframework.boot.context.properties.ConfigurationProperties; 21 | 22 | /** 23 | * Typesafe custom configuration. 24 | * 25 | * @author Maciej Szarlinski 26 | */ 27 | @Data 28 | @ConfigurationProperties(prefix = "vets") 29 | public class VetsProperties { 30 | 31 | private Cache cache; 32 | 33 | @Data 34 | public static class Cache { 35 | 36 | private int ttl; 37 | 38 | private int heapSize; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: vets-service 4 | config: 5 | import: optional:configserver:${CONFIG_SERVER_URL:http://localhost:8888/} 6 | cache: 7 | cache-names: vets 8 | profiles: 9 | active: production 10 | 11 | eureka: 12 | instance: 13 | preferIpAddress: true 14 | client: 15 | service-url: 16 | defaultZone: ${DISCOVERY_SERVER_URL:http://localhost:8761/eureka} 17 | 18 | logging: 19 | pattern: 20 | level: trace_id=%mdc{trace_id} span_id=%mdc{span_id} trace_flags=%mdc{trace_flags} %5p 21 | 22 | --- 23 | spring: 24 | config: 25 | activate: 26 | on-profile: docker 27 | import: configserver:http://config-server:8888 28 | 29 | --- 30 | # Prod profile 31 | spring: 32 | config: 33 | activate: 34 | on-profile: ecs 35 | 36 | eureka: 37 | instance: 38 | ipAddress: ${VETS_SERVICE_IP:vets-service} 39 | 40 | --- 41 | # EC2 profile 42 | spring: 43 | config: 44 | activate: 45 | on-profile: ec2 46 | 47 | eureka: 48 | instance: 49 | hostName: ${VETS_SERVICE_IP:http://vets.demo.local} -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/resources/db/hsqldb/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO vets VALUES (1, 'James', 'Carter'); 2 | INSERT INTO vets VALUES (2, 'Helen', 'Leary'); 3 | INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); 4 | INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); 5 | INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); 6 | INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); 7 | 8 | INSERT INTO specialties VALUES (1, 'radiology'); 9 | INSERT INTO specialties VALUES (2, 'surgery'); 10 | INSERT INTO specialties VALUES (3, 'dentistry'); 11 | 12 | INSERT INTO vet_specialties VALUES (2, 1); 13 | INSERT INTO vet_specialties VALUES (3, 2); 14 | INSERT INTO vet_specialties VALUES (3, 3); 15 | INSERT INTO vet_specialties VALUES (4, 2); 16 | INSERT INTO vet_specialties VALUES (5, 1); 17 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/resources/db/hsqldb/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE vet_specialties IF EXISTS; 2 | DROP TABLE vets IF EXISTS; 3 | DROP TABLE specialties IF EXISTS; 4 | 5 | CREATE TABLE vets ( 6 | id INTEGER IDENTITY PRIMARY KEY, 7 | first_name VARCHAR(30), 8 | last_name VARCHAR(30) 9 | ); 10 | CREATE INDEX vets_last_name ON vets (last_name); 11 | 12 | CREATE TABLE specialties ( 13 | id INTEGER IDENTITY PRIMARY KEY, 14 | name VARCHAR(80) 15 | ); 16 | CREATE INDEX specialties_name ON specialties (name); 17 | 18 | CREATE TABLE vet_specialties ( 19 | vet_id INTEGER NOT NULL, 20 | specialty_id INTEGER NOT NULL 21 | ); 22 | ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id); 23 | ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id); 24 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/resources/db/mysql/data.sql: -------------------------------------------------------------------------------- 1 | INSERT IGNORE INTO vets VALUES (1, 'James', 'Carter'); 2 | INSERT IGNORE INTO vets VALUES (2, 'Helen', 'Leary'); 3 | INSERT IGNORE INTO vets VALUES (3, 'Linda', 'Douglas'); 4 | INSERT IGNORE INTO vets VALUES (4, 'Rafael', 'Ortega'); 5 | INSERT IGNORE INTO vets VALUES (5, 'Henry', 'Stevens'); 6 | INSERT IGNORE INTO vets VALUES (6, 'Sharon', 'Jenkins'); 7 | 8 | INSERT IGNORE INTO specialties VALUES (1, 'radiology'); 9 | INSERT IGNORE INTO specialties VALUES (2, 'surgery'); 10 | INSERT IGNORE INTO specialties VALUES (3, 'dentistry'); 11 | 12 | INSERT IGNORE INTO vet_specialties VALUES (2, 1); 13 | INSERT IGNORE INTO vet_specialties VALUES (3, 2); 14 | INSERT IGNORE INTO vet_specialties VALUES (3, 3); 15 | INSERT IGNORE INTO vet_specialties VALUES (4, 2); 16 | INSERT IGNORE INTO vet_specialties VALUES (5, 1); 17 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/resources/db/mysql/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS petclinic; 2 | GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; 3 | 4 | USE petclinic; 5 | 6 | CREATE TABLE IF NOT EXISTS vets ( 7 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 8 | first_name VARCHAR(30), 9 | last_name VARCHAR(30), 10 | INDEX(last_name) 11 | ) engine=InnoDB; 12 | 13 | CREATE TABLE IF NOT EXISTS specialties ( 14 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 15 | name VARCHAR(80), 16 | INDEX(name) 17 | ) engine=InnoDB; 18 | 19 | CREATE TABLE IF NOT EXISTS vet_specialties ( 20 | vet_id INT(4) UNSIGNED NOT NULL, 21 | specialty_id INT(4) UNSIGNED NOT NULL, 22 | FOREIGN KEY (vet_id) REFERENCES vets(id), 23 | FOREIGN KEY (specialty_id) REFERENCES specialties(id), 24 | UNIQUE (vet_id,specialty_id) 25 | ) engine=InnoDB; 26 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-petclinic-vets-service/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | enabled: false 5 | sql: 6 | init: 7 | schema-locations: classpath*:db/hsqldb/schema.sql 8 | data-locations: classpath*:db/hsqldb/data.sql 9 | jpa: 10 | hibernate: 11 | ddl-auto: none 12 | 13 | eureka: 14 | client: 15 | enabled: false 16 | 17 | vets: 18 | cache: 19 | ttl: 10 20 | heap-size: 10 21 | -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/java/org/springframework/samples/petclinic/visits/Util.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package org.springframework.samples.petclinic.visits; 4 | 5 | import com.amazonaws.util.EC2MetadataUtils; 6 | 7 | public class Util { 8 | public static final String REGION_FROM_EKS = System.getProperty("AWS_REGION") != null ? System.getProperty("AWS_REGION") 9 | : System.getenv("AWS_REGION") != null ? System.getenv("AWS_REGION") 10 | : "us-west-2"; 11 | 12 | public static final String REGION_FROM_EC2 = EC2MetadataUtils.getEC2InstanceRegion() != null ? EC2MetadataUtils.getEC2InstanceRegion() : "us-west-2"; 13 | 14 | public static class WellKnownAttributes { 15 | public static final String OWNER_ID = "owner.id"; 16 | public static final String PET_ID = "pet.id"; 17 | public static final String ORDER_ID = "order.id"; 18 | } 19 | } -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/java/org/springframework/samples/petclinic/visits/web/InvalidDateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * Modifications Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 17 | * SPDX-License-Identifier: Apache-2.0 18 | */ 19 | package org.springframework.samples.petclinic.visits.web; 20 | import org.springframework.http.HttpStatus; 21 | import org.springframework.web.bind.annotation.ResponseStatus; 22 | 23 | @ResponseStatus(value = HttpStatus.BAD_REQUEST) 24 | public class InvalidDateException extends RuntimeException { 25 | public InvalidDateException(String message) { 26 | super(message); 27 | } 28 | } -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: visits-service 4 | config: 5 | import: optional:configserver:${CONFIG_SERVER_URL:http://localhost:8888/} 6 | 7 | eureka: 8 | instance: 9 | preferIpAddress: true 10 | client: 11 | service-url: 12 | defaultZone: ${DISCOVERY_SERVER_URL:http://localhost:8761/eureka} 13 | 14 | logging: 15 | pattern: 16 | level: trace_id=%mdc{trace_id} span_id=%mdc{span_id} trace_flags=%mdc{trace_flags} %5p 17 | 18 | --- 19 | spring: 20 | config: 21 | activate: 22 | on-profile: docker 23 | import: configserver:http://config-server:8888 24 | 25 | --- 26 | # Prod profile 27 | spring: 28 | config: 29 | activate: 30 | on-profile: ecs 31 | 32 | eureka: 33 | instance: 34 | ipAddress: ${VISITS_SERVICE_IP:visits-service} -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/resources/db/hsqldb/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO visits VALUES (1, 7, '2013-01-01', 'rabies shot'); 2 | INSERT INTO visits VALUES (2, 8, '2013-01-02', 'rabies shot'); 3 | INSERT INTO visits VALUES (3, 8, '2013-01-03', 'neutered'); 4 | INSERT INTO visits VALUES (4, 7, '2013-01-04', 'spayed'); 5 | -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/resources/db/hsqldb/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE visits IF EXISTS; 2 | 3 | CREATE TABLE visits ( 4 | id INTEGER IDENTITY PRIMARY KEY, 5 | pet_id INTEGER NOT NULL, 6 | visit_date DATE, 7 | description VARCHAR(8192) 8 | ); 9 | 10 | CREATE INDEX visits_pet_id ON visits (pet_id); 11 | -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/resources/db/mysql/data.sql: -------------------------------------------------------------------------------- 1 | INSERT IGNORE INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot'); 2 | INSERT IGNORE INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot'); 3 | INSERT IGNORE INTO visits VALUES (3, 8, '2009-06-04', 'neutered'); 4 | INSERT IGNORE INTO visits VALUES (4, 7, '2008-09-04', 'spayed'); 5 | -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/resources/db/mysql/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS petclinic; 2 | GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; 3 | 4 | USE petclinic; 5 | 6 | CREATE TABLE IF NOT EXISTS visits ( 7 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 8 | pet_id INT(4) UNSIGNED NOT NULL, 9 | visit_date DATE, 10 | description VARCHAR(8192), 11 | FOREIGN KEY (pet_id) REFERENCES pets(id) 12 | ) engine=InnoDB; 13 | -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-petclinic-visits-service/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | enabled: false 5 | sql: 6 | init: 7 | schema-locations: classpath*:db/hsqldb/schema.sql 8 | data-locations: classpath*:db/hsqldb/data.sql 9 | jpa: 10 | hibernate: 11 | ddl-auto: none 12 | 13 | eureka: 14 | client: 15 | enabled: false 16 | 17 | logging.level.org.springframework: INFO 18 | 19 | -------------------------------------------------------------------------------- /terraform/eks/alb-controller.tf: -------------------------------------------------------------------------------- 1 | module "eks-lb-controller" { 2 | #checkov:skip=CKV_AWS_111: ALB ingress controller allow no resource restriction 3 | #checkov:skip=CKV_AWS_356: ALB ingress controller resources with "*" is correct 4 | 5 | source = "git::https://github.com/DNXLabs/terraform-aws-eks-lb-controller.git?ref=266ca73d03a759b66c51d6ce619bf632c492190b" 6 | 7 | cluster_identity_oidc_issuer = module.eks.cluster_oidc_issuer_url 8 | cluster_identity_oidc_issuer_arn = module.eks.oidc_provider_arn 9 | cluster_name = var.cluster_name # helm_release.karpentermodule.eks.cluster_id 10 | # helm_chart_version = "1.4.7" 11 | depends_on = [ module.eks ] 12 | } 13 | -------------------------------------------------------------------------------- /terraform/eks/data.tf: -------------------------------------------------------------------------------- 1 | data "aws_eks_cluster_auth" "this" { 2 | name = var.cluster_name 3 | depends_on = [ module.eks ] 4 | } 5 | 6 | data "aws_partition" "current" {} 7 | data "aws_caller_identity" "current" {} 8 | -------------------------------------------------------------------------------- /terraform/eks/outputs.tf: -------------------------------------------------------------------------------- 1 | output "postgres_endpoint" { 2 | value = module.db.db_instance_endpoint 3 | } -------------------------------------------------------------------------------- /terraform/eks/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | 3 | } 4 | 5 | provider "kubernetes" { 6 | host = module.eks.cluster_endpoint 7 | cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) 8 | token = data.aws_eks_cluster_auth.this.token 9 | } 10 | 11 | provider "helm" { 12 | kubernetes { 13 | host = module.eks.cluster_endpoint 14 | cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) 15 | token = data.aws_eks_cluster_auth.this.token 16 | } 17 | debug = true 18 | } -------------------------------------------------------------------------------- /terraform/eks/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cluster_name" { 2 | default = "app-signals-demo" 3 | } 4 | 5 | variable "cloudwatch_observability_addon_version" { 6 | default = "v1.5.1-eksbuild.1" 7 | } -------------------------------------------------------------------------------- /terraform/eks/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | aws = { 4 | source = "hashicorp/aws" 5 | version = "~> 5.44.0" 6 | } 7 | kubernetes = { 8 | source = "hashicorp/kubernetes" 9 | version = "~> 2.27.0" 10 | } 11 | helm = { 12 | source = "hashicorp/helm" 13 | version = "~> 2.7.1" 14 | } 15 | } 16 | # backend "s3" { 17 | # bucket = "yagr-tfstate-log-us" 18 | # key = "tfc/observability/blog/python-apm-demo" 19 | # region = "us-east-1" 20 | # } 21 | } 22 | -------------------------------------------------------------------------------- /traffic-generator/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official lightweight Node.js 16 image. 2 | # https://hub.docker.com/_/node 3 | # FROM node:16-slim 4 | FROM public.ecr.aws/eks-distro-build-tooling/nodejs:16 5 | 6 | # Create and change to the app directory. 7 | WORKDIR /usr/src/app 8 | 9 | # Copy application dependency manifests to the container image. 10 | # A wildcard is used to ensure copying both package.json AND package-lock.json (if available). 11 | # Copying this first prevents re-running npm install on every code change. 12 | COPY package*.json ./ 13 | 14 | # Install production dependencies. 15 | # If you have native dependencies, you'll need additional tools. 16 | # For a full list of package.json changes, see: 17 | # https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md 18 | RUN npm install --only=production 19 | 20 | # Copy local code to the container image. 21 | COPY . . 22 | 23 | # Run the web service on container startup. 24 | CMD [ "node", "index.js" ] 25 | -------------------------------------------------------------------------------- /traffic-generator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "random-traffic-generator", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "axios": "^1.4.0", 13 | "node-cron": "^3.0.2" 14 | } 15 | } --------------------------------------------------------------------------------