• les dernières technologies innovantes en cours de développement ou en phase de lancement sur le marché.
  • les critiques de produits technologiques populaires, tels que les téléphones intelligents, les ordinateurs portables, les tablettes, les écouteurs, les caméras, etc.
  • des conseils sur la façon de rester en sécurité en ligne, notamment en ce qui concerne la protection de la vie privée, la sécurité des données et la prévention des escroqueries en ligne.
  • les dernières nouvelles et mises à jour dans le monde de la technologie, y compris les fusions et acquisitions, les partenariats, les changements de direction, etc.
Affichage des articles dont le libellé est stockage. Afficher tous les articles
Affichage des articles dont le libellé est stockage. Afficher tous les articles

mercredi 29 mars 2023

Event Sourcing en Java: Comment stocker et reconstruire l'état d'un système avec fiabilité


L'Event Sourcing est une technique de développement de logiciels qui a gagné en popularité ces dernières années en raison de sa capacité à améliorer la résilience et la scalabilité des systèmes. En utilisant cette technique, un développeur peut stocker l'état d'un système en enregistrant une séquence d'événements plutôt que de stocker uniquement l'état actuel. Dans cet article, nous allons examiner comment implémenter l'Event Sourcing en Java en utilisant un exemple concret.


Qu'est-ce que l'Event Sourcing ?


L'Event Sourcing est une approche de développement de logiciels dans laquelle l'état du système est stocké sous forme de séquence d'événements. Chaque événement représente une modification de l'état du système à un moment précis. En utilisant cette technique, les développeurs peuvent facilement récupérer l'état du système à n'importe quel moment en rejouant simplement les événements.


Cette approche a plusieurs avantages. Tout d'abord, elle offre une résilience accrue. En enregistrant chaque événement, le développeur peut facilement retracer l'historique de toutes les modifications apportées au système. Cela facilite également la détection et la correction des erreurs. De plus, l'Event Sourcing offre une scalabilité améliorée, car il est facile de partitionner les événements pour les stocker dans différents emplacements.


Comment implémenter l'Event Sourcing en Java ?


En Java, l'Event Sourcing peut être implémenté en utilisant une base de données NoSQL. Les bases de données NoSQL sont particulièrement bien adaptées à cette approche car elles offrent une flexibilité accrue par rapport aux bases de données relationnelles traditionnelles.

Exemple concret

Pour illustrer comment implémenter l'Event Sourcing en Java, prenons l'exemple d'un système de réservation de vols.

1. Créer des événements

Pour chaque action effectuée dans le système de réservation de vols, nous créons un événement correspondant. Par exemple, lorsque nous créons une nouvelle réservation, nous créons un événement "ReservationCreatedEvent". Chaque événement est représenté par une classe Java qui contient les informations nécessaires pour décrire l'action effectuée.

Exemple de classe d'événement

public class ReservationCreatedEvent {
private UUID reservationId;
private String passengerName;
private String flightNumber;

public ReservationCreatedEvent(UUID reservationId, String passengerName, String flightNumber) {
	this.reservationId = reservationId;
	this.passengerName = passengerName;
	this.flightNumber = flightNumber;
}

// getters and setters
}

2. Stocker les événements

Pour stocker les événements, nous utilisons une base de données NoSQL telle que Cassandra. Nous créons une table "Reservations" qui contient une colonne "events" de type liste. Pour ajouter un nouvel événement à une réservation, nous pouvons utiliser la méthode "saveEvent" de notre repository.

Exemple de repository

public class ReservationRepository {
private static final String INSERT_EVENT_QUERY = "UPDATE Reservations SET events = events + ? WHERE id = ?";
private static final String SELECT_EVENTS_QUERY = "SELECT events FROM Reservations WHERE id = ?";

private final Session session;

public ReservationRepository(Session session) {
	this.session = session;
}

public void saveEvent(UUID id, Object event) {
	session.execute(INSERT_EVENT_QUERY, id, toJson(event));
}

public List getEvents(UUID id) {
	ResultSet result = session.execute(SELECT_EVENTS_QUERY, id);
	Row row = result.one();
	List events = new ArrayList<>();
	if (row != null) {
		List<JsonNode> jsonNodes = row.getList("events", JsonNode.class);
		jsonNodes.forEach(jsonNode -> events.add(fromJson(jsonNode)));
	}
	return events;
}

private JsonNode toJson(Object object) {
	ObjectMapper mapper = new ObjectMapper();
	return mapper.valueToTree(object);
}

private Object fromJson(JsonNode jsonNode) {
	try {
		ObjectMapper mapper = new ObjectMapper();
		Class<?> clazz = Class.forName(jsonNode.get("type").asText());
		return mapper.treeToValue(jsonNode, clazz);
	} catch (ClassNotFoundException | JsonProcessingException e) {
		throw new RuntimeException(e);
	}
}
}

3. Rejouer les événements

Pour récupérer l'état actuel d'une réservation, nous devons rejouer tous les événements associés à cette réservation. Pour ce faire, nous pouvons utiliser la méthode "getEvents" de notre repository pour récupérer tous les événements associés à une réservation, puis les rejouer dans l'ordre chronologique pour reconstruire l'état actuel de la réservation.

Exemple de méthode pour récupérer l'état actuel d'une réservation

public class ReservationService {
private final ReservationRepository reservationRepository;

public ReservationService(ReservationRepository reservationRepository) {
	this.reservationRepository = reservationRepository;
}

public Reservation getReservation(UUID id) {
	List events = reservationRepository.getEvents(id);
	Reservation reservation = new Reservation(id);
	events.forEach(event -> {
		if (event instanceof ReservationCreatedEvent) {
			reservation.createReservation((ReservationCreatedEvent) event);
		} else if (event instanceof ReservationCancelledEvent) {
			reservation.cancelReservation((ReservationCancelledEvent) event);
		}
		// add more else-if clauses for other types of events
	});
	return reservation;
}
}

Dans cet exemple, la classe "Reservation" représente l'état actuel d'une réservation. Lorsque nous rejouons les événements associés à une réservation, nous utilisons les méthodes "createReservation" et "cancelReservation" pour mettre à jour l'état de la réservation en fonction des événements.

Avantages de l'Event Sourcing

L'Event Sourcing présente plusieurs avantages par rapport aux méthodes traditionnelles de développement de logiciels:

  • Réversibilité: En stockant tous les événements qui se produisent dans un système, nous pouvons facilement revenir en arrière en rejouant simplement les événements dans l'ordre inverse.
  • Reconstruction de l'état: En rejouant tous les événements associés à une entité, nous pouvons reconstruire son état actuel de manière fiable.
  • Facilité de mise à l'échelle: En stockant les événements dans une base de données NoSQL, nous pouvons facilement mettre à l'échelle horizontalement en ajoutant des nœuds à notre cluster.
  • Meilleure traçabilité: En enregistrant tous les événements qui se produisent dans un système, nous pouvons facilement retracer l'historique de toutes les actions effectuées.

Conclusion

L'Event Sourcing est une technique de développement de logiciels puissante qui peut être utilisée pour construire des systèmes fiables, évolutifs et traçables. En utilisant l'Event Sourcing en Java, nous pouvons facilement stocker tous les événements qui se produisent dans un système, récupérer l'état actuel de ce système en rejouant ces événements, et profiter des avantages que cette approche offre.