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
+