CQRS Pattern - > first implement Customer module end to end.
This commit is contained in:
38
.idea/compiler.xml
generated
38
.idea/compiler.xml
generated
@@ -11,8 +11,27 @@
|
||||
<module name="order-application-service" />
|
||||
<module name="common-domain" />
|
||||
<module name="order-core-domain" />
|
||||
<module name="customer-container" />
|
||||
<module name="customer-service-application" />
|
||||
<module name="restaurant-core-domain" />
|
||||
<module name="payment-domain-core" />
|
||||
<module name="saga" />
|
||||
<module name="restaurant-application-service" />
|
||||
<module name="customer-messaging" />
|
||||
<module name="order-application-service" />
|
||||
<module name="kafka-producer" />
|
||||
<module name="customer-data-access" />
|
||||
<module name="order-data-access" />
|
||||
<module name="payment-dataaccess" />
|
||||
<module name="common-data-access" />
|
||||
<module name="outbox" />
|
||||
<module name="order-container" />
|
||||
<module name="order-app" />
|
||||
<module name="restaurant-dataaccess" />
|
||||
<module name="payment-container" />
|
||||
<module name="customer-application" />
|
||||
<module name="customer-domain-core" />
|
||||
<module name="restaurant-messaging" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
@@ -21,9 +40,26 @@
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||
<module name="common" options="-parameters" />
|
||||
<module name="clean-hexagonal-architecture-kafka-saga-outbox" options="" />
|
||||
<module name="common" options="" />
|
||||
<module name="common-application" options="-parameters" />
|
||||
<module name="common-data-access" options="-parameters" />
|
||||
<module name="common-domain" options="-parameters" />
|
||||
<module name="customer-application" options="-parameters" />
|
||||
<module name="customer-container" options="-parameters" />
|
||||
<module name="customer-data-access" options="-parameters" />
|
||||
<module name="customer-domain" options="" />
|
||||
<module name="customer-domain-core" options="-parameters" />
|
||||
<module name="customer-messaging" options="-parameters" />
|
||||
<module name="customer-service" options="" />
|
||||
<module name="customer-service-application" options="-parameters" />
|
||||
<module name="food-ordering-system" options="" />
|
||||
<module name="infrastructure" options="" />
|
||||
<module name="kafka" options="" />
|
||||
<module name="kafka-config" options="-parameters" />
|
||||
<module name="kafka-consumer" options="-parameters" />
|
||||
<module name="kafka-model" options="-parameters" />
|
||||
<module name="kafka-producer" options="-parameters" />
|
||||
<module name="order-app" options="-parameters" />
|
||||
<module name="order-application-service" options="-parameters" />
|
||||
<module name="order-container" options="-parameters" />
|
||||
|
||||
20
.idea/encodings.xml
generated
20
.idea/encodings.xml
generated
@@ -4,6 +4,26 @@
|
||||
<file url="file://$PROJECT_DIR$/common/common-domain/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-application/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-container/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-data-access/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-domain/customer-domain-core/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-domain/customer-service-application/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-domain/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-domain/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/customer-messaging/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/customer-service/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/kafka/kafka-config/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/kafka/kafka-consumer/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/kafka/kafka-model/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/kafka/kafka-producer/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/kafka/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/kafka/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/outbox/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/saga/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/infrastructure/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/order-service/order-app/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/order-service/order-app/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/order-service/order-container/src/main/java" charset="UTF-8" />
|
||||
|
||||
33
customer-service/customer-application/pom.xml
Normal file
33
customer-service/customer-application/pom.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-service</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-application</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-service-application</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>common-application</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.food.order.system.customer.rest.application.handler;
|
||||
|
||||
import com.food.order.system.application.handler.ErrorDTO;
|
||||
import com.food.order.system.application.handler.GlobalExceptionHandler;
|
||||
import com.food.order.system.customer.domain.exception.CustomerDomainException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class CustomerGlobalExceptionHandler extends GlobalExceptionHandler {
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(value = {CustomerDomainException.class})
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public ErrorDTO handleException(CustomerDomainException exception) {
|
||||
log.error(exception.getMessage(), exception);
|
||||
return ErrorDTO.builder().code(HttpStatus.BAD_REQUEST.getReasonPhrase())
|
||||
.message(exception.getMessage()).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.food.order.system.customer.rest.application.rest;
|
||||
|
||||
import com.food.order.system.customer.service.create.CreateCustomerCommand;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerResponse;
|
||||
import com.food.order.system.customer.service.ports.input.service.CustomerApplicationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping(value = "/customers", produces = "application/vnd.api.v1+json")
|
||||
public class CustomerController {
|
||||
|
||||
private final CustomerApplicationService customerApplicationService;
|
||||
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<CreateCustomerResponse> createCustomer(@RequestBody CreateCustomerCommand
|
||||
createCustomerCommand) {
|
||||
log.info("Creating customer with username: {}", createCustomerCommand.username());
|
||||
CreateCustomerResponse response = customerApplicationService.createCustomer(createCustomerCommand);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
}
|
||||
63
customer-service/customer-container/pom.xml
Normal file
63
customer-service/customer-container/pom.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-service</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-container</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-service-application</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-domain-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-data-access</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-messaging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-application</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<image>
|
||||
<name>${project.groupId}/customer.service:${project.version}</name>
|
||||
</image>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>build-image</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.food.order.system.customer.service;
|
||||
|
||||
import com.food.order.system.customer.domain.CustomerDomainService;
|
||||
import com.food.order.system.customer.domain.CustomerDomainServiceImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class BeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public CustomerDomainService customerDomainService() {
|
||||
return new CustomerDomainServiceImpl();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.food.order.system.customer.service;
|
||||
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@EnableJpaRepositories(basePackages = {"com.food.order.system.customer.dataaccess",
|
||||
"com.food.order.system.common.data.access"})
|
||||
@EntityScan(basePackages = {"com.food.order.system.customer.dataaccess",
|
||||
"com.food.order.system.common.data.access"})
|
||||
@SpringBootApplication(scanBasePackages = "com.food.order")
|
||||
public class CustomerServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CustomerServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
server:
|
||||
port: 8184
|
||||
|
||||
customer-service:
|
||||
customer-topic-name: customer
|
||||
|
||||
|
||||
spring:
|
||||
jpa:
|
||||
open-in-view: false
|
||||
show-sql: false
|
||||
database-platform: org.hibernate.dialect.PostgreSQL9Dialect
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.PostgreSQL9Dialect
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:5432/postgres?currentSchema=customer&binaryTransfer=true&reWriteBatchedInserts=true
|
||||
username: postgres
|
||||
password: postgres
|
||||
driver-class-name: org.postgresql.Driver
|
||||
sql:
|
||||
init:
|
||||
mode: always
|
||||
schema-locations: classpath:init-schema.sql
|
||||
data-locations: classpath:init-data.sql
|
||||
platform: postgres
|
||||
|
||||
kafka-config:
|
||||
bootstrap-servers: localhost:19092, localhost:29092, localhost:39092
|
||||
schema-registry-url-key: schema.registry.url
|
||||
schema-registry-url: http://localhost:8081
|
||||
num-of-partitions: 3
|
||||
replication-factor: 3
|
||||
|
||||
kafka-producer-config:
|
||||
key-serializer-class: org.apache.kafka.common.serialization.StringSerializer
|
||||
value-serializer-class: io.confluent.kafka.serializers.KafkaAvroSerializer
|
||||
compression-type: snappy
|
||||
acks: all
|
||||
batch-size: 16384
|
||||
batch-size-boost-factor: 100
|
||||
linger-ms: 5
|
||||
request-timeout-ms: 60000
|
||||
retry-count: 5
|
||||
33
customer-service/customer-data-access/pom.xml
Normal file
33
customer-service/customer-data-access/pom.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-service</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-data-access</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-service-application</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>common-data-access</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.food.order.system.customer.dataaccess.adapter;
|
||||
|
||||
import com.food.order.system.customer.dataaccess.mapper.CustomerDataAccessMapper;
|
||||
import com.food.order.system.customer.dataaccess.repository.CustomerJpaRepository;
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.customer.service.ports.output.repository.CustomerRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomerRepositoryImpl implements CustomerRepository {
|
||||
|
||||
private final CustomerJpaRepository customerJpaRepository;
|
||||
|
||||
private final CustomerDataAccessMapper customerDataAccessMapper;
|
||||
|
||||
public CustomerRepositoryImpl(CustomerJpaRepository customerJpaRepository,
|
||||
CustomerDataAccessMapper customerDataAccessMapper) {
|
||||
this.customerJpaRepository = customerJpaRepository;
|
||||
this.customerDataAccessMapper = customerDataAccessMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Customer createCustomer(Customer customer) {
|
||||
return customerDataAccessMapper.customerEntityToCustomer(
|
||||
customerJpaRepository.save(customerDataAccessMapper.customerToCustomerEntity(customer)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.food.order.system.customer.dataaccess.entity;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "customers")
|
||||
@Entity
|
||||
public class CustomerEntity {
|
||||
|
||||
@Id
|
||||
private UUID id;
|
||||
private String username;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.food.order.system.customer.dataaccess.exception;
|
||||
|
||||
public class CustomerDataaccessException extends RuntimeException {
|
||||
|
||||
public CustomerDataaccessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.food.order.system.customer.dataaccess.mapper;
|
||||
|
||||
import com.food.order.system.customer.dataaccess.entity.CustomerEntity;
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.valueobject.CustomerId;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomerDataAccessMapper {
|
||||
|
||||
public Customer customerEntityToCustomer(CustomerEntity customerEntity) {
|
||||
return new Customer(new CustomerId(customerEntity.getId()),
|
||||
customerEntity.getUsername(),
|
||||
customerEntity.getFirstName(),
|
||||
customerEntity.getLastName());
|
||||
}
|
||||
|
||||
public CustomerEntity customerToCustomerEntity(Customer customer) {
|
||||
return CustomerEntity.builder()
|
||||
.id(customer.getId().getValue())
|
||||
.username(customer.getUsername())
|
||||
.firstName(customer.getFirstName())
|
||||
.lastName(customer.getLastName())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.food.order.system.customer.dataaccess.repository;
|
||||
|
||||
import com.food.order.system.customer.dataaccess.entity.CustomerEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface CustomerJpaRepository extends JpaRepository<CustomerEntity, UUID> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-domain</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-domain-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>common-domain</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.food.order.system.customer.domain;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
|
||||
public interface CustomerDomainService {
|
||||
|
||||
CustomerCreatedEvent validateAndInitiateCustomer(Customer customer);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.food.order.system.customer.domain;
|
||||
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
@Slf4j
|
||||
public class CustomerDomainServiceImpl implements CustomerDomainService {
|
||||
|
||||
public CustomerCreatedEvent validateAndInitiateCustomer(Customer customer) {
|
||||
//Any Business logic required to run for a customer creation
|
||||
log.info("Customer with id: {} is initiated", customer.getId().getValue());
|
||||
return new CustomerCreatedEvent(customer, ZonedDateTime.now(ZoneId.of("UTC")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.food.order.system.customer.domain.entity;
|
||||
|
||||
|
||||
import com.food.order.system.entity.AggregateRoot;
|
||||
import com.food.order.system.valueobject.CustomerId;
|
||||
|
||||
public class Customer extends AggregateRoot<CustomerId> {
|
||||
private final String username;
|
||||
private final String firstName;
|
||||
private final String lastName;
|
||||
|
||||
public Customer(CustomerId customerId, String username, String firstName, String lastName) {
|
||||
super.setId(customerId);
|
||||
this.username = username;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.food.order.system.customer.domain.event;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.event.DomainEvent;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
public class CustomerCreatedEvent implements DomainEvent<Customer> {
|
||||
|
||||
private final Customer customer;
|
||||
|
||||
private final ZonedDateTime createdAt;
|
||||
|
||||
public CustomerCreatedEvent(Customer customer, ZonedDateTime createdAt) {
|
||||
this.customer = customer;
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.food.order.system.customer.domain.exception;
|
||||
|
||||
|
||||
import com.food.order.system.exception.DomainException;
|
||||
|
||||
public class CustomerDomainException extends DomainException {
|
||||
|
||||
public CustomerDomainException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-domain</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-service-application</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-domain-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>common-domain</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.food.order.system.customer.service;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerCommand;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerResponse;
|
||||
import com.food.order.system.customer.service.mapper.CustomerDataMapper;
|
||||
import com.food.order.system.customer.service.ports.input.service.CustomerApplicationService;
|
||||
import com.food.order.system.customer.service.ports.output.message.publisher.CustomerMessagePublisher;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Slf4j
|
||||
@Validated
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
class CustomerApplicationServiceImpl implements CustomerApplicationService {
|
||||
|
||||
private final CustomerCreateCommandHandler customerCreateCommandHandler;
|
||||
|
||||
private final CustomerDataMapper customerDataMapper;
|
||||
|
||||
private final CustomerMessagePublisher customerMessagePublisher;
|
||||
|
||||
|
||||
@Override
|
||||
public CreateCustomerResponse createCustomer(CreateCustomerCommand createCustomerCommand) {
|
||||
CustomerCreatedEvent customerCreatedEvent = customerCreateCommandHandler.createCustomer(createCustomerCommand);
|
||||
customerMessagePublisher.publish(customerCreatedEvent);
|
||||
return customerDataMapper
|
||||
.customerToCreateCustomerResponse(customerCreatedEvent.getCustomer(),
|
||||
"Customer saved successfully!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.food.order.system.customer.service;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.CustomerDomainService;
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
import com.food.order.system.customer.domain.exception.CustomerDomainException;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerCommand;
|
||||
import com.food.order.system.customer.service.mapper.CustomerDataMapper;
|
||||
import com.food.order.system.customer.service.ports.output.repository.CustomerRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class CustomerCreateCommandHandler {
|
||||
|
||||
private final CustomerDomainService customerDomainService;
|
||||
|
||||
private final CustomerRepository customerRepository;
|
||||
|
||||
private final CustomerDataMapper customerDataMapper;
|
||||
|
||||
|
||||
|
||||
@Transactional
|
||||
public CustomerCreatedEvent createCustomer(CreateCustomerCommand createCustomerCommand) {
|
||||
Customer customer = customerDataMapper.createCustomerCommandToCustomer(createCustomerCommand);
|
||||
CustomerCreatedEvent customerCreatedEvent = customerDomainService.validateAndInitiateCustomer(customer);
|
||||
Customer savedCustomer = customerRepository.createCustomer(customer);
|
||||
if (savedCustomer == null) {
|
||||
log.error("Could not save customer with id: {}", createCustomerCommand.customerId());
|
||||
throw new CustomerDomainException("Could not save customer with id " +
|
||||
createCustomerCommand.customerId());
|
||||
}
|
||||
log.info("Returning CustomerCreatedEvent for customer id: {}", createCustomerCommand.customerId());
|
||||
return customerCreatedEvent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.food.order.system.customer.service.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "customer-service")
|
||||
public class CustomerServiceConfigData {
|
||||
private String customerTopicName;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.food.order.system.customer.service.create;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.UUID;
|
||||
|
||||
@Builder
|
||||
public record CreateCustomerCommand(@NotNull UUID customerId, @NotNull String username, @NotNull String firstName,
|
||||
@NotNull String lastName) {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.food.order.system.customer.service.create;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.UUID;
|
||||
|
||||
@Builder
|
||||
public record CreateCustomerResponse(@NotNull UUID customerId, @NotNull String message) {
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.food.order.system.customer.service.mapper;
|
||||
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerCommand;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerResponse;
|
||||
import com.food.order.system.valueobject.CustomerId;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomerDataMapper {
|
||||
|
||||
public Customer createCustomerCommandToCustomer(CreateCustomerCommand createCustomerCommand) {
|
||||
return new Customer(new CustomerId(createCustomerCommand.customerId()),
|
||||
createCustomerCommand.username(),
|
||||
createCustomerCommand.firstName(),
|
||||
createCustomerCommand.lastName());
|
||||
}
|
||||
|
||||
public CreateCustomerResponse customerToCreateCustomerResponse(Customer customer, String message) {
|
||||
return new CreateCustomerResponse(customer.getId().getValue(), message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.food.order.system.customer.service.ports.input.service;
|
||||
|
||||
|
||||
import com.food.order.system.customer.service.create.CreateCustomerCommand;
|
||||
import com.food.order.system.customer.service.create.CreateCustomerResponse;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface CustomerApplicationService {
|
||||
|
||||
CreateCustomerResponse createCustomer(@Valid CreateCustomerCommand createCustomerCommand);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.food.order.system.customer.service.ports.output.message.publisher;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
|
||||
public interface CustomerMessagePublisher {
|
||||
|
||||
void publish(CustomerCreatedEvent customerCreatedEvent);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.food.order.system.customer.service.ports.output.repository;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.entity.Customer;
|
||||
|
||||
public interface CustomerRepository {
|
||||
|
||||
Customer createCustomer(Customer customer);
|
||||
}
|
||||
20
customer-service/customer-domain/pom.xml
Normal file
20
customer-service/customer-domain/pom.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-service</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-domain</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>customer-domain-core</module>
|
||||
<module>customer-service-application</module>
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
30
customer-service/customer-messaging/pom.xml
Normal file
30
customer-service/customer-messaging/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>customer-service</artifactId>
|
||||
<groupId>com.food.order</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-messaging</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-service-application</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>kafka-producer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>kafka-model</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.food.order.system.customer.messaging.mapper;
|
||||
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
import com.food.order.system.kafka.order.avro.model.CustomerAvroModel;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomerMessagingDataMapper {
|
||||
|
||||
public CustomerAvroModel paymentResponseAvroModelToPaymentResponse(CustomerCreatedEvent
|
||||
customerCreatedEvent) {
|
||||
return CustomerAvroModel.newBuilder()
|
||||
.setId(customerCreatedEvent.getCustomer().getId().getValue().toString())
|
||||
.setUsername(customerCreatedEvent.getCustomer().getUsername())
|
||||
.setFirstName(customerCreatedEvent.getCustomer().getFirstName())
|
||||
.setLastName(customerCreatedEvent.getCustomer().getLastName())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.food.order.system.customer.messaging.publisher.kafka;
|
||||
|
||||
|
||||
import com.food.order.system.customer.domain.event.CustomerCreatedEvent;
|
||||
import com.food.order.system.customer.messaging.mapper.CustomerMessagingDataMapper;
|
||||
import com.food.order.system.customer.service.config.CustomerServiceConfigData;
|
||||
import com.food.order.system.customer.service.ports.output.message.publisher.CustomerMessagePublisher;
|
||||
import com.food.order.system.kafka.order.avro.model.CustomerAvroModel;
|
||||
import com.food.order.system.kafka.producer.service.KafkaProducer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.kafka.clients.producer.RecordMetadata;
|
||||
import org.springframework.kafka.support.SendResult;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CustomerCreatedEventKafkaPublisher implements CustomerMessagePublisher {
|
||||
|
||||
private final CustomerMessagingDataMapper customerMessagingDataMapper;
|
||||
|
||||
private final KafkaProducer<String, CustomerAvroModel> kafkaProducer;
|
||||
|
||||
private final CustomerServiceConfigData customerServiceConfigData;
|
||||
|
||||
@Override
|
||||
public void publish(CustomerCreatedEvent customerCreatedEvent) {
|
||||
log.info("Received CustomerCreatedEvent for customer id: {}",
|
||||
customerCreatedEvent.getCustomer().getId().getValue());
|
||||
try {
|
||||
CustomerAvroModel customerAvroModel = customerMessagingDataMapper
|
||||
.paymentResponseAvroModelToPaymentResponse(customerCreatedEvent);
|
||||
|
||||
kafkaProducer.send(customerServiceConfigData.getCustomerTopicName(), customerAvroModel.getId(),
|
||||
customerAvroModel,
|
||||
getCallback(customerServiceConfigData.getCustomerTopicName(), customerAvroModel));
|
||||
|
||||
log.info("CustomerCreatedEvent sent to kafka for customer id: {}",
|
||||
customerAvroModel.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("Error while sending CustomerCreatedEvent to kafka for customer id: {}," +
|
||||
" error: {}", customerCreatedEvent.getCustomer().getId().getValue(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private ListenableFutureCallback<SendResult<String, CustomerAvroModel>>
|
||||
getCallback(String topicName, CustomerAvroModel message) {
|
||||
return new ListenableFutureCallback<>() {
|
||||
@Override
|
||||
public void onFailure(Throwable throwable) {
|
||||
log.error("Error while sending message {} to topic {}", message.toString(), topicName, throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SendResult<String, CustomerAvroModel> result) {
|
||||
RecordMetadata metadata = result.getRecordMetadata();
|
||||
log.info("Received new metadata. Topic: {}; Partition {}; Offset {}; Timestamp {}, at time {}",
|
||||
metadata.topic(),
|
||||
metadata.partition(),
|
||||
metadata.offset(),
|
||||
metadata.timestamp(),
|
||||
System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -10,46 +10,15 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>customer-service</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>customer-container</module>
|
||||
<module>customer-application</module>
|
||||
<module>customer-data-access</module>
|
||||
<module>customer-messaging</module>
|
||||
<module>customer-domain</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<image>
|
||||
<name>${project.groupId}/customer.service:${project.version}</name>
|
||||
</image>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>build-image</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.food.order.system.customer.service;
|
||||
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "com.food.order")
|
||||
public class CustomerServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CustomerServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
server:
|
||||
port: 8184
|
||||
|
||||
spring:
|
||||
jpa:
|
||||
open-in-view: false
|
||||
show-sql: false
|
||||
database-platform: org.hibernate.dialect.PostgreSQL9Dialect
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.PostgreSQL9Dialect
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:5432/postgres?currentSchema=customer&binaryTransfer=true&reWriteBatchedInserts=true
|
||||
username: postgres
|
||||
password: postgres
|
||||
driver-class-name: org.postgresql.Driver
|
||||
sql:
|
||||
init:
|
||||
mode: always
|
||||
schema-locations: classpath:init-schema.sql
|
||||
data-locations: classpath:init-data.sql
|
||||
platform: postgres
|
||||
@@ -13,12 +13,14 @@ services:
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --topic payment-response-value --delete --if-exists
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --topic restaurant-approval-request-value --delete --if-exists
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --topic restaurant-approval-response-value --delete --if-exists
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --topic customer-value --delete --if-exists
|
||||
|
||||
echo -e 'Creating kafka topics'
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic payment-request-value --replication-factor 3 --partitions 3
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic payment-response-value --replication-factor 3 --partitions 3
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic restaurant-approval-request-value --replication-factor 3 --partitions 3
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic restaurant-approval-response-value --replication-factor 3 --partitions 3
|
||||
kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic customer-value --replication-factor 3 --partitions 3
|
||||
|
||||
|
||||
echo -e 'Successfully created the following topics:'
|
||||
|
||||
@@ -0,0 +1,512 @@
|
||||
/**
|
||||
* Autogenerated by Avro
|
||||
*
|
||||
* DO NOT EDIT DIRECTLY
|
||||
*/
|
||||
package com.food.order.system.kafka.order.avro.model;
|
||||
|
||||
import org.apache.avro.message.BinaryMessageDecoder;
|
||||
import org.apache.avro.message.BinaryMessageEncoder;
|
||||
import org.apache.avro.message.SchemaStore;
|
||||
import org.apache.avro.specific.SpecificData;
|
||||
|
||||
@org.apache.avro.specific.AvroGenerated
|
||||
public class CustomerAvroModel extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
|
||||
private static final long serialVersionUID = 7953499667909084838L;
|
||||
|
||||
|
||||
public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"CustomerAvroModel\",\"namespace\":\"com.food.order.system.kafka.order.avro.model\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"username\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"firstName\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"lastName\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}]}");
|
||||
public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
|
||||
|
||||
private static final SpecificData MODEL$ = new SpecificData();
|
||||
|
||||
private static final BinaryMessageEncoder<CustomerAvroModel> ENCODER =
|
||||
new BinaryMessageEncoder<CustomerAvroModel>(MODEL$, SCHEMA$);
|
||||
|
||||
private static final BinaryMessageDecoder<CustomerAvroModel> DECODER =
|
||||
new BinaryMessageDecoder<CustomerAvroModel>(MODEL$, SCHEMA$);
|
||||
|
||||
/**
|
||||
* Return the BinaryMessageEncoder instance used by this class.
|
||||
* @return the message encoder used by this class
|
||||
*/
|
||||
public static BinaryMessageEncoder<CustomerAvroModel> getEncoder() {
|
||||
return ENCODER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BinaryMessageDecoder instance used by this class.
|
||||
* @return the message decoder used by this class
|
||||
*/
|
||||
public static BinaryMessageDecoder<CustomerAvroModel> getDecoder() {
|
||||
return DECODER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
|
||||
* @param resolver a {@link SchemaStore} used to find schemas by fingerprint
|
||||
* @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
|
||||
*/
|
||||
public static BinaryMessageDecoder<CustomerAvroModel> createDecoder(SchemaStore resolver) {
|
||||
return new BinaryMessageDecoder<CustomerAvroModel>(MODEL$, SCHEMA$, resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes this CustomerAvroModel to a ByteBuffer.
|
||||
* @return a buffer holding the serialized data for this instance
|
||||
* @throws java.io.IOException if this instance could not be serialized
|
||||
*/
|
||||
public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
|
||||
return ENCODER.encode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a CustomerAvroModel from a ByteBuffer.
|
||||
* @param b a byte buffer holding serialized data for an instance of this class
|
||||
* @return a CustomerAvroModel instance decoded from the given buffer
|
||||
* @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
|
||||
*/
|
||||
public static CustomerAvroModel fromByteBuffer(
|
||||
java.nio.ByteBuffer b) throws java.io.IOException {
|
||||
return DECODER.decode(b);
|
||||
}
|
||||
|
||||
private java.lang.String id;
|
||||
private java.lang.String username;
|
||||
private java.lang.String firstName;
|
||||
private java.lang.String lastName;
|
||||
|
||||
/**
|
||||
* Default constructor. Note that this does not initialize fields
|
||||
* to their default values from the schema. If that is desired then
|
||||
* one should use <code>newBuilder()</code>.
|
||||
*/
|
||||
public CustomerAvroModel() {}
|
||||
|
||||
/**
|
||||
* All-args constructor.
|
||||
* @param id The new value for id
|
||||
* @param username The new value for username
|
||||
* @param firstName The new value for firstName
|
||||
* @param lastName The new value for lastName
|
||||
*/
|
||||
public CustomerAvroModel(java.lang.String id, java.lang.String username, java.lang.String firstName, java.lang.String lastName) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
|
||||
public org.apache.avro.Schema getSchema() { return SCHEMA$; }
|
||||
// Used by DatumWriter. Applications should not call.
|
||||
public java.lang.Object get(int field$) {
|
||||
switch (field$) {
|
||||
case 0: return id;
|
||||
case 1: return username;
|
||||
case 2: return firstName;
|
||||
case 3: return lastName;
|
||||
default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
|
||||
}
|
||||
}
|
||||
|
||||
private static final org.apache.avro.Conversion<?>[] conversions =
|
||||
new org.apache.avro.Conversion<?>[] {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
};
|
||||
|
||||
@Override
|
||||
public org.apache.avro.Conversion<?> getConversion(int field) {
|
||||
return conversions[field];
|
||||
}
|
||||
|
||||
// Used by DatumReader. Applications should not call.
|
||||
@SuppressWarnings(value="unchecked")
|
||||
public void put(int field$, java.lang.Object value$) {
|
||||
switch (field$) {
|
||||
case 0: id = value$ != null ? value$.toString() : null; break;
|
||||
case 1: username = value$ != null ? value$.toString() : null; break;
|
||||
case 2: firstName = value$ != null ? value$.toString() : null; break;
|
||||
case 3: lastName = value$ != null ? value$.toString() : null; break;
|
||||
default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'id' field.
|
||||
* @return The value of the 'id' field.
|
||||
*/
|
||||
public java.lang.String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'id' field.
|
||||
* @param value the value to set.
|
||||
*/
|
||||
public void setId(java.lang.String value) {
|
||||
this.id = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'username' field.
|
||||
* @return The value of the 'username' field.
|
||||
*/
|
||||
public java.lang.String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'username' field.
|
||||
* @param value the value to set.
|
||||
*/
|
||||
public void setUsername(java.lang.String value) {
|
||||
this.username = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'firstName' field.
|
||||
* @return The value of the 'firstName' field.
|
||||
*/
|
||||
public java.lang.String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'firstName' field.
|
||||
* @param value the value to set.
|
||||
*/
|
||||
public void setFirstName(java.lang.String value) {
|
||||
this.firstName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'lastName' field.
|
||||
* @return The value of the 'lastName' field.
|
||||
*/
|
||||
public java.lang.String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'lastName' field.
|
||||
* @param value the value to set.
|
||||
*/
|
||||
public void setLastName(java.lang.String value) {
|
||||
this.lastName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CustomerAvroModel RecordBuilder.
|
||||
* @return A new CustomerAvroModel RecordBuilder
|
||||
*/
|
||||
public static com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder newBuilder() {
|
||||
return new com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CustomerAvroModel RecordBuilder by copying an existing Builder.
|
||||
* @param other The existing builder to copy.
|
||||
* @return A new CustomerAvroModel RecordBuilder
|
||||
*/
|
||||
public static com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder newBuilder(com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder other) {
|
||||
if (other == null) {
|
||||
return new com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder();
|
||||
} else {
|
||||
return new com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder(other);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CustomerAvroModel RecordBuilder by copying an existing CustomerAvroModel instance.
|
||||
* @param other The existing instance to copy.
|
||||
* @return A new CustomerAvroModel RecordBuilder
|
||||
*/
|
||||
public static com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder newBuilder(com.food.order.system.kafka.order.avro.model.CustomerAvroModel other) {
|
||||
if (other == null) {
|
||||
return new com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder();
|
||||
} else {
|
||||
return new com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder(other);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RecordBuilder for CustomerAvroModel instances.
|
||||
*/
|
||||
@org.apache.avro.specific.AvroGenerated
|
||||
public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<CustomerAvroModel>
|
||||
implements org.apache.avro.data.RecordBuilder<CustomerAvroModel> {
|
||||
|
||||
private java.lang.String id;
|
||||
private java.lang.String username;
|
||||
private java.lang.String firstName;
|
||||
private java.lang.String lastName;
|
||||
|
||||
/** Creates a new Builder */
|
||||
private Builder() {
|
||||
super(SCHEMA$, MODEL$);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder by copying an existing Builder.
|
||||
* @param other The existing Builder to copy.
|
||||
*/
|
||||
private Builder(com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder other) {
|
||||
super(other);
|
||||
if (isValidValue(fields()[0], other.id)) {
|
||||
this.id = data().deepCopy(fields()[0].schema(), other.id);
|
||||
fieldSetFlags()[0] = other.fieldSetFlags()[0];
|
||||
}
|
||||
if (isValidValue(fields()[1], other.username)) {
|
||||
this.username = data().deepCopy(fields()[1].schema(), other.username);
|
||||
fieldSetFlags()[1] = other.fieldSetFlags()[1];
|
||||
}
|
||||
if (isValidValue(fields()[2], other.firstName)) {
|
||||
this.firstName = data().deepCopy(fields()[2].schema(), other.firstName);
|
||||
fieldSetFlags()[2] = other.fieldSetFlags()[2];
|
||||
}
|
||||
if (isValidValue(fields()[3], other.lastName)) {
|
||||
this.lastName = data().deepCopy(fields()[3].schema(), other.lastName);
|
||||
fieldSetFlags()[3] = other.fieldSetFlags()[3];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder by copying an existing CustomerAvroModel instance
|
||||
* @param other The existing instance to copy.
|
||||
*/
|
||||
private Builder(com.food.order.system.kafka.order.avro.model.CustomerAvroModel other) {
|
||||
super(SCHEMA$, MODEL$);
|
||||
if (isValidValue(fields()[0], other.id)) {
|
||||
this.id = data().deepCopy(fields()[0].schema(), other.id);
|
||||
fieldSetFlags()[0] = true;
|
||||
}
|
||||
if (isValidValue(fields()[1], other.username)) {
|
||||
this.username = data().deepCopy(fields()[1].schema(), other.username);
|
||||
fieldSetFlags()[1] = true;
|
||||
}
|
||||
if (isValidValue(fields()[2], other.firstName)) {
|
||||
this.firstName = data().deepCopy(fields()[2].schema(), other.firstName);
|
||||
fieldSetFlags()[2] = true;
|
||||
}
|
||||
if (isValidValue(fields()[3], other.lastName)) {
|
||||
this.lastName = data().deepCopy(fields()[3].schema(), other.lastName);
|
||||
fieldSetFlags()[3] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'id' field.
|
||||
* @return The value.
|
||||
*/
|
||||
public java.lang.String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'id' field.
|
||||
* @param value The value of 'id'.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder setId(java.lang.String value) {
|
||||
validate(fields()[0], value);
|
||||
this.id = value;
|
||||
fieldSetFlags()[0] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the 'id' field has been set.
|
||||
* @return True if the 'id' field has been set, false otherwise.
|
||||
*/
|
||||
public boolean hasId() {
|
||||
return fieldSetFlags()[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the value of the 'id' field.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder clearId() {
|
||||
id = null;
|
||||
fieldSetFlags()[0] = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'username' field.
|
||||
* @return The value.
|
||||
*/
|
||||
public java.lang.String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'username' field.
|
||||
* @param value The value of 'username'.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder setUsername(java.lang.String value) {
|
||||
validate(fields()[1], value);
|
||||
this.username = value;
|
||||
fieldSetFlags()[1] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the 'username' field has been set.
|
||||
* @return True if the 'username' field has been set, false otherwise.
|
||||
*/
|
||||
public boolean hasUsername() {
|
||||
return fieldSetFlags()[1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the value of the 'username' field.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder clearUsername() {
|
||||
username = null;
|
||||
fieldSetFlags()[1] = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'firstName' field.
|
||||
* @return The value.
|
||||
*/
|
||||
public java.lang.String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'firstName' field.
|
||||
* @param value The value of 'firstName'.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder setFirstName(java.lang.String value) {
|
||||
validate(fields()[2], value);
|
||||
this.firstName = value;
|
||||
fieldSetFlags()[2] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the 'firstName' field has been set.
|
||||
* @return True if the 'firstName' field has been set, false otherwise.
|
||||
*/
|
||||
public boolean hasFirstName() {
|
||||
return fieldSetFlags()[2];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the value of the 'firstName' field.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder clearFirstName() {
|
||||
firstName = null;
|
||||
fieldSetFlags()[2] = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the 'lastName' field.
|
||||
* @return The value.
|
||||
*/
|
||||
public java.lang.String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the 'lastName' field.
|
||||
* @param value The value of 'lastName'.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder setLastName(java.lang.String value) {
|
||||
validate(fields()[3], value);
|
||||
this.lastName = value;
|
||||
fieldSetFlags()[3] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the 'lastName' field has been set.
|
||||
* @return True if the 'lastName' field has been set, false otherwise.
|
||||
*/
|
||||
public boolean hasLastName() {
|
||||
return fieldSetFlags()[3];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the value of the 'lastName' field.
|
||||
* @return This builder.
|
||||
*/
|
||||
public com.food.order.system.kafka.order.avro.model.CustomerAvroModel.Builder clearLastName() {
|
||||
lastName = null;
|
||||
fieldSetFlags()[3] = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public CustomerAvroModel build() {
|
||||
try {
|
||||
CustomerAvroModel record = new CustomerAvroModel();
|
||||
record.id = fieldSetFlags()[0] ? this.id : (java.lang.String) defaultValue(fields()[0]);
|
||||
record.username = fieldSetFlags()[1] ? this.username : (java.lang.String) defaultValue(fields()[1]);
|
||||
record.firstName = fieldSetFlags()[2] ? this.firstName : (java.lang.String) defaultValue(fields()[2]);
|
||||
record.lastName = fieldSetFlags()[3] ? this.lastName : (java.lang.String) defaultValue(fields()[3]);
|
||||
return record;
|
||||
} catch (org.apache.avro.AvroMissingFieldException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new org.apache.avro.AvroRuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final org.apache.avro.io.DatumWriter<CustomerAvroModel>
|
||||
WRITER$ = (org.apache.avro.io.DatumWriter<CustomerAvroModel>)MODEL$.createDatumWriter(SCHEMA$);
|
||||
|
||||
@Override public void writeExternal(java.io.ObjectOutput out)
|
||||
throws java.io.IOException {
|
||||
WRITER$.write(this, SpecificData.getEncoder(out));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final org.apache.avro.io.DatumReader<CustomerAvroModel>
|
||||
READER$ = (org.apache.avro.io.DatumReader<CustomerAvroModel>)MODEL$.createDatumReader(SCHEMA$);
|
||||
|
||||
@Override public void readExternal(java.io.ObjectInput in)
|
||||
throws java.io.IOException {
|
||||
READER$.read(this, SpecificData.getDecoder(in));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"namespace": "com.food.order.system.kafka.order.avro.model",
|
||||
"type": "record",
|
||||
"name": "CustomerAvroModel",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"type": {
|
||||
"type": "string",
|
||||
"logicalType": "uuid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "firstName",
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lastName",
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
34
pom.xml
34
pom.xml
@@ -49,6 +49,40 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-domain-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-service-application</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-application</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-data-access</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>customer-messaging</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>payment-domain</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user