extended analysis
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package click.kamil.examples.statemachine.extended.config;
|
||||
|
||||
import click.kamil.examples.statemachine.extended.constants.MyEvents;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine(name = "extendedStateMachine")
|
||||
public class ExtendedStateMachineConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Value("${app.states.initial:START}")
|
||||
private String initialState;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(initialState)
|
||||
.state("PROCESSING")
|
||||
.state("COMPLETED")
|
||||
.state("CANCELLED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("START").target("PROCESSING")
|
||||
.event(MyEvents.SUBMIT)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("PROCESSING").target("COMPLETED")
|
||||
.event("FINISH")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("PROCESSING").target("CANCELLED")
|
||||
.event(MyEvents.CANCEL)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("START").target("PROCESSING")
|
||||
.event("REACTIVE_EVENT")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("START").target("START")
|
||||
.event("AUDIT_EVENT")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("START").target("PROCESSING")
|
||||
.event("EXTERNAL_TRIGGER");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package click.kamil.examples.statemachine.extended.constants;
|
||||
|
||||
public class MyEvents {
|
||||
public static final String SUBMIT = "SUBMIT_EVENT";
|
||||
public static final String CANCEL = "CANCEL_EVENT";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package click.kamil.examples.statemachine.extended.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ExternalNotificationService {
|
||||
public void sendExternalNotification(String message) {
|
||||
// Simulated third-party call that triggers a state change in an external system
|
||||
System.out.println("Notifying external system: " + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package click.kamil.examples.statemachine.extended.service;
|
||||
|
||||
import click.kamil.examples.statemachine.extended.constants.MyEvents;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.persist.StateMachinePersister;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class OrderService {
|
||||
|
||||
private final StateMachine<String, String> stateMachine;
|
||||
private final StateMachinePersister<String, String, String> persister;
|
||||
private final ExternalNotificationService notificationService;
|
||||
|
||||
public void processSubmit() {
|
||||
// Business logic here...
|
||||
notificationService.sendExternalNotification("Submit processed");
|
||||
stateMachine.sendEvent(MyEvents.SUBMIT);
|
||||
}
|
||||
|
||||
public void processCancel() {
|
||||
// More business logic...
|
||||
stateMachine.sendEvent(MyEvents.CANCEL);
|
||||
}
|
||||
|
||||
public void resumeOrder(String orderId) throws Exception {
|
||||
persister.restore(stateMachine, orderId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package click.kamil.examples.statemachine.extended.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ReactiveOrderService {
|
||||
|
||||
private final StateMachine<String, String> stateMachine;
|
||||
|
||||
public Mono<Void> processReactive(String orderId) {
|
||||
return Mono.just(orderId)
|
||||
.doOnNext(id -> {
|
||||
// Hidden trigger inside a lambda!
|
||||
stateMachine.sendEvent("REACTIVE_EVENT");
|
||||
})
|
||||
.then();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package click.kamil.examples.statemachine.extended.web;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class AuditInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final StateMachine<String, String> stateMachine;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
stateMachine.sendEvent("AUDIT_EVENT");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package click.kamil.examples.statemachine.extended.web;
|
||||
|
||||
import click.kamil.examples.statemachine.extended.constants.MyEvents;
|
||||
import click.kamil.examples.statemachine.extended.service.OrderService;
|
||||
import click.kamil.examples.statemachine.extended.service.ReactiveOrderService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/orders")
|
||||
@RequiredArgsConstructor
|
||||
public class OrderController {
|
||||
|
||||
private final StateMachine<String, String> stateMachine;
|
||||
private final OrderService orderService;
|
||||
private final ReactiveOrderService reactiveOrderService;
|
||||
|
||||
@PostMapping("/submit")
|
||||
public void submitOrder() {
|
||||
orderService.processSubmit();
|
||||
}
|
||||
|
||||
@PostMapping("/cancel")
|
||||
public void cancelOrder() {
|
||||
orderService.processCancel();
|
||||
}
|
||||
|
||||
@PostMapping("/finish")
|
||||
public void finishOrder() {
|
||||
stateMachine.sendEvent("FINISH");
|
||||
}
|
||||
|
||||
@PostMapping("/resume")
|
||||
public void resumeOrder(String orderId) throws Exception {
|
||||
orderService.resumeOrder(orderId);
|
||||
}
|
||||
|
||||
@PostMapping("/reactive")
|
||||
public Mono<Void> reactiveOrder(String orderId) {
|
||||
return reactiveOrderService.processReactive(orderId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
app.states.initial=PROD_INITIAL
|
||||
@@ -0,0 +1 @@
|
||||
app.states.initial=INIT_STATE
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"methodFqn": "ExternalNotificationService.sendExternalNotification",
|
||||
"event": "EXTERNAL_TRIGGER"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user