2016-07-06 8 views
0
、私は非常に単純なシナリオのための私のSSMを設定するトラブルを抱えている

に基づきますlog_onイベントが発生したときに発生します。私はSSMのドキュメントを再読み込みし、これが「フォーク」、「ガード」、または階層構成のいずれであるかわからない。春のステートマシンは、アクション

「アクション」がここで行われる:

@Component 
public class LogonValidationAction implements Action<PickStates, PickEvents> { 

Logger logger = LogManager.getLogger(); 

volatile int counter = 0; 

@Override 
public void execute(StateContext<PickStates, PickEvents> context) { 
    String eventName = context.getEvent().name(); 
    logger.info("executing {} for event {}", LogonValidationAction.class.getName(), eventName); 

    // basically, if success, send success, if failure, send failure 
    // for testing 
    if(counter % 2 == 0) 
     context.getStateMachine().sendEvent(PickEvents.logon_sucess); 
    else 
     context.getStateMachine().sendEvent(PickEvents.logon_fail); 
} 
} 

私は「失敗」(logged_off状態が残っている)、または「成功」のいずれかに流れを誘導するために私のテストでは「カウンター」を使用しています(の状態変化ログオン)。あなたはlogon_sucessかのいずれかを送信しよう

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Application.class) 
public class EzpickStateMachineTest { 

Logger logger = LogManager.getLogger(); 

@Autowired 
StateMachineFactory<PickStates, PickEvents> stateMachineFactory; 

// for testing so can toggle success/failure when logging in 
@Autowired 
LogonValidationAction logonValidationAction; 

@Test 
public void failLogon() throws Exception { 
    StateMachine<PickStates, PickEvents> stateMachine = stateMachineFactory.getStateMachine(); 

    stateMachine.start(); 

    // when sm starts, state is 'logged_off' 
    assertThat(stateMachine.getState().getId().name(), is(PickStates.logged_off.name())); 

    // odd numbers fire 'failure' event 
    logonValidationAction.setCounter(1); 

    stateMachine.sendEvent(PickEvents.log_on); 

    // if logon fails, state is 'logged_off' 
    assertThat(stateMachine.getState().getId().name(), is(PickStates.logged_off.name())); 
} 
} 

答えて

0

アクションから:ここ

の設定です:

@Configuration 
@EnableStateMachineFactory 
public class Config extends EnumStateMachineConfigurerAdapter<PickStates, PickEvents>{ 

@Autowired 
StateMachineListener stateMachineListener; 

@Autowired 
LogonValidationAction logonValidationAction; 

@Override 
public void configure(StateMachineStateConfigurer<PickStates, PickEvents> states) throws Exception { 
    states 
     .withStates() 
     .initial(PickStates.logged_off) 
     .state(PickStates.logged_on) 
     .states(EnumSet.allOf(PickStates.class)); 
} 

@Override 
public void configure(StateMachineTransitionConfigurer<PickStates, PickEvents> transitions) throws Exception { 
    transitions 
     .withExternal() 
     .source(PickStates.logged_off) 
     .target(PickStates.logged_on) 
     .event(PickEvents.log_on) 
     .action(logonValidationAction) 
     .and() 
     .withExternal() 
     .source(PickStates.logged_on) 
     .target(PickStates.logged_off) 
     .event(PickEvents.log_off); 
} 

@Override 
public void configure(StateMachineConfigurationConfigurer<PickStates, PickEvents> config) throws Exception { 
    config 
     .withConfiguration() 
     .autoStartup(true) 
     .listener(stateMachineListener); 
} 
} 

が、これは(アクションがlogon_failイベントを発生時に 'logged_off' を期待して)失敗するテストですlogon_failマシン設定では、これらのイベントの遷移を定義していないため、マシンは何もしません。

その他の注意事項、counterをアクションbeanに格納しないでください。マシンの拡張状態変数を使用すると、マシンを使用しているすべてのコンポーネントまたはStateContextに表示されます。

counterが拡張状態で利用可能な場合、拡張状態からそのカウンタを使用するガードを使用して匿名遷移を作成することができます。もう1つの可能性は、選択可能な擬似ステートとガードを使用してターゲット状態を選択することです。あなたのカウンターの使用は、拡張状態のセクションでwikiが言及しているものと全く同じです。https://en.wikipedia.org/wiki/UML_state_machine#Extended_states

+0

"アクションでは、logon_sucessまたはlogon_failを送信しようとしましたが、マシン構成では、 " これを行う方法の例を教えてください...これは私の質問の主要な部分でした。 「カウンター」の提案に感謝します。私はそれを調べるでしょうあなたが推薦しているものを理解していません – maspen

+0

設定に関してあなたからの利用可能な応答がまだありませんでした。設定例を提供してください – maspen

+0

あなたは 'event(PickEvents.log_on)'と 'イベント(PickEvents.log_off) 'を作成し、テストで使用します。これらは、トランジションに関連付けられたイベントだけです。それから、アクションからは、遷移が関連付けられていない 'PickEvents.logon_sucess'を送信するので、マシンは何もしません。どのように私は行方不明を記述するか分からない。 (コードスニペットが不完全な場合を除きます) –

関連する問題