Order and Payment
This commit is contained in:
@@ -10,6 +10,15 @@ import demo.order.OrderStatus;
|
||||
* @author kbastani
|
||||
*/
|
||||
public enum OrderEventType {
|
||||
// TODO: Implement
|
||||
ORDER_CREATED
|
||||
ORDER_CREATED,
|
||||
ACCOUNT_CONNECTED,
|
||||
RESERVATION_PENDING,
|
||||
INVENTORY_RESERVED,
|
||||
RESERVATION_SUCCEEDED,
|
||||
RESERVATION_FAILED,
|
||||
PAYMENT_CREATED,
|
||||
PAYMENT_CONNECTED,
|
||||
PAYMENT_PENDING,
|
||||
PAYMENT_SUCCEEDED,
|
||||
PAYMENT_FAILED
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Order extends BaseEntity {
|
||||
private Address shippingAddress;
|
||||
|
||||
public Order() {
|
||||
this.status = OrderStatus.PURCHASED;
|
||||
this.status = OrderStatus.ORDER_CREATED;
|
||||
}
|
||||
|
||||
public Order(String accountNumber, Address shippingAddress) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package demo.order;
|
||||
|
||||
public enum OrderCommand {
|
||||
// TODO: Create commands
|
||||
TODO
|
||||
CONNECT_ACCOUNT,
|
||||
RESERVE_INVENTORY,
|
||||
CREATE_PAYMENT,
|
||||
CONNECT_PAYMENT,
|
||||
PROCESS_PAYMENT
|
||||
}
|
||||
|
||||
@@ -76,10 +76,42 @@ public class OrderController {
|
||||
.orElseThrow(() -> new RuntimeException("The order could not be found"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/orders/{id}/commands/todo")
|
||||
public ResponseEntity confirmOrder(@PathVariable Long id) {
|
||||
@GetMapping(path = "/orders/{id}/commands/connectAccount")
|
||||
public ResponseEntity connectAccount(@PathVariable Long id) {
|
||||
return Optional.ofNullable(getOrderResource(
|
||||
orderService.applyCommand(id, OrderCommand.TODO)))
|
||||
orderService.applyCommand(id, OrderCommand.CONNECT_ACCOUNT)))
|
||||
.map(e -> new ResponseEntity<>(e, HttpStatus.OK))
|
||||
.orElseThrow(() -> new RuntimeException("The command could not be applied"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/orders/{id}/commands/connectPayment")
|
||||
public ResponseEntity connectPayment(@PathVariable Long id) {
|
||||
return Optional.ofNullable(getOrderResource(
|
||||
orderService.applyCommand(id, OrderCommand.CONNECT_PAYMENT)))
|
||||
.map(e -> new ResponseEntity<>(e, HttpStatus.OK))
|
||||
.orElseThrow(() -> new RuntimeException("The command could not be applied"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/orders/{id}/commands/createPayment")
|
||||
public ResponseEntity createPayment(@PathVariable Long id) {
|
||||
return Optional.ofNullable(getOrderResource(
|
||||
orderService.applyCommand(id, OrderCommand.CREATE_PAYMENT)))
|
||||
.map(e -> new ResponseEntity<>(e, HttpStatus.OK))
|
||||
.orElseThrow(() -> new RuntimeException("The command could not be applied"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/orders/{id}/commands/processPayment")
|
||||
public ResponseEntity processPayment(@PathVariable Long id) {
|
||||
return Optional.ofNullable(getOrderResource(
|
||||
orderService.applyCommand(id, OrderCommand.PROCESS_PAYMENT)))
|
||||
.map(e -> new ResponseEntity<>(e, HttpStatus.OK))
|
||||
.orElseThrow(() -> new RuntimeException("The command could not be applied"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/orders/{id}/commands/reserveInventory")
|
||||
public ResponseEntity reserveInventory(@PathVariable Long id) {
|
||||
return Optional.ofNullable(getOrderResource(
|
||||
orderService.applyCommand(id, OrderCommand.RESERVE_INVENTORY)))
|
||||
.map(e -> new ResponseEntity<>(e, HttpStatus.OK))
|
||||
.orElseThrow(() -> new RuntimeException("The command could not be applied"));
|
||||
}
|
||||
@@ -177,17 +209,20 @@ public class OrderController {
|
||||
if (orderResource != null) {
|
||||
commandResource.add(
|
||||
getCommandLinkBuilder(id)
|
||||
.slash("confirm")
|
||||
.withRel("confirm"),
|
||||
.slash("connectAccount")
|
||||
.withRel("connectAccount"),
|
||||
getCommandLinkBuilder(id)
|
||||
.slash("activate")
|
||||
.withRel("activate"),
|
||||
.slash("reserveInventory")
|
||||
.withRel("reserveInventory"),
|
||||
getCommandLinkBuilder(id)
|
||||
.slash("suspend")
|
||||
.withRel("suspend"),
|
||||
.slash("createPayment")
|
||||
.withRel("createPayment"),
|
||||
getCommandLinkBuilder(id)
|
||||
.slash("archive")
|
||||
.withRel("archive")
|
||||
.slash("connectPayment")
|
||||
.withRel("connectPayment"),
|
||||
getCommandLinkBuilder(id)
|
||||
.slash("processPayment")
|
||||
.withRel("processPayment")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package demo.order;
|
||||
|
||||
public enum OrderStatus {
|
||||
PURCHASED,
|
||||
PENDING,
|
||||
CONFIRMED,
|
||||
SHIPPED,
|
||||
DELIVERED
|
||||
ORDER_CREATED,
|
||||
ACCOUNT_CONNECTED,
|
||||
RESERVATION_PENDING,
|
||||
INVENTORY_RESERVED,
|
||||
RESERVATION_SUCCEEDED,
|
||||
RESERVATION_FAILED,
|
||||
PAYMENT_CREATED,
|
||||
PAYMENT_CONNECTED,
|
||||
PAYMENT_PENDING,
|
||||
PAYMENT_SUCCEEDED,
|
||||
PAYMENT_FAILED
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ package demo.config;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.function.OrderFunction;
|
||||
import demo.function.*;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import demo.stream.OrderStream;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.client.Traverson;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
@@ -15,6 +19,7 @@ import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
@@ -23,7 +28,7 @@ import java.util.EnumSet;
|
||||
* <p>
|
||||
* A state machine provides a robust declarative language for describing the state of an {@link Order}
|
||||
* resource given a sequence of ordered {@link demo.event.OrderEvents}. When an event is received
|
||||
* in {@link demo.event.OrderEventStream}, an in-memory state machine is fully replicated given the
|
||||
* in {@link OrderStream}, an in-memory state machine is fully replicated given the
|
||||
* {@link demo.event.OrderEvents} attached to an {@link Order} resource.
|
||||
*
|
||||
* @author kbastani
|
||||
@@ -44,7 +49,7 @@ public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderS
|
||||
try {
|
||||
// Describe the initial condition of the order state machine
|
||||
states.withStates()
|
||||
.initial(OrderStatus.PENDING)
|
||||
.initial(OrderStatus.ORDER_CREATED)
|
||||
.states(EnumSet.allOf(OrderStatus.class));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("State machine configuration failed", e);
|
||||
@@ -63,12 +68,240 @@ public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderS
|
||||
public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderEventType> transitions) {
|
||||
try {
|
||||
// Describe state machine transitions for orders
|
||||
// TODO: Configure state machine
|
||||
transitions.withExternal()
|
||||
.source(OrderStatus.ORDER_CREATED)
|
||||
.target(OrderStatus.ORDER_CREATED)
|
||||
.event(OrderEventType.ORDER_CREATED)
|
||||
.action(orderCreated())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.ORDER_CREATED)
|
||||
.target(OrderStatus.ACCOUNT_CONNECTED)
|
||||
.event(OrderEventType.ACCOUNT_CONNECTED)
|
||||
.action(accountConnected())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.ACCOUNT_CONNECTED)
|
||||
.target(OrderStatus.RESERVATION_PENDING)
|
||||
.event(OrderEventType.RESERVATION_PENDING)
|
||||
.action(reservationPending())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.RESERVATION_PENDING)
|
||||
.target(OrderStatus.RESERVATION_SUCCEEDED)
|
||||
.event(OrderEventType.RESERVATION_SUCCEEDED)
|
||||
.action(reservationSucceeded())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.RESERVATION_PENDING)
|
||||
.target(OrderStatus.RESERVATION_FAILED)
|
||||
.event(OrderEventType.RESERVATION_FAILED)
|
||||
.action(reservationFailed())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.RESERVATION_SUCCEEDED)
|
||||
.target(OrderStatus.PAYMENT_CREATED)
|
||||
.event(OrderEventType.PAYMENT_CREATED)
|
||||
.action(paymentCreated())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.PAYMENT_CREATED)
|
||||
.target(OrderStatus.PAYMENT_CONNECTED)
|
||||
.event(OrderEventType.PAYMENT_CONNECTED)
|
||||
.action(paymentConnected())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.PAYMENT_CONNECTED)
|
||||
.target(OrderStatus.PAYMENT_PENDING)
|
||||
.event(OrderEventType.PAYMENT_PENDING)
|
||||
.action(paymentPending())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.PAYMENT_PENDING)
|
||||
.target(OrderStatus.PAYMENT_SUCCEEDED)
|
||||
.event(OrderEventType.PAYMENT_SUCCEEDED)
|
||||
.action(paymentSucceeded())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderStatus.PAYMENT_PENDING)
|
||||
.target(OrderStatus.PAYMENT_FAILED)
|
||||
.event(OrderEventType.PAYMENT_FAILED)
|
||||
.action(paymentFailed());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not configure state machine transitions", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> orderCreated() {
|
||||
return context -> applyEvent(context,
|
||||
new OrderCreated(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> paymentPending() {
|
||||
return context -> applyEvent(context,
|
||||
new PaymentPending(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> reservationPending() {
|
||||
return context -> applyEvent(context,
|
||||
new ReservationPending(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> paymentFailed() {
|
||||
return context -> applyEvent(context,
|
||||
new PaymentFailed(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> paymentSucceeded() {
|
||||
return context -> applyEvent(context,
|
||||
new PaymentSucceeded(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> paymentConnected() {
|
||||
return context -> applyEvent(context,
|
||||
new PaymentConnected(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> paymentCreated() {
|
||||
return context -> applyEvent(context,
|
||||
new PaymentCreated(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> reservationSucceeded() {
|
||||
return context -> applyEvent(context,
|
||||
new ReservationSucceeded(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> reservationFailed() {
|
||||
return context -> applyEvent(context,
|
||||
new ReservationSucceeded(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<OrderStatus, OrderEventType> accountConnected() {
|
||||
return context -> applyEvent(context,
|
||||
new ReservationFailed(context, event -> {
|
||||
log.info(event.getType() + ": " + event.getLink("order").getHref());
|
||||
// Get the account resource for the event
|
||||
Traverson traverson = new Traverson(
|
||||
URI.create(event.getLink("order").getHref()),
|
||||
MediaTypes.HAL_JSON
|
||||
);
|
||||
|
||||
return traverson.follow("self")
|
||||
.toEntity(Order.class)
|
||||
.getBody();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions are mapped to actions that are triggered during the replication of a state machine. Functions
|
||||
* should only be executed after the state machine has completed replication. This method checks the state
|
||||
@@ -78,12 +311,12 @@ public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderS
|
||||
* The {@link OrderFunction} argument is only applied if an {@link OrderEvent} is provided as a
|
||||
* message header in the {@link StateContext}.
|
||||
*
|
||||
* @param context is the state machine context that may include an {@link OrderEvent}
|
||||
* @param context is the state machine context that may include an {@link OrderEvent}
|
||||
* @param orderFunction is the order function to apply after the state machine has completed replication
|
||||
* @return an {@link OrderEvent} only if this event has not yet been processed, otherwise returns null
|
||||
*/
|
||||
private OrderEvent applyEvent(StateContext<OrderStatus, OrderEventType> context,
|
||||
OrderFunction orderFunction) {
|
||||
OrderFunction orderFunction) {
|
||||
OrderEvent orderEvent = null;
|
||||
|
||||
// Log out the progress of the state machine replication
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
package demo.event;
|
||||
|
||||
public enum OrderEventType {
|
||||
// TODO: Add event types
|
||||
ORDER_CREATED,
|
||||
ACCOUNT_CONNECTED,
|
||||
RESERVATION_PENDING,
|
||||
INVENTORY_RESERVED,
|
||||
RESERVATION_SUCCEEDED,
|
||||
RESERVATION_FAILED,
|
||||
PAYMENT_CREATED,
|
||||
PAYMENT_CONNECTED,
|
||||
PAYMENT_PENDING,
|
||||
PAYMENT_SUCCEEDED,
|
||||
PAYMENT_FAILED
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class AccountConnected extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(AccountConnected.class);
|
||||
|
||||
public AccountConnected(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for account connected...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class OrderCreated extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(OrderCreated.class);
|
||||
|
||||
public OrderCreated(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for order created...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ public abstract class OrderFunction {
|
||||
// Execute the lambda function
|
||||
Order result = lambda.apply(event);
|
||||
context.getExtendedState().getVariables().put("order", result);
|
||||
log.info("Order function: " + event.getType());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaymentConnected extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(PaymentConnected.class);
|
||||
|
||||
public PaymentConnected(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for payment connected...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaymentCreated extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(PaymentCreated.class);
|
||||
|
||||
public PaymentCreated(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for payment created...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaymentFailed extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(PaymentFailed.class);
|
||||
|
||||
public PaymentFailed(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for payment failed...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaymentPending extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(PaymentPending.class);
|
||||
|
||||
public PaymentPending(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for payment pending...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaymentSucceeded extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(PaymentSucceeded.class);
|
||||
|
||||
public PaymentSucceeded(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for payment succeeded...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ReservationFailed extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(ReservationFailed.class);
|
||||
|
||||
public ReservationFailed(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for reservation failed...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ReservationPending extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(ReservationPending.class);
|
||||
|
||||
public ReservationPending(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for reservation pending...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package demo.function;
|
||||
|
||||
import demo.event.OrderEvent;
|
||||
import demo.event.OrderEventType;
|
||||
import demo.order.Order;
|
||||
import demo.order.OrderStatus;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ReservationSucceeded extends OrderFunction {
|
||||
|
||||
final private Logger log = Logger.getLogger(ReservationSucceeded.class);
|
||||
|
||||
public ReservationSucceeded(StateContext<OrderStatus, OrderEventType> context, Function<OrderEvent, Order> lambda) {
|
||||
super(context, lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an {@link OrderEvent} to the lambda function that was provided through the
|
||||
* constructor of this {@link OrderFunction}.
|
||||
*
|
||||
* @param event is the {@link OrderEvent} to apply to the lambda function
|
||||
*/
|
||||
@Override
|
||||
public Order apply(OrderEvent event) {
|
||||
log.info("Executing workflow for reservation succeeded...");
|
||||
return super.apply(event);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
package demo.order;
|
||||
|
||||
/**
|
||||
* A simple domain class for the {@link LineItem} concept in the order context.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
* @author Josh Long
|
||||
*/
|
||||
public class LineItem {
|
||||
import java.io.Serializable;
|
||||
|
||||
public class LineItem implements Serializable {
|
||||
|
||||
private String name, productId;
|
||||
private Integer quantity;
|
||||
private Double price, tax;
|
||||
|
||||
public LineItem() {
|
||||
}
|
||||
|
||||
public LineItem(String name, String productId, Integer quantity,
|
||||
Double price, Double tax) {
|
||||
this.name = name;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package demo.order;
|
||||
|
||||
/**
|
||||
* Describes the state of an {@link Order}.
|
||||
*
|
||||
* @author Kenny Bastani
|
||||
* @author Josh Long
|
||||
*/
|
||||
public enum OrderStatus {
|
||||
PENDING,
|
||||
CONFIRMED,
|
||||
SHIPPED,
|
||||
DELIVERED
|
||||
ORDER_CREATED,
|
||||
ACCOUNT_CONNECTED,
|
||||
RESERVATION_PENDING,
|
||||
RESERVATION_SUCCEEDED,
|
||||
RESERVATION_FAILED,
|
||||
PAYMENT_CREATED,
|
||||
PAYMENT_CONNECTED,
|
||||
PAYMENT_PENDING,
|
||||
PAYMENT_SUCCEEDED,
|
||||
PAYMENT_FAILED
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package demo.event;
|
||||
package demo.stream;
|
||||
|
||||
import demo.event.EventService;
|
||||
import demo.event.OrderEvent;
|
||||
import demo.order.Order;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
@@ -8,7 +10,7 @@ import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/**
|
||||
* The {@link OrderEventStream} monitors for a variety of {@link OrderEvent} domain
|
||||
* The {@link OrderStream} monitors for a variety of {@link OrderEvent} domain
|
||||
* events for an {@link Order}.
|
||||
*
|
||||
* @author kbastani
|
||||
@@ -16,11 +18,11 @@ import org.springframework.context.annotation.Profile;
|
||||
@EnableAutoConfiguration
|
||||
@EnableBinding(Sink.class)
|
||||
@Profile({ "cloud", "development" })
|
||||
public class OrderEventStream {
|
||||
public class OrderStream {
|
||||
|
||||
private EventService eventService;
|
||||
|
||||
public OrderEventStream(EventService eventService) {
|
||||
public OrderStream(EventService eventService) {
|
||||
this.eventService = eventService;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ spring:
|
||||
stream:
|
||||
bindings:
|
||||
input:
|
||||
destination: account
|
||||
group: account-group
|
||||
destination: order
|
||||
group: order-group
|
||||
contentType: 'application/json'
|
||||
consumer:
|
||||
durableSubscription: true
|
||||
|
||||
Reference in New Issue
Block a user