diff --git a/README.md b/README.md index d9cc1b9..dd5d0c4 100644 --- a/README.md +++ b/README.md @@ -1 +1,143 @@ -# reservation-service +# Reservation-Service +Bootstrap Skaffold configuration +Run the following command to generate a skaffold.yaml config file: +skaffold init + +### Use skaffold dev +Run the following command to begin using Skaffold for continuous development +skaffold dev + +### Provide external IP +minikube tunnel + +### Kafka +#### Create a topic and recovery +kubectl exec -it kafka-0 -- bash + +#### Create a topic named reservation with three partitions and a replication factor of 3. +kafka-topics --create --topic reservation --partitions 2 --replication-factor 2 --bootstrap-server kafka-0.kafka-headless.kafka.svc.cluster.local:9092 + +#### Verify the topic partitions are replicated across all three brokers: +kafka-topics --describe --topic reservation --bootstrap-server kafka-0.kafka-headless.kafka.svc.cluster.local:9092 + +### Debugging With Skaffold + + +## EventStorming Proccess +### Schema + +### Topic +1. reservation + +### Unstructured Exploration +1. ReservationRequestedEvent +Triggered by the customer submitting a reservation request. +2. AvailabilityConfirmed +Emitted by the system after validating the request and confirming availability. +1. ReservationCreatedEvent +Signals that a new reservation has been successfully created. +2. ReservationCanceledEvent +Indicates that a reservation has been cancelled. +3. ReservationModifiedEvent +Notifies that changes have been made to an existing reservation. +4. ReservationCheckedInEvent +Signals that a booked service or resource usage has started. +5. ReservationCheckedOutEvent +Indicates that a booked service or resource usage has ended. +6. AddedToWaitlistEvent +Notifies that a customer has been added to a waitlist for a service/resource. +7. PromotionAppliedEvent +Signals the successful application of a promotion or discount to a reservation. +8. ReservationExpiredEvent +Signals that a reservation request has expired due to inactivity. +9. OverreservationProcessedEvent +Signals that the system has handled the situation of overreservation by managing excess reservations. +10. ReservationConfirmationSentEvent +Indicates that a confirmation notification has been sent to the customer after a successful reservation. +11. PaymentAuthorizedEvent (Policy Event Trigger) +Signals successful authorization of payment associated with a reservation. +12. PaymentCompletedEvent +Indicates the successful completion of a payment transaction for a reservation. +13. PaymentFailedEvent +Signals that a payment transaction for a reservation has failed. + +### Timelines +Happy Path Workflow: +1. Reservation Creation +- Customer submits a reservation request. +- System validates the request and confirms availability. +- Reservation is successfully created. +- Confirmation is sent to the customer. +- Payment authorization is requested. +- Payment is successfully authorized. +- Payment completion is confirmed. +- Reservation is finalized. +2. Reservation Modification +- Customer requests a modification to an existing reservation. +- System validates the modification and confirms availability. +- Reservation is successfully updated. +- Confirmation of modification is sent to the customer. +- Payment authorization may be requested for additional charges. +- Payment, if required, is successfully authorized and completed. +- Updated reservation details are finalized. +3. Reservation Cancellation +- Customer requests cancellation of a reservation. +- System confirms cancellation. +- Reservation is successfully cancelled. +- Confirmation of cancellation is sent to the customer. +- Any applicable refunds are processed. +4. Check-In and Check-Out +- Customer checks in for a booked service/resource. +- System confirms check-in. +- Customer uses the service/resource. +- Customer checks out. +- System confirms check-out. + + +Alternative Path Workflow +1. Reservation Creation Failure +- Customer submits a reservation request. +- System validates the request but finds no availability. +- System notifies the customer of unavailability. +- Optionally, customer may be added to a waitlist. +2. Reservation Modification Failure +- Customer requests a modification to an existing reservation. +- System validates the modification but finds conflicts. +- System notifies the customer of the conflict and suggests alternatives. +3. Reservation Cancellation Failure +- Customer requests cancellation of a reservation. +- System encounters an error in cancellation. +- System notifies the customer of the failure and suggests contacting support. +4. Payment Failure +- Customer submits a reservation request. +- System validates the request and confirms availability. +- Payment authorization fails. +- System notifies the customer of the payment failure and suggests alternative payment methods. +5. Overreservation Handling +- Customer submits a reservation request. +- System validates the request and detects potential overreservation. +- System notifies the customer of the situation and suggests alternative reservation times or accommodations. + +### Commands +1. CreateReservationCommand +Initiates the process of creating a new reservation. +2. SendReservationConfirmationCommand +Sends a confirmation notification to the customer after a successful reservation. +3. CancelReservationCommand +Requests the cancellation of an existing reservation. +4. ModifyReservationCommand +Initiates changes to an existing reservation, such as altering the time, duration, or details of the reservation. +5. CheckinCommand +Indicates the beginning of a booked service or resource usage. +6. CheckoutCommand +Indicates the end of a booked service or resource usage. +7. AddToWaitlistCommand +Adds a customer to a waitlist for a service/resource that is currently unavailable. +8. ApplyPromotionCommand +Applies a promotion or discount to a reservation. +9. ExpireReservationCommand +Marks a reservation request as expired due to inactivity or lack of confirmation. +10. ProcessOverreservationCommand +Handles the situation of overreservation by managing the excess reservations. + + diff --git a/build-deploy-ks8.sh b/build-deploy-ks8.sh deleted file mode 100755 index 51f5523..0000000 --- a/build-deploy-ks8.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# eval $(minikube docker-env) -# Jib google docker build with minikube -./mvnw com.google.cloud.tools:jib-maven-plugin:dockerBuild -Dimage=reservation-service:v0.1.0-alpha - -# Build deployment and service -kubectl apply -f ./k8s \ No newline at end of file diff --git a/kustomize/base/application.yaml b/kustomize/base/application.yaml new file mode 100644 index 0000000..453642e --- /dev/null +++ b/kustomize/base/application.yaml @@ -0,0 +1,4 @@ +logging: + level: + org: + springframework: INFO \ No newline at end of file diff --git a/k8s/deployment.yaml b/kustomize/base/deployment.yaml similarity index 81% rename from k8s/deployment.yaml rename to kustomize/base/deployment.yaml index 10dbcab..9ebb11f 100644 --- a/k8s/deployment.yaml +++ b/kustomize/base/deployment.yaml @@ -2,6 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: reservation-service-deployment + namespace: reservation-develop labels: app: reservation-service spec: @@ -18,6 +19,9 @@ spec: containers: - name: reservation-service image: reservation-service:v0.1.0-alpha + volumeMounts: + - name: config-volume + mountPath: /workspace/config imagePullPolicy: Never # SHOULD NOT DO IT ON PRODUCTION the kubelet does not try fetching the image. If the image is somehow already present locally resources: limits: @@ -38,4 +42,9 @@ spec: # preStop: # exec: # command: ["sh", "-c", "sleep 10"] + + volumes: + - name: config-volume + configMap: + name: reservation-service-config \ No newline at end of file diff --git a/kustomize/base/kafka-local.yaml b/kustomize/base/kafka-local.yaml new file mode 100644 index 0000000..726655d --- /dev/null +++ b/kustomize/base/kafka-local.yaml @@ -0,0 +1,118 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kafka + namespace: reservation-develop +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: kafka + name: kafka-headless + namespace: reservation-develop +spec: + clusterIP: None + clusterIPs: + - None + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: tcp-kafka-int + port: 9092 + protocol: TCP + targetPort: tcp-kafka-int + - name: tcp-kafka-ctrl + port: 29093 + protocol: TCP + targetPort: tcp-kafka-ctrl + selector: + app: kafka + sessionAffinity: None + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: kafka + name: kafka + namespace: reservation-develop +spec: + podManagementPolicy: Parallel + replicas: 2 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: kafka # has to match .spec.template.metadata.labels + serviceName: kafka-headless + template: + metadata: + labels: + app: kafka # has to match .spec.selector.matchLabels + spec: + serviceAccountName: kafka + containers: + - command: + - sh + - -exc + - | + export CLUSTER_ID="6PMpHYL9QkeyXRj9Nrp4KA" && \ + export KAFKA_NODE_ID=${HOSTNAME##*-} + export KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${POD_NAME}.kafka-headless.reservation-develop.svc.cluster.local:9092 + export KAFKA_CONTROLLER_QUORUM_VOTERS="0@kafka-0.kafka-headless.reservation-develop.svc.cluster.local:29093,1@kafka-1.kafka-headless.reservation-develop.svc.cluster.local:29093" + + exec /etc/confluent/docker/run + env: + - name: KAFKA_CONTROLLER_LISTENER_NAMES + value: "CONTROLLER" + - name: KAFKA_LISTENERS + value: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:29093 + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + name: kafka + image: docker.io/confluentinc/confluent-local:7.5.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9092 + name: tcp-kafka-int + protocol: TCP + - containerPort: 29093 + name: tcp-kafka-ctrl + protocol: TCP + resources: + limits: + cpu: "1" + memory: 1400Mi + requests: + cpu: 250m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + runAsGroup: 1000 + runAsUser: 1000 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/kafka + name: config + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 1000 + terminationGracePeriodSeconds: 30 + volumes: + - emptyDir: {} + name: config + updateStrategy: + type: RollingUpdate \ No newline at end of file diff --git a/kustomize/base/kustomization.yaml b/kustomize/base/kustomization.yaml new file mode 100644 index 0000000..2bb9c46 --- /dev/null +++ b/kustomize/base/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- namespace.yaml +- kafka-local.yaml +- service.yaml +- deployment.yaml + +configMapGenerator: + - name: reservation-service-config + namespace: reservation-develop + files: + - application.yaml \ No newline at end of file diff --git a/kustomize/base/namespace.yaml b/kustomize/base/namespace.yaml new file mode 100644 index 0000000..29128fd --- /dev/null +++ b/kustomize/base/namespace.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: reservation-develop \ No newline at end of file diff --git a/k8s/service.yaml b/kustomize/base/service.yaml similarity index 86% rename from k8s/service.yaml rename to kustomize/base/service.yaml index a4508ba..8e323ff 100644 --- a/k8s/service.yaml +++ b/kustomize/base/service.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: name: reservation-service-kuservice + namespace: reservation-develop spec: type: LoadBalancer selector: diff --git a/kustomize/qa/kustomization.yaml b/kustomize/qa/kustomization.yaml new file mode 100644 index 0000000..3e84fb0 --- /dev/null +++ b/kustomize/qa/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../base + +patchesStrategicMerge: +- update-replicas.yaml \ No newline at end of file diff --git a/kustomize/qa/update-replicas.yaml b/kustomize/qa/update-replicas.yaml new file mode 100644 index 0000000..4fd3004 --- /dev/null +++ b/kustomize/qa/update-replicas.yaml @@ -0,0 +1,6 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reservation-service-deployment +spec: + replicas: 2 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 985957c..6a4e414 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,6 @@ org.flywaydb flyway-core - org.springframework.boot spring-boot-devtools @@ -93,6 +92,10 @@ mapstruct ${org.mapstruct.version} + + org.springframework.kafka + spring-kafka + diff --git a/skaffold.yaml b/skaffold.yaml index c44ee5a..35c3075 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -8,6 +8,6 @@ build: jib: project: com.ubluetech:reservation-service manifests: - rawYaml: - - k8s/deployment.yaml - - k8s/service.yaml + kustomize: + paths: + - kustomize/base diff --git a/src/main/java/com/ubluetech/reservationservice/application/ReservationCommandHandler.java b/src/main/java/com/ubluetech/reservationservice/application/ReservationCommandHandler.java new file mode 100644 index 0000000..46ef8ba --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/application/ReservationCommandHandler.java @@ -0,0 +1,23 @@ +package com.ubluetech.reservationservice.application; + +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Service; + +import com.ubluetech.reservationservice.domain.RequestReservationCommand; +import com.ubluetech.reservationservice.domain.ReservationRequestedEvent; +import com.ubluetech.reservationservice.infrastructure.CommandHandler; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +@Service +class ReservationCommandHandler implements CommandHandler { + private final KafkaTemplate kafkaTemplate; + + @Override + public void handle(RequestReservationCommand command) { + ReservationRequestedEvent event = new ReservationRequestedEvent(); + kafkaTemplate.send("reservation", event); + } + +} diff --git a/src/main/java/com/ubluetech/reservationservice/application/ReservationServiceImpl.java b/src/main/java/com/ubluetech/reservationservice/application/ReservationServiceImpl.java index f242123..dda6f58 100644 --- a/src/main/java/com/ubluetech/reservationservice/application/ReservationServiceImpl.java +++ b/src/main/java/com/ubluetech/reservationservice/application/ReservationServiceImpl.java @@ -1,6 +1,7 @@ package com.ubluetech.reservationservice.application; import com.ubluetech.reservationservice.domain.Reservation; +import com.ubluetech.reservationservice.infrastructure.ReservationRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/ubluetech/reservationservice/domain/EventType.java b/src/main/java/com/ubluetech/reservationservice/domain/EventType.java new file mode 100644 index 0000000..1ab0d42 --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/domain/EventType.java @@ -0,0 +1,15 @@ +package com.ubluetech.reservationservice.domain; + +enum EventType { + RESERVATION_REQUESTED_EVENT, + AVAILABILITY_CONFIRMED, + RESERVATION_CREATED_EVENT, + RESERVATION_CANCELED_EVENT, + RESERVATION_MODIFIED_EVENT, + RESERVATION_CHECKEDIN_EVENT, + RESERVATION_CHECKEDOUT_EVENT, + RESERVATION_CONFIRMATION_SENT_EVENT, + PAYMENT_AUTHORIZED_EVENT, + PAYMENT_COMPLETED_EVENT, + PAYMENT_FAILED_EVENT +} diff --git a/src/main/java/com/ubluetech/reservationservice/domain/Guest.java b/src/main/java/com/ubluetech/reservationservice/domain/Guest.java index 316026c..f453ea0 100644 --- a/src/main/java/com/ubluetech/reservationservice/domain/Guest.java +++ b/src/main/java/com/ubluetech/reservationservice/domain/Guest.java @@ -6,7 +6,7 @@ @Embeddable @Getter -class Guest { +public class Guest { @Column(nullable = false) private String fullName; diff --git a/src/main/java/com/ubluetech/reservationservice/domain/Metadata.java b/src/main/java/com/ubluetech/reservationservice/domain/Metadata.java new file mode 100644 index 0000000..6aa6074 --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/domain/Metadata.java @@ -0,0 +1,17 @@ +package com.ubluetech.reservationservice.domain; + +import java.time.LocalDateTime; +import java.util.UUID; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +class Metadata { + private UUID correlationId; + private LocalDateTime timestamp; + private String version; + private String source; + +} diff --git a/src/main/java/com/ubluetech/reservationservice/domain/RequestReservationCommand.java b/src/main/java/com/ubluetech/reservationservice/domain/RequestReservationCommand.java new file mode 100644 index 0000000..29e8e5f --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/domain/RequestReservationCommand.java @@ -0,0 +1,14 @@ +package com.ubluetech.reservationservice.domain; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +public class RequestReservationCommand { + private List guest; +} diff --git a/src/main/java/com/ubluetech/reservationservice/domain/ReservationRequestedEvent.java b/src/main/java/com/ubluetech/reservationservice/domain/ReservationRequestedEvent.java new file mode 100644 index 0000000..7c1c6d6 --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/domain/ReservationRequestedEvent.java @@ -0,0 +1,15 @@ +package com.ubluetech.reservationservice.domain; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class ReservationRequestedEvent { + private EventType eventType; + private Metadata metadata; + private List guests; + private List rooms; +} diff --git a/src/main/java/com/ubluetech/reservationservice/domain/RoomType.java b/src/main/java/com/ubluetech/reservationservice/domain/RoomType.java index 9b4e514..10f33fe 100644 --- a/src/main/java/com/ubluetech/reservationservice/domain/RoomType.java +++ b/src/main/java/com/ubluetech/reservationservice/domain/RoomType.java @@ -1,5 +1,5 @@ package com.ubluetech.reservationservice.domain; -public enum RoomType { +enum RoomType { SINGLE, DOUBLE, STUDIO, QUEEN, KING, TWIN, LUXURY, SUITE, VILLA, SMOKING } diff --git a/src/main/java/com/ubluetech/reservationservice/infrastructure/CommandHandler.java b/src/main/java/com/ubluetech/reservationservice/infrastructure/CommandHandler.java new file mode 100644 index 0000000..8b88d45 --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/infrastructure/CommandHandler.java @@ -0,0 +1,5 @@ +package com.ubluetech.reservationservice.infrastructure; + +public interface CommandHandler { + void handle(T command); +} diff --git a/src/main/java/com/ubluetech/reservationservice/infrastructure/EventListener.java b/src/main/java/com/ubluetech/reservationservice/infrastructure/EventListener.java new file mode 100644 index 0000000..4420b8b --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/infrastructure/EventListener.java @@ -0,0 +1,5 @@ +package com.ubluetech.reservationservice.infrastructure; + +public interface EventListener { + void onEvent(T event); +} diff --git a/src/main/java/com/ubluetech/reservationservice/infrastructure/KafkaTopicConfig.java b/src/main/java/com/ubluetech/reservationservice/infrastructure/KafkaTopicConfig.java new file mode 100644 index 0000000..bd4f40d --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/infrastructure/KafkaTopicConfig.java @@ -0,0 +1,22 @@ +package com.ubluetech.reservationservice.infrastructure; + +import org.apache.kafka.clients.admin.NewTopic; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.TopicBuilder; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +@Configuration +class KafkaTopicConfig { + private final KafkaTopicProperties kafkaTopicProperties; + + @Bean + public NewTopic reservationTopic() { + return TopicBuilder.name(kafkaTopicProperties.getName()) + .partitions(kafkaTopicProperties.getPartitions()) + .replicas(kafkaTopicProperties.getReplicas()) + .build(); + } +} diff --git a/src/main/java/com/ubluetech/reservationservice/infrastructure/KafkaTopicProperties.java b/src/main/java/com/ubluetech/reservationservice/infrastructure/KafkaTopicProperties.java new file mode 100644 index 0000000..d5b715b --- /dev/null +++ b/src/main/java/com/ubluetech/reservationservice/infrastructure/KafkaTopicProperties.java @@ -0,0 +1,27 @@ +package com.ubluetech.reservationservice.infrastructure; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import org.springframework.validation.annotation.Validated; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; + +@Component +@Getter +@Setter +@Validated +@ConfigurationProperties(prefix = "kafka.topic") +public class KafkaTopicProperties { + @NotNull @Size(max = 64) + private String name; + + @Min(3) @NotNull + private int partitions; + + @Min(1) @NotNull + private int replicas; +} diff --git a/src/main/java/com/ubluetech/reservationservice/application/ReservationRepository.java b/src/main/java/com/ubluetech/reservationservice/infrastructure/ReservationRepository.java similarity index 82% rename from src/main/java/com/ubluetech/reservationservice/application/ReservationRepository.java rename to src/main/java/com/ubluetech/reservationservice/infrastructure/ReservationRepository.java index e73ab10..42618db 100644 --- a/src/main/java/com/ubluetech/reservationservice/application/ReservationRepository.java +++ b/src/main/java/com/ubluetech/reservationservice/infrastructure/ReservationRepository.java @@ -1,4 +1,4 @@ -package com.ubluetech.reservationservice.application; +package com.ubluetech.reservationservice.infrastructure; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/ubluetech/reservationservice/presentation/ReservationController.java b/src/main/java/com/ubluetech/reservationservice/presentation/ReservationController.java index 47708d3..7d6db54 100644 --- a/src/main/java/com/ubluetech/reservationservice/presentation/ReservationController.java +++ b/src/main/java/com/ubluetech/reservationservice/presentation/ReservationController.java @@ -4,12 +4,14 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.ubluetech.reservationservice.application.ReservationRepository; -import com.ubluetech.reservationservice.domain.ReservationDto; -import com.ubluetech.reservationservice.domain.ReservationMapper; +import com.ubluetech.reservationservice.domain.RequestReservationCommand; +import com.ubluetech.reservationservice.infrastructure.CommandHandler; +import com.ubluetech.reservationservice.infrastructure.ReservationRepository; import lombok.RequiredArgsConstructor; @@ -20,6 +22,7 @@ public class ReservationController { private final ReservationRepository repository; private final ReservationMapper reservationMapper; + private final CommandHandler commandHandler; @GetMapping public List getAllReservations() { @@ -39,4 +42,9 @@ public ReservationDto getReservation(@PathVariable(value = "id") Long id) { .orElse(null) ); } + + @PostMapping + public void createReservation(@RequestBody RequestReservationCommand command) { + commandHandler.handle(command); + } } diff --git a/src/main/java/com/ubluetech/reservationservice/domain/ReservationDto.java b/src/main/java/com/ubluetech/reservationservice/presentation/ReservationDto.java similarity index 78% rename from src/main/java/com/ubluetech/reservationservice/domain/ReservationDto.java rename to src/main/java/com/ubluetech/reservationservice/presentation/ReservationDto.java index a471c98..03a22df 100644 --- a/src/main/java/com/ubluetech/reservationservice/domain/ReservationDto.java +++ b/src/main/java/com/ubluetech/reservationservice/presentation/ReservationDto.java @@ -1,4 +1,4 @@ -package com.ubluetech.reservationservice.domain; +package com.ubluetech.reservationservice.presentation; import java.time.LocalDate; @@ -7,7 +7,7 @@ @Getter @Setter -public class ReservationDto { +class ReservationDto { private Long reservationId; private String fullName; private String email; diff --git a/src/main/java/com/ubluetech/reservationservice/domain/ReservationMapper.java b/src/main/java/com/ubluetech/reservationservice/presentation/ReservationMapper.java similarity index 83% rename from src/main/java/com/ubluetech/reservationservice/domain/ReservationMapper.java rename to src/main/java/com/ubluetech/reservationservice/presentation/ReservationMapper.java index f5409cf..aa56a57 100644 --- a/src/main/java/com/ubluetech/reservationservice/domain/ReservationMapper.java +++ b/src/main/java/com/ubluetech/reservationservice/presentation/ReservationMapper.java @@ -1,9 +1,11 @@ -package com.ubluetech.reservationservice.domain; +package com.ubluetech.reservationservice.presentation; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; +import com.ubluetech.reservationservice.domain.Reservation; + @Mapper(componentModel = "spring") public interface ReservationMapper { ReservationMapper INSTANCE = Mappers.getMapper(ReservationMapper.class); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4ff8080..b003964 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,3 +8,24 @@ management.health.readinessstate.enabled=true # Handling In Fflight Requests server.shutdown=graceful + +# Kafka config +# spring.kafka.bootstrap-servers=kafka-headless:9092 +spring.kafka.bootstrap-servers=localhost:9092 +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer +#0: No wait for kafka response +#1: Leader write success, not wait for follower +#-1: wait for all leader, and replication +spring.kafka.producer.acks=-1 +spring.kafka.producer.retries=3 + +# Prevent duplicate send +spring.kafka.producer.properties.[enable.idempotence]=true +spring.kafka.producer.properties.[max.in.flight.requests.per.connection]=5 + + +# Kafka topic +kafka.topic.name=reservation +kafka.topic.partitions=3 +kafka.topic.replicas=1 +