diff --git a/data-generator/src/main/java/cloud/project/datagenerator/rabbitmq/requests/transports/TransportUpdateRequest.java b/data-generator/src/main/java/cloud/project/datagenerator/rabbitmq/requests/transports/TransportUpdateRequest.java index 7d63dfde..58b81920 100644 --- a/data-generator/src/main/java/cloud/project/datagenerator/rabbitmq/requests/transports/TransportUpdateRequest.java +++ b/data-generator/src/main/java/cloud/project/datagenerator/rabbitmq/requests/transports/TransportUpdateRequest.java @@ -1,5 +1,6 @@ package cloud.project.datagenerator.rabbitmq.requests.transports; +import cloud.project.datagenerator.rabbitmq.requests.DataUpdateType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,7 +16,7 @@ @Builder public class TransportUpdateRequest { - private String updateType; + private DataUpdateType updateType; private UUID id; diff --git a/data-generator/src/main/java/cloud/project/datagenerator/transports/TransportsDataGenerator.java b/data-generator/src/main/java/cloud/project/datagenerator/transports/TransportsDataGenerator.java index 84ca782d..e595c711 100644 --- a/data-generator/src/main/java/cloud/project/datagenerator/transports/TransportsDataGenerator.java +++ b/data-generator/src/main/java/cloud/project/datagenerator/transports/TransportsDataGenerator.java @@ -4,6 +4,7 @@ import cloud.project.datagenerator.hotels.repositories.HotelRepository; import cloud.project.datagenerator.rabbitmq.QueuesConfigTransports; import cloud.project.datagenerator.rabbitmq.json.JsonConverter; +import cloud.project.datagenerator.rabbitmq.requests.DataUpdateType; import cloud.project.datagenerator.rabbitmq.requests.transports.TransportUpdateRequest; import cloud.project.datagenerator.transports.domain.Transport; import cloud.project.datagenerator.transports.domain.TransportCourse; @@ -26,10 +27,6 @@ public class TransportsDataGenerator { private final HotelRepository hotelRepository; - enum DataUpdateType { - CREATE, - UPDATE - } private final Random random = new Random(); private final RabbitTemplate rabbitTemplate; @@ -100,7 +97,7 @@ private void updateRandomTransport() { public void updateTransportDataInTransportModules(DataUpdateType updateType, Transport transport) { TransportUpdateRequest transportUpdateRequest = TransportUpdateRequest.builder() - .updateType(String.valueOf(updateType)) + .updateType(updateType) .id(transport.getId()) .courseId(transport.getCourse().getId()) .courseLocationFromId(transport.getCourse().getDepartureFrom().getId()) diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsCommandController.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsCommandController.java index 4b0fc45e..62462f61 100644 --- a/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsCommandController.java +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsCommandController.java @@ -2,16 +2,23 @@ import lombok.RequiredArgsConstructor; import org.microarchitecturovisco.transport.model.cqrs.commands.CreateTransportReservationCommand; +import org.microarchitecturovisco.transport.model.domain.Transport; +import org.microarchitecturovisco.transport.model.dto.data_generator.DataUpdateType; +import org.microarchitecturovisco.transport.model.dto.data_generator.TransportUpdateRequest; import org.microarchitecturovisco.transport.services.TransportCommandService; +import org.microarchitecturovisco.transport.services.TransportsQueryService; import org.microarchitecturovisco.transport.utils.json.JsonReader; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; +import java.util.logging.Logger; + @Component @RequiredArgsConstructor public class TransportsCommandController { private final TransportCommandService transportCommandService; + private final TransportsQueryService transportsQueryService; @RabbitListener(queues = "#{createTransportReservationRequestQueue.name}") public void consumeCreateTransportReservationCommand(String commandDtoJson) { @@ -19,4 +26,33 @@ public void consumeCreateTransportReservationCommand(String commandDtoJson) { transportCommandService.createReservation(command); } + + @RabbitListener(queues = "#{handleDataGeneratorCreateQueue}") + public void consumeDataGeneratorMessage(String requestJson) { + Logger logger = Logger.getLogger("TransportController"); + logger.info("Got Create/Update transport request from Data Generator: " + requestJson); + + TransportUpdateRequest request = JsonReader.readDtoFromJson(requestJson, TransportUpdateRequest.class); + + // create transport + if (request.getUpdateType() == DataUpdateType.CREATE) { + logger.info("Created transport: " + request); + + transportCommandService.createTransport(request.getId(), request.getCourseId(), request.getDepartureDate(), + request.getCapacity(), request.getPricePerAdult()); + return; + } + + Transport transport = transportsQueryService.getTransportById(request.getId()); + if (transport == null) + { + return; + } + // update transport + if (request.getUpdateType() == DataUpdateType.UPDATE) { + logger.info("Updated transport: " + request); + + transportCommandService.updateTransport(request.getId(), request.getCapacity(), request.getPricePerAdult()); + } + } } diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsQueryController.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsQueryController.java index 77afe644..9ed83215 100644 --- a/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsQueryController.java +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/controllers/TransportsQueryController.java @@ -10,6 +10,7 @@ import org.microarchitecturovisco.transport.model.dto.LocationDto; import org.microarchitecturovisco.transport.model.dto.TransportDto; import org.microarchitecturovisco.transport.model.dto.TransportReservationDto; +import org.microarchitecturovisco.transport.model.dto.data_generator.TransportUpdateRequest; import org.microarchitecturovisco.transport.model.dto.request.*; import org.microarchitecturovisco.transport.model.dto.response.AvailableTransportsDto; import org.microarchitecturovisco.transport.model.dto.response.CheckTransportAvailabilityResponseDto; @@ -32,6 +33,8 @@ import java.util.List; import java.util.UUID; import java.util.logging.Logger; +import org.microarchitecturovisco.transport.model.dto.data_generator.DataUpdateType; + @RestController() @RequestMapping("/transports") @@ -201,4 +204,5 @@ public void consumeMessageDeleteTransportReservation(String requestJson) { transportCommandService.deleteReservation(command); } } + } diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/model/dto/data_generator/DataUpdateType.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/model/dto/data_generator/DataUpdateType.java new file mode 100644 index 00000000..beeca79d --- /dev/null +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/model/dto/data_generator/DataUpdateType.java @@ -0,0 +1,14 @@ +package org.microarchitecturovisco.transport.model.dto.data_generator; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum DataUpdateType { + CREATE("CREATE"), + UPDATE("UPDATE"); + + private final String value; +} + diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/model/dto/data_generator/TransportUpdateRequest.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/model/dto/data_generator/TransportUpdateRequest.java new file mode 100644 index 00000000..79cd0c38 --- /dev/null +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/model/dto/data_generator/TransportUpdateRequest.java @@ -0,0 +1,33 @@ +package org.microarchitecturovisco.transport.model.dto.data_generator; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.UUID; + + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class TransportUpdateRequest { + + private DataUpdateType updateType; + + private UUID id; + + private UUID courseId; + + private UUID courseLocationFromId; + private UUID courseLocationToId; + + private LocalDateTime departureDate; + + private int capacity; + + private float pricePerAdult; +} + diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/model/events/TransportUpdateEvent.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/model/events/TransportUpdateEvent.java new file mode 100644 index 00000000..a4a1de0a --- /dev/null +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/model/events/TransportUpdateEvent.java @@ -0,0 +1,29 @@ +package org.microarchitecturovisco.transport.model.events; + +import jakarta.persistence.Entity; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +import java.time.LocalDateTime; +import java.util.UUID; + + +@Entity +@NoArgsConstructor +@SuperBuilder +@Getter +@Setter +public class TransportUpdateEvent extends TransportEvent { + private int capacity; + private float pricePerAdult; + + public TransportUpdateEvent(UUID transportId, int capacity, float pricePerAdult){ + this.setEventTimeStamp(LocalDateTime.now()); + this.setIdTransport(transportId); + this.capacity = capacity; + this.pricePerAdult = pricePerAdult; + } +} diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/queues/config/DataGeneratorExchangeConfig.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/queues/config/DataGeneratorExchangeConfig.java new file mode 100644 index 00000000..be34eb22 --- /dev/null +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/queues/config/DataGeneratorExchangeConfig.java @@ -0,0 +1,36 @@ +package org.microarchitecturovisco.transport.queues.config; + + +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.FanoutExchange; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.Binding; +import java.util.UUID; + +@Configuration +public class DataGeneratorExchangeConfig { + + public static final String EXCHANGE_DATA_GENERATOR = "data.generate.transports.exchange"; + + @Bean + public FanoutExchange handleDataGeneratorExchange() { + return new FanoutExchange(EXCHANGE_DATA_GENERATOR); + } + + @Bean + public Queue handleDataGeneratorCreateQueue() { + String uniqueQueueName = "data.generate.transports.queue" + UUID.randomUUID(); + return new Queue(uniqueQueueName, false, false, false); + } + + @Bean + public Binding handleDataGeneratorBinding( + FanoutExchange handleDataGeneratorExchange, + Queue handleDataGeneratorCreateQueue) { + return BindingBuilder.bind(handleDataGeneratorCreateQueue).to(handleDataGeneratorExchange); + } +} + diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/repositories/TransportCourseRepository.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/repositories/TransportCourseRepository.java index 17a6d2fe..98726ea4 100644 --- a/transport-service/src/main/java/org/microarchitecturovisco/transport/repositories/TransportCourseRepository.java +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/repositories/TransportCourseRepository.java @@ -3,5 +3,7 @@ import org.microarchitecturovisco.transport.model.domain.TransportCourse; import org.springframework.data.jpa.repository.JpaRepository; -public interface TransportCourseRepository extends JpaRepository { +import java.util.UUID; + +public interface TransportCourseRepository extends JpaRepository { } diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportCommandService.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportCommandService.java index 2c2d6f69..bda681ad 100644 --- a/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportCommandService.java +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportCommandService.java @@ -4,12 +4,13 @@ import org.microarchitecturovisco.transport.model.cqrs.commands.CreateTransportCommand; import org.microarchitecturovisco.transport.model.cqrs.commands.CreateTransportReservationCommand; import org.microarchitecturovisco.transport.model.cqrs.commands.DeleteTransportReservationCommand; -import org.microarchitecturovisco.transport.model.events.TransportCreatedEvent; -import org.microarchitecturovisco.transport.model.events.TransportReservationCreatedEvent; -import org.microarchitecturovisco.transport.model.events.TransportReservationDeletedEvent; +import org.microarchitecturovisco.transport.model.domain.TransportCourse; +import org.microarchitecturovisco.transport.model.events.*; +import org.microarchitecturovisco.transport.repositories.TransportCourseRepository; import org.microarchitecturovisco.transport.repositories.TransportEventStore; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.List; import java.util.UUID; @@ -20,6 +21,7 @@ public class TransportCommandService { private final TransportEventStore transportEventStore; private final TransportEventSourcingHandler eventSourcingHandler; + private final TransportCourseRepository transportCourseRepository; public void createTransport(CreateTransportCommand command) { TransportCreatedEvent transportCreatedEvent = new TransportCreatedEvent( @@ -58,4 +60,34 @@ public void deleteReservation(DeleteTransportReservationCommand command) { eventSourcingHandler.project(List.of(reservationDeletedEvent)); } + public void updateTransport(UUID transportId, int capacity, float pricePerAdult) { + TransportUpdateEvent transportUpdateEvent = new TransportUpdateEvent(transportId, capacity, pricePerAdult); + transportEventStore.save(transportUpdateEvent); + eventSourcingHandler.project(List.of(transportUpdateEvent)); + } + + public void createTransport(UUID transportId, UUID courseId, LocalDateTime departureDate, int capacity, + float pricePerAdult) { + TransportCourse transportCourse = transportCourseRepository.findById(courseId).orElse(null); + if (transportCourse == null) return; + + TransportCreatedEvent transportCreatedEvent = TransportCreatedEvent.builder() + .idTransport(transportId) + .idTransportCourse(courseId) + .departureDate(departureDate) + .eventTimeStamp(LocalDateTime.now()) + .capacity(capacity) + .pricePerAdult(pricePerAdult) + .idDepartureLocation(transportCourse.getDepartureFrom().getId()) + .departureLocationCountry(transportCourse.getDepartureFrom().getCountry()) + .departureLocationRegion(transportCourse.getDepartureFrom().getRegion()) + .arrivalLocationCountry(transportCourse.getArrivalAt().getCountry()) + .arrivalLocationRegion(transportCourse.getArrivalAt().getRegion()) + .idArrivalLocation(transportCourse.getArrivalAt().getId()) + .type(transportCourse.getType()) + .build(); + transportEventStore.save(transportCreatedEvent); + eventSourcingHandler.project(List.of(transportCreatedEvent)); + } + } diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportEventSourcingHandler.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportEventSourcingHandler.java index 3abe2ca6..9843a570 100644 --- a/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportEventSourcingHandler.java +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportEventSourcingHandler.java @@ -5,10 +5,7 @@ import org.microarchitecturovisco.transport.model.domain.Transport; import org.microarchitecturovisco.transport.model.domain.TransportCourse; import org.microarchitecturovisco.transport.model.domain.TransportReservation; -import org.microarchitecturovisco.transport.model.events.TransportCreatedEvent; -import org.microarchitecturovisco.transport.model.events.TransportEvent; -import org.microarchitecturovisco.transport.model.events.TransportReservationCreatedEvent; -import org.microarchitecturovisco.transport.model.events.TransportReservationDeletedEvent; +import org.microarchitecturovisco.transport.model.events.*; import org.microarchitecturovisco.transport.repositories.LocationRepository; import org.microarchitecturovisco.transport.repositories.TransportCourseRepository; import org.microarchitecturovisco.transport.repositories.TransportRepository; @@ -39,6 +36,9 @@ public void project(List transportEvents) { if (transportEvent instanceof TransportReservationDeletedEvent) { apply((TransportReservationDeletedEvent) transportEvent); } + if (transportEvent instanceof TransportUpdateEvent){ + apply((TransportUpdateEvent) transportEvent); + } } } @@ -110,4 +110,12 @@ private void apply(TransportReservationDeletedEvent event) { } } + + private void apply(TransportUpdateEvent event) + { + Transport transport = transportRepository.findById(event.getIdTransport()).orElseThrow(RuntimeException::new); + transport.setCapacity(event.getCapacity()); + transport.setPricePerAdult(event.getPricePerAdult()); + transportRepository.save(transport); + } } diff --git a/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportsQueryService.java b/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportsQueryService.java index d034a17c..fdbe0ade 100644 --- a/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportsQueryService.java +++ b/transport-service/src/main/java/org/microarchitecturovisco/transport/services/TransportsQueryService.java @@ -14,6 +14,7 @@ import org.microarchitecturovisco.transport.model.mappers.TransportMapper; import org.microarchitecturovisco.transport.repositories.LocationRepository; import org.microarchitecturovisco.transport.repositories.TransportCourseRepository; +import org.microarchitecturovisco.transport.repositories.TransportEventStore; import org.microarchitecturovisco.transport.repositories.TransportRepository; import org.springframework.stereotype.Service; @@ -30,6 +31,8 @@ public class TransportsQueryService { private final TransportCourseRepository transportCourseRepository; private final TransportRepository transportRepository; private final LocationRepository locationRepository; + private final TransportEventSourcingHandler transportEventSourcingHandler; + private final TransportEventStore transportEventStore; public List getAllTransports() { List transports = transportRepository.findAll();