String node = getNodeName(zkw, encoded);
zkw.sync(node);
// Read existing data of the node
Stat stat = new Stat();
byte [] existingBytes = ZKUtil.getDataNoWatch(zkw, node, stat);
if (existingBytes == null) {
// Node no longer exists. Return -1. It means unsuccessful transition.
return -1;
}
// Verify it is the expected version
if (expectedVersion != -1 && stat.getVersion() != expectedVersion) {
LOG.warn(zkw.prefix("Attempt to transition the " +
"unassigned node for " + encoded +
" from " + beginState + " to " + endState + " failed, " +
"the node existed but was version " + stat.getVersion() +
" not the expected version " + expectedVersion));
return -1;
}
if (beginState.equals(EventType.M_ZK_REGION_OFFLINE)
&& endState.equals(EventType.RS_ZK_REGION_OPENING)
&& expectedVersion == -1 && stat.getVersion() != 0) {
// the below check ensures that double assignment doesnot happen.
// When the node is created for the first time then the expected version
// that is passed will be -1 and the version in znode will be 0.
// In all other cases the version in znode will be > 0.
LOG.warn(zkw.prefix("Attempt to transition the " + "unassigned node for "
+ encoded + " from " + beginState + " to " + endState + " failed, "
+ "the node existed but was version " + stat.getVersion()
+ " not the expected version " + expectedVersion));
return -1;
}
RegionTransition rt = getRegionTransition(existingBytes);
// Verify the server transition happens on is not changed
if (!rt.getServerName().equals(serverName)) {
LOG.warn(zkw.prefix("Attempt to transition the " +
"unassigned node for " + encoded +
" from " + beginState + " to " + endState + " failed, " +
"the server that tried to transition was " + serverName +
" not the expected " + rt.getServerName()));
return -1;
}
// Verify it is in expected state
EventType et = rt.getEventType();
if (!et.equals(beginState)) {
String existingServer = (rt.getServerName() == null)
? "<unknown>" : rt.getServerName().toString();
LOG.warn(zkw.prefix("Attempt to transition the unassigned node for " + encoded
+ " from " + beginState + " to " + endState + " failed, the node existed but"
+ " was in the state " + et + " set by the server " + existingServer));
return -1;
}
// Write new data, ensuring data has not changed since we last read it
try {
rt = RegionTransition.createRegionTransition(
endState, region.getRegionName(), serverName, payload);
if(!ZKUtil.setData(zkw, node, rt.toByteArray(), stat.getVersion())) {
LOG.warn(zkw.prefix("Attempt to transition the " +
"unassigned node for " + encoded +
" from " + beginState + " to " + endState + " failed, " +
"the node existed and was in the expected state but then when " +
"setting data we got a version mismatch"));
return -1;
}
if(LOG.isDebugEnabled()) {
LOG.debug(zkw.prefix("Transitioned node " + encoded +
" from " + beginState + " to " + endState));
}
return stat.getVersion() + 1;
} catch (KeeperException.NoNodeException nne) {
LOG.warn(zkw.prefix("Attempt to transition the " +
"unassigned node for " + encoded +
" from " + beginState + " to " + endState + " failed, " +
"the node existed and was in the expected state but then when " +