Skip to content

Commit

Permalink
Merge branch 'release/1.2.5'
Browse files Browse the repository at this point in the history
Release 1.2.5. For more information about this, see the CHANGELOG
  • Loading branch information
amusarra committed May 13, 2024
2 parents 7fe9d7c + 451836f commit 9289067
Show file tree
Hide file tree
Showing 15 changed files with 781 additions and 333 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Deprecated
### Security

[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
- Adeguamento file JMX `scenario_2.jmx`

### Fixed
- Risoluzione issue di SonarCloud

[1.2.4] - 2024-05-13
### Added
- Aggiunto altro unit test per la pubblicazione di messaggi fake
Expand Down
69 changes: 65 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ Puoi eseguire l'applicazione in modalità sviluppo che abilita il live coding ut
```
Console 6 - 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/.
> **_NOTE:_** Quarkus ora include una UI di sviluppo, disponibile solo in modalità sviluppo all'indirizzo http://localhost:8080/q/dev/.

![Quarkus Dev UI](src/doc/resources/images/quarkus_dev_ui_home_page.jpg)

Expand Down Expand Up @@ -383,7 +383,7 @@ eseguito in locale, per cui abbiate cura di avere l'applicazione Quarkus in esec
I Thread Group in questo caso sono stati configurati per simulare 100 utenti virtuali che inviano 300 richieste al
servizio REST `api/rest/echo` esposto dall'applicazione Quarkus con un periodo di ramp-up di 0.5 secondi.

> **_NOTA:_** I dati mostrati a seguire fanno riferimento all'esecuzione del Test Plan sull'ambiente Developer
> **_NOTA:_** I dati mostrati a seguire fanno riferimento all'esecuzione del Test Plan sull'ambiente Developer
> Sandbox di Red Hat OpenShift, con attivi tre pod dell'applicazione Quarkus, un pod per il servizio MongoDB e un pod
> per il servizio AMQP (Apache ActiveMQ Artemis).

Expand Down Expand Up @@ -425,6 +425,69 @@ potete vedere la struttura aprendolo con JMeter. A seguire è mostrata la strutt

Figura 8 - Configurazione del Test Plan di JMeter (scenario 2 `src/test/jmeter/scenario_2.jmx`)

I thread group sono stati configurati con lo stesso principio del primo scenario di Load Testing, di conseguenza sono
stati creati per versione di protocollo HTTP (HTTPS/1.1, HTTP/2 over TLS e compressed); per ognuno di essi è stato
creato un flusso di richieste verso i servizi JAX-RS dell'entità ORM `Owner` e `Horse` (introdotte dalla versione
[1.2.0](https://github.com/amusarra/eventbus-logging-filter-jaxrs/releases/tag/v1.2.0) del progetto).

Per questo scenario, attraverso l'elemento di configurazione [HTTP Header Manager](https://jmeter.apache.org/usermanual/component_reference.html#HTTP_Header_Manager), sono stati configurati un set di header HTTP custom e che
riguardano nello specifico delle informazioni su JMeter; questi sono:
1. X-TestCaseId: un identificativo univoco del test case
2. X-TestPlanName: il nome del test plan
3. X-TestThreadGroupName: il nome del thread group
4. X-TestThreadNumber: il numero del thread

Queste informazioni possono essere utili per tracciare le richieste HTTP inviate da JMeter e per identificare il test.
A seguire un esempio di una richiesta eseguita da JMeter e tracciata su MongoDB dove sono evidenti gli header HTTP custom.

```bson
{
"_id" : ObjectId("66425a820d65f7240e2ba113"),
"X-Correlation-ID" : "bc187f1f-9c6c-499b-9d13-0b87b31d2abb",
"remote-ip-address" : "127.0.0.1",
"headers" : {
"Accept" : [
"*/*"
],
"X-TestThreadGroupName" : [
"HTTPS/1.1"
],
"Connection" : [
"keep-alive"
],
"User-Agent" : [
"Java/21.0.2"
],
"X-TestPlanName" : [
"modified_scenario_2.jmx"
],
"Host" : [
"127.0.0.1:8443"
],
"X-TestCaseId" : [
"005044d0-9848-4f22-8e50-02fa395a5ede"
],
"Content-Length" : [
"296"
],
"Content-Type" : [
"application/json;charset=UTF-8"
],
"X-TestThreadNumber" : [
"1"
]
},
"body" : "{\r\n \"name\": \"Crimson Comet-updated\",\r\n \"sex\": \"F\",\r\n \"coat\": \"chestnut\",\r\n \"breed\": \"Appaloosa\",\r\n \"dateOfBirth\": \"2004-01-19\",\r\n \"registrationNumber\": \"0FOTDW12MI531U\",\r\n \"microchipNumber\": \"C782CF2I1IN\",\r\n \"passportNumber\": \"39K4CK1I3ZDU4\",\r\n \"height\": 134,\r\n \"owners\": [{\"id\": 3}]\r\n}",
"uri-info" : "https://127.0.0.1:8443/api/rest/repository/horse/v1/6",
"local-date-time-in" : "2024-05-13T20:22:58.622629",
"method" : "PUT",
"media-type" : "application/json",
"acceptable-language" : "[]",
"acceptable-media-types" : "[*/*]"
}
```
Log 3 - 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.

Expand All @@ -446,8 +509,6 @@ Dalla versione [1.2.4](https://github.com/amusarra/eventbus-logging-filter-jaxrs
in esecuzione quando questa è avviata utilizzando il docker-compose. Questo è possibile grazie alla configurazione
mostrata a seguire e in particolare i parametri `JAVA_OPTS` che abilitano la JMX.

```shell script
```yaml
logging-filter:
# Use the following image if you want to use the pre-built image from Docker Hub:
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>it.dontesta.eventbus</groupId>
<artifactId>eventbus-logging-filter-jaxrs</artifactId>
<version>1.2.4</version>
<version>1.2.5</version>
<name>eventbus-logging-filter-jaxrs</name>
<description>Event Bus Logging Filter JAX-RS</description>
<url>https://amusarra.github.io/eventbus-logging-filter-jaxrs-docs</url>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package it.dontesta.eventbus.application.configuration;

import java.util.List;

/**
* Questa classe rappresenta l'indirizzo dell'event handler.
*
* <p>Questo componente è usato per definire l'indirizzo dell'event handler e se è abilitato o meno
* e usato dal converter {@code EventHandlerAddressConverter} per convertire la stringa di
* configurazione in un oggetto {@code EventHandlerAddress}.
*
* @see it.dontesta.eventbus.application.configuration.converter.EventHandlerAddressConverter
*/
public class EventHandlerAddress {

private String address;

private boolean enabled;

/**
* Costruttore di default.
*/
public EventHandlerAddress(String address, boolean enabled) {
this.address = address;
this.enabled = enabled;
}

/**
* Restituisce l'indirizzo dell'event handler.
*
* @return l'indirizzo dell'event handler
*/
public String getAddress() {
return address;
}

/**
* Imposta l'indirizzo dell'event handler.
*
* @param address l'indirizzo dell'event handler
*/
public void setAddress(String address) {
this.address = address;
}

/**
* Restituisce se l'event handler è abilitato o meno.
*
* @return true se l'event handler è abilitato, false altrimenti
*/
public boolean isEnabled() {
return enabled;
}

/**
* Imposta se l'event handler è abilitato o meno.
*
* @param enabled true se l'event handler è abilitato, false altrimenti
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

/**
* Verifica se l'indirizzo dell'event handler esiste e se è abilitato.
*
* @param eventHandlerAddresses la lista degli indirizzi degli event handler
* @param address l'indirizzo dell'event handler
* @return true se l'indirizzo dell'event handler esiste e se è abilitato, false altrimenti
*/
public static boolean isAddressAndExistsEnabled(List<EventHandlerAddress> eventHandlerAddresses,
String address) {
return eventHandlerAddresses.stream()
.anyMatch(eventHandlerAddress ->
eventHandlerAddress.getAddress().equals(address) &&
eventHandlerAddress.isEnabled());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package it.dontesta.eventbus.application.configuration.converter;

import it.dontesta.eventbus.application.configuration.EventHandlerAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.microprofile.config.spi.Converter;

/**
* Questa classe implementa l'interfaccia {@code Converter} per convertire una stringa in un oggetto
* {@code EventHandlerAddress}.
*
* <p>Questo converter è utilizzato in modo specifico per convertire le proprietà di configurazione
* relative agli indirizzi degli event handler. La proprietà di configurazione si chiama
* {@code app.eventbus.consumer.event.handler.addresses[i]} dove i è un numero intero che
* rappresenta l'indice dell'indirizzo dell'event handler.
*
* <p>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 è
* abilitato o meno.
*/
public class EventHandlerAddressConverter implements Converter<EventHandlerAddress> {

@Override
public EventHandlerAddress convert(String value) {
// Definisci il pattern per estrarre i valori di address ed enabled dalle properties
Pattern pattern = Pattern.compile("address=(.*),enabled=(.*)");
Matcher matcher = pattern.matcher(value.trim());

// Itera su tutte le occorrenze del pattern nella stringa value
while (matcher.find()) {
String address = matcher.group(1);
boolean enabled = Boolean.parseBoolean(matcher.group(2));
if (address != null && !address.isEmpty()) {
return (new EventHandlerAddress(address, enabled));
}
}
throw new IllegalArgumentException(
"Failed to parse Event Handler Address {%s}".formatted(value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.vertx.mutiny.core.eventbus.EventBus;
import io.vertx.mutiny.core.eventbus.Message;
import io.vertx.mutiny.core.eventbus.MessageConsumer;
import it.dontesta.eventbus.application.configuration.EventHandlerAddress;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
Expand All @@ -20,7 +21,9 @@
* gli eventi ricevuti dall'event bus tramite il metodo {@code handleEvent}.
*
* <p>Questo componente è responsabile di inviare gli eventi ricevuti da un consumer a uno o più
* consumer target specificati nell'header {@TARGET_VIRTUAL_ADDRESSES} del messaggio.
* consumer target che sono stati abilitati da configurazione
* {@code app.eventbus.consumer.event.handler.addresses}. Questi consumer target sono i cosiddetti
* event handler.
*
* <p>La registrazione avviene all'avvio dell'applicazione tramite l'annotazione {@code @Observes}
* e il metodo {@code onStart}.
Expand All @@ -29,7 +32,7 @@
* di configurazione {@code app.eventbus.consumer.dispatcher.address} che viene iniettato tramite
* l'annotazione {@code @ConfigProperty}
*
* <p>In questo caso il dispatcher invia l'evento ricevuto a uno o più consumer target specificati
* <p>In questo caso il dispatcher invia l'evento ricevuto a uno o più consumer target configurati
* attendendo una risposta da ciascuno di essi scrivendo il risultato sul log.
*/
@ApplicationScoped
Expand All @@ -43,14 +46,15 @@ public class Dispatcher {
@ConfigProperty(name = "app.eventbus.consumer.dispatcher.address")
String dispatcherVirtualAddress;

@ConfigProperty(name = "app.eventbus.consumer.event.handler.addresses")
List<EventHandlerAddress> eventHandlerVirtualAddresses;

MessageConsumer<JsonObject> consumer;

public static final String SOURCE_VIRTUAL_ADDRESS = "source-virtual-address";

public static final String SOURCE_COMPONENT = "source-component";

public static final String TARGET_VIRTUAL_ADDRESSES = "target-virtual-addresses";

void onStart(@Observes StartupEvent ev) {
log.debugf(
"Registering the Dispatcher to the event bus for the event handler at addresses: {%s}",
Expand Down Expand Up @@ -78,16 +82,24 @@ public void handleEvent(Message<JsonObject> message) {
// Leggere gli header dalle DeliveryOptions
String sourceVirtualAddress = message.headers().get(SOURCE_VIRTUAL_ADDRESS);
String sourceComponent = message.headers().get(SOURCE_COMPONENT);
List<String> targetVirtualAddressesList =
List.of(message.headers().get(TARGET_VIRTUAL_ADDRESSES).split(","));

// Filtra gli indirizzi degli event handler abilitati
List<EventHandlerAddress> enabledEventHandlerAddresses = eventHandlerVirtualAddresses.stream()
.filter(EventHandlerAddress::isEnabled)
.toList();

// Estrai la lista degli indirizzi virtuali di destinazione
List<String> targetVirtualAddressesList = enabledEventHandlerAddresses.stream()
.map(EventHandlerAddress::getAddress)
.toList();

log.debugf(
new StringBuilder().append(
"Received event message from source virtual address: %s and source component: %s ")
.append("for the target virtual addresses: %s").toString(),
sourceVirtualAddress, sourceComponent, message.headers().get(TARGET_VIRTUAL_ADDRESSES));
"Received event message from source virtual address: %s and source component: %s " +
"for the target virtual addresses: %s",
sourceVirtualAddress, sourceComponent, targetVirtualAddressesList);

// Invia l'evento a tutti i target virtual addresses
// che sono stati abilitati da configurazione app.eventbus.consumer.event.handler.addresses
targetVirtualAddressesList.forEach(targetVirtualAddress -> {

// Creare le opzioni di consegna desiderate
Expand Down
Loading

0 comments on commit 9289067

Please sign in to comment.