You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dd...@apache.org on 2011/12/09 23:31:57 UTC
svn commit: r1212669 - in /incubator/ambari/trunk: ./
client/src/main/java/org/apache/ambari/common/state/
controller/src/main/java/org/apache/ambari/resource/statemachine/
controller/src/test/java/org/apache/ambari/controller/
controller/src/test/java...
Author: ddas
Date: Fri Dec 9 22:31:56 2011
New Revision: 1212669
URL: http://svn.apache.org/viewvc?rev=1212669&view=rev
Log:
AMBARI-150. Simplifies states in controller state machine.
Added:
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/NoOpDispatcher.java
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImplServiceCreation.java
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestRoleImpl.java
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestServiceImpl.java
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachine.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachineFactory.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterImpl.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterStateFSM.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleImpl.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleState.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceEventType.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceImpl.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceState.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/StateMachineInvoker.java
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/TestHeartbeat.java
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImpl.java
Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Fri Dec 9 22:31:56 2011
@@ -2,6 +2,8 @@ Ambari Change log
Release 0.1.0 - unreleased
+ AMBARI-150. Simplifies states in controller state machine (thejas via ddas)
+
AMBARI-149. Filter the meta ambari category out of the flattened stacks.
(omalley)
@@ -10,7 +12,7 @@ Release 0.1.0 - unreleased
AMBARI-147. Create a stack flattener and introduce Guice. (omalley)
AMBARI-145. FSMs are created for only those components that have
- active roles (Thejas M Nair via ddas)
+ active roles (thejas via ddas)
AMBARI-146. Fix test case failures in agent's FileUtil. (omalley)
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachine.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachine.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachine.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachine.java Fri Dec 9 22:31:56 2011
@@ -23,4 +23,5 @@ public interface StateMachine
public STATE getCurrentState();
public STATE doTransition(EVENTTYPE eventType, EVENT event)
throws InvalidStateTransitonException;
+ public void setCurrentState(STATE state);
}
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachineFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachineFactory.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachineFactory.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/state/StateMachineFactory.java Fri Dec 9 22:31:56 2011
@@ -439,5 +439,10 @@ final public class StateMachineFactory
(operand, currentState, eventType, event);
return currentState;
}
+
+ @Override
+ public void setCurrentState(STATE state) {
+ currentState = state;
+ }
}
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterImpl.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterImpl.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterImpl.java Fri Dec 9 22:31:56 2011
@@ -42,14 +42,10 @@ import org.apache.commons.logging.LogFac
public class ClusterImpl implements ClusterFSM, EventHandler<ClusterEvent> {
/* The state machine for the cluster looks like:
- * INACTIVE --START--> STARTING --START_SUCCESS from all services--> ACTIVE
+ * INACTIVE or FAIL --START--> STARTING --START_SUCCESS from all services--> ACTIVE
* --START_FAILURE from any service--> FAIL
- * ACTIVE --STOP--> STOPPING --STOP_SUCCESS from all services--> INACTIVE
- * --STOP_FAILURE from any service--> UNCLEAN_STOP
- * FAIL --STOP--> STOPPING --STOP_SUCCESS--> STOPPED
- * --STOP_FAILURE--> UNCLEAN_STOP
- * INACTIVE --RELEASE_NODES--> ATTIC
- * ATTIC --ADD_NODES--> INACTIVE
+ * ACTIVE or FAIL --STOP--> STOPPING --STOP_SUCCESS from all services--> INACTIVE
+ * --STOP_FAILURE from any service--> FAIL
*/
private static final StateMachineFactory
@@ -59,6 +55,9 @@ public class ClusterImpl implements Clus
.addTransition(ClusterStateFSM.INACTIVE, ClusterStateFSM.STARTING,
ClusterEventType.START, new StartClusterTransition())
+
+ .addTransition(ClusterStateFSM.FAIL, ClusterStateFSM.STARTING,
+ ClusterEventType.START, new StartClusterTransition())
.addTransition(ClusterStateFSM.STARTING, EnumSet.of(ClusterStateFSM.ACTIVE,
ClusterStateFSM.STARTING), ClusterEventType.START_SUCCESS,
@@ -70,31 +69,19 @@ public class ClusterImpl implements Clus
.addTransition(ClusterStateFSM.ACTIVE, ClusterStateFSM.STOPPING,
ClusterEventType.STOP, new StopClusterTransition())
+ .addTransition(ClusterStateFSM.FAIL, ClusterStateFSM.STOPPING,
+ ClusterEventType.STOP, new StopClusterTransition())
+
.addTransition(ClusterStateFSM.STOPPING, EnumSet.of(ClusterStateFSM.INACTIVE,
ClusterStateFSM.STOPPING), ClusterEventType.STOP_SUCCESS,
new ServiceStoppedTransition())
- .addTransition(ClusterStateFSM.STOPPING, ClusterStateFSM.UNCLEAN_STOP,
+ .addTransition(ClusterStateFSM.STOPPING, ClusterStateFSM.FAIL,
ClusterEventType.STOP_FAILURE)
- .addTransition(ClusterStateFSM.FAIL, ClusterStateFSM.STOPPING,
- ClusterEventType.STOP)
-
- .addTransition(ClusterStateFSM.STOPPING, ClusterStateFSM.INACTIVE,
- ClusterEventType.STOP_SUCCESS)
-
.addTransition(ClusterStateFSM.INACTIVE, ClusterStateFSM.INACTIVE,
ClusterEventType.STOP_SUCCESS)
- .addTransition(ClusterStateFSM.STOPPING, ClusterStateFSM.UNCLEAN_STOP,
- ClusterEventType.STOP_FAILURE)
-
- .addTransition(ClusterStateFSM.INACTIVE, ClusterStateFSM.ATTIC,
- ClusterEventType.RELEASE_NODES)
-
- .addTransition(ClusterStateFSM.ATTIC, ClusterStateFSM.INACTIVE,
- ClusterEventType.ADD_NODES)
-
.installTopology();
private List<ServiceFSM> services;
@@ -116,7 +103,11 @@ public class ClusterImpl implements Clus
for (String service :
cluster.getClusterDefinition(revision).getEnabledServices()) {
if(hasActiveRoles(cluster, service)){
- ServiceImpl serviceImpl = new ServiceImpl(cluster, this, service);
+ ServiceImpl serviceImpl = new ServiceImpl(
+ cluster.getComponentDefinition(service).getActiveRoles(),
+ this,
+ service);
+
serviceImpls.add(serviceImpl);
}
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterStateFSM.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterStateFSM.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterStateFSM.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ClusterStateFSM.java Fri Dec 9 22:31:56 2011
@@ -18,5 +18,5 @@
package org.apache.ambari.resource.statemachine;
public enum ClusterStateFSM {
- INACTIVE, STARTING, ACTIVE, FAIL, ATTIC, STOPPING, UNCLEAN_STOP
+ INACTIVE, STARTING, ACTIVE, FAIL, STOPPING,
}
\ No newline at end of file
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleImpl.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleImpl.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleImpl.java Fri Dec 9 22:31:56 2011
@@ -24,30 +24,29 @@ import org.apache.ambari.event.EventHand
public class RoleImpl implements RoleFSM, EventHandler<RoleEvent> {
- private RoleState myState;
- private String roleName;
- private ServiceFSM service;
+ private final String roleName;
+ private final ServiceFSM service;
/* The state machine for the role looks like:
- * INACTIVE --S_START--> STARTING --S_START_SUCCESS--> ACTIVE
+ * (INACTIVE or FAIL) --S_START--> STARTING --S_START_SUCCESS--> ACTIVE
* --S_START_FAILURE--> FAIL
- * ACTIVE --S_STOP--> STOPPING --S_STOP_SUCCESS--> INACTIVE
- * --S_STOP_FAILURE--> UNCLEAN_STOP
- * FAIL --S_STOP--> STOPPING --S_STOP_SUCCESS--> STOPPED
- * --S_STOP_FAILURE--> UNCLEAN_STOP
+ * (ACTIVE or FAIL) --S_STOP--> STOPPING --S_STOP_SUCCESS--> INACTIVE
+ * --S_STOP_FAILURE--> FAIL
*/
private static final StateMachineFactory
<RoleImpl, RoleState, RoleEventType, RoleEvent> stateMachineFactory
= new StateMachineFactory<RoleImpl, RoleState, RoleEventType,
RoleEvent>(RoleState.INACTIVE)
-
+
+ //START event transitions
.addTransition(RoleState.INACTIVE, RoleState.STARTING,
RoleEventType.START)
- .addTransition(RoleState.STOPPED, RoleState.STARTING,
+ .addTransition(RoleState.FAIL, RoleState.STARTING,
RoleEventType.START)
+ //START_SUCCESS event transitions
.addTransition(RoleState.STARTING,
RoleState.ACTIVE,
RoleEventType.START_SUCCESS, new SuccessfulStartTransition())
@@ -59,33 +58,25 @@ public class RoleImpl implements RoleFSM
RoleEventType.START_SUCCESS)
.addTransition(RoleState.STARTING,
- RoleState.STARTING,
- RoleEventType.START_FAILURE)
-
- .addTransition(RoleState.FAIL, RoleState.FAIL,
+ RoleState.FAIL,
RoleEventType.START_FAILURE)
-
+
+ //STOP event transitions
.addTransition(RoleState.ACTIVE, RoleState.STOPPING,
RoleEventType.STOP)
-
+
+ .addTransition(RoleState.FAIL, RoleState.STOPPING,
+ RoleEventType.STOP)
+
+ //STOP_SUCCESS event transitions
.addTransition(RoleState.STOPPING, RoleState.INACTIVE,
RoleEventType.STOP_SUCCESS, new RoleStopTransition())
-
- .addTransition(RoleState.STOPPING, RoleState.UNCLEAN_STOP,
- RoleEventType.STOP_FAILURE)
-
- .addTransition(RoleState.FAIL, RoleState.STOPPING, RoleEventType.STOP)
-
- .addTransition(RoleState.STOPPING, RoleState.STOPPED,
- RoleEventType.STOP_SUCCESS)
-
- .addTransition(RoleState.STOPPED, RoleState.STOPPED,
+
+ .addTransition(RoleState.INACTIVE, RoleState.INACTIVE,
RoleEventType.STOP_SUCCESS)
- .addTransition(RoleState.STOPPING, RoleState.UNCLEAN_STOP,
- RoleEventType.STOP_FAILURE)
-
- .addTransition(RoleState.UNCLEAN_STOP, RoleState.UNCLEAN_STOP,
+ //STOP_FAILURE event transitions
+ .addTransition(RoleState.STOPPING, RoleState.FAIL,
RoleEventType.STOP_FAILURE)
.installTopology();
@@ -96,11 +87,10 @@ public class RoleImpl implements RoleFSM
public RoleImpl(ServiceFSM service, String roleName) {
this.roleName = roleName;
this.service = service;
- this.myState = RoleState.INACTIVE;
stateMachine = stateMachineFactory.make(this);
}
- public StateMachine getStateMachine() {
+ StateMachine<RoleState, RoleEventType, RoleEvent> getStateMachine() {
return stateMachine;
}
@@ -133,11 +123,24 @@ public class RoleImpl implements RoleFSM
//if one instance of the role starts up fine, we consider the service
//as ready for the 'safe-mode' kinds of checks
StateMachineInvoker.getAMBARIEventHandler().handle(
- new ServiceEvent(ServiceEventType.ROLE_STARTED, service,
+ new ServiceEvent(ServiceEventType.ROLE_START_SUCCESS, service,
operand));
}
}
+ static class FailedStartTransition implements
+ SingleArcTransition<RoleImpl, RoleEvent> {
+
+ @Override
+ public void transition(RoleImpl operand, RoleEvent event) {
+ ServiceFSM service = operand.getAssociatedService();
+ //if one instance of the role starts up fine, we consider the service
+ //as ready for the 'safe-mode' kinds of checks
+ StateMachineInvoker.getAMBARIEventHandler().handle(
+ new ServiceEvent(ServiceEventType.ROLE_START_SUCCESS, service,
+ operand));
+ }
+ }
static class RoleStopTransition implements
SingleArcTransition<RoleImpl, RoleEvent> {
@@ -146,7 +149,7 @@ public class RoleImpl implements RoleFSM
public void transition(RoleImpl operand, RoleEvent event) {
ServiceFSM service = operand.getAssociatedService();
StateMachineInvoker.getAMBARIEventHandler().handle(
- new ServiceEvent(ServiceEventType.ROLE_STOPPED, service,
+ new ServiceEvent(ServiceEventType.ROLE_STOP_SUCCESS, service,
operand));
}
}
@@ -166,7 +169,7 @@ public class RoleImpl implements RoleFSM
@Override
public boolean shouldStop() {
return getRoleState() == RoleState.STOPPING
- || getRoleState() == RoleState.STOPPED;
+ || getRoleState() == RoleState.INACTIVE;
}
@Override
@@ -174,4 +177,5 @@ public class RoleImpl implements RoleFSM
return getRoleState() == RoleState.STARTING
|| getRoleState() == RoleState.ACTIVE;
}
+
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleState.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleState.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleState.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/RoleState.java Fri Dec 9 22:31:56 2011
@@ -18,5 +18,5 @@
package org.apache.ambari.resource.statemachine;
public enum RoleState {
- INACTIVE, STARTING, ACTIVE, FAIL, STOPPING, UNCLEAN_STOP, STOPPED
+ INACTIVE, STARTING, ACTIVE, FAIL, STOPPING,
}
\ No newline at end of file
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceEventType.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceEventType.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceEventType.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceEventType.java Fri Dec 9 22:31:56 2011
@@ -32,26 +32,21 @@ public enum ServiceEventType {
STOP,
//Producer: Service
- START_SUCCESS,
-
- //Producer: Service
- START_FAILURE,
-
- //Producer: Service
AVAILABLE_CHECK_SUCCESS,
//Producer: Service
AVAILABLE_CHECK_FAILURE,
-
- //Producer: Service
- STOP_SUCCESS,
-
- //Producer: Service
- STOP_FAILURE,
-
+
//Producer: Role
- ROLE_STARTED,
-
+ ROLE_START_SUCCESS,
+
+ //Producer: Role
+ ROLE_START_FAILURE,
+
+ //Producer: Role
+ ROLE_STOP_SUCCESS,
+
//Producer: Role
- ROLE_STOPPED
+ ROLE_STOP_FAILURE
+
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceImpl.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceImpl.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceImpl.java Fri Dec 9 22:31:56 2011
@@ -27,26 +27,21 @@ import org.apache.ambari.common.state.Mu
import org.apache.ambari.common.state.SingleArcTransition;
import org.apache.ambari.common.state.StateMachine;
import org.apache.ambari.common.state.StateMachineFactory;
-import org.apache.ambari.components.ComponentPlugin;
-import org.apache.ambari.controller.Cluster;
import org.apache.ambari.event.EventHandler;
public class ServiceImpl implements ServiceFSM, EventHandler<ServiceEvent> {
- private ClusterFSM clusterFsm;
- private ComponentPlugin plugin;
+ private final ClusterFSM clusterFsm;
/* The state machine for the service looks like:
- * INACTIVE --S_START--> PRESTART
+ * INACTIVE or FAIL --S_START--> PRESTART
* PRESTART --S_PRESTART_FAILURE--> FAIL
* PRESTART --S_PRESTART_SUCCESS--> STARTING --S_START_SUCCESS--> STARTED
* --S_START_FAILURE--> FAIL
- * STARTED --S_AVAILABLE--> ACTIVE (check for things like safemode here)
- * STARTED --S_UNAVAILABLE--> FAIL
- * ACTIVE --S_STOP--> STOPPING --S_STOP_SUCCESS--> INACTIVE
- * --S_STOP_FAILURE--> UNCLEAN_STOP
- * FAIL --S_STOP--> STOPPING --S_STOP_SUCCESS--> STOPPED
- * --S_STOP_FAILURE--> UNCLEAN_STOP
+ * STARTED --S_AVAILABLE_CHECK_SUCCESS--> ACTIVE (check for things like safemode here)
+ * STARTED --S_AVAILABLE_CHECK_FAILURE--> FAIL
+ * ACTIVE or FAIL --S_STOP--> STOPPING --S_STOP_SUCCESS--> INACTIVE
+ * --S_STOP_FAILURE--> FAIL
*/
private static final StateMachineFactory
@@ -55,10 +50,10 @@ public class ServiceImpl implements Serv
= new StateMachineFactory<ServiceImpl, ServiceState, ServiceEventType,
ServiceEvent>(ServiceState.INACTIVE)
- .addTransition(ServiceState.INACTIVE, ServiceState.PRESTART,
+ .addTransition(ServiceState.INACTIVE, ServiceState.PRESTART,
ServiceEventType.START)
- .addTransition(ServiceState.STOPPED, ServiceState.PRESTART,
+ .addTransition(ServiceState.FAIL, ServiceState.PRESTART,
ServiceEventType.START)
.addTransition(ServiceState.PRESTART, ServiceState.FAIL,
@@ -66,14 +61,14 @@ public class ServiceImpl implements Serv
.addTransition(ServiceState.PRESTART, ServiceState.STARTING,
ServiceEventType.PRESTART_SUCCESS, new StartServiceTransition())
-
+
.addTransition(ServiceState.STARTING,
EnumSet.of(ServiceState.STARTED, ServiceState.STARTING),
- ServiceEventType.ROLE_STARTED,
+ ServiceEventType.ROLE_START_SUCCESS,
new RoleStartedTransition())
.addTransition(ServiceState.STARTING, ServiceState.FAIL,
- ServiceEventType.START_FAILURE)
+ ServiceEventType.ROLE_START_FAILURE)
.addTransition(ServiceState.STARTED,
ServiceState.ACTIVE,
@@ -86,30 +81,24 @@ public class ServiceImpl implements Serv
new UnavailableTransition())
.addTransition(ServiceState.ACTIVE, ServiceState.ACTIVE,
- ServiceEventType.ROLE_STARTED)
+ ServiceEventType.ROLE_START_SUCCESS)
.addTransition(ServiceState.ACTIVE, ServiceState.STOPPING,
ServiceEventType.STOP, new StopServiceTransition())
.addTransition(ServiceState.STOPPING,
EnumSet.of(ServiceState.INACTIVE, ServiceState.STOPPING),
- ServiceEventType.STOP_SUCCESS,
+ ServiceEventType.ROLE_STOP_SUCCESS,
new RoleStoppedTransition())
- .addTransition(ServiceState.STOPPING, ServiceState.UNCLEAN_STOP,
- ServiceEventType.STOP_FAILURE)
+ .addTransition(ServiceState.STOPPING, ServiceState.FAIL,
+ ServiceEventType.ROLE_STOP_FAILURE)
.addTransition(ServiceState.FAIL, ServiceState.STOPPING,
- ServiceEventType.STOP)
-
- .addTransition(ServiceState.STOPPING, ServiceState.STOPPED,
- ServiceEventType.STOP_SUCCESS)
-
- .addTransition(ServiceState.STOPPED, ServiceState.STOPPED,
- ServiceEventType.STOP_SUCCESS)
+ ServiceEventType.STOP, new StopServiceTransition())
- .addTransition(ServiceState.STOPPING, ServiceState.UNCLEAN_STOP,
- ServiceEventType.STOP_FAILURE)
+ .addTransition(ServiceState.INACTIVE, ServiceState.INACTIVE,
+ ServiceEventType.ROLE_STOP_SUCCESS)
.installTopology();
@@ -118,22 +107,24 @@ public class ServiceImpl implements Serv
private final List<RoleFSM> serviceRoles = new ArrayList<RoleFSM>();
private Iterator<RoleFSM> iterator;
private final String serviceName;
-
- public ServiceImpl(Cluster cluster, ClusterFSM clusterFsm, String serviceName)
+
+ public ServiceImpl(String[] roles, ClusterFSM clusterFsm, String serviceName)
throws IOException {
this.clusterFsm = clusterFsm;
this.serviceName = serviceName;
- //load plugin and get the roles and create them
- this.plugin = cluster.getComponentDefinition(serviceName);
- String[] roles = this.plugin.getActiveRoles();
+ setRoles(roles);
+ stateMachine = stateMachineFactory.make(this);
+ }
+
+ private void setRoles(String[] roles) {
+ serviceRoles.clear();
+ //get the roles for this service
for (String role : roles) {
RoleImpl roleImpl = new RoleImpl(this, role);
serviceRoles.add(roleImpl);
- }
-
- stateMachine = stateMachineFactory.make(this);
+ }
}
-
+
public StateMachine getStateMachine() {
return stateMachine;
}
@@ -157,10 +148,6 @@ public class ServiceImpl implements Serv
public String getServiceName() {
return serviceName;
}
-
- public void addRoles(List<RoleFSM> roles) {
- this.serviceRoles.addAll(roles);
- }
private RoleFSM getFirstRole() {
//this call should reset the iterator
@@ -304,4 +291,5 @@ public class ServiceImpl implements Serv
public List<RoleFSM> getRoles() {
return serviceRoles;
}
+
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceState.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceState.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceState.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/ServiceState.java Fri Dec 9 22:31:56 2011
@@ -18,5 +18,5 @@
package org.apache.ambari.resource.statemachine;
public enum ServiceState {
- INACTIVE, PRESTART, STARTING, STARTED, ACTIVE, FAIL, STOPPING, UNCLEAN_STOP, STOPPED
+ INACTIVE, PRESTART, STARTING, STARTED, ACTIVE, FAIL, STOPPING,
}
\ No newline at end of file
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/StateMachineInvoker.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/StateMachineInvoker.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/StateMachineInvoker.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/resource/statemachine/StateMachineInvoker.java Fri Dec 9 22:31:56 2011
@@ -47,7 +47,14 @@ public class StateMachineInvoker {
private static Dispatcher dispatcher;
private static Log LOG = LogFactory.getLog(StateMachineInvoker.class);
+ public Dispatcher getAMBARIDispatcher() {
+ return dispatcher;
+ }
+ public static void setAMBARIDispatcher(Dispatcher dispatcher1) {
+ dispatcher = dispatcher1;
+ }
+
public static EventHandler getAMBARIEventHandler() {
return dispatcher.getEventHandler();
}
@@ -115,4 +122,7 @@ public class StateMachineInvoker {
long clusterDefinitionRev) {
return clusters.get(clusterId).getClusterState();
}
+
+
+
}
Modified: incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/TestHeartbeat.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/TestHeartbeat.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/TestHeartbeat.java (original)
+++ incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/TestHeartbeat.java Fri Dec 9 22:31:56 2011
@@ -17,6 +17,11 @@
*/
package org.apache.ambari.controller;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -49,12 +54,6 @@ import org.apache.ambari.resource.statem
import org.apache.ambari.resource.statemachine.ServiceFSM;
import org.apache.ambari.resource.statemachine.ServiceState;
import org.apache.ambari.resource.statemachine.StateMachineInvoker;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -206,7 +205,7 @@ public class TestHeartbeat {
ServiceFSM serviceImpl = clusterImpl.getServices().get(0);
((TestServiceImpl)serviceImpl).setServiceState(ServiceState.STARTED);
c.put("cluster1", clusterImpl);
- checkSpecialAction(ServiceState.STARTED, ServiceEventType.ROLE_STARTED,
+ checkSpecialAction(ServiceState.STARTED, ServiceEventType.ROLE_START_SUCCESS,
SpecialServiceIDs.SERVICE_AVAILABILITY_CHECK_ID);
}
Added: incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/NoOpDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/NoOpDispatcher.java?rev=1212669&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/NoOpDispatcher.java (added)
+++ incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/NoOpDispatcher.java Fri Dec 9 22:31:56 2011
@@ -0,0 +1,36 @@
+package org.apache.ambari.resource.statemachine;
+
+import org.apache.ambari.event.Dispatcher;
+import org.apache.ambari.event.Event;
+import org.apache.ambari.event.EventHandler;
+
+/**
+ * To test objects with state in isolation, set this no-op Dispatcher
+ */
+class NoOPDispatcher implements Dispatcher{
+ class NoOPEventHandler implements EventHandler<Event>{
+
+ @Override
+ public void handle(Event event) {
+ //no-op
+ }
+
+ }
+ EventHandler<?> ehandler = new NoOPEventHandler();
+
+ @Override
+ public EventHandler<?> getEventHandler() {
+ return ehandler;
+ }
+
+ @Override
+ public void register(Class<? extends Enum> eventType, EventHandler handler) {
+ //no-op
+ }
+
+ @Override
+ public void start() {
+ //no-op
+ }
+
+}
\ No newline at end of file
Modified: incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImpl.java?rev=1212669&r1=1212668&r2=1212669&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImpl.java (original)
+++ incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImpl.java Fri Dec 9 22:31:56 2011
@@ -6,80 +6,104 @@ import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.ArrayList;
import org.apache.ambari.common.rest.entities.ClusterDefinition;
-import org.apache.ambari.components.ComponentPlugin;
+import org.apache.ambari.common.rest.entities.ClusterState;
import org.apache.ambari.controller.Cluster;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+/**
+ *Test ClusterImpl state transitions
+ */
public class TestClusterImpl {
+
+ ClusterImpl clusterImpl;
+ ClusterEventType [] startEvents = {
+ ClusterEventType.START,
+ ClusterEventType.START_SUCCESS,
+ };
+
+ ClusterStateFSM [] startStates = {
+ ClusterStateFSM.STARTING,
+ ClusterStateFSM.ACTIVE
+ };
+
+
+ @BeforeMethod
+ public void setup() throws IOException{
+ StateMachineInvoker.setAMBARIDispatcher(new NoOPDispatcher());
+
+ ClusterDefinition clusterDef = mock(ClusterDefinition.class);
+ when(clusterDef.getEnabledServices()).thenReturn(new ArrayList<String>());
+ Cluster cluster = mock(Cluster.class);
+ when(cluster.getClusterDefinition(anyInt())).thenReturn(clusterDef);
+ ClusterState clusterState= new ClusterState();
+ clusterImpl = new ClusterImpl(cluster, 1, clusterState);
+ }
+
/**
- * Create cluster with two components, both having active roles.
- * There should be two component objects in the ClusterImpl created
- * @throws IOException
+ * Test INACTIVE to ACTIVE transition
+ * @throws Exception
*/
@Test
- public void testClusterImplWithTwoActiveComponents() throws IOException {
-
- //set component plugin that returns one active role
- ComponentPlugin pluginWActiveRole = mock(ComponentPlugin.class);
- String[] servicesWithActive = {"abc"};
- when(pluginWActiveRole.getActiveRoles()).thenReturn(servicesWithActive);
-
- ClusterImpl clusterImpl = buildClusterImplWithComponents(pluginWActiveRole, pluginWActiveRole);
- assertEquals(clusterImpl.getServices().size(), 2, "number of components with active service");
+ public void testInactiveToActive() throws Exception{
+ verifyTransitions(ClusterStateFSM.INACTIVE, startEvents, startStates);
+ }
+
+ /**
+ * Test FAIL to ACTIVE transition
+ * @throws Exception
+ */
+ @Test
+ public void testFailToActive() throws Exception{
+ verifyTransitions(ClusterStateFSM.FAIL, startEvents, startStates);
}
+ ClusterEventType [] stopEvents = {
+ ClusterEventType.STOP,
+ ClusterEventType.STOP_SUCCESS,
+ };
+
+ ClusterStateFSM [] stopStates = {
+ ClusterStateFSM.STOPPING,
+ ClusterStateFSM.INACTIVE
+ };
+
+
/**
- * Create cluster with two components, only one of which has active role(s)
- * There should be only one component object in the ClusterImpl created
- * @throws IOException
+ * Test ACTIVE to INACTIVE transition
+ * @throws Exception
*/
@Test
- public void testClusterImplWithOneActiveComponents() throws IOException {
-
- //set component plugin that returns one active role
- ComponentPlugin pluginWActiveRole = mock(ComponentPlugin.class);
- String[] servicesWithActive = {"abc"};
- when(pluginWActiveRole.getActiveRoles()).thenReturn(servicesWithActive);
-
- //set component plugin that returns NO active roles
- ComponentPlugin pluginWOActiveRole = mock(ComponentPlugin.class);
- String[] servicesNoActive = {};
- when(pluginWOActiveRole.getActiveRoles()).thenReturn(servicesNoActive);
-
- ClusterImpl clusterImpl = buildClusterImplWithComponents(pluginWActiveRole, pluginWOActiveRole);
- assertEquals(clusterImpl.getServices().size(), 1, "number of components with active service");
-
+ public void testActivetoInactive() throws Exception{
+ verifyTransitions(ClusterStateFSM.ACTIVE, stopEvents, stopStates);
}
-
/**
- * Create a mocked ClusterImpl that has two components, using the ComponentPlugins args
- * @param componentPlugin1 - the ComponentPlugin for first component
- * @param componentPlugin2 - the ComponentPlugin for second component
- * @return the ClusterImpl
- * @throws IOException
+ * Test FAIL to INACTIVE transition
+ * @throws Exception
*/
- private ClusterImpl buildClusterImplWithComponents(
- ComponentPlugin componentPlugin1, ComponentPlugin componentPlugin2)
- throws IOException {
- //set list of components
- ClusterDefinition cdef = mock(ClusterDefinition.class);
- when(cdef.getEnabledServices()).thenReturn(Arrays.asList("comp1","comp2"));
-
- Cluster cluster = mock(Cluster.class);
- when(cluster.getClusterDefinition(anyInt())).thenReturn(cdef);
-
- when(cluster.getComponentDefinition("comp1")).thenReturn(componentPlugin1);
- when(cluster.getComponentDefinition("comp2")).thenReturn(componentPlugin2);
-
- ClusterImpl clusterImpl = new ClusterImpl(cluster, 1, null);
- return clusterImpl;
+ @Test
+ public void testFailtoInactive() throws Exception{
+ verifyTransitions(ClusterStateFSM.FAIL, stopEvents, stopStates);
}
-
+
+ private void verifyTransitions(ClusterStateFSM startState, ClusterEventType[] ClusterEvents,
+ ClusterStateFSM[] ClusterStateFSMs) {
+
+ clusterImpl.getStateMachine().setCurrentState(startState);
+ for(int i=0; i < ClusterEvents.length; i++){
+ ClusterEventType rEvent = ClusterEvents[i];
+ clusterImpl.handle(new ClusterEvent(rEvent, clusterImpl));
+ ClusterStateFSM expectedRState = ClusterStateFSMs[i];
+ assertEquals(clusterImpl.getStateMachine().getCurrentState(), expectedRState);
+ }
+
+ }
+
}
Added: incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImplServiceCreation.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImplServiceCreation.java?rev=1212669&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImplServiceCreation.java (added)
+++ incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestClusterImplServiceCreation.java Fri Dec 9 22:31:56 2011
@@ -0,0 +1,85 @@
+package org.apache.ambari.resource.statemachine;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.ambari.common.rest.entities.ClusterDefinition;
+import org.apache.ambari.components.ComponentPlugin;
+import org.apache.ambari.controller.Cluster;
+import org.testng.annotations.Test;
+
+public class TestClusterImpl {
+
+ /**
+ * Create cluster with two components, both having active roles.
+ * There should be two component objects in the ClusterImpl created
+ * @throws IOException
+ */
+ @Test
+ public void testClusterImplWithTwoActiveComponents() throws IOException {
+
+ //set component plugin that returns one active role
+ ComponentPlugin pluginWActiveRole = mock(ComponentPlugin.class);
+ String[] servicesWithActive = {"abc"};
+ when(pluginWActiveRole.getActiveRoles()).thenReturn(servicesWithActive);
+
+ ClusterImpl clusterImpl = buildClusterImplWithComponents(pluginWActiveRole, pluginWActiveRole);
+ assertEquals(clusterImpl.getServices().size(), 2, "number of components with active service");
+
+ }
+
+ /**
+ * Create cluster with two components, only one of which has active role(s)
+ * There should be only one component object in the ClusterImpl created
+ * @throws IOException
+ */
+ @Test
+ public void testClusterImplWithOneActiveComponents() throws IOException {
+
+ //set component plugin that returns one active role
+ ComponentPlugin pluginWActiveRole = mock(ComponentPlugin.class);
+ String[] servicesWithActive = {"abc"};
+ when(pluginWActiveRole.getActiveRoles()).thenReturn(servicesWithActive);
+
+ //set component plugin that returns NO active roles
+ ComponentPlugin pluginWOActiveRole = mock(ComponentPlugin.class);
+ String[] servicesNoActive = {};
+ when(pluginWOActiveRole.getActiveRoles()).thenReturn(servicesNoActive);
+
+ ClusterImpl clusterImpl = buildClusterImplWithComponents(pluginWActiveRole, pluginWOActiveRole);
+ assertEquals(clusterImpl.getServices().size(), 1, "number of components with active service");
+
+ }
+
+
+
+ /**
+ * Create a mocked ClusterImpl that has two components, using the ComponentPlugins args
+ * @param componentPlugin1 - the ComponentPlugin for first component
+ * @param componentPlugin2 - the ComponentPlugin for second component
+ * @return the ClusterImpl
+ * @throws IOException
+ */
+ private ClusterImpl buildClusterImplWithComponents(
+ ComponentPlugin componentPlugin1, ComponentPlugin componentPlugin2)
+ throws IOException {
+ //set list of components
+ ClusterDefinition cdef = mock(ClusterDefinition.class);
+ when(cdef.getEnabledServices()).thenReturn(Arrays.asList("comp1","comp2"));
+
+ Cluster cluster = mock(Cluster.class);
+ when(cluster.getClusterDefinition(anyInt())).thenReturn(cdef);
+
+ when(cluster.getComponentDefinition("comp1")).thenReturn(componentPlugin1);
+ when(cluster.getComponentDefinition("comp2")).thenReturn(componentPlugin2);
+
+ ClusterImpl clusterImpl = new ClusterImpl(cluster, 1, null);
+ return clusterImpl;
+ }
+
+}
Added: incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestRoleImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestRoleImpl.java?rev=1212669&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestRoleImpl.java (added)
+++ incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestRoleImpl.java Fri Dec 9 22:31:56 2011
@@ -0,0 +1,149 @@
+package org.apache.ambari.resource.statemachine;
+
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.ambari.common.state.InvalidStateTransitonException;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+
+
+public class TestRoleImpl {
+ RoleImpl role;
+
+
+ @BeforeMethod
+ public void setup(){
+ StateMachineInvoker.setAMBARIDispatcher(new NoOPDispatcher());
+ ServiceFSM service = mock(ServiceFSM.class);
+ role = new RoleImpl(service, "role1");
+
+ }
+
+ @Test
+ public void testStateTransitionsInactiveToActive() throws IOException {
+ //from inactive to active
+ verifyTransitions(RoleState.INACTIVE, getEventsForActivate(), getStatesToActive());
+ }
+
+ @Test
+ public void testStateTransitionsFailToActive() throws IOException {
+ //from fail to active
+ verifyTransitions(RoleState.FAIL, getEventsForActivate(), getStatesToActive());
+ }
+
+ @Test
+ public void testStateTransitionsActiveToActive() throws IOException {
+ //start event on active state throws exception
+ verifyTransitionException(RoleState.ACTIVE, getEventsForActivate(), getStatesToActive());
+ }
+
+ RoleEventType[] getEventsForActivate(){
+ //events that would move role to activated
+ RoleEventType[] roleEvents = {RoleEventType.START, RoleEventType.START_SUCCESS};
+ return roleEvents;
+ }
+
+ RoleState[] getStatesToActive(){
+ //states to active state
+ RoleState[] roleStates = {RoleState.STARTING, RoleState.ACTIVE};
+ return roleStates;
+ }
+
+ @Test
+ public void testStateTransitionFailToInactive(){
+ //from fail to inactive
+ verifyTransitions(RoleState.FAIL, getEventsForInActivate(), getStatesToInActive());
+ }
+
+ @Test
+ public void testStateTransitionActiveToInactive(){
+ //from active to inactive
+ verifyTransitions(RoleState.ACTIVE, getEventsForInActivate(), getStatesToInActive());
+ }
+
+ @Test
+ public void testStateTransitionInactiveToInactive(){
+ //inactive to inactive throw exception
+ verifyTransitionException(RoleState.INACTIVE, getEventsForInActivate(), getStatesToInActive());
+ }
+
+
+ RoleEventType[] getEventsForInActivate(){
+ //events that would move role to activated
+ RoleEventType[] roleEvents = {RoleEventType.STOP, RoleEventType.STOP_SUCCESS};
+ return roleEvents;
+ }
+
+ RoleState[] getStatesToInActive(){
+ //states to active state
+ RoleState[] roleStates = {RoleState.STOPPING, RoleState.INACTIVE};
+ return roleStates;
+ }
+
+ @Test
+ public void testStateTransitionInactiveToFail(){
+ RoleEventType[] startFailEvents = {RoleEventType.START, RoleEventType.START_FAILURE};
+ RoleState[] roleStates = {RoleState.STARTING, RoleState.FAIL};
+ //inactive to inactive throw exception
+ verifyTransitions(RoleState.INACTIVE, startFailEvents, roleStates);
+ }
+
+ @Test
+ public void testStateTransitionActiveToFail(){
+ RoleEventType[] startFailEvents = {RoleEventType.STOP, RoleEventType.STOP_FAILURE};
+ RoleState[] roleStates = {RoleState.STOPPING, RoleState.FAIL};
+ //inactive to inactive throw exception
+ verifyTransitions(RoleState.ACTIVE, startFailEvents, roleStates);
+ }
+
+ private void verifyTransitionException(RoleState startState, RoleEventType[] roleEvents,
+ RoleState[] roleStates){
+ boolean foundException = false;
+ try{
+ verifyTransitions(startState, roleEvents, roleStates);
+ }catch(InvalidStateTransitonException e){
+ foundException = true;
+ }
+ assertTrue(foundException, "exception expected");
+ }
+
+ private void verifyTransitions(RoleState startState, RoleEventType[] roleEvents,
+ RoleState[] roleStates) {
+ role.getStateMachine().setCurrentState(startState);
+ for(int i=0; i < roleEvents.length; i++){
+ RoleEventType rEvent = roleEvents[i];
+ role.handle(new RoleEvent(rEvent, role));
+ RoleState expectedRState = roleStates[i];
+ assertEquals(role.getRoleState(), expectedRState);
+ }
+
+ }
+
+
+
+
+
+
+
+// static class RoleImplTestModule extends AbstractModule{
+//
+// @Override
+// protected void configure() {
+// bind(RoleFSM.class).to(RoleImpl.class);
+// bind(ServiceFSM.class).to(ServiceImpl.class);
+// bind(ClusterFSM.class).to(ClusterImpl.class);
+//
+// install(new FactoryModuleBuilder()
+// .implement(Cluster.class,Cluster.class)
+// .build(ClusterFactory.class));
+//
+// }
+//
+// }
+
+}
Added: incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestServiceImpl.java?rev=1212669&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestServiceImpl.java (added)
+++ incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/resource/statemachine/TestServiceImpl.java Fri Dec 9 22:31:56 2011
@@ -0,0 +1,271 @@
+package org.apache.ambari.resource.statemachine;
+
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ *
+ */
+public class TestServiceImpl {
+
+
+ ServiceImpl service;
+ ServiceEventType [] startEvents = {
+ ServiceEventType.START,
+ ServiceEventType.PRESTART_SUCCESS,
+ ServiceEventType.ROLE_START_SUCCESS,
+ ServiceEventType.AVAILABLE_CHECK_SUCCESS
+ };
+
+ ServiceState [] startStates = {
+ ServiceState.PRESTART,
+ ServiceState.STARTING,
+ ServiceState.STARTED,
+ ServiceState.ACTIVE
+ };
+
+
+ @BeforeMethod
+ public void setup() throws IOException{
+ StateMachineInvoker.setAMBARIDispatcher(new NoOPDispatcher());
+ String roles[] = {"role1"};
+ ClusterImpl clusterImpl = mock(ClusterImpl.class);
+ service = new ServiceImpl(roles, clusterImpl, "service1");
+ }
+
+ /**
+ * Test INACTIVE to ACTIVE transition with one role
+ * @throws Exception
+ */
+ @Test
+ public void testInactiveToActiveOneRole() throws Exception{
+ verifyTransitions(ServiceState.INACTIVE, startEvents, startStates);
+ }
+
+ /**
+ * Test INACTIVE to ACTIVE transition with two roles
+ * @throws Exception
+ */
+ @Test
+ public void testInactiveToActiveTwoRole() throws Exception{
+ String roles[] = {"role1", "role2"};
+ setRoles(roles);
+ ServiceEventType [] events = {
+ ServiceEventType.START,
+ ServiceEventType.PRESTART_SUCCESS,
+ ServiceEventType.ROLE_START_SUCCESS, //1st role
+ ServiceEventType.ROLE_START_SUCCESS, //2nd role
+ ServiceEventType.AVAILABLE_CHECK_SUCCESS
+ };
+ ServiceState [] states = {
+ ServiceState.PRESTART,
+ ServiceState.STARTING,
+ ServiceState.STARTING,
+ ServiceState.STARTED,
+ ServiceState.ACTIVE
+ };
+
+ verifyTransitions(ServiceState.INACTIVE, events, states);
+ }
+
+ /**
+ * Test FAIL to ACTIVE transition with one roles
+ * @throws Exception
+ */
+ @Test
+ public void testFailToActiveOneRole() throws Exception{
+ verifyTransitions(ServiceState.FAIL, startEvents, startStates);
+ }
+
+ /**
+ * Test start failure scenario
+ * @throws Exception
+ */
+ @Test
+ public void testInactiveToFail1() throws Exception{
+
+ ServiceEventType[] events = truncateServiceEventArray(startEvents, 2,
+ ServiceEventType.PRESTART_FAILURE);
+
+ ServiceState[] states = getFailedStartSequence(2);
+ verifyTransitions(ServiceState.INACTIVE, events, states);
+
+ }
+
+
+ private ServiceState[] getFailedStartSequence(int i) {
+ return truncateServiceStateArray(startStates, i, ServiceState.FAIL);
+ }
+
+ /**
+ * Test start failure scenario
+ * @throws Exception
+ */
+ @Test
+ public void testInactiveToFail2() throws Exception{
+
+ ServiceEventType[] events = truncateServiceEventArray(startEvents, 3,
+ ServiceEventType.ROLE_START_FAILURE);
+ ServiceState[] states = getFailedStartSequence(3);
+
+ verifyTransitions(ServiceState.INACTIVE, events, states);
+
+ }
+
+
+ /**
+ * Test start failure scenario
+ * @throws Exception
+ */
+ @Test
+ public void testInactiveToFail3() throws Exception{
+
+ ServiceEventType[] events = truncateServiceEventArray(startEvents, 4,
+ ServiceEventType.AVAILABLE_CHECK_FAILURE);
+ ServiceState[] states = getFailedStartSequence(4);
+
+ verifyTransitions(ServiceState.INACTIVE, events, states);
+
+ }
+
+
+ /**
+ * truncate startevents with lenght n and replace with state at position n-1
+ * with newState
+ * @param startEvents
+ * @param n
+ * @param newState
+ * @return
+ */
+ private ServiceEventType[] truncateServiceEventArray(
+ ServiceEventType[] startEvents, int n, ServiceEventType newState) {
+ return truncateArrayAndReplaceLastState(startEvents, n, newState, ServiceEventType.class);
+ }
+
+ private ServiceState[] truncateServiceStateArray(
+ ServiceState[] startEvents2, int n, ServiceState prestartFailure) {
+ return truncateArrayAndReplaceLastState(startStates, n, prestartFailure, ServiceState.class);
+ }
+
+ ServiceEventType [] stopEvents = {
+ ServiceEventType.STOP,
+ ServiceEventType.ROLE_STOP_SUCCESS,
+ };
+
+ ServiceState [] stopStates = {
+ ServiceState.STOPPING,
+ ServiceState.INACTIVE
+ };
+
+
+
+ /**
+ * Test active to inactive transition with one role
+ * @throws Exception
+ */
+ @Test
+ public void testActiveToInactiveOneRole() throws Exception{
+ verifyTransitions(ServiceState.ACTIVE, stopEvents, stopStates);
+ }
+
+ /**
+ * Test fail to inactive transition with one role
+ * @throws Exception
+ */
+ @Test
+ public void testFailToInactiveOneRole() throws Exception{
+ verifyTransitions(ServiceState.FAIL, stopEvents, stopStates);
+ }
+
+ /**
+ * Test failure in stop role
+ * @throws Exception
+ */
+ @Test
+ public void testActiveStopFailure() throws Exception{
+ ServiceEventType [] stopEvents = {
+ ServiceEventType.STOP,
+ ServiceEventType.ROLE_STOP_FAILURE,
+ };
+
+ ServiceState [] stopStates = {
+ ServiceState.STOPPING,
+ ServiceState.FAIL
+ };
+ verifyTransitions(ServiceState.ACTIVE, stopEvents, stopStates);
+ }
+
+
+ /**
+ * Test active to inactive transition with two roles
+ * @throws Exception
+ */
+ @Test
+ public void testActiveToInactiveTwoRoles() throws Exception{
+ String roles[] = {"role1", "role2"};
+ ServiceEventType [] stopEvents = {
+ ServiceEventType.STOP,
+ ServiceEventType.ROLE_STOP_SUCCESS,//1st role
+ ServiceEventType.ROLE_STOP_SUCCESS,//2nd role
+ };
+
+ ServiceState [] stopStates = {
+ ServiceState.STOPPING,
+ ServiceState.STOPPING,
+ ServiceState.INACTIVE
+ };
+
+ setRoles(roles);
+ verifyTransitions(ServiceState.ACTIVE, stopEvents, stopStates);
+ }
+
+
+ /**
+ * truncate inpArr array with length n and replace state at position n-1
+ * with newState
+ * @param inpArr
+ * @param n
+ * @param newState
+ * @param tclass
+ * @return
+ */
+ private<T> T[] truncateArrayAndReplaceLastState(
+ T[] inpArr,
+ int n, T newState, Class<?> tclass) {
+ T[] newEnumArr = Arrays.copyOf(inpArr, n);
+ newEnumArr[n-1] = newState;
+ return newEnumArr;
+ }
+
+ /**
+ * Call ServiceImpl.setRoles private function using reflection
+ * @param roles
+ * @throws Exception
+ */
+ private void setRoles(String[] roles) throws Exception {
+ Method method = ServiceImpl.class.getDeclaredMethod("setRoles", new Class[]{String[].class});
+ method.setAccessible(true);
+ method.invoke(service, new Object[]{roles});
+
+ }
+
+ private void verifyTransitions(ServiceState startState, ServiceEventType[] serviceEvents,
+ ServiceState[] serviceStates) {
+ service.getStateMachine().setCurrentState(startState);
+ for(int i=0; i < serviceEvents.length; i++){
+ ServiceEventType rEvent = serviceEvents[i];
+ service.handle(new ServiceEvent(rEvent, service));
+ ServiceState expectedRState = serviceStates[i];
+ assertEquals(service.getServiceState(), expectedRState);
+ }
+
+ }
+
+}