updated tests

This commit is contained in:
Roni Dover 2024-04-14 17:14:09 -07:00
parent f4191cbbf7
commit 28feaae451
13 changed files with 171 additions and 68 deletions

View file

@ -4,11 +4,11 @@ receivers:
grpc: grpc:
http: http:
extensions: #extensions:
basicauth/client: # basicauth/client:
client_auth: # client_auth:
username: 738734 # username: 738734
password: glc_eyJvIjoiOTQzMDk3IiwibiI6Im90bHAtb3RscCIsImsiOiJEWnhpNTFsZVZWMHJYcTg5MTVqODJOOEgiLCJtIjp7InIiOiJ1cyJ9fQ== # password: glc_eyJvIjoiOTQzMDk3IiwibiI6Im90bHAtb3RscCIsImsiOiJEWnhpNTFsZVZWMHJYcTg5MTVqODJOOEgiLCJtIjp7InIiOiJ1cyJ9fQ==
exporters: exporters:
otlp/jaeger: otlp/jaeger:
@ -16,15 +16,15 @@ exporters:
tls: tls:
insecure: true insecure: true
prometheus: # prometheus:
endpoint: "0.0.0.0:8889" # endpoint: "0.0.0.0:8889"
otlphttp/grafana: # otlphttp/grafana:
endpoint: https://otlp-gateway-prod-us-east-0.grafana.net/otlp # endpoint: https://otlp-gateway-prod-us-east-0.grafana.net/otlp
auth: # auth:
authenticator: basicauth/client # authenticator: basicauth/client
tls: # tls:
insecure: false # insecure: false
otlp/digma: otlp/digma:
endpoint: ${OTLP_EXPORTER_DIGMA_COLLECTOR_API} endpoint: ${OTLP_EXPORTER_DIGMA_COLLECTOR_API}
@ -35,13 +35,14 @@ processors:
batch: batch:
service: service:
extensions: [basicauth/client] #extensions: [basicauth/client]
pipelines: pipelines:
traces: traces:
receivers: [otlp] receivers: [otlp]
exporters: [otlphttp/grafana,otlp/jaeger] # exporters: [otlphttp/grafana,otlp/jaeger]
exporters: [otlp/jaeger,otlp/digma]
processors: [batch] processors: [batch]
metrics: # metrics:
receivers: [otlp] # receivers: [otlp]
exporters: [prometheus] # exporters: [prometheus]
processors: [batch] # processors: [batch]

View file

@ -2,7 +2,7 @@ version: "3.6"
services: services:
jaeger: jaeger:
image: jaegertracing/all-in-one:latest image: jaegertracing/all-in-one:1.45.0
container_name: jaeger container_name: jaeger
volumes: volumes:
- badger_data:/badger - badger_data:/badger
@ -12,34 +12,40 @@ services:
- "16686:16686" - "16686:16686"
- "14250" - "14250"
- "0.0.0.0:14268:14268" - "0.0.0.0:14268:14268"
command: |
--query.additional-headers "Access-Control-Allow-Origin: *"
environment: environment:
- SPAN_STORAGE_TYPE=badger - SPAN_STORAGE_TYPE=badger
- COLLECTOR_OTLP_ENABLED=true
- BADGER_EPHEMERAL=false - BADGER_EPHEMERAL=false
- BADGER_SPAN_STORE_TTL=2000h
- BADGER_DIRECTORY_VALUE=/badger/data - BADGER_DIRECTORY_VALUE=/badger/data
- BADGER_DIRECTORY_KEY=/badger/key - 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: # grafana:
container_name: grafana # container_name: grafana
volumes: # volumes:
- ./grafana/provisioning:/etc/grafana/provisioning # - ./grafana/provisioning:/etc/grafana/provisioning
image: grafana/grafana-oss:latest # image: grafana/grafana-oss:latest
ports: # ports:
- 3000:3000 # - 3000:3000
environment: # environment:
- GF_SECURITY_ADMIN_USER=admin # - GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin # - GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false # - GF_USERS_ALLOW_SIGN_UP=false
prometheus: # prometheus:
container_name: prometheus # container_name: prometheus
image: prom/prometheus:latest # image: prom/prometheus:latest
volumes: # volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml # - ./prometheus.yaml:/etc/prometheus/prometheus.yml
ports: # ports:
- "9090:9090" # - "9090:9090"
extra_hosts: # extra_hosts:
- "host.docker.internal:host-gateway" # - "host.docker.internal:host-gateway"
collector: collector:
image: otel/opentelemetry-collector-contrib image: otel/opentelemetry-collector-contrib

View file

@ -38,6 +38,10 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId> <artifactId>spring-boot-testcontainers</artifactId>

View file

@ -16,9 +16,33 @@
package org.springframework.samples.petclinic; 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.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportRuntimeHints; 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. * PetClinic Spring Boot Application.
@ -35,3 +59,5 @@ public class PetClinicApplication {
} }
} }

View file

@ -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<String, String> kafkaTemplate;
public PetVaccinationRequestMessage(KafkaTemplate<String, String> kafkaTemplate){
this.kafkaTemplate = kafkaTemplate;
}
public void Send(){
//template.convertAndSend("petVaccineRequests", "Hello, world!");
kafkaTemplate.send("petVaccineRequests","test");
}
}

View file

@ -34,11 +34,12 @@ public class OwnerValidation {
public void ValidateOwnerWithExternalService(Owner owner) { public void ValidateOwnerWithExternalService(Owner owner) {
this.AuthServiceValidateUser(owner); this.AuthServiceValidateUser(owner);
this.NewFunction();
} }
@WithSpan
private void NewFunction() { private void NewFunction() {
// do nothing
} }
@WithSpan @WithSpan
@ -52,7 +53,6 @@ public class OwnerValidation {
} }
// This function and classes were generated by ChatGPT // This function and classes were generated by ChatGPT
@WithSpan @WithSpan
public boolean ValidateUserAccess(String usr, String pswd, String sysCode) { public boolean ValidateUserAccess(String usr, String pswd, String sysCode) {
@ -93,15 +93,49 @@ public class OwnerValidation {
return true; return true;
} }
String usr;
String pswd;
String sysCode;
@WithSpan @WithSpan
private synchronized void AuthServiceValidateUser(Owner owner) { private synchronized void AuthServiceValidateUser(Owner owner) {
// This is the actual Root Cause!! // This is the actual Root Cause!!
try { boolean vldUsr = usrValSvc.vldtUsr(usr);
Thread.sleep(4200 + ThreadLocalRandom.current().nextInt(90, 1100 + 1)); 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 @WithSpan

View file

@ -1,10 +1,10 @@
package org.springframework.samples.petclinic.domain; package org.springframework.samples.petclinic.domain;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.annotations.WithSpan; import io.opentelemetry.instrumentation.annotations.WithSpan;
public class TwoFactorAuthenticationService { public class TwoFactorAuthenticationService {
@WithSpan
public boolean init2FA(String usr) { public boolean init2FA(String usr) {
try { try {
Thread.sleep(400); Thread.sleep(400);

View file

@ -52,6 +52,7 @@ class OwnerController {
private OwnerValidation validator; private OwnerValidation validator;
public OwnerController(OwnerRepository clinicService) { public OwnerController(OwnerRepository clinicService) {
this.owners = clinicService; this.owners = clinicService;
var otelTracer = getTracer("OwnerController"); var otelTracer = getTracer("OwnerController");
validator = new OwnerValidation(otelTracer); validator = new OwnerValidation(otelTracer);
@ -79,12 +80,13 @@ class OwnerController {
// } // }
@GetMapping("/owners/new") @GetMapping("/owners/new")
public String initCreationForm(Map<String, Object> model) { public String initCreationForm(Map<String, Object> model) throws NoSuchMethodException {
// if (model!=null){
// throw new RuntimeException();
//
// }
// if (model!=null){
// throw new RuntimeException();
//
// }
Owner owner = new Owner(); Owner owner = new Owner();
validator.ValidateOwnerWithExternalService(owner); validator.ValidateOwnerWithExternalService(owner);
@ -112,8 +114,8 @@ class OwnerController {
} }
@GetMapping("/owners") @GetMapping("/owners")
public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result, public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner,
Model model) { BindingResult result, Model model) {
validator.ValidateUserAccess("admin", "pwd", "fullaccess"); validator.ValidateUserAccess("admin", "pwd", "fullaccess");
// if (owner.getLastName()!=null){ // if (owner.getLastName()!=null){
// throw new RuntimeException(); // throw new RuntimeException();
@ -124,7 +126,6 @@ class OwnerController {
owner.setLastName(""); // empty string signifies broadest possible search owner.setLastName(""); // empty string signifies broadest possible search
} }
// find owners by last name // find owners by last name
Page<Owner> ownersResults = findPaginatedForOwnersLastName(page, owner.getLastName()); Page<Owner> ownersResults = findPaginatedForOwnersLastName(page, owner.getLastName());
if (ownersResults.isEmpty()) { if (ownersResults.isEmpty()) {

View file

@ -15,8 +15,6 @@
*/ */
package org.springframework.samples.petclinic.owner; package org.springframework.samples.petclinic.owner;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; 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.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.samples.petclinic.adapters.PetVaccinationRequestMessage;
import org.springframework.samples.petclinic.domain.PetVaccinationStatusService; import org.springframework.samples.petclinic.domain.PetVaccinationStatusService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; 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 static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
private final OwnerRepository owners; private final OwnerRepository owners;
private final PetVaccinationRequestMessage vaccinationRequestMessage;
@Autowired @Autowired
private PetVaccinationStatusService petVaccinationStatus; private PetVaccinationStatusService petVaccinationStatus;
private ExecutorService executorService; private ExecutorService executorService;
public PetController(OwnerRepository owners) { public PetController(OwnerRepository owners,
PetVaccinationRequestMessage petVaccinationRequestMessage) {
this.owners = owners; this.owners = owners;
this.vaccinationRequestMessage = petVaccinationRequestMessage;
} }
@ModelAttribute("types") @ModelAttribute("types")
@ -111,16 +113,17 @@ class PetController implements InitializingBean {
this.owners.save(owner); this.owners.save(owner);
// var pets = owner.getPets().toArray(Pet[]::new); // var pets = owner.getPets().toArray(Pet[]::new);
var petRequests = owner.getPets() // var petRequests = owner.getPets()
.stream() // .stream()
.map(x -> new PetVaccinationStatusService.UpdateVaccineStatusRequest(owner.getId(), x.getId())) // .map(x -> new PetVaccinationStatusService.UpdateVaccineStatusRequest(owner.getId(), x.getId()))
.toList(); // .toList().subList(0,1);
// executorService.submit(() -> // executorService.submit(() ->
// petVaccinationStatus.updateVaccinationStatus(petRequests)).get(); // 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}"; return "redirect:/owners/{ownerId}";
} }

View file

@ -15,12 +15,16 @@ spring.messages.basename=messages/messages
# Actuator # Actuator
management.endpoints.web.exposure.include=* 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.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 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
logging.level.org.springframework=INFO logging.level.org.springframework=INFO
# logging.level.org.springframework.web=DEBUG # logging.level.org.springframework.web=DEBUG

View file

@ -104,6 +104,8 @@ class OwnerControllerTests {
.statusCode(200) .statusCode(200)
.body(ownerLinkMatcher, Matchers.notNullValue()); .body(ownerLinkMatcher, Matchers.notNullValue());
assertThat(false).isTrue();
} }
@NotNull @NotNull

View file

@ -33,6 +33,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import io.opentelemetry.api.trace.Span;
import org.assertj.core.util.Lists; import org.assertj.core.util.Lists;
import org.hamcrest.BaseMatcher; import org.hamcrest.BaseMatcher;
import org.hamcrest.Description; import org.hamcrest.Description;
@ -64,6 +65,7 @@ class OwnerControllerTests {
private OwnerRepository owners; private OwnerRepository owners;
private Owner george() { private Owner george() {
Owner george = new Owner(); Owner george = new Owner();
george.setId(TEST_OWNER_ID); george.setId(TEST_OWNER_ID);
george.setFirstName("George"); george.setFirstName("George");