This commit is contained in:
Roni Dover 2023-10-04 11:22:03 +02:00
parent 0e5c72d5ec
commit bfec3b0cd5
10 changed files with 122 additions and 62 deletions

View file

@ -11,6 +11,10 @@ extensions:
password: glc_eyJvIjoiOTQzMDk3IiwibiI6Im90bHAtb3RscCIsImsiOiJEWnhpNTFsZVZWMHJYcTg5MTVqODJOOEgiLCJtIjp7InIiOiJ1cyJ9fQ== password: glc_eyJvIjoiOTQzMDk3IiwibiI6Im90bHAtb3RscCIsImsiOiJEWnhpNTFsZVZWMHJYcTg5MTVqODJOOEgiLCJtIjp7InIiOiJ1cyJ9fQ==
exporters: exporters:
otlp/jaeger:
endpoint: "jaeger:4320"
tls:
insecure: true
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:
@ -31,5 +35,5 @@ service:
pipelines: pipelines:
traces: traces:
receivers: [otlp] receivers: [otlp]
exporters: [otlphttp/grafana,otlp/digma] exporters: [otlphttp/grafana,otlp/digma,otlp/jaeger]
processors: [batch] processors: [batch]

View file

@ -1,6 +1,21 @@
version: "3.6" version: "3.6"
services: services:
jaeger:
image: jaegertracing/all-in-one:latest
container_name: jaeger
volumes:
- badger_data:/badger
ports:
- "16686:16686"
- "14250"
- "0.0.0.0:14268:14268"
environment:
- SPAN_STORAGE_TYPE=badger
- BADGER_EPHEMERAL=false
- BADGER_SPAN_STORE_TTL=2000h
- BADGER_DIRECTORY_VALUE=/badger/data
- BADGER_DIRECTORY_KEY=/badger/key
collector: collector:
image: otel/opentelemetry-collector-contrib image: otel/opentelemetry-collector-contrib
@ -8,10 +23,12 @@ services:
volumes: volumes:
- ./collector-config.yaml:/otel-local-config.yaml - ./collector-config.yaml:/otel-local-config.yaml
ports: ports:
- "0.0.0.0:4317:4317" # OTLP receiver - "0.0.0.0:4318:4318" # HTTP OTLP receiver
- "0.0.0.0:8889:8889" # METRICS - "0.0.0.0:8889:8889" # METRICS
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
depends_on:
- jaeger
environment: environment:
- OTLP_EXPORTER_DIGMA_COLLECTOR_API=host.docker.internal:5050 - OTLP_EXPORTER_DIGMA_COLLECTOR_API=host.docker.internal:5050

33
pom.xml
View file

@ -40,14 +40,10 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.jobrunr</groupId> <groupId>org.jobrunr</groupId>
<artifactId>jobrunr-spring-boot-3-starter</artifactId> <artifactId>jobrunr-pro-spring-boot-3-starter</artifactId>
<version>6.3.0</version> <version>6.3.1</version>
</dependency> </dependency>
<!-- Spring and Spring Boot dependencies --> <!-- Spring and Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId> <artifactId>spring-boot-starter-cache</artifactId>
@ -111,11 +107,6 @@
<artifactId>postgresql</artifactId> <artifactId>postgresql</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
<!-- caching --> <!-- caching -->
<dependency> <dependency>
<groupId>javax.cache</groupId> <groupId>javax.cache</groupId>
@ -168,6 +159,22 @@
<artifactId>android-json</artifactId> <artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version> <version>0.0.20131108.vaadin1</version>
</dependency> </dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<version>1.26.0</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>io.github.digma-ai</groupId>
<artifactId>digma-spring-boot-micrometer-tracing-autoconf</artifactId>
<version>0.7.4</version>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
@ -313,6 +320,10 @@
<enabled>false</enabled> <enabled>false</enabled>
</snapshots> </snapshots>
</repository> </repository>
<repository>
<id>JobRunrPro</id>
<url>https://repo.jobrunr.io/private-trials-202310/</url>
</repository>
</repositories> </repositories>
<pluginRepositories> <pluginRepositories>

View file

@ -53,6 +53,7 @@ public class OwnerValidation {
} }
// This function and classes were generated by ChatGPT // This function and classes were generated by ChatGPT
@WithSpan
public boolean ValidateUserAccess(String usr, String pswd, String sysCode) { public boolean ValidateUserAccess(String usr, String pswd, String sysCode) {
UserNameMustStartWithR(usr); UserNameMustStartWithR(usr);
@ -162,8 +163,41 @@ public class OwnerValidation {
} }
} }
@WithSpan public boolean PerformValidationFlow(String usr, String pswd, String sysCode) {
public void PerformValidationFlow(Owner owner) { UserNameMustStartWithR(usr);
boolean vldUsr = usrValSvc.vldtUsr(usr);
if (!vldUsr) {
return false;
}
boolean vldPswd = pwdUtils.vldtPswd(usr, pswd);
if (!vldPswd) {
return false;
}
boolean vldUsrRole = roleSvc.vldtUsrRole(usr, sysCode);
if (!vldUsrRole) {
return false;
}
boolean is2FASuccess = twoFASvc.init2FA(usr);
if (!is2FASuccess) {
return false;
}
boolean is2FATokenValid = false;
int retry = 0;
while (retry < 3 && !is2FATokenValid) {
String token = twoFASvc.getTokenInput();
is2FATokenValid = twoFASvc.vldtToken(usr, token);
retry++;
}
if (!is2FATokenValid) {
return false;
}
return true;
} }

View file

@ -15,15 +15,10 @@ public class PasswordUtils {
return true; return true;
} }
@WithSpan
public String encPswd(String pswd) { public String encPswd(String pswd) {
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
return ""; return "";
} }
} }

View file

@ -1,6 +1,7 @@
package org.springframework.samples.petclinic.domain; package org.springframework.samples.petclinic.domain;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.instrumentation.annotations.WithSpan; import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.json.JSONException; import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,19 +20,24 @@ import java.util.List;
@Component @Component
public class PetVaccinationStatusService { public class PetVaccinationStatusService {
public record UpdateVaccineStatusRequest(int ownerId, int petId) {
}
@Autowired @Autowired
private OwnerRepository ownerRepositorys; private OwnerRepository ownerRepositorys;
@Autowired @Autowired
private PetVaccinationService adapter; private PetVaccinationService adapter;
@WithSpan @WithSpan
public void updateVaccinationStatus(List<Integer> petIds) { public void updateVaccinationStatus(List<UpdateVaccineStatusRequest> updateVaccineStatusRequests) {
for (Integer petId : petIds) { for (UpdateVaccineStatusRequest request : updateVaccineStatusRequests) {
var pet = ownerRepositorys.findById(petId).getPet(petId); var owner = ownerRepositorys.findById(request.ownerId);
var pet = owner.getPet(request.petId);
try { try {
var vaccinationRecords = this.adapter.allVaccines(); var vaccinationRecords = this.adapter.allVaccines();

View file

@ -63,7 +63,6 @@ class OwnerController {
dataBinder.setDisallowedFields("id"); dataBinder.setDisallowedFields("id");
} }
@ModelAttribute("owner") @ModelAttribute("owner")
public Owner findOwner(@PathVariable(name = "ownerId", required = false) Integer ownerId) { public Owner findOwner(@PathVariable(name = "ownerId", required = false) Integer ownerId) {
return ownerId == null ? new Owner() : this.owners.findById(ownerId); return ownerId == null ? new Owner() : this.owners.findById(ownerId);
@ -89,15 +88,13 @@ class OwnerController {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
} }
@PostMapping("/owners/new") @PostMapping("/owners/new")
public String processCreationForm(@Valid Owner owner, BindingResult result) { public String processCreationForm(@Valid Owner owner, BindingResult result) {
if (result.hasErrors()) { if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
} }
validator.ValidateOwnerWithExternalService(owner); validator.ValidateOwnerWithExternalService(owner);
validator.PerformValidationFlow(owner); // validator.PerformValidationFlow(owner);
validator.checkOwnerValidity(owner); validator.checkOwnerValidity(owner);
this.owners.save(owner); this.owners.save(owner);
@ -110,8 +107,6 @@ class OwnerController {
return "owners/findOwners"; return "owners/findOwners";
} }
@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, BindingResult result,
Model model) { Model model) {

View file

@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.owner;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -50,7 +51,6 @@ 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;
@Autowired @Autowired
@ -97,7 +97,8 @@ class PetController implements InitializingBean {
} }
@PostMapping("/pets/new") @PostMapping("/pets/new")
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model)
throws ExecutionException, InterruptedException {
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
result.rejectValue("name", "duplicate", "already exists"); result.rejectValue("name", "duplicate", "already exists");
} }
@ -109,12 +110,18 @@ 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);
// executorService.submit(
// () -> petVaccinationStatus.updateVaccinationStatus(pets));
var petIds = owner.getPets().stream().map(Pet::getId).toList(); var petRequests = owner.getPets()
BackgroundJob.enqueue(() -> petVaccinationStatus.updateVaccinationStatus(petIds) ); .stream()
.map(x -> new PetVaccinationStatusService.UpdateVaccineStatusRequest(owner.getId(), x.getId()))
.toList();
// executorService.submit(() ->
// petVaccinationStatus.updateVaccinationStatus(petRequests)).get();
executorService.submit(() -> petVaccinationStatus.updateVaccinationStatus(petRequests));
//
// BackgroundJob.enqueue(() ->
// petVaccinationStatus.updateVaccinationStatus(petRequests));
return "redirect:/owners/{ownerId}"; return "redirect:/owners/{ownerId}";
} }

View file

@ -5,6 +5,9 @@ spring.sql.init.data-locations=classpath*:db/${database}/data.sql
org.jobrunr.job-scheduler.enabled=true org.jobrunr.job-scheduler.enabled=true
org.jobrunr.background-job-server.enabled=true org.jobrunr.background-job-server.enabled=true
org.jobrunr.dashboard.enabled=true org.jobrunr.dashboard.enabled=true
org.jobrunr.metrics.otel-observability.enabled=true
org.jobrunr.metrics.enabled=true
# Web # Web
spring.thymeleaf.mode=HTML spring.thymeleaf.mode=HTML

View file

@ -38,24 +38,12 @@ public class OwnerControllerTests {
@LocalServerPort @LocalServerPort
private Integer port; private Integer port;
@BeforeAll
static void beforeAll() {
postgres.start();
}
@AfterAll
static void afterAll() {
postgres.stop();
}
@Container @Container
@ServiceConnection @ServiceConnection
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15-alpine"); static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15-alpine");
@BeforeEach @BeforeEach
void setUp() { void setUp() {
// ownerRepository.deleteAll();
RestAssured.baseURI = "http://localhost:" + port; RestAssured.baseURI = "http://localhost:" + port;
} }