Merge branch 'master' into BAEL-3874-OCR-with-Tesseract

This commit is contained in:
Anshul BANSAL 2020-03-03 12:21:14 +02:00
commit ceaac9022c
106 changed files with 2117 additions and 294 deletions

View File

@ -0,0 +1,57 @@
package com.baeldung.algorithms.suffixtree;
import java.util.ArrayList;
import java.util.List;
public class Node {
private String text;
private List<Node> children;
private int position;
public Node(String word, int position) {
this.text = word;
this.position = position;
this.children = new ArrayList<>();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public String printTree(String depthIndicator) {
String str = "";
String positionStr = position > -1 ? "[" + String.valueOf(position) + "]" : "";
str += depthIndicator + text + positionStr + "\n";
for (int i = 0; i < children.size(); i++) {
str += children.get(i)
.printTree(depthIndicator + "\t");
}
return str;
}
@Override
public String toString() {
return printTree("");
}
}

View File

@ -0,0 +1,175 @@
package com.baeldung.algorithms.suffixtree;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SuffixTree {
private static final Logger LOGGER = LoggerFactory.getLogger(SuffixTree.class);
private static final String WORD_TERMINATION = "$";
private static final int POSITION_UNDEFINED = -1;
private Node root;
private String fullText;
public SuffixTree(String text) {
root = new Node("", POSITION_UNDEFINED);
for (int i = 0; i < text.length(); i++) {
addSuffix(text.substring(i) + WORD_TERMINATION, i);
}
fullText = text;
}
public List<String> searchText(String pattern) {
LOGGER.info("Searching for pattern \"{}\"", pattern);
List<String> result = new ArrayList<>();
List<Node> nodes = getAllNodesInTraversePath(pattern, root, false);
if (nodes.size() > 0) {
Node lastNode = nodes.get(nodes.size() - 1);
if (lastNode != null) {
List<Integer> positions = getPositions(lastNode);
positions = positions.stream()
.sorted()
.collect(Collectors.toList());
positions.forEach(m -> result.add((markPatternInText(m, pattern))));
}
}
return result;
}
private void addSuffix(String suffix, int position) {
LOGGER.info(">>>>>>>>>>>> Adding new suffix {}", suffix);
List<Node> nodes = getAllNodesInTraversePath(suffix, root, true);
if (nodes.size() == 0) {
addChildNode(root, suffix, position);
LOGGER.info("{}", printTree());
} else {
Node lastNode = nodes.remove(nodes.size() - 1);
String newText = suffix;
if (nodes.size() > 0) {
String existingSuffixUptoLastNode = nodes.stream()
.map(a -> a.getText())
.reduce("", String::concat);
// Remove prefix from newText already included in parent
newText = newText.substring(existingSuffixUptoLastNode.length());
}
extendNode(lastNode, newText, position);
LOGGER.info("{}", printTree());
}
}
private List<Integer> getPositions(Node node) {
List<Integer> positions = new ArrayList<>();
if (node.getText()
.endsWith(WORD_TERMINATION)) {
positions.add(node.getPosition());
}
for (int i = 0; i < node.getChildren()
.size(); i++) {
positions.addAll(getPositions(node.getChildren()
.get(i)));
}
return positions;
}
private String markPatternInText(Integer startPosition, String pattern) {
String matchingTextLHS = fullText.substring(0, startPosition);
String matchingText = fullText.substring(startPosition, startPosition + pattern.length());
String matchingTextRHS = fullText.substring(startPosition + pattern.length());
return matchingTextLHS + "[" + matchingText + "]" + matchingTextRHS;
}
private void addChildNode(Node parentNode, String text, int position) {
parentNode.getChildren()
.add(new Node(text, position));
}
private void extendNode(Node node, String newText, int position) {
String currentText = node.getText();
String commonPrefix = getLongestCommonPrefix(currentText, newText);
if (commonPrefix != currentText) {
String parentText = currentText.substring(0, commonPrefix.length());
String childText = currentText.substring(commonPrefix.length());
splitNodeToParentAndChild(node, parentText, childText);
}
String remainingText = newText.substring(commonPrefix.length());
addChildNode(node, remainingText, position);
}
private void splitNodeToParentAndChild(Node parentNode, String parentNewText, String childNewText) {
Node childNode = new Node(childNewText, parentNode.getPosition());
if (parentNode.getChildren()
.size() > 0) {
while (parentNode.getChildren()
.size() > 0) {
childNode.getChildren()
.add(parentNode.getChildren()
.remove(0));
}
}
parentNode.getChildren()
.add(childNode);
parentNode.setText(parentNewText);
parentNode.setPosition(POSITION_UNDEFINED);
}
private String getLongestCommonPrefix(String str1, String str2) {
int compareLength = Math.min(str1.length(), str2.length());
for (int i = 0; i < compareLength; i++) {
if (str1.charAt(i) != str2.charAt(i)) {
return str1.substring(0, i);
}
}
return str1.substring(0, compareLength);
}
private List<Node> getAllNodesInTraversePath(String pattern, Node startNode, boolean isAllowPartialMatch) {
List<Node> nodes = new ArrayList<>();
for (int i = 0; i < startNode.getChildren()
.size(); i++) {
Node currentNode = startNode.getChildren()
.get(i);
String nodeText = currentNode.getText();
if (pattern.charAt(0) == nodeText.charAt(0)) {
if (isAllowPartialMatch && pattern.length() <= nodeText.length()) {
nodes.add(currentNode);
return nodes;
}
int compareLength = Math.min(nodeText.length(), pattern.length());
for (int j = 1; j < compareLength; j++) {
if (pattern.charAt(j) != nodeText.charAt(j)) {
if (isAllowPartialMatch) {
nodes.add(currentNode);
}
return nodes;
}
}
nodes.add(currentNode);
if (pattern.length() > compareLength) {
List<Node> nodes2 = getAllNodesInTraversePath(pattern.substring(compareLength), currentNode, isAllowPartialMatch);
if (nodes2.size() > 0) {
nodes.addAll(nodes2);
} else if (!isAllowPartialMatch) {
nodes.add(null);
}
}
return nodes;
}
}
return nodes;
}
public String printTree() {
return root.printTree("");
}
}

View File

@ -0,0 +1,77 @@
package com.baeldung.algorithms.suffixtree;
import java.util.List;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SuffixTreeUnitTest {
private static final Logger LOGGER = LoggerFactory.getLogger(SuffixTreeUnitTest.class);
private static SuffixTree suffixTree;
@BeforeClass
public static void setUp() {
suffixTree = new SuffixTree("havanabanana");
printTree();
}
@Test
public void givenSuffixTree_whenSearchingForA_thenReturn6Matches() {
List<String> matches = suffixTree.searchText("a");
matches.stream()
.forEach(m -> LOGGER.info(m));
Assert.assertArrayEquals(new String[] { "h[a]vanabanana", "hav[a]nabanana", "havan[a]banana", "havanab[a]nana", "havanaban[a]na", "havanabanan[a]" }, matches.toArray());
}
@Test
public void givenSuffixTree_whenSearchingForNab_thenReturn1Match() {
List<String> matches = suffixTree.searchText("nab");
matches.stream()
.forEach(m -> LOGGER.info(m));
Assert.assertArrayEquals(new String[] { "hava[nab]anana" }, matches.toArray());
}
@Test
public void givenSuffixTree_whenSearchingForNag_thenReturnNoMatches() {
List<String> matches = suffixTree.searchText("nag");
matches.stream()
.forEach(m -> LOGGER.info(m));
Assert.assertArrayEquals(new String[] {}, matches.toArray());
}
@Test
public void givenSuffixTree_whenSearchingForBanana_thenReturn2Matches() {
List<String> matches = suffixTree.searchText("ana");
matches.stream()
.forEach(m -> LOGGER.info(m));
Assert.assertArrayEquals(new String[] { "hav[ana]banana", "havanab[ana]na", "havanaban[ana]" }, matches.toArray());
}
@Test
public void givenSuffixTree_whenSearchingForNa_thenReturn4Matches() {
List<String> matches = suffixTree.searchText("na");
matches.stream()
.forEach(m -> LOGGER.info(m));
Assert.assertArrayEquals(new String[] { "hava[na]banana", "havanaba[na]na", "havanabana[na]" }, matches.toArray());
}
@Test
public void givenSuffixTree_whenSearchingForX_thenReturnNoMatches() {
List<String> matches = suffixTree.searchText("x");
matches.stream()
.forEach(m -> LOGGER.info(m));
Assert.assertArrayEquals(new String[] {}, matches.toArray());
}
private static void printTree() {
suffixTree.printTree();
LOGGER.info("\n" + suffixTree.printTree());
LOGGER.info("==============================================");
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.java14.patternmatchingforinstanceof;
public class PatternMatchingForInstanceOf {
public void performAnimalOperations(Animal animal) {
if (animal instanceof Cat cat) {
cat.meow();
} else if(animal instanceof Dog dog) {
dog.woof();
}
}
abstract class Animal {
}
final class Cat extends Animal {
void meow() {
}
}
final class Dog extends Animal {
void woof() {
}
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.java14.patternmatchingforinstanceof;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.Test;
import com.baeldung.java14.patternmatchingforinstanceof.PatternMatchingForInstanceOf.Cat;
import com.baeldung.java14.patternmatchingforinstanceof.PatternMatchingForInstanceOf.Dog;
class PatternMatchingForInstanceOfUnitTest {
@Test
void givenAnAnimal_whenTypeIsCat_ThenCatGoesMeow() {
Cat animal = mock(Cat.class);
PatternMatchingForInstanceOf instanceOf = new PatternMatchingForInstanceOf();
instanceOf.performAnimalOperations(animal);
verify(animal).meow();
}
@Test
void givenAnAnimal_whenTypeIsDog_ThenDogGoesWoof() {
Dog animal = mock(Dog.class);
PatternMatchingForInstanceOf instanceOf = new PatternMatchingForInstanceOf();
instanceOf.performAnimalOperations(animal);
verify(animal).woof();
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.suppressed;
public class ExceptionalResource implements AutoCloseable {
public void processSomething() {
throw new IllegalArgumentException("Thrown from processSomething()");
}
@Override
public void close() throws Exception {
throw new NullPointerException("Thrown from close()");
}
}

View File

@ -0,0 +1,44 @@
package com.baeldung.suppressed;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class SuppressedExceptionsDemo {
public static void demoSuppressedException(String filePath) throws IOException {
FileInputStream fileIn = null;
try {
fileIn = new FileInputStream(filePath);
} catch (FileNotFoundException e) {
throw new IOException(e);
} finally {
fileIn.close();
}
}
public static void demoAddSuppressedException(String filePath) throws IOException {
Throwable firstException = null;
FileInputStream fileIn = null;
try {
fileIn = new FileInputStream(filePath);
} catch (IOException e) {
firstException = e;
} finally {
try {
fileIn.close();
} catch (NullPointerException npe) {
if (firstException != null) {
npe.addSuppressed(firstException);
}
throw npe;
}
}
}
public static void demoExceptionalResource() throws Exception {
try (ExceptionalResource exceptionalResource = new ExceptionalResource()) {
exceptionalResource.processSomething();
}
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.suppressed;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.instanceOf;
public class SuppressedExceptionsUnitTest {
@Test(expected = NullPointerException.class)
public void givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException() throws IOException {
SuppressedExceptionsDemo.demoSuppressedException("/non-existent-path/non-existent-file.txt");
}
@Test
public void givenNonExistentFileName_whenAttemptFileOpenStoreSuppressed_thenSuppressedExceptionAvailable() {
try {
SuppressedExceptionsDemo.demoAddSuppressedException("/non-existent-path/non-existent-file.txt");
} catch (Exception e) {
assertThat(e, instanceOf(NullPointerException.class));
assertEquals(1, e.getSuppressed().length);
assertThat(e.getSuppressed()[0], instanceOf(FileNotFoundException.class));
}
}
@Test
public void whenUsingExceptionalResource_thenSuppressedExceptionAvailable() {
try {
SuppressedExceptionsDemo.demoExceptionalResource();
} catch (Exception e) {
assertThat(e, instanceOf(IllegalArgumentException.class));
assertEquals("Thrown from processSomething()", e.getMessage());
assertEquals(1, e.getSuppressed().length);
assertThat(e.getSuppressed()[0], instanceOf(NullPointerException.class));
assertEquals("Thrown from close()", e.getSuppressed()[0].getMessage());
}
}
}

1
ddd-modules/README.md Normal file
View File

@ -0,0 +1 @@
## Relevant Articles

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dddmodules.infrastructure</groupId>
<artifactId>infrastructure</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.dddmodules</groupId>
<artifactId>dddmodules</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.baeldung.dddmodules.shippingcontext</groupId>
<artifactId>shippingcontext</artifactId>
<version>${appmodules.version}</version>
</dependency>
<dependency>
<groupId>com.baeldung.dddmodules.ordercontext</groupId>
<artifactId>ordercontext</artifactId>
<version>${appmodules.version}</version>
</dependency>
<dependency>
<groupId>com.baeldung.dddmodules.sharedkernel</groupId>
<artifactId>sharedkernel</artifactId>
<version>${appmodules.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<source.version>9</source.version>
<target.version>9</target.version>
</properties>
</project>

View File

@ -0,0 +1,79 @@
package com.baeldung.dddmodules.infrastructure.db;
import com.baeldung.dddmodules.ordercontext.model.CustomerOrder;
import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository;
import com.baeldung.dddmodules.shippingcontext.model.PackageItem;
import com.baeldung.dddmodules.shippingcontext.model.ShippableOrder;
import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
public class InMemoryOrderStore implements CustomerOrderRepository, ShippingOrderRepository {
private Map<Integer, PersistenceOrder> ordersDb = new HashMap<>();
private volatile static InMemoryOrderStore instance = new InMemoryOrderStore();
@Override
public void saveCustomerOrder(CustomerOrder order) {
this.ordersDb.put(order.getOrderId(), new PersistenceOrder(order.getOrderId(),
order.getPaymentMethod(),
order.getAddress(),
order
.getOrderItems()
.stream()
.map(orderItem ->
new PersistenceOrder.OrderItem(orderItem.getProductId(),
orderItem.getQuantity(),
orderItem.getUnitWeight(),
orderItem.getUnitPrice()))
.collect(Collectors.toList())
));
}
@Override
public Optional<ShippableOrder> findShippableOrder(int orderId) {
if (!this.ordersDb.containsKey(orderId)) return Optional.empty();
PersistenceOrder orderRecord = this.ordersDb.get(orderId);
return Optional.of(
new ShippableOrder(orderRecord.orderId, orderRecord.orderItems
.stream().map(orderItem -> new PackageItem(orderItem.productId,
orderItem.itemWeight,
orderItem.quantity * orderItem.unitPrice)
).collect(Collectors.toList())));
}
public static InMemoryOrderStore provider() {
return instance;
}
public static class PersistenceOrder {
public int orderId;
public String paymentMethod;
public String address;
public List<OrderItem> orderItems;
public PersistenceOrder(int orderId, String paymentMethod, String address, List<OrderItem> orderItems) {
this.orderId = orderId;
this.paymentMethod = paymentMethod;
this.address = address;
this.orderItems = orderItems;
}
public static class OrderItem {
public int productId;
public float unitPrice;
public float itemWeight;
public int quantity;
public OrderItem(int productId, int quantity, float unitWeight, float unitPrice) {
this.itemWeight = unitWeight;
this.quantity = quantity;
this.unitPrice = unitPrice;
this.productId = productId;
}
}
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.dddmodules.infrastructure.events;
import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent;
import com.baeldung.dddmodules.sharedkernel.events.EventBus;
import com.baeldung.dddmodules.sharedkernel.events.EventSubscriber;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
public class SimpleEventBus implements EventBus {
private final Map<String, Set<EventSubscriber>> subscribers = new ConcurrentHashMap<>();
@Override
public <E extends ApplicationEvent> void publish(E event) {
if (subscribers.containsKey(event.getType())) {
subscribers.get(event.getType())
.forEach(subscriber -> subscriber.onEvent(event));
}
}
@Override
public <E extends ApplicationEvent> void subscribe(String eventType, EventSubscriber subscriber) {
Set<EventSubscriber> eventSubscribers = subscribers.get(eventType);
if (eventSubscribers == null) {
eventSubscribers = new CopyOnWriteArraySet<>();
subscribers.put(eventType, eventSubscribers);
}
eventSubscribers.add(subscriber);
}
@Override
public <E extends ApplicationEvent> void unsubscribe(String eventType, EventSubscriber subscriber) {
if (subscribers.containsKey(eventType)) {
subscribers.get(eventType).remove(subscriber);
}
}
}

View File

@ -0,0 +1,11 @@
module com.baeldung.dddmodules.infrastructure {
requires transitive com.baeldung.dddmodules.sharedkernel;
requires transitive com.baeldung.dddmodules.ordercontext;
requires transitive com.baeldung.dddmodules.shippingcontext;
provides com.baeldung.dddmodules.sharedkernel.events.EventBus
with com.baeldung.dddmodules.infrastructure.events.SimpleEventBus;
provides com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository
with com.baeldung.dddmodules.infrastructure.db.InMemoryOrderStore;
provides com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository
with com.baeldung.dddmodules.infrastructure.db.InMemoryOrderStore;
}

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dddmodules.mainapp</groupId>
<artifactId>mainapp</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.dddmodules</groupId>
<artifactId>dddmodules</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.baeldung.dddmodules.infrastructure</groupId>
<artifactId>infrastructure</artifactId>
<version>${appmodules.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<enableAssertions>true</enableAssertions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler.plugin.version}</version>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<source.version>9</source.version>
<target.version>9</target.version>
</properties>
</project>

View File

@ -0,0 +1,54 @@
package com.baeldung.dddmodules.mainapp;
import com.baeldung.dddmodules.ordercontext.model.CustomerOrder;
import com.baeldung.dddmodules.ordercontext.model.OrderItem;
import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository;
import com.baeldung.dddmodules.ordercontext.service.OrderService;
import com.baeldung.dddmodules.sharedkernel.events.EventBus;
import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository;
import com.baeldung.dddmodules.shippingcontext.service.ShippingService;
import java.util.*;
public class Application {
public static void main(String args[]) {
Map<Class<?>, Object> container = createContainer();
OrderService orderService = (OrderService) container.get(OrderService.class);
ShippingService shippingService = (ShippingService) container.get(ShippingService.class);
shippingService.listenToOrderEvents();
CustomerOrder customerOrder = new CustomerOrder();
int orderId = 1;
customerOrder.setOrderId(orderId);
List<OrderItem> orderItems = new ArrayList<OrderItem>();
orderItems.add(new OrderItem(1, 2, 3, 1));
orderItems.add(new OrderItem(2, 1, 1, 1));
orderItems.add(new OrderItem(3, 4, 11, 21));
customerOrder.setOrderItems(orderItems);
customerOrder.setPaymentMethod("PayPal");
customerOrder.setAddress("Full address here");
orderService.placeOrder(customerOrder);
if (orderId == shippingService.getParcelByOrderId(orderId).get().getOrderId()) {
System.out.println("Order has been processed and shipped successfully");
}
}
public static Map<Class<?>, Object> createContainer() {
EventBus eventBus = ServiceLoader.load(EventBus.class).findFirst().get();
CustomerOrderRepository customerOrderRepository = ServiceLoader.load(CustomerOrderRepository.class).findFirst().get();
ShippingOrderRepository shippingOrderRepository = ServiceLoader.load(ShippingOrderRepository.class).findFirst().get();
ShippingService shippingService = ServiceLoader.load(ShippingService.class).findFirst().get();
shippingService.setEventBus(eventBus);
shippingService.setOrderRepository(shippingOrderRepository);
OrderService orderService = ServiceLoader.load(OrderService.class).findFirst().get();
orderService.setEventBus(eventBus);
orderService.setOrderRepository(customerOrderRepository);
HashMap<Class<?>, Object> container = new HashMap<>();
container.put(OrderService.class, orderService);
container.put(ShippingService.class, shippingService);
return container;
}
}

View File

@ -0,0 +1,8 @@
module com.baeldung.dddmodules.mainapp {
uses com.baeldung.dddmodules.sharedkernel.events.EventBus;
uses com.baeldung.dddmodules.ordercontext.service.OrderService;
uses com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository;
uses com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository;
uses com.baeldung.dddmodules.shippingcontext.service.ShippingService;
requires transitive com.baeldung.dddmodules.infrastructure;
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dddmodules.ordercontext</groupId>
<artifactId>ordercontext</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.dddmodules</groupId>
<artifactId>dddmodules</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.baeldung.dddmodules.sharedkernel</groupId>
<artifactId>sharedkernel</artifactId>
<version>${appmodules.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<source.version>9</source.version>
<target.version>9</target.version>
<entitymodule.version>1.0</entitymodule.version>
<daomodule.version>1.0</daomodule.version>
</properties>
</project>

View File

@ -0,0 +1,51 @@
package com.baeldung.dddmodules.ordercontext.model;
import java.util.List;
public class CustomerOrder {
private int orderId;
private String paymentMethod;
private String address;
private List<OrderItem> orderItems;
public CustomerOrder() {
}
public float calculateTotalPrice() {
return orderItems.stream().map(OrderItem::getTotalPrice)
.reduce(0F, Float::sum);
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public int getOrderId() {
return orderId;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.dddmodules.ordercontext.model;
public class OrderItem {
private int productId;
private int quantity;
private float unitPrice;
private float unitWeight;
public OrderItem(int productId, int quantity, float unitPrice, float unitWeight) {
this.productId = productId;
this.quantity = quantity;
this.unitPrice = unitPrice;
this.unitWeight = unitWeight;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public float getTotalPrice() {
return this.quantity * this.unitPrice;
}
public void setUnitPrice(float unitPrice) {
this.unitPrice = unitPrice;
}
public float getUnitWeight() {
return unitWeight;
}
public float getUnitPrice() {
return unitPrice;
}
public void setUnitWeight(float unitWeight) {
this.unitWeight = unitWeight;
}
}

View File

@ -0,0 +1,7 @@
package com.baeldung.dddmodules.ordercontext.repository;
import com.baeldung.dddmodules.ordercontext.model.CustomerOrder;
public interface CustomerOrderRepository {
void saveCustomerOrder(CustomerOrder order);
}

View File

@ -0,0 +1,44 @@
package com.baeldung.dddmodules.ordercontext.service;
import com.baeldung.dddmodules.ordercontext.model.CustomerOrder;
import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository;
import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent;
import com.baeldung.dddmodules.sharedkernel.events.EventBus;
import java.util.HashMap;
import java.util.Map;
public class CustomerOrderService implements OrderService {
public static final String EVENT_ORDER_READY_FOR_SHIPMENT = "OrderReadyForShipmentEvent";
private CustomerOrderRepository orderRepository;
private EventBus eventBus;
@Override
public void placeOrder(CustomerOrder order) {
this.orderRepository.saveCustomerOrder(order);
Map<String, String> payload = new HashMap<>();
payload.put("order_id", String.valueOf(order.getOrderId()));
ApplicationEvent event = new ApplicationEvent(payload) {
@Override
public String getType() {
return EVENT_ORDER_READY_FOR_SHIPMENT;
}
};
this.eventBus.publish(event);
}
@Override
public EventBus getEventBus() {
return eventBus;
}
public void setOrderRepository(CustomerOrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public void setEventBus(EventBus eventBus) {
this.eventBus = eventBus;
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.dddmodules.ordercontext.service;
import com.baeldung.dddmodules.ordercontext.model.CustomerOrder;
import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository;
import com.baeldung.dddmodules.sharedkernel.service.ApplicationService;
public interface OrderService extends ApplicationService {
void placeOrder(CustomerOrder order);
void setOrderRepository(CustomerOrderRepository orderRepository);
}

View File

@ -0,0 +1,8 @@
module com.baeldung.dddmodules.ordercontext {
requires com.baeldung.dddmodules.sharedkernel;
exports com.baeldung.dddmodules.ordercontext.service;
exports com.baeldung.dddmodules.ordercontext.model;
exports com.baeldung.dddmodules.ordercontext.repository;
provides com.baeldung.dddmodules.ordercontext.service.OrderService
with com.baeldung.dddmodules.ordercontext.service.CustomerOrderService;
}

68
ddd-modules/pom.xml Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dddmodules</groupId>
<artifactId>dddmodules</artifactId>
<version>1.0</version>
<name>ddd-modules</name>
<packaging>pom</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modules>
<module>sharedkernel</module>
<module>infrastructure</module>
<module>shippingcontext</module>
<module>ordercontext</module>
<module>mainapp</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler.plugin.version}</version>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<properties>
<compiler.plugin.version>3.8.1</compiler.plugin.version>
<source.version>9</source.version>
<target.version>9</target.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<assertj-core.version>3.12.2</assertj-core.version>
<appmodules.version>1.0</appmodules.version>
</properties>
</project>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dddmodules.sharedkernel</groupId>
<artifactId>sharedkernel</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.dddmodules</groupId>
<artifactId>dddmodules</artifactId>
<version>1.0</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<source.version>9</source.version>
<target.version>9</target.version>
</properties>
</project>

View File

@ -0,0 +1,21 @@
package com.baeldung.dddmodules.sharedkernel.events;
import java.util.Map;
public abstract class ApplicationEvent {
protected Map<String, String> payload;
public abstract String getType();
public String getPayloadValue(String key) {
if (this.payload.containsKey(key)) {
return this.payload.get(key);
}
return "";
}
public ApplicationEvent(Map<String, String> payload) {
this.payload = payload;
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.dddmodules.sharedkernel.events;
public interface EventBus {
<E extends ApplicationEvent> void publish(E event);
<E extends ApplicationEvent> void subscribe(String eventType, EventSubscriber subscriber);
<E extends ApplicationEvent> void unsubscribe(String eventType, EventSubscriber subscriber);
}

View File

@ -0,0 +1,5 @@
package com.baeldung.dddmodules.sharedkernel.events;
public interface EventSubscriber {
<E extends ApplicationEvent> void onEvent(E event);
}

View File

@ -0,0 +1,33 @@
package com.baeldung.dddmodules.sharedkernel.service;
import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent;
import com.baeldung.dddmodules.sharedkernel.events.EventBus;
import com.baeldung.dddmodules.sharedkernel.events.EventSubscriber;
public interface ApplicationService {
default <E extends ApplicationEvent> void publishEvent(E event) {
EventBus eventBus = getEventBus();
if (eventBus != null) {
eventBus.publish(event);
}
}
default <E extends ApplicationEvent> void subscribe(String eventType, EventSubscriber subscriber) {
EventBus eventBus = getEventBus();
if (eventBus != null) {
eventBus.subscribe(eventType, subscriber);
}
}
default <E extends ApplicationEvent> void unsubscribe(String eventType, EventSubscriber subscriber) {
EventBus eventBus = getEventBus();
if (eventBus != null) {
eventBus.unsubscribe(eventType, subscriber);
}
}
EventBus getEventBus();
void setEventBus(EventBus eventBus);
}

View File

@ -0,0 +1,4 @@
module com.baeldung.dddmodules.sharedkernel {
exports com.baeldung.dddmodules.sharedkernel.events;
exports com.baeldung.dddmodules.sharedkernel.service;
}

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dddmodules.shippingcontext</groupId>
<artifactId>shippingcontext</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.dddmodules</groupId>
<artifactId>dddmodules</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.baeldung.dddmodules.sharedkernel</groupId>
<artifactId>sharedkernel</artifactId>
<version>${appmodules.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<source.version>9</source.version>
<target.version>9</target.version>
</properties>
</project>

View File

@ -0,0 +1,37 @@
package com.baeldung.dddmodules.shippingcontext.model;
public class PackageItem {
private int productId;
private float weight;
private float estimatedValue;
public PackageItem(int productId, float weight, float estimatedValue) {
this.productId = productId;
this.weight = weight;
this.estimatedValue = estimatedValue;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
public float getEstimatedValue() {
return estimatedValue;
}
public void setEstimatedValue(float estimatedValue) {
this.estimatedValue = estimatedValue;
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung.dddmodules.shippingcontext.model;
import java.util.List;
public class Parcel {
private int orderId;
private String address;
private String trackingId;
private List<PackageItem> packageItems;
public Parcel(int orderId, String address, List<PackageItem> packageItems) {
this.orderId = orderId;
this.address = address;
this.packageItems = packageItems;
}
public float calculateTotalWeight() {
return packageItems.stream().map(PackageItem::getWeight)
.reduce(0F, Float::sum);
}
public boolean isTaxable() {
return calculateEstimatedValue() > 100;
}
public float calculateEstimatedValue() {
return packageItems.stream().map(PackageItem::getWeight)
.reduce(0F, Float::sum);
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getTrackingId() {
return trackingId;
}
public void setTrackingId(String trackingId) {
this.trackingId = trackingId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.dddmodules.shippingcontext.model;
import java.util.List;
public class ShippableOrder {
private int orderId;
private String address;
private List<PackageItem> packageItems;
public ShippableOrder(int orderId, List<PackageItem> packageItems) {
this.orderId = orderId;
this.packageItems = packageItems;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public List<PackageItem> getPackageItems() {
return packageItems;
}
public void setPackageItems(List<PackageItem> packageItems) {
this.packageItems = packageItems;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.dddmodules.shippingcontext.repository;
import com.baeldung.dddmodules.shippingcontext.model.ShippableOrder;
import java.util.Optional;
public interface ShippingOrderRepository {
Optional<ShippableOrder> findShippableOrder(int orderId);
}

View File

@ -0,0 +1,63 @@
package com.baeldung.dddmodules.shippingcontext.service;
import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent;
import com.baeldung.dddmodules.sharedkernel.events.EventBus;
import com.baeldung.dddmodules.sharedkernel.events.EventSubscriber;
import com.baeldung.dddmodules.shippingcontext.model.Parcel;
import com.baeldung.dddmodules.shippingcontext.model.ShippableOrder;
import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class ParcelShippingService implements ShippingService {
public static final String EVENT_ORDER_READY_FOR_SHIPMENT = "OrderReadyForShipmentEvent";
private ShippingOrderRepository orderRepository;
private EventBus eventBus;
private Map<Integer, Parcel> shippedParcels = new HashMap<>();
@Override
public void shipOrder(int orderId) {
Optional<ShippableOrder> order = this.orderRepository.findShippableOrder(orderId);
order.ifPresent(completedOrder -> {
Parcel parcel = new Parcel(completedOrder.getOrderId(), completedOrder.getAddress(), completedOrder.getPackageItems());
if (parcel.isTaxable()) {
// Calculate additional taxes
}
// Ship parcel
this.shippedParcels.put(completedOrder.getOrderId(), parcel);
});
}
@Override
public void listenToOrderEvents() {
this.eventBus.subscribe(EVENT_ORDER_READY_FOR_SHIPMENT, new EventSubscriber() {
@Override
public <E extends ApplicationEvent> void onEvent(E event) {
shipOrder(Integer.parseInt(event.getPayloadValue("order_id")));
}
});
}
@Override
public Optional<Parcel> getParcelByOrderId(int orderId) {
return Optional.ofNullable(this.shippedParcels.get(orderId));
}
public void setOrderRepository(ShippingOrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public EventBus getEventBus() {
return eventBus;
}
@Override
public void setEventBus(EventBus eventBus) {
this.eventBus = eventBus;
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.dddmodules.shippingcontext.service;
import com.baeldung.dddmodules.sharedkernel.service.ApplicationService;
import com.baeldung.dddmodules.shippingcontext.model.Parcel;
import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository;
import java.util.Optional;
public interface ShippingService extends ApplicationService {
void shipOrder(int orderId);
void listenToOrderEvents();
Optional<Parcel> getParcelByOrderId(int orderId);
void setOrderRepository(ShippingOrderRepository orderRepository);
}

View File

@ -0,0 +1,8 @@
module com.baeldung.dddmodules.shippingcontext {
requires com.baeldung.dddmodules.sharedkernel;
exports com.baeldung.dddmodules.shippingcontext.service;
exports com.baeldung.dddmodules.shippingcontext.model;
exports com.baeldung.dddmodules.shippingcontext.repository;
provides com.baeldung.dddmodules.shippingcontext.service.ShippingService
with com.baeldung.dddmodules.shippingcontext.service.ParcelShippingService;
}

View File

@ -0,0 +1,41 @@
repositories {
mavenCentral()
}
apply plugin: 'java'
apply plugin: 'maven'
group = 'com.baeldung'
// by default, pom's artifactId is taken from the directory name
version = '0.0.1-SNAPSHOT'
dependencies {
compile('org.slf4j:slf4j-api')
testCompile('junit:junit')
}
install {
repositories {
mavenInstaller {
pom.version = '0.0.1-maven-SNAPSHOT'
pom.groupId = 'com.baeldung.sample'
pom.artifactId = 'gradle-maven-converter'
pom.project {
inceptionYear '2020'
licenses {
license {
name 'My License'
url 'http://www.mycompany.com/licenses/license.txt'
distribution 'repo'
}
}
}
pom.whenConfigured {pom ->
pom.dependencies.find {dep -> dep.groupId == 'junit' && dep.artifactId == 'junit' }.optional = true
}
pom.writeTo("${mavenPomDir}/${project.group}/${project.name}/pom.xml")
}
}
}

View File

@ -1,15 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Remote Debugger" type="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" />
<option name="HOST" value="localhost" />
<option name="PORT" value="5005" />
<option name="AUTO_RESTART" value="false" />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="5005" />
<option name="LOCAL" value="false" />
</RunnerSettings>
<method v="2" />
</configuration>
</component>

View File

@ -1,2 +0,0 @@
If you have not previously done so, please fill out and
submit the https://cla.pivotal.io/sign/spring[Contributor License Agreement].

View File

@ -1,16 +0,0 @@
All code in this repository is:
=======================================================================
Copyright (c) 2013 GoPivotal, Inc. All Rights Reserved
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1 +0,0 @@
Except where otherwise noted, this work is licensed under https://creativecommons.org/licenses/by-nd/3.0/

View File

@ -1,3 +0,0 @@
### Relevant Articles:
- [Remote Debugging with IntelliJ IDEA](https://www.baeldung.com/intellij-remote-debugging)

View File

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>gs-scheduling-tasks</artifactId>
<version>0.1.0</version>
<name>gs-scheduling-tasks</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<properties>
<java.version>1.8</java.version>
<awaitility.version>3.1.2</awaitility.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,38 +0,0 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hello;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("The time is now {}", dateFormat.format(new Date()));
}
}

View File

@ -11,3 +11,4 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
- [Parsing Command-Line Parameters with JCommander](https://www.baeldung.com/jcommander-parsing-command-line-parameters)
- [Guide to the Cactoos Library](https://www.baeldung.com/java-cactoos)
- [Parsing Command-Line Parameters with Airline](https://www.baeldung.com/java-airline)
- [Introduction to cache2k](https://www.baeldung.com/java-cache2k)

View File

@ -53,24 +53,6 @@
</dependency>
</dependencies>
</profile>
<profile>
<id>mac-profile</id>
<activation>
<activeByDefault>false</activeByDefault>
<file>
<exists>${java.home}/../Classes/classes.jar</exists>
</file>
</activation>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${java.home}/../Classes/classes.jar</systemPath>
</dependency>
</dependencies>
</profile>
</profiles>
<properties>

View File

@ -23,6 +23,16 @@
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>

View File

@ -1,14 +1,13 @@
package hello;
package com.baeldung.storedprocedure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application {
public class StoredProcedureApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class);
SpringApplication.run(StoredProcedureApplication.class, args);
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.storedprocedure.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.storedprocedure.entity.Car;
import com.baeldung.storedprocedure.service.CarService;
@RestController
public class CarController {
@Autowired
private CarService carService;
@GetMapping(path = "/modelcount")
public long getTotalCarsByModel(@RequestParam("model") String model) {
return carService.getTotalCarsByModel(model);
}
@GetMapping(path = "/modelcountP")
public long getTotalCarsByModelProcedureName(@RequestParam("model") String model) {
return carService.getTotalCarsByModelProcedureName(model);
}
@GetMapping(path = "/modelcountV")
public long getTotalCarsByModelVaue(@RequestParam("model") String model) {
return carService.getTotalCarsByModelValue(model);
}
@GetMapping(path = "/modelcountEx")
public long getTotalCarsByModelExplicit(@RequestParam("model") String model) {
return carService.getTotalCarsByModelExplicit(model);
}
@GetMapping(path = "/modelcountEn")
public long getTotalCarsByModelEntity(@RequestParam("model") String model) {
return carService.getTotalCarsByModelEntity(model);
}
@GetMapping(path = "/carsafteryear")
public List<Car> findCarsAfterYear(@RequestParam("year") Integer year) {
return carService.findCarsAfterYear(year);
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.storedprocedure.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.StoredProcedureParameter;
import javax.persistence.ParameterMode;
@Entity
@NamedStoredProcedureQuery(name = "Car.getTotalCardsbyModelEntity", procedureName = "GET_TOTAL_CARS_BY_MODEL", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "model_in", type = String.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "count_out", type = Integer.class) })
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private long id;
@Column
private String model;
@Column
private Integer year;
public long getId() {
return id;
}
public String getModel() {
return model;
}
public Integer getYear() {
return year;
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.storedprocedure.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.baeldung.storedprocedure.entity.Car;
@Repository
public interface CarRepository extends JpaRepository<Car, Integer> {
@Procedure
int GET_TOTAL_CARS_BY_MODEL(String model);
@Procedure("GET_TOTAL_CARS_BY_MODEL")
int getTotalCarsByModel(String model);
@Procedure(procedureName = "GET_TOTAL_CARS_BY_MODEL")
int getTotalCarsByModelProcedureName(String model);
@Procedure(value = "GET_TOTAL_CARS_BY_MODEL")
int getTotalCarsByModelValue(String model);
@Procedure(name = "Car.getTotalCardsbyModelEntity")
int getTotalCarsByModelEntiy(@Param("model_in") String model);
@Query(value = "CALL FIND_CARS_AFTER_YEAR(:year_in);", nativeQuery = true)
List<Car> findCarsAfterYear(@Param("year_in") Integer year_in);
}

View File

@ -0,0 +1,39 @@
package com.baeldung.storedprocedure.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baeldung.storedprocedure.entity.Car;
import com.baeldung.storedprocedure.repository.CarRepository;
@Service
public class CarService {
@Autowired
private CarRepository carRepository;
public int getTotalCarsByModel(String model) {
return carRepository.getTotalCarsByModel(model);
}
public int getTotalCarsByModelProcedureName(String model) {
return carRepository.getTotalCarsByModelProcedureName(model);
}
public int getTotalCarsByModelValue(String model) {
return carRepository.getTotalCarsByModelValue(model);
}
public int getTotalCarsByModelExplicit(String model) {
return carRepository.GET_TOTAL_CARS_BY_MODEL(model);
}
public int getTotalCarsByModelEntity(String model) {
return carRepository.getTotalCarsByModelEntiy(model);
}
public List<Car> findCarsAfterYear(Integer year) {
return carRepository.findCarsAfterYear(year);
}
}

View File

@ -1 +1,5 @@
spring.jpa.show-sql=true
spring.jpa.show-sql=true
#MySql
spring.datasource.url=jdbc:mysql://localhost:3306/baeldung
spring.datasource.username=baeldung
spring.datasource.password=baeldung

View File

@ -0,0 +1,27 @@
DROP TABLE IF EXISTS car;
CREATE TABLE car (id int(10) NOT NULL AUTO_INCREMENT,
model varchar(50) NOT NULL,
year int(4) NOT NULL,
PRIMARY KEY (id));
INSERT INTO car (model, year) VALUES ('BMW', 2000);
INSERT INTO car (model, year) VALUES ('BENZ', 2010);
INSERT INTO car (model, year) VALUES ('PORCHE', 2005);
INSERT INTO car (model, year) VALUES ('PORCHE', 2004);
DELIMITER $$
DROP PROCEDURE IF EXISTS FIND_CARS_AFTER_YEAR$$
CREATE PROCEDURE FIND_CARS_AFTER_YEAR(IN year_in INT)
BEGIN
SELECT * FROM car WHERE year >= year_in ORDER BY year;
END$$
DROP PROCEDURE IF EXISTS GET_TOTAL_CARS_BY_MODEL$$
CREATE PROCEDURE GET_TOTAL_CARS_BY_MODEL(IN model_in VARCHAR(50), OUT count_out INT)
BEGIN
SELECT COUNT(*) into count_out from car WHERE model = model_in;
END$$
DELIMITER ;

View File

@ -408,6 +408,7 @@
<module>dagger</module>
<module>data-structures</module>
<module>ddd</module>
<!-- <module>ddd-modules</module>--> <!-- we haven't upgraded to Java 9 -->
<module>deeplearning4j</module>
<module>disruptor</module>
<module>dozer</module>
@ -640,7 +641,7 @@
<module>spring-bom</module>
<module>spring-boot-modules</module>
<module>spring-boot-rest</module>
<module>spring-caching</module>
<module>spring-cloud</module>
@ -728,6 +729,7 @@
<module>spring-static-resources</module>
<module>spring-swagger-codegen</module>
<module>spring-threads</module>
<module>spring-thymeleaf</module>
<module>spring-thymeleaf-2</module>
@ -918,6 +920,7 @@
<module>dagger</module>
<module>data-structures</module>
<module>ddd</module>
<!-- <module>ddd-modules</module>--> <!-- we haven't upgraded to Java 9 -->
<module>deeplearning4j</module>
<module>disruptor</module>
<module>dozer</module>
@ -1334,7 +1337,7 @@
<mockito.version>2.21.0</mockito.version>
<!-- logging -->
<org.slf4j.version>1.7.21</org.slf4j.version>
<org.slf4j.version>1.7.30</org.slf4j.version>
<logback.version>1.1.7</logback.version>
<!-- plugins -->

View File

@ -11,7 +11,7 @@
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
<relativePath>../../../parent-boot-2</relativePath>
</parent>
<dependencies>

View File

@ -12,7 +12,7 @@
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
<relativePath>../../../parent-boot-2</relativePath>
</parent>
<dependencyManagement>

View File

@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController;
public class AccountController {
@CrossOrigin("http://example.com")
@RequestMapping("/{id}")
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
return new Account(id);
}

View File

@ -0,0 +1,16 @@
package com.baeldung.cors.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}

View File

@ -132,7 +132,6 @@
<spock.version>1.2-groovy-2.4</spock.version>
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
<redis.version>0.7.2</redis.version>
<spring-boot.version>2.1.9.RELEASE</spring-boot.version>
</properties>
</project>

View File

@ -1,8 +1,10 @@
package com.baeldung.boot
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
@ -12,8 +14,9 @@ import spock.lang.Title
@Title("WebController Specification")
@Narrative("The Specification of the behaviour of the WebController. It can greet a person, change the name and reset it to 'world'")
@AutoConfigureMockMvc(secure=false)
@WebMvcTest()
@SpringBootTest
@AutoConfigureMockMvc
@EnableAutoConfiguration(exclude= SecurityAutoConfiguration.class)
class WebControllerTest extends Specification {
@Autowired

View File

@ -31,3 +31,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring Shutdown Callbacks](https://www.baeldung.com/spring-shutdown-callbacks)
- [Container Configuration in Spring Boot 2](https://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot)
- [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation)
- [The BeanDefinitionOverrideException in Spring Boot](https://www.baeldung.com/spring-boot-bean-definition-override-exception)

View File

@ -4,6 +4,8 @@ import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
@ -11,6 +13,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@ -25,6 +28,8 @@ import org.springframework.web.util.UriComponentsBuilder;
import com.baeldung.persistence.model.Foo;
import com.baeldung.persistence.service.IFooService;
import com.baeldung.web.exception.CustomException1;
import com.baeldung.web.exception.CustomException2;
import com.baeldung.web.exception.MyResourceNotFoundException;
import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent;
import com.baeldung.web.hateoas.event.ResourceCreatedEvent;
@ -36,6 +41,8 @@ import com.google.common.base.Preconditions;
@RequestMapping(value = "/foos")
public class FooController {
private static final Logger logger = LoggerFactory.getLogger(FooController.class);
@Autowired
private ApplicationEventPublisher eventPublisher;
@ -137,4 +144,10 @@ public class FooController {
public void delete(@PathVariable("id") final Long id) {
service.deleteById(id);
}
@ExceptionHandler({ CustomException1.class, CustomException2.class })
public void handleException(final Exception ex) {
final String error = "Application specific error handling";
logger.error(error, ex);
}
}

View File

@ -0,0 +1,73 @@
package com.baeldung.web.error;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
@Component
public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {
private static final Logger logger = LoggerFactory.getLogger(RestResponseStatusExceptionResolver.class);
@Override
protected ModelAndView doResolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
try {
if (ex instanceof IllegalArgumentException) {
return handleIllegalArgument(
(IllegalArgumentException) ex, request, response, handler);
}
} catch (Exception handlerException) {
logger.warn("Handling of [{}] resulted in Exception", ex.getClass().getName(), handlerException);
}
return null;
}
private ModelAndView handleIllegalArgument(IllegalArgumentException ex,
final HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
final String accept = request.getHeader(HttpHeaders.ACCEPT);
response.sendError(HttpServletResponse.SC_CONFLICT);
response.setHeader("ContentType", accept);
final ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("error", prepareErrorResponse(accept));
return modelAndView;
}
/** Prepares error object based on the provided accept type.
* @param accept The Accept header present in the request.
* @return The response to return
* @throws JsonProcessingException
*/
private String prepareErrorResponse(String accept) throws JsonProcessingException {
final Map<String, String> error = new HashMap<>();
error.put("Error", "Application specific error message");
final String response;
if(MediaType.APPLICATION_JSON_VALUE.equals(accept)) {
response = new ObjectMapper().writeValueAsString(error);
} else {
response = new XmlMapper().writeValueAsString(error);
}
return response;
}
}

View File

@ -0,0 +1,7 @@
package com.baeldung.web.exception;
public class CustomException1 extends RuntimeException {
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,7 @@
package com.baeldung.web.exception;
public class CustomException2 extends RuntimeException {
private static final long serialVersionUID = 1L;
}

View File

@ -1,5 +1,9 @@
package com.baeldung.web.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public final class MyResourceNotFoundException extends RuntimeException {
public MyResourceNotFoundException() {

View File

@ -10,8 +10,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.util.Collections;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@ -24,6 +26,7 @@ import org.springframework.test.web.servlet.MockMvc;
import com.baeldung.persistence.model.Foo;
import com.baeldung.persistence.service.IFooService;
import com.baeldung.web.controller.FooController;
import com.baeldung.web.exception.CustomException1;
import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent;
/**
@ -56,5 +59,15 @@ public class FooControllerWebLayerIntegrationTest {
.andExpect(status().isOk())
.andExpect(jsonPath("$",Matchers.hasSize(1)));
}
@Test
public void delete_forException_fromService() throws Exception {
Mockito.when(service.findAll()).thenThrow(new CustomException1());
this.mockMvc.perform(get("/foos")).andDo(h -> {
final Exception expectedException = h.getResolvedException();
Assert.assertTrue(expectedException instanceof CustomException1);
});
}
}

View File

@ -35,7 +35,7 @@
<module>spring-cloud-archaius</module>
<module>spring-cloud-functions</module>
<module>spring-cloud-vault</module>
<!-- <module>spring-cloud-security</module> --> <!-- Fixing in BAEL-10887 -->
<module>spring-cloud-security</module>
<module>spring-cloud-task</module>
<module>spring-cloud-zuul</module>
<module>spring-cloud-zuul-fallback</module>

View File

@ -1,14 +0,0 @@
package com.baeldung.ejb.spring.comparison.ejb.singleton;
import javax.ejb.Singleton;
@Singleton
public class CounterEJB implements CounterEJBRemote {
private int count = 1;
public int count() {
return count++;
}
}

View File

@ -1,8 +0,0 @@
package com.baeldung.ejb.spring.comparison.ejb.singleton;
import javax.ejb.Remote;
@Remote
public interface CounterEJBRemote {
int count();
}

View File

@ -1,12 +0,0 @@
package com.baeldung.ejb.spring.comparison.spring.singleton;
import org.springframework.stereotype.Component;
@Component
public class CounterBean {
private int count = 1;
public int count() {
return count++;
}
}

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.ejb.messagedriven;
package com.baeldung.ejbspringcomparison.ejb.messagedriven;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;

View File

@ -0,0 +1,23 @@
package com.baeldung.ejbspringcomparison.ejb.singleton;
import javax.ejb.Singleton;
@Singleton
public class CounterEJB implements CounterEJBRemote {
private int count = 1;
private String name;
public int count() {
return count++;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.ejbspringcomparison.ejb.singleton;
import javax.ejb.Remote;
@Remote
public interface CounterEJBRemote {
int count();
String getName();
void setName(String name);
}

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.ejb.stateful;
package com.baeldung.ejbspringcomparison.ejb.stateful;
import java.util.ArrayList;
import java.util.List;
@ -7,7 +7,7 @@ import javax.ejb.Stateful;
@Stateful
public class ShoppingCartEJB implements ShoppingCartEJBRemote {
private String name;
private List<String> shoppingCart;
public ShoppingCartEJB() {
@ -22,4 +22,11 @@ public class ShoppingCartEJB implements ShoppingCartEJBRemote {
return shoppingCart;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.ejb.stateful;
package com.baeldung.ejbspringcomparison.ejb.stateful;
import java.util.List;
@ -10,4 +10,8 @@ public interface ShoppingCartEJBRemote {
void addItem(String item);
List<String> getItems();
void setName(String name);
String getName();
}

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.ejb.stateless;
package com.baeldung.ejbspringcomparison.ejb.stateless;
import java.util.HashMap;
import java.util.Map;

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.ejb.stateless;
package com.baeldung.ejbspringcomparison.ejb.stateless;
import javax.ejb.Remote;

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.spring.config;
package com.baeldung.ejbspringcomparison.spring.config;
import javax.jms.ConnectionFactory;
@ -11,7 +11,7 @@ import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
@Configuration
@ComponentScan(basePackages = "com.baeldung.ejb.spring.comparison.spring")
@ComponentScan(basePackages = "com.baeldung.ejbspringcomparison.spring")
@EnableJms
public class ApplicationConfig {

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.spring.messagedriven;
package com.baeldung.ejbspringcomparison.spring.messagedriven;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.spring.messagedriven;
package com.baeldung.ejbspringcomparison.spring.messagedriven;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;

View File

@ -0,0 +1,22 @@
package com.baeldung.ejbspringcomparison.spring.singleton;
import org.springframework.stereotype.Component;
@Component
public class CounterBean {
private int count = 1;
private String name;
public int count() {
return count++;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -1,4 +1,4 @@
package com.baeldung.ejb.spring.comparison.spring.stateful;
package com.baeldung.ejbspringcomparison.spring.stateful;
import java.util.ArrayList;
import java.util.List;
@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ShoppingCartBean {
private String name;
private List<String> shoppingCart;
public ShoppingCartBean() {
@ -25,4 +26,11 @@ public class ShoppingCartBean {
return shoppingCart;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View File

@ -1,9 +1,7 @@
package com.baeldung.ejb.spring.comparison.ejb;
package com.baeldung.ejbspringcomparison.ejb;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import javax.annotation.Resource;
import javax.ejb.EJB;
@ -25,9 +23,9 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.baeldung.ejb.spring.comparison.ejb.singleton.CounterEJBRemote;
import com.baeldung.ejb.spring.comparison.ejb.stateful.ShoppingCartEJBRemote;
import com.baeldung.ejb.spring.comparison.ejb.stateless.FinderEJBRemote;
import com.baeldung.ejbspringcomparison.ejb.singleton.CounterEJBRemote;
import com.baeldung.ejbspringcomparison.ejb.stateful.ShoppingCartEJBRemote;
import com.baeldung.ejbspringcomparison.ejb.stateless.FinderEJBRemote;
public class EJBUnitTest {
@ -51,7 +49,7 @@ public class EJBUnitTest {
public static void start() throws NamingException {
ejbContainer = EJBContainer.createEJBContainer();
}
@Before
public void initializeContext() throws NamingException {
context = ejbContainer.getContext();
@ -60,42 +58,44 @@ public class EJBUnitTest {
@Test
public void givenSingletonBean_whenCounterInvoked_thenCountIsIncremented() throws NamingException {
int count = 0;
CounterEJBRemote counterEJB = (CounterEJBRemote) context.lookup("java:global/ejb-beans/CounterEJB");
CounterEJBRemote firstCounter = (CounterEJBRemote) context.lookup("java:global/ejb-beans/CounterEJB");
firstCounter.setName("first");
for (int i = 0; i < 10; i++)
count = counterEJB.count();
assertThat(count, is(not(1)));
}
@Test
public void givenSingletonBean_whenCounterInvokedAgain_thenCountIsIncremented() throws NamingException {
CounterEJBRemote counterEJB = (CounterEJBRemote) context.lookup("java:global/ejb-beans/CounterEJB");
for (int i = 0; i < 10; i++) {
count = firstCounter.count();
}
int count = 0;
for (int i = 0; i < 10; i++)
count = counterEJB.count();
assertEquals(10, count);
assertEquals("first", firstCounter.getName());
CounterEJBRemote secondCounter = (CounterEJBRemote) context.lookup("java:global/ejb-beans/CounterEJB");
int count2 = 0;
for (int i = 0; i < 10; i++) {
count2 = secondCounter.count();
}
assertEquals(20, count2);
assertEquals("first", secondCounter.getName());
assertThat(count, is(not(1)));
}
@Test
public void givenStatefulBean_whenBathingCartWithThreeItemsAdded_thenItemsSizeIsThree() throws NamingException {
ShoppingCartEJBRemote bathingCart = (ShoppingCartEJBRemote) context.lookup("java:global/ejb-beans/ShoppingCartEJB");
bathingCart.setName("bathingCart");
bathingCart.addItem("soap");
bathingCart.addItem("shampoo");
bathingCart.addItem("oil");
assertEquals(3, bathingCart.getItems()
.size());
}
assertEquals("bathingCart", bathingCart.getName());
@Test
public void givenStatefulBean_whenFruitCartWithTwoItemsAdded_thenItemsSizeIsTwo() throws NamingException {
ShoppingCartEJBRemote fruitCart = (ShoppingCartEJBRemote) context.lookup("java:global/ejb-beans/ShoppingCartEJB");
fruitCart.addItem("apples");
@ -103,6 +103,7 @@ public class EJBUnitTest {
assertEquals(2, fruitCart.getItems()
.size());
assertNull(fruitCart.getName());
}
@Test
@ -131,10 +132,7 @@ public class EJBUnitTest {
}
@AfterClass
public static void checkTotalCountAndcloseContext() throws NamingException {
CounterEJBRemote counterEJB = (CounterEJBRemote) context.lookup("java:global/ejb-beans/CounterEJB");
assertEquals(21, counterEJB.count());
public static void closeContext() throws NamingException {
context.close();
ejbContainer.close();
}

View File

@ -1,9 +1,7 @@
package com.baeldung.ejb.spring.comparison.spring;
package com.baeldung.ejbspringcomparison.spring;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import javax.naming.NamingException;
@ -15,10 +13,10 @@ import org.junit.ClassRule;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.baeldung.ejb.spring.comparison.spring.config.ApplicationConfig;
import com.baeldung.ejb.spring.comparison.spring.messagedriven.Producer;
import com.baeldung.ejb.spring.comparison.spring.singleton.CounterBean;
import com.baeldung.ejb.spring.comparison.spring.stateful.ShoppingCartBean;
import com.baeldung.ejbspringcomparison.spring.config.ApplicationConfig;
import com.baeldung.ejbspringcomparison.spring.messagedriven.Producer;
import com.baeldung.ejbspringcomparison.spring.singleton.CounterBean;
import com.baeldung.ejbspringcomparison.spring.stateful.ShoppingCartBean;
public class SpringUnitTest {
@ -46,40 +44,44 @@ public class SpringUnitTest {
@Test
public void whenCounterInvoked_thenCountIsIncremented() throws NamingException {
CounterBean counterBean = context.getBean(CounterBean.class);
CounterBean firstCounter = context.getBean(CounterBean.class);
firstCounter.setName("first");
int count = 0;
for (int i = 0; i < 10; i++)
count = counterBean.count();
for (int i = 0; i < 10; i++) {
count = firstCounter.count();
}
assertThat(count, is(not(1)));
}
assertEquals(10, count);
assertEquals("first", firstCounter.getName());
@Test
public void whenCounterInvokedAgain_thenCountIsIncremented() throws NamingException {
CounterBean counterBean = context.getBean(CounterBean.class);
CounterBean secondCounter = context.getBean(CounterBean.class);
int count = 0;
for (int i = 0; i < 10; i++)
count = counterBean.count();
int count2 = 0;
for (int i = 0; i < 10; i++) {
count2 = secondCounter.count();
}
assertEquals(20, count2);
assertEquals("first", secondCounter.getName());
assertThat(count, is(not(1)));
}
@Test
public void whenBathingCartWithThreeItemsAdded_thenItemsSizeIsThree() throws NamingException {
ShoppingCartBean bathingCart = context.getBean(ShoppingCartBean.class);
bathingCart.setName("bathingCart");
bathingCart.addItem("soap");
bathingCart.addItem("shampoo");
bathingCart.addItem("oil");
assertEquals(3, bathingCart.getItems()
.size());
}
@Test
public void whenFruitCartWithTwoItemsAdded_thenItemsSizeIsTwo() throws NamingException {
assertEquals("bathingCart", bathingCart.getName());
ShoppingCartBean fruitCart = context.getBean(ShoppingCartBean.class);
fruitCart.addItem("apples");
@ -87,6 +89,7 @@ public class SpringUnitTest {
assertEquals(2, fruitCart.getItems()
.size());
assertNull(fruitCart.getName());
}
@Test
@ -98,10 +101,7 @@ public class SpringUnitTest {
}
@AfterClass
public static void checkTotalCountAndcloseContext() throws NamingException {
CounterBean counterBean = context.getBean(CounterBean.class);
int count = counterBean.count();
assertEquals(21, count);
public static void closeContext() throws NamingException {
context.close();
}

View File

@ -36,6 +36,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!-- Spring -->
@ -194,7 +195,6 @@
<sql-maven-plugin.version>1.5</sql-maven-plugin.version>
<properties-maven-plugin.version>1.0.0</properties-maven-plugin.version>
<start-class>org.jooq.example.spring.Application</start-class>
<spring-boot.version>2.1.9.RELEASE</spring-boot.version>
</properties>
</project>

View File

@ -25,7 +25,7 @@ public class KafkaApplication {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(KafkaApplication.class, args);
MessageProducer producer = context.getBean(MessageProducer.class);
MessageListener listener = context.getBean(MessageListener.class);
/*
@ -101,15 +101,17 @@ public class KafkaApplication {
private String greetingTopicName;
public void sendMessage(String message) {
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
@Override
public void onSuccess(SendResult<String, String> result) {
System.out.println("Sent message=[" + message + "] with offset=[" + result.getRecordMetadata().offset() + "]");
System.out.println("Sent message=[" + message + "] with offset=[" + result.getRecordMetadata()
.offset() + "]");
}
@Override
public void onFailure(Throwable ex) {
System.out.println("Unable to send message=[" + message + "] due to : " + ex.getMessage());
@ -158,7 +160,7 @@ public class KafkaApplication {
latch.countDown();
}
@KafkaListener(topicPartitions = @TopicPartition(topic = "${partitioned.topic.name}", partitions = { "0", "3" }))
@KafkaListener(topicPartitions = @TopicPartition(topic = "${partitioned.topic.name}", partitions = { "0", "3" }), containerFactory = "partitionsKafkaListenerContainerFactory")
public void listenToParition(@Payload String message, @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
System.out.println("Received Message: " + message + " from partition: " + partition);
this.partitionLatch.countDown();

View File

@ -29,7 +29,7 @@ public class KafkaConsumerConfig {
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
return new DefaultKafkaConsumerFactory<>(props);
}
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(String groupId) {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory(groupId));
@ -50,12 +50,12 @@ public class KafkaConsumerConfig {
public ConcurrentKafkaListenerContainerFactory<String, String> headersKafkaListenerContainerFactory() {
return kafkaListenerContainerFactory("headers");
}
@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> partitionsKafkaListenerContainerFactory() {
return kafkaListenerContainerFactory("partitions");
}
@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> filterKafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = kafkaListenerContainerFactory("filter");

View File

@ -32,7 +32,7 @@ public class KafkaProducerConfig {
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
@Bean
public ProducerFactory<String, Greeting> greetingProducerFactory() {
Map<String, Object> configProps = new HashMap<>();
@ -41,10 +41,10 @@ public class KafkaProducerConfig {
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
return new DefaultKafkaProducerFactory<>(configProps);
}
@Bean
public KafkaTemplate<String, Greeting> greetingKafkaTemplate() {
return new KafkaTemplate<>(greetingProducerFactory());
}
}

View File

@ -12,10 +12,10 @@ import org.springframework.kafka.core.KafkaAdmin;
@Configuration
public class KafkaTopicConfig {
@Value(value = "${kafka.bootstrapAddress}")
private String bootstrapAddress;
@Value(value = "${message.topic.name}")
private String topicName;
@ -27,31 +27,31 @@ public class KafkaTopicConfig {
@Value(value = "${greeting.topic.name}")
private String greetingTopicName;
@Bean
public KafkaAdmin kafkaAdmin() {
Map<String, Object> configs = new HashMap<>();
configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
return new KafkaAdmin(configs);
}
@Bean
public NewTopic topic1() {
return new NewTopic(topicName, 1, (short) 1);
return new NewTopic(topicName, 1, (short) 1);
}
@Bean
public NewTopic topic2() {
return new NewTopic(partionedTopicName, 6, (short) 1);
return new NewTopic(partionedTopicName, 6, (short) 1);
}
@Bean
public NewTopic topic3() {
return new NewTopic(filteredTopicName, 1, (short) 1);
return new NewTopic(filteredTopicName, 1, (short) 1);
}
@Bean
public NewTopic topic4() {
return new NewTopic(greetingTopicName, 1, (short) 1);
return new NewTopic(greetingTopicName, 1, (short) 1);
}
}

Some files were not shown because too many files have changed in this diff Show More