another test state machine

This commit is contained in:
2026-06-28 11:57:01 +02:00
parent 16dccbf81b
commit f3d030b19a
3 changed files with 135 additions and 34 deletions

View File

@@ -116,9 +116,23 @@ public class HeuristicEventMatchingEngine implements EventMatchingEngine {
}
private boolean isWildcardVariable(String eventStr) {
return eventStr.equals("event") || eventStr.equals("e") ||
eventStr.equals("msg") || eventStr.equals("message") ||
eventStr.equals("payload");
if (eventStr == null) return false;
if (eventStr.equals("event") || eventStr.equals("e") ||
eventStr.equals("msg") || eventStr.equals("message") ||
eventStr.equals("payload")) {
return true;
}
if (eventStr.contains(".valueOf(") || eventStr.contains("valueOf (")) {
return true;
}
if (eventStr.contains(" ? ") && eventStr.contains(" : ")) {
return true;
}
return false;
}
private String simplify(String name) {

View File

@@ -15,14 +15,48 @@ public class StateMachineController {
this.dispatcher = dispatcher;
}
@PostMapping("/order/pay")
public ResponseEntity<String> payOrder(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.payOrder(userId));
}
@PostMapping("/order/ship")
public ResponseEntity<String> shipOrder(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.shipOrder(userId));
}
@PostMapping("/document/submit")
public ResponseEntity<String> submitDocument(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.submitDocument(userId));
}
@PostMapping("/document/approve")
public ResponseEntity<String> approveDocument(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.approveDocument(userId));
}
@PostMapping("/document/reject")
public ResponseEntity<String> rejectDocument(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.rejectDocument(userId));
}
@PostMapping("/user/verify")
public ResponseEntity<String> verifyUser(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.verifyUser(userId));
}
@PostMapping("/user/suspend")
public ResponseEntity<String> suspendUser(@RequestParam(defaultValue = "system-user") String userId) {
return ResponseEntity.ok(dispatcher.suspendUser(userId));
}
@PostMapping("/{machineType}/transition/{event}")
public ResponseEntity<String> transition(
@PathVariable String machineType,
@PathVariable String event,
@RequestParam(defaultValue = "system-user") String userId) {
try {
String result = dispatcher.dispatch(machineType, event, userId, null);
String result = dispatcher.dispatch(machineType, event);
return ResponseEntity.ok(result);
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());

View File

@@ -1,45 +1,98 @@
package click.kamil.enterprise.web;
import click.kamil.enterprise.core.AbstractStateMachine;
import click.kamil.enterprise.core.EnterpriseEvent;
import click.kamil.enterprise.core.TransitionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import click.kamil.enterprise.machines.order.OrderEvent;
import click.kamil.enterprise.machines.order.OrderState;
import click.kamil.enterprise.machines.document.DocumentEvent;
import click.kamil.enterprise.machines.document.DocumentState;
import click.kamil.enterprise.machines.user.UserEvent;
import click.kamil.enterprise.machines.user.UserState;
@Service
public class StateMachineDispatcher {
private final Map<String, AbstractStateMachine<?, ?>> registry = new HashMap<>();
@Autowired
private StateMachineFactory<OrderState, OrderEvent> orderStateMachineFactory;
@Autowired
public StateMachineDispatcher(List<AbstractStateMachine<?, ?>> machines) {
for (AbstractStateMachine<?, ?> machine : machines) {
registry.put(machine.getMachineType().toUpperCase(), machine);
}
private StateMachineFactory<DocumentState, DocumentEvent> documentStateMachineFactory;
@Autowired
private StateMachineFactory<UserState, UserEvent> userStateMachineFactory;
public String payOrder(String userId) {
StateMachine<OrderState, OrderEvent> machine = orderStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(OrderEvent.PAY);
return "Order paid by " + userId;
}
@SuppressWarnings({"unchecked", "rawtypes"})
public String dispatch(String machineType, String eventString, String userId, Object payload) {
AbstractStateMachine machine = registry.get(machineType.toUpperCase());
if (machine == null) {
throw new IllegalArgumentException("Unknown machine type: " + machineType);
public String shipOrder(String userId) {
StateMachine<OrderState, OrderEvent> machine = orderStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(OrderEvent.SHIP);
return "Order shipped by " + userId;
}
public String submitDocument(String userId) {
StateMachine<DocumentState, DocumentEvent> machine = documentStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(DocumentEvent.SUBMIT);
return "Document submitted by " + userId;
}
public String approveDocument(String userId) {
StateMachine<DocumentState, DocumentEvent> machine = documentStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(DocumentEvent.APPROVE);
return "Document approved by " + userId;
}
public String rejectDocument(String userId) {
StateMachine<DocumentState, DocumentEvent> machine = documentStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(DocumentEvent.REJECT);
return "Document rejected by " + userId;
}
public String verifyUser(String userId) {
StateMachine<UserState, UserEvent> machine = userStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(UserEvent.VERIFY);
return "User verified: " + userId;
}
public String suspendUser(String userId) {
StateMachine<UserState, UserEvent> machine = userStateMachineFactory.getStateMachine();
machine.start();
machine.sendEvent(UserEvent.SUSPEND);
return "User suspended: " + userId;
}
public String dispatch(String machineType, String eventString) {
if ("ORDER".equalsIgnoreCase(machineType)) {
StateMachine<OrderState, OrderEvent> machine = orderStateMachineFactory.getStateMachine();
machine.start();
OrderEvent event = OrderEvent.valueOf(eventString.toUpperCase());
machine.sendEvent(event);
return "Triggered " + event;
} else if ("DOCUMENT".equalsIgnoreCase(machineType)) {
StateMachine<DocumentState, DocumentEvent> machine = documentStateMachineFactory.getStateMachine();
machine.start();
DocumentEvent event = DocumentEvent.valueOf(eventString.toUpperCase());
machine.sendEvent(event);
return "Triggered " + event;
} else if ("USER".equalsIgnoreCase(machineType)) {
StateMachine<UserState, UserEvent> machine = userStateMachineFactory.getStateMachine();
machine.start();
UserEvent event = UserEvent.valueOf(eventString.toUpperCase());
machine.sendEvent(event);
return "Triggered " + event;
}
Class<? extends Enum> eventType = (Class<? extends Enum>) machine.getEventType();
Enum eventEnum;
try {
eventEnum = Enum.valueOf(eventType, eventString.toUpperCase());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid event " + eventString + " for machine " + machineType);
}
TransitionContext<Object> context = new TransitionContext<>(userId, payload);
machine.trigger((EnterpriseEvent) eventEnum, context);
return "Triggered " + eventEnum.name() + " on " + machineType + ". New State: " + machine.getCurrentState().name();
throw new IllegalArgumentException("Unknown machine type: " + machineType);
}
}