From e0729766ddfe076b96961b243d3207ce4318fb7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E4=B9=9F?= Date: Thu, 15 Sep 2022 13:52:03 +0800 Subject: [PATCH 1/5] =?UTF-8?q?[FEATURE]:[=E7=BB=99=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=E6=8F=90=E4=BE=9B=E4=B8=80=E4=BA=9B=E6=96=B0=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=8E=A5=E5=8F=A3]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 增加com.alibaba.cola.statemachine.StateMachine#verify方法 用来判断当前状态能否响应某个事件 2. 增加com.alibaba.cola.statemachine.builder.StateMachineBuilder#setFailoverCallback 用来增加在状态流转没有命中当前配置的规则时执行的回调 接口定义 com.alibaba.cola.statemachine.builder.FailoverCallback 默认为NumbFailoverCallbackImpl,与当前行为一样,什么都不做。 另外内置AlertFailoverCallbackImpl,用于抛出异常TransitionFailoverException --- .../cola-component-statemachine/pom.xml | 1 + .../cola/statemachine/StateMachine.java | 8 + .../builder/AlertFailoverCallbackImpl.java | 18 ++ .../builder/FailoverCallback.java | 18 ++ .../builder/NumbFailoverCallbackImpl.java | 15 ++ .../builder/StateMachineBuilder.java | 12 +- .../builder/StateMachineBuilderImpl.java | 15 +- .../TransitionFailoverException.java | 12 ++ .../statemachine/impl/StateMachineImpl.java | 25 ++- .../alibaba/cola/test/StateMachineTest.java | 156 +++++++++++------- 10 files changed, 215 insertions(+), 65 deletions(-) create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java diff --git a/cola-components/cola-component-statemachine/pom.xml b/cola-components/cola-component-statemachine/pom.xml index 80ab78521..0a174b47d 100644 --- a/cola-components/cola-component-statemachine/pom.xml +++ b/cola-components/cola-component-statemachine/pom.xml @@ -8,6 +8,7 @@ cola-component-statemachine + 4.4.1-SNAPSHOT jar ${project.artifactId} ${project.artifactId} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java index e99102f84..0e743a0d0 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java @@ -12,6 +12,14 @@ */ public interface StateMachine extends Visitable{ + /** + * Verify if an event {@code E} can be fired from current state {@code S} + * @param sourceStateId + * @param event + * @return + */ + boolean verify(S sourceStateId,E event); + /** * Send an event {@code E} to the state machine. * diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java new file mode 100644 index 000000000..260c11ec8 --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java @@ -0,0 +1,18 @@ +package com.alibaba.cola.statemachine.builder; + +import com.alibaba.cola.statemachine.exception.TransitionFailoverException; + +/** + * Default failover callback, do nothing. + * + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +public class AlertFailoverCallbackImpl implements FailoverCallback { + + @Override + public void onFailover(S sourceState, E event, C context) { + throw new TransitionFailoverException( + "Cannot fire event [" + event + "] on current state [" + sourceState + "] with context [" + context + "]"); + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java new file mode 100644 index 000000000..afa5b4784 --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java @@ -0,0 +1,18 @@ +package com.alibaba.cola.statemachine.builder; + +/** + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +@FunctionalInterface +public interface FailoverCallback { + + /** + * Callback function to execute on failover + * + * @param sourceState + * @param event + * @param context + */ + void onFailover(S sourceState, E event, C context); +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java new file mode 100644 index 000000000..3abc1f3fd --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java @@ -0,0 +1,15 @@ +package com.alibaba.cola.statemachine.builder; + +/** + * Default failover callback, do nothing. + * + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +public class NumbFailoverCallbackImpl implements FailoverCallback { + + @Override + public void onFailover(S sourceState, E event, C context) { + //do nothing + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java index 029433e0c..ca910cf39 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java @@ -11,22 +11,32 @@ public interface StateMachineBuilder { /** * Builder for one transition + * * @return External transition builder */ ExternalTransitionBuilder externalTransition(); /** * Builder for multiple transitions + * * @return External transition builder */ ExternalTransitionsBuilder externalTransitions(); /** * Start to build internal transition + * * @return Internal transition builder */ InternalTransitionBuilder internalTransition(); - StateMachine build(String machineId); + /** + * set up failover callback, default do nothing {@code NumbFailoverCallbackImpl} + * + * @param callback + */ + void setFailoverCallback(FailoverCallback callback); + + StateMachine build(String machineId); } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java index 497cb9e3c..07e576766 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java @@ -1,14 +1,14 @@ package com.alibaba.cola.statemachine.builder; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import com.alibaba.cola.statemachine.State; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.StateMachineFactory; import com.alibaba.cola.statemachine.impl.StateMachineImpl; import com.alibaba.cola.statemachine.impl.TransitionType; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - /** * StateMachineBuilderImpl * @@ -20,8 +20,9 @@ public class StateMachineBuilderImpl implements StateMachineBuilder> stateMap = new ConcurrentHashMap<>(); + private final Map> stateMap = new ConcurrentHashMap<>(); private final StateMachineImpl stateMachine = new StateMachineImpl<>(stateMap); + private FailoverCallback failoverCallback = new NumbFailoverCallbackImpl<>(); @Override public ExternalTransitionBuilder externalTransition() { @@ -38,10 +39,16 @@ public InternalTransitionBuilder internalTransition() { return new TransitionBuilderImpl<>(stateMap, TransitionType.INTERNAL); } + @Override + public void setFailoverCallback(FailoverCallback callback) { + this.failoverCallback = callback; + } + @Override public StateMachine build(String machineId) { stateMachine.setMachineId(machineId); stateMachine.setReady(true); + stateMachine.setFailoverCallback(failoverCallback); StateMachineFactory.register(stateMachine); return stateMachine; } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java new file mode 100644 index 000000000..bf3f01bcf --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java @@ -0,0 +1,12 @@ +package com.alibaba.cola.statemachine.exception; + +/** + * @author 龙也 + * @date 2022/9/15 12:08 PM + */ +public class TransitionFailoverException extends RuntimeException { + + public TransitionFailoverException(String errMsg) { + super(errMsg); + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java index f36fa83d3..ca09a7cab 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java @@ -1,12 +1,13 @@ package com.alibaba.cola.statemachine.impl; +import java.util.List; +import java.util.Map; + import com.alibaba.cola.statemachine.State; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.Transition; import com.alibaba.cola.statemachine.Visitor; - -import java.util.List; -import java.util.Map; +import com.alibaba.cola.statemachine.builder.FailoverCallback; /** * For performance consideration, @@ -26,10 +27,23 @@ public class StateMachineImpl implements StateMachine { private boolean ready; + private FailoverCallback failoverCallback; + public StateMachineImpl(Map> stateMap) { this.stateMap = stateMap; } + @Override + public boolean verify(S sourceStateId, E event) { + isReady(); + + State sourceState = getState(sourceStateId); + + List> transitions = sourceState.getEventTransitions(event); + + return transitions != null && transitions.size() != 0; + } + @Override public S fireEvent(S sourceStateId, E event, C ctx) { isReady(); @@ -37,6 +51,7 @@ public S fireEvent(S sourceStateId, E event, C ctx) { if (transition == null) { Debugger.debug("There is no Transition for " + event); + failoverCallback.onFailover(sourceStateId, event, ctx); return sourceStateId; } @@ -115,4 +130,8 @@ public void setMachineId(String machineId) { public void setReady(boolean ready) { this.ready = ready; } + + public void setFailoverCallback(FailoverCallback failoverCallback) { + this.failoverCallback = failoverCallback; + } } diff --git a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java index 8959345a5..270f34958 100644 --- a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java +++ b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java @@ -4,8 +4,11 @@ import com.alibaba.cola.statemachine.Condition; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.StateMachineFactory; +import com.alibaba.cola.statemachine.builder.AlertFailoverCallbackImpl; import com.alibaba.cola.statemachine.builder.StateMachineBuilder; import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory; +import com.alibaba.cola.statemachine.exception.TransitionFailoverException; + import org.junit.Assert; import org.junit.Test; @@ -20,27 +23,34 @@ public class StateMachineTest { static String MACHINE_ID = "TestStateMachine"; static enum States { - STATE1, STATE2, STATE3, STATE4 + STATE1, + STATE2, + STATE3, + STATE4 } static enum Events { - EVENT1, EVENT2, EVENT3, EVENT4, INTERNAL_EVENT + EVENT1, + EVENT2, + EVENT3, + EVENT4, + INTERNAL_EVENT } - static class Context{ + static class Context { String operator = "frank"; String entityId = "123465"; } @Test - public void testExternalNormal(){ + public void testExternalNormal() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransition() - .from(States.STATE1) - .to(States.STATE2) - .on(Events.EVENT1) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); StateMachine stateMachine = builder.build(MACHINE_ID); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context()); @@ -48,29 +58,62 @@ public void testExternalNormal(){ } @Test - public void testExternalTransitionsNormal(){ + public void testFailover() { + StateMachineBuilder builder = StateMachineBuilderFactory.create(); + builder.externalTransition() + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); + + builder.setFailoverCallback(new AlertFailoverCallbackImpl<>()); + + StateMachine stateMachine = builder.build(MACHINE_ID); + Assert.assertThrows(TransitionFailoverException.class, + () -> stateMachine.fireEvent(States.STATE2, Events.EVENT1, new Context())); + } + + @Test + public void testVerify() { + StateMachineBuilder builder = StateMachineBuilderFactory.create(); + builder.externalTransition() + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); + + StateMachine stateMachine = builder.build(MACHINE_ID); + + Assert.assertTrue(stateMachine.verify(States.STATE1, Events.EVENT1)); + Assert.assertFalse(stateMachine.verify(States.STATE1, Events.EVENT2)); + } + + @Test + public void testExternalTransitionsNormal() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransitions() - .fromAmong(States.STATE1, States.STATE2, States.STATE3) - .to(States.STATE4) - .on(Events.EVENT1) - .when(checkCondition()) - .perform(doAction()); + .fromAmong(States.STATE1, States.STATE2, States.STATE3) + .to(States.STATE4) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); - StateMachine stateMachine = builder.build(MACHINE_ID+"1"); + StateMachine stateMachine = builder.build(MACHINE_ID + "1"); States target = stateMachine.fireEvent(States.STATE2, Events.EVENT1, new Context()); Assert.assertEquals(States.STATE4, target); } @Test - public void testInternalNormal(){ + public void testInternalNormal() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.internalTransition() - .within(States.STATE1) - .on(Events.INTERNAL_EVENT) - .when(checkCondition()) - .perform(doAction()); - StateMachine stateMachine = builder.build(MACHINE_ID+"2"); + .within(States.STATE1) + .on(Events.INTERNAL_EVENT) + .when(checkCondition()) + .perform(doAction()); + StateMachine stateMachine = builder.build(MACHINE_ID + "2"); stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context()); States target = stateMachine.fireEvent(States.STATE1, Events.INTERNAL_EVENT, new Context()); @@ -78,7 +121,7 @@ public void testInternalNormal(){ } @Test - public void testExternalInternalNormal(){ + public void testExternalInternalNormal() { StateMachine stateMachine = buildStateMachine("testExternalInternalNormal"); Context context = new Context(); @@ -95,38 +138,38 @@ public void testExternalInternalNormal(){ private StateMachine buildStateMachine(String machineId) { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransition() - .from(States.STATE1) - .to(States.STATE2) - .on(Events.EVENT1) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); builder.internalTransition() - .within(States.STATE2) - .on(Events.INTERNAL_EVENT) - .when(checkCondition()) - .perform(doAction()); + .within(States.STATE2) + .on(Events.INTERNAL_EVENT) + .when(checkCondition()) + .perform(doAction()); builder.externalTransition() - .from(States.STATE2) - .to(States.STATE1) - .on(Events.EVENT2) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE2) + .to(States.STATE1) + .on(Events.EVENT2) + .when(checkCondition()) + .perform(doAction()); builder.externalTransition() - .from(States.STATE1) - .to(States.STATE3) - .on(Events.EVENT3) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE1) + .to(States.STATE3) + .on(Events.EVENT3) + .when(checkCondition()) + .perform(doAction()); builder.externalTransitions() - .fromAmong(States.STATE1, States.STATE2, States.STATE3) - .to(States.STATE4) - .on(Events.EVENT4) - .when(checkCondition()) - .perform(doAction()); + .fromAmong(States.STATE1, States.STATE2, States.STATE3) + .to(States.STATE4) + .on(Events.EVENT4) + .when(checkCondition()) + .perform(doAction()); builder.build(machineId); @@ -136,11 +179,11 @@ private StateMachine buildStateMachine(String machineId } @Test - public void testMultiThread(){ + public void testMultiThread() { buildStateMachine("testMultiThread"); - for(int i=0 ; i<10 ; i++){ - Thread thread = new Thread(()->{ + for (int i = 0; i < 10; i++) { + Thread thread = new Thread(() -> { StateMachine stateMachine = StateMachineFactory.get("testMultiThread"); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context()); Assert.assertEquals(States.STATE2, target); @@ -148,8 +191,7 @@ public void testMultiThread(){ thread.start(); } - - for(int i=0 ; i<10 ; i++) { + for (int i = 0; i < 10; i++) { Thread thread = new Thread(() -> { StateMachine stateMachine = StateMachineFactory.get("testMultiThread"); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT4, new Context()); @@ -158,7 +200,7 @@ public void testMultiThread(){ thread.start(); } - for(int i=0 ; i<10 ; i++) { + for (int i = 0; i < 10; i++) { Thread thread = new Thread(() -> { StateMachine stateMachine = StateMachineFactory.get("testMultiThread"); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT3, new Context()); @@ -169,20 +211,20 @@ public void testMultiThread(){ } - private Condition checkCondition() { return new Condition() { @Override public boolean isSatisfied(Context context) { - System.out.println("Check condition : "+context); + System.out.println("Check condition : " + context); return true; } }; } private Action doAction() { - return (from, to, event, ctx)->{ - System.out.println(ctx.operator+" is operating "+ctx.entityId+" from:"+from+" to:"+to+" on:"+event); + return (from, to, event, ctx) -> { + System.out.println( + ctx.operator + " is operating " + ctx.entityId + " from:" + from + " to:" + to + " on:" + event); }; } From df7ca57eecdc44cda3ecdc268a5a378c79f0d70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E4=B9=9F?= Date: Thu, 15 Sep 2022 13:52:03 +0800 Subject: [PATCH 2/5] =?UTF-8?q?[FEATURE]:[=E7=BB=99=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=E6=8F=90=E4=BE=9B=E4=B8=80=E4=BA=9B=E6=96=B0=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=8E=A5=E5=8F=A3]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 增加com.alibaba.cola.statemachine.StateMachine#verify方法 用来判断当前状态能否响应某个事件 2. 增加com.alibaba.cola.statemachine.builder.StateMachineBuilder#setFailoverCallback 用来增加在状态流转没有命中当前配置的规则时执行的回调 接口定义 com.alibaba.cola.statemachine.builder.FailoverCallback 默认为NumbFailoverCallbackImpl,与当前行为一样,什么都不做。 另外内置AlertFailoverCallbackImpl,用于抛出异常TransitionFailoverException --- .../cola/statemachine/StateMachine.java | 8 + .../builder/AlertFailoverCallbackImpl.java | 18 ++ .../builder/FailoverCallback.java | 18 ++ .../builder/NumbFailoverCallbackImpl.java | 15 ++ .../builder/StateMachineBuilder.java | 12 +- .../builder/StateMachineBuilderImpl.java | 15 +- .../TransitionFailoverException.java | 12 ++ .../statemachine/impl/StateMachineImpl.java | 25 ++- .../alibaba/cola/test/StateMachineTest.java | 156 +++++++++++------- 9 files changed, 214 insertions(+), 65 deletions(-) create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java index e99102f84..0e743a0d0 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachine.java @@ -12,6 +12,14 @@ */ public interface StateMachine extends Visitable{ + /** + * Verify if an event {@code E} can be fired from current state {@code S} + * @param sourceStateId + * @param event + * @return + */ + boolean verify(S sourceStateId,E event); + /** * Send an event {@code E} to the state machine. * diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java new file mode 100644 index 000000000..260c11ec8 --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java @@ -0,0 +1,18 @@ +package com.alibaba.cola.statemachine.builder; + +import com.alibaba.cola.statemachine.exception.TransitionFailoverException; + +/** + * Default failover callback, do nothing. + * + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +public class AlertFailoverCallbackImpl implements FailoverCallback { + + @Override + public void onFailover(S sourceState, E event, C context) { + throw new TransitionFailoverException( + "Cannot fire event [" + event + "] on current state [" + sourceState + "] with context [" + context + "]"); + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java new file mode 100644 index 000000000..afa5b4784 --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java @@ -0,0 +1,18 @@ +package com.alibaba.cola.statemachine.builder; + +/** + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +@FunctionalInterface +public interface FailoverCallback { + + /** + * Callback function to execute on failover + * + * @param sourceState + * @param event + * @param context + */ + void onFailover(S sourceState, E event, C context); +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java new file mode 100644 index 000000000..3abc1f3fd --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java @@ -0,0 +1,15 @@ +package com.alibaba.cola.statemachine.builder; + +/** + * Default failover callback, do nothing. + * + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +public class NumbFailoverCallbackImpl implements FailoverCallback { + + @Override + public void onFailover(S sourceState, E event, C context) { + //do nothing + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java index 029433e0c..ca910cf39 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java @@ -11,22 +11,32 @@ public interface StateMachineBuilder { /** * Builder for one transition + * * @return External transition builder */ ExternalTransitionBuilder externalTransition(); /** * Builder for multiple transitions + * * @return External transition builder */ ExternalTransitionsBuilder externalTransitions(); /** * Start to build internal transition + * * @return Internal transition builder */ InternalTransitionBuilder internalTransition(); - StateMachine build(String machineId); + /** + * set up failover callback, default do nothing {@code NumbFailoverCallbackImpl} + * + * @param callback + */ + void setFailoverCallback(FailoverCallback callback); + + StateMachine build(String machineId); } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java index 497cb9e3c..07e576766 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java @@ -1,14 +1,14 @@ package com.alibaba.cola.statemachine.builder; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import com.alibaba.cola.statemachine.State; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.StateMachineFactory; import com.alibaba.cola.statemachine.impl.StateMachineImpl; import com.alibaba.cola.statemachine.impl.TransitionType; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - /** * StateMachineBuilderImpl * @@ -20,8 +20,9 @@ public class StateMachineBuilderImpl implements StateMachineBuilder> stateMap = new ConcurrentHashMap<>(); + private final Map> stateMap = new ConcurrentHashMap<>(); private final StateMachineImpl stateMachine = new StateMachineImpl<>(stateMap); + private FailoverCallback failoverCallback = new NumbFailoverCallbackImpl<>(); @Override public ExternalTransitionBuilder externalTransition() { @@ -38,10 +39,16 @@ public InternalTransitionBuilder internalTransition() { return new TransitionBuilderImpl<>(stateMap, TransitionType.INTERNAL); } + @Override + public void setFailoverCallback(FailoverCallback callback) { + this.failoverCallback = callback; + } + @Override public StateMachine build(String machineId) { stateMachine.setMachineId(machineId); stateMachine.setReady(true); + stateMachine.setFailoverCallback(failoverCallback); StateMachineFactory.register(stateMachine); return stateMachine; } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java new file mode 100644 index 000000000..bf3f01bcf --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java @@ -0,0 +1,12 @@ +package com.alibaba.cola.statemachine.exception; + +/** + * @author 龙也 + * @date 2022/9/15 12:08 PM + */ +public class TransitionFailoverException extends RuntimeException { + + public TransitionFailoverException(String errMsg) { + super(errMsg); + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java index f36fa83d3..ca09a7cab 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java @@ -1,12 +1,13 @@ package com.alibaba.cola.statemachine.impl; +import java.util.List; +import java.util.Map; + import com.alibaba.cola.statemachine.State; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.Transition; import com.alibaba.cola.statemachine.Visitor; - -import java.util.List; -import java.util.Map; +import com.alibaba.cola.statemachine.builder.FailoverCallback; /** * For performance consideration, @@ -26,10 +27,23 @@ public class StateMachineImpl implements StateMachine { private boolean ready; + private FailoverCallback failoverCallback; + public StateMachineImpl(Map> stateMap) { this.stateMap = stateMap; } + @Override + public boolean verify(S sourceStateId, E event) { + isReady(); + + State sourceState = getState(sourceStateId); + + List> transitions = sourceState.getEventTransitions(event); + + return transitions != null && transitions.size() != 0; + } + @Override public S fireEvent(S sourceStateId, E event, C ctx) { isReady(); @@ -37,6 +51,7 @@ public S fireEvent(S sourceStateId, E event, C ctx) { if (transition == null) { Debugger.debug("There is no Transition for " + event); + failoverCallback.onFailover(sourceStateId, event, ctx); return sourceStateId; } @@ -115,4 +130,8 @@ public void setMachineId(String machineId) { public void setReady(boolean ready) { this.ready = ready; } + + public void setFailoverCallback(FailoverCallback failoverCallback) { + this.failoverCallback = failoverCallback; + } } diff --git a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java index 8959345a5..270f34958 100644 --- a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java +++ b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java @@ -4,8 +4,11 @@ import com.alibaba.cola.statemachine.Condition; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.StateMachineFactory; +import com.alibaba.cola.statemachine.builder.AlertFailoverCallbackImpl; import com.alibaba.cola.statemachine.builder.StateMachineBuilder; import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory; +import com.alibaba.cola.statemachine.exception.TransitionFailoverException; + import org.junit.Assert; import org.junit.Test; @@ -20,27 +23,34 @@ public class StateMachineTest { static String MACHINE_ID = "TestStateMachine"; static enum States { - STATE1, STATE2, STATE3, STATE4 + STATE1, + STATE2, + STATE3, + STATE4 } static enum Events { - EVENT1, EVENT2, EVENT3, EVENT4, INTERNAL_EVENT + EVENT1, + EVENT2, + EVENT3, + EVENT4, + INTERNAL_EVENT } - static class Context{ + static class Context { String operator = "frank"; String entityId = "123465"; } @Test - public void testExternalNormal(){ + public void testExternalNormal() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransition() - .from(States.STATE1) - .to(States.STATE2) - .on(Events.EVENT1) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); StateMachine stateMachine = builder.build(MACHINE_ID); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context()); @@ -48,29 +58,62 @@ public void testExternalNormal(){ } @Test - public void testExternalTransitionsNormal(){ + public void testFailover() { + StateMachineBuilder builder = StateMachineBuilderFactory.create(); + builder.externalTransition() + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); + + builder.setFailoverCallback(new AlertFailoverCallbackImpl<>()); + + StateMachine stateMachine = builder.build(MACHINE_ID); + Assert.assertThrows(TransitionFailoverException.class, + () -> stateMachine.fireEvent(States.STATE2, Events.EVENT1, new Context())); + } + + @Test + public void testVerify() { + StateMachineBuilder builder = StateMachineBuilderFactory.create(); + builder.externalTransition() + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); + + StateMachine stateMachine = builder.build(MACHINE_ID); + + Assert.assertTrue(stateMachine.verify(States.STATE1, Events.EVENT1)); + Assert.assertFalse(stateMachine.verify(States.STATE1, Events.EVENT2)); + } + + @Test + public void testExternalTransitionsNormal() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransitions() - .fromAmong(States.STATE1, States.STATE2, States.STATE3) - .to(States.STATE4) - .on(Events.EVENT1) - .when(checkCondition()) - .perform(doAction()); + .fromAmong(States.STATE1, States.STATE2, States.STATE3) + .to(States.STATE4) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); - StateMachine stateMachine = builder.build(MACHINE_ID+"1"); + StateMachine stateMachine = builder.build(MACHINE_ID + "1"); States target = stateMachine.fireEvent(States.STATE2, Events.EVENT1, new Context()); Assert.assertEquals(States.STATE4, target); } @Test - public void testInternalNormal(){ + public void testInternalNormal() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.internalTransition() - .within(States.STATE1) - .on(Events.INTERNAL_EVENT) - .when(checkCondition()) - .perform(doAction()); - StateMachine stateMachine = builder.build(MACHINE_ID+"2"); + .within(States.STATE1) + .on(Events.INTERNAL_EVENT) + .when(checkCondition()) + .perform(doAction()); + StateMachine stateMachine = builder.build(MACHINE_ID + "2"); stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context()); States target = stateMachine.fireEvent(States.STATE1, Events.INTERNAL_EVENT, new Context()); @@ -78,7 +121,7 @@ public void testInternalNormal(){ } @Test - public void testExternalInternalNormal(){ + public void testExternalInternalNormal() { StateMachine stateMachine = buildStateMachine("testExternalInternalNormal"); Context context = new Context(); @@ -95,38 +138,38 @@ public void testExternalInternalNormal(){ private StateMachine buildStateMachine(String machineId) { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransition() - .from(States.STATE1) - .to(States.STATE2) - .on(Events.EVENT1) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE1) + .to(States.STATE2) + .on(Events.EVENT1) + .when(checkCondition()) + .perform(doAction()); builder.internalTransition() - .within(States.STATE2) - .on(Events.INTERNAL_EVENT) - .when(checkCondition()) - .perform(doAction()); + .within(States.STATE2) + .on(Events.INTERNAL_EVENT) + .when(checkCondition()) + .perform(doAction()); builder.externalTransition() - .from(States.STATE2) - .to(States.STATE1) - .on(Events.EVENT2) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE2) + .to(States.STATE1) + .on(Events.EVENT2) + .when(checkCondition()) + .perform(doAction()); builder.externalTransition() - .from(States.STATE1) - .to(States.STATE3) - .on(Events.EVENT3) - .when(checkCondition()) - .perform(doAction()); + .from(States.STATE1) + .to(States.STATE3) + .on(Events.EVENT3) + .when(checkCondition()) + .perform(doAction()); builder.externalTransitions() - .fromAmong(States.STATE1, States.STATE2, States.STATE3) - .to(States.STATE4) - .on(Events.EVENT4) - .when(checkCondition()) - .perform(doAction()); + .fromAmong(States.STATE1, States.STATE2, States.STATE3) + .to(States.STATE4) + .on(Events.EVENT4) + .when(checkCondition()) + .perform(doAction()); builder.build(machineId); @@ -136,11 +179,11 @@ private StateMachine buildStateMachine(String machineId } @Test - public void testMultiThread(){ + public void testMultiThread() { buildStateMachine("testMultiThread"); - for(int i=0 ; i<10 ; i++){ - Thread thread = new Thread(()->{ + for (int i = 0; i < 10; i++) { + Thread thread = new Thread(() -> { StateMachine stateMachine = StateMachineFactory.get("testMultiThread"); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context()); Assert.assertEquals(States.STATE2, target); @@ -148,8 +191,7 @@ public void testMultiThread(){ thread.start(); } - - for(int i=0 ; i<10 ; i++) { + for (int i = 0; i < 10; i++) { Thread thread = new Thread(() -> { StateMachine stateMachine = StateMachineFactory.get("testMultiThread"); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT4, new Context()); @@ -158,7 +200,7 @@ public void testMultiThread(){ thread.start(); } - for(int i=0 ; i<10 ; i++) { + for (int i = 0; i < 10; i++) { Thread thread = new Thread(() -> { StateMachine stateMachine = StateMachineFactory.get("testMultiThread"); States target = stateMachine.fireEvent(States.STATE1, Events.EVENT3, new Context()); @@ -169,20 +211,20 @@ public void testMultiThread(){ } - private Condition checkCondition() { return new Condition() { @Override public boolean isSatisfied(Context context) { - System.out.println("Check condition : "+context); + System.out.println("Check condition : " + context); return true; } }; } private Action doAction() { - return (from, to, event, ctx)->{ - System.out.println(ctx.operator+" is operating "+ctx.entityId+" from:"+from+" to:"+to+" on:"+event); + return (from, to, event, ctx) -> { + System.out.println( + ctx.operator + " is operating " + ctx.entityId + " from:" + from + " to:" + to + " on:" + event); }; } From be83fad92b461edcc4a73a4cf363a8a476591816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E4=B9=9F?= Date: Thu, 15 Sep 2022 13:55:34 +0800 Subject: [PATCH 3/5] [CHORE]:[no need to change version] --- cola-components/cola-component-statemachine/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/cola-components/cola-component-statemachine/pom.xml b/cola-components/cola-component-statemachine/pom.xml index 0a174b47d..80ab78521 100644 --- a/cola-components/cola-component-statemachine/pom.xml +++ b/cola-components/cola-component-statemachine/pom.xml @@ -8,7 +8,6 @@ cola-component-statemachine - 4.4.1-SNAPSHOT jar ${project.artifactId} ${project.artifactId} From e4da4602c6a68206d246290351eb86d0900fe12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E4=B9=9F?= Date: Thu, 15 Sep 2022 14:15:39 +0800 Subject: [PATCH 4/5] [TEST]:[fix testVerify tc] --- .../src/test/java/com/alibaba/cola/test/StateMachineTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java index 270f34958..9d45e7484 100644 --- a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java +++ b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java @@ -69,7 +69,7 @@ public void testFailover() { builder.setFailoverCallback(new AlertFailoverCallbackImpl<>()); - StateMachine stateMachine = builder.build(MACHINE_ID); + StateMachine stateMachine = builder.build(MACHINE_ID + "-testFailover"); Assert.assertThrows(TransitionFailoverException.class, () -> stateMachine.fireEvent(States.STATE2, Events.EVENT1, new Context())); } @@ -84,7 +84,7 @@ public void testVerify() { .when(checkCondition()) .perform(doAction()); - StateMachine stateMachine = builder.build(MACHINE_ID); + StateMachine stateMachine = builder.build(MACHINE_ID + "-testVerify"); Assert.assertTrue(stateMachine.verify(States.STATE1, Events.EVENT1)); Assert.assertFalse(stateMachine.verify(States.STATE1, Events.EVENT2)); From 935b811c87be8c999558089f23134f5a02e1f5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E4=B9=9F?= Date: Mon, 10 Oct 2022 16:53:37 +0800 Subject: [PATCH 5/5] [REFACTOR]:[rename failover to fail] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 这里不是故障恢复,只是出错回调 --- .../builder/AlertFailCallback.java | 19 +++++++++++++++++++ .../builder/AlertFailoverCallbackImpl.java | 18 ------------------ ...ailoverCallback.java => FailCallback.java} | 8 +++++--- .../builder/NumbFailCallback.java | 15 +++++++++++++++ .../builder/NumbFailoverCallbackImpl.java | 15 --------------- .../builder/StateMachineBuilder.java | 4 ++-- .../builder/StateMachineBuilderImpl.java | 8 ++++---- ...tion.java => TransitionFailException.java} | 4 ++-- .../statemachine/impl/StateMachineImpl.java | 10 +++++----- .../alibaba/cola/test/StateMachineTest.java | 12 ++++++------ 10 files changed, 58 insertions(+), 55 deletions(-) create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailCallback.java delete mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java rename cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/{FailoverCallback.java => FailCallback.java} (54%) create mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailCallback.java delete mode 100644 cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java rename cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/{TransitionFailoverException.java => TransitionFailException.java} (52%) diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailCallback.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailCallback.java new file mode 100644 index 000000000..56a7290ed --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailCallback.java @@ -0,0 +1,19 @@ +package com.alibaba.cola.statemachine.builder; + +import com.alibaba.cola.statemachine.exception.TransitionFailException; + +/** + * Alert fail callback, throw an {@code TransitionFailException} + * + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +public class AlertFailCallback implements FailCallback { + + @Override + public void onFail(S sourceState, E event, C context) { + throw new TransitionFailException( + "Cannot fire event [" + event + "] on current state [" + sourceState + "] with context [" + context + "]" + ); + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java deleted file mode 100644 index 260c11ec8..000000000 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/AlertFailoverCallbackImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.alibaba.cola.statemachine.builder; - -import com.alibaba.cola.statemachine.exception.TransitionFailoverException; - -/** - * Default failover callback, do nothing. - * - * @author 龙也 - * @date 2022/9/15 12:02 PM - */ -public class AlertFailoverCallbackImpl implements FailoverCallback { - - @Override - public void onFailover(S sourceState, E event, C context) { - throw new TransitionFailoverException( - "Cannot fire event [" + event + "] on current state [" + sourceState + "] with context [" + context + "]"); - } -} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailCallback.java similarity index 54% rename from cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java rename to cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailCallback.java index afa5b4784..716642a71 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailoverCallback.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/FailCallback.java @@ -1,18 +1,20 @@ package com.alibaba.cola.statemachine.builder; /** + * FailCallback + * * @author 龙也 * @date 2022/9/15 12:02 PM */ @FunctionalInterface -public interface FailoverCallback { +public interface FailCallback { /** - * Callback function to execute on failover + * Callback function to execute if failed to trigger an Event * * @param sourceState * @param event * @param context */ - void onFailover(S sourceState, E event, C context); + void onFail(S sourceState, E event, C context); } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailCallback.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailCallback.java new file mode 100644 index 000000000..943cd6826 --- /dev/null +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailCallback.java @@ -0,0 +1,15 @@ +package com.alibaba.cola.statemachine.builder; + +/** + * Default fail callback, do nothing. + * + * @author 龙也 + * @date 2022/9/15 12:02 PM + */ +public class NumbFailCallback implements FailCallback { + + @Override + public void onFail(S sourceState, E event, C context) { + //do nothing + } +} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java deleted file mode 100644 index 3abc1f3fd..000000000 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/NumbFailoverCallbackImpl.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.alibaba.cola.statemachine.builder; - -/** - * Default failover callback, do nothing. - * - * @author 龙也 - * @date 2022/9/15 12:02 PM - */ -public class NumbFailoverCallbackImpl implements FailoverCallback { - - @Override - public void onFailover(S sourceState, E event, C context) { - //do nothing - } -} diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java index ca910cf39..1b09ef410 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilder.java @@ -31,11 +31,11 @@ public interface StateMachineBuilder { InternalTransitionBuilder internalTransition(); /** - * set up failover callback, default do nothing {@code NumbFailoverCallbackImpl} + * set up fail callback, default do nothing {@code NumbFailCallbackImpl} * * @param callback */ - void setFailoverCallback(FailoverCallback callback); + void setFailCallback(FailCallback callback); StateMachine build(String machineId); diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java index 07e576766..f08365e26 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/builder/StateMachineBuilderImpl.java @@ -22,7 +22,7 @@ public class StateMachineBuilderImpl implements StateMachineBuilder> stateMap = new ConcurrentHashMap<>(); private final StateMachineImpl stateMachine = new StateMachineImpl<>(stateMap); - private FailoverCallback failoverCallback = new NumbFailoverCallbackImpl<>(); + private FailCallback failCallback = new NumbFailCallback<>(); @Override public ExternalTransitionBuilder externalTransition() { @@ -40,15 +40,15 @@ public InternalTransitionBuilder internalTransition() { } @Override - public void setFailoverCallback(FailoverCallback callback) { - this.failoverCallback = callback; + public void setFailCallback(FailCallback callback) { + this.failCallback = callback; } @Override public StateMachine build(String machineId) { stateMachine.setMachineId(machineId); stateMachine.setReady(true); - stateMachine.setFailoverCallback(failoverCallback); + stateMachine.setFailCallback(failCallback); StateMachineFactory.register(stateMachine); return stateMachine; } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailException.java similarity index 52% rename from cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java rename to cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailException.java index bf3f01bcf..0512a4732 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailoverException.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/exception/TransitionFailException.java @@ -4,9 +4,9 @@ * @author 龙也 * @date 2022/9/15 12:08 PM */ -public class TransitionFailoverException extends RuntimeException { +public class TransitionFailException extends RuntimeException { - public TransitionFailoverException(String errMsg) { + public TransitionFailException(String errMsg) { super(errMsg); } } diff --git a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java index ca09a7cab..b930216f4 100644 --- a/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java +++ b/cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/impl/StateMachineImpl.java @@ -7,7 +7,7 @@ import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.Transition; import com.alibaba.cola.statemachine.Visitor; -import com.alibaba.cola.statemachine.builder.FailoverCallback; +import com.alibaba.cola.statemachine.builder.FailCallback; /** * For performance consideration, @@ -27,7 +27,7 @@ public class StateMachineImpl implements StateMachine { private boolean ready; - private FailoverCallback failoverCallback; + private FailCallback failCallback; public StateMachineImpl(Map> stateMap) { this.stateMap = stateMap; @@ -51,7 +51,7 @@ public S fireEvent(S sourceStateId, E event, C ctx) { if (transition == null) { Debugger.debug("There is no Transition for " + event); - failoverCallback.onFailover(sourceStateId, event, ctx); + failCallback.onFail(sourceStateId, event, ctx); return sourceStateId; } @@ -131,7 +131,7 @@ public void setReady(boolean ready) { this.ready = ready; } - public void setFailoverCallback(FailoverCallback failoverCallback) { - this.failoverCallback = failoverCallback; + public void setFailCallback(FailCallback failCallback) { + this.failCallback = failCallback; } } diff --git a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java index 9d45e7484..cbc39d423 100644 --- a/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java +++ b/cola-components/cola-component-statemachine/src/test/java/com/alibaba/cola/test/StateMachineTest.java @@ -4,10 +4,10 @@ import com.alibaba.cola.statemachine.Condition; import com.alibaba.cola.statemachine.StateMachine; import com.alibaba.cola.statemachine.StateMachineFactory; -import com.alibaba.cola.statemachine.builder.AlertFailoverCallbackImpl; +import com.alibaba.cola.statemachine.builder.AlertFailCallback; import com.alibaba.cola.statemachine.builder.StateMachineBuilder; import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory; -import com.alibaba.cola.statemachine.exception.TransitionFailoverException; +import com.alibaba.cola.statemachine.exception.TransitionFailException; import org.junit.Assert; import org.junit.Test; @@ -58,7 +58,7 @@ public void testExternalNormal() { } @Test - public void testFailover() { + public void testFail() { StateMachineBuilder builder = StateMachineBuilderFactory.create(); builder.externalTransition() .from(States.STATE1) @@ -67,10 +67,10 @@ public void testFailover() { .when(checkCondition()) .perform(doAction()); - builder.setFailoverCallback(new AlertFailoverCallbackImpl<>()); + builder.setFailCallback(new AlertFailCallback<>()); - StateMachine stateMachine = builder.build(MACHINE_ID + "-testFailover"); - Assert.assertThrows(TransitionFailoverException.class, + StateMachine stateMachine = builder.build(MACHINE_ID + "-testFail"); + Assert.assertThrows(TransitionFailException.class, () -> stateMachine.fireEvent(States.STATE2, Events.EVENT1, new Context())); }