From 91fc4ecb06fe0cdea57fff1dc7fe2fe9aecbd7db Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sun, 17 Nov 2019 15:19:28 +0100 Subject: [PATCH 01/11] BAEL-2275: Init version --- ddd/docker/.env | 1 + ddd/docker/docker-compose.yml | 14 +++ ddd/docker/mongo-init.js | 12 +++ ddd/pom.xml | 5 + .../ddd/layers/DomainLayerApplication.java | 13 +++ .../layers/application/OrderController.java | 44 +++++++++ .../request/AddProductRequest.java | 18 ++++ .../request/CreateOrderRequest.java | 21 +++++ .../response/CreateOrderResponse.java | 15 +++ .../com/baeldung/ddd/layers/domain/Order.java | 84 +++++++++++++++++ .../ddd/layers/domain/OrderStatus.java | 5 + .../baeldung/ddd/layers/domain/Product.java | 43 +++++++++ .../domain/exception/DomainException.java | 7 ++ .../domain/repository/OrderRepository.java | 12 +++ .../domain/service/DomainOrderService.java | 56 ++++++++++++ .../layers/domain/service/OrderService.java | 16 ++++ .../configuration/DomainConfiguration.java | 16 ++++ .../configuration/MongoDBConfiguration.java | 7 ++ .../repository/MongoDbOrderRepository.java | 30 ++++++ .../repository/SpringDataOrderRepository.java | 10 ++ ddd/src/main/resources/ddd-layers.properties | 5 + .../ddd/layers/domain/OrderProvider.java | 19 ++++ .../ddd/layers/domain/OrderUnitTest.java | 57 ++++++++++++ .../service/DomainOrderServiceUnitTest.java | 91 +++++++++++++++++++ .../MongoDbOrderRepositoryUnitTest.java | 25 +++++ 25 files changed, 626 insertions(+) create mode 100644 ddd/docker/.env create mode 100644 ddd/docker/docker-compose.yml create mode 100644 ddd/docker/mongo-init.js create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java create mode 100644 ddd/src/main/resources/ddd-layers.properties create mode 100644 ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java diff --git a/ddd/docker/.env b/ddd/docker/.env new file mode 100644 index 0000000000..99f7e8b8d4 --- /dev/null +++ b/ddd/docker/.env @@ -0,0 +1 @@ +ORDER_DOCKER_MONGODB_PORT=27017 \ No newline at end of file diff --git a/ddd/docker/docker-compose.yml b/ddd/docker/docker-compose.yml new file mode 100644 index 0000000000..eb27e56061 --- /dev/null +++ b/ddd/docker/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3' + +services: + order-mongo-database: + image: mongo:3.4.13 + restart: always + ports: + - ${ORDER_DOCKER_MONGODB_PORT}:27017 + environment: + MONGO_INITDB_ROOT_USERNAME: admin + MONGO_INITDB_ROOT_PASSWORD: admin + MONGO_INITDB_DATABASE: order-database + volumes: + - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro \ No newline at end of file diff --git a/ddd/docker/mongo-init.js b/ddd/docker/mongo-init.js new file mode 100644 index 0000000000..b1564df50a --- /dev/null +++ b/ddd/docker/mongo-init.js @@ -0,0 +1,12 @@ +db.createUser( + { + user: "order", + pwd: "order", + roles: [ + { + role: "readWrite", + db: "order-database" + } + ] + } +); \ No newline at end of file diff --git a/ddd/pom.xml b/ddd/pom.xml index c249007ba4..6571470116 100644 --- a/ddd/pom.xml +++ b/ddd/pom.xml @@ -74,6 +74,11 @@ spring-boot-starter-test test + + org.mockito + mockito-core + test + de.flapdoodle.embed de.flapdoodle.embed.mongo diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java b/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java new file mode 100644 index 0000000000..35fb1958e2 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.ddd.layers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource(value={"classpath:ddd-layers.properties"}) +public class DomainLayerApplication { + public static void main(String[] args) { + SpringApplication.run(DomainLayerApplication.class, args); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java new file mode 100644 index 0000000000..fa3576eb37 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java @@ -0,0 +1,44 @@ +package com.baeldung.ddd.layers.application; + +import com.baeldung.ddd.layers.application.request.AddProductRequest; +import com.baeldung.ddd.layers.application.request.CreateOrderRequest; +import com.baeldung.ddd.layers.application.response.CreateOrderResponse; +import com.baeldung.ddd.layers.domain.service.OrderService; +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/orders") +public class OrderController { + + private final OrderService orderService; + + @Autowired + public OrderController(OrderService orderService) { + this.orderService = orderService; + } + + @PostMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + CreateOrderResponse createOrder(@RequestBody final CreateOrderRequest createOrderRequest) { + return new CreateOrderResponse(orderService + .createOrder(createOrderRequest.getProducts()) + .toString()); + } + + @PostMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + void addProduct(@PathVariable final ObjectId id, @RequestBody final AddProductRequest addProductRequest) { + orderService.addProduct(id, addProductRequest.getProduct()); + } + + @DeleteMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + void deleteProduct(@PathVariable final ObjectId id, @RequestParam final String name) { + orderService.deleteProduct(id, name); + } + + @PostMapping("/{id}/complete") + void completeOrder(@PathVariable final ObjectId id) { + orderService.completeOrder(id); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java new file mode 100644 index 0000000000..823b2191ef --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java @@ -0,0 +1,18 @@ +package com.baeldung.ddd.layers.application.request; + +import com.baeldung.ddd.layers.domain.Product; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class AddProductRequest { + private Product product; + + @JsonCreator + public AddProductRequest(@JsonProperty("product") final Product product) { + this.product = product; + } + + public Product getProduct() { + return product; + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java new file mode 100644 index 0000000000..a2dabd05fc --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java @@ -0,0 +1,21 @@ +package com.baeldung.ddd.layers.application.request; + +import com.baeldung.ddd.layers.domain.Product; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +public class CreateOrderRequest { + private List products; + + @JsonCreator + public CreateOrderRequest(@JsonProperty("products") final List productList) { + this.products = new ArrayList<>(productList); + } + + public List getProducts() { + return products; + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java new file mode 100644 index 0000000000..d57f297bde --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java @@ -0,0 +1,15 @@ +package com.baeldung.ddd.layers.application.response; + +import org.bson.types.ObjectId; + +public class CreateOrderResponse { + private final String id; + + public CreateOrderResponse(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java new file mode 100644 index 0000000000..d69b51ae57 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java @@ -0,0 +1,84 @@ +package com.baeldung.ddd.layers.domain; + +import com.baeldung.ddd.layers.domain.exception.DomainException; +import org.bson.types.ObjectId; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Order { + private final ObjectId id; + private OrderStatus status; + private List products; + private BigDecimal price; + + public Order(final ObjectId id, final List products) { + this.id = id; + this.products = new ArrayList<>(products); + this.status = OrderStatus.CREATED; + this.price = products + .stream() + .map(Product::getPrice) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + public void complete() { + validateState(); + this.status = OrderStatus.COMPLETED; + } + + public void addProduct(final Product product) { + validateState(); + validateProduct(product); + products.add(product); + price = price.add(product.getPrice()); + } + + public void removeProduct(final String name) { + validateState(); + final Product product = getProduct(name); + products.remove(product); + + price = price.subtract(product.getPrice()); + } + + private Product getProduct(String name) { + return products + .stream() + .filter(product -> product + .getName() + .equals(name)) + .findFirst() + .orElseThrow(() -> new DomainException("Product with " + name + " doesn't exist.")); + } + + private void validateState() { + if (OrderStatus.COMPLETED.equals(status)) { + throw new DomainException("The order is in completed state."); + } + } + + private void validateProduct(final Product product) { + if (product == null) { + throw new DomainException("The product cannot be null."); + } + } + + public ObjectId getId() { + return id; + } + + public OrderStatus getStatus() { + return status; + } + + public List getProducts() { + return Collections.unmodifiableList(products); + } + + public BigDecimal getPrice() { + return price; + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java new file mode 100644 index 0000000000..f5d32374be --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java @@ -0,0 +1,5 @@ +package com.baeldung.ddd.layers.domain; + +public enum OrderStatus { + CREATED, COMPLETED +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java new file mode 100644 index 0000000000..286585d84a --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java @@ -0,0 +1,43 @@ +package com.baeldung.ddd.layers.domain; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.math.BigDecimal; +import java.util.Objects; + +public class Product { + private final BigDecimal price; + private final String name; + + @JsonCreator + public Product(@JsonProperty("price") final BigDecimal price, @JsonProperty("name") final String name) { + this.price = price; + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public String getName() { + return name; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Product product = (Product) o; + return Objects.equals(price, product.price) && Objects.equals(name, product.name); + } + + @Override + public int hashCode() { + return Objects.hash(price, name); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java new file mode 100644 index 0000000000..05d25cc800 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java @@ -0,0 +1,7 @@ +package com.baeldung.ddd.layers.domain.exception; + +public class DomainException extends RuntimeException { + public DomainException(final String message) { + super(message); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java new file mode 100644 index 0000000000..45b0c42782 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.ddd.layers.domain.repository; + +import com.baeldung.ddd.layers.domain.Order; +import org.bson.types.ObjectId; + +import java.util.Optional; + +public interface OrderRepository { + Optional findById(ObjectId id); + + void save(Order order); +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java new file mode 100644 index 0000000000..961309e94e --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java @@ -0,0 +1,56 @@ +package com.baeldung.ddd.layers.domain.service; + +import com.baeldung.ddd.layers.domain.Order; +import com.baeldung.ddd.layers.domain.Product; +import com.baeldung.ddd.layers.domain.exception.DomainException; +import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import org.bson.types.ObjectId; + +import java.util.List; + +public class DomainOrderService implements OrderService { + + private final OrderRepository orderRepository; + + public DomainOrderService(OrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Override + public ObjectId createOrder(List products) { + final Order order = new Order(ObjectId.get(), products); + orderRepository.save(order); + + return order.getId(); + } + + @Override + public void addProduct(ObjectId id, Product product) { + final Order order = getOrder(id); + order.addProduct(product); + + orderRepository.save(order); + } + + @Override + public void completeOrder(ObjectId id) { + final Order order = getOrder(id); + order.complete(); + + orderRepository.save(order); + } + + @Override + public void deleteProduct(ObjectId id, String name) { + final Order order = getOrder(id); + order.removeProduct(name); + + orderRepository.save(order); + } + + private Order getOrder(ObjectId id) { + return orderRepository + .findById(id) + .orElseThrow(() -> new RuntimeException("Order with given id doesn't exist")); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java new file mode 100644 index 0000000000..dbc7d3aba1 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java @@ -0,0 +1,16 @@ +package com.baeldung.ddd.layers.domain.service; + +import com.baeldung.ddd.layers.domain.Product; +import org.bson.types.ObjectId; + +import java.util.List; + +public interface OrderService { + ObjectId createOrder(List products); + + void addProduct(ObjectId id, Product product); + + void completeOrder(ObjectId id); + + void deleteProduct(ObjectId id, String name); +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java new file mode 100644 index 0000000000..7c56456719 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java @@ -0,0 +1,16 @@ +package com.baeldung.ddd.layers.infrastracture.configuration; + +import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import com.baeldung.ddd.layers.domain.service.DomainOrderService; +import com.baeldung.ddd.layers.domain.service.OrderService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DomainConfiguration { + + @Bean + OrderService orderService(final OrderRepository orderRepository) { + return new DomainOrderService(orderRepository); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java new file mode 100644 index 0000000000..db6743e90f --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java @@ -0,0 +1,7 @@ +package com.baeldung.ddd.layers.infrastracture.configuration; + +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@EnableMongoRepositories +public class MongoDBConfiguration { +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java new file mode 100644 index 0000000000..5ec166738a --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java @@ -0,0 +1,30 @@ +package com.baeldung.ddd.layers.infrastracture.repository; + +import com.baeldung.ddd.layers.domain.Order; +import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +public class MongoDbOrderRepository implements OrderRepository { + + private final SpringDataOrderRepository orderRepository; + + @Autowired + public MongoDbOrderRepository(final SpringDataOrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Override + public Optional findById(final ObjectId id) { + return orderRepository.findById(id); + } + + @Override + public void save(final Order order) { + orderRepository.save(order); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java new file mode 100644 index 0000000000..0cbbcb3827 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.ddd.layers.infrastracture.repository; + +import com.baeldung.ddd.layers.domain.Order; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SpringDataOrderRepository extends MongoRepository { +} diff --git a/ddd/src/main/resources/ddd-layers.properties b/ddd/src/main/resources/ddd-layers.properties new file mode 100644 index 0000000000..0479996b17 --- /dev/null +++ b/ddd/src/main/resources/ddd-layers.properties @@ -0,0 +1,5 @@ +spring.data.mongodb.host=localhost +spring.data.mongodb.port=27017 +spring.data.mongodb.database=order-database +spring.data.mongodb.username=order +spring.data.mongodb.password=order \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java new file mode 100644 index 0000000000..8aa3ff4068 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java @@ -0,0 +1,19 @@ +package com.baeldung.ddd.layers.domain; + +import org.bson.types.ObjectId; + +import java.math.BigDecimal; +import java.util.Arrays; + +public class OrderProvider { + public static Order getCreatedOrder() { + return new Order(ObjectId.get(), Arrays.asList(new Product(BigDecimal.TEN, "productName"))); + } + + public static Order getCompletedOrder() { + final Order order = getCreatedOrder(); + order.complete(); + + return order; + } +} diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java new file mode 100644 index 0000000000..0996383610 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.ddd.layers.domain; + +import com.baeldung.ddd.layers.domain.exception.DomainException; +import org.bson.types.ObjectId; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import java.math.BigDecimal; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class OrderUnitTest { + + @Test + void shouldCompleteOrder_thenChangeStatus() { + final Order order = OrderProvider.getCreatedOrder(); + + order.complete(); + + assertEquals(OrderStatus.COMPLETED, order.getStatus()); + } + + @Test + void shouldAddProduct_thenUpdatePrice() { + final Order order = OrderProvider.getCreatedOrder(); + final int orderOriginalProductSize = order.getProducts().size(); + final BigDecimal orderOriginalPrice = order.getPrice(); + final Product productToAdd = new Product(new BigDecimal("20"), "secondProduct"); + + order.addProduct(productToAdd); + + assertEquals(orderOriginalProductSize + 1, order.getProducts().size()); + assertEquals(orderOriginalPrice.add(productToAdd.getPrice()), order.getPrice()); + } + + @Test + void shouldAddProduct_thenThrowException(){ + final Order order = OrderProvider.getCompletedOrder(); + final Product productToAdd = new Product(new BigDecimal("20"), "secondProduct"); + + final Executable executable = () -> order.addProduct(productToAdd); + + Assertions.assertThrows(DomainException.class, executable); + } + + @Test + void shouldRemoveProduct_thenUpdatePrice() { + final Order order = OrderProvider.getCreatedOrder(); + + order.removeProduct(order.getProducts().get(0).getName()); + + assertEquals(0, order.getProducts().size()); + assertEquals(BigDecimal.ZERO, order.getPrice()); + } +} \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java new file mode 100644 index 0000000000..841f49f7f5 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.ddd.layers.domain.service; + +import com.baeldung.ddd.layers.domain.Order; +import com.baeldung.ddd.layers.domain.OrderProvider; +import com.baeldung.ddd.layers.domain.Product; +import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import org.bson.types.ObjectId; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +class DomainOrderServiceUnitTest { + + private OrderRepository orderRepository; + private DomainOrderService tested; + + @BeforeEach + void setUp() { + orderRepository = mock(OrderRepository.class); + tested = new DomainOrderService(orderRepository); + } + + @Test + void shouldCreateOrder_thenSaveIt() { + final Product product = new Product(BigDecimal.TEN, "productName"); + + final ObjectId id = tested.createOrder(Arrays.asList(product)); + + verify(orderRepository).save(any(Order.class)); + assertNotNull(id); + } + + @Test + void shouldAddProduct_thenSaveOrder() { + final Order order = spy(OrderProvider.getCreatedOrder()); + final Product product = new Product(BigDecimal.TEN, "test"); + when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); + + tested.addProduct(order.getId(), product); + + verify(orderRepository).save(order); + verify(order).addProduct(product); + } + + @Test + void shouldAddProduct_thenThrowException() { + final Product product = new Product(BigDecimal.TEN, "test"); + final ObjectId id = ObjectId.get(); + when(orderRepository.findById(id)).thenReturn(Optional.empty()); + + final Executable executable = () -> tested.addProduct(id, product); + + verify(orderRepository, times(0)).save(any(Order.class)); + assertThrows(RuntimeException.class, executable); + } + + @Test + void shouldCompleteOrder_thenSaveIt() { + final Order order = spy(OrderProvider.getCreatedOrder()); + when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); + + tested.completeOrder(order.getId()); + + verify(orderRepository).save(any(Order.class)); + verify(order).complete(); + } + + @Test + void shouldDeleteProduct_thenSaveOrder() { + final Order order = spy(OrderProvider.getCreatedOrder()); + final String productName = order + .getProducts() + .get(0) + .getName(); + when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); + + tested.deleteProduct(order.getId(), productName); + + verify(orderRepository).save(order); + verify(order).removeProduct(productName); + } +} \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java new file mode 100644 index 0000000000..356e60946c --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.ddd.layers.infrastracture.repository; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class MongoDbOrderRepositoryUnitTest { + + private SpringDataOrderRepository springDataOrderRepository; + private MongoDbOrderRepository tested; + + @BeforeEach + void setUp(){ + + } + + @Test + void findById() { + } + + @Test + void save() { + } +} \ No newline at end of file From 75ff212f1dadbf1be73d77c3e32bd8f5084bc3cb Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sun, 17 Nov 2019 15:54:37 +0100 Subject: [PATCH 02/11] BAEL-2275: Change constructor of Order --- .../PersistingDddAggregatesApplication.java | 24 +++++++++---------- .../layers/application/OrderController.java | 6 ++--- .../request/AddProductRequest.java | 4 +++- .../request/CreateOrderRequest.java | 13 +++++----- .../com/baeldung/ddd/layers/domain/Order.java | 9 +++---- .../domain/service/DomainOrderService.java | 7 ++---- .../layers/domain/service/OrderService.java | 4 +--- .../configuration/DomainConfiguration.java | 3 +++ .../configuration/MongoDBConfiguration.java | 3 ++- .../ddd/layers/domain/OrderProvider.java | 3 +-- .../service/DomainOrderServiceUnitTest.java | 3 +-- .../MongoDbOrderRepositoryUnitTest.java | 2 +- 12 files changed, 38 insertions(+), 43 deletions(-) diff --git a/ddd/src/main/java/com/baeldung/ddd/PersistingDddAggregatesApplication.java b/ddd/src/main/java/com/baeldung/ddd/PersistingDddAggregatesApplication.java index cd9be34278..3a52fd0440 100644 --- a/ddd/src/main/java/com/baeldung/ddd/PersistingDddAggregatesApplication.java +++ b/ddd/src/main/java/com/baeldung/ddd/PersistingDddAggregatesApplication.java @@ -1,12 +1,12 @@ -package com.baeldung.ddd; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class PersistingDddAggregatesApplication { - - public static void main(String[] args) { - SpringApplication.run(PersistingDddAggregatesApplication.class, args); - } -} +package com.baeldung.ddd; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.ddd.order") +public class PersistingDddAggregatesApplication { + + public static void main(String[] args) { + SpringApplication.run(PersistingDddAggregatesApplication.class, args); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java index fa3576eb37..19aa0493fa 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java @@ -22,9 +22,9 @@ public class OrderController { @PostMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) CreateOrderResponse createOrder(@RequestBody final CreateOrderRequest createOrderRequest) { - return new CreateOrderResponse(orderService - .createOrder(createOrderRequest.getProducts()) - .toString()); + final ObjectId id = orderService.createOrder(createOrderRequest.getProduct()); + + return new CreateOrderResponse(id.toString()); } @PostMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java index 823b2191ef..18a09e3636 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java @@ -4,8 +4,10 @@ import com.baeldung.ddd.layers.domain.Product; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import javax.validation.constraints.NotNull; + public class AddProductRequest { - private Product product; + @NotNull private Product product; @JsonCreator public AddProductRequest(@JsonProperty("product") final Product product) { diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java index a2dabd05fc..26d6d379c5 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java @@ -4,18 +4,17 @@ import com.baeldung.ddd.layers.domain.Product; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; +import javax.validation.constraints.NotNull; public class CreateOrderRequest { - private List products; + @NotNull private Product product; @JsonCreator - public CreateOrderRequest(@JsonProperty("products") final List productList) { - this.products = new ArrayList<>(productList); + public CreateOrderRequest(@JsonProperty("product") @NotNull Product product) { + this.product = product; } - public List getProducts() { - return products; + public Product getProduct() { + return product; } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java index d69b51ae57..c41d856d33 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java @@ -14,14 +14,11 @@ public class Order { private List products; private BigDecimal price; - public Order(final ObjectId id, final List products) { + public Order(final ObjectId id, final Product product) { this.id = id; - this.products = new ArrayList<>(products); + this.products = new ArrayList<>(Collections.singletonList(product)); this.status = OrderStatus.CREATED; - this.price = products - .stream() - .map(Product::getPrice) - .reduce(BigDecimal.ZERO, BigDecimal::add); + this.price = product.getPrice(); } public void complete() { diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java index 961309e94e..6ccef2e842 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java @@ -2,12 +2,9 @@ package com.baeldung.ddd.layers.domain.service; import com.baeldung.ddd.layers.domain.Order; import com.baeldung.ddd.layers.domain.Product; -import com.baeldung.ddd.layers.domain.exception.DomainException; import com.baeldung.ddd.layers.domain.repository.OrderRepository; import org.bson.types.ObjectId; -import java.util.List; - public class DomainOrderService implements OrderService { private final OrderRepository orderRepository; @@ -17,8 +14,8 @@ public class DomainOrderService implements OrderService { } @Override - public ObjectId createOrder(List products) { - final Order order = new Order(ObjectId.get(), products); + public ObjectId createOrder(final Product product) { + final Order order = new Order(ObjectId.get(), product); orderRepository.save(order); return order.getId(); diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java index dbc7d3aba1..b00d5b286a 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java @@ -3,10 +3,8 @@ package com.baeldung.ddd.layers.domain.service; import com.baeldung.ddd.layers.domain.Product; import org.bson.types.ObjectId; -import java.util.List; - public interface OrderService { - ObjectId createOrder(List products); + ObjectId createOrder(final Product product); void addProduct(ObjectId id, Product product); diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java index 7c56456719..8e97b4ca01 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java @@ -1,12 +1,15 @@ package com.baeldung.ddd.layers.infrastracture.configuration; +import com.baeldung.ddd.layers.DomainLayerApplication; import com.baeldung.ddd.layers.domain.repository.OrderRepository; import com.baeldung.ddd.layers.domain.service.DomainOrderService; import com.baeldung.ddd.layers.domain.service.OrderService; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration +@ComponentScan(basePackageClasses = DomainLayerApplication.class) public class DomainConfiguration { @Bean diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java index db6743e90f..5341b9fe95 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java @@ -1,7 +1,8 @@ package com.baeldung.ddd.layers.infrastracture.configuration; +import com.baeldung.ddd.layers.infrastracture.repository.SpringDataOrderRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; -@EnableMongoRepositories +@EnableMongoRepositories(basePackageClasses = SpringDataOrderRepository.class) public class MongoDBConfiguration { } diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java index 8aa3ff4068..8b86992ad5 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java @@ -3,11 +3,10 @@ package com.baeldung.ddd.layers.domain; import org.bson.types.ObjectId; import java.math.BigDecimal; -import java.util.Arrays; public class OrderProvider { public static Order getCreatedOrder() { - return new Order(ObjectId.get(), Arrays.asList(new Product(BigDecimal.TEN, "productName"))); + return new Order(ObjectId.get(), new Product(BigDecimal.TEN, "productName")); } public static Order getCompletedOrder() { diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java index 841f49f7f5..3ac40a867e 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java @@ -10,7 +10,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; import java.math.BigDecimal; -import java.util.Arrays; import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -33,7 +32,7 @@ class DomainOrderServiceUnitTest { void shouldCreateOrder_thenSaveIt() { final Product product = new Product(BigDecimal.TEN, "productName"); - final ObjectId id = tested.createOrder(Arrays.asList(product)); + final ObjectId id = tested.createOrder(product); verify(orderRepository).save(any(Order.class)); assertNotNull(id); diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java index 356e60946c..1b4eac06be 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java @@ -14,7 +14,7 @@ class MongoDbOrderRepositoryUnitTest { void setUp(){ } - + @Test void findById() { } From a99c2c818f3d72d2d6283fa6800b4f1e8954dae1 Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sun, 17 Nov 2019 20:55:03 +0100 Subject: [PATCH 03/11] BAEL-2275: Add OrderItem --- .../ddd/layers/DomainLayerApplication.java | 4 +- .../layers/application/OrderController.java | 6 ++- .../request/CreateOrderRequest.java | 2 +- .../response/CreateOrderResponse.java | 2 +- .../ddd/layers/domain/DomainException.java | 7 ++++ .../com/baeldung/ddd/layers/domain/Order.java | 39 ++++++++++--------- .../baeldung/ddd/layers/domain/OrderItem.java | 33 ++++++++++++++++ .../baeldung/ddd/layers/domain/Product.java | 25 ++++++------ .../domain/exception/DomainException.java | 7 ---- .../domain/service/DomainOrderService.java | 14 ++++--- .../layers/domain/service/OrderService.java | 4 +- ...figuration.java => BeanConfiguration.java} | 2 +- .../ddd/layers/domain/OrderProvider.java | 3 +- .../ddd/layers/domain/OrderUnitTest.java | 32 +++++++++------ .../service/DomainOrderServiceUnitTest.java | 20 +++++----- 15 files changed, 127 insertions(+), 73 deletions(-) create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java delete mode 100644 ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java rename ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/{DomainConfiguration.java => BeanConfiguration.java} (95%) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java b/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java index 35fb1958e2..1a57311df8 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java @@ -5,9 +5,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.PropertySource; @SpringBootApplication -@PropertySource(value={"classpath:ddd-layers.properties"}) +@PropertySource(value = { "classpath:ddd-layers.properties" }) public class DomainLayerApplication { - public static void main(String[] args) { + public static void main(final String[] args) { SpringApplication.run(DomainLayerApplication.class, args); } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java index 19aa0493fa..18f1514d05 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java @@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; +import java.util.UUID; + @RestController @RequestMapping("/orders") public class OrderController { @@ -33,8 +35,8 @@ public class OrderController { } @DeleteMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) - void deleteProduct(@PathVariable final ObjectId id, @RequestParam final String name) { - orderService.deleteProduct(id, name); + void deleteProduct(@PathVariable final ObjectId id, @RequestParam final UUID productId) { + orderService.deleteProduct(id, productId); } @PostMapping("/{id}/complete") diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java index 26d6d379c5..198feaf0d2 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java @@ -10,7 +10,7 @@ public class CreateOrderRequest { @NotNull private Product product; @JsonCreator - public CreateOrderRequest(@JsonProperty("product") @NotNull Product product) { + public CreateOrderRequest(@JsonProperty("product") @NotNull final Product product) { this.product = product; } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java index d57f297bde..04e5b89e6a 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java @@ -5,7 +5,7 @@ import org.bson.types.ObjectId; public class CreateOrderResponse { private final String id; - public CreateOrderResponse(String id) { + public CreateOrderResponse(final String id) { this.id = id; } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java new file mode 100644 index 0000000000..ca0dff4a69 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java @@ -0,0 +1,7 @@ +package com.baeldung.ddd.layers.domain; + +class DomainException extends RuntimeException { + DomainException(final String message) { + super(message); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java index c41d856d33..99ad09b2e3 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java @@ -1,22 +1,22 @@ package com.baeldung.ddd.layers.domain; -import com.baeldung.ddd.layers.domain.exception.DomainException; import org.bson.types.ObjectId; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.UUID; public class Order { private final ObjectId id; private OrderStatus status; - private List products; + private List orderItems; private BigDecimal price; public Order(final ObjectId id, final Product product) { this.id = id; - this.products = new ArrayList<>(Collections.singletonList(product)); + this.orderItems = new ArrayList<>(Collections.singletonList(new OrderItem(product))); this.status = OrderStatus.CREATED; this.price = product.getPrice(); } @@ -26,29 +26,30 @@ public class Order { this.status = OrderStatus.COMPLETED; } - public void addProduct(final Product product) { + public void addOrder(final Product product) { validateState(); validateProduct(product); - products.add(product); + orderItems.add(new OrderItem(product)); price = price.add(product.getPrice()); } - public void removeProduct(final String name) { + public void removeOrder(final UUID id) { validateState(); - final Product product = getProduct(name); - products.remove(product); + final OrderItem orderItem = getOrderItem(id); + orderItems.remove(orderItem); - price = price.subtract(product.getPrice()); + price = price.subtract(orderItem.getPrice()); } - private Product getProduct(String name) { - return products + private OrderItem getOrderItem(final UUID id) { + return orderItems .stream() - .filter(product -> product - .getName() - .equals(name)) + .filter(orderItem -> orderItem + .getProduct() + .getId() + .equals(id)) .findFirst() - .orElseThrow(() -> new DomainException("Product with " + name + " doesn't exist.")); + .orElseThrow(() -> new DomainException("Product with " + id + " doesn't exist.")); } private void validateState() { @@ -71,11 +72,11 @@ public class Order { return status; } - public List getProducts() { - return Collections.unmodifiableList(products); - } - public BigDecimal getPrice() { return price; } + + public List getOrderItems() { + return orderItems; + } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java new file mode 100644 index 0000000000..06b8bd69f4 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java @@ -0,0 +1,33 @@ +package com.baeldung.ddd.layers.domain; + +import java.math.BigDecimal; +import java.util.Objects; + +public class OrderItem { + private final Product product; + + public OrderItem(final Product product) { + this.product = product; + } + + public BigDecimal getPrice() { + return product.getPrice(); + } + + public Product getProduct() { + return product; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OrderItem orderItem = (OrderItem) o; + return Objects.equals(product, orderItem.product); + } + + @Override + public int hashCode() { + return Objects.hash(product); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java index 286585d84a..31928fc0fd 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java @@ -5,13 +5,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.math.BigDecimal; import java.util.Objects; +import java.util.UUID; public class Product { + private final UUID id; private final BigDecimal price; private final String name; @JsonCreator - public Product(@JsonProperty("price") final BigDecimal price, @JsonProperty("name") final String name) { + public Product(@JsonProperty("id") final UUID id, @JsonProperty("price") final BigDecimal price, @JsonProperty("name") final String name) { + this.id = id; this.price = price; this.name = name; } @@ -24,20 +27,20 @@ public class Product { return name; } + public UUID getId() { + return id; + } + @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final Product product = (Product) o; - return Objects.equals(price, product.price) && Objects.equals(name, product.name); + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product product = (Product) o; + return Objects.equals(id, product.id) && Objects.equals(price, product.price) && Objects.equals(name, product.name); } @Override public int hashCode() { - return Objects.hash(price, name); + return Objects.hash(id, price, name); } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java deleted file mode 100644 index 05d25cc800..0000000000 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/exception/DomainException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.baeldung.ddd.layers.domain.exception; - -public class DomainException extends RuntimeException { - public DomainException(final String message) { - super(message); - } -} diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java index 6ccef2e842..ceaf7de863 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java @@ -5,11 +5,13 @@ import com.baeldung.ddd.layers.domain.Product; import com.baeldung.ddd.layers.domain.repository.OrderRepository; import org.bson.types.ObjectId; +import java.util.UUID; + public class DomainOrderService implements OrderService { private final OrderRepository orderRepository; - public DomainOrderService(OrderRepository orderRepository) { + public DomainOrderService(final OrderRepository orderRepository) { this.orderRepository = orderRepository; } @@ -22,15 +24,15 @@ public class DomainOrderService implements OrderService { } @Override - public void addProduct(ObjectId id, Product product) { + public void addProduct(final ObjectId id, final Product product) { final Order order = getOrder(id); - order.addProduct(product); + order.addOrder(product); orderRepository.save(order); } @Override - public void completeOrder(ObjectId id) { + public void completeOrder(final ObjectId id) { final Order order = getOrder(id); order.complete(); @@ -38,9 +40,9 @@ public class DomainOrderService implements OrderService { } @Override - public void deleteProduct(ObjectId id, String name) { + public void deleteProduct(final ObjectId id, final UUID productId) { final Order order = getOrder(id); - order.removeProduct(name); + order.removeOrder(productId); orderRepository.save(order); } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java index b00d5b286a..ed3ffe5ed3 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java @@ -3,6 +3,8 @@ package com.baeldung.ddd.layers.domain.service; import com.baeldung.ddd.layers.domain.Product; import org.bson.types.ObjectId; +import java.util.UUID; + public interface OrderService { ObjectId createOrder(final Product product); @@ -10,5 +12,5 @@ public interface OrderService { void completeOrder(ObjectId id); - void deleteProduct(ObjectId id, String name); + void deleteProduct(ObjectId id, UUID productId); } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/BeanConfiguration.java similarity index 95% rename from ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java rename to ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/BeanConfiguration.java index 8e97b4ca01..68429f1fb8 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/DomainConfiguration.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/BeanConfiguration.java @@ -10,7 +10,7 @@ import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackageClasses = DomainLayerApplication.class) -public class DomainConfiguration { +public class BeanConfiguration { @Bean OrderService orderService(final OrderRepository orderRepository) { diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java index 8b86992ad5..5133ece1b8 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java @@ -3,10 +3,11 @@ package com.baeldung.ddd.layers.domain; import org.bson.types.ObjectId; import java.math.BigDecimal; +import java.util.UUID; public class OrderProvider { public static Order getCreatedOrder() { - return new Order(ObjectId.get(), new Product(BigDecimal.TEN, "productName")); + return new Order(ObjectId.get(), new Product(UUID.randomUUID(), BigDecimal.TEN, "productName")); } public static Order getCompletedOrder() { diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java index 0996383610..48c55769ab 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java @@ -1,13 +1,11 @@ package com.baeldung.ddd.layers.domain; -import com.baeldung.ddd.layers.domain.exception.DomainException; -import org.bson.types.ObjectId; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; import java.math.BigDecimal; -import java.util.Arrays; +import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -25,22 +23,26 @@ class OrderUnitTest { @Test void shouldAddProduct_thenUpdatePrice() { final Order order = OrderProvider.getCreatedOrder(); - final int orderOriginalProductSize = order.getProducts().size(); + final int orderOriginalProductSize = order + .getOrderItems() + .size(); final BigDecimal orderOriginalPrice = order.getPrice(); - final Product productToAdd = new Product(new BigDecimal("20"), "secondProduct"); + final Product productToAdd = new Product(UUID.randomUUID(), new BigDecimal("20"), "secondProduct"); - order.addProduct(productToAdd); + order.addOrder(productToAdd); - assertEquals(orderOriginalProductSize + 1, order.getProducts().size()); + assertEquals(orderOriginalProductSize + 1, order + .getOrderItems() + .size()); assertEquals(orderOriginalPrice.add(productToAdd.getPrice()), order.getPrice()); } @Test - void shouldAddProduct_thenThrowException(){ + void shouldAddProduct_thenThrowException() { final Order order = OrderProvider.getCompletedOrder(); - final Product productToAdd = new Product(new BigDecimal("20"), "secondProduct"); + final Product productToAdd = new Product(UUID.randomUUID(), new BigDecimal("20"), "secondProduct"); - final Executable executable = () -> order.addProduct(productToAdd); + final Executable executable = () -> order.addOrder(productToAdd); Assertions.assertThrows(DomainException.class, executable); } @@ -49,9 +51,15 @@ class OrderUnitTest { void shouldRemoveProduct_thenUpdatePrice() { final Order order = OrderProvider.getCreatedOrder(); - order.removeProduct(order.getProducts().get(0).getName()); + order.removeOrder(order + .getOrderItems() + .get(0) + .getProduct() + .getId()); - assertEquals(0, order.getProducts().size()); + assertEquals(0, order + .getOrderItems() + .size()); assertEquals(BigDecimal.ZERO, order.getPrice()); } } \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java index 3ac40a867e..572afada00 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.function.Executable; import java.math.BigDecimal; import java.util.Optional; +import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -30,7 +31,7 @@ class DomainOrderServiceUnitTest { @Test void shouldCreateOrder_thenSaveIt() { - final Product product = new Product(BigDecimal.TEN, "productName"); + final Product product = new Product(UUID.randomUUID(), BigDecimal.TEN, "productName"); final ObjectId id = tested.createOrder(product); @@ -41,18 +42,18 @@ class DomainOrderServiceUnitTest { @Test void shouldAddProduct_thenSaveOrder() { final Order order = spy(OrderProvider.getCreatedOrder()); - final Product product = new Product(BigDecimal.TEN, "test"); + final Product product = new Product(UUID.randomUUID(), BigDecimal.TEN, "test"); when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); tested.addProduct(order.getId(), product); verify(orderRepository).save(order); - verify(order).addProduct(product); + verify(order).addOrder(product); } @Test void shouldAddProduct_thenThrowException() { - final Product product = new Product(BigDecimal.TEN, "test"); + final Product product = new Product(UUID.randomUUID(), BigDecimal.TEN, "test"); final ObjectId id = ObjectId.get(); when(orderRepository.findById(id)).thenReturn(Optional.empty()); @@ -76,15 +77,16 @@ class DomainOrderServiceUnitTest { @Test void shouldDeleteProduct_thenSaveOrder() { final Order order = spy(OrderProvider.getCreatedOrder()); - final String productName = order - .getProducts() + final UUID productId = order + .getOrderItems() .get(0) - .getName(); + .getProduct() + .getId(); when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); - tested.deleteProduct(order.getId(), productName); + tested.deleteProduct(order.getId(), productId); verify(orderRepository).save(order); - verify(order).removeProduct(productName); + verify(order).removeOrder(productId); } } \ No newline at end of file From 9f8c01aca93fbb37de64fbde5b2490a00e5cc76e Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sun, 17 Nov 2019 21:27:07 +0100 Subject: [PATCH 04/11] BAEL-2275: Change orderitem to be built based on product --- .../com/baeldung/ddd/layers/domain/Order.java | 3 +-- .../baeldung/ddd/layers/domain/OrderItem.java | 21 +++++++++++-------- .../ddd/layers/domain/OrderUnitTest.java | 8 +++---- .../service/DomainOrderServiceUnitTest.java | 4 ++-- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java index 99ad09b2e3..369f860bae 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java @@ -45,8 +45,7 @@ public class Order { return orderItems .stream() .filter(orderItem -> orderItem - .getProduct() - .getId() + .getProductId() .equals(id)) .findFirst() .orElseThrow(() -> new DomainException("Product with " + id + " doesn't exist.")); diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java index 06b8bd69f4..703a512ea2 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java @@ -2,20 +2,23 @@ package com.baeldung.ddd.layers.domain; import java.math.BigDecimal; import java.util.Objects; +import java.util.UUID; public class OrderItem { - private final Product product; + private final UUID productId; + private final BigDecimal price; public OrderItem(final Product product) { - this.product = product; + this.productId = product.getId(); + this.price = product.getPrice(); + } + + public UUID getProductId() { + return productId; } public BigDecimal getPrice() { - return product.getPrice(); - } - - public Product getProduct() { - return product; + return price; } @Override @@ -23,11 +26,11 @@ public class OrderItem { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OrderItem orderItem = (OrderItem) o; - return Objects.equals(product, orderItem.product); + return Objects.equals(productId, orderItem.productId) && Objects.equals(price, orderItem.price); } @Override public int hashCode() { - return Objects.hash(product); + return Objects.hash(productId, price); } } diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java index 48c55769ab..086624bf77 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java @@ -50,12 +50,12 @@ class OrderUnitTest { @Test void shouldRemoveProduct_thenUpdatePrice() { final Order order = OrderProvider.getCreatedOrder(); - - order.removeOrder(order + final UUID productId = order .getOrderItems() .get(0) - .getProduct() - .getId()); + .getProductId(); + + order.removeOrder(productId); assertEquals(0, order .getOrderItems() diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java index 572afada00..a9e967229d 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java @@ -80,8 +80,8 @@ class DomainOrderServiceUnitTest { final UUID productId = order .getOrderItems() .get(0) - .getProduct() - .getId(); + .getProductId(); + when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); tested.deleteProduct(order.getId(), productId); From a81467e234fbb4a7045524d34fb6a5549ec0c4fd Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Mon, 25 Nov 2019 21:57:06 +0100 Subject: [PATCH 05/11] BAEL-2275: Return immutable list when getting order items --- ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java index 369f860bae..6306138100 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java @@ -76,6 +76,6 @@ public class Order { } public List getOrderItems() { - return orderItems; + return Collections.unmodifiableList(orderItems); } } From 342ac1b42372d78d8afec86a7f2067a96b95033c Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Wed, 27 Nov 2019 20:35:28 +0100 Subject: [PATCH 06/11] [ BAEL-2275 ]: Move controller to controller package --- .../layers/application/{ => controller}/OrderController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ddd/src/main/java/com/baeldung/ddd/layers/application/{ => controller}/OrderController.java (96%) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java similarity index 96% rename from ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java rename to ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java index 18f1514d05..e4642799ac 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/OrderController.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.application; +package com.baeldung.ddd.layers.application.controller; import com.baeldung.ddd.layers.application.request.AddProductRequest; import com.baeldung.ddd.layers.application.request.CreateOrderRequest; From 7e1581abcd16d0c8b7086844fdb19980012450b3 Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sat, 30 Nov 2019 23:11:02 +0100 Subject: [PATCH 07/11] [ BAEL-2275 ] : Use UUID instead of ObjectId. --- .../application/controller/OrderController.java | 11 +++++------ .../application/response/CreateOrderResponse.java | 8 ++++---- .../java/com/baeldung/ddd/layers/domain/Order.java | 11 ++++++----- .../com/baeldung/ddd/layers/domain/OrderItem.java | 7 +++++-- .../layers/domain/repository/OrderRepository.java | 4 ++-- .../layers/domain/service/DomainOrderService.java | 13 ++++++------- .../ddd/layers/domain/service/OrderService.java | 9 ++++----- .../repository/MongoDbOrderRepository.java | 4 ++-- .../repository/SpringDataOrderRepository.java | 5 +++-- .../baeldung/ddd/layers/domain/OrderProvider.java | 4 +--- .../domain/service/DomainOrderServiceUnitTest.java | 7 +++---- 11 files changed, 41 insertions(+), 42 deletions(-) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java index e4642799ac..6dc8e4c215 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java @@ -4,7 +4,6 @@ import com.baeldung.ddd.layers.application.request.AddProductRequest; import com.baeldung.ddd.layers.application.request.CreateOrderRequest; import com.baeldung.ddd.layers.application.response.CreateOrderResponse; import com.baeldung.ddd.layers.domain.service.OrderService; -import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; @@ -24,23 +23,23 @@ public class OrderController { @PostMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) CreateOrderResponse createOrder(@RequestBody final CreateOrderRequest createOrderRequest) { - final ObjectId id = orderService.createOrder(createOrderRequest.getProduct()); + final UUID id = orderService.createOrder(createOrderRequest.getProduct()); - return new CreateOrderResponse(id.toString()); + return new CreateOrderResponse(id); } @PostMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) - void addProduct(@PathVariable final ObjectId id, @RequestBody final AddProductRequest addProductRequest) { + void addProduct(@PathVariable final UUID id, @RequestBody final AddProductRequest addProductRequest) { orderService.addProduct(id, addProductRequest.getProduct()); } @DeleteMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) - void deleteProduct(@PathVariable final ObjectId id, @RequestParam final UUID productId) { + void deleteProduct(@PathVariable final UUID id, @RequestParam final UUID productId) { orderService.deleteProduct(id, productId); } @PostMapping("/{id}/complete") - void completeOrder(@PathVariable final ObjectId id) { + void completeOrder(@PathVariable final UUID id) { orderService.completeOrder(id); } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java index 04e5b89e6a..14cbc978e5 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java @@ -1,15 +1,15 @@ package com.baeldung.ddd.layers.application.response; -import org.bson.types.ObjectId; +import java.util.UUID; public class CreateOrderResponse { - private final String id; + private final UUID id; - public CreateOrderResponse(final String id) { + public CreateOrderResponse(final UUID id) { this.id = id; } - public String getId() { + public UUID getId() { return id; } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java index 6306138100..4af8d13f8a 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java @@ -1,7 +1,5 @@ package com.baeldung.ddd.layers.domain; -import org.bson.types.ObjectId; - import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; @@ -9,12 +7,12 @@ import java.util.List; import java.util.UUID; public class Order { - private final ObjectId id; + private UUID id; private OrderStatus status; private List orderItems; private BigDecimal price; - public Order(final ObjectId id, final Product product) { + public Order(final UUID id, final Product product) { this.id = id; this.orderItems = new ArrayList<>(Collections.singletonList(new OrderItem(product))); this.status = OrderStatus.CREATED; @@ -63,7 +61,7 @@ public class Order { } } - public ObjectId getId() { + public UUID getId() { return id; } @@ -78,4 +76,7 @@ public class Order { public List getOrderItems() { return Collections.unmodifiableList(orderItems); } + + private Order() { + } } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java index 703a512ea2..4ad26a0a3d 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java @@ -5,8 +5,8 @@ import java.util.Objects; import java.util.UUID; public class OrderItem { - private final UUID productId; - private final BigDecimal price; + private UUID productId; + private BigDecimal price; public OrderItem(final Product product) { this.productId = product.getId(); @@ -21,6 +21,9 @@ public class OrderItem { return price; } + private OrderItem() { + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java index 45b0c42782..659aa39609 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java @@ -1,12 +1,12 @@ package com.baeldung.ddd.layers.domain.repository; import com.baeldung.ddd.layers.domain.Order; -import org.bson.types.ObjectId; import java.util.Optional; +import java.util.UUID; public interface OrderRepository { - Optional findById(ObjectId id); + Optional findById(UUID id); void save(Order order); } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java index ceaf7de863..e7793ee08d 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java @@ -3,7 +3,6 @@ package com.baeldung.ddd.layers.domain.service; import com.baeldung.ddd.layers.domain.Order; import com.baeldung.ddd.layers.domain.Product; import com.baeldung.ddd.layers.domain.repository.OrderRepository; -import org.bson.types.ObjectId; import java.util.UUID; @@ -16,15 +15,15 @@ public class DomainOrderService implements OrderService { } @Override - public ObjectId createOrder(final Product product) { - final Order order = new Order(ObjectId.get(), product); + public UUID createOrder(final Product product) { + final Order order = new Order(UUID.randomUUID(), product); orderRepository.save(order); return order.getId(); } @Override - public void addProduct(final ObjectId id, final Product product) { + public void addProduct(final UUID id, final Product product) { final Order order = getOrder(id); order.addOrder(product); @@ -32,7 +31,7 @@ public class DomainOrderService implements OrderService { } @Override - public void completeOrder(final ObjectId id) { + public void completeOrder(final UUID id) { final Order order = getOrder(id); order.complete(); @@ -40,14 +39,14 @@ public class DomainOrderService implements OrderService { } @Override - public void deleteProduct(final ObjectId id, final UUID productId) { + public void deleteProduct(final UUID id, final UUID productId) { final Order order = getOrder(id); order.removeOrder(productId); orderRepository.save(order); } - private Order getOrder(ObjectId id) { + private Order getOrder(UUID id) { return orderRepository .findById(id) .orElseThrow(() -> new RuntimeException("Order with given id doesn't exist")); diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java index ed3ffe5ed3..48caf467aa 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java @@ -1,16 +1,15 @@ package com.baeldung.ddd.layers.domain.service; import com.baeldung.ddd.layers.domain.Product; -import org.bson.types.ObjectId; import java.util.UUID; public interface OrderService { - ObjectId createOrder(final Product product); + UUID createOrder(Product product); - void addProduct(ObjectId id, Product product); + void addProduct(UUID id, Product product); - void completeOrder(ObjectId id); + void completeOrder(UUID id); - void deleteProduct(ObjectId id, UUID productId); + void deleteProduct(UUID id, UUID productId); } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java index 5ec166738a..e7409e05db 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java @@ -2,11 +2,11 @@ package com.baeldung.ddd.layers.infrastracture.repository; import com.baeldung.ddd.layers.domain.Order; import com.baeldung.ddd.layers.domain.repository.OrderRepository; -import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Optional; +import java.util.UUID; @Component public class MongoDbOrderRepository implements OrderRepository { @@ -19,7 +19,7 @@ public class MongoDbOrderRepository implements OrderRepository { } @Override - public Optional findById(final ObjectId id) { + public Optional findById(final UUID id) { return orderRepository.findById(id); } diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java index 0cbbcb3827..d4fac2e454 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java @@ -1,10 +1,11 @@ package com.baeldung.ddd.layers.infrastracture.repository; import com.baeldung.ddd.layers.domain.Order; -import org.bson.types.ObjectId; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; +import java.util.UUID; + @Repository -public interface SpringDataOrderRepository extends MongoRepository { +public interface SpringDataOrderRepository extends MongoRepository { } diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java index 5133ece1b8..1708aee942 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java @@ -1,13 +1,11 @@ package com.baeldung.ddd.layers.domain; -import org.bson.types.ObjectId; - import java.math.BigDecimal; import java.util.UUID; public class OrderProvider { public static Order getCreatedOrder() { - return new Order(ObjectId.get(), new Product(UUID.randomUUID(), BigDecimal.TEN, "productName")); + return new Order(UUID.randomUUID(), new Product(UUID.randomUUID(), BigDecimal.TEN, "productName")); } public static Order getCompletedOrder() { diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java index a9e967229d..87a2c1beb0 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java +++ b/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java @@ -4,7 +4,6 @@ import com.baeldung.ddd.layers.domain.Order; import com.baeldung.ddd.layers.domain.OrderProvider; import com.baeldung.ddd.layers.domain.Product; import com.baeldung.ddd.layers.domain.repository.OrderRepository; -import org.bson.types.ObjectId; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; @@ -33,7 +32,7 @@ class DomainOrderServiceUnitTest { void shouldCreateOrder_thenSaveIt() { final Product product = new Product(UUID.randomUUID(), BigDecimal.TEN, "productName"); - final ObjectId id = tested.createOrder(product); + final UUID id = tested.createOrder(product); verify(orderRepository).save(any(Order.class)); assertNotNull(id); @@ -54,7 +53,7 @@ class DomainOrderServiceUnitTest { @Test void shouldAddProduct_thenThrowException() { final Product product = new Product(UUID.randomUUID(), BigDecimal.TEN, "test"); - final ObjectId id = ObjectId.get(); + final UUID id = UUID.randomUUID(); when(orderRepository.findById(id)).thenReturn(Optional.empty()); final Executable executable = () -> tested.addProduct(id, product); @@ -81,7 +80,7 @@ class DomainOrderServiceUnitTest { .getOrderItems() .get(0) .getProductId(); - + when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); tested.deleteProduct(order.getId(), productId); From f32815f5fc59cfff9f801b50d300dca3b756377f Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sat, 30 Nov 2019 23:15:39 +0100 Subject: [PATCH 08/11] [ BAEL - 2275 ] : Remove UTF from APPLICATION_JSON --- .../ddd/layers/application/controller/OrderController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java b/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java index 6dc8e4c215..e3909013b7 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java +++ b/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java @@ -21,19 +21,19 @@ public class OrderController { this.orderService = orderService; } - @PostMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) CreateOrderResponse createOrder(@RequestBody final CreateOrderRequest createOrderRequest) { final UUID id = orderService.createOrder(createOrderRequest.getProduct()); return new CreateOrderResponse(id); } - @PostMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + @PostMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_VALUE) void addProduct(@PathVariable final UUID id, @RequestBody final AddProductRequest addProductRequest) { orderService.addProduct(id, addProductRequest.getProduct()); } - @DeleteMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + @DeleteMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_VALUE) void deleteProduct(@PathVariable final UUID id, @RequestParam final UUID productId) { orderService.deleteProduct(id, productId); } From 0efb132504dd3685da3958643be9e5fb9d4be210 Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sat, 7 Dec 2019 17:40:17 +0100 Subject: [PATCH 09/11] BAEL-2275: Fill the test. Rename package. --- .../DomainLayerApplication.java | 2 +- .../controller/OrderController.java | 10 ++-- .../request/AddProductRequest.java | 4 +- .../request/CreateOrderRequest.java | 4 +- .../response/CreateOrderResponse.java | 2 +- .../domain/DomainException.java | 2 +- .../domain/Order.java | 2 +- .../domain/OrderItem.java | 2 +- .../domain/OrderStatus.java | 2 +- .../domain/Product.java | 2 +- .../domain/repository/OrderRepository.java | 4 +- .../domain/service/DomainOrderService.java | 8 +-- .../domain/service/OrderService.java | 4 +- .../configuration/BeanConfiguration.java | 10 ++-- .../configuration/MongoDBConfiguration.java | 4 +- .../repository/MongoDbOrderRepository.java | 6 +-- .../repository/SpringDataOrderRepository.java | 4 +- .../MongoDbOrderRepositoryUnitTest.java | 25 --------- .../domain/OrderProvider.java | 2 +- .../domain/OrderUnitTest.java | 2 +- .../service/DomainOrderServiceUnitTest.java | 10 ++-- .../MongoDbOrderRepositoryUnitTest.java | 51 +++++++++++++++++++ 22 files changed, 94 insertions(+), 68 deletions(-) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/DomainLayerApplication.java (91%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/application/controller/OrderController.java (79%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/application/request/AddProductRequest.java (78%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/application/request/CreateOrderRequest.java (79%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/application/response/CreateOrderResponse.java (77%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/DomainException.java (72%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/Order.java (97%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/OrderItem.java (94%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/OrderStatus.java (52%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/Product.java (95%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/repository/OrderRepository.java (58%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/service/DomainOrderService.java (83%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/service/OrderService.java (67%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/infrastracture/configuration/BeanConfiguration.java (55%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/infrastracture/configuration/MongoDBConfiguration.java (55%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/infrastracture/repository/MongoDbOrderRepository.java (77%) rename ddd/src/main/java/com/baeldung/{ddd/layers => dddhexagonalspring}/infrastracture/repository/SpringDataOrderRepository.java (66%) delete mode 100644 ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java rename ddd/src/test/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/OrderProvider.java (89%) rename ddd/src/test/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/OrderUnitTest.java (97%) rename ddd/src/test/java/com/baeldung/{ddd/layers => dddhexagonalspring}/domain/service/DomainOrderServiceUnitTest.java (90%) create mode 100644 ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java similarity index 91% rename from ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java index 1a57311df8..988f96042b 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/DomainLayerApplication.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers; +package com.baeldung.dddhexagonalspring; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java similarity index 79% rename from ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java index e3909013b7..80ba36d01b 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/controller/OrderController.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java @@ -1,9 +1,9 @@ -package com.baeldung.ddd.layers.application.controller; +package com.baeldung.dddhexagonalspring.application.controller; -import com.baeldung.ddd.layers.application.request.AddProductRequest; -import com.baeldung.ddd.layers.application.request.CreateOrderRequest; -import com.baeldung.ddd.layers.application.response.CreateOrderResponse; -import com.baeldung.ddd.layers.domain.service.OrderService; +import com.baeldung.dddhexagonalspring.application.request.AddProductRequest; +import com.baeldung.dddhexagonalspring.application.request.CreateOrderRequest; +import com.baeldung.dddhexagonalspring.application.response.CreateOrderResponse; +import com.baeldung.dddhexagonalspring.domain.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/AddProductRequest.java similarity index 78% rename from ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/AddProductRequest.java index 18a09e3636..ec107d635b 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/AddProductRequest.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/AddProductRequest.java @@ -1,6 +1,6 @@ -package com.baeldung.ddd.layers.application.request; +package com.baeldung.dddhexagonalspring.application.request; -import com.baeldung.ddd.layers.domain.Product; +import com.baeldung.dddhexagonalspring.domain.Product; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/CreateOrderRequest.java similarity index 79% rename from ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/CreateOrderRequest.java index 198feaf0d2..8c51fbe479 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/request/CreateOrderRequest.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/CreateOrderRequest.java @@ -1,6 +1,6 @@ -package com.baeldung.ddd.layers.application.request; +package com.baeldung.dddhexagonalspring.application.request; -import com.baeldung.ddd.layers.domain.Product; +import com.baeldung.dddhexagonalspring.domain.Product; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/response/CreateOrderResponse.java similarity index 77% rename from ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/application/response/CreateOrderResponse.java index 14cbc978e5..72ee1134c3 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/application/response/CreateOrderResponse.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/response/CreateOrderResponse.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.application.response; +package com.baeldung.dddhexagonalspring.application.response; import java.util.UUID; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/DomainException.java similarity index 72% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/DomainException.java index ca0dff4a69..7baef7bab6 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/DomainException.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/DomainException.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; class DomainException extends RuntimeException { DomainException(final String message) { diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java similarity index 97% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java index 4af8d13f8a..7d40007411 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; import java.math.BigDecimal; import java.util.ArrayList; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderItem.java similarity index 94% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderItem.java index 4ad26a0a3d..9debb02680 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderItem.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderItem.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; import java.math.BigDecimal; import java.util.Objects; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderStatus.java similarity index 52% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderStatus.java index f5d32374be..2ee5df3ab7 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/OrderStatus.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderStatus.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; public enum OrderStatus { CREATED, COMPLETED diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Product.java similarity index 95% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Product.java index 31928fc0fd..e05b4afe62 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/Product.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Product.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/repository/OrderRepository.java similarity index 58% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/repository/OrderRepository.java index 659aa39609..14b34e13f3 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/repository/OrderRepository.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/repository/OrderRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.ddd.layers.domain.repository; +package com.baeldung.dddhexagonalspring.domain.repository; -import com.baeldung.ddd.layers.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Order; import java.util.Optional; import java.util.UUID; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderService.java similarity index 83% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderService.java index e7793ee08d..4fb2377745 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/DomainOrderService.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderService.java @@ -1,8 +1,8 @@ -package com.baeldung.ddd.layers.domain.service; +package com.baeldung.dddhexagonalspring.domain.service; -import com.baeldung.ddd.layers.domain.Order; -import com.baeldung.ddd.layers.domain.Product; -import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; import java.util.UUID; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/OrderService.java similarity index 67% rename from ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/OrderService.java index 48caf467aa..37297d74c4 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/domain/service/OrderService.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/OrderService.java @@ -1,6 +1,6 @@ -package com.baeldung.ddd.layers.domain.service; +package com.baeldung.dddhexagonalspring.domain.service; -import com.baeldung.ddd.layers.domain.Product; +import com.baeldung.dddhexagonalspring.domain.Product; import java.util.UUID; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/BeanConfiguration.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/BeanConfiguration.java similarity index 55% rename from ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/BeanConfiguration.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/BeanConfiguration.java index 68429f1fb8..4be5d84ba7 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/BeanConfiguration.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/BeanConfiguration.java @@ -1,9 +1,9 @@ -package com.baeldung.ddd.layers.infrastracture.configuration; +package com.baeldung.dddhexagonalspring.infrastracture.configuration; -import com.baeldung.ddd.layers.DomainLayerApplication; -import com.baeldung.ddd.layers.domain.repository.OrderRepository; -import com.baeldung.ddd.layers.domain.service.DomainOrderService; -import com.baeldung.ddd.layers.domain.service.OrderService; +import com.baeldung.dddhexagonalspring.DomainLayerApplication; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; +import com.baeldung.dddhexagonalspring.domain.service.DomainOrderService; +import com.baeldung.dddhexagonalspring.domain.service.OrderService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java similarity index 55% rename from ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java index 5341b9fe95..fd76b2eb0e 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/configuration/MongoDBConfiguration.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java @@ -1,6 +1,6 @@ -package com.baeldung.ddd.layers.infrastracture.configuration; +package com.baeldung.dddhexagonalspring.infrastracture.configuration; -import com.baeldung.ddd.layers.infrastracture.repository.SpringDataOrderRepository; +import com.baeldung.dddhexagonalspring.infrastracture.repository.SpringDataOrderRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @EnableMongoRepositories(basePackageClasses = SpringDataOrderRepository.class) diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java similarity index 77% rename from ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java index e7409e05db..3123ef3e2f 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepository.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java @@ -1,7 +1,7 @@ -package com.baeldung.ddd.layers.infrastracture.repository; +package com.baeldung.dddhexagonalspring.infrastracture.repository; -import com.baeldung.ddd.layers.domain.Order; -import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java similarity index 66% rename from ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java index d4fac2e454..0279a5ce4a 100644 --- a/ddd/src/main/java/com/baeldung/ddd/layers/infrastracture/repository/SpringDataOrderRepository.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.ddd.layers.infrastracture.repository; +package com.baeldung.dddhexagonalspring.infrastracture.repository; -import com.baeldung.ddd.layers.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Order; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java deleted file mode 100644 index 1b4eac06be..0000000000 --- a/ddd/src/test/java/com/baeldung/ddd/layers/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.baeldung.ddd.layers.infrastracture.repository; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class MongoDbOrderRepositoryUnitTest { - - private SpringDataOrderRepository springDataOrderRepository; - private MongoDbOrderRepository tested; - - @BeforeEach - void setUp(){ - - } - - @Test - void findById() { - } - - @Test - void save() { - } -} \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderProvider.java similarity index 89% rename from ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java rename to ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderProvider.java index 1708aee942..c534713ca3 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderProvider.java +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderProvider.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; import java.math.BigDecimal; import java.util.UUID; diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderUnitTest.java similarity index 97% rename from ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java rename to ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderUnitTest.java index 086624bf77..eceed999d8 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/OrderUnitTest.java +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.ddd.layers.domain; +package com.baeldung.dddhexagonalspring.domain; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderServiceUnitTest.java similarity index 90% rename from ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java rename to ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderServiceUnitTest.java index 87a2c1beb0..797068a30a 100644 --- a/ddd/src/test/java/com/baeldung/ddd/layers/domain/service/DomainOrderServiceUnitTest.java +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderServiceUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.ddd.layers.domain.service; +package com.baeldung.dddhexagonalspring.domain.service; -import com.baeldung.ddd.layers.domain.Order; -import com.baeldung.ddd.layers.domain.OrderProvider; -import com.baeldung.ddd.layers.domain.Product; -import com.baeldung.ddd.layers.domain.repository.OrderRepository; +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.OrderProvider; +import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; diff --git a/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java new file mode 100644 index 0000000000..8f7e8260a3 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Product; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Optional; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class MongoDbOrderRepositoryUnitTest { + + private SpringDataOrderRepository springDataOrderRepository; + private MongoDbOrderRepository tested; + + @BeforeEach + void setUp(){ + springDataOrderRepository = mock(SpringDataOrderRepository.class); + + tested = new MongoDbOrderRepository(springDataOrderRepository); + } + + @Test + void shouldFindById_thenReturnOrder() { + final UUID id = UUID.randomUUID(); + final Order order = createOrder(id); + when(springDataOrderRepository.findById(id)).thenReturn(Optional.of(order)); + + final Optional result = tested.findById(id); + + assertEquals(order, result.get()); + } + + @Test + void shouldSaveOrder_viaSpringDataOrderRepository() { + final UUID id = UUID.randomUUID(); + final Order order = createOrder(id); + + tested.save(order); + + verify(springDataOrderRepository).save(order); + } + + private Order createOrder(UUID id) { + return new Order(id, new Product(UUID.randomUUID(), BigDecimal.TEN, "product")); + } +} \ No newline at end of file From b00e9f81ae19f536118c924472a3e33c28269516 Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sat, 7 Dec 2019 21:50:20 +0100 Subject: [PATCH 10/11] BAEL-2275: Move docker directory to test resources. Add README.md for it. --- ddd/docker/.env | 1 - .../resources/com/baeldung/dddhexagonalspring/README.md | 7 +++++++ .../com/baeldung/dddhexagonalspring}/docker-compose.yml | 2 +- .../com/baeldung/dddhexagonalspring}/mongo-init.js | 0 4 files changed, 8 insertions(+), 2 deletions(-) delete mode 100644 ddd/docker/.env create mode 100644 ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md rename ddd/{docker => src/test/resources/com/baeldung/dddhexagonalspring}/docker-compose.yml (88%) rename ddd/{docker => src/test/resources/com/baeldung/dddhexagonalspring}/mongo-init.js (100%) diff --git a/ddd/docker/.env b/ddd/docker/.env deleted file mode 100644 index 99f7e8b8d4..0000000000 --- a/ddd/docker/.env +++ /dev/null @@ -1 +0,0 @@ -ORDER_DOCKER_MONGODB_PORT=27017 \ No newline at end of file diff --git a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md new file mode 100644 index 0000000000..e8cf5c8e37 --- /dev/null +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md @@ -0,0 +1,7 @@ +## Setup DDD Hexagonal Spring Application + +To run this project, follow these steps: + +* Launch the Spring Boot Application (DomainLayerApplication). +* Run the application database by executing `docker-compose up` in this directory. +* By default, application will connect to this database (configuration in *ddd-layers.properties*) \ No newline at end of file diff --git a/ddd/docker/docker-compose.yml b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml similarity index 88% rename from ddd/docker/docker-compose.yml rename to ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml index eb27e56061..d85ddf4a0e 100644 --- a/ddd/docker/docker-compose.yml +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml @@ -5,7 +5,7 @@ services: image: mongo:3.4.13 restart: always ports: - - ${ORDER_DOCKER_MONGODB_PORT}:27017 + - 27017:27017 environment: MONGO_INITDB_ROOT_USERNAME: admin MONGO_INITDB_ROOT_PASSWORD: admin diff --git a/ddd/docker/mongo-init.js b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/mongo-init.js similarity index 100% rename from ddd/docker/mongo-init.js rename to ddd/src/test/resources/com/baeldung/dddhexagonalspring/mongo-init.js From 53075a11dce6a4fbe68278529e09285beb3fde8e Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Sun, 8 Dec 2019 11:11:46 +0100 Subject: [PATCH 11/11] BAEL-2275: Fix order in README --- .../test/resources/com/baeldung/dddhexagonalspring/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md index e8cf5c8e37..e0337498fc 100644 --- a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md @@ -2,6 +2,6 @@ To run this project, follow these steps: -* Launch the Spring Boot Application (DomainLayerApplication). * Run the application database by executing `docker-compose up` in this directory. +* Launch the Spring Boot Application (DomainLayerApplication). * By default, application will connect to this database (configuration in *ddd-layers.properties*) \ No newline at end of file