Can you paste the NodeState class. Quickstart has pretty much the same code
and that works. The only difference in your case are the names LEADER -->
MASTER, FOLLOWER --> SLAVE.
StateModelDefinition.Builder builder = new
StateModelDefinition.Builder(STATE_MODEL_NAME);
// Add states and their rank to indicate priority. Lower the rank
higher the
// priority
builder.addState(MASTER, 1);
builder.addState(SLAVE, 2);
builder.addState(OFFLINE);
builder.addState(DROPPED);
// Set the initial state when the node starts
builder.initialState(OFFLINE);
// Add transitions between the states.
builder.addTransition(OFFLINE, SLAVE);
builder.addTransition(SLAVE, OFFLINE);
builder.addTransition(SLAVE, MASTER);
builder.addTransition(MASTER, SLAVE);
builder.addTransition(OFFLINE, DROPPED);
// set constraints on states.
// static constraint
builder.upperBound(MASTER, 1);
// dynamic constraint, R means it should be derived based on the
replication
// factor.
builder.dynamicUpperBound(SLAVE, "R");
On Tue, Feb 18, 2014 at 10:55 PM, Sandeep Nayak <[email protected]> wrote:
> Hi guys,
>
> I have the following states for my instances
>
> StateModelDefinition.Builder builder = new StateModelDefinition.Builder(
> NODE_STATE_MODEL);
>
> builder.initialState(NodeState.OFFLINE.label());
>
> builder.addState(NodeState.LEADER.label(), 1);
>
> builder.addState(NodeState.FOLLOWER.label(), 2);
>
> builder.addState(NodeState.OFFLINE.label());
>
> builder.addState(NodeState.DROPPED.label());
>
> //State transitions
>
> builder.addTransition(NodeState.OFFLINE.label(),NodeState.FOLLOWER
> .label());
>
> builder.addTransition(NodeState.FOLLOWER.label(),NodeState.OFFLINE
> .label());
>
> builder.addTransition(NodeState.FOLLOWER.label(), NodeState.LEADER
> .label());
>
> builder.addTransition(NodeState.LEADER.label(), NodeState.FOLLOWER
> .label());
>
> builder.addTransition(NodeState.OFFLINE.label(), NodeState.DROPPED
> .label());
>
> builder.upperBound(NodeState.LEADER.label(), 1);
>
> builder.dynamicUpperBound(NodeState.FOLLOWER.label(), "R");
>
> stateModelDefinition = builder.build();
>
> if(admin.getStateModelDef(clusterName, stateModelDefinition.getId())
> == null){
>
> admin.addStateModelDef(clusterName, NODE_STATE_MODEL,
> stateModelDefinition);
>
> }
>
>
> The addStateModelDef fails with the following exception
>
> ERROR org.apache.helix.model.util.StateModelDefinitionValidator - Defined
> states does not include the DROPPED state, state model: Node-State-Model
>
> org.apache.helix.HelixException: The ZNRecord for STATEMODELDEFS is not
> valid.
>
> at org.apache.helix.manager.zk.ZKHelixDataAccessor.setProperty(
> ZKHelixDataAccessor.java:97)
>
> at org.apache.helix.manager.zk.ZKHelixAdmin.addStateModelDef(
> ZKHelixAdmin.java:698)
>
>
> Any idea what I am doing wrong?
>
> On a separate note a few things to note
>
> (1) we should have symmetry on the APIs, the getStateModelDef does return
> null and does not throw an exception like the getInstanceConfig if it does
> not find the state model def.
>
> (2) Should the validation happen in the builder? So that it fails early?
>
>
> Thanks,
>
> Sandeep
>