From 28feaae451d5d9d47606416cb0fe5ece17ce64af Mon Sep 17 00:00:00 2001 From: Roni Dover Date: Sun, 14 Apr 2024 17:14:09 -0700 Subject: [PATCH] updated tests --- observability/tracing/collector-config.yaml | 39 ++++++++------- .../tracing/docker-compose.trace.yml | 50 +++++++++++-------- pom.xml | 4 ++ .../petclinic/HttpRequestResponseFilter.java | 0 .../petclinic/PetClinicApplication.java | 26 ++++++++++ .../PetVaccinationRequestMessage.java | 20 ++++++++ .../petclinic/domain/OwnerValidation.java | 46 ++++++++++++++--- .../TwoFactorAuthenticationService.java | 2 +- .../petclinic/owner/OwnerController.java | 17 ++++--- .../petclinic/owner/PetController.java | 23 +++++---- src/main/resources/application.properties | 8 ++- .../integration/OwnerControllerTests.java | 2 + .../petclinic/owner/OwnerControllerTests.java | 2 + 13 files changed, 171 insertions(+), 68 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/HttpRequestResponseFilter.java create mode 100644 src/main/java/org/springframework/samples/petclinic/adapters/PetVaccinationRequestMessage.java diff --git a/observability/tracing/collector-config.yaml b/observability/tracing/collector-config.yaml index 5bfac5722..c615f788b 100644 --- a/observability/tracing/collector-config.yaml +++ b/observability/tracing/collector-config.yaml @@ -4,11 +4,11 @@ receivers: grpc: http: -extensions: - basicauth/client: - client_auth: - username: 738734 - password: glc_eyJvIjoiOTQzMDk3IiwibiI6Im90bHAtb3RscCIsImsiOiJEWnhpNTFsZVZWMHJYcTg5MTVqODJOOEgiLCJtIjp7InIiOiJ1cyJ9fQ== +#extensions: +# basicauth/client: +# client_auth: +# username: 738734 +# password: glc_eyJvIjoiOTQzMDk3IiwibiI6Im90bHAtb3RscCIsImsiOiJEWnhpNTFsZVZWMHJYcTg5MTVqODJOOEgiLCJtIjp7InIiOiJ1cyJ9fQ== exporters: otlp/jaeger: @@ -16,15 +16,15 @@ exporters: tls: insecure: true - prometheus: - endpoint: "0.0.0.0:8889" +# prometheus: +# endpoint: "0.0.0.0:8889" - otlphttp/grafana: - endpoint: https://otlp-gateway-prod-us-east-0.grafana.net/otlp - auth: - authenticator: basicauth/client - tls: - insecure: false +# otlphttp/grafana: +# endpoint: https://otlp-gateway-prod-us-east-0.grafana.net/otlp +# auth: +# authenticator: basicauth/client +# tls: +# insecure: false otlp/digma: endpoint: ${OTLP_EXPORTER_DIGMA_COLLECTOR_API} @@ -35,13 +35,14 @@ processors: batch: service: - extensions: [basicauth/client] + #extensions: [basicauth/client] pipelines: traces: receivers: [otlp] - exporters: [otlphttp/grafana,otlp/jaeger] +# exporters: [otlphttp/grafana,otlp/jaeger] + exporters: [otlp/jaeger,otlp/digma] processors: [batch] - metrics: - receivers: [otlp] - exporters: [prometheus] - processors: [batch] \ No newline at end of file +# metrics: +# receivers: [otlp] +# exporters: [prometheus] +# processors: [batch] diff --git a/observability/tracing/docker-compose.trace.yml b/observability/tracing/docker-compose.trace.yml index 359dfd5e6..7fc1519d3 100644 --- a/observability/tracing/docker-compose.trace.yml +++ b/observability/tracing/docker-compose.trace.yml @@ -2,7 +2,7 @@ version: "3.6" services: jaeger: - image: jaegertracing/all-in-one:latest + image: jaegertracing/all-in-one:1.45.0 container_name: jaeger volumes: - badger_data:/badger @@ -12,34 +12,40 @@ services: - "16686:16686" - "14250" - "0.0.0.0:14268:14268" + command: | + --query.additional-headers "Access-Control-Allow-Origin: *" environment: - SPAN_STORAGE_TYPE=badger + - COLLECTOR_OTLP_ENABLED=true - BADGER_EPHEMERAL=false - - BADGER_SPAN_STORE_TTL=2000h - BADGER_DIRECTORY_VALUE=/badger/data - BADGER_DIRECTORY_KEY=/badger/key + - BADGER_SPAN_STORE_TTL=336h0m0s + - COLLECTOR_GRPC_PORT=5317 + - COLLECTOR_OTLP_GRPC_MAX_MESSAGE_SIZE=41943040 + restart: unless-stopped - grafana: - container_name: grafana - volumes: - - ./grafana/provisioning:/etc/grafana/provisioning - image: grafana/grafana-oss:latest - ports: - - 3000:3000 - environment: - - GF_SECURITY_ADMIN_USER=admin - - GF_SECURITY_ADMIN_PASSWORD=admin - - GF_USERS_ALLOW_SIGN_UP=false +# grafana: +# container_name: grafana +# volumes: +# - ./grafana/provisioning:/etc/grafana/provisioning +# image: grafana/grafana-oss:latest +# ports: +# - 3000:3000 +# environment: +# - GF_SECURITY_ADMIN_USER=admin +# - GF_SECURITY_ADMIN_PASSWORD=admin +# - GF_USERS_ALLOW_SIGN_UP=false - prometheus: - container_name: prometheus - image: prom/prometheus:latest - volumes: - - ./prometheus.yaml:/etc/prometheus/prometheus.yml - ports: - - "9090:9090" - extra_hosts: - - "host.docker.internal:host-gateway" +# prometheus: +# container_name: prometheus +# image: prom/prometheus:latest +# volumes: +# - ./prometheus.yaml:/etc/prometheus/prometheus.yml +# ports: +# - "9090:9090" +# extra_hosts: +# - "host.docker.internal:host-gateway" collector: image: otel/opentelemetry-collector-contrib diff --git a/pom.xml b/pom.xml index c680fa9a0..323a12e55 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,10 @@ + + org.springframework.kafka + spring-kafka + org.springframework.boot spring-boot-testcontainers diff --git a/src/main/java/org/springframework/samples/petclinic/HttpRequestResponseFilter.java b/src/main/java/org/springframework/samples/petclinic/HttpRequestResponseFilter.java new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index ac6e15030..0eb182d9b 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -16,9 +16,33 @@ package org.springframework.samples.petclinic; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.annotation.Profile; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.ContentCachingResponseWrapper; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; /** * PetClinic Spring Boot Application. @@ -35,3 +59,5 @@ public class PetClinicApplication { } } + + diff --git a/src/main/java/org/springframework/samples/petclinic/adapters/PetVaccinationRequestMessage.java b/src/main/java/org/springframework/samples/petclinic/adapters/PetVaccinationRequestMessage.java new file mode 100644 index 000000000..72ac297d2 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/adapters/PetVaccinationRequestMessage.java @@ -0,0 +1,20 @@ +package org.springframework.samples.petclinic.adapters; + +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +@Component +public class PetVaccinationRequestMessage { + + private final KafkaTemplate kafkaTemplate; + + public PetVaccinationRequestMessage(KafkaTemplate kafkaTemplate){ + + this.kafkaTemplate = kafkaTemplate; + } + public void Send(){ + //template.convertAndSend("petVaccineRequests", "Hello, world!"); + kafkaTemplate.send("petVaccineRequests","test"); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/domain/OwnerValidation.java b/src/main/java/org/springframework/samples/petclinic/domain/OwnerValidation.java index 9a0ab4c14..ba5533627 100644 --- a/src/main/java/org/springframework/samples/petclinic/domain/OwnerValidation.java +++ b/src/main/java/org/springframework/samples/petclinic/domain/OwnerValidation.java @@ -34,11 +34,12 @@ public class OwnerValidation { public void ValidateOwnerWithExternalService(Owner owner) { this.AuthServiceValidateUser(owner); + this.NewFunction(); } - @WithSpan private void NewFunction() { + // do nothing } @WithSpan @@ -52,7 +53,6 @@ public class OwnerValidation { } - // This function and classes were generated by ChatGPT @WithSpan public boolean ValidateUserAccess(String usr, String pswd, String sysCode) { @@ -93,15 +93,49 @@ public class OwnerValidation { return true; } + String usr; + String pswd; + String sysCode; + + + @WithSpan private synchronized void AuthServiceValidateUser(Owner owner) { // This is the actual Root Cause!! - try { - Thread.sleep(4200 + ThreadLocalRandom.current().nextInt(90, 1100 + 1)); + boolean vldUsr = usrValSvc.vldtUsr(usr); + if (!vldUsr) { + return; } - catch (InterruptedException e) { - throw new RuntimeException(e); + + boolean vldPswd = pwdUtils.vldtPswd(usr, pswd); + if (!vldPswd) { + return; } + + boolean vldUsrRole = roleSvc.vldtUsrRole(usr, sysCode); + if (!vldUsrRole) { + return; + } + + boolean is2FASuccess = twoFASvc.init2FA(usr); + if (!is2FASuccess) { + return; + } + + boolean is2FATokenValid = false; + int retry = 0; + while (retry < 3 && !is2FATokenValid) { + String token = twoFASvc.getTokenInput(); + is2FATokenValid = twoFASvc.vldtToken(usr, token); + retry++; + } + + if (!is2FATokenValid) { + return; + } + + return; + } @WithSpan diff --git a/src/main/java/org/springframework/samples/petclinic/domain/TwoFactorAuthenticationService.java b/src/main/java/org/springframework/samples/petclinic/domain/TwoFactorAuthenticationService.java index 87e4998ef..5cfdd4bf8 100644 --- a/src/main/java/org/springframework/samples/petclinic/domain/TwoFactorAuthenticationService.java +++ b/src/main/java/org/springframework/samples/petclinic/domain/TwoFactorAuthenticationService.java @@ -1,10 +1,10 @@ package org.springframework.samples.petclinic.domain; +import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.annotations.WithSpan; public class TwoFactorAuthenticationService { - @WithSpan public boolean init2FA(String usr) { try { Thread.sleep(400); diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index d0e7a0703..ea2e49133 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -52,6 +52,7 @@ class OwnerController { private OwnerValidation validator; public OwnerController(OwnerRepository clinicService) { + this.owners = clinicService; var otelTracer = getTracer("OwnerController"); validator = new OwnerValidation(otelTracer); @@ -79,12 +80,13 @@ class OwnerController { // } @GetMapping("/owners/new") - public String initCreationForm(Map model) { + public String initCreationForm(Map model) throws NoSuchMethodException { + + // if (model!=null){ + // throw new RuntimeException(); + // + // } -// if (model!=null){ -// throw new RuntimeException(); -// -// } Owner owner = new Owner(); validator.ValidateOwnerWithExternalService(owner); @@ -112,8 +114,8 @@ class OwnerController { } @GetMapping("/owners") - public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result, - Model model) { + public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, + BindingResult result, Model model) { validator.ValidateUserAccess("admin", "pwd", "fullaccess"); // if (owner.getLastName()!=null){ // throw new RuntimeException(); @@ -124,7 +126,6 @@ class OwnerController { owner.setLastName(""); // empty string signifies broadest possible search } - // find owners by last name Page ownersResults = findPaginatedForOwnersLastName(page, owner.getLastName()); if (ownersResults.isEmpty()) { diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java index 8437be036..374f32910 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java @@ -15,8 +15,6 @@ */ package org.springframework.samples.petclinic.owner; -import java.time.Instant; -import java.util.Arrays; import java.util.Collection; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -24,6 +22,7 @@ import java.util.concurrent.Executors; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.adapters.PetVaccinationRequestMessage; import org.springframework.samples.petclinic.domain.PetVaccinationStatusService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; @@ -51,14 +50,17 @@ class PetController implements InitializingBean { private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; private final OwnerRepository owners; + private final PetVaccinationRequestMessage vaccinationRequestMessage; @Autowired private PetVaccinationStatusService petVaccinationStatus; private ExecutorService executorService; - public PetController(OwnerRepository owners) { + public PetController(OwnerRepository owners, + PetVaccinationRequestMessage petVaccinationRequestMessage) { this.owners = owners; + this.vaccinationRequestMessage = petVaccinationRequestMessage; } @ModelAttribute("types") @@ -111,16 +113,17 @@ class PetController implements InitializingBean { this.owners.save(owner); // var pets = owner.getPets().toArray(Pet[]::new); - var petRequests = owner.getPets() - .stream() - .map(x -> new PetVaccinationStatusService.UpdateVaccineStatusRequest(owner.getId(), x.getId())) - .toList(); +// var petRequests = owner.getPets() +// .stream() +// .map(x -> new PetVaccinationStatusService.UpdateVaccineStatusRequest(owner.getId(), x.getId())) +// .toList().subList(0,1); // executorService.submit(() -> // petVaccinationStatus.updateVaccinationStatus(petRequests)).get(); - executorService.submit(() -> petVaccinationStatus.updateVaccinationStatus(petRequests)); + //executorService.submit(() -> petVaccinationStatus.updateVaccinationStatus(petRequests)); + //petVaccinationStatus.updateVaccinationStatus(petRequests.subList(0,1)); // - // BackgroundJob.enqueue(() -> - // petVaccinationStatus.updateVaccinationStatus(petRequests)); + + vaccinationRequestMessage.Send(); return "redirect:/owners/{ownerId}"; } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d35812dc3..3edd18f5d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -15,12 +15,16 @@ spring.messages.basename=messages/messages # Actuator management.endpoints.web.exposure.include=* -management.metrics.distribution.slo.http.server.requests=50ms, 100ms, 200ms, 400ms management.metrics.distribution.percentiles.http.server.requests=0.5, 0.9, 0.95, 0.99, 0.999 -management.metrics.web.server.request.autotime.percentiles=0.95 management.metrics.distribution.percentiles-histogram.http.server.requests=true +spring.rabbitmq.host=localhost +spring.rabbitmq.port=5672 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest +spring.kafka.bootstrap-servers=localhost:9092 +spring.kafka.consumer.group-id=myGroup # Logging logging.level.org.springframework=INFO # logging.level.org.springframework.web=DEBUG diff --git a/src/test/java/org/springframework/samples/petclinic/integration/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/integration/OwnerControllerTests.java index ca9ffcc77..d0af89ae7 100644 --- a/src/test/java/org/springframework/samples/petclinic/integration/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/integration/OwnerControllerTests.java @@ -104,6 +104,8 @@ class OwnerControllerTests { .statusCode(200) .body(ownerLinkMatcher, Matchers.notNullValue()); + assertThat(false).isTrue(); + } @NotNull diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 5478de154..13878d691 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -33,6 +33,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.time.LocalDate; import java.util.List; +import io.opentelemetry.api.trace.Span; import org.assertj.core.util.Lists; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -64,6 +65,7 @@ class OwnerControllerTests { private OwnerRepository owners; private Owner george() { + Owner george = new Owner(); george.setId(TEST_OWNER_ID); george.setFirstName("George");