From 16dccbf81bf4a531e772f2ce3988f584bec5fc0a Mon Sep 17 00:00:00 2001 From: Kamil Patryk Kozakowski Date: Sun, 28 Jun 2026 11:42:18 +0200 Subject: [PATCH] another test state machine --- run_golden.gradle | 1 + settings.gradle | 1 + .../GoldenUpdater.java | 18 ++++ .../DocumentStateMachineConfiguration.dot | 13 +++ .../DocumentStateMachineConfiguration.json | 89 ++++++++++++++++++ .../DocumentStateMachineConfiguration.png | Bin 0 -> 16317 bytes .../DocumentStateMachineConfiguration.puml | 33 +++++++ ...ocumentStateMachineConfiguration.scxml.xml | 13 +++ .../OrderStateMachineConfiguration.dot | 12 +++ .../OrderStateMachineConfiguration.json | 79 ++++++++++++++++ .../OrderStateMachineConfiguration.png | Bin 0 -> 12203 bytes .../OrderStateMachineConfiguration.puml | 32 +++++++ .../OrderStateMachineConfiguration.scxml.xml | 12 +++ .../UserStateMachineConfiguration.dot | 12 +++ .../UserStateMachineConfiguration.json | 72 ++++++++++++++ .../UserStateMachineConfiguration.png | Bin 0 -> 11785 bytes .../UserStateMachineConfiguration.puml | 32 +++++++ .../UserStateMachineConfiguration.scxml.xml | 12 +++ .../state_machine_enterprise/build.gradle | 30 ++++++ .../EnterpriseStateMachineApplication.java | 11 +++ .../enterprise/core/AbstractStateMachine.java | 50 ++++++++++ .../AbstractStateMachineConfiguration.java | 25 +++++ .../enterprise/core/EnterpriseEvent.java | 5 + .../enterprise/core/EnterpriseState.java | 5 + .../enterprise/core/TransitionContext.java | 17 ++++ .../machines/document/DocumentEvent.java | 7 ++ .../machines/document/DocumentState.java | 7 ++ .../document/DocumentStateMachine.java | 30 ++++++ .../DocumentStateMachineConfiguration.java | 35 +++++++ .../enterprise/machines/order/OrderEvent.java | 7 ++ .../enterprise/machines/order/OrderState.java | 7 ++ .../machines/order/OrderStateMachine.java | 38 ++++++++ .../order/OrderStateMachineConfiguration.java | 33 +++++++ .../enterprise/machines/user/UserEvent.java | 7 ++ .../enterprise/machines/user/UserState.java | 7 ++ .../machines/user/UserStateMachine.java | 29 ++++++ .../user/UserStateMachineConfiguration.java | 32 +++++++ .../web/StateMachineController.java | 31 ++++++ .../web/StateMachineDispatcher.java | 45 +++++++++ 39 files changed, 889 insertions(+) create mode 100644 state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.dot create mode 100644 state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json create mode 100644 state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.png create mode 100644 state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.puml create mode 100644 state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml create mode 100644 state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.dot create mode 100644 state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json create mode 100644 state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.png create mode 100644 state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.puml create mode 100644 state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml create mode 100644 state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.dot create mode 100644 state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json create mode 100644 state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.png create mode 100644 state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.puml create mode 100644 state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml create mode 100644 state_machines/state_machine_enterprise/build.gradle create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/EnterpriseStateMachineApplication.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachine.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachineConfiguration.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseEvent.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseState.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/TransitionContext.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentEvent.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentState.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachine.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachineConfiguration.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderEvent.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderState.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachine.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachineConfiguration.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserEvent.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserState.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachine.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachineConfiguration.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineController.java create mode 100644 state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java diff --git a/run_golden.gradle b/run_golden.gradle index 6363a67..41f1735 100644 --- a/run_golden.gradle +++ b/run_golden.gradle @@ -1,4 +1,5 @@ task runGolden(type: JavaExec) { mainClass = "click.kamil.springstatemachineexporter.GoldenUpdater" classpath = sourceSets.test.runtimeClasspath + workingDir = rootProject.projectDir } diff --git a/settings.gradle b/settings.gradle index 7bf430a..212252e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,3 +19,4 @@ include ':state_machines:ultimate_ecosystem_sm' include ':state_machines:enterprise_order_system' include ':state_machines:multi_module_sample:api-module' include ':state_machines:multi_module_sample:core-module' +include ':state_machines:state_machine_enterprise' diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/GoldenUpdater.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/GoldenUpdater.java index f789b06..2cb3a9b 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/GoldenUpdater.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/GoldenUpdater.java @@ -158,6 +158,24 @@ public class GoldenUpdater { Path.of("state_machines/inheritance_extra_functions3_state_machine"), Path.of("src/test/resources/golden/G2StateMachineConfiguration"), "G2StateMachineConfiguration" + ), + new TestScenario( + "Enterprise Order State Machine", + Path.of("state_machines/state_machine_enterprise"), + Path.of("src/test/resources/golden/OrderStateMachineConfiguration"), + "OrderStateMachineConfiguration" + ), + new TestScenario( + "Enterprise Document State Machine", + Path.of("state_machines/state_machine_enterprise"), + Path.of("src/test/resources/golden/DocumentStateMachineConfiguration"), + "DocumentStateMachineConfiguration" + ), + new TestScenario( + "Enterprise User State Machine", + Path.of("state_machines/state_machine_enterprise"), + Path.of("src/test/resources/golden/UserStateMachineConfiguration"), + "UserStateMachineConfiguration" ) ); } diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.dot b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.dot new file mode 100644 index 0000000..17ae9cf --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.dot @@ -0,0 +1,13 @@ +digraph statemachine { + rankdir=LR; + node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"]; + edge [fontname="Arial", fontsize=10]; + + _start [shape=circle, label="", fillcolor=black, width=0.1]; + _start -> DRAFT; + APPROVED [fillcolor=lightgray]; + DRAFT -> IN_REVIEW [label="DocumentEvent.SUBMIT", style="solid", color="black"]; + IN_REVIEW -> APPROVED [label="DocumentEvent.APPROVE", style="solid", color="black"]; + IN_REVIEW -> DRAFT [label="DocumentEvent.REJECT", style="solid", color="black"]; +} + diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json new file mode 100644 index 0000000..cdf9499 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json @@ -0,0 +1,89 @@ +{ + "metadata" : { + "triggers" : [ ], + "entryPoints" : [ { + "type" : "REST", + "name" : "POST /api/machine/{machineType}/transition/{event}", + "className" : "click.kamil.enterprise.web.StateMachineController", + "methodName" : "transition", + "sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java", + "metadata" : { + "path" : "/api/machine/{machineType}/transition/{event}", + "verb" : "POST" + }, + "parameters" : [ { + "name" : "machineType", + "type" : "String", + "annotations" : [ "PathVariable" ] + }, { + "name" : "event", + "type" : "String", + "annotations" : [ "PathVariable" ] + }, { + "name" : "userId", + "type" : "String", + "annotations" : [ "RequestParam" ] + } ] + } ], + "callChains" : [ ], + "properties" : { + "default" : { } + } + }, + "name" : "click.kamil.enterprise.machines.document.DocumentStateMachineConfiguration", + "renderChoicesAsDiamonds" : true, + "startStates" : [ "DocumentState.DRAFT" ], + "transitions" : [ { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "DocumentState.DRAFT", + "fullIdentifier" : "DocumentState.DRAFT" + } ], + "targetStates" : [ { + "rawName" : "DocumentState.IN_REVIEW", + "fullIdentifier" : "DocumentState.IN_REVIEW" + } ], + "event" : { + "rawName" : "DocumentEvent.SUBMIT", + "fullIdentifier" : "DocumentEvent.SUBMIT" + }, + "guard" : null, + "actions" : [ ], + "order" : null + }, { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "DocumentState.IN_REVIEW", + "fullIdentifier" : "DocumentState.IN_REVIEW" + } ], + "targetStates" : [ { + "rawName" : "DocumentState.APPROVED", + "fullIdentifier" : "DocumentState.APPROVED" + } ], + "event" : { + "rawName" : "DocumentEvent.APPROVE", + "fullIdentifier" : "DocumentEvent.APPROVE" + }, + "guard" : null, + "actions" : [ ], + "order" : null + }, { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "DocumentState.IN_REVIEW", + "fullIdentifier" : "DocumentState.IN_REVIEW" + } ], + "targetStates" : [ { + "rawName" : "DocumentState.DRAFT", + "fullIdentifier" : "DocumentState.DRAFT" + } ], + "event" : { + "rawName" : "DocumentEvent.REJECT", + "fullIdentifier" : "DocumentEvent.REJECT" + }, + "guard" : null, + "actions" : [ ], + "order" : null + } ], + "endStates" : [ "DocumentState.APPROVED" ] +} diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.png b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..f6db9f26abdc4db699c668273d7d026b20631a8f GIT binary patch literal 16317 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 DocumentState.DRAFT + + +DocumentState.DRAFT -[#1E90FF,bold]-> DocumentState.IN_REVIEW <> : DocumentEvent.SUBMIT +DocumentState.IN_REVIEW -[#1E90FF,bold]-> DocumentState.APPROVED <> : DocumentEvent.APPROVE +DocumentState.IN_REVIEW -[#1E90FF,bold]-> DocumentState.DRAFT <> : DocumentEvent.REJECT + +DocumentState.APPROVED --> [*] +@enduml + diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml new file mode 100644 index 0000000..c71ad83 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.dot b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.dot new file mode 100644 index 0000000..61d8ad4 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.dot @@ -0,0 +1,12 @@ +digraph statemachine { + rankdir=LR; + node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"]; + edge [fontname="Arial", fontsize=10]; + + _start [shape=circle, label="", fillcolor=black, width=0.1]; + _start -> NEW; + SHIPPED [fillcolor=lightgray]; + NEW -> PENDING [label="OrderEvent.PAY / λ", style="solid", color="black"]; + PENDING -> SHIPPED [label="OrderEvent.SHIP", style="solid", color="black"]; +} + diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json new file mode 100644 index 0000000..d911922 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json @@ -0,0 +1,79 @@ +{ + "metadata" : { + "triggers" : [ ], + "entryPoints" : [ { + "type" : "REST", + "name" : "POST /api/machine/{machineType}/transition/{event}", + "className" : "click.kamil.enterprise.web.StateMachineController", + "methodName" : "transition", + "sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java", + "metadata" : { + "path" : "/api/machine/{machineType}/transition/{event}", + "verb" : "POST" + }, + "parameters" : [ { + "name" : "machineType", + "type" : "String", + "annotations" : [ "PathVariable" ] + }, { + "name" : "event", + "type" : "String", + "annotations" : [ "PathVariable" ] + }, { + "name" : "userId", + "type" : "String", + "annotations" : [ "RequestParam" ] + } ] + } ], + "callChains" : [ ], + "properties" : { + "default" : { } + } + }, + "name" : "click.kamil.enterprise.machines.order.OrderStateMachineConfiguration", + "renderChoicesAsDiamonds" : true, + "startStates" : [ "OrderState.NEW" ], + "transitions" : [ { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "OrderState.NEW", + "fullIdentifier" : "OrderState.NEW" + } ], + "targetStates" : [ { + "rawName" : "OrderState.PENDING", + "fullIdentifier" : "OrderState.PENDING" + } ], + "event" : { + "rawName" : "OrderEvent.PAY", + "fullIdentifier" : "OrderEvent.PAY" + }, + "guard" : null, + "actions" : [ { + "expression" : "context -> System.out.println(\"Payment processed.\")", + "isLambda" : true, + "internalLogic" : "context -> System.out.println(\"Payment processed.\")", + "lineNumber" : 28, + "className" : "click.kamil.enterprise.machines.order.OrderStateMachineConfiguration", + "sourceFile" : "src/main/java/click/kamil/enterprise/machines/order/OrderStateMachineConfiguration.java" + } ], + "order" : null + }, { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "OrderState.PENDING", + "fullIdentifier" : "OrderState.PENDING" + } ], + "targetStates" : [ { + "rawName" : "OrderState.SHIPPED", + "fullIdentifier" : "OrderState.SHIPPED" + } ], + "event" : { + "rawName" : "OrderEvent.SHIP", + "fullIdentifier" : "OrderEvent.SHIP" + }, + "guard" : null, + "actions" : [ ], + "order" : null + } ], + "endStates" : [ "OrderState.SHIPPED" ] +} diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.png b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..82cd2dab8f18c65dc31aa699b994534016c17f7f GIT binary patch literal 12203 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 OrderState.NEW + + +OrderState.NEW -[#1E90FF,bold]-> OrderState.PENDING <> : OrderEvent.PAY / λ +OrderState.PENDING -[#1E90FF,bold]-> OrderState.SHIPPED <> : OrderEvent.SHIP + +OrderState.SHIPPED --> [*] +@enduml + diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml new file mode 100644 index 0000000..e05c8a3 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.dot b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.dot new file mode 100644 index 0000000..4f1a746 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.dot @@ -0,0 +1,12 @@ +digraph statemachine { + rankdir=LR; + node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"]; + edge [fontname="Arial", fontsize=10]; + + _start [shape=circle, label="", fillcolor=black, width=0.1]; + _start -> GUEST; + VERIFIED [fillcolor=lightgray]; + GUEST -> REGISTERED [label="UserEvent.REGISTER", style="solid", color="black"]; + REGISTERED -> VERIFIED [label="UserEvent.VERIFY", style="solid", color="black"]; +} + diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json new file mode 100644 index 0000000..6f04727 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json @@ -0,0 +1,72 @@ +{ + "metadata" : { + "triggers" : [ ], + "entryPoints" : [ { + "type" : "REST", + "name" : "POST /api/machine/{machineType}/transition/{event}", + "className" : "click.kamil.enterprise.web.StateMachineController", + "methodName" : "transition", + "sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java", + "metadata" : { + "path" : "/api/machine/{machineType}/transition/{event}", + "verb" : "POST" + }, + "parameters" : [ { + "name" : "machineType", + "type" : "String", + "annotations" : [ "PathVariable" ] + }, { + "name" : "event", + "type" : "String", + "annotations" : [ "PathVariable" ] + }, { + "name" : "userId", + "type" : "String", + "annotations" : [ "RequestParam" ] + } ] + } ], + "callChains" : [ ], + "properties" : { + "default" : { } + } + }, + "name" : "click.kamil.enterprise.machines.user.UserStateMachineConfiguration", + "renderChoicesAsDiamonds" : true, + "startStates" : [ "UserState.GUEST" ], + "transitions" : [ { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "UserState.GUEST", + "fullIdentifier" : "UserState.GUEST" + } ], + "targetStates" : [ { + "rawName" : "UserState.REGISTERED", + "fullIdentifier" : "UserState.REGISTERED" + } ], + "event" : { + "rawName" : "UserEvent.REGISTER", + "fullIdentifier" : "UserEvent.REGISTER" + }, + "guard" : null, + "actions" : [ ], + "order" : null + }, { + "type" : "EXTERNAL", + "sourceStates" : [ { + "rawName" : "UserState.REGISTERED", + "fullIdentifier" : "UserState.REGISTERED" + } ], + "targetStates" : [ { + "rawName" : "UserState.VERIFIED", + "fullIdentifier" : "UserState.VERIFIED" + } ], + "event" : { + "rawName" : "UserEvent.VERIFY", + "fullIdentifier" : "UserEvent.VERIFY" + }, + "guard" : null, + "actions" : [ ], + "order" : null + } ], + "endStates" : [ "UserState.VERIFIED" ] +} diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.png b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..2231de8695cdad8c6a14cec2f3ec4fc42dec8344 GIT binary patch literal 11785 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

`J5Pez|E6Nz(R3#ihAIZEk7~(G8&5 zZH6-Z4xU1%L(J1WwMIiu_U5d#eu6B8|Agt+ho&z^2a$JXjwbZoLz|dlAXejwWP~*H z{nL(82JPw2y%sM{vnZo65$sw;vLkGXgJ6o{K!e2OW_^e|1Oc!cxVjM^!WkVbD~l19 zNNIFlULL7|$K%+_&_5nxm-{{}_{x~k0pDdK=sd7v!$i*m-;&n;nXPOwYGYCpyuvIY z4S+UY2@GHlWWTk0Dh`a-G~j-}GfGcdIa<4w;nLJD1tN)34rT^#uH$F zBRyho4#K=g3p9geK1b{VZF+0!yZG%#hp$WqQmF=X;BT<-9Aels^VYND^p_qPg9vk@ zSjc%xDzV_1S+DG?k%v*g(<|@rccu%mLgKvB%}0tK7iVW5kz{JyN;ry>I8w~w#i ztetNdesPBIJE6i#n#(<^==54ev`vAMM?_%|* zV4;kl;**_Jo8Hm#&*SXT=YW1|uM~ z(Y*M?aT7=10>3_d;lOn^>}=0+@UX!tbXMa`$Xewu9UP(6HuTu(UHy3mi-K%s=5j|c zX^V;*0zY3jkVX_|`Zja_{I@`+Ca;^IBZji=h3an7zimKbcEk5z1LYr1>UJ-Da=A7Z zVpr%9(%iN<7UeaJ)|OPWksiJ^hWH0p9g;3nlrBTn+Y2tysC@xRJ!|0F|9!VZ+pwNj zypD9`kh<^s1$5+%>+AjVO?$noJ=JXg3JwDFPt;lrWdL#jBLCv{x~l43d=nK492bXG zLZVpLBmdQfCLbIUj0A`gm<9}SlnwgIS=S6{v17hy;%rMdEdiR=S z^T)N(=?tr@!pAGc2vDW;fX@afM>n~$lw7xCY;t-$=u?{nz)k$<(Nl9_jp%ibwg`6` zXrd|IF>P69W=cblJ;{2(Y?(Vb)c?I{ceK5AyRnfGlXCJ~AclnDhb!GN!6KFt@DD1GHbJ`;EmFg6GuP}9^&J3YvhIV zQ`~2U>JeBLzL1ts#v{w``=}v>Y;^~X9H8MKbxgwXeYufz!oCmPUZF-l-SeGMNgJ(T zx^y`1|SC$wwHuMV6K3)RO z^p8|okx{cM7CPvXQm*@-4Yfi>-X>0s@2_rc2mR}JDgO3K-kSkqWmH&_h9Bu|MR0uW zw1Q;<98)+@8tv9d3FMk}qdQhj8p{Yo1i6Br1sd19ir;2B+Uy-@-&<-627uN3e_a9~ z_dYJ!hbo>eu6IAOLMFts72;ys*Z=)b0F347R23Y@c_TC@K=UJDWX}wPVdyoRne%HU zJaAo(G!>i>1zgMwH~?j>zY`0v+vcn*c{gK-N&EbQ;<+k*)w|HIok=iyF|kIlo^s0{ z?FgDyyJHI9*SP>?`5U+YZv)ZK4z8v(y^r6i3)QILJErWYgx~jF zF=TQos-5nNJf`AB97Wd1SVY{xYwc3~VxYP~FO0D<%~^IMtNG1MjjDM8n!0x%-~s(sKLX|5~9Wy&H4zkBnY zsY@4*11N62X-_O5VISvy9fKw)L0nv1hA&_kUsCkC?O4)^vVa;K3?gI(W4*7jtxImn zG1(QPqWZSsx30Q|Mzr UserState.GUEST + + +UserState.GUEST -[#1E90FF,bold]-> UserState.REGISTERED <> : UserEvent.REGISTER +UserState.REGISTERED -[#1E90FF,bold]-> UserState.VERIFIED <> : UserEvent.VERIFY + +UserState.VERIFIED --> [*] +@enduml + diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml new file mode 100644 index 0000000..b70b364 --- /dev/null +++ b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/state_machines/state_machine_enterprise/build.gradle b/state_machines/state_machine_enterprise/build.gradle new file mode 100644 index 0000000..9772ac9 --- /dev/null +++ b/state_machines/state_machine_enterprise/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.5.3' + id 'io.spring.dependency-management' version '1.1.7' +} + +group = 'click.kamil' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.statemachine:spring-statemachine-starter:3.2.0' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} + +bootJar { enabled = false } +jar { enabled = true } diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/EnterpriseStateMachineApplication.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/EnterpriseStateMachineApplication.java new file mode 100644 index 0000000..7dec8e6 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/EnterpriseStateMachineApplication.java @@ -0,0 +1,11 @@ +package click.kamil.enterprise; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class EnterpriseStateMachineApplication { + public static void main(String[] args) { + SpringApplication.run(EnterpriseStateMachineApplication.class, args); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachine.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachine.java new file mode 100644 index 0000000..0668791 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachine.java @@ -0,0 +1,50 @@ +package click.kamil.enterprise.core; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class AbstractStateMachine & EnterpriseState, E extends Enum & EnterpriseEvent> { + + private S currentState; + private final Map transitions = new ConcurrentHashMap<>(); + + protected AbstractStateMachine(S initialState) { + this.currentState = initialState; + configureTransitions(); + } + + public abstract String getMachineType(); + + protected abstract void configureTransitions(); + + protected void addTransition(E event, S targetState) { + transitions.put(event, targetState); + } + + public synchronized void trigger(E event, TransitionContext context) { + S target = transitions.get(event); + if (target == null) { + throw new IllegalStateException("Invalid event " + event + " for state " + currentState); + } + + executePreChecks(currentState, target, context); + S oldState = currentState; + currentState = target; + onTransition(oldState, currentState, event, context); + } + + protected void executePreChecks(S from, S to, TransitionContext context) { + // Parent checking logic + System.out.println("[Abstract] Executing pre-checks from " + from.name() + " to " + to.name() + " by user " + context.getUserId()); + } + + protected abstract void onTransition(S from, S to, E event, TransitionContext context); + + public S getCurrentState() { + return currentState; + } + + public Class getEventType() { + return (Class) transitions.keySet().iterator().next().getClass(); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachineConfiguration.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachineConfiguration.java new file mode 100644 index 0000000..af44378 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/AbstractStateMachineConfiguration.java @@ -0,0 +1,25 @@ +package click.kamil.enterprise.core; + +import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; + +public abstract class AbstractStateMachineConfiguration & EnterpriseState, E extends Enum & EnterpriseEvent> extends EnumStateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + configureStates(states); + } + + @Override + public void configure(StateMachineTransitionConfigurer transitions) throws Exception { + configureTransitions(transitions); + } + + protected abstract void configureStates(StateMachineStateConfigurer states) throws Exception; + protected abstract void configureTransitions(StateMachineTransitionConfigurer transitions) throws Exception; + + protected void commonProtectedMethod() { + System.out.println("Common protected method called in AbstractStateMachineConfiguration."); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseEvent.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseEvent.java new file mode 100644 index 0000000..9e9a9f3 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseEvent.java @@ -0,0 +1,5 @@ +package click.kamil.enterprise.core; + +public interface EnterpriseEvent { + String name(); +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseState.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseState.java new file mode 100644 index 0000000..8d88dc7 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/EnterpriseState.java @@ -0,0 +1,5 @@ +package click.kamil.enterprise.core; + +public interface EnterpriseState { + String name(); +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/TransitionContext.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/TransitionContext.java new file mode 100644 index 0000000..9dbb78e --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/core/TransitionContext.java @@ -0,0 +1,17 @@ +package click.kamil.enterprise.core; + +import lombok.Data; +import java.time.Instant; + +@Data +public class TransitionContext { + private final String userId; + private final Instant timestamp; + private final T payload; + + public TransitionContext(String userId, T payload) { + this.userId = userId; + this.timestamp = Instant.now(); + this.payload = payload; + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentEvent.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentEvent.java new file mode 100644 index 0000000..8bdeb08 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentEvent.java @@ -0,0 +1,7 @@ +package click.kamil.enterprise.machines.document; + +import click.kamil.enterprise.core.EnterpriseEvent; + +public enum DocumentEvent implements EnterpriseEvent { + SUBMIT, APPROVE, REJECT; +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentState.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentState.java new file mode 100644 index 0000000..6f5865f --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentState.java @@ -0,0 +1,7 @@ +package click.kamil.enterprise.machines.document; + +import click.kamil.enterprise.core.EnterpriseState; + +public enum DocumentState implements EnterpriseState { + DRAFT, IN_REVIEW, APPROVED; +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachine.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachine.java new file mode 100644 index 0000000..3af338b --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachine.java @@ -0,0 +1,30 @@ +package click.kamil.enterprise.machines.document; + +import click.kamil.enterprise.core.AbstractStateMachine; +import click.kamil.enterprise.core.TransitionContext; +import org.springframework.stereotype.Component; + +@Component +public class DocumentStateMachine extends AbstractStateMachine { + + public DocumentStateMachine() { + super(DocumentState.DRAFT); + } + + @Override + public String getMachineType() { + return "DOCUMENT"; + } + + @Override + protected void configureTransitions() { + addTransition(DocumentEvent.SUBMIT, DocumentState.IN_REVIEW); + addTransition(DocumentEvent.APPROVE, DocumentState.APPROVED); + addTransition(DocumentEvent.REJECT, DocumentState.DRAFT); + } + + @Override + protected void onTransition(DocumentState from, DocumentState to, DocumentEvent event, TransitionContext context) { + System.out.println("[Document] Document modified by " + context.getUserId() + ". Now " + to); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachineConfiguration.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachineConfiguration.java new file mode 100644 index 0000000..686f780 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/document/DocumentStateMachineConfiguration.java @@ -0,0 +1,35 @@ +package click.kamil.enterprise.machines.document; + +import click.kamil.enterprise.core.AbstractStateMachineConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.config.EnableStateMachineFactory; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; + +@Configuration +@EnableStateMachineFactory(name = "documentStateMachineFactory") +public class DocumentStateMachineConfiguration extends AbstractStateMachineConfiguration { + + @Override + protected void configureStates(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial(DocumentState.DRAFT) + .state(DocumentState.IN_REVIEW) + .end(DocumentState.APPROVED); + } + + @Override + protected void configureTransitions(StateMachineTransitionConfigurer transitions) throws Exception { + commonProtectedMethod(); + transitions + .withExternal() + .source(DocumentState.DRAFT).target(DocumentState.IN_REVIEW).event(DocumentEvent.SUBMIT) + .and() + .withExternal() + .source(DocumentState.IN_REVIEW).target(DocumentState.APPROVED).event(DocumentEvent.APPROVE) + .and() + .withExternal() + .source(DocumentState.IN_REVIEW).target(DocumentState.DRAFT).event(DocumentEvent.REJECT); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderEvent.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderEvent.java new file mode 100644 index 0000000..21fdec6 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderEvent.java @@ -0,0 +1,7 @@ +package click.kamil.enterprise.machines.order; + +import click.kamil.enterprise.core.EnterpriseEvent; + +public enum OrderEvent implements EnterpriseEvent { + PAY, SHIP; +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderState.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderState.java new file mode 100644 index 0000000..b46448a --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderState.java @@ -0,0 +1,7 @@ +package click.kamil.enterprise.machines.order; + +import click.kamil.enterprise.core.EnterpriseState; + +public enum OrderState implements EnterpriseState { + NEW, PENDING, SHIPPED; +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachine.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachine.java new file mode 100644 index 0000000..1b25fac --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachine.java @@ -0,0 +1,38 @@ +package click.kamil.enterprise.machines.order; + +import click.kamil.enterprise.core.AbstractStateMachine; +import click.kamil.enterprise.core.TransitionContext; +import org.springframework.stereotype.Component; + +@Component +public class OrderStateMachine extends AbstractStateMachine { + + public OrderStateMachine() { + super(OrderState.NEW); + } + + @Override + public String getMachineType() { + return "ORDER"; + } + + @Override + protected void configureTransitions() { + addTransition(OrderEvent.PAY, OrderState.PENDING); + addTransition(OrderEvent.SHIP, OrderState.SHIPPED); + } + + @Override + protected void executePreChecks(OrderState from, OrderState to, TransitionContext context) { + super.executePreChecks(from, to, context); + if (to == OrderState.SHIPPED && from != OrderState.PENDING) { + throw new IllegalStateException("Must be PENDING to ship!"); + } + System.out.println("[Order] Specific pre-checks passed for order."); + } + + @Override + protected void onTransition(OrderState from, OrderState to, OrderEvent event, TransitionContext context) { + System.out.println("[Order] Transitioned from " + from + " to " + to + " via " + event); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachineConfiguration.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachineConfiguration.java new file mode 100644 index 0000000..54781c8 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/order/OrderStateMachineConfiguration.java @@ -0,0 +1,33 @@ +package click.kamil.enterprise.machines.order; + +import click.kamil.enterprise.core.AbstractStateMachineConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.config.EnableStateMachineFactory; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; + +@Configuration +@EnableStateMachineFactory(name = "orderStateMachineFactory") +public class OrderStateMachineConfiguration extends AbstractStateMachineConfiguration { + + @Override + protected void configureStates(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial(OrderState.NEW) + .state(OrderState.PENDING) + .end(OrderState.SHIPPED); + } + + @Override + protected void configureTransitions(StateMachineTransitionConfigurer transitions) throws Exception { + commonProtectedMethod(); + transitions + .withExternal() + .source(OrderState.NEW).target(OrderState.PENDING).event(OrderEvent.PAY) + .action(context -> System.out.println("Payment processed.")) + .and() + .withExternal() + .source(OrderState.PENDING).target(OrderState.SHIPPED).event(OrderEvent.SHIP); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserEvent.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserEvent.java new file mode 100644 index 0000000..72849ec --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserEvent.java @@ -0,0 +1,7 @@ +package click.kamil.enterprise.machines.user; + +import click.kamil.enterprise.core.EnterpriseEvent; + +public enum UserEvent implements EnterpriseEvent { + REGISTER, VERIFY; +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserState.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserState.java new file mode 100644 index 0000000..dd601f7 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserState.java @@ -0,0 +1,7 @@ +package click.kamil.enterprise.machines.user; + +import click.kamil.enterprise.core.EnterpriseState; + +public enum UserState implements EnterpriseState { + GUEST, REGISTERED, VERIFIED; +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachine.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachine.java new file mode 100644 index 0000000..9719088 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachine.java @@ -0,0 +1,29 @@ +package click.kamil.enterprise.machines.user; + +import click.kamil.enterprise.core.AbstractStateMachine; +import click.kamil.enterprise.core.TransitionContext; +import org.springframework.stereotype.Component; + +@Component +public class UserStateMachine extends AbstractStateMachine { + + public UserStateMachine() { + super(UserState.GUEST); + } + + @Override + public String getMachineType() { + return "USER"; + } + + @Override + protected void configureTransitions() { + addTransition(UserEvent.REGISTER, UserState.REGISTERED); + addTransition(UserEvent.VERIFY, UserState.VERIFIED); + } + + @Override + protected void onTransition(UserState from, UserState to, UserEvent event, TransitionContext context) { + System.out.println("[User] " + context.getUserId() + " is now " + to); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachineConfiguration.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachineConfiguration.java new file mode 100644 index 0000000..b0747d9 --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/machines/user/UserStateMachineConfiguration.java @@ -0,0 +1,32 @@ +package click.kamil.enterprise.machines.user; + +import click.kamil.enterprise.core.AbstractStateMachineConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.config.EnableStateMachineFactory; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; + +@Configuration +@EnableStateMachineFactory(name = "userStateMachineFactory") +public class UserStateMachineConfiguration extends AbstractStateMachineConfiguration { + + @Override + protected void configureStates(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial(UserState.GUEST) + .state(UserState.REGISTERED) + .end(UserState.VERIFIED); + } + + @Override + protected void configureTransitions(StateMachineTransitionConfigurer transitions) throws Exception { + commonProtectedMethod(); + transitions + .withExternal() + .source(UserState.GUEST).target(UserState.REGISTERED).event(UserEvent.REGISTER) + .and() + .withExternal() + .source(UserState.REGISTERED).target(UserState.VERIFIED).event(UserEvent.VERIFY); + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineController.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineController.java new file mode 100644 index 0000000..4b8e5bb --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineController.java @@ -0,0 +1,31 @@ +package click.kamil.enterprise.web; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/machine") +public class StateMachineController { + + private final StateMachineDispatcher dispatcher; + + @Autowired + public StateMachineController(StateMachineDispatcher dispatcher) { + this.dispatcher = dispatcher; + } + + @PostMapping("/{machineType}/transition/{event}") + public ResponseEntity transition( + @PathVariable String machineType, + @PathVariable String event, + @RequestParam(defaultValue = "system-user") String userId) { + + try { + String result = dispatcher.dispatch(machineType, event, userId, null); + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } +} diff --git a/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java new file mode 100644 index 0000000..992f46b --- /dev/null +++ b/state_machines/state_machine_enterprise/src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java @@ -0,0 +1,45 @@ +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.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class StateMachineDispatcher { + + private final Map> registry = new HashMap<>(); + + @Autowired + public StateMachineDispatcher(List> machines) { + for (AbstractStateMachine machine : machines) { + registry.put(machine.getMachineType().toUpperCase(), machine); + } + } + + @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); + } + + Class eventType = (Class) machine.getEventType(); + Enum eventEnum; + try { + eventEnum = Enum.valueOf(eventType, eventString.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid event " + eventString + " for machine " + machineType); + } + + TransitionContext context = new TransitionContext<>(userId, payload); + machine.trigger((EnterpriseEvent) eventEnum, context); + + return "Triggered " + eventEnum.name() + " on " + machineType + ". New State: " + machine.getCurrentState().name(); + } +}