use of org.apache.helix.model.LiveInstance in project helix by apache.
the class ZKHelixAdmin method resetPartition.
@Override
public void resetPartition(String clusterName, String instanceName, String resourceName, List<String> partitionNames) {
HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_zkClient));
Builder keyBuilder = accessor.keyBuilder();
// check the instance is alive
LiveInstance liveInstance = accessor.getProperty(keyBuilder.liveInstance(instanceName));
if (liveInstance == null) {
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because " + instanceName + " is not alive");
}
// check resource group exists
IdealState idealState = accessor.getProperty(keyBuilder.idealStates(resourceName));
if (idealState == null) {
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because " + resourceName + " is not added");
}
// check partition exists in resource group
Set<String> resetPartitionNames = new HashSet<String>(partitionNames);
if (idealState.getRebalanceMode() == RebalanceMode.CUSTOMIZED) {
Set<String> partitions = new HashSet<String>(idealState.getRecord().getMapFields().keySet());
if (!partitions.containsAll(resetPartitionNames)) {
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because not all " + partitionNames + " exist");
}
} else {
Set<String> partitions = new HashSet<String>(idealState.getRecord().getListFields().keySet());
if (!partitions.containsAll(resetPartitionNames)) {
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because not all " + partitionNames + " exist");
}
}
// check partition is in ERROR state
String sessionId = liveInstance.getSessionId();
CurrentState curState = accessor.getProperty(keyBuilder.currentState(instanceName, sessionId, resourceName));
for (String partitionName : resetPartitionNames) {
if (!curState.getState(partitionName).equals(HelixDefinedState.ERROR.toString())) {
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because not all " + partitionNames + " are in ERROR state");
}
}
// check stateModelDef exists and get initial state
String stateModelDef = idealState.getStateModelDefRef();
StateModelDefinition stateModel = accessor.getProperty(keyBuilder.stateModelDef(stateModelDef));
if (stateModel == null) {
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because " + stateModelDef + " is NOT found");
}
// check there is no pending messages for the partitions exist
List<Message> messages = accessor.getChildValues(keyBuilder.messages(instanceName));
for (Message message : messages) {
if (!MessageType.STATE_TRANSITION.name().equalsIgnoreCase(message.getMsgType()) || !sessionId.equals(message.getTgtSessionId()) || !resourceName.equals(message.getResourceName()) || !resetPartitionNames.contains(message.getPartitionName())) {
continue;
}
throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because a pending message exists: " + message);
}
String adminName = null;
try {
adminName = InetAddress.getLocalHost().getCanonicalHostName() + "-ADMIN";
} catch (UnknownHostException e) {
// can ignore it
logger.info("Unable to get host name. Will set it to UNKNOWN, mostly ignorable", e);
adminName = "UNKNOWN";
}
List<Message> resetMessages = new ArrayList<Message>();
List<PropertyKey> messageKeys = new ArrayList<PropertyKey>();
for (String partitionName : resetPartitionNames) {
// send ERROR to initialState message
String msgId = UUID.randomUUID().toString();
Message message = new Message(MessageType.STATE_TRANSITION, msgId);
message.setSrcName(adminName);
message.setTgtName(instanceName);
message.setMsgState(MessageState.NEW);
message.setPartitionName(partitionName);
message.setResourceName(resourceName);
message.setTgtSessionId(sessionId);
message.setStateModelDef(stateModelDef);
message.setFromState(HelixDefinedState.ERROR.toString());
message.setToState(stateModel.getInitialState());
message.setStateModelFactoryName(idealState.getStateModelFactoryName());
if (idealState.getResourceGroupName() != null) {
message.setResourceGroupName(idealState.getResourceGroupName());
}
if (idealState.getInstanceGroupTag() != null) {
message.setResourceTag(idealState.getInstanceGroupTag());
}
resetMessages.add(message);
messageKeys.add(keyBuilder.message(instanceName, message.getId()));
}
accessor.setChildren(messageKeys, resetMessages);
}
use of org.apache.helix.model.LiveInstance in project helix by apache.
the class ZKHelixManager method isLeader.
@Override
public boolean isLeader() {
if (_instanceType != InstanceType.CONTROLLER && _instanceType != InstanceType.CONTROLLER_PARTICIPANT) {
return false;
}
if (!isConnected()) {
return false;
}
try {
LiveInstance leader = _dataAccessor.getProperty(_keyBuilder.controllerLeader());
if (leader != null) {
String leaderName = leader.getInstanceName();
String sessionId = leader.getSessionId();
if (leaderName != null && leaderName.equals(_instanceName) && sessionId != null && sessionId.equals(_sessionId)) {
return true;
}
}
} catch (Exception e) {
// log
}
return false;
}
use of org.apache.helix.model.LiveInstance in project helix by apache.
the class DefaultMessagingService method generateMessage.
public Map<InstanceType, List<Message>> generateMessage(final Criteria recipientCriteria, final Message message) {
Map<InstanceType, List<Message>> messagesToSendMap = new HashMap<InstanceType, List<Message>>();
InstanceType instanceType = recipientCriteria.getRecipientInstanceType();
if (instanceType == InstanceType.CONTROLLER) {
List<Message> messages = generateMessagesForController(message);
messagesToSendMap.put(InstanceType.CONTROLLER, messages);
// _dataAccessor.setControllerProperty(PropertyType.MESSAGES,
// newMessage.getRecord(), CreateMode.PERSISTENT);
} else if (instanceType == InstanceType.PARTICIPANT) {
List<Message> messages = new ArrayList<Message>();
List<Map<String, String>> matchedList = _evaluator.evaluateCriteria(recipientCriteria, _manager);
if (!matchedList.isEmpty()) {
Map<String, String> sessionIdMap = new HashMap<String, String>();
if (recipientCriteria.isSessionSpecific()) {
HelixDataAccessor accessor = _manager.getHelixDataAccessor();
Builder keyBuilder = accessor.keyBuilder();
List<LiveInstance> liveInstances = accessor.getChildValues(keyBuilder.liveInstances());
for (LiveInstance liveInstance : liveInstances) {
sessionIdMap.put(liveInstance.getInstanceName(), liveInstance.getSessionId());
}
}
for (Map<String, String> map : matchedList) {
String id = UUID.randomUUID().toString();
Message newMessage = new Message(message.getRecord(), id);
String srcInstanceName = _manager.getInstanceName();
String tgtInstanceName = map.get("instanceName");
// Don't send message to self
if (recipientCriteria.isSelfExcluded() && srcInstanceName.equalsIgnoreCase(tgtInstanceName)) {
continue;
}
newMessage.setSrcName(srcInstanceName);
newMessage.setTgtName(tgtInstanceName);
newMessage.setResourceName(map.get("resourceName"));
newMessage.setPartitionName(map.get("partitionName"));
if (recipientCriteria.isSessionSpecific()) {
newMessage.setTgtSessionId(sessionIdMap.get(tgtInstanceName));
}
messages.add(newMessage);
}
messagesToSendMap.put(InstanceType.PARTICIPANT, messages);
}
}
return messagesToSendMap;
}
use of org.apache.helix.model.LiveInstance in project helix by apache.
the class DistributedLeaderElection method tryUpdateController.
private boolean tryUpdateController(HelixManager manager) {
HelixDataAccessor accessor = manager.getHelixDataAccessor();
Builder keyBuilder = accessor.keyBuilder();
LiveInstance leader = new LiveInstance(manager.getInstanceName());
try {
leader.setLiveInstance(ManagementFactory.getRuntimeMXBean().getName());
leader.setSessionId(manager.getSessionId());
leader.setHelixVersion(manager.getVersion());
boolean success = accessor.createControllerLeader(leader);
if (success) {
return true;
} else {
LOG.info("Unable to become leader probably because some other controller becames the leader");
}
} catch (Exception e) {
LOG.error("Exception when trying to updating leader record in cluster:" + manager.getClusterName() + ". Need to check again whether leader node has been created or not", e);
}
leader = accessor.getProperty(keyBuilder.controllerLeader());
if (leader != null) {
String leaderSessionId = leader.getSessionId();
LOG.info("Leader exists for cluster: " + manager.getClusterName() + ", currentLeader: " + leader.getInstanceName() + ", leaderSessionId: " + leaderSessionId);
if (leaderSessionId != null && leaderSessionId.equals(manager.getSessionId())) {
return true;
}
}
return false;
}
use of org.apache.helix.model.LiveInstance in project helix by apache.
the class ParticipantManager method createLiveInstance.
private void createLiveInstance() {
String liveInstancePath = _keyBuilder.liveInstance(_instanceName).getPath();
LiveInstance liveInstance = new LiveInstance(_instanceName);
liveInstance.setSessionId(_sessionId);
liveInstance.setHelixVersion(_manager.getVersion());
liveInstance.setLiveInstance(ManagementFactory.getRuntimeMXBean().getName());
// LiveInstanceInfoProvider liveInstanceInfoProvider = _manager._liveInstanceInfoProvider;
if (_liveInstanceInfoProvider != null) {
LOG.info("invoke liveInstanceInfoProvider");
ZNRecord additionalLiveInstanceInfo = _liveInstanceInfoProvider.getAdditionalLiveInstanceInfo();
if (additionalLiveInstanceInfo != null) {
additionalLiveInstanceInfo.merge(liveInstance.getRecord());
ZNRecord mergedLiveInstance = new ZNRecord(additionalLiveInstanceInfo, _instanceName);
liveInstance = new LiveInstance(mergedLiveInstance);
LOG.info("instanceName: " + _instanceName + ", mergedLiveInstance: " + liveInstance);
}
}
boolean retry;
do {
retry = false;
try {
_zkclient.createEphemeral(liveInstancePath, liveInstance.getRecord());
LOG.info("LiveInstance created, path: " + liveInstancePath + ", sessionId: " + liveInstance.getSessionId());
} catch (ZkNodeExistsException e) {
LOG.warn("found another instance with same instanceName: " + _instanceName + " in cluster " + _clusterName);
Stat stat = new Stat();
ZNRecord record = _zkclient.readData(liveInstancePath, stat, true);
if (record == null) {
/**
* live-instance is gone as we check it, retry create live-instance
*/
retry = true;
} else {
String ephemeralOwner = Long.toHexString(stat.getEphemeralOwner());
if (ephemeralOwner.equals(_sessionId)) {
/**
* update sessionId field in live-instance if necessary
*/
LiveInstance curLiveInstance = new LiveInstance(record);
if (!curLiveInstance.getSessionId().equals(_sessionId)) {
/**
* in last handle-new-session,
* live-instance is created by new zkconnection with stale session-id inside
* just update session-id field
*/
LOG.info("overwriting session-id by ephemeralOwner: " + ephemeralOwner + ", old-sessionId: " + curLiveInstance.getSessionId() + ", new-sessionId: " + _sessionId);
curLiveInstance.setSessionId(_sessionId);
_zkclient.writeData(liveInstancePath, curLiveInstance.getRecord());
}
} else {
/**
* wait for a while, in case previous helix-participant exits unexpectedly
* and its live-instance still hangs around until session timeout
*/
try {
TimeUnit.MILLISECONDS.sleep(_sessionTimeout + 5000);
} catch (InterruptedException ex) {
LOG.warn("Sleep interrupted while waiting for previous live-instance to go away.", ex);
}
/**
* give a last try after exit while loop
*/
retry = true;
break;
}
}
}
} while (retry);
/**
* give a last shot
*/
if (retry) {
try {
_zkclient.createEphemeral(liveInstancePath, liveInstance.getRecord());
LOG.info("LiveInstance created, path: " + liveInstancePath + ", sessionId: " + liveInstance.getSessionId());
} catch (Exception e) {
String errorMessage = "instance: " + _instanceName + " already has a live-instance in cluster " + _clusterName;
LOG.error(errorMessage);
throw new HelixException(errorMessage);
}
}
ParticipantHistory history = getHistory();
history.reportOnline(_sessionId, _manager.getVersion());
persistHistory(history);
}
Aggregations