diff --git a/core-java-modules/core-java-exceptions-2/README.md b/core-java-modules/core-java-exceptions-2/README.md new file mode 100644 index 0000000000..3ad5189b5e --- /dev/null +++ b/core-java-modules/core-java-exceptions-2/README.md @@ -0,0 +1,5 @@ +## Core Java Exceptions 2 + +This module contains articles about core java exceptions + +### diff --git a/core-java-modules/core-java-exceptions-2/pom.xml b/core-java-modules/core-java-exceptions-2/pom.xml new file mode 100644 index 0000000000..2f7f613faf --- /dev/null +++ b/core-java-modules/core-java-exceptions-2/pom.xml @@ -0,0 +1,24 @@ + + 4.0.0 + + core-java-exceptions-2 + core-java-exceptions-2 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + http://maven.apache.org + + + UTF-8 + + + diff --git a/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/RethrowDifferentExceptionDemo.java b/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/RethrowDifferentExceptionDemo.java new file mode 100644 index 0000000000..ce2fcb2c7a --- /dev/null +++ b/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/RethrowDifferentExceptionDemo.java @@ -0,0 +1,29 @@ +package com.baeldung.rethrow; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.baeldung.rethrow.custom.InvalidDataException; + +public class RethrowDifferentExceptionDemo { + + private final static Logger LOGGER = Logger.getLogger(RethrowDifferentExceptionDemo.class.getName()); + + public static void main(String[] args) throws Exception { + String name = null; + + try { + + // Below line will throw NullPointerException + if (name.equals("Joe")) { + // Do blah blah.. + } + + } catch (Exception e) { + LOGGER.log(Level.WARNING, "So and so user is unable to cast vote because he is found uneligible"); + throw new InvalidDataException(e); + } + + } + +} diff --git a/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/RethrowSameExceptionDemo.java b/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/RethrowSameExceptionDemo.java new file mode 100644 index 0000000000..bf53f67d34 --- /dev/null +++ b/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/RethrowSameExceptionDemo.java @@ -0,0 +1,27 @@ +package com.baeldung.rethrow; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class RethrowSameExceptionDemo { + + private final static Logger LOGGER = Logger.getLogger(RethrowDifferentExceptionDemo.class.getName()); + + public static void main(String[] args) throws Exception { + String name = null; + + try { + + // Below line will throw NullPointerException + if (name.equals("Joe")) { + // Do blah blah.. + } + + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Exception occurred due to invalid name"); + throw e; + } + + } + +} diff --git a/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/custom/InvalidDataException.java b/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/custom/InvalidDataException.java new file mode 100644 index 0000000000..5a74e32012 --- /dev/null +++ b/core-java-modules/core-java-exceptions-2/src/main/java/com/baeldung/rethrow/custom/InvalidDataException.java @@ -0,0 +1,8 @@ +package com.baeldung.rethrow.custom; + +public class InvalidDataException extends Exception { + + public InvalidDataException(Exception e) { + super(e); + } +} diff --git a/ddd/pom.xml b/ddd/pom.xml index 508bccdbf2..9a0523a4c6 100644 --- a/ddd/pom.xml +++ b/ddd/pom.xml @@ -76,6 +76,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/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/dddhexagonalspring/DomainLayerApplication.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java new file mode 100644 index 0000000000..988f96042b --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/DomainLayerApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.dddhexagonalspring; + +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(final String[] args) { + SpringApplication.run(DomainLayerApplication.class, args); + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java new file mode 100644 index 0000000000..80ba36d01b --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/controller/OrderController.java @@ -0,0 +1,45 @@ +package com.baeldung.dddhexagonalspring.application.controller; + +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.*; + +import java.util.UUID; + +@RestController +@RequestMapping("/orders") +public class OrderController { + + private final OrderService orderService; + + @Autowired + public OrderController(OrderService orderService) { + this.orderService = orderService; + } + + @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_VALUE) + void addProduct(@PathVariable final UUID id, @RequestBody final AddProductRequest addProductRequest) { + orderService.addProduct(id, addProductRequest.getProduct()); + } + + @DeleteMapping(value = "/{id}/products", consumes = MediaType.APPLICATION_JSON_VALUE) + void deleteProduct(@PathVariable final UUID id, @RequestParam final UUID productId) { + orderService.deleteProduct(id, productId); + } + + @PostMapping("/{id}/complete") + void completeOrder(@PathVariable final UUID id) { + orderService.completeOrder(id); + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/AddProductRequest.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/AddProductRequest.java new file mode 100644 index 0000000000..ec107d635b --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/AddProductRequest.java @@ -0,0 +1,20 @@ +package com.baeldung.dddhexagonalspring.application.request; + +import com.baeldung.dddhexagonalspring.domain.Product; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; + +public class AddProductRequest { + @NotNull 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/dddhexagonalspring/application/request/CreateOrderRequest.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/CreateOrderRequest.java new file mode 100644 index 0000000000..8c51fbe479 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/request/CreateOrderRequest.java @@ -0,0 +1,20 @@ +package com.baeldung.dddhexagonalspring.application.request; + +import com.baeldung.dddhexagonalspring.domain.Product; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; + +public class CreateOrderRequest { + @NotNull private Product product; + + @JsonCreator + public CreateOrderRequest(@JsonProperty("product") @NotNull final Product product) { + this.product = product; + } + + public Product getProduct() { + return product; + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/response/CreateOrderResponse.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/response/CreateOrderResponse.java new file mode 100644 index 0000000000..72ee1134c3 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/application/response/CreateOrderResponse.java @@ -0,0 +1,15 @@ +package com.baeldung.dddhexagonalspring.application.response; + +import java.util.UUID; + +public class CreateOrderResponse { + private final UUID id; + + public CreateOrderResponse(final UUID id) { + this.id = id; + } + + public UUID getId() { + return id; + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/DomainException.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/DomainException.java new file mode 100644 index 0000000000..7baef7bab6 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/DomainException.java @@ -0,0 +1,7 @@ +package com.baeldung.dddhexagonalspring.domain; + +class DomainException extends RuntimeException { + DomainException(final String message) { + super(message); + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java new file mode 100644 index 0000000000..7d40007411 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Order.java @@ -0,0 +1,82 @@ +package com.baeldung.dddhexagonalspring.domain; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +public class Order { + private UUID id; + private OrderStatus status; + private List orderItems; + private BigDecimal price; + + public Order(final UUID id, final Product product) { + this.id = id; + this.orderItems = new ArrayList<>(Collections.singletonList(new OrderItem(product))); + this.status = OrderStatus.CREATED; + this.price = product.getPrice(); + } + + public void complete() { + validateState(); + this.status = OrderStatus.COMPLETED; + } + + public void addOrder(final Product product) { + validateState(); + validateProduct(product); + orderItems.add(new OrderItem(product)); + price = price.add(product.getPrice()); + } + + public void removeOrder(final UUID id) { + validateState(); + final OrderItem orderItem = getOrderItem(id); + orderItems.remove(orderItem); + + price = price.subtract(orderItem.getPrice()); + } + + 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.")); + } + + 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 UUID getId() { + return id; + } + + public OrderStatus getStatus() { + return status; + } + + public BigDecimal getPrice() { + return price; + } + + public List getOrderItems() { + return Collections.unmodifiableList(orderItems); + } + + private Order() { + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderItem.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderItem.java new file mode 100644 index 0000000000..9debb02680 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderItem.java @@ -0,0 +1,39 @@ +package com.baeldung.dddhexagonalspring.domain; + +import java.math.BigDecimal; +import java.util.Objects; +import java.util.UUID; + +public class OrderItem { + private UUID productId; + private BigDecimal price; + + public OrderItem(final Product product) { + this.productId = product.getId(); + this.price = product.getPrice(); + } + + public UUID getProductId() { + return productId; + } + + public BigDecimal getPrice() { + return price; + } + + private OrderItem() { + } + + @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(productId, orderItem.productId) && Objects.equals(price, orderItem.price); + } + + @Override + public int hashCode() { + return Objects.hash(productId, price); + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderStatus.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderStatus.java new file mode 100644 index 0000000000..2ee5df3ab7 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/OrderStatus.java @@ -0,0 +1,5 @@ +package com.baeldung.dddhexagonalspring.domain; + +public enum OrderStatus { + CREATED, COMPLETED +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Product.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Product.java new file mode 100644 index 0000000000..e05b4afe62 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/Product.java @@ -0,0 +1,46 @@ +package com.baeldung.dddhexagonalspring.domain; + +import com.fasterxml.jackson.annotation.JsonCreator; +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("id") final UUID id, @JsonProperty("price") final BigDecimal price, @JsonProperty("name") final String name) { + this.id = id; + this.price = price; + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public String getName() { + return name; + } + + public UUID getId() { + return id; + } + + @Override + 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(id, price, name); + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/repository/OrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/repository/OrderRepository.java new file mode 100644 index 0000000000..14b34e13f3 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/repository/OrderRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.dddhexagonalspring.domain.repository; + +import com.baeldung.dddhexagonalspring.domain.Order; + +import java.util.Optional; +import java.util.UUID; + +public interface OrderRepository { + Optional findById(UUID id); + + void save(Order order); +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderService.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderService.java new file mode 100644 index 0000000000..4fb2377745 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderService.java @@ -0,0 +1,54 @@ +package com.baeldung.dddhexagonalspring.domain.service; + +import com.baeldung.dddhexagonalspring.domain.Order; +import com.baeldung.dddhexagonalspring.domain.Product; +import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository; + +import java.util.UUID; + +public class DomainOrderService implements OrderService { + + private final OrderRepository orderRepository; + + public DomainOrderService(final OrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Override + 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 UUID id, final Product product) { + final Order order = getOrder(id); + order.addOrder(product); + + orderRepository.save(order); + } + + @Override + public void completeOrder(final UUID id) { + final Order order = getOrder(id); + order.complete(); + + orderRepository.save(order); + } + + @Override + public void deleteProduct(final UUID id, final UUID productId) { + final Order order = getOrder(id); + order.removeOrder(productId); + + orderRepository.save(order); + } + + 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/dddhexagonalspring/domain/service/OrderService.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/OrderService.java new file mode 100644 index 0000000000..37297d74c4 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/domain/service/OrderService.java @@ -0,0 +1,15 @@ +package com.baeldung.dddhexagonalspring.domain.service; + +import com.baeldung.dddhexagonalspring.domain.Product; + +import java.util.UUID; + +public interface OrderService { + UUID createOrder(Product product); + + void addProduct(UUID id, Product product); + + void completeOrder(UUID id); + + void deleteProduct(UUID id, UUID productId); +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/BeanConfiguration.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/BeanConfiguration.java new file mode 100644 index 0000000000..4be5d84ba7 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/BeanConfiguration.java @@ -0,0 +1,19 @@ +package com.baeldung.dddhexagonalspring.infrastracture.configuration; + +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; + +@Configuration +@ComponentScan(basePackageClasses = DomainLayerApplication.class) +public class BeanConfiguration { + + @Bean + OrderService orderService(final OrderRepository orderRepository) { + return new DomainOrderService(orderRepository); + } +} 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 new file mode 100644 index 0000000000..fd76b2eb0e --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/configuration/MongoDBConfiguration.java @@ -0,0 +1,8 @@ +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) +public class MongoDBConfiguration { +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java new file mode 100644 index 0000000000..3123ef3e2f --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/MongoDbOrderRepository.java @@ -0,0 +1,30 @@ +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; + +import java.util.Optional; +import java.util.UUID; + +@Component +public class MongoDbOrderRepository implements OrderRepository { + + private final SpringDataOrderRepository orderRepository; + + @Autowired + public MongoDbOrderRepository(final SpringDataOrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Override + public Optional findById(final UUID id) { + return orderRepository.findById(id); + } + + @Override + public void save(final Order order) { + orderRepository.save(order); + } +} diff --git a/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java new file mode 100644 index 0000000000..0279a5ce4a --- /dev/null +++ b/ddd/src/main/java/com/baeldung/dddhexagonalspring/infrastracture/repository/SpringDataOrderRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.dddhexagonalspring.infrastracture.repository; + +import com.baeldung.dddhexagonalspring.domain.Order; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.UUID; + +@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/dddhexagonalspring/domain/OrderProvider.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderProvider.java new file mode 100644 index 0000000000..c534713ca3 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderProvider.java @@ -0,0 +1,17 @@ +package com.baeldung.dddhexagonalspring.domain; + +import java.math.BigDecimal; +import java.util.UUID; + +public class OrderProvider { + public static Order getCreatedOrder() { + return new Order(UUID.randomUUID(), new Product(UUID.randomUUID(), BigDecimal.TEN, "productName")); + } + + public static Order getCompletedOrder() { + final Order order = getCreatedOrder(); + order.complete(); + + return order; + } +} diff --git a/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderUnitTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderUnitTest.java new file mode 100644 index 0000000000..eceed999d8 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/OrderUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.dddhexagonalspring.domain; + +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.UUID; + +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 + .getOrderItems() + .size(); + final BigDecimal orderOriginalPrice = order.getPrice(); + final Product productToAdd = new Product(UUID.randomUUID(), new BigDecimal("20"), "secondProduct"); + + order.addOrder(productToAdd); + + assertEquals(orderOriginalProductSize + 1, order + .getOrderItems() + .size()); + assertEquals(orderOriginalPrice.add(productToAdd.getPrice()), order.getPrice()); + } + + @Test + void shouldAddProduct_thenThrowException() { + final Order order = OrderProvider.getCompletedOrder(); + final Product productToAdd = new Product(UUID.randomUUID(), new BigDecimal("20"), "secondProduct"); + + final Executable executable = () -> order.addOrder(productToAdd); + + Assertions.assertThrows(DomainException.class, executable); + } + + @Test + void shouldRemoveProduct_thenUpdatePrice() { + final Order order = OrderProvider.getCreatedOrder(); + final UUID productId = order + .getOrderItems() + .get(0) + .getProductId(); + + order.removeOrder(productId); + + 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/dddhexagonalspring/domain/service/DomainOrderServiceUnitTest.java b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderServiceUnitTest.java new file mode 100644 index 0000000000..797068a30a --- /dev/null +++ b/ddd/src/test/java/com/baeldung/dddhexagonalspring/domain/service/DomainOrderServiceUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.dddhexagonalspring.domain.service; + +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; + +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; +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(UUID.randomUUID(), BigDecimal.TEN, "productName"); + + final UUID id = tested.createOrder(product); + + verify(orderRepository).save(any(Order.class)); + assertNotNull(id); + } + + @Test + void shouldAddProduct_thenSaveOrder() { + final Order order = spy(OrderProvider.getCreatedOrder()); + 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).addOrder(product); + } + + @Test + void shouldAddProduct_thenThrowException() { + final Product product = new Product(UUID.randomUUID(), BigDecimal.TEN, "test"); + final UUID id = UUID.randomUUID(); + 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 UUID productId = order + .getOrderItems() + .get(0) + .getProductId(); + + when(orderRepository.findById(order.getId())).thenReturn(Optional.of(order)); + + tested.deleteProduct(order.getId(), productId); + + verify(orderRepository).save(order); + verify(order).removeOrder(productId); + } +} \ 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 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 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..e0337498fc --- /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: + +* 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 diff --git a/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml new file mode 100644 index 0000000000..d85ddf4a0e --- /dev/null +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3' + +services: + order-mongo-database: + image: mongo:3.4.13 + restart: always + ports: + - 27017: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/src/test/resources/com/baeldung/dddhexagonalspring/mongo-init.js b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/mongo-init.js new file mode 100644 index 0000000000..b1564df50a --- /dev/null +++ b/ddd/src/test/resources/com/baeldung/dddhexagonalspring/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/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java index 9912e73c2b..1752c27286 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java @@ -34,7 +34,7 @@ public class HttpClientMultipartLiveTest { // No longer available // private static final String SERVER = "http://echo.200please.com"; - private static final String SERVER = "http://posttestserver.com/post.php"; + private static final String SERVER = "http://localhost:8080/spring-mvc-java/stub/multipart"; private static final String TEXTFILENAME = "temp.txt"; private static final String IMAGEFILENAME = "image.jpg"; private static final String ZIPFILENAME = "zipFile.zip"; @@ -84,7 +84,7 @@ public class HttpClientMultipartLiveTest { // final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); - builder.addPart("upfile", fileBody); + builder.addPart("file", fileBody); builder.addPart("text1", stringBody1); builder.addPart("text2", stringBody2); final HttpEntity entity = builder.build(); @@ -112,7 +112,7 @@ public class HttpClientMultipartLiveTest { final String message = "This is a multipart post"; final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); - builder.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, TEXTFILENAME); + builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, TEXTFILENAME); builder.addTextBody("text", message, ContentType.DEFAULT_BINARY); final HttpEntity entity = builder.build(); post.setEntity(entity); @@ -141,7 +141,7 @@ public class HttpClientMultipartLiveTest { final String message = "This is a multipart post"; final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); - builder.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, IMAGEFILENAME); + builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, IMAGEFILENAME); builder.addBinaryBody("upstream", inputStream, ContentType.create("application/zip"), ZIPFILENAME); builder.addTextBody("text", message, ContentType.TEXT_PLAIN); final HttpEntity entity = builder.build(); @@ -165,7 +165,7 @@ public class HttpClientMultipartLiveTest { final byte[] bytes = "binary code".getBytes(); final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); - builder.addBinaryBody("upfile", bytes, ContentType.DEFAULT_BINARY, TEXTFILENAME); + builder.addBinaryBody("file", bytes, ContentType.DEFAULT_BINARY, TEXTFILENAME); builder.addTextBody("text", message, ContentType.TEXT_PLAIN); final HttpEntity entity = builder.build(); post.setEntity(entity); diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java index e33d9ee212..317cdca529 100644 --- a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java +++ b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java @@ -24,10 +24,7 @@ public class ConvertToMap { public TreeMap listToSortedMap(List books) { return books.stream() - .sorted(Comparator.comparing(Book::getName)) .collect(Collectors.toMap(Book::getName, Function.identity(), (o1, o2) -> o1, TreeMap::new)); } - - } diff --git a/libraries-server/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java b/libraries-server/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java index 6c4fed6d07..f42db2d3de 100644 --- a/libraries-server/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java +++ b/libraries-server/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java @@ -7,22 +7,50 @@ import org.apache.tomcat.util.descriptor.web.FilterDef; import org.apache.tomcat.util.descriptor.web.FilterMap; import java.io.File; +import java.io.IOException; +import java.net.ServerSocket; +import java.util.Random; /** * Created by adi on 1/10/18. */ public class ProgrammaticTomcat { + private static boolean isFree(int port) { + try { + new ServerSocket(port).close(); + return true; + } catch (IOException e) { + return false; + } + } + private Tomcat tomcat = null; + private int randomPort; + + public ProgrammaticTomcat() { + // Get a random port number in range 6000 (inclusive) - 9000 (exclusive) + this.randomPort = new Random() + .ints(6000, 9000) + .filter(ProgrammaticTomcat::isFree) + .findFirst() + .orElse(8080); + } + // uncomment for live test // public static void main(String[] args) throws LifecycleException, ServletException, URISyntaxException, IOException { // startTomcat(); // } + + public int getPort() { + return randomPort; + } + public void startTomcat() throws LifecycleException { tomcat = new Tomcat(); - tomcat.setPort(8080); + tomcat.setPort(randomPort); tomcat.setHostname("localhost"); String appBase = "."; tomcat.getHost().setAppBase(appBase); diff --git a/libraries-server/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java b/libraries-server/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java index 9224561341..888fb8e366 100644 --- a/libraries-server/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java +++ b/libraries-server/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java @@ -37,7 +37,8 @@ public class ProgrammaticTomcatIntegrationTest { @Test public void givenTomcatStarted_whenAccessServlet_responseIsTestAndResponseHeaderIsSet() throws Exception { CloseableHttpClient httpClient = HttpClientBuilder.create().build(); - HttpGet getServlet = new HttpGet("http://localhost:8080/my-servlet"); + String uri = "http://localhost:" + tomcat.getPort() + "/my-servlet"; + HttpGet getServlet = new HttpGet(uri); HttpResponse response = httpClient.execute(getServlet); assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); diff --git a/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Customer.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Customer.java similarity index 100% rename from persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Customer.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Customer.java diff --git a/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Order.java similarity index 100% rename from persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Order.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Order.java diff --git a/persistence-modules/hibernate5-2/pom.xml b/persistence-modules/hibernate5-2/pom.xml index 516ab83997..16f6c10a7a 100644 --- a/persistence-modules/hibernate5-2/pom.xml +++ b/persistence-modules/hibernate5-2/pom.xml @@ -27,6 +27,12 @@ h2 1.4.200 + + + org.apache.commons + commons-lang3 + 3.8.1 + diff --git a/persistence-modules/hibernate5-2/src/main/java/com/baeldung/hibernate/logging/Employee.java b/persistence-modules/hibernate5-2/src/main/java/com/baeldung/hibernate/logging/Employee.java new file mode 100644 index 0000000000..9dcf4058a7 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/main/java/com/baeldung/hibernate/logging/Employee.java @@ -0,0 +1,59 @@ +package com.baeldung.hibernate.logging; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Employee { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + + private String employeeNumber; + + private String title; + + private String name; + + public Employee() { + } + + public Employee(String name, String employeeNumber) { + this.name = name; + this.employeeNumber = employeeNumber; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmployeeNumber() { + return employeeNumber; + } + + public void setEmployeeNumber(String employeeNumber) { + this.employeeNumber = employeeNumber; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/persistence-modules/hibernate5-2/src/main/resources/hibernate-logging.cfg.xml b/persistence-modules/hibernate5-2/src/main/resources/hibernate-logging.cfg.xml new file mode 100644 index 0000000000..52ef1ee685 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/main/resources/hibernate-logging.cfg.xml @@ -0,0 +1,27 @@ + + + + + + + org.h2.Driver + jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1 + sa + + + 1 + + org.hibernate.dialect.H2Dialect + + org.hibernate.cache.internal.NoCacheProvider + + true + + create + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate5-2/src/test/java/com/baeldung/hibernatelogging/HibernateLoggingIntegrationTest.java b/persistence-modules/hibernate5-2/src/test/java/com/baeldung/hibernatelogging/HibernateLoggingIntegrationTest.java new file mode 100644 index 0000000000..8ec722671d --- /dev/null +++ b/persistence-modules/hibernate5-2/src/test/java/com/baeldung/hibernatelogging/HibernateLoggingIntegrationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.hibernatelogging; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.query.Query; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.logging.Employee; + +public class HibernateLoggingIntegrationTest { + + private SessionFactory sessionFactory; + + @Before + public void setUp() throws IOException { + final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("hibernate-logging.cfg.xml") + .build(); + try { + sessionFactory = new MetadataSources(registry).buildMetadata() + .buildSessionFactory(); + Session session = sessionFactory.openSession(); + session.beginTransaction(); + session.save(new Employee("John Smith", "001")); + session.getTransaction() + .commit(); + session.close(); + } catch (Exception e) { + fail(e); + StandardServiceRegistryBuilder.destroy(registry); + } + } + + @Test + public void whenAllEmployeesAreSelected_ThenSuccess() { + Query query = sessionFactory.openSession().createQuery("from com.baeldung.hibernate.logging.Employee", Employee.class); + List deptEmployees = query.list(); + Employee deptEmployee = deptEmployees.get(0); + assertEquals("John Smith", deptEmployee.getName()); + } +} diff --git a/persistence-modules/hibernate5-2/src/test/resources/log4j.xml b/persistence-modules/hibernate5-2/src/test/resources/log4j.xml new file mode 100644 index 0000000000..2d153af124 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/test/resources/log4j.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate5-2/src/test/resources/log4j2.xml b/persistence-modules/hibernate5-2/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..c5d0f12462 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/test/resources/log4j2.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate5-2/src/test/resources/logback.xml b/persistence-modules/hibernate5-2/src/test/resources/logback.xml new file mode 100644 index 0000000000..9e591977d7 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/test/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + %d{yyyy-MM-dd HH:mm:ss} | %-5p | [%thread] %logger{5}:%L - %msg%n + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/pom.xml b/spring-cloud/spring-cloud-zuul/pom.xml index 1593bc59e9..b1f2e886de 100644 --- a/spring-cloud/spring-cloud-zuul/pom.xml +++ b/spring-cloud/spring-cloud-zuul/pom.xml @@ -73,8 +73,8 @@ UTF-8 UTF-8 - Finchley.SR1 - 2.0.6.RELEASE + Hoxton.RELEASE + 2.2.2.RELEASE diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/pom.xml index 57e566657b..f5a8c3b613 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/pom.xml @@ -12,10 +12,6 @@ - - org.springframework.boot - spring-boot-starter-web - org.apache.commons commons-lang3 diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/controller/FooController.java b/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/controller/FooController.java index 87f237b75c..f8f07342f6 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/controller/FooController.java +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/controller/FooController.java @@ -1,11 +1,9 @@ package com.baeldung.web.controller; import com.baeldung.web.dto.Foo; -import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -13,22 +11,15 @@ import javax.servlet.http.HttpServletResponse; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; -@Controller +@RestController public class FooController { - public FooController() { - super(); - } - - // API - read - @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") - @ResponseBody + @GetMapping("/foos/{id}") public Foo findById(@PathVariable final long id, HttpServletRequest req, HttpServletResponse res) { - // System.out.println(req.getHeaderNames()); - // System.out.println("------" + req.getHeader("Test")); if (req.getHeader("Test") != null) { res.addHeader("Test", req.getHeader("Test")); } + return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4)); } diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/dto/Foo.java b/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/dto/Foo.java index 107f982f98..b25aef266d 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/dto/Foo.java +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-foos-resource/src/main/java/com/baeldung/web/dto/Foo.java @@ -1,22 +1,15 @@ package com.baeldung.web.dto; public class Foo { + private long id; private String name; - public Foo() { - super(); - } - public Foo(final long id, final String name) { - super(); - this.id = id; this.name = name; } - // - public long getId() { return id; } diff --git a/spring-di/src/main/java/org/baeldung/store/AppConfig.java b/spring-di/src/main/java/org/baeldung/store/AppConfig.java new file mode 100644 index 0000000000..80b6733dff --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/store/AppConfig.java @@ -0,0 +1,23 @@ +package org.baeldung.store; + +import org.springframework.context.annotation.Bean; + +public class AppConfig { + + @Bean + public Item item1() { + return new ItemImpl1(); + } + + @Bean + public Store storeThroughConstructorInjection() { + return new Store(item1()); + } + + @Bean + public Store storeThroughSetterInjection() { + Store store = new Store(); + store.setItem(item1()); + return store; + } +} diff --git a/spring-di/src/main/java/org/baeldung/store/Item.java b/spring-di/src/main/java/org/baeldung/store/Item.java new file mode 100644 index 0000000000..1d7292fc35 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/store/Item.java @@ -0,0 +1,5 @@ +package org.baeldung.store; + +public interface Item { + +} diff --git a/spring-di/src/main/java/org/baeldung/store/ItemImpl1.java b/spring-di/src/main/java/org/baeldung/store/ItemImpl1.java new file mode 100644 index 0000000000..8bda9f24c9 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/store/ItemImpl1.java @@ -0,0 +1,5 @@ +package org.baeldung.store; + +public class ItemImpl1 implements Item { + +} diff --git a/spring-di/src/main/java/org/baeldung/store/Store.java b/spring-di/src/main/java/org/baeldung/store/Store.java new file mode 100644 index 0000000000..dcc2c3be48 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/store/Store.java @@ -0,0 +1,23 @@ +package org.baeldung.store; + +import org.springframework.beans.factory.annotation.Autowired; + +public class Store { + + @Autowired + private Item item; + + public Store() {} + + public Store(Item item) { + this.item = item; + } + + public Item getItem() { + return item; + } + + public void setItem(Item item) { + this.item = item; + } +} diff --git a/spring-di/src/main/resources/ioc-context-by-type.xml b/spring-di/src/main/resources/ioc-context-by-type.xml new file mode 100644 index 0000000000..1249ce51af --- /dev/null +++ b/spring-di/src/main/resources/ioc-context-by-type.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di/src/main/resources/ioc-context.xml b/spring-di/src/main/resources/ioc-context.xml new file mode 100644 index 0000000000..0e1d0ac29c --- /dev/null +++ b/spring-di/src/main/resources/ioc-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di/src/test/java/org/baeldung/store/AppConfigUnitTest.java b/spring-di/src/test/java/org/baeldung/store/AppConfigUnitTest.java new file mode 100644 index 0000000000..3260114679 --- /dev/null +++ b/spring-di/src/test/java/org/baeldung/store/AppConfigUnitTest.java @@ -0,0 +1,35 @@ +package org.baeldung.store; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = AppConfig.class) +public class AppConfigUnitTest { + + @Autowired + @Qualifier("storeThroughConstructorInjection") + private Store storeByConstructorInjection; + + @Autowired + @Qualifier("storeThroughSetterInjection") + private Store storeBySetterInjection; + + @Test + public void givenValidXmlConfig_WhenInjectStoreByConstructorInjection_ThenBeanIsNotNull() { + assertNotNull(storeByConstructorInjection); + assertNotNull(storeByConstructorInjection.getItem()); + } + + @Test + public void givenValidXmlConfig_WhenInjectStoreBySetterInjection_ThenBeanIsNotNull() { + assertNotNull(storeBySetterInjection); + assertNotNull(storeByConstructorInjection.getItem()); + } +} diff --git a/spring-di/src/test/java/org/baeldung/store/XmlAppConfigByTypeUnitTest.java b/spring-di/src/test/java/org/baeldung/store/XmlAppConfigByTypeUnitTest.java new file mode 100644 index 0000000000..036399e537 --- /dev/null +++ b/spring-di/src/test/java/org/baeldung/store/XmlAppConfigByTypeUnitTest.java @@ -0,0 +1,30 @@ +package org.baeldung.store; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Separate unit test class where only one Item object is available for + * autowiring. If the ioc-context.xml were used for autowiring by type, there + * would be multiple qualifying Item objects, causing a failure. + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:/ioc-context-by-type.xml") +public class XmlAppConfigByTypeUnitTest { + + @Autowired + @Qualifier("xml-store-by-autowire-type") + private Store storeByAutowireInjectionByType; + + @Test + public void givenValidXmlConfig_WhenInjectStoreByAutowireInjectionByType_ThenBeanIsNotNull() { + assertNotNull(storeByAutowireInjectionByType); + assertNotNull(storeByAutowireInjectionByType.getItem()); + } +} diff --git a/spring-di/src/test/java/org/baeldung/store/XmlAppConfigUnitTest.java b/spring-di/src/test/java/org/baeldung/store/XmlAppConfigUnitTest.java new file mode 100644 index 0000000000..2dd4d6ccd6 --- /dev/null +++ b/spring-di/src/test/java/org/baeldung/store/XmlAppConfigUnitTest.java @@ -0,0 +1,55 @@ +package org.baeldung.store; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:/ioc-context.xml") +public class XmlAppConfigUnitTest { + + @Autowired + @Qualifier("xml-store-by-constructor") + private Store storeByConstructorInjection; + + @Autowired + @Qualifier("xml-store-by-setter") + private Store storeBySetterInjection; + + @Autowired + @Qualifier("xml-store-by-autowire-name") + private Store storeByAutowireInjectionByName; + + @Autowired + @Qualifier("xml-store-by-setter-lazy") + private Store storeBySetterInjectionLazy; + + @Test + public void givenValidXmlConfig_WhenInjectStoreByConstructorInjection_ThenBeanIsNotNull() { + assertNotNull(storeByConstructorInjection); + assertNotNull(storeByConstructorInjection.getItem()); + } + + @Test + public void givenValidXmlConfig_WhenInjectStoreBySetterInjection_ThenBeanIsNotNull() { + assertNotNull(storeBySetterInjection); + assertNotNull(storeByConstructorInjection.getItem()); + } + + @Test + public void givenValidXmlConfig_WhenInjectStoreByAutowireInjectionByName_ThenBeanIsNotNull() { + assertNotNull(storeByAutowireInjectionByName); + assertNotNull(storeByAutowireInjectionByName.getItem()); + } + + @Test + public void givenValidXmlConfig_WhenInjectStoreBySetterInjectionLazy_ThenBeanIsNotNull() { + assertNotNull(storeBySetterInjectionLazy); + assertNotNull(storeByConstructorInjection.getItem()); + } +} diff --git a/spring-mvc-basics-2/src/main/java/com/baeldung/model/Article.java b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/Article.java similarity index 87% rename from spring-mvc-basics-2/src/main/java/com/baeldung/model/Article.java rename to spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/Article.java index 141bd17db7..f6675295ed 100644 --- a/spring-mvc-basics-2/src/main/java/com/baeldung/model/Article.java +++ b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/Article.java @@ -1,4 +1,4 @@ -package com.baeldung.model; +package com.baeldung.controller.optionalpathvars; public class Article { diff --git a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerController.java b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerController.java index 62c2502242..14b16e148b 100644 --- a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerController.java +++ b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerController.java @@ -1,13 +1,11 @@ package com.baeldung.controller.optionalpathvars; -import static com.baeldung.model.Article.DEFAULT_ARTICLE; +import static com.baeldung.controller.optionalpathvars.Article.DEFAULT_ARTICLE; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.model.Article; - @RestController public class ArticleViewerController { diff --git a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamController.java b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamController.java index d16cf4115c..50744b6067 100644 --- a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamController.java +++ b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamController.java @@ -1,6 +1,6 @@ package com.baeldung.controller.optionalpathvars; -import static com.baeldung.model.Article.DEFAULT_ARTICLE; +import static com.baeldung.controller.optionalpathvars.Article.DEFAULT_ARTICLE; import java.util.Map; @@ -8,8 +8,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.model.Article; - @RestController @RequestMapping(value = "/mapParam") public class ArticleViewerWithMapParamController { diff --git a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java index fd7b900535..ff645fbcc7 100644 --- a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java +++ b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java @@ -1,14 +1,12 @@ package com.baeldung.controller.optionalpathvars; -import static com.baeldung.model.Article.DEFAULT_ARTICLE; +import static com.baeldung.controller.optionalpathvars.Article.DEFAULT_ARTICLE; import java.util.Optional; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.baeldung.model.Article;; +import org.springframework.web.bind.annotation.RestController;; @RestController @RequestMapping("/optionalParam") diff --git a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java index d9b36f93e8..8cd1539391 100644 --- a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java +++ b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java @@ -1,12 +1,10 @@ package com.baeldung.controller.optionalpathvars; -import static com.baeldung.model.Article.DEFAULT_ARTICLE; +import static com.baeldung.controller.optionalpathvars.Article.DEFAULT_ARTICLE; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.baeldung.model.Article;; +import org.springframework.web.bind.annotation.RestController;; @RestController @RequestMapping(value = "/requiredAttribute") diff --git a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java index 0b66b6cf43..0ea401a589 100644 --- a/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java +++ b/spring-mvc-basics-2/src/main/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java @@ -1,13 +1,11 @@ package com.baeldung.controller.optionalpathvars; -import static com.baeldung.model.Article.DEFAULT_ARTICLE; +import static com.baeldung.controller.optionalpathvars.Article.DEFAULT_ARTICLE; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.model.Article; - @RestController @RequestMapping(value = "/seperateMethods") public class ArticleViewerWithTwoSeparateMethodsController { diff --git a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java index 629e37f963..c7b568b68e 100644 --- a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java +++ b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java @@ -12,8 +12,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.model.Article; import org.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java index 00494171c0..760d94af17 100644 --- a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java +++ b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java @@ -12,8 +12,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.model.Article; import org.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java index 3c82b11578..fca6bba5fd 100644 --- a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java +++ b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java @@ -12,8 +12,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.model.Article; import org.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java index 9532270c43..5d2733ec92 100644 --- a/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java +++ b/spring-mvc-basics-2/src/test/java/com/baeldung/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java @@ -12,8 +12,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.model.Article; import org.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java new file mode 100644 index 0000000000..28c35e8603 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java @@ -0,0 +1,58 @@ +package com.baeldung.web.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.multipart.MultipartFile; + +@Controller +public class MultipartFileUploadStubController { + + @PostMapping("/stub/multipart") + public ResponseEntity uploadFile(MultipartFile file, String text, String text1, String text2, MultipartFile upstream) { + UploadResultResource result = new UploadResultResource(file, text, text1, text2, upstream); + return new ResponseEntity<>(result, HttpStatus.OK); + } + + public static class UploadResultResource { + + private final String file; + private final String text; + private final String text1; + private final String text2; + private final String upstream; + + public UploadResultResource(MultipartFile file, String text, String text1, String text2, MultipartFile upstream) { + this.file = format(file); + this.text = text; + this.text1 = text1; + this.text2 = text2; + this.upstream = format(upstream); + } + + private static String format(MultipartFile file) { + return file == null ? null : file.getOriginalFilename() + " (size: " + file.getSize() + " bytes)"; + } + + public String getFile() { + return file; + } + + public String getText() { + return text; + } + + public String getText1() { + return text1; + } + + public String getText2() { + return text2; + } + + public String getUpstream() { + return upstream; + } + } +} diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequest.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequest.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequest.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequest.java diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/CachedBodyServletInputStream.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/CachedBodyServletInputStream.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/CachedBodyServletInputStream.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/CachedBodyServletInputStream.java diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/ContentCachingFilter.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/ContentCachingFilter.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/ContentCachingFilter.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/ContentCachingFilter.java diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/HttpRequestDemoConfig.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/HttpRequestDemoConfig.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/HttpRequestDemoConfig.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/HttpRequestDemoConfig.java diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/Person.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/Person.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/Person.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/Person.java diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/PersonController.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/PersonController.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/PersonController.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/PersonController.java diff --git a/spring-core-2/src/main/java/org/baeldung/cachedrequest/PrintRequestContentFilter.java b/spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/PrintRequestContentFilter.java similarity index 100% rename from spring-core-2/src/main/java/org/baeldung/cachedrequest/PrintRequestContentFilter.java rename to spring-mvc-simple-2/src/main/java/org/baeldung/cachedrequest/PrintRequestContentFilter.java diff --git a/spring-core-2/src/test/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java b/spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java similarity index 100% rename from spring-core-2/src/test/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java rename to spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java diff --git a/spring-core-2/src/test/java/org/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java b/spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java similarity index 100% rename from spring-core-2/src/test/java/org/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java rename to spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java diff --git a/spring-core-2/src/test/java/org/baeldung/cachedrequest/ContentCachingFilterUnitTest.java b/spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/ContentCachingFilterUnitTest.java similarity index 100% rename from spring-core-2/src/test/java/org/baeldung/cachedrequest/ContentCachingFilterUnitTest.java rename to spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/ContentCachingFilterUnitTest.java diff --git a/spring-core-2/src/test/java/org/baeldung/cachedrequest/PersonControllerIntegrationTest.java b/spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/PersonControllerIntegrationTest.java similarity index 100% rename from spring-core-2/src/test/java/org/baeldung/cachedrequest/PersonControllerIntegrationTest.java rename to spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/PersonControllerIntegrationTest.java diff --git a/spring-core-2/src/test/java/org/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java b/spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java similarity index 100% rename from spring-core-2/src/test/java/org/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java rename to spring-mvc-simple-2/src/test/java/org/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java diff --git a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java index 9dc45c5b32..de41019e49 100644 --- a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -6,6 +6,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -16,9 +17,12 @@ import java.util.Base64; @RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class SpringSessionMongoDBIntegrationTest { + @LocalServerPort + private int port; + @Autowired private MongoOperationsSessionRepository repository; @@ -27,7 +31,7 @@ public class SpringSessionMongoDBIntegrationTest { @Test public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { HttpEntity response = restTemplate - .exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); + .exchange("http://localhost:" + port, HttpMethod.GET, null, String.class); HttpHeaders headers = response.getHeaders(); String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); diff --git a/spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java b/spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java index f739aeb3ab..7ee0294315 100644 --- a/spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java +++ b/spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java @@ -1,16 +1,11 @@ package com.baeldung.spring.session; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Set; - import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -20,19 +15,27 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; - import redis.clients.jedis.Jedis; import redis.embedded.RedisServer; +import java.io.IOException; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @RunWith(SpringRunner.class) -@SpringBootTest(classes = SessionWebApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) +@SpringBootTest(classes = SessionWebApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class SessionControllerIntegrationTest { - private Jedis jedis; private static RedisServer redisServer; + + @LocalServerPort + private int port; + + private Jedis jedis; private TestRestTemplate testRestTemplate; private TestRestTemplate testRestTemplateWithAuth; - private String testUrl = "http://localhost:8080/"; @BeforeClass public static void startRedisServer() throws IOException { @@ -41,7 +44,7 @@ public class SessionControllerIntegrationTest { } @AfterClass - public static void stopRedisServer() throws IOException { + public static void stopRedisServer() { redisServer.stop(); } @@ -63,13 +66,13 @@ public class SessionControllerIntegrationTest { @Test public void testUnauthenticatedCantAccess() { - ResponseEntity result = testRestTemplate.getForEntity(testUrl, String.class); + ResponseEntity result = testRestTemplate.getForEntity(getTestUrl(), String.class); assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); } @Test public void testRedisControlsSession() { - ResponseEntity result = testRestTemplateWithAuth.getForEntity(testUrl, String.class); + ResponseEntity result = testRestTemplateWithAuth.getForEntity(getTestUrl(), String.class); assertEquals("hello admin", result.getBody()); // login worked Set redisResult = jedis.keys("*"); @@ -80,13 +83,16 @@ public class SessionControllerIntegrationTest { headers.add("Cookie", sessionCookie); HttpEntity httpEntity = new HttpEntity<>(headers); - result = testRestTemplate.exchange(testUrl, HttpMethod.GET, httpEntity, String.class); + result = testRestTemplate.exchange(getTestUrl(), HttpMethod.GET, httpEntity, String.class); assertEquals("hello admin", result.getBody()); // access with session works worked jedis.flushAll(); // clear all keys in redis - result = testRestTemplate.exchange(testUrl, HttpMethod.GET, httpEntity, String.class); + result = testRestTemplate.exchange(getTestUrl(), HttpMethod.GET, httpEntity, String.class); assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());// access denied after sessions are removed in redis + } + private String getTestUrl(){ + return "http://localhost:" + port; } } \ No newline at end of file diff --git a/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumber/books/BookStore.java b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumber/books/BookStore.java index 4ccfe61542..da9b711a16 100644 --- a/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumber/books/BookStore.java +++ b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumber/books/BookStore.java @@ -19,10 +19,4 @@ public class BookStore { .filter(book -> Objects.equals(author, book.getAuthor())) .collect(Collectors.toList()); } - - public Optional bookByTitle(String title) { - return books.stream() - .filter(book -> book.getTitle().equals(title)) - .findFirst(); - } } diff --git a/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumberbackground/books/Book.java b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumberbackground/books/Book.java new file mode 100644 index 0000000000..5fd1e680a0 --- /dev/null +++ b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumberbackground/books/Book.java @@ -0,0 +1,35 @@ +package com.baeldung.cucumberbackground.books; + +public class Book { + + private String title; + private String author; + + public Book(String title, String author) { + this.title = title; + this.author = author; + } + + public Book() {} + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return "Book [title=" + title + ", author=" + author + "]"; + } +} diff --git a/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumberbackground/books/BookStore.java b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumberbackground/books/BookStore.java new file mode 100644 index 0000000000..f22eecb5f3 --- /dev/null +++ b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumberbackground/books/BookStore.java @@ -0,0 +1,28 @@ +package com.baeldung.cucumberbackground.books; + +import java.util.*; +import java.util.stream.Collectors; + +public class BookStore { + private List books = new ArrayList<>(); + + public void addBook(Book book) { + books.add(book); + } + + public void addAllBooks(Collection books) { + this.books.addAll(books); + } + + public List booksByAuthor(String author) { + return books.stream() + .filter(book -> Objects.equals(author, book.getAuthor())) + .collect(Collectors.toList()); + } + + public Optional bookByTitle(String title) { + return books.stream() + .filter(book -> book.getTitle().equals(title)) + .findFirst(); + } +} diff --git a/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumber/books/BookStoreRunSteps.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumber/books/BookStoreRunSteps.java index 995a3469f0..a0c759ab26 100644 --- a/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumber/books/BookStoreRunSteps.java +++ b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumber/books/BookStoreRunSteps.java @@ -56,11 +56,6 @@ public class BookStoreRunSteps { foundBooks = store.booksByAuthor(author); } - @When("^I search for a book titled (.+)$") - public void searchForBookByTitle(String title) { - foundBook = store.bookByTitle(title).orElse(null); - } - @Then("^I find (\\d+) books$") public void findBooks(int count) { assertEquals(count, foundBooks.size()); diff --git a/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreRunSteps.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreRunSteps.java new file mode 100644 index 0000000000..981fe41f11 --- /dev/null +++ b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreRunSteps.java @@ -0,0 +1,58 @@ +package com.baeldung.cucumberbackground.books; + +import io.cucumber.datatable.DataTable; +import io.cucumber.java.Before; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + +public class BookStoreRunSteps { + private BookStore store; + private List foundBooks; + private Book foundBook; + + @Before + public void setUp() { + store = new BookStore(); + foundBooks = new ArrayList<>(); + } + + @Given("^I have the following books in the store$") + public void haveBooksInTheStore(DataTable table) { + List> rows = table.asLists(String.class); + + for (List columns: rows) { + store.addBook(new Book(columns.get(0), columns.get(1))); + } + } + + @When("^I search for books by author (.+)$") + public void searchForBooksByAuthor(String author) { + foundBooks = store.booksByAuthor(author); + } + + @When("^I search for a book titled (.+)$") + public void searchForBookByTitle(String title) { + foundBook = store.bookByTitle(title).orElse(null); + } + + @Then("^I find (\\d+) books$") + public void findBooks(int count) { + assertEquals(count, foundBooks.size()); + } + + @Then("^I find a book$") + public void findABook() { + assertNotNull(foundBook); + } + + @Then("^I find no book$") + public void findNoBook() { + assertNull(foundBook); + } +} diff --git a/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreWithBackgroundIntegrationTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreWithBackgroundIntegrationTest.java new file mode 100644 index 0000000000..528ccbc882 --- /dev/null +++ b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreWithBackgroundIntegrationTest.java @@ -0,0 +1,12 @@ +package com.baeldung.cucumberbackground.books; + +import io.cucumber.junit.Cucumber; +import io.cucumber.junit.CucumberOptions; +import org.junit.runner.RunWith; + +@RunWith(Cucumber.class) +@CucumberOptions(features = "classpath:features/book-store-with-background.feature") +public class BookStoreWithBackgroundIntegrationTest { + +} + diff --git a/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreWithoutBackgroundIntegrationTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreWithoutBackgroundIntegrationTest.java new file mode 100644 index 0000000000..6343a52cdc --- /dev/null +++ b/testing-modules/testing-libraries/src/test/java/com/baeldung/cucumberbackground/books/BookStoreWithoutBackgroundIntegrationTest.java @@ -0,0 +1,12 @@ +package com.baeldung.cucumberbackground.books; + +import io.cucumber.junit.Cucumber; +import io.cucumber.junit.CucumberOptions; +import org.junit.runner.RunWith; + +@RunWith(Cucumber.class) +@CucumberOptions(features = "classpath:features/book-store-without-background.feature") +public class BookStoreWithoutBackgroundIntegrationTest { + +} +