commit
87cb200877
@ -44,18 +44,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<io.jenetics.version>3.7.0</io.jenetics.version>
|
||||
|
@ -49,18 +49,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -54,18 +54,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -74,18 +74,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
<commons-collections4.version>4.3</commons-collections4.version>
|
||||
|
@ -34,18 +34,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
<guava.version>27.0.1-jre</guava.version>
|
||||
|
@ -49,18 +49,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<tradukisto.version>1.0.1</tradukisto.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
|
@ -44,18 +44,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
|
@ -45,18 +45,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
|
@ -30,7 +30,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
@ -4,9 +4,9 @@
|
||||
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>
|
||||
<artifactId>aws-lambda-examples</artifactId>
|
||||
<artifactId>lambda</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>aws-lambda-examples</name>
|
||||
<name>lambda</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<artifactId>ShippingFunction</artifactId>
|
||||
<version>1.0</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>Shipping Tracker Lambda Function</name>
|
||||
<name>ShippingFunction</name>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
|
@ -53,7 +53,7 @@
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<axon.version>4.1.2</axon.version>
|
||||
<axon.version>4.4.7</axon.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -1,59 +0,0 @@
|
||||
package com.baeldung.axon.commandmodel;
|
||||
|
||||
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
||||
|
||||
import org.axonframework.commandhandling.CommandHandler;
|
||||
import org.axonframework.eventsourcing.EventSourcingHandler;
|
||||
import org.axonframework.modelling.command.AggregateIdentifier;
|
||||
import org.axonframework.spring.stereotype.Aggregate;
|
||||
|
||||
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||
import com.baeldung.axon.coreapi.exceptions.UnconfirmedOrderException;
|
||||
|
||||
@Aggregate
|
||||
public class OrderAggregate {
|
||||
|
||||
@AggregateIdentifier
|
||||
private String orderId;
|
||||
private boolean orderConfirmed;
|
||||
|
||||
@CommandHandler
|
||||
public OrderAggregate(PlaceOrderCommand command) {
|
||||
apply(new OrderPlacedEvent(command.getOrderId(), command.getProduct()));
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(ConfirmOrderCommand command) {
|
||||
apply(new OrderConfirmedEvent(orderId));
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(ShipOrderCommand command) {
|
||||
if (!orderConfirmed) {
|
||||
throw new UnconfirmedOrderException();
|
||||
}
|
||||
|
||||
apply(new OrderShippedEvent(orderId));
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(OrderPlacedEvent event) {
|
||||
this.orderId = event.getOrderId();
|
||||
this.orderConfirmed = false;
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(OrderConfirmedEvent event) {
|
||||
this.orderConfirmed = true;
|
||||
}
|
||||
|
||||
protected OrderAggregate() {
|
||||
// Required by Axon to build a default Aggregate prior to Event Sourcing
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package com.baeldung.axon.commandmodel.order;
|
||||
|
||||
import com.baeldung.axon.coreapi.commands.AddProductCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.CreateOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderCreatedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductAddedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
|
||||
import com.baeldung.axon.coreapi.exceptions.DuplicateOrderLineException;
|
||||
import com.baeldung.axon.coreapi.exceptions.OrderAlreadyConfirmedException;
|
||||
import com.baeldung.axon.coreapi.exceptions.UnconfirmedOrderException;
|
||||
import org.axonframework.commandhandling.CommandHandler;
|
||||
import org.axonframework.eventsourcing.EventSourcingHandler;
|
||||
import org.axonframework.modelling.command.AggregateIdentifier;
|
||||
import org.axonframework.modelling.command.AggregateMember;
|
||||
import org.axonframework.spring.stereotype.Aggregate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
||||
|
||||
@Aggregate
|
||||
public class OrderAggregate {
|
||||
|
||||
@AggregateIdentifier
|
||||
private String orderId;
|
||||
private boolean orderConfirmed;
|
||||
|
||||
@AggregateMember
|
||||
private Map<String, OrderLine> orderLines;
|
||||
|
||||
@CommandHandler
|
||||
public OrderAggregate(CreateOrderCommand command) {
|
||||
apply(new OrderCreatedEvent(command.getOrderId()));
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(AddProductCommand command) {
|
||||
if (orderConfirmed) {
|
||||
throw new OrderAlreadyConfirmedException(orderId);
|
||||
}
|
||||
|
||||
String productId = command.getProductId();
|
||||
if (orderLines.containsKey(productId)) {
|
||||
throw new DuplicateOrderLineException(productId);
|
||||
}
|
||||
apply(new ProductAddedEvent(orderId, productId));
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(ConfirmOrderCommand command) {
|
||||
if (orderConfirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
apply(new OrderConfirmedEvent(orderId));
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(ShipOrderCommand command) {
|
||||
if (!orderConfirmed) {
|
||||
throw new UnconfirmedOrderException();
|
||||
}
|
||||
|
||||
apply(new OrderShippedEvent(orderId));
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(OrderCreatedEvent event) {
|
||||
this.orderId = event.getOrderId();
|
||||
this.orderConfirmed = false;
|
||||
this.orderLines = new HashMap<>();
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(OrderConfirmedEvent event) {
|
||||
this.orderConfirmed = true;
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(ProductAddedEvent event) {
|
||||
String productId = event.getProductId();
|
||||
this.orderLines.put(productId, new OrderLine(productId));
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(ProductRemovedEvent event) {
|
||||
this.orderLines.remove(event.getProductId());
|
||||
}
|
||||
|
||||
protected OrderAggregate() {
|
||||
// Required by Axon to build a default Aggregate prior to Event Sourcing
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.baeldung.axon.commandmodel.order;
|
||||
|
||||
import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand;
|
||||
import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand;
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
|
||||
import com.baeldung.axon.coreapi.exceptions.OrderAlreadyConfirmedException;
|
||||
import org.axonframework.commandhandling.CommandHandler;
|
||||
import org.axonframework.eventsourcing.EventSourcingHandler;
|
||||
import org.axonframework.modelling.command.EntityId;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
||||
|
||||
public class OrderLine {
|
||||
|
||||
@EntityId
|
||||
private final String productId;
|
||||
private Integer count;
|
||||
private boolean orderConfirmed;
|
||||
|
||||
public OrderLine(String productId) {
|
||||
this.productId = productId;
|
||||
this.count = 1;
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(IncrementProductCountCommand command) {
|
||||
if (orderConfirmed) {
|
||||
throw new OrderAlreadyConfirmedException(command.getOrderId());
|
||||
}
|
||||
|
||||
apply(new ProductCountIncrementedEvent(command.getOrderId(), productId));
|
||||
}
|
||||
|
||||
@CommandHandler
|
||||
public void handle(DecrementProductCountCommand command) {
|
||||
if (orderConfirmed) {
|
||||
throw new OrderAlreadyConfirmedException(command.getOrderId());
|
||||
}
|
||||
|
||||
if (count <= 1) {
|
||||
apply(new ProductRemovedEvent(command.getOrderId(), productId));
|
||||
} else {
|
||||
apply(new ProductCountDecrementedEvent(command.getOrderId(), productId));
|
||||
}
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(ProductCountIncrementedEvent event) {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(ProductCountDecrementedEvent event) {
|
||||
this.count--;
|
||||
}
|
||||
|
||||
@EventSourcingHandler
|
||||
public void on(OrderConfirmedEvent event) {
|
||||
this.orderConfirmed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OrderLine orderLine = (OrderLine) o;
|
||||
return Objects.equals(productId, orderLine.productId) && Objects.equals(count, orderLine.count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(productId, count);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.baeldung.axon.coreapi.commands;
|
||||
|
||||
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class AddProductCommand {
|
||||
|
||||
@TargetAggregateIdentifier
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public AddProductCommand(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AddProductCommand that = (AddProductCommand) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AddProductCommand{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.axon.coreapi.commands;
|
||||
|
||||
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class CreateOrderCommand {
|
||||
|
||||
@TargetAggregateIdentifier
|
||||
private final String orderId;
|
||||
|
||||
public CreateOrderCommand(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
CreateOrderCommand that = (CreateOrderCommand) o;
|
||||
return Objects.equals(orderId, that.orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CreateOrderCommand{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.baeldung.axon.coreapi.commands;
|
||||
|
||||
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DecrementProductCountCommand {
|
||||
|
||||
@TargetAggregateIdentifier
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public DecrementProductCountCommand(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DecrementProductCountCommand that = (DecrementProductCountCommand) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DecrementProductCountCommand{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.baeldung.axon.coreapi.commands;
|
||||
|
||||
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class IncrementProductCountCommand {
|
||||
|
||||
@TargetAggregateIdentifier
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public IncrementProductCountCommand(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
IncrementProductCountCommand that = (IncrementProductCountCommand) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IncrementProductCountCommand{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package com.baeldung.axon.coreapi.commands;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||
|
||||
public class PlaceOrderCommand {
|
||||
|
||||
@TargetAggregateIdentifier
|
||||
private final String orderId;
|
||||
private final String product;
|
||||
|
||||
public PlaceOrderCommand(String orderId, String product) {
|
||||
this.orderId = orderId;
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final PlaceOrderCommand other = (PlaceOrderCommand) obj;
|
||||
return Objects.equals(this.orderId, other.orderId)
|
||||
&& Objects.equals(this.product, other.product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlaceOrderCommand{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", product='" + product + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.baeldung.axon.coreapi.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class OrderCreatedEvent {
|
||||
|
||||
private final String orderId;
|
||||
|
||||
public OrderCreatedEvent(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OrderCreatedEvent that = (OrderCreatedEvent) o;
|
||||
return Objects.equals(orderId, that.orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrderCreatedEvent{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.baeldung.axon.coreapi.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class OrderPlacedEvent {
|
||||
|
||||
private final String orderId;
|
||||
private final String product;
|
||||
|
||||
public OrderPlacedEvent(String orderId, String product) {
|
||||
this.orderId = orderId;
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final OrderPlacedEvent other = (OrderPlacedEvent) obj;
|
||||
return Objects.equals(this.orderId, other.orderId)
|
||||
&& Objects.equals(this.product, other.product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrderPlacedEvent{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", product='" + product + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.axon.coreapi.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ProductAddedEvent {
|
||||
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public ProductAddedEvent(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProductAddedEvent that = (ProductAddedEvent) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProductAddedEvent{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.axon.coreapi.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ProductCountDecrementedEvent {
|
||||
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public ProductCountDecrementedEvent(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProductCountDecrementedEvent that = (ProductCountDecrementedEvent) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProductCountDecrementedEvent{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.axon.coreapi.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ProductCountIncrementedEvent {
|
||||
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public ProductCountIncrementedEvent(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProductCountIncrementedEvent that = (ProductCountIncrementedEvent) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProductCountIncrementedEvent{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.axon.coreapi.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ProductRemovedEvent {
|
||||
|
||||
private final String orderId;
|
||||
private final String productId;
|
||||
|
||||
public ProductRemovedEvent(String orderId, String productId) {
|
||||
this.orderId = orderId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProductRemovedEvent that = (ProductRemovedEvent) o;
|
||||
return Objects.equals(orderId, that.orderId) && Objects.equals(productId, that.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProductRemovedEvent{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.baeldung.axon.coreapi.exceptions;
|
||||
|
||||
public class DuplicateOrderLineException extends IllegalStateException {
|
||||
|
||||
public DuplicateOrderLineException(String productId) {
|
||||
super("Cannot duplicate order line for product identifier [" + productId + "]");
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.baeldung.axon.coreapi.exceptions;
|
||||
|
||||
public class OrderAlreadyConfirmedException extends IllegalStateException {
|
||||
|
||||
public OrderAlreadyConfirmedException(String orderId) {
|
||||
super("Cannot perform operation because order [" + orderId + "] is already confirmed.");
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.baeldung.axon.coreapi.queries;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Order {
|
||||
|
||||
private final String orderId;
|
||||
private final Map<String, Integer> products;
|
||||
private OrderStatus orderStatus;
|
||||
|
||||
public Order(String orderId) {
|
||||
this.orderId = orderId;
|
||||
this.products = new HashMap<>();
|
||||
orderStatus = OrderStatus.CREATED;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getProducts() {
|
||||
return products;
|
||||
}
|
||||
|
||||
public OrderStatus getOrderStatus() {
|
||||
return orderStatus;
|
||||
}
|
||||
|
||||
public void addProduct(String productId) {
|
||||
products.putIfAbsent(productId, 1);
|
||||
}
|
||||
|
||||
public void incrementProductInstance(String productId) {
|
||||
products.computeIfPresent(productId, (id, count) -> ++count);
|
||||
}
|
||||
|
||||
public void decrementProductInstance(String productId) {
|
||||
products.computeIfPresent(productId, (id, count) -> --count);
|
||||
}
|
||||
|
||||
|
||||
public void removeProduct(String productId) {
|
||||
products.remove(productId);
|
||||
}
|
||||
|
||||
public void setOrderConfirmed() {
|
||||
this.orderStatus = OrderStatus.CONFIRMED;
|
||||
}
|
||||
|
||||
public void setOrderShipped() {
|
||||
this.orderStatus = OrderStatus.SHIPPED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Order that = (Order) o;
|
||||
return Objects.equals(orderId, that.orderId)
|
||||
&& Objects.equals(products, that.products)
|
||||
&& orderStatus == that.orderStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, products, orderStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", products=" + products +
|
||||
", orderStatus=" + orderStatus +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -2,6 +2,5 @@ package com.baeldung.axon.coreapi.queries;
|
||||
|
||||
public enum OrderStatus {
|
||||
|
||||
PLACED, CONFIRMED, SHIPPED
|
||||
|
||||
CREATED, CONFIRMED, SHIPPED
|
||||
}
|
||||
|
@ -1,64 +0,0 @@
|
||||
package com.baeldung.axon.coreapi.queries;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class OrderedProduct {
|
||||
|
||||
private final String orderId;
|
||||
private final String product;
|
||||
private OrderStatus orderStatus;
|
||||
|
||||
public OrderedProduct(String orderId, String product) {
|
||||
this.orderId = orderId;
|
||||
this.product = product;
|
||||
orderStatus = OrderStatus.PLACED;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public String getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public OrderStatus getOrderStatus() {
|
||||
return orderStatus;
|
||||
}
|
||||
|
||||
public void setOrderConfirmed() {
|
||||
this.orderStatus = OrderStatus.CONFIRMED;
|
||||
}
|
||||
|
||||
public void setOrderShipped() {
|
||||
this.orderStatus = OrderStatus.SHIPPED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, product, orderStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final OrderedProduct other = (OrderedProduct) obj;
|
||||
return Objects.equals(this.orderId, other.orderId)
|
||||
&& Objects.equals(this.product, other.product)
|
||||
&& Objects.equals(this.orderStatus, other.orderStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrderedProduct{" +
|
||||
"orderId='" + orderId + '\'' +
|
||||
", product='" + product + '\'' +
|
||||
", orderStatus=" + orderStatus +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,20 +1,24 @@
|
||||
package com.baeldung.axon.gui;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.baeldung.axon.coreapi.commands.AddProductCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.CreateOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand;
|
||||
import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||
import com.baeldung.axon.coreapi.queries.Order;
|
||||
import org.axonframework.commandhandling.gateway.CommandGateway;
|
||||
import org.axonframework.messaging.responsetypes.ResponseTypes;
|
||||
import org.axonframework.queryhandling.QueryGateway;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||
import com.baeldung.axon.coreapi.queries.OrderedProduct;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@RestController
|
||||
public class OrderRestEndpoint {
|
||||
@ -28,25 +32,63 @@ public class OrderRestEndpoint {
|
||||
}
|
||||
|
||||
@PostMapping("/ship-order")
|
||||
public void shipOrder() {
|
||||
public CompletableFuture<Void> shipOrder() {
|
||||
String orderId = UUID.randomUUID().toString();
|
||||
commandGateway.send(new PlaceOrderCommand(orderId, "Deluxe Chair"));
|
||||
commandGateway.send(new ConfirmOrderCommand(orderId));
|
||||
commandGateway.send(new ShipOrderCommand(orderId));
|
||||
return commandGateway.send(new CreateOrderCommand(orderId))
|
||||
.thenCompose(result -> commandGateway.send(new AddProductCommand(orderId, "Deluxe Chair")))
|
||||
.thenCompose(result -> commandGateway.send(new ConfirmOrderCommand(orderId)))
|
||||
.thenCompose(result -> commandGateway.send(new ShipOrderCommand(orderId)));
|
||||
}
|
||||
|
||||
@PostMapping("/ship-unconfirmed-order")
|
||||
public void shipUnconfirmedOrder() {
|
||||
public CompletableFuture<Void> shipUnconfirmedOrder() {
|
||||
String orderId = UUID.randomUUID().toString();
|
||||
commandGateway.send(new PlaceOrderCommand(orderId, "Deluxe Chair"));
|
||||
return commandGateway.send(new CreateOrderCommand(orderId))
|
||||
.thenCompose(result -> commandGateway.send(new AddProductCommand(orderId, "Deluxe Chair")))
|
||||
// This throws an exception, as an Order cannot be shipped if it has not been confirmed yet.
|
||||
commandGateway.send(new ShipOrderCommand(orderId));
|
||||
.thenCompose(result -> commandGateway.send(new ShipOrderCommand(orderId)));
|
||||
}
|
||||
|
||||
@PostMapping("/order")
|
||||
public CompletableFuture<String> createOrder() {
|
||||
return createOrder(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
@PostMapping("/order/{order-id}")
|
||||
public CompletableFuture<String> createOrder(@PathVariable("order-id") String orderId) {
|
||||
return commandGateway.send(new CreateOrderCommand(orderId));
|
||||
}
|
||||
|
||||
@PostMapping("/order/{order-id}/product/{product-id}")
|
||||
public CompletableFuture<Void> addProduct(@PathVariable("order-id") String orderId,
|
||||
@PathVariable("product-id") String productId) {
|
||||
return commandGateway.send(new AddProductCommand(orderId, productId));
|
||||
}
|
||||
|
||||
@PostMapping("/order/{order-id}/product/{product-id}/increment")
|
||||
public CompletableFuture<Void> incrementProduct(@PathVariable("order-id") String orderId,
|
||||
@PathVariable("product-id") String productId) {
|
||||
return commandGateway.send(new IncrementProductCountCommand(orderId, productId));
|
||||
}
|
||||
|
||||
@PostMapping("/order/{order-id}/product/{product-id}/decrement")
|
||||
public CompletableFuture<Void> decrementProduct(@PathVariable("order-id") String orderId,
|
||||
@PathVariable("product-id") String productId) {
|
||||
return commandGateway.send(new DecrementProductCountCommand(orderId, productId));
|
||||
}
|
||||
|
||||
@PostMapping("/order/{order-id}/confirm")
|
||||
public CompletableFuture<Void> confirmOrder(@PathVariable("order-id") String orderId) {
|
||||
return commandGateway.send(new ConfirmOrderCommand(orderId));
|
||||
}
|
||||
|
||||
@PostMapping("/order/{order-id}/ship")
|
||||
public CompletableFuture<Void> shipOrder(@PathVariable("order-id") String orderId) {
|
||||
return commandGateway.send(new ShipOrderCommand(orderId));
|
||||
}
|
||||
|
||||
@GetMapping("/all-orders")
|
||||
public List<OrderedProduct> findAllOrderedProducts() {
|
||||
return queryGateway.query(new FindAllOrderedProductsQuery(), ResponseTypes.multipleInstancesOf(OrderedProduct.class))
|
||||
.join();
|
||||
public CompletableFuture<List<Order>> findAllOrders() {
|
||||
return queryGateway.query(new FindAllOrderedProductsQuery(), ResponseTypes.multipleInstancesOf(Order.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
package com.baeldung.axon.querymodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.axonframework.config.ProcessingGroup;
|
||||
import org.axonframework.eventhandling.EventHandler;
|
||||
import org.axonframework.queryhandling.QueryHandler;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||
import com.baeldung.axon.coreapi.queries.OrderedProduct;
|
||||
|
||||
@Service
|
||||
@ProcessingGroup("ordered-products")
|
||||
public class OrderedProductsEventHandler {
|
||||
|
||||
private final Map<String, OrderedProduct> orderedProducts = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void on(OrderPlacedEvent event) {
|
||||
String orderId = event.getOrderId();
|
||||
orderedProducts.put(orderId, new OrderedProduct(orderId, event.getProduct()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(OrderConfirmedEvent event) {
|
||||
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
|
||||
orderedProduct.setOrderConfirmed();
|
||||
return orderedProduct;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(OrderShippedEvent event) {
|
||||
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
|
||||
orderedProduct.setOrderShipped();
|
||||
return orderedProduct;
|
||||
});
|
||||
}
|
||||
|
||||
@QueryHandler
|
||||
public List<OrderedProduct> handle(FindAllOrderedProductsQuery query) {
|
||||
return new ArrayList<>(orderedProducts.values());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.baeldung.axon.querymodel;
|
||||
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderCreatedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductAddedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
|
||||
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||
import com.baeldung.axon.coreapi.queries.Order;
|
||||
import org.axonframework.config.ProcessingGroup;
|
||||
import org.axonframework.eventhandling.EventHandler;
|
||||
import org.axonframework.queryhandling.QueryHandler;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@ProcessingGroup("orders")
|
||||
public class OrdersEventHandler {
|
||||
|
||||
private final Map<String, Order> orders = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void on(OrderCreatedEvent event) {
|
||||
String orderId = event.getOrderId();
|
||||
orders.put(orderId, new Order(orderId));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ProductAddedEvent event) {
|
||||
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
|
||||
order.addProduct(event.getProductId());
|
||||
return order;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ProductCountIncrementedEvent event) {
|
||||
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
|
||||
order.incrementProductInstance(event.getProductId());
|
||||
return order;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ProductCountDecrementedEvent event) {
|
||||
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
|
||||
order.decrementProductInstance(event.getProductId());
|
||||
return order;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ProductRemovedEvent event) {
|
||||
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
|
||||
order.removeProduct(event.getProductId());
|
||||
return order;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(OrderConfirmedEvent event) {
|
||||
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
|
||||
order.setOrderConfirmed();
|
||||
return order;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(OrderShippedEvent event) {
|
||||
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
|
||||
order.setOrderShipped();
|
||||
return order;
|
||||
});
|
||||
}
|
||||
|
||||
@QueryHandler
|
||||
public List<Order> handle(FindAllOrderedProductsQuery query) {
|
||||
return new ArrayList<>(orders.values());
|
||||
}
|
||||
}
|
@ -1,11 +1,37 @@
|
||||
### Create Order, Add Product, Confirm and Ship Order
|
||||
|
||||
POST http://localhost:8080/ship-order
|
||||
|
||||
###
|
||||
### Create Order, Add Product and Ship Order
|
||||
|
||||
POST http://localhost:8080/ship-unconfirmed-order
|
||||
|
||||
###
|
||||
### Retrieve all existing Orders
|
||||
|
||||
GET http://localhost:8080/all-orders
|
||||
|
||||
### Create Order with id 666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
### Add Product a6aa01eb-4e38-4dfb-b53b-b5b82961fbf3 to Order 666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768/product/a6aa01eb-4e38-4dfb-b53b-b5b82961fbf3
|
||||
|
||||
### Increment Product a6aa01eb-4e38-4dfb-b53b-b5b82961fbf3 to Order 666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768/product/a6aa01eb-4e38-4dfb-b53b-b5b82961fbf3/increment
|
||||
|
||||
### Decrement Product a6aa01eb-4e38-4dfb-b53b-b5b82961fbf3 to Order 666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768/product/a6aa01eb-4e38-4dfb-b53b-b5b82961fbf3/decrement
|
||||
|
||||
### Confirm Order 666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768/confirm
|
||||
|
||||
### Ship Order 666a1661-474d-4046-8b12-8b5896312768
|
||||
|
||||
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768/ship
|
||||
|
||||
###
|
||||
|
@ -1,62 +1,139 @@
|
||||
package com.baeldung.axon.commandmodel;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.baeldung.axon.commandmodel.order.OrderAggregate;
|
||||
import com.baeldung.axon.coreapi.commands.AddProductCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.CreateOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand;
|
||||
import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderCreatedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductAddedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent;
|
||||
import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
|
||||
import com.baeldung.axon.coreapi.exceptions.DuplicateOrderLineException;
|
||||
import com.baeldung.axon.coreapi.exceptions.OrderAlreadyConfirmedException;
|
||||
import com.baeldung.axon.coreapi.exceptions.UnconfirmedOrderException;
|
||||
import org.axonframework.test.aggregate.AggregateTestFixture;
|
||||
import org.axonframework.test.aggregate.FixtureConfiguration;
|
||||
import org.junit.*;
|
||||
import org.axonframework.test.matchers.Matchers;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OrderAggregateUnitTest {
|
||||
class OrderAggregateUnitTest {
|
||||
|
||||
private static final String ORDER_ID = UUID.randomUUID().toString();
|
||||
private static final String PRODUCT_ID = UUID.randomUUID().toString();
|
||||
|
||||
private FixtureConfiguration<OrderAggregate> fixture;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
fixture = new AggregateTestFixture<>(OrderAggregate.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveNoPriorActivity_whenPlaceOrderCommand_thenShouldPublishOrderPlacedEvent() {
|
||||
String orderId = UUID.randomUUID().toString();
|
||||
String product = "Deluxe Chair";
|
||||
void giveNoPriorActivity_whenCreateOrderCommand_thenShouldPublishOrderCreatedEvent() {
|
||||
fixture.givenNoPriorActivity()
|
||||
.when(new PlaceOrderCommand(orderId, product))
|
||||
.expectEvents(new OrderPlacedEvent(orderId, product));
|
||||
.when(new CreateOrderCommand(ORDER_ID))
|
||||
.expectEvents(new OrderCreatedEvent(ORDER_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOrderPlacedEvent_whenConfirmOrderCommand_thenShouldPublishOrderConfirmedEvent() {
|
||||
String orderId = UUID.randomUUID().toString();
|
||||
String product = "Deluxe Chair";
|
||||
fixture.given(new OrderPlacedEvent(orderId, product))
|
||||
.when(new ConfirmOrderCommand(orderId))
|
||||
.expectEvents(new OrderConfirmedEvent(orderId));
|
||||
void givenOrderCreatedEvent_whenAddProductCommand_thenShouldPublishProductAddedEvent() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID))
|
||||
.when(new AddProductCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectEvents(new ProductAddedEvent(ORDER_ID, PRODUCT_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOrderPlacedEvent_whenShipOrderCommand_thenShouldThrowUnconfirmedOrderException() {
|
||||
String orderId = UUID.randomUUID().toString();
|
||||
String product = "Deluxe Chair";
|
||||
fixture.given(new OrderPlacedEvent(orderId, product))
|
||||
.when(new ShipOrderCommand(orderId))
|
||||
void givenOrderCreatedEventAndProductAddedEvent_whenAddProductCommandForSameProductId_thenShouldThrowDuplicateOrderLineException() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID))
|
||||
.when(new AddProductCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectException(DuplicateOrderLineException.class)
|
||||
.expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(PRODUCT_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventAndProductAddedEvent_whenIncrementProductCountCommand_thenShouldPublishProductCountIncrementedEvent() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID))
|
||||
.when(new IncrementProductCountCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectEvents(new ProductCountIncrementedEvent(ORDER_ID, PRODUCT_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventProductAddedEventAndProductCountIncrementedEvent_whenDecrementProductCountCommand_thenShouldPublishProductCountDecrementedEvent() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID),
|
||||
new ProductAddedEvent(ORDER_ID, PRODUCT_ID),
|
||||
new ProductCountIncrementedEvent(ORDER_ID, PRODUCT_ID))
|
||||
.when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectEvents(new ProductCountDecrementedEvent(ORDER_ID, PRODUCT_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventAndProductAddedEvent_whenDecrementProductCountCommand_thenShouldPublishProductRemovedEvent() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID))
|
||||
.when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectEvents(new ProductRemovedEvent(ORDER_ID, PRODUCT_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEvent_whenConfirmOrderCommand_thenShouldPublishOrderConfirmedEvent() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID))
|
||||
.when(new ConfirmOrderCommand(ORDER_ID))
|
||||
.expectEvents(new OrderConfirmedEvent(ORDER_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventAndOrderConfirmedEvent_whenConfirmOrderCommand_thenExpectNoEvents() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID))
|
||||
.when(new ConfirmOrderCommand(ORDER_ID))
|
||||
.expectNoEvents();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEvent_whenShipOrderCommand_thenShouldThrowUnconfirmedOrderException() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID))
|
||||
.when(new ShipOrderCommand(ORDER_ID))
|
||||
.expectException(UnconfirmedOrderException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOrderPlacedEventAndOrderConfirmedEvent_whenShipOrderCommand_thenShouldPublishOrderShippedEvent() {
|
||||
String orderId = UUID.randomUUID().toString();
|
||||
String product = "Deluxe Chair";
|
||||
fixture.given(new OrderPlacedEvent(orderId, product), new OrderConfirmedEvent(orderId))
|
||||
.when(new ShipOrderCommand(orderId))
|
||||
.expectEvents(new OrderShippedEvent(orderId));
|
||||
void givenOrderCreatedEventAndOrderConfirmedEvent_whenShipOrderCommand_thenShouldPublishOrderShippedEvent() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID))
|
||||
.when(new ShipOrderCommand(ORDER_ID))
|
||||
.expectEvents(new OrderShippedEvent(ORDER_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventProductAndOrderConfirmedEvent_whenAddProductCommand_thenShouldThrowOrderAlreadyConfirmedException() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID))
|
||||
.when(new AddProductCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectException(OrderAlreadyConfirmedException.class)
|
||||
.expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(ORDER_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventProductAddedEventAndOrderConfirmedEvent_whenIncrementProductCountCommand_thenShouldThrowOrderAlreadyConfirmedException() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID),
|
||||
new ProductAddedEvent(ORDER_ID, PRODUCT_ID),
|
||||
new OrderConfirmedEvent(ORDER_ID))
|
||||
.when(new IncrementProductCountCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectException(OrderAlreadyConfirmedException.class)
|
||||
.expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(ORDER_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOrderCreatedEventProductAddedEventAndOrderConfirmedEvent_whenDecrementProductCountCommand_thenShouldThrowOrderAlreadyConfirmedException() {
|
||||
fixture.given(new OrderCreatedEvent(ORDER_ID),
|
||||
new ProductAddedEvent(ORDER_ID, PRODUCT_ID),
|
||||
new OrderConfirmedEvent(ORDER_ID))
|
||||
.when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID))
|
||||
.expectException(OrderAlreadyConfirmedException.class)
|
||||
.expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(ORDER_ID)));
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.concurrent.interrupt;
|
||||
|
||||
public class CustomInterruptedException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
CustomInterruptedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.concurrent.interrupt;
|
||||
|
||||
public class InterruptExample extends Thread {
|
||||
|
||||
public static void propagateException() throws InterruptedException {
|
||||
Thread.sleep(1000);
|
||||
Thread.currentThread().interrupt();
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean restoreTheState() {
|
||||
InterruptExample thread1 = new InterruptExample();
|
||||
thread1.start();
|
||||
thread1.interrupt();
|
||||
return thread1.isInterrupted();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public static void throwCustomException() throws Exception {
|
||||
|
||||
Thread.sleep(1000);
|
||||
Thread.currentThread().interrupt();
|
||||
if (Thread.interrupted()) {
|
||||
throw new CustomInterruptedException("This thread was interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean handleWithCustomException() throws CustomInterruptedException{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new CustomInterruptedException("This thread was interrupted...");
|
||||
}
|
||||
return Thread.currentThread().isInterrupted();
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baeldung.concurrent.interrupt;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class InterruptExampleUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenPropagateException_thenThrowsInterruptedException() {
|
||||
assertThrows(InterruptedException.class, () -> InterruptExample.propagateException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRestoreTheState_thenReturnsTrue() {
|
||||
assertTrue(InterruptExample.restoreTheState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenThrowCustomException_thenContainsExpectedMessage() {
|
||||
Exception exception = assertThrows(CustomInterruptedException.class, () -> InterruptExample.throwCustomException());
|
||||
String expectedMessage = "This thread was interrupted";
|
||||
String actualMessage = exception.getMessage();
|
||||
|
||||
assertTrue(actualMessage.contains(expectedMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenHandleWithCustomException_thenReturnsTrue() throws CustomInterruptedException{
|
||||
assertTrue(InterruptExample.handleWithCustomException());
|
||||
}
|
||||
}
|
@ -45,7 +45,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
@ -105,7 +104,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
@ -134,7 +132,6 @@
|
||||
|
||||
<properties>
|
||||
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<source.version>1.8</source.version>
|
||||
<target.version>1.8</target.version>
|
||||
</properties>
|
||||
|
@ -60,7 +60,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
@ -108,7 +107,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
|
@ -189,7 +189,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
@ -249,7 +248,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
@ -397,7 +395,6 @@
|
||||
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
|
||||
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
|
||||
<spring-boot-maven-plugin.version>2.0.3.RELEASE</spring-boot-maven-plugin.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<source.version>1.8</source.version>
|
||||
<target.version>1.8</target.version>
|
||||
</properties>
|
||||
|
@ -6,9 +6,15 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.decoupling-pattern1</groupId>
|
||||
<artifactId>decoupling-pattern1</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-jpms</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>servicemodule</module>
|
||||
<module>consumermodule</module>
|
||||
|
@ -32,6 +32,11 @@
|
||||
<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>
|
||||
|
@ -9,6 +9,12 @@
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-jpms</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>servicemodule</module>
|
||||
<module>providermodule</module>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.baeldung.servicemodule</groupId>
|
||||
<artifactId>servicemodule2</artifactId>
|
||||
<artifactId>servicemodule</artifactId>
|
||||
<version>${servicemodule.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@ -27,6 +27,11 @@
|
||||
<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>
|
||||
|
@ -19,6 +19,11 @@
|
||||
<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>
|
||||
|
@ -20,4 +20,26 @@
|
||||
<module>decoupling-pattern2</module>
|
||||
</modules>
|
||||
|
||||
<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.0</compiler.plugin.version>
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
@ -3,3 +3,4 @@
|
||||
This module contains articles about core features in the Java language
|
||||
|
||||
- [The Java final Keyword – Impact on Performance](https://www.baeldung.com/java-final-performance)
|
||||
- [The package-info.java File](https://www.baeldung.com/java-package-info)
|
||||
|
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* This module is about impact of the final keyword on performance
|
||||
* <p>
|
||||
* This module explores if there are any performance benefits from
|
||||
* using the final keyword in our code. This module examines the performance
|
||||
* implications of using final on a variable, method, and class level.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.0
|
||||
* @author baeldung
|
||||
* @version 1.1
|
||||
*/
|
||||
package com.baeldung.finalkeyword;
|
@ -62,18 +62,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
|
@ -9,4 +9,5 @@ This module contains articles about core Java non-blocking input and output (IO)
|
||||
- [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector)
|
||||
- [Using Java MappedByteBuffer](https://www.baeldung.com/java-mapped-byte-buffer)
|
||||
- [How to Lock a File in Java](https://www.baeldung.com/java-lock-files)
|
||||
- [Java NIO DatagramChannel](https://www.baeldung.com/java-nio-datagramchannel)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-nio)
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.baeldung.datagramchannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
|
||||
public class DatagramChannelBuilder {
|
||||
|
||||
public static DatagramChannel openChannel() throws IOException {
|
||||
DatagramChannel datagramChannel = DatagramChannel.open();
|
||||
return datagramChannel;
|
||||
}
|
||||
|
||||
public static DatagramChannel bindChannel(SocketAddress local) throws IOException {
|
||||
return openChannel().bind(local);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baeldung.datagramchannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
|
||||
public class DatagramClient {
|
||||
|
||||
public static DatagramChannel startClient() throws IOException {
|
||||
DatagramChannel client = DatagramChannelBuilder.bindChannel(null);
|
||||
client.configureBlocking(false);
|
||||
return client;
|
||||
}
|
||||
|
||||
public static void sendMessage(DatagramChannel client, String msg, SocketAddress serverAddress) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
|
||||
client.send(buffer, serverAddress);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
DatagramChannel client = startClient();
|
||||
String msg = "Hello, this is a Baeldung's DatagramChannel based UDP client!";
|
||||
InetSocketAddress serverAddress = new InetSocketAddress("localhost", 7001);
|
||||
|
||||
sendMessage(client, msg, serverAddress);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.baeldung.datagramchannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
|
||||
public class DatagramServer {
|
||||
|
||||
public static DatagramChannel startServer() throws IOException {
|
||||
InetSocketAddress address = new InetSocketAddress("localhost", 7001);
|
||||
DatagramChannel server = DatagramChannelBuilder.bindChannel(address);
|
||||
|
||||
System.out.println("Server started at #" + address);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
public static String receiveMessage(DatagramChannel server) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
||||
SocketAddress remoteAdd = server.receive(buffer);
|
||||
String message = extractMessage(buffer);
|
||||
|
||||
System.out.println("Client at #" + remoteAdd + " sent: " + message);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private static String extractMessage(ByteBuffer buffer) {
|
||||
buffer.flip();
|
||||
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
buffer.get(bytes);
|
||||
|
||||
String msg = new String(bytes);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
DatagramChannel server = startServer();
|
||||
receiveMessage(server);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.baeldung.datagramchannel;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DatagramChannelUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenClientSendsAndServerReceivesUDPPacket_thenCorrect() throws IOException {
|
||||
DatagramChannel server = DatagramServer.startServer();
|
||||
DatagramChannel client = DatagramClient.startClient();
|
||||
|
||||
String msg1 = "Hello, this is a Baeldung's DatagramChannel based UDP client!";
|
||||
String msg2 = "Hi again!, Are you there!";
|
||||
|
||||
InetSocketAddress serverAddress = new InetSocketAddress("localhost", 7001);
|
||||
|
||||
DatagramClient.sendMessage(client, msg1, serverAddress);
|
||||
DatagramClient.sendMessage(client, msg2, serverAddress);
|
||||
|
||||
assertEquals("Hello, this is a Baeldung's DatagramChannel based UDP client!", DatagramServer.receiveMessage(server));
|
||||
assertEquals("Hi again!, Are you there!", DatagramServer.receiveMessage(server));
|
||||
}
|
||||
|
||||
}
|
@ -101,7 +101,8 @@ class ProcessUnderstandingUnitTest {
|
||||
.replace("/", File.separator));
|
||||
|
||||
BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
int value = Integer.parseInt(output.readLine());
|
||||
String line = output.readLine();
|
||||
int value = Integer.parseInt(line);
|
||||
|
||||
assertEquals(3, value);
|
||||
}
|
||||
|
@ -16,4 +16,5 @@ This module contains articles about core Java Security
|
||||
- [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption)
|
||||
- [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception)
|
||||
- [The java.security.egd JVM Option](https://www.baeldung.com/java-security-egd)
|
||||
- [RSA in Java](https://www.baeldung.com/java-rsa)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security)
|
||||
|
@ -11,4 +11,5 @@ This module contains articles about the Stream API in Java.
|
||||
- [Add BigDecimals using the Stream API](https://www.baeldung.com/java-stream-add-bigdecimals)
|
||||
- [Should We Close a Java Stream?](https://www.baeldung.com/java-stream-close)
|
||||
- [Returning Stream vs. Collection](https://www.baeldung.com/java-return-stream-collection)
|
||||
- [Convert a Java Enumeration Into a Stream](https://www.baeldung.com/java-enumeration-to-stream)
|
||||
- More articles: [[<-- prev>]](/../core-java-streams-2)
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.streams.conversion;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Spliterators.AbstractSpliterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EnumerationSpliterator<T> extends AbstractSpliterator<T> {
|
||||
|
||||
private final Enumeration<T> enumeration;
|
||||
|
||||
public EnumerationSpliterator(long est, int additionalCharacteristics, Enumeration<T> enumeration) {
|
||||
super(est, additionalCharacteristics);
|
||||
this.enumeration = enumeration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super T> action) {
|
||||
if (enumeration.hasMoreElements()) {
|
||||
action.accept(enumeration.nextElement());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(Consumer<? super T> action) {
|
||||
while (enumeration.hasMoreElements())
|
||||
action.accept(enumeration.nextElement());
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.baeldung.streams.conversion;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Spliterator;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class EnumerationStreamConversion {
|
||||
|
||||
public static <T> Stream<T> convert(Enumeration<T> enumeration) {
|
||||
EnumerationSpliterator<T> spliterator = new EnumerationSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED, enumeration);
|
||||
Stream<T> stream = StreamSupport.stream(spliterator, false);
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.streams.conversion;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class EnumerationStreamConversionUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenEnumeration_whenConvertedToStream_thenNotNull() {
|
||||
Vector<Integer> input = new Vector<>(Arrays.asList(1, 2, 3, 4, 5));
|
||||
|
||||
Stream<Integer> resultingStream = EnumerationStreamConversion.convert(input.elements());
|
||||
|
||||
Assert.assertNotNull(resultingStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToList_thenCorrect() {
|
||||
Vector<Integer> input = new Vector<>(Arrays.asList(1, 2, 3, 4, 5));
|
||||
|
||||
Stream<Integer> stream = EnumerationStreamConversion.convert(input.elements());
|
||||
List<Integer> list = stream.filter(e -> e >= 3)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(list, contains(3, 4, 5));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.baeldung.splitstringbynewline;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class SplitStringByNewLineUnitTest {
|
||||
@Test
|
||||
public void givenString_whenSplitByNewLineUsingSystemLineSeparator_thenReturnsArray() {
|
||||
assertThat("Line1\nLine2\nLine3".split(System.lineSeparator())).containsExactly("Line1", "Line2", "Line3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenString_whenSplitByNewLineUsingRegularExpressionPattern_thenReturnsArray() {
|
||||
assertThat("Line1\nLine2\nLine3".split("\\r?\\n|\\r")).containsExactly("Line1", "Line2", "Line3");
|
||||
|
||||
assertThat("Line1\rLine2\rLine3".split("\\r?\\n|\\r")).containsExactly("Line1", "Line2", "Line3");
|
||||
|
||||
assertThat("Line1\r\nLine2\r\nLine3".split("\\r?\\n|\\r")).containsExactly("Line1", "Line2", "Line3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenString_whenSplitByNewLineUsingJava8Pattern_thenReturnsArray() {
|
||||
assertThat("Line1\nLine2\nLine3".split("\\R")).containsExactly("Line1", "Line2", "Line3");
|
||||
|
||||
assertThat("Line1\rLine2\rLine3".split("\\R")).containsExactly("Line1", "Line2", "Line3");
|
||||
|
||||
assertThat("Line1\r\nLine2\r\nLine3".split("\\R")).containsExactly("Line1", "Line2", "Line3");
|
||||
}
|
||||
}
|
@ -44,7 +44,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
@ -68,7 +67,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
|
@ -94,7 +94,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
@ -154,7 +153,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
@ -193,7 +191,6 @@
|
||||
<javamoney.moneta.version>1.1</javamoney.moneta.version>
|
||||
|
||||
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<source.version>1.8</source.version>
|
||||
<target.version>1.8</target.version>
|
||||
</properties>
|
||||
|
@ -35,7 +35,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
@ -2,21 +2,18 @@
|
||||
<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>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.5.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>discord4j-bot</artifactId>
|
||||
<artifactId>discord4j</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>discord4j-bot</name>
|
||||
<name>discord4j</name>
|
||||
<description>Demo Discord bot using Discord4J + Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -68,4 +65,8 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
@ -2,21 +2,18 @@
|
||||
<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>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung.docker</groupId>
|
||||
<artifactId>docker-spring-boot-postgres</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>docker-spring-boot-postgres</name>
|
||||
<description>Demo project showing Spring Boot, PostgreSQL, and Docker</description>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -45,4 +42,8 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -4,13 +4,6 @@
|
||||
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>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.1.RELEASE</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>com.baeldung.docker</groupId>
|
||||
<artifactId>docker</artifactId>
|
||||
<version>0.0.1</version>
|
||||
@ -18,6 +11,13 @@
|
||||
<description>Demo project showing Spring Boot and Docker</description>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<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>11</java.version>
|
||||
</properties>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<artifactId>bookstore-monolith</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>Bookstore</name>
|
||||
<name>bookstore-monolith</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>jhipster-5</artifactId>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<groupId>com.baeldung.jhipster.gateway</groupId>
|
||||
<artifactId>gateway</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>Gateway</name>
|
||||
<name>gateway</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<repositories>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<groupId>com.baeldung.jhipster.quotes</groupId>
|
||||
<artifactId>quotes</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>Quotes</name>
|
||||
<name>quotes</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<repositories>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<groupId>com.baeldung.jhipster.uaa</groupId>
|
||||
<artifactId>uaa</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>Uaa</name>
|
||||
<name>uaa</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<repositories>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>kubernetes-parent</artifactId>
|
||||
<artifactId>kubernetes</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>k8s-intro</artifactId>
|
||||
|
@ -0,0 +1,72 @@
|
||||
package com.baeldung.kubernetes.intro;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.ApiException;
|
||||
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
import io.kubernetes.client.openapi.models.V1Pod;
|
||||
import io.kubernetes.client.util.Config;
|
||||
import io.kubernetes.client.util.Watch;
|
||||
import io.kubernetes.client.util.Watch.Response;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
public class WatchPods {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(WatchPods.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ApiClient client = Config.defaultClient();
|
||||
|
||||
// Optional, put helpful during tests: disable client timeout and enable
|
||||
// HTTP wire-level logs
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> log.info(message));
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
OkHttpClient newClient = client.getHttpClient()
|
||||
.newBuilder()
|
||||
.addInterceptor(interceptor)
|
||||
.readTimeout(0, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
client.setHttpClient(newClient);
|
||||
CoreV1Api api = new CoreV1Api(client);
|
||||
|
||||
// Create the watch object that monitors pod creation/deletion/update events
|
||||
while (true) {
|
||||
log.info("[I46] Creating watch...");
|
||||
try (Watch<V1Pod> watch = Watch.createWatch(
|
||||
client,
|
||||
api.listPodForAllNamespacesCall(false, null, null, null, null, "false", null, null, 10, true, null),
|
||||
new TypeToken<Response<V1Pod>>(){}.getType())) {
|
||||
|
||||
log.info("[I52] Receiving events:");
|
||||
for (Response<V1Pod> event : watch) {
|
||||
V1Pod pod = event.object;
|
||||
V1ObjectMeta meta = pod.getMetadata();
|
||||
switch (event.type) {
|
||||
case "ADDED":
|
||||
case "MODIFIED":
|
||||
case "DELETED":
|
||||
log.info("event.type: {}, namespace={}, name={}",
|
||||
event.type,
|
||||
meta.getNamespace(),
|
||||
meta.getName());
|
||||
break;
|
||||
default:
|
||||
log.warn("[W66] Unknown event type: {}", event.type);
|
||||
}
|
||||
}
|
||||
} catch (ApiException ex) {
|
||||
log.error("[E70] ApiError", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.baeldung.kubernetes.intro;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.ApiException;
|
||||
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
import io.kubernetes.client.openapi.models.V1Pod;
|
||||
import io.kubernetes.client.openapi.models.V1PodList;
|
||||
import io.kubernetes.client.util.Config;
|
||||
import io.kubernetes.client.util.Watch;
|
||||
import io.kubernetes.client.util.Watch.Response;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
public class WatchPodsUsingBookmarks {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(WatchPodsUsingBookmarks.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ApiClient client = Config.defaultClient();
|
||||
|
||||
// Optional, put helpful during tests: disable client timeout and enable
|
||||
// HTTP wire-level logs
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> log.info(message));
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
OkHttpClient newClient = client.getHttpClient()
|
||||
.newBuilder()
|
||||
.addInterceptor(interceptor)
|
||||
.readTimeout(0, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
client.setHttpClient(newClient);
|
||||
CoreV1Api api = new CoreV1Api(client);
|
||||
|
||||
String resourceVersion = null;
|
||||
while (true) {
|
||||
// Get a fresh list only we need to resync
|
||||
if ( resourceVersion == null ) {
|
||||
log.info("[I48] Creating initial POD list...");
|
||||
V1PodList podList = api.listPodForAllNamespaces(true, null, null, null, null, "false", resourceVersion, null, null, null);
|
||||
resourceVersion = podList.getMetadata().getResourceVersion();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
log.info("[I54] Creating watch: resourceVersion={}", resourceVersion);
|
||||
try (Watch<V1Pod> watch = Watch.createWatch(
|
||||
client,
|
||||
api.listPodForAllNamespacesCall(true, null, null, null, null, "false", resourceVersion, null, 10, true, null),
|
||||
new TypeToken<Response<V1Pod>>(){}.getType())) {
|
||||
|
||||
log.info("[I60] Receiving events:");
|
||||
for (Response<V1Pod> event : watch) {
|
||||
V1Pod pod = event.object;
|
||||
V1ObjectMeta meta = pod.getMetadata();
|
||||
switch (event.type) {
|
||||
case "BOOKMARK":
|
||||
resourceVersion = meta.getResourceVersion();
|
||||
log.info("[I67] event.type: {}, resourceVersion={}", event.type,resourceVersion);
|
||||
break;
|
||||
case "ADDED":
|
||||
case "MODIFIED":
|
||||
case "DELETED":
|
||||
log.info("event.type: {}, namespace={}, name={}",
|
||||
event.type,
|
||||
meta.getNamespace(),
|
||||
meta.getName());
|
||||
break;
|
||||
default:
|
||||
log.warn("[W76] Unknown event type: {}", event.type);
|
||||
}
|
||||
}
|
||||
} catch (ApiException ex) {
|
||||
log.error("[E80] ApiError", ex);
|
||||
resourceVersion = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.baeldung.kubernetes.intro;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.ApiException;
|
||||
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
import io.kubernetes.client.openapi.models.V1Pod;
|
||||
import io.kubernetes.client.openapi.models.V1PodList;
|
||||
import io.kubernetes.client.util.Config;
|
||||
import io.kubernetes.client.util.Watch;
|
||||
import io.kubernetes.client.util.Watch.Response;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
public class WatchPodsUsingResourceVersions {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(WatchPodsUsingResourceVersions.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ApiClient client = Config.defaultClient();
|
||||
|
||||
// Optional, put helpful during tests: disable client timeout and enable
|
||||
// HTTP wire-level logs
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> log.info(message));
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
OkHttpClient newClient = client.getHttpClient()
|
||||
.newBuilder()
|
||||
.addInterceptor(interceptor)
|
||||
.readTimeout(0, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
client.setHttpClient(newClient);
|
||||
CoreV1Api api = new CoreV1Api(client);
|
||||
|
||||
String resourceVersion = null;
|
||||
while (true) {
|
||||
try {
|
||||
if ( resourceVersion == null ) {
|
||||
V1PodList podList = api.listPodForAllNamespaces(null, null, null, null, null, null, resourceVersion, null, null, null);
|
||||
resourceVersion = podList.getMetadata().getResourceVersion();
|
||||
}
|
||||
|
||||
log.info("[I59] Creating watch: resourceVersion={}", resourceVersion);
|
||||
try (Watch<V1Pod> watch = Watch.createWatch(
|
||||
client,
|
||||
api.listPodForAllNamespacesCall(null, null, null, null, null, null, resourceVersion, null, 60, true, null),
|
||||
new TypeToken<Response<V1Pod>>(){}.getType())) {
|
||||
|
||||
log.info("[I65] Receiving events:");
|
||||
for (Response<V1Pod> event : watch) {
|
||||
V1Pod pod = event.object;
|
||||
V1ObjectMeta meta = pod.getMetadata();
|
||||
switch (event.type) {
|
||||
case "ADDED":
|
||||
case "MODIFIED":
|
||||
case "DELETED":
|
||||
log.info("event: type={}, namespace={}, name={}",
|
||||
event.type,
|
||||
meta.getNamespace(),
|
||||
meta.getName());
|
||||
break;
|
||||
default:
|
||||
log.warn("[W76] Unknown event type: {}", event.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ApiException ex) {
|
||||
if ( ex.getCode() == 504 || ex.getCode() == 410 ) {
|
||||
resourceVersion = extractResourceVersionFromException(ex);
|
||||
}
|
||||
else {
|
||||
// Reset resource version
|
||||
resourceVersion = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractResourceVersionFromException(ApiException ex) {
|
||||
|
||||
String body = ex.getResponseBody();
|
||||
if (body == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Gson gson = new Gson();
|
||||
Map<?,?> st = gson.fromJson(body, Map.class);
|
||||
Pattern p = Pattern.compile("Timeout: Too large resource version: (\\d+), current: (\\d+)");
|
||||
String msg = (String)st.get("message");
|
||||
Matcher m = p.matcher(msg);
|
||||
if (!m.matches()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return m.group(2);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.kubernetes.intro;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class WatchPodsLiveTest {
|
||||
@Test
|
||||
void whenWatchPods_thenSuccess() throws Exception {
|
||||
WatchPods.main(new String[] {});
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.kubernetes.intro;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class WatchPodsUsingBookmarksLiveTest {
|
||||
@Test
|
||||
void whenWatchPods_thenSuccess() throws Exception {
|
||||
WatchPodsUsingBookmarks.main(new String[] {});
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.kubernetes.intro;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class WatchPodsUsingResourceVersionsLiveTest {
|
||||
@Test
|
||||
void whenWatchPods_thenSuccess() throws Exception {
|
||||
WatchPodsUsingResourceVersions.main(new String[] {});
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>kubernetes-parent</artifactId>
|
||||
<artifactId>kubernetes</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>k8s-intro</module>
|
||||
|
@ -189,7 +189,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>start-server</id>
|
||||
@ -229,7 +228,6 @@
|
||||
<httpcore.version>4.4.13</httpcore.version>
|
||||
<httpclient.version>4.5.12</httpclient.version>
|
||||
<velocity-engine-core.version>2.2</velocity-engine-core.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<nullaway.version>0.3.0</nullaway.version>
|
||||
<plexus-compiler.version>2.8</plexus-compiler.version>
|
||||
<errorprone.version>2.1.3</errorprone.version>
|
||||
|
@ -47,7 +47,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.quasar.App</mainClass>
|
||||
<workingDirectory>target/classes</workingDirectory>
|
||||
|
@ -102,7 +102,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec.plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<arguments>
|
||||
@ -146,7 +145,6 @@
|
||||
<lombok.version>1.2.3</lombok.version>
|
||||
<reactor.version>3.1.6.RELEASE</reactor.version>
|
||||
<compiler.plugin.version>3.7.0</compiler.plugin.version>
|
||||
<exec.plugin.version>1.6.0</exec.plugin.version>
|
||||
<shade.plugin.version>3.1.0</shade.plugin.version>
|
||||
</properties>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
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>
|
||||
<artifactId>genie</artifactId>
|
||||
<name>Genie</name>
|
||||
<name>genie</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Sample project for Netflix Genie</description>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
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>
|
||||
<artifactId>mantis</artifactId>
|
||||
<name>Mantis</name>
|
||||
<name>mantis</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Sample project for Netflix Mantis</description>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
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>
|
||||
<artifactId>netflix-modules</artifactId>
|
||||
<name>Netflix Modules</name>
|
||||
<name>netflix-modules</name>
|
||||
<packaging>pom</packaging>
|
||||
<description>Module for Netflix projects</description>
|
||||
|
||||
|
@ -8,3 +8,4 @@ This module contains articles about Annotations used in Hibernate.
|
||||
- [Difference Between @JoinColumn and mappedBy](https://www.baeldung.com/jpa-joincolumn-vs-mappedby)
|
||||
- [Hibernate One to Many Annotation Tutorial](https://www.baeldung.com/hibernate-one-to-many)
|
||||
- [Hibernate @WhereJoinTable Annotation](https://www.baeldung.com/hibernate-wherejointable)
|
||||
- [Usage of the Hibernate @LazyCollection Annotation](https://www.baeldung.com/hibernate-lazycollection)
|
||||
|
@ -0,0 +1,103 @@
|
||||
package com.baeldung.hibernate.lazycollection.model;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OrderColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Entity;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
public class Branch {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public Branch() {
|
||||
}
|
||||
public Branch(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@OneToMany(mappedBy = "mainBranch")
|
||||
@LazyCollection(LazyCollectionOption.TRUE)
|
||||
private List<Employee> mainEmployees;
|
||||
|
||||
@OneToMany(mappedBy = "subBranch")
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
private List<Employee> subEmployees;
|
||||
|
||||
@OneToMany(mappedBy = "additionalBranch")
|
||||
@LazyCollection(LazyCollectionOption.EXTRA)
|
||||
@OrderColumn(name = "order_id")
|
||||
private List<Employee> additionalEmployees;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Employee> getMainEmployees() {
|
||||
return mainEmployees;
|
||||
}
|
||||
|
||||
public void setMainEmployees(List<Employee> mainEmployees) {
|
||||
this.mainEmployees = mainEmployees;
|
||||
}
|
||||
|
||||
public List<Employee> getSubEmployees() {
|
||||
return subEmployees;
|
||||
}
|
||||
|
||||
public void setSubEmployees(List<Employee> subEmployees) {
|
||||
this.subEmployees = subEmployees;
|
||||
}
|
||||
|
||||
public List<Employee> getAdditionalEmployees() {
|
||||
return additionalEmployees;
|
||||
}
|
||||
|
||||
public void setAdditionalEmployees(List<Employee> additionalEmployees) {
|
||||
this.additionalEmployees = additionalEmployees;
|
||||
}
|
||||
|
||||
public void addMainEmployee(Employee employee) {
|
||||
if (this.mainEmployees == null) {
|
||||
this.mainEmployees = new ArrayList<>();
|
||||
}
|
||||
this.mainEmployees.add(employee);
|
||||
}
|
||||
|
||||
public void addSubEmployee(Employee employee) {
|
||||
if (this.subEmployees == null) {
|
||||
this.subEmployees = new ArrayList<>();
|
||||
}
|
||||
this.subEmployees.add(employee);
|
||||
}
|
||||
|
||||
public void addAdditionalEmployee(Employee employee) {
|
||||
if (this.additionalEmployees == null) {
|
||||
this.additionalEmployees = new ArrayList<>();
|
||||
}
|
||||
this.additionalEmployees.add(employee);
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.baeldung.hibernate.lazycollection.model;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OrderColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Employee {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String address;
|
||||
|
||||
public Employee() {
|
||||
|
||||
}
|
||||
|
||||
public Employee(String name, Branch mainBranch, Branch subBranch, Branch additionalBranch) {
|
||||
this.name = name;
|
||||
this.mainBranch = mainBranch;
|
||||
this.subBranch = subBranch;
|
||||
this.additionalBranch = additionalBranch;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
private Branch mainBranch;
|
||||
|
||||
@ManyToOne
|
||||
private Branch subBranch;
|
||||
|
||||
@ManyToOne
|
||||
private Branch additionalBranch;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Branch getMainBranch() {
|
||||
return mainBranch;
|
||||
}
|
||||
|
||||
public void setMainBranch(Branch mainBranch) {
|
||||
this.mainBranch = mainBranch;
|
||||
}
|
||||
|
||||
public Branch getSubBranch() {
|
||||
return subBranch;
|
||||
}
|
||||
|
||||
public void setSubBranch(Branch subBranch) {
|
||||
this.subBranch = subBranch;
|
||||
}
|
||||
|
||||
public Branch getAdditionalBranch() {
|
||||
return additionalBranch;
|
||||
}
|
||||
|
||||
public void setAdditionalBranch(Branch additionalBranch) {
|
||||
this.additionalBranch = additionalBranch;
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package com.baeldung.hibernate.lazycollection;
|
||||
|
||||
import com.baeldung.hibernate.lazycollection.model.Branch;
|
||||
import com.baeldung.hibernate.lazycollection.model.Employee;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
public class LazyCollectionIntegrationTest {
|
||||
|
||||
private static SessionFactory sessionFactory;
|
||||
|
||||
private Session session;
|
||||
|
||||
Branch branch;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeTests() {
|
||||
Configuration configuration = new Configuration().addAnnotatedClass(Branch.class)
|
||||
.addAnnotatedClass(Employee.class).setProperty("hibernate.dialect", H2Dialect.class.getName())
|
||||
.setProperty("hibernate.connection.driver_class", org.h2.Driver.class.getName())
|
||||
.setProperty("hibernate.connection.url", "jdbc:h2:mem:test")
|
||||
.setProperty("hibernate.connection.username", "sa").setProperty("hibernate.connection.password", "")
|
||||
.setProperty("hibernate.hbm2ddl.auto", "update");
|
||||
|
||||
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
|
||||
.applySettings(configuration.getProperties()).build();
|
||||
|
||||
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
session = sessionFactory.openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
branch = new Branch("Main Branch");
|
||||
|
||||
session.save(branch);
|
||||
|
||||
Employee mainEmployee1 = new Employee("main employee 1", branch, null, null);
|
||||
Employee mainEmployee2 = new Employee("main employee 2", branch, null, null);
|
||||
Employee mainEmployee3 = new Employee("main employee 3", branch, null, null);
|
||||
|
||||
session.save(mainEmployee1);
|
||||
session.save(mainEmployee2);
|
||||
session.save(mainEmployee3);
|
||||
|
||||
Employee subEmployee1 = new Employee("sub employee 1", null, branch, null);
|
||||
Employee subEmployee2 = new Employee("sub employee 2", null, branch, null);
|
||||
Employee subEmployee3 = new Employee("sub employee 3", null, branch, null);
|
||||
|
||||
session.save(subEmployee1);
|
||||
session.save(subEmployee2);
|
||||
session.save(subEmployee3);
|
||||
|
||||
Employee additionalEmployee1 = new Employee("additional employee 1", null, null, branch);
|
||||
Employee additionalEmployee2 = new Employee("additional employee 2", null, null, branch);
|
||||
Employee additionalEmployee3 = new Employee("additional employee 3", null, null, branch);
|
||||
|
||||
session.save(additionalEmployee1);
|
||||
session.save(additionalEmployee2);
|
||||
session.save(additionalEmployee3);
|
||||
|
||||
session.flush();
|
||||
session.refresh(branch);
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLazyFetching() {
|
||||
Assert.assertFalse(Hibernate.isInitialized(branch.getMainEmployees()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEagerFetching() {
|
||||
Assert.assertTrue(Hibernate.isInitialized(branch.getSubEmployees()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtraFetching() {
|
||||
Assert.assertFalse(Hibernate.isInitialized(branch.getAdditionalEmployees()));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterTests() {
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
@ -55,7 +55,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>document</id>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jooq</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>jooq-examples</name>
|
||||
<name>jooq</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>jOOQ Examples</description>
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
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>
|
||||
<artifactId>spring-data-cosmosdb</artifactId>
|
||||
<name>spring-data-cosmos-db</name>
|
||||
<name>spring-data-cosmosdb</name>
|
||||
<description>tutorial for spring-data-cosmosdb</description>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
@ -6,18 +6,15 @@ import com.baeldung.projection.repository.PersonRepository;
|
||||
import com.baeldung.projection.view.AddressView;
|
||||
import com.baeldung.projection.view.PersonDto;
|
||||
import com.baeldung.projection.view.PersonView;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
|
||||
|
||||
@DataJpaTest
|
||||
@RunWith(SpringRunner.class)
|
||||
@Sql(scripts = "/projection-insert-data.sql")
|
||||
@Sql(scripts = "/projection-clean-up-data.sql", executionPhase = AFTER_TEST_METHOD)
|
||||
public class JpaProjectionIntegrationTest {
|
||||
|
3
pom.xml
3
pom.xml
@ -1375,13 +1375,12 @@
|
||||
<!-- can't upgrade the plugin yet; as there is an issue with 2.22 no longer running all the tests-->
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
|
||||
<java.version>1.8</java.version>
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<esapi.version>2.2.2.0</esapi.version>
|
||||
<jmh-core.version>1.28</jmh-core.version>
|
||||
<jmh-generator.version>1.28</jmh-generator.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<maven-failsafe-plugin.version>2.21.0</maven-failsafe-plugin.version>
|
||||
<commons-io.version>2.8.0</commons-io.version>
|
||||
<commons-lang.version>2.6</commons-lang.version>
|
||||
|
@ -40,7 +40,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
|
@ -45,7 +45,6 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.examples.slack.MainClass</mainClass>
|
||||
</configuration>
|
||||
|
@ -9,4 +9,5 @@ This module contains articles about reactive Spring 5
|
||||
- [Debugging Reactive Streams in Java](https://www.baeldung.com/spring-debugging-reactive-streams)
|
||||
- [Static Content in Spring WebFlux](https://www.baeldung.com/spring-webflux-static-content)
|
||||
- [Server-Sent Events in Spring](https://www.baeldung.com/spring-server-sent-events)
|
||||
- [Backpressure Mechanism in Spring WebFlux](https://www.baeldung.com/spring-webflux-backpressure)
|
||||
- More articles: [[<-- prev]](/spring-5-reactive)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user