diff --git a/ddd/pom.xml b/ddd/pom.xml index 9a0523a4c6..f27f1d24a9 100644 --- a/ddd/pom.xml +++ b/ddd/pom.xml @@ -20,6 +20,10 @@ org.springframework.boot spring-boot-starter-data-mongodb + + org.springframework.boot + spring-boot-starter-data-cassandra + org.junit.jupiter junit-jupiter-api diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java index 988f96042b..235021b03e 100644 --- a/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java @@ -1,13 +1,37 @@ package com.baeldung.dddhexagonalspring; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.PropertySource; +import com.baeldung.dddhexagonalspring.application.cli.CliOrderController; + @SpringBootApplication @PropertySource(value = { "classpath:ddd-layers.properties" }) -public class DomainLayerApplication { +public class DomainLayerApplication implements CommandLineRunner { + public static void main(final String[] args) { - SpringApplication.run(DomainLayerApplication.class, args); + SpringApplication application = new SpringApplication(DomainLayerApplication.class); + // uncomment to run just the console application + // application.setWebApplicationType(WebApplicationType.NONE); + application.run(args); + } + + @Autowired + public CliOrderController orderController; + + @Autowired + public ConfigurableApplicationContext context; + + @Override + public void run(String... args) throws Exception { + orderController.createCompleteOrder(); + orderController.createIncompleteOrder(); + // uncomment to stop the context when execution is done + // context.close(); } } diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/cli/CliOrderController.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/cli/CliOrderController.java new file mode 100644 index 0000000000..3d595533f3 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/cli/CliOrderController.java @@ -0,0 +1,47 @@ +package com.baeldung.dddhexagonalspring.application.cli; + +import java.math.BigDecimal; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.domain.service.OrderService; + +@Component +public class CliOrderController { + + private static final Logger LOG = LoggerFactory.getLogger(CliOrderController.class); + + private final OrderService orderService; + + @Autowired + public CliOrderController(OrderService orderService) { + this.orderService = orderService; + } + + public void createCompleteOrder() { + LOG.info("<>"); + UUID orderId = createOrder(); + orderService.completeOrder(orderId); + } + + public void createIncompleteOrder() { + LOG.info("<>"); + UUID orderId = createOrder(); + } + + private UUID createOrder() { + LOG.info("Placing a new order with two products"); + Product mobilePhone = new Product(UUID.randomUUID(), BigDecimal.valueOf(200), "mobile"); + Product razor = new Product(UUID.randomUUID(), BigDecimal.valueOf(50), "razor"); + LOG.info("Creating order with mobile phone"); + UUID orderId = orderService.createOrder(mobilePhone); + LOG.info("Adding a razor to the order"); + orderService.addProduct(orderId, razor); + return orderId; + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/rest/OrderController.java similarity index 96% rename from ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/application/rest/OrderController.java index 80ba36d01b..12bb8ddea4 100644 --- a/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/rest/OrderController.java @@ -1,4 +1,4 @@ -package com.baeldung.dddhexagonalspring.application.controller; +package com.baeldung.dddhexagonalspring.application.rest; import com.baeldung.dddhexagonalspring.application.request.AddProductRequest; import com.baeldung.dddhexagonalspring.application.request.CreateOrderRequest; diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java index 7d40007411..a8745eadbe 100644 --- a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.UUID; public class Order { @@ -40,13 +41,11 @@ public class Order { } private OrderItem getOrderItem(final UUID id) { - return orderItems - .stream() - .filter(orderItem -> orderItem - .getProductId() - .equals(id)) - .findFirst() - .orElseThrow(() -> new DomainException("Product with " + id + " doesn't exist.")); + return orderItems.stream() + .filter(orderItem -> orderItem.getProductId() + .equals(id)) + .findFirst() + .orElseThrow(() -> new DomainException("Product with " + id + " doesn't exist.")); } private void validateState() { @@ -77,6 +76,21 @@ public class Order { return Collections.unmodifiableList(orderItems); } + @Override + public int hashCode() { + return Objects.hash(id, orderItems, price, status); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof Order)) + return false; + Order other = (Order) obj; + return Objects.equals(id, other.id) && Objects.equals(orderItems, other.orderItems) && Objects.equals(price, other.price) && status == other.status; + } + private Order() { } } diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/CassandraConfiguration.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/CassandraConfiguration.java new file mode 100644 index 0000000000..3b5911979a --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/CassandraConfiguration.java @@ -0,0 +1,10 @@ +package com.baeldung.dddhexagonalspring.infrastracture.configuration; + +import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; + +import com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra.SpringDataCassandraOrderRepository; + +@EnableCassandraRepositories(basePackageClasses = SpringDataCassandraOrderRepository.class) +public class CassandraConfiguration { + +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java index fd76b2eb0e..8ec6daf370 100644 --- a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java @@ -1,8 +1,9 @@ package com.baeldung.dddhexagonalspring.infrastracture.configuration; -import com.baeldung.dddhexagonalspring.infrastracture.repository.SpringDataOrderRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; -@EnableMongoRepositories(basePackageClasses = SpringDataOrderRepository.class) +import com.baeldung.dddhexagonalspring.infrastracture.repository.mongo.SpringDataMongoOrderRepository; + +@EnableMongoRepositories(basePackageClasses = SpringDataMongoOrderRepository.class) public class MongoDBConfiguration { } diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/CassandraDbOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/CassandraDbOrderRepository.java new file mode 100644 index 0000000000..686fc428e7 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/CassandraDbOrderRepository.java @@ -0,0 +1,38 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra; + +import java.util.Optional; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; + +@Component +public class CassandraDbOrderRepository implements OrderRepository { + + private final SpringDataCassandraOrderRepository orderRepository; + + @Autowired + public CassandraDbOrderRepository(SpringDataCassandraOrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Override + public Optional findById(UUID id) { + Optional orderEntity = orderRepository.findById(id); + if (orderEntity.isPresent()) { + return Optional.of(orderEntity.get() + .toOrder()); + } else { + return Optional.empty(); + } + } + + @Override + public void save(Order order) { + orderRepository.save(new OrderEntity(order)); + } + +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/OrderEntity.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/OrderEntity.java new file mode 100644 index 0000000000..b9841a4433 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/OrderEntity.java @@ -0,0 +1,75 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra; + +import java.math.BigDecimal; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.springframework.data.cassandra.core.mapping.PrimaryKey; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.OrderItem; +import com.baeldung.dddhexagonalspring.domain.OrderStatus; +import com.baeldung.dddhexagonalspring.domain.Product; + +public class OrderEntity { + + @PrimaryKey + private UUID id; + private OrderStatus status; + private List orderItemEntities; + private BigDecimal price; + + public OrderEntity(UUID id, OrderStatus status, List orderItemEntities, BigDecimal price) { + this.id = id; + this.status = status; + this.orderItemEntities = orderItemEntities; + this.price = price; + } + + public OrderEntity() { + } + + public OrderEntity(Order order) { + this.id = order.getId(); + this.price = order.getPrice(); + this.status = order.getStatus(); + this.orderItemEntities = order.getOrderItems() + .stream() + .map(OrderItemEntity::new) + .collect(Collectors.toList()); + + } + + public Order toOrder() { + List orderItems = orderItemEntities.stream() + .map(OrderItemEntity::toOrderItem) + .collect(Collectors.toList()); + List namelessProducts = orderItems.stream() + .map(orderItem -> new Product(orderItem.getProductId(), orderItem.getPrice(), "")) + .collect(Collectors.toList()); + Order order = new Order(id, namelessProducts.remove(0)); + namelessProducts.forEach(product -> order.addOrder(product)); + if (status == OrderStatus.COMPLETED) { + order.complete(); + } + return order; + } + + public UUID getId() { + return id; + } + + public OrderStatus getStatus() { + return status; + } + + public List getOrderItems() { + return orderItemEntities; + } + + public BigDecimal getPrice() { + return price; + } + +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/OrderItemEntity.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/OrderItemEntity.java new file mode 100644 index 0000000000..2cf8ac7845 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/OrderItemEntity.java @@ -0,0 +1,44 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra; + +import java.math.BigDecimal; +import java.util.UUID; + +import org.springframework.data.cassandra.core.mapping.UserDefinedType; + +import com.baeldung.dddhexagonalspring.domain.OrderItem; +import com.baeldung.dddhexagonalspring.domain.Product; + +@UserDefinedType +public class OrderItemEntity { + + private UUID productId; + private BigDecimal price; + + public OrderItemEntity() { + } + + public OrderItemEntity(final OrderItem orderItem) { + this.productId = orderItem.getProductId(); + this.price = orderItem.getPrice(); + } + + public OrderItem toOrderItem() { + return new OrderItem(new Product(productId, price, "")); + } + + public UUID getProductId() { + return productId; + } + + public void setProductId(UUID productId) { + this.productId = productId; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/SpringDataCassandraOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/SpringDataCassandraOrderRepository.java new file mode 100644 index 0000000000..93cd7ab83f --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/cassandra/SpringDataCassandraOrderRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra; + +import java.util.UUID; + +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SpringDataCassandraOrderRepository extends CassandraRepository { +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/mongo/MongoDbOrderRepository.java similarity index 75% rename from ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/mongo/MongoDbOrderRepository.java index 3123ef3e2f..b48b738cbd 100644 --- a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/mongo/MongoDbOrderRepository.java @@ -1,20 +1,23 @@ -package com.baeldung.dddhexagonalspring.infrastracture.repository; - -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; +package com.baeldung.dddhexagonalspring.infrastracture.repository.mongo; import java.util.Optional; import java.util.UUID; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; + @Component +@Primary public class MongoDbOrderRepository implements OrderRepository { - private final SpringDataOrderRepository orderRepository; + private final SpringDataMongoOrderRepository orderRepository; @Autowired - public MongoDbOrderRepository(final SpringDataOrderRepository orderRepository) { + public MongoDbOrderRepository(final SpringDataMongoOrderRepository orderRepository) { this.orderRepository = orderRepository; } diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/mongo/SpringDataMongoOrderRepository.java similarity index 74% rename from ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java rename to ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/mongo/SpringDataMongoOrderRepository.java index 0279a5ce4a..73aa74e7d7 100644 --- a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/mongo/SpringDataMongoOrderRepository.java @@ -1,4 +1,4 @@ -package com.baeldung.dddhexagonalspring.infrastracture.repository; +package com.baeldung.dddhexagonalspring.infrastracture.repository.mongo; import com.baeldung.dddhexagonalspring.domain.Order; import org.springframework.data.mongodb.repository.MongoRepository; @@ -7,5 +7,5 @@ import org.springframework.stereotype.Repository; import java.util.UUID; @Repository -public interface SpringDataOrderRepository extends MongoRepository { +public interface SpringDataMongoOrderRepository extends MongoRepository { } diff --git a/ddd/src/main/resources/ddd-layers.properties b/ddd/src/main/resources/ddd-layers.properties index 0479996b17..412c24eef7 100644 --- a/ddd/src/main/resources/ddd-layers.properties +++ b/ddd/src/main/resources/ddd-layers.properties @@ -1,5 +1,12 @@ +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 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 +spring.data.mongodb.password=order + +spring.data.cassandra.keyspaceName=order_database +spring.data.cassandra.username=cassandra +spring.data.cassandra.password=cassandra +spring.data.cassandra.contactPoints=localhost +spring.data.cassandra.port=9042 \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/CassandraDbOrderRepositoryIntegrationTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/CassandraDbOrderRepositoryIntegrationTest.java new file mode 100644 index 0000000000..668d1e5e34 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/CassandraDbOrderRepositoryIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import java.util.Optional; +import java.util.UUID; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; +import com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra.SpringDataCassandraOrderRepository; + +@SpringJUnitConfig +@SpringBootTest +@TestPropertySource("classpath:ddd-layers-test.properties") +class CassandraDbOrderRepositoryIntegrationTest { + + @Autowired + private SpringDataCassandraOrderRepository cassandraOrderRepository; + + @Autowired + private OrderRepository orderRepository; + + @AfterEach + void cleanUp() { + cassandraOrderRepository.deleteAll(); + } + + @Test + void shouldFindById_thenReturnOrder() { + + // given + final UUID id = UUID.randomUUID(); + final Order order = createOrder(id); + order.addOrder(new Product(UUID.randomUUID(), BigDecimal.TEN, "second")); + order.complete(); + + // when + orderRepository.save(order); + + final Optional result = orderRepository.findById(id); + + assertEquals(order, result.get()); + } + + private Order createOrder(UUID id) { + return new Order(id, new Product(UUID.randomUUID(), BigDecimal.TEN, "product")); + } +} \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryIntegrationTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryIntegrationTest.java new file mode 100644 index 0000000000..9a7736c419 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import java.util.Optional; +import java.util.UUID; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; +import com.baeldung.dddhexagonalspring.infrastracture.repository.mongo.SpringDataMongoOrderRepository; + +@SpringJUnitConfig +@SpringBootTest +@TestPropertySource("classpath:ddd-layers-test.properties") +class MongoDbOrderRepositoryIntegrationTest { + + @Autowired + private SpringDataMongoOrderRepository mongoOrderRepository; + + @Autowired + private OrderRepository orderRepository; + + @AfterEach + void cleanUp() { + mongoOrderRepository.deleteAll(); + } + + @Test + void shouldFindById_thenReturnOrder() { + + // given + final UUID id = UUID.randomUUID(); + final Order order = createOrder(id); + + // when + orderRepository.save(order); + + final Optional result = orderRepository.findById(id); + + assertEquals(order, result.get()); + } + + private Order createOrder(UUID id) { + return new Order(id, new Product(UUID.randomUUID(), BigDecimal.TEN, "product")); + } +} \ No newline at end of file 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 index 8f7e8260a3..4c75daaa4d 100644 --- a/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepositoryUnitTest.java @@ -2,6 +2,9 @@ package com.baeldung.dddhexagonalspring.infrastracture.repository; import com.baeldung.dddhexagonalspring.domain.Order; import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.infrastracture.repository.mongo.MongoDbOrderRepository; +import com.baeldung.dddhexagonalspring.infrastracture.repository.mongo.SpringDataMongoOrderRepository; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -14,12 +17,12 @@ import static org.mockito.Mockito.*; class MongoDbOrderRepositoryUnitTest { - private SpringDataOrderRepository springDataOrderRepository; + private SpringDataMongoOrderRepository springDataOrderRepository; private MongoDbOrderRepository tested; @BeforeEach - void setUp(){ - springDataOrderRepository = mock(SpringDataOrderRepository.class); + void setUp() { + springDataOrderRepository = mock(SpringDataMongoOrderRepository.class); tested = new MongoDbOrderRepository(springDataOrderRepository); } diff --git a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md index e0337498fc..1355514a3d 100644 --- a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/README.md @@ -4,4 +4,6 @@ To run this project, follow these steps: * 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 +* By default, the application will connect to the one of the two databases (configuration in *ddd-layers.properties*) + * check `CassandraDbOrderRepository.java` and `MongoDbOrderRepository.java` + * switch between the databases by making one of the above beans primary using the `@Primary` annotation \ No newline at end of file diff --git a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/cassandra-init.cql b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/cassandra-init.cql new file mode 100644 index 0000000000..cbb22d2525 --- /dev/null +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/cassandra-init.cql @@ -0,0 +1,12 @@ +CREATE KEYSPACE IF NOT exists order_database +WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}; + +CREATE TYPE IF NOT EXISTS order_database.orderitementity (productid uuid, price decimal); + +CREATE TABLE IF NOT EXISTS order_database.orderentity( + id uuid, + status text, + orderitementities list>, + price decimal, + primary key(id) +); diff --git a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml index d85ddf4a0e..7de0d30d43 100644 --- a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml @@ -3,6 +3,7 @@ version: '3' services: order-mongo-database: image: mongo:3.4.13 + container_name: order-mongo-db restart: always ports: - 27017:27017 @@ -11,4 +12,19 @@ services: 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 + - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro + order-cassandra-database: + image: cassandra:3.11.5 + container_name: order-cassandra-db + restart: always + ports: + - 9042:9042 + order-cassandra-init: + image: cassandra:3.11.5 + container_name: order-cassandra-db-init + depends_on: + - order-cassandra-database + volumes: + - ./cassandra-init.cql:/cassandra-init.cql:ro + command: bin/bash -c "echo Initializing cassandra schema... && sleep 30 && cqlsh -u cassandra -p cassandra -f cassandra-init.cql order-cassandra-db" + \ No newline at end of file diff --git a/ddd/src/test/resources/ddd-layers-test.properties b/ddd/src/test/resources/ddd-layers-test.properties new file mode 100644 index 0000000000..d41689d91b --- /dev/null +++ b/ddd/src/test/resources/ddd-layers-test.properties @@ -0,0 +1,12 @@ +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration +spring.data.mongodb.host=127.0.0.1 +spring.data.mongodb.port=27017 +spring.data.mongodb.database=order-database +spring.data.mongodb.username=order +spring.data.mongodb.password=order + +spring.data.cassandra.keyspaceName=order_database +spring.data.cassandra.username=cassandra +spring.data.cassandra.password=cassandra +spring.data.cassandra.contactPoints=127.0.0.1 +spring.data.cassandra.port=9042 \ No newline at end of file