Add internal transition to web sample

- This is purely for jepsen tests, though also
  handy for UI for showing that variable can be changed.
  Essentially we want to have a way to set extended state
  variable via internal transition which takes an value from
  event headers and set that to extended state. This is then
  supposed to be used from jepsen to test concurrenty issues
  around extended state variables.
This commit is contained in:
Janne Valkealahti
2015-08-07 17:22:28 +01:00
parent 435b306cf9
commit 672a41ecf1
4 changed files with 47 additions and 6 deletions

View File

@@ -151,8 +151,11 @@ public class StateMachineConfig {
.source(States.S211).target(States.S212).event(Events.I)
.and()
.withExternal()
.source(States.S12).target(States.S212).event(Events.I);
.source(States.S12).target(States.S212).event(Events.I)
.and()
.withInternal()
.source(States.S11).event(Events.J)
.action(setVariableAction());
}
@Bean
@@ -170,6 +173,11 @@ public class StateMachineConfig {
return new FooAction();
}
@Bean
public SetVariableAction setVariableAction() {
return new SetVariableAction();
}
@Bean
public StateMachineEnsemble<States, Events> stateMachineEnsemble() throws Exception {
return new ZookeeperStateMachineEnsemble<States, Events>(curatorClient(), "/foo");
@@ -193,7 +201,7 @@ public class StateMachineConfig {
}
public static enum Events {
A, B, C, D, E, F, G, H, I
A, B, C, D, E, F, G, H, I, J
}
private static class FooAction implements Action<States, Events> {
@@ -230,4 +238,18 @@ public class StateMachineConfig {
}
}
private static class SetVariableAction implements Action<States, Events> {
@Override
public void execute(StateContext<States, Events> context) {
System.out.println("XXXXXXXXXXX execute");
String testVariable = context.getMessageHeaders().get("testVariable", String.class);
System.out.println("XXXXXXXXXXX execute testVariable=" + testVariable);
if (testVariable != null) {
context.getExtendedState().getVariables().put("testVariable", testVariable);
}
}
}
}

View File

@@ -26,10 +26,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineException;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
@@ -118,9 +120,14 @@ public class StateMachineController {
@RequestMapping("/event")
@ResponseStatus(HttpStatus.OK)
public void sendEvent(@RequestParam(value="id") Events id) {
log.info("Got request to send event " + id);
stateMachine.sendEvent(id);
public void sendEvent(@RequestParam(value = "id") Events id,
@RequestParam(value = "testVariable", required = false) String testVariable) {
log.info("Got request to send event " + id + " testVariable " + testVariable);
Message<Events> message = MessageBuilder
.withPayload(id)
.setHeader("testVariable", testVariable)
.build();
stateMachine.sendEvent(message);
}
@RequestMapping(value = "/states", method = RequestMethod.GET, produces="application/json")

View File

@@ -35,6 +35,12 @@
<button ng-click="sendEvent('I')">event I</button>
</div>
</div>
<div class="row">
<div>
<button ng-click="sendEventAndVariable('J')">event J</button>
<input id="newTestVariable" type="text" ng-model="testVariable" placeholder="New testVariable value..." />
</div>
</div>
<div class="row">
<div class="col-xs-3">
<h4>States</h4>

View File

@@ -18,6 +18,12 @@ angular.module('springChat.controllers', ['toaster'])
});
};
$scope.sendEventAndVariable = function(event) {
$http.post('/event', null, {params:{"id": event, "testVariable": $scope.testVariable}}).
success(function(data) {
});
};
var initStompClient = function() {
chatSocket.init('/ws');