/**
* Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.linkedin.pinot.controller.helix.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.helix.ZNRecord;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.model.StateModelDefinition.StateModelDefinitionProperty;
/**
* Broker resource state model generator describes the transitions for the resources
* broker will serve.
*
* Online to Offline, Online to Dropped
* Offline to Online, Offline to Dropped
*
*
*/
public class PinotHelixBrokerResourceOnlineOfflineStateModelGenerator {
public static final String PINOT_BROKER_RESOURCE_ONLINE_OFFLINE_STATE_MODEL = "BrokerResourceOnlineOfflineStateModel";
public static final String ONLINE_STATE = "ONLINE";
public static final String OFFLINE_STATE = "OFFLINE";
public static final String DROPPED_STATE = "DROPPED";
public static StateModelDefinition generatePinotStateModelDefinition() {
ZNRecord record = new ZNRecord(PINOT_BROKER_RESOURCE_ONLINE_OFFLINE_STATE_MODEL);
/*
* initial state in always offline for an instance.
*
*/
record.setSimpleField(StateModelDefinitionProperty.INITIAL_STATE.toString(), OFFLINE_STATE);
/*
* this is a ondered list of states in which we want the instances to be in. the first entry is
* given the top most priority.
*
*/
List<String> statePriorityList = new ArrayList<String>();
statePriorityList.add(ONLINE_STATE);
statePriorityList.add(OFFLINE_STATE);
statePriorityList.add(DROPPED_STATE);
record.setListField(StateModelDefinitionProperty.STATE_PRIORITY_LIST.toString(), statePriorityList);
/**
*
* If you are wondering what R and -1 signify, here is an explanation -1 means that don't even
* try to keep any instances in this state. R says that all instances in the preference list
* should be in this state.
*
*/
for (String state : statePriorityList) {
String key = state + ".meta";
Map<String, String> metadata = new HashMap<String, String>();
if (state.equals(ONLINE_STATE)) {
metadata.put("count", "R");
record.setMapField(key, metadata);
}
if (state.equals(OFFLINE_STATE)) {
metadata.put("count", "-1");
record.setMapField(key, metadata);
}
if (state.equals(DROPPED_STATE)) {
metadata.put("count", "-1");
record.setMapField(key, metadata);
}
}
/*
* construction a state transition table, this tells the controller the next state given initial
* and final states.
*
*/
for (String state : statePriorityList) {
String key = state + ".next";
if (state.equals(ONLINE_STATE)) {
Map<String, String> metadata = new HashMap<String, String>();
metadata.put(OFFLINE_STATE, OFFLINE_STATE);
metadata.put(DROPPED_STATE, DROPPED_STATE);
record.setMapField(key, metadata);
}
if (state.equals("OFFLINE")) {
Map<String, String> metadata = new HashMap<String, String>();
metadata.put(ONLINE_STATE, ONLINE_STATE);
metadata.put(DROPPED_STATE, DROPPED_STATE);
record.setMapField(key, metadata);
}
}
/*
* This is the transition priority list, again the first inserted gets the top most priority.
*
*/
List<String> stateTransitionPriorityList = new ArrayList<String>();
stateTransitionPriorityList.add("ONLINE-OFFLINE");
stateTransitionPriorityList.add("ONLINE-DROPPED");
stateTransitionPriorityList.add("OFFLINE-ONLINE");
stateTransitionPriorityList.add("OFFLINE-DROPPED");
record.setListField(StateModelDefinitionProperty.STATE_TRANSITION_PRIORITYLIST.toString(),
stateTransitionPriorityList);
return new StateModelDefinition(record);
}
}