diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d8014c..56ea00e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Deprecated ### Security -[1.2.5] - 2024-05-14 +## [1.2.6] - 2024-05-19 +### Added +- Aggiunta nota sul file README.md riguardo l'uso di Podman rispetto a Docker +- Aggiunta nuova operation `createHorses()` per inserire più Horse in una sola chiamata +- Aggiunta nuova operation `countHorses()` per contare il numero di Horse +- Aggiunta nuova operation `deleteHorses()` per eliminare tutti gli Horse +- Aggiunti nuovi test per le nuove operazioni + +### Changed +- Aggiornamento operation `getAllHorses()` per accettare il parametro `limit` con l'obiettivo di limitare il numero di Horse restituiti +- Aggiornamento scenario di test JMeter `scenario_2.jmx` per includere le nuove operazioni +- Uso di `Instant.now()` per la generazione del tracking invece di `LocalDateTime.now()` + +### Fixed +- Removed unused import in `HorseRepositoryResources` +- Rivista `@Order` annotation per i test + +## [1.2.5] - 2024-05-14 ### Changed - Aggiornamento del file README.md sezione Scenari di Test con JMeter e Taurus - Aggiornamento della gestione degli Event Handler attraverso la configurazione di Quarkus @@ -21,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Risoluzione issue di SonarCloud -[1.2.4] - 2024-05-13 +## [1.2.4] - 2024-05-13 ### Added - Aggiunto altro unit test per la pubblicazione di messaggi fake - Aggiunta configurazione Jacoco per l'exclusion di una classe dal coverage report diff --git a/README.md b/README.md index cd809c0..572ccf7 100644 --- a/README.md +++ b/README.md @@ -266,13 +266,44 @@ req/s : 95.02 131.20 109.66 19.40 60.00% ``` Log 2 - Esempio di output del comando h2load +### Qualche nota sulla configurazione di Podman +Nel caso in cui abbiate Podman al posto di Docker, potreste incontrare il problema mostrato seguire quanto avvierete l'applicazione. + +```text +... +2024-05-15 12:22:07,164 ERROR [org.tes.doc.DockerClientProviderStrategy] (build-43) Could not find a valid Docker environment. Please check configuration. Attempted configurations were: + UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause AccessDeniedException (/var/run/docker.sock) + DockerDesktopClientProviderStrategy: failed with exception NullPointerException (Cannot invoke "java.nio.file.Path.toString()" because the return value of "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy.getSocketPath()" is null)As no valid configuration was found, execution cannot continue. +... +``` +Log 3 - Esempio di errore di configurazione di Podman + +In questo caso, dovreste attivare il servizio `podman.socket` per le [API service](https://github.com/containers/podman/blob/main/docs/tutorials/socket_activation.md) e in modo che il socket sia accessibile a tutti gli utenti. Per fare ciò, eseguire i seguenti comandi. + +```shell script +# I comandi seguenti devono essere eseguiti come utente normale (!= root) +# Abilita il servizio podman.socket per le API service in modalità user +systemctl --user start podman.socket + +# Verifica che il socket sia stato creato +ls -l $XDG_RUNTIME_DIR/podman/podman.sock + +# Verifica che il servizio podman.socket sia attivo +systemctl --user status podman.socket + +# Export della variabile d'ambiente DOCKER_HOST +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock +``` +Console 6 - Abilita il servizio podman.socket per le API service + + ## Esecuzione dell'applicazione in dev mode Puoi eseguire l'applicazione in modalità sviluppo che abilita il live coding utilizzando: ```shell script ./mvnw compile quarkus:dev ``` -Console 6 - Esecuzione dell'applicazione in modalità sviluppo +Console 7 - Esecuzione dell'applicazione in modalità sviluppo > **_NOTE:_** Quarkus ora include una UI di sviluppo, disponibile solo in modalità sviluppo all'indirizzo http://localhost:8080/q/dev/. @@ -286,7 +317,7 @@ L'applicazione può essere preparata utilizzando: ```shell script ./mvnw package ``` -Console 7 - Packaging dell'applicazione +Console 8 - Packaging dell'applicazione Il processo produrrà il file `quarkus-run.jar` in `target/quarkus-app/`. Questo non è un _über-jar_ in quanto le dipendenze sono copiate nella @@ -298,7 +329,7 @@ Se vuoi creare un _über-jar_, esegui il seguente comando: ```shell script ./mvnw package -Dquarkus.package.type=uber-jar ``` -Console 8 - Impacchettamento dell'applicazione come _über-jar_ +Console 9 - Impacchettamento dell'applicazione come _über-jar_ L'applicazione, impacchettata come un _über-jar_, è ora eseguibile utilizzando `java -jar target/*-runner.jar`. @@ -316,7 +347,7 @@ utilizzando: ```shell script ./mvnw package -Dnative -Dquarkus.native.container-build=true ``` -Console 10 - Creazione di un eseguibile nativo in un container +Console 11 - Creazione di un eseguibile nativo in un container Puoi eseguire l'eseguibile nativo con: `./target/eventbus-logging-filter-jaxrs-1.0.0-SNAPSHOT-runner` @@ -373,7 +404,7 @@ bzt -o modules.jmeter.properties.numberOfThreads=100 \ src/test/jmeter/taurus/config.yml \ src/test/jmeter/scenario_1.jmx ``` -Console 11 - Esecuzione del Test Plan di JMeter con Taurus +Console 12 - Esecuzione del Test Plan di JMeter con Taurus Il comando `bzt` esegue il Test Plan di JMeter con Taurus e i parametri `-o` sono utilizzati per sovrascrivere i valori delle variabili definite nel file di configurazione di Taurus `src/test/jmeter/taurus/config.yml` che in questo caso @@ -486,7 +517,7 @@ A seguire un esempio di una richiesta eseguita da JMeter e tracciata su MongoDB "acceptable-media-types" : "[*/*]" } ``` -Log 3 - Esempio di richiesta HTTP tracciata su MongoDB +Log 4 - Esempio di richiesta HTTP tracciata su MongoDB È possibile eseguire questo scenario sempre con Taurus utilizzando comando `bzt` come mostrato in precedenza. A seguire è riportato il comando per eseguire lo scenario di Load Testing con Taurus. @@ -502,7 +533,7 @@ bzt -o modules.jmeter.properties.numberOfThreads=1 \ src/test/jmeter/taurus/config.yml \ src/test/jmeter/scenario_2.jmx ``` -Console 12 - Esecuzione dello scenario di Load Testing con Taurus +Console 13 - Esecuzione dello scenario di Load Testing con Taurus ## Accesso alla Java Management Extensions (JMX) Dalla versione [1.2.4](https://github.com/amusarra/eventbus-logging-filter-jaxrs/releases/tag/v1.2.4) del progetto è possibile accedere alla Java Management Extensions (JMX) dell'applicazione Quarkus diff --git a/pom.xml b/pom.xml index 5540abe..9c34a85 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.dontesta.eventbus eventbus-logging-filter-jaxrs - 1.2.5 + 1.2.6 eventbus-logging-filter-jaxrs Event Bus Logging Filter JAX-RS https://amusarra.github.io/eventbus-logging-filter-jaxrs-docs @@ -39,9 +39,11 @@ scm:git:git@github.com:amusarra/eventbus-logging-filter-jaxrs.git + 2.0.0 3.12.1 21 3.0.1 + 3.6.3 UTF-8 UTF-8 quarkus-bom @@ -252,6 +254,39 @@ false + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + 21 + Event Bus Logging Filter JAX-RS - API + true + true + ${basedir}/src/main/javadoc/overview.html + + https://docs.oracle.com/en/java/javase/21/docs/api + + + + JAX-RS Application Packages + it.dontesta.eventbus.ws.* + + + Application Configuration Packages + it.dontesta.eventbus.application.* + + + Event Bus Consumer Packages + it.dontesta.eventbus.consumers.* + + + ORM Packages + it.dontesta.eventbus.orm.* + + + + diff --git a/src/doc/resources/images/jmeter_configurazione_piano_test_scenario_2.jpg b/src/doc/resources/images/jmeter_configurazione_piano_test_scenario_2.jpg index 2702d1a..c2b943d 100644 Binary files a/src/doc/resources/images/jmeter_configurazione_piano_test_scenario_2.jpg and b/src/doc/resources/images/jmeter_configurazione_piano_test_scenario_2.jpg differ diff --git a/src/main/docker/docker-compose.yml b/src/main/docker/docker-compose.yml index 2999ac1..e85e0ee 100644 --- a/src/main/docker/docker-compose.yml +++ b/src/main/docker/docker-compose.yml @@ -17,7 +17,7 @@ networks: # 4. Logging Filter services: mongodb: - image: docker.io/library/mongo:4.4 + image: docker.io/library/mongo:4.4.3-bionic container_name: mongodb networks: - logging_filter_network diff --git a/src/main/java/it/dontesta/eventbus/application/configuration/EventHandlerAddress.java b/src/main/java/it/dontesta/eventbus/application/configuration/EventHandlerAddress.java index c82675d..27325a2 100644 --- a/src/main/java/it/dontesta/eventbus/application/configuration/EventHandlerAddress.java +++ b/src/main/java/it/dontesta/eventbus/application/configuration/EventHandlerAddress.java @@ -9,6 +9,7 @@ * e usato dal converter {@code EventHandlerAddressConverter} per convertire la stringa di * configurazione in un oggetto {@code EventHandlerAddress}. * + * @since 1.2.5 * @see it.dontesta.eventbus.application.configuration.converter.EventHandlerAddressConverter */ public class EventHandlerAddress { @@ -19,6 +20,9 @@ public class EventHandlerAddress { /** * Costruttore di default. + * + * @param address l'indirizzo dell'event handler + * @param enabled true se l'event handler è abilitato, false altrimenti */ public EventHandlerAddress(String address, boolean enabled) { this.address = address; diff --git a/src/main/java/it/dontesta/eventbus/application/configuration/converter/EventHandlerAddressConverter.java b/src/main/java/it/dontesta/eventbus/application/configuration/converter/EventHandlerAddressConverter.java index 9087d57..a9238d4 100644 --- a/src/main/java/it/dontesta/eventbus/application/configuration/converter/EventHandlerAddressConverter.java +++ b/src/main/java/it/dontesta/eventbus/application/configuration/converter/EventHandlerAddressConverter.java @@ -15,7 +15,7 @@ * rappresenta l'indice dell'indirizzo dell'event handler. * *

Il formato della stringa è il seguente: {@code address=address,enabled=enabled} dove address è - * l'indirizzo dell'event handler e enabled è un flag booleano che indica se l'event handler è + * l'indirizzo dell'event handler ed enabled è un flag booleano che indica se l'event handler è * abilitato o meno. */ public class EventHandlerAddressConverter implements Converter { diff --git a/src/main/java/it/dontesta/eventbus/consumers/events/handlers/Dispatcher.java b/src/main/java/it/dontesta/eventbus/consumers/events/handlers/Dispatcher.java index 7c69aef..e7093d4 100644 --- a/src/main/java/it/dontesta/eventbus/consumers/events/handlers/Dispatcher.java +++ b/src/main/java/it/dontesta/eventbus/consumers/events/handlers/Dispatcher.java @@ -51,8 +51,18 @@ public class Dispatcher { MessageConsumer consumer; + /** + * Source virtual address header. + * È il nome dell'header che contiene l'indirizzo virtuale del consumer che ha inviato l'evento. + */ public static final String SOURCE_VIRTUAL_ADDRESS = "source-virtual-address"; + /** + * Source component header. + * È il nome dell'header che contiene il nome del componente sorgente + * che ha inviato l'evento. Il nome del componente è in formato + * FQCN (Fully Qualified Class Name). + */ public static final String SOURCE_COMPONENT = "source-component"; void onStart(@Observes StartupEvent ev) { @@ -94,7 +104,8 @@ public void handleEvent(Message message) { .toList(); log.debugf( - "Received event message from source virtual address: %s and source component: %s " + + "Received event message from source virtual address: %s and source component: %s " + + "for the target virtual addresses: %s", sourceVirtualAddress, sourceComponent, targetVirtualAddressesList); diff --git a/src/main/java/it/dontesta/eventbus/consumers/events/handlers/nosql/MongoDbEventHandler.java b/src/main/java/it/dontesta/eventbus/consumers/events/handlers/nosql/MongoDbEventHandler.java index 8a9df75..35a1795 100644 --- a/src/main/java/it/dontesta/eventbus/consumers/events/handlers/nosql/MongoDbEventHandler.java +++ b/src/main/java/it/dontesta/eventbus/consumers/events/handlers/nosql/MongoDbEventHandler.java @@ -65,6 +65,12 @@ public class MongoDbEventHandler { MessageConsumer consumer; + /** + * Source component header. + * È il nome dell'header che contiene il nome del componente sorgente + * che ha inviato l'evento. Il nome del componente è in formato + * FQCN (Fully Qualified Class Name). + */ public static final String SOURCE_COMPONENT = "source-component"; public static final String SOURCE_VIRTUAL_ADDRESS_NOSQL = "nosql-trace"; diff --git a/src/main/java/it/dontesta/eventbus/consumers/events/handlers/queue/AmqpEventHandler.java b/src/main/java/it/dontesta/eventbus/consumers/events/handlers/queue/AmqpEventHandler.java index 45b48c7..237ccca 100644 --- a/src/main/java/it/dontesta/eventbus/consumers/events/handlers/queue/AmqpEventHandler.java +++ b/src/main/java/it/dontesta/eventbus/consumers/events/handlers/queue/AmqpEventHandler.java @@ -25,7 +25,7 @@ * per AMQP e gestisce gli eventi ricevuti dall'event bus tramite il metodo {@code handleEvent}. * *

Questo componente è responsabile di processare gli eventi/messaggi veicolati dal Dispatcher - * tramite l'event bus e inviare il messaggio verso il brocker AMQP.. + * tramite l'event bus e inviare il messaggio verso il broker AMQP. * L'esito dell'operazione viene inviato come risposta al Dispatcher. * *

La registrazione avviene all'avvio dell'applicazione tramite l'annotazione {@code @Observes} @@ -57,8 +57,19 @@ public class AmqpEventHandler { MessageConsumer consumer; + /** + * Source component header. + * È il nome dell'header che contiene il nome del componente sorgente + * che ha inviato l'evento. Il nome del componente è in formato + * FQCN (Fully Qualified Class Name). + */ public static final String SOURCE_COMPONENT = "source-component"; + /** + * Indirizzo virtuale della coda AMQP per la gestione degli eventi. + * È il nome dell'indirizzo virtuale della coda AMQP per la gestione degli eventi + * su cui il consumer si registra per ricevere gli eventi. @see {@link #onStart(StartupEvent)} + */ public static final String SOURCE_VIRTUAL_ADDRESS_QUEUE = "queue-trace"; void onStart(@Observes StartupEvent ev) { diff --git a/src/main/java/it/dontesta/eventbus/consumers/http/HttpRequestConsumer.java b/src/main/java/it/dontesta/eventbus/consumers/http/HttpRequestConsumer.java index b3f5803..b742ff4 100644 --- a/src/main/java/it/dontesta/eventbus/consumers/http/HttpRequestConsumer.java +++ b/src/main/java/it/dontesta/eventbus/consumers/http/HttpRequestConsumer.java @@ -42,8 +42,18 @@ public class HttpRequestConsumer { MessageConsumer consumer; + /** + * Source virtual address header. + * È il nome dell'header che contiene l'indirizzo virtuale del consumer che ha inviato l'evento. + */ public static final String SOURCE_VIRTUAL_ADDRESS = "source-virtual-address"; + /** + * Source component header. + * È il nome dell'header che contiene il nome del componente sorgente + * che ha inviato l'evento. Il nome del componente è in formato + * FQCN (Fully Qualified Class Name). + */ public static final String SOURCE_COMPONENT = "source-component"; void onStart(@Observes StartupEvent ev) { diff --git a/src/main/java/it/dontesta/eventbus/consumers/http/HttpResponseConsumer.java b/src/main/java/it/dontesta/eventbus/consumers/http/HttpResponseConsumer.java index cab7087..70ec917 100644 --- a/src/main/java/it/dontesta/eventbus/consumers/http/HttpResponseConsumer.java +++ b/src/main/java/it/dontesta/eventbus/consumers/http/HttpResponseConsumer.java @@ -43,8 +43,18 @@ public class HttpResponseConsumer { MessageConsumer consumer; + /** + * Source virtual address header. + * È il nome dell'header che contiene l'indirizzo virtuale del consumer che ha inviato l'evento. + */ public static final String SOURCE_VIRTUAL_ADDRESS = "source-virtual-address"; + /** + * Source component header. + * È il nome dell'header che contiene il nome del componente sorgente + * che ha inviato l'evento. Il nome del componente è in formato + * FQCN (Fully Qualified Class Name). + */ public static final String SOURCE_COMPONENT = "source-component"; void onStart(@Observes StartupEvent ev) { diff --git a/src/main/java/it/dontesta/eventbus/orm/panache/entity/Horse.java b/src/main/java/it/dontesta/eventbus/orm/panache/entity/Horse.java index a4fbe8d..f99af9e 100644 --- a/src/main/java/it/dontesta/eventbus/orm/panache/entity/Horse.java +++ b/src/main/java/it/dontesta/eventbus/orm/panache/entity/Horse.java @@ -16,34 +16,64 @@ @Cacheable public class Horse extends PanacheEntity { + /** + * Il nome del cavallo. + */ @Column(length = 60, nullable = false) public String name; + /** + * Il sesso del cavallo. + */ @Column(length = 1, nullable = false) @Pattern(regexp = "^[MF]$", message = "The admitted values for the sex attribute are: 'M' or 'F'") public String sex; + /** + * Il colore del mantello del cavallo. + */ @Column(length = 15, nullable = false) public String coat; + /** + * La razza del cavallo. + */ @Column(length = 60, nullable = false) public String breed; + /** + * La data di nascita del cavallo. + */ @Column(nullable = false) public LocalDate dateOfBirth; - @Column(length = 15) + /** + * Il numero di registrazione del cavallo. + */ + @Column(length = 20) public String registrationNumber; - @Column(length = 15) + /** + * Il numero del microchip del cavallo. + */ + @Column(length = 20) public String microchipNumber; - @Column(length = 15) + /** + * Il numero del passaporto del cavallo. + */ + @Column(length = 20) public String passportNumber; + /** + * L'altezza del cavallo in centimetri. + */ @Column(length = 3) public int height; + /** + * La lista dei proprietari del cavallo. + */ @ManyToMany public List owners; } diff --git a/src/main/java/it/dontesta/eventbus/orm/panache/entity/Owner.java b/src/main/java/it/dontesta/eventbus/orm/panache/entity/Owner.java index 00727d6..bd8d207 100644 --- a/src/main/java/it/dontesta/eventbus/orm/panache/entity/Owner.java +++ b/src/main/java/it/dontesta/eventbus/orm/panache/entity/Owner.java @@ -15,33 +15,63 @@ @Cacheable public class Owner extends PanacheEntity { + /** + * Il nome del proprietario. + */ @Column(length = 60, nullable = false) public String name; + /** + * Il cognome del proprietario. + */ @Column(length = 60, nullable = false) public String surname; + /** + * L'indirizzo email del proprietario. + */ @Column(length = 60, nullable = false, unique = true) public String email; + /** + * Il numero di telefono del proprietario. + */ @Column(length = 20) public String phoneNumber; + /** + * L'indirizzo del proprietario. + */ @Column(length = 60) public String address; + /** + * La città del proprietario. + */ @Column(length = 60) public String city; + /** + * Lo stato del proprietario. + */ @Column(length = 2) public String state; + /** + * Il codice postale del proprietario. + */ @Column(length = 10) public String zipCode; + /** + * Il paese del proprietario. + */ @Column(length = 60) public String country; + /** + * La lista dei cavalli di proprietà del proprietario. + */ @ManyToMany(mappedBy = "owners") @JsonBackReference public List horses; diff --git a/src/main/java/it/dontesta/eventbus/orm/panache/repository/HorseRepository.java b/src/main/java/it/dontesta/eventbus/orm/panache/repository/HorseRepository.java index 9695dfa..9c8b74f 100644 --- a/src/main/java/it/dontesta/eventbus/orm/panache/repository/HorseRepository.java +++ b/src/main/java/it/dontesta/eventbus/orm/panache/repository/HorseRepository.java @@ -10,6 +10,12 @@ */ @ApplicationScoped public class HorseRepository implements PanacheRepository { + + /** + * This method finds all the horses ordered by name. + * + * @return the list of horses ordered by name + */ public List findOrderedByName() { return find("ORDER BY name").list(); } diff --git a/src/main/java/it/dontesta/eventbus/orm/panache/repository/OwnerRepository.java b/src/main/java/it/dontesta/eventbus/orm/panache/repository/OwnerRepository.java index 3c65ea3..76f14cf 100644 --- a/src/main/java/it/dontesta/eventbus/orm/panache/repository/OwnerRepository.java +++ b/src/main/java/it/dontesta/eventbus/orm/panache/repository/OwnerRepository.java @@ -10,6 +10,12 @@ */ @ApplicationScoped public class OwnerRepository implements PanacheRepository { + + /** + * This method finds all the owners ordered by name. + * + * @return the list of owners ordered by name + */ public List findOrderedByName() { return find("ORDER BY name").list(); } diff --git a/src/main/java/it/dontesta/eventbus/ws/filter/TraceJaxRsRequestResponseFilter.java b/src/main/java/it/dontesta/eventbus/ws/filter/TraceJaxRsRequestResponseFilter.java index 63602ca..e43409b 100644 --- a/src/main/java/it/dontesta/eventbus/ws/filter/TraceJaxRsRequestResponseFilter.java +++ b/src/main/java/it/dontesta/eventbus/ws/filter/TraceJaxRsRequestResponseFilter.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -111,7 +111,7 @@ public void filter(ContainerRequestContext requestContext) { // Applica la logica del filtro in base all'URI if (requestUriIsFiltered(requestUri)) { // Aggiungi la data ora di quando la richiesta arriva al filtro - requestContext.setProperty(LOCAL_DATE_TIME_IN, LocalDateTime.now()); + requestContext.setProperty(LOCAL_DATE_TIME_IN, Instant.now()); /* * Se l'URI richiesto è presente nell'elenco delle URI da filtrare @@ -290,7 +290,7 @@ private JsonObject prepareMessage(ContainerResponseContext responseContext) { return new JsonObject() .put(CORRELATION_ID_HEADER, responseContext.getHeaders().get(CORRELATION_ID_HEADER).getFirst()) - .put(LOCAL_DATE_TIME_OUT, LocalDateTime.now().toString()) + .put(LOCAL_DATE_TIME_OUT, Instant.now()) .put("status", responseContext.getStatus()) .put("status-info-family-name", responseContext.getStatusInfo().getFamily().name()) .put("status-info-reason", responseContext.getStatusInfo().getReasonPhrase()) diff --git a/src/main/java/it/dontesta/eventbus/ws/input/wrapper/HorseListWrapper.java b/src/main/java/it/dontesta/eventbus/ws/input/wrapper/HorseListWrapper.java new file mode 100644 index 0000000..51466b6 --- /dev/null +++ b/src/main/java/it/dontesta/eventbus/ws/input/wrapper/HorseListWrapper.java @@ -0,0 +1,24 @@ +package it.dontesta.eventbus.ws.input.wrapper; + +import it.dontesta.eventbus.orm.panache.entity.Horse; +import jakarta.validation.constraints.Size; +import java.util.List; + +/** + * The class is a wrapper class that contains a list of {@link Horse} objects. + */ +public class HorseListWrapper { + + @Size(max = 10, message = "The number of horses must not exceed 10") + private List horses; + + /** + * Return the list of the horses. + * + * @see Horse + * @return The list of the horses. + */ + public List getHorses() { + return horses; + } +} \ No newline at end of file diff --git a/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/EchoResourceEndPoint.java b/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/EchoResourceEndPoint.java index 4b5ab2d..2d0bac0 100644 --- a/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/EchoResourceEndPoint.java +++ b/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/EchoResourceEndPoint.java @@ -16,6 +16,13 @@ @Consumes(MediaType.APPLICATION_JSON) public class EchoResourceEndPoint { + /** + * This method echoes the input parameter. + * + * @param input the input parameter + * + * @return the response + */ @Path("echo") @POST public Response echo( diff --git a/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResources.java b/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResources.java index aa69ed1..9d8517c 100644 --- a/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResources.java +++ b/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResources.java @@ -1,10 +1,13 @@ package it.dontesta.eventbus.ws.resources.endpoint.repository.v1; +import io.quarkus.panache.common.Page; import it.dontesta.eventbus.orm.panache.entity.Horse; import it.dontesta.eventbus.orm.panache.entity.Owner; import it.dontesta.eventbus.orm.panache.repository.HorseRepository; +import it.dontesta.eventbus.ws.input.wrapper.HorseListWrapper; import jakarta.inject.Inject; import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; @@ -13,6 +16,7 @@ import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -41,7 +45,10 @@ public class HorseRepositoryResources { * @return A list of horses. */ @GET - public List getAllHorses() { + public List getAllHorses(@QueryParam("limit") Integer limit) { + if (limit != null) { + return horseRepository.findAll().page(Page.ofSize(limit)).list(); + } return horseRepository.findAll().list(); } @@ -64,6 +71,17 @@ public Horse getHorseById(@NotNull Long id) { return horse; } + /** + * Retrieves the number of horses in the repository. + * + * @return The number of horses. + */ + @GET + @Path("count") + public long countHorses() { + return horseRepository.count(); + } + /** * This method creates a new horse. * @@ -84,6 +102,26 @@ public Response createHorse(@NotNull Horse horse) { return Response.ok(horse).status(Response.Status.CREATED).build(); } + /** + * This method creates a horses from a list of horses. + * + * @param horseListWrapper The list of horses to create. + * @return The created horses. + */ + @POST + @Path("list") + @Transactional + public Response createHorses(@Valid HorseListWrapper horseListWrapper) { + // Return a 422 Unprocessable Entity if an ID was provided + horseListWrapper.getHorses().forEach(horse -> { + if (horse.id != null) { + throw new WebApplicationException("Id was invalidly set on request.", 422); + } + horseRepository.persist(horse); + }); + return Response.ok(horseListWrapper).status(Response.Status.CREATED).build(); + } + /** * This method updates a horse. * @@ -148,4 +186,17 @@ public Response deleteHorse(@NotNull Long id) { horseRepository.delete(horse); return Response.status(Response.Status.NO_CONTENT).build(); } + + /** + * This method deletes all horses. + * + * @return The response. + */ + @DELETE + @Path("all") + @Transactional + public Response deleteAllHorses() { + horseRepository.deleteAll(); + return Response.status(Response.Status.NO_CONTENT).build(); + } } diff --git a/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResources.java b/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResources.java index 26012fd..fc67bba 100644 --- a/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResources.java +++ b/src/main/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResources.java @@ -16,7 +16,6 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.List; -import org.jboss.logging.Logger; /** * This class represents the REST endpoint for the Owner repository. @@ -29,9 +28,11 @@ public class OwnerRepositoryResources { @Inject OwnerRepository ownerRepository; - @Inject - Logger log; - + /** + * Retrieves all owners from the repository. + * + * @return The list of owners. + */ @GET public List getAllOwners() { return ownerRepository.findAll().list(); diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html new file mode 100644 index 0000000..3e47734 --- /dev/null +++ b/src/main/javadoc/overview.html @@ -0,0 +1,74 @@ + + + + + Overview + + + +

Overview

+

Questo è il documento di overview per il progetto Event Bus Logging Filter JAX-RS.

+

Per questo progetto è disponibile la + documentazione estesa +

+ +

Package Principali

+ + +

Classi Principali

+ + + diff --git a/src/test/java/it/dontesta/eventbus/publish/PublishMessageOnEventBusTest.java b/src/test/java/it/dontesta/eventbus/publish/PublishMessageOnEventBusTest.java index fcae38a..826f7f7 100644 --- a/src/test/java/it/dontesta/eventbus/publish/PublishMessageOnEventBusTest.java +++ b/src/test/java/it/dontesta/eventbus/publish/PublishMessageOnEventBusTest.java @@ -51,6 +51,12 @@ class PublishMessageOnEventBusTest { final String SOURCE_VIRTUAL_ADDRESS = "source-virtual-address"; + /** + * Source component header. + * È il nome dell'header che contiene il nome del componente sorgente + * che ha inviato l'evento. Il nome del componente è in formato + * FQCN (Fully Qualified Class Name). + */ final String SOURCE_COMPONENT = "source-component"; final String TARGET_VIRTUAL_ADDRESSES = "target-virtual-addresses"; diff --git a/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResourcesTest.java b/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResourcesTest.java index 605d0fb..504b0f8 100644 --- a/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResourcesTest.java +++ b/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/HorseRepositoryResourcesTest.java @@ -27,6 +27,26 @@ void getAllHorsesSuccess() { @Test @Order(2) + void getAllHorsesLimitSuccess() { + given() + .contentType(ContentType.JSON) + .when().get("/api/rest/repository/horse/v1?limit=10") + .then() + .statusCode(Response.Status.OK.getStatusCode()); + } + + @Test + @Order(3) + void getCountSuccess() { + given() + .contentType(ContentType.JSON) + .when().get("/api/rest/repository/horse/v1/count") + .then() + .statusCode(Response.Status.OK.getStatusCode()); + } + + @Test + @Order(4) void getHorseByIdSuccess() { given() .contentType(ContentType.JSON) @@ -37,7 +57,7 @@ void getHorseByIdSuccess() { } @Test - @Order(3) + @Order(5) void getHorseByIdNotFound() { given() .contentType(ContentType.JSON) @@ -48,7 +68,7 @@ void getHorseByIdNotFound() { } @Test - @Order(4) + @Order(6) void testCreateHorseBodyNull() { given() .contentType(ContentType.JSON) @@ -59,7 +79,7 @@ void testCreateHorseBodyNull() { } @Test - @Order(5) + @Order(7) void testCreateHorse() { String json = """ { @@ -82,7 +102,7 @@ void testCreateHorse() { } @Test - @Order(5) + @Order(8) void testCreateHorseWithId() { String json = """ { @@ -106,7 +126,106 @@ void testCreateHorseWithId() { } @Test - @Order(6) + @Order(9) + void testCreateHorses() { + String json = """ + { + "horses": [ + { + "name": "Thunder", + "coat": "Black", + "breed": "PSA", + "sex": "M", + "dateOfBirth": "2024-05-11", + "owners": [ + { + "id": 3 + } + ] + }, + { + "name": "Furia", + "coat": "White", + "breed": "Quarter", + "sex": "F", + "dateOfBirth": "2024-05-12", + "owners": [ + { + "id": 1 + } + ] + }, + { + "name": "Focoso", + "coat": "White", + "breed": "Quarter", + "sex": "F", + "dateOfBirth": "2024-05-12", + "owners": [ + { + "id": 1 + } + ] + } + ] + } + """; + + given() + .contentType(ContentType.JSON) + .body(json) + .when().post("/api/rest/repository/horse/v1/list") + .then() + .statusCode(Response.Status.CREATED.getStatusCode()) + .body("horses[0].name", is("Thunder")) + .body("horses[1].name", is("Furia")); + } + + @Test + @Order(10) + void testCreateHorsesWhitId() { + String json = """ + { + "horses": [ + { + "id": 100, + "name": "Thunder", + "coat": "Black", + "breed": "PSA", + "sex": "M", + "dateOfBirth": "2024-05-11", + "owners": [ + { + "id": 3 + } + ] + }, + { + "name": "Furia", + "coat": "White", + "breed": "Quarter", + "sex": "F", + "dateOfBirth": "2024-05-12", + "owners": [ + { + "id": 1 + } + ] + } + ] + } + """; + + given() + .contentType(ContentType.JSON) + .body(json) + .when().post("/api/rest/repository/horse/v1/list") + .then() + .statusCode(422); + } + + @Test + @Order(11) void testUpdateHorse() { String json = """ { @@ -129,7 +248,7 @@ void testUpdateHorse() { } @Test - @Order(7) + @Order(12) void testUpdateHorseNotFoundId() { String json = """ { @@ -152,7 +271,7 @@ void testUpdateHorseNotFoundId() { } @Test - @Order(8) + @Order(13) void testUpdateHorseNewOwnerId() { String json = """ { @@ -175,7 +294,7 @@ void testUpdateHorseNewOwnerId() { } @Test - @Order(9) + @Order(14) void testDeleteHorseByIdSuccess() { given() .when().delete("/api/rest/repository/horse/v1/1") @@ -184,11 +303,20 @@ void testDeleteHorseByIdSuccess() { } @Test - @Order(9) + @Order(15) void testDeleteHorseByIdNotFound() { given() .when().delete("/api/rest/repository/horse/v1/100") .then() .statusCode(Response.Status.NOT_FOUND.getStatusCode()); } + + @Test + @Order(16) + void testDeleteHorseAll() { + given() + .when().delete("/api/rest/repository/horse/v1/all") + .then() + .statusCode(Response.Status.NO_CONTENT.getStatusCode()); + } } diff --git a/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResourcesTest.java b/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResourcesTest.java index b1eb433..149b76c 100644 --- a/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResourcesTest.java +++ b/src/test/java/it/dontesta/eventbus/ws/resources/endpoint/repository/v1/OwnerRepositoryResourcesTest.java @@ -205,7 +205,7 @@ void testDeleteOwnerByIdSuccess() { given() .when().delete("/api/rest/repository/owner/v1/1") .then() - .statusCode(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + .statusCode(Response.Status.NO_CONTENT.getStatusCode()); } } diff --git a/src/test/jmeter/scenario_2.jmx b/src/test/jmeter/scenario_2.jmx index 6806523..32f1f1d 100644 --- a/src/test/jmeter/scenario_2.jmx +++ b/src/test/jmeter/scenario_2.jmx @@ -24,7 +24,7 @@ numberOfThreads = - ${__P(numberOfThreads,1)} + ${__P(numberOfThreads,2)} rampUpPeriod @@ -34,7 +34,7 @@ loopCount = - ${__P(loopCount,1)} + ${__P(loopCount,2)} @@ -134,11 +134,11 @@ Connect to 5s false 60 5 - false + true true - + true false @@ -357,7 +357,7 @@ Connect to 5s - + true false @@ -713,11 +713,11 @@ Connect to 5s false 60 5 - false + true true - + true false @@ -942,7 +942,7 @@ Connect to 5s - + true false @@ -1262,7 +1262,7 @@ Connect to 5s - + Servizio REST /api/rest/repository/owner/v1 false false @@ -1310,7 +1310,7 @@ Connect to 5s false 60 5 - false + true true @@ -1323,7 +1323,7 @@ Connect to 5s - + true false @@ -1548,7 +1548,7 @@ Connect to 5s - + true false @@ -1565,7 +1565,7 @@ Connect to 5s - /api/rest/repository/horse/v1 + /api/rest/repository/horse/v1?limit=15 GET false false @@ -1600,7 +1600,7 @@ Connect to 5s $[0].name 0 false - false + true false false Check JSON Path and value @@ -1868,19 +1868,164 @@ Connect to 5s - - Servizio REST /api/rest/repository/owner/v1 + + 50 + + + + false + false + 6 + 2.0.5 + true + + + + false + { + "horses": [ + { + "name": "${horseName}-${__Random(1,999,)}", + "coat": "${coat}", + "breed": "${breed}", + "sex": "${sex}", + "dateOfBirth": "${__RandomDate(yyyy-MM-dd,2000-05-17,2024-05-17,it_IT,)}", + "registrationNumber": "${registrationNumber}-${__Random(1,999,)}", + "microchipNumber": "${microchipNumber}-${__Random(1,999,)}", + "passportNumber": "${passportNumber}-${__Random(1,999,)}", + "height": ${__Random(100,180,)}, + "owners": [{"id": ${createdOwnerId}}] + }, + { + "name": "${horseName}-${__Random(1,999,)}", + "coat": "${coat}", + "breed": "${breed}", + "sex": "${sex}", + "dateOfBirth": "${__RandomDate(yyyy-MM-dd,2000-05-17,2024-05-17,it_IT,)}", + "registrationNumber": "${registrationNumber}-${__Random(1,999,)}", + "microchipNumber": "${microchipNumber}-${__Random(1,999,)}", + "passportNumber": "${passportNumber}-${__Random(1,999,)}", + "height": ${__Random(100,180,)}, + "owners": [{"id": ${createdOwnerId}}] + }, + { + "name": "${horseName}-${__Random(1,999,)}", + "coat": "${coat}", + "breed": "${breed}", + "sex": "${sex}", + "dateOfBirth": "${__RandomDate(yyyy-MM-dd,2000-05-17,2024-05-17,it_IT,)}", + "registrationNumber": "${registrationNumber}-${__Random(1,999,)}", + "microchipNumber": "${microchipNumber}-${__Random(1,999,)}", + "passportNumber": "${passportNumber}-${__Random(1,999,)}", + "height": ${__Random(100,180,)}, + "owners": [{"id": ${createdOwnerId}}] + }, + { + "name": "${horseName}-${__Random(1,999,)}", + "coat": "${coat}", + "breed": "${breed}", + "sex": "${sex}", + "dateOfBirth": "${__RandomDate(yyyy-MM-dd,2000-05-17,2024-05-17,it_IT,)}", + "registrationNumber": "${registrationNumber}-${__Random(1,999,)}", + "microchipNumber": "${microchipNumber}-${__Random(1,999,)}", + "passportNumber": "${passportNumber}-${__Random(1,999,)}", + "height": ${__Random(100,180,)}, + "owners": [{"id": ${createdOwnerId}}] + }, + { + "name": "${horseName}-${__Random(1,999,)}", + "coat": "${coat}", + "breed": "${breed}", + "sex": "${sex}", + "dateOfBirth": "${__RandomDate(yyyy-MM-dd,2000-05-17,2024-05-17,it_IT,)}", + "registrationNumber": "${registrationNumber}-${__Random(1,999,)}", + "microchipNumber": "${microchipNumber}-${__Random(1,999,)}", + "passportNumber": "${passportNumber}-${__Random(1,999,)}", + "height": ${__Random(100,180,)}, + "owners": [{"id": ${createdOwnerId}}] + }, + { + "name": "${horseName}${__Random(1,999,)}", + "coat": "${coat}", + "breed": "${breed}", + "sex": "${sex}", + "dateOfBirth": "${__RandomDate(yyyy-MM-dd,2000-05-17,2024-05-17,it_IT,)}", + "registrationNumber": "${registrationNumber}-${__Random(1,999,)}", + "microchipNumber": "${microchipNumber}-${__Random(1,999,)}", + "passportNumber": "${passportNumber}-${__Random(1,999,)}", + "height": ${__Random(100,180,)}, + "owners": [{"id": ${createdOwnerId}}] + } + ] +} + = + + + + /api/rest/repository/horse/v1/list + POST + false + false + false + false + false + false + + + + + Servizio REST /api/rest/repository/horse/v1/count false false 6 - 5000 - 30000 2.0.5 false - + - /api/rest/repository/owner/v1/${createdOwnerId} + /api/rest/repository/horse/v1/count + GET + false + false + false + false + false + false + + + + + 200 + + Assertion.response_code + false + 1 + + + + + + x-correlation-id: + content-type: application/json;charset=UTF-8 + + Assertion.response_headers + false + 2 + + + + + + Servizio REST /api/rest/repository/horse/v1 + false + false + 6 + 2.0.5 + false + + + + /api/rest/repository/horse/v1/all DELETE false false @@ -1901,10 +2046,131 @@ Connect to 5s + + Servizio REST /api/rest/repository/horse/v1/count + false + false + 6 + 2.0.5 + false + + + + /api/rest/repository/horse/v1/count + GET + false + false + false + false + false + false + + + + + 200 + + Assertion.response_code + false + 1 + + + + + + x-correlation-id: + content-type: application/json;charset=UTF-8 + + Assertion.response_headers + false + 2 + + + + + + Servizio REST /api/rest/repository/horse/v1 + false + false + 6 + 5000 + 30000 + 2.0.5 + true + + + + false + { + "name": "${horseName}", + "sex": "${sex}", + "coat": "${coat}", + "breed": "${breed}", + "dateOfBirth": "${dateOfBirth}", + "registrationNumber": "${registrationNumber}", + "microchipNumber": "${microchipNumber}", + "passportNumber": "${passportNumber}", + "height": ${height}, + "owners": [{"id": ${createdOwnerId}}] +} + = + + + + /api/rest/repository/horse/v1 + POST + false + false + false + false + false + false + + + + + 201 + + Assertion.response_code + false + 1 + + + + + + x-correlation-id: + content-type: application/json;charset=UTF-8 + + Assertion.response_headers + false + 2 + + + + + $.name + 0 + false + false + false + false + Check JSON Path and value + + + + createdHorseId + id + 0 + 0 + Estrazione dell'identificativo dell'Horse. Il valore sarà utilizzato per la successiva chiamata getHorseById + + + - false + true saveConfig