/** * Creates a new unassigned node in the OFFLINE state for the specified * entityGroup. * * <p> * Does not transition nodes from other states. If a node already exists for * this entityGroup, a {@link org.apache.zookeeper.KeeperException.NodeExistsException} will be thrown. * * <p> * Sets a watcher on the unassigned entityGroup node if the method is * successful. * * <p> * This method should only be used during cluster startup and the enabling of * a table. * * @param zkw zk reference * @param entityGroup entityGroup to be created as offline * @param serverName server transition will happen on * @throws org.apache.zookeeper.KeeperException if unexpected zookeeper exception * @throws org.apache.zookeeper.KeeperException.NodeExistsException if node already exists */ public static void createNodeOffline(ZooKeeperWatcher zkw, EntityGroupInfo entityGroup, ServerName serverName) throws KeeperException, KeeperException.NodeExistsException { createNodeOffline(zkw, entityGroup, serverName, EventType.M_ZK_ENTITYGROUP_OFFLINE); }
/** * Deletes an existing unassigned node that is in the OFFLINE state for the * specified entityGroup. * * <p> * If a node does not already exist for this entityGroup, a * {@link org.apache.zookeeper.KeeperException.NoNodeException} will be thrown. * * <p> * No watcher is set whether this succeeds or not. * * <p> * Returns false if the node was not in the proper state but did exist. * * <p> * This method is used during master failover when the entityGroups on an RS * that has died are all set to OFFLINE before being processed. * * @param zkw zk reference * @param entityGroupName closed entityGroup to be deleted from zk * @throws org.apache.zookeeper.KeeperException if unexpected zookeeper exception * @throws org.apache.zookeeper.KeeperException.NoNodeException if node does not exist */ public static boolean deleteOfflineNode(ZooKeeperWatcher zkw, String entityGroupName) throws KeeperException, KeeperException.NoNodeException { return deleteNode(zkw, entityGroupName, EventType.M_ZK_ENTITYGROUP_OFFLINE); }
/** * @param zkw * @param pathOrEntityGroupName * @return Path to znode */ public static String getPath(final ZooKeeperWatcher zkw, final String pathOrEntityGroupName) { return pathOrEntityGroupName.startsWith("/") ? pathOrEntityGroupName : getNodeName( zkw, pathOrEntityGroupName); }
int versionid = ZKAssign.transitionNodeClosed(this.watcher, ENTITYGROUPINFO, SERVERNAME_A, -1); assertNotSame(versionid, -1); versionid = ZKAssign.getVersion(this.watcher, ENTITYGROUPINFO); assertNotSame(-1, versionid); versionid = ZKAssign.transitionNode(server.getZooKeeper(), ENTITYGROUPINFO, SERVERNAME_A, EventHandler.EventType.M_ZK_ENTITYGROUP_OFFLINE, EventHandler.EventType.FSERVER_ZK_ENTITYGROUP_OPENING, versionid); assertNotSame(-1, versionid); versionid = ZKAssign.transitionNodeOpened(this.watcher, ENTITYGROUPINFO, SERVERNAME_B, versionid); assertNotSame(-1, versionid); am.shutdown(); ZKAssign.deleteAllNodes(this.watcher);
/** * Creates a znode with OPENED state. * * @param TEST_UTIL * @param entityGroup * @param serverName * @return * @throws java.io.IOException * @throws ZooKeeperConnectionException * @throws org.apache.zookeeper.KeeperException * @throws org.apache.zookeeper.KeeperException.NodeExistsException */ public static ZooKeeperWatcher createAndForceNodeToOpenedState( WaspTestingUtility TEST_UTIL, EntityGroup entityGroup, ServerName serverName) throws ZooKeeperConnectionException, IOException, KeeperException, NodeExistsException { ZooKeeperWatcher zkw = getZooKeeperWatcher(TEST_UTIL); ZKAssign.createNodeOffline(zkw, entityGroup.getEntityGroupInfo(), serverName); int version = ZKAssign.transitionNodeOpening(zkw, entityGroup.getEntityGroupInfo(), serverName); ZKAssign.transitionNodeOpened(zkw, entityGroup.getEntityGroupInfo(), serverName, version); return zkw; }
private void openEntityGroup(Server server, FServerServices rss, FTable ftd, EntityGroupInfo egi) throws IOException, NodeExistsException, KeeperException, DeserializationException { // Create it OFFLINE node, which is what Master set before sending OPEN RPC ZKAssign.createNodeOffline(server.getZooKeeper(), egi, server.getServerName()); OpenEntityGroupHandler openHandler = new OpenEntityGroupHandler(server, rss, egi, ftd); openHandler.process(); // This parse is not used? EntityGroupTransaction.parseFrom(ZKAssign.getData(server.getZooKeeper(), egi.getEncodedName())); // delete the node, which is what Master do after the entityGroup is opened ZKAssign.deleteNode(server.getZooKeeper(), egi.getEncodedName(), EventType.FSERVER_ZK_ENTITYGROUP_OPENED); } }
public static int transitionNodeOpening(ZooKeeperWatcher zkw, EntityGroupInfo entityGroup, ServerName serverName, final EventType beginState) throws KeeperException { return transitionNode(zkw, entityGroup, serverName, beginState, EventType.FSERVER_ZK_ENTITYGROUP_OPENING, -1); }
@Test public void testFailedOpenEntityGroup() throws Exception { Server server = new MockServer(WTU); FServerServices rsServices = new MockFServerServices(); // Create it OFFLINE, which is what it expects ZKAssign.createNodeOffline(server.getZooKeeper(), TEST_EGI, server.getServerName()); // Create the handler OpenEntityGroupHandler handler = new OpenEntityGroupHandler(server, rsServices, TEST_EGI, TEST_FTD) { @Override EntityGroup openEntityGroup() { // Fake failure of opening a entityGroup due to an IOE, which is caught return null; } }; handler.process(); // Handler should have transitioned it to FAILED_OPEN EntityGroupTransaction rt = EntityGroupTransaction.parseFrom(ZKAssign .getData(server.getZooKeeper(), TEST_EGI.getEncodedName())); assertEquals(EventType.FSERVER_ZK_ENTITYGROUP_FAILED_OPEN, rt.getEventType()); }
/** * Test if the entityGroup can be closed properly * * @throws java.io.IOException * @throws org.apache.zookeeper.KeeperException.NodeExistsException * @throws org.apache.zookeeper.KeeperException * @throws com.alibaba.wasp.DeserializationException */ @Test public void testCloseEntityGroup() throws IOException, NodeExistsException, KeeperException, DeserializationException { final Server server = new MockServer(WTU); final MockFServerServices rss = new MockFServerServices(); FTable htd = TEST_FTD; EntityGroupInfo egi = TEST_EGI; openEntityGroup(server, rss, htd, egi); int versionOfClosingNode = ZKAssign.createNodeClosing( server.getZooKeeper(), egi, server.getServerName()); CloseEntityGroupHandler handler = new CloseEntityGroupHandler(server, rss, egi, false, true, versionOfClosingNode, EventType.M_FSERVER_CLOSE_ENTITYGROUP); handler.process(); EntityGroupTransaction rt = EntityGroupTransaction.parseFrom(ZKAssign .getData(server.getZooKeeper(), egi.getEncodedName())); assertTrue(rt.getEventType() .equals(EventType.FSERVER_ZK_ENTITYGROUP_CLOSED)); }
String path = ZKAssign.getNodeName(zkw, egi.getEncodedName()); Stat stats = zkw.getRecoverableZooKeeper().exists(path, false); LOG.info("EPHEMERAL NODE BEFORE SERVER ABORT, path=" + path + ", stats=" + stats); EntityGroupTransaction rtd = EntityGroupTransaction.parseFrom(ZKAssign .getData(zkw, egi.getEncodedName()));
HConstants.EMPTY_BYTE_ARRAY); byte[] data = rt.toByteArray(); String node = getNodeName(zkw, entityGroup.getEncodedName()); zkw.sync(node); int version = ZKUtil.checkExists(zkw, node); byte[] bytes = ZKAssign.getData(zkw, entityGroup.getEncodedName()); rt = getEntityGroupTransition(bytes); if (rt.getEventType() != EventType.M_ZK_ENTITYGROUP_OFFLINE) {
/** * Fakes the regionserver-side zk transitions of a region open. * @param w ZooKeeperWatcher to use. * @param sn Name of the regionserver doing the 'opening' * @param egInfo EntityGroup we're 'opening'. * @throws org.apache.zookeeper.KeeperException * @throws com.alibaba.wasp.DeserializationException */ static void fakeEntityGroupServerEntityGroupOpenInZK(FMaster master, final ZooKeeperWatcher w, final ServerName sn, final EntityGroupInfo egInfo) throws KeeperException, DeserializationException, InterruptedException { // Wait till the we region is ready to be open in RIT. waitForEntityGroupPendingOpenInRIT(master.getAssignmentManager(), egInfo.getEncodedName()); // Get current versionid else will fail on transition from OFFLINE to OPENING below int versionid = ZKAssign.getVersion(w, egInfo); assertNotSame(-1, versionid); // This uglyness below is what the openregionhandler on FSERVER side does. I // looked at exposing the method over in openregionhandler but its just a // one liner and its deep over in another package so just repeat it below. versionid = ZKAssign.transitionNode(w, egInfo, sn, EventType.M_ZK_ENTITYGROUP_OFFLINE, EventType.FSERVER_ZK_ENTITYGROUP_OPENING, versionid); assertNotSame(-1, versionid); // Move znode from OPENING to OPENED as FSERVER does on successful open. versionid = ZKAssign.transitionNodeOpened(w, egInfo, sn, versionid); assertNotSame(-1, versionid); // We should be done now. The master open handler will notice the // transition and remove this regions znode. }
LOG.debug(zkw.prefix("Deleting existing unassigned " + "node for " + entityGroupName + " that is in expected state " + expectedState)); String node = getNodeName(zkw, entityGroupName); zkw.sync(node); Stat stat = new Stat(); EntityGroupTransaction rt = getEntityGroupTransition(bytes); EventType et = rt.getEventType(); if (!et.equals(expectedState)) {
when(am.getZKTable()).thenReturn(new ZKTable(zkw)); Stat stat = new Stat(); String nodeName = ZKAssign.getNodeName(zkw, entityGroup .getEntityGroupInfo().getEncodedName()); ZKUtil.getDataAndWatch(zkw, nodeName, stat); stat.getVersion()); ZKAssign.transitionNode(zkw, entityGroup.getEntityGroupInfo(), server.getServerName(), EventType.FSERVER_ZK_ENTITYGROUP_OPENED, EventType.FSERVER_ZK_ENTITYGROUP_OPENED, stat.getVersion());
String node = ZKAssign.getNodeName(watcher, entityGroupInfo.getEncodedName()); Stat stat = new Stat(); byte[] data = ZKAssign.getDataNoWatch(watcher, node, stat); if (data == null) { LOG.warn("Data is null, node " + node + " no longer exists");
ZKAssign.createNodeClosing(zkw, egi, new ServerName("any.old.server", 1234, -1)); ZKAssign.deleteClosingNode(zkw, egi);
@After public void after() throws KeeperException { if (this.watcher != null) { // Clean up all znodes ZKAssign.deleteAllNodes(this.watcher); this.watcher.close(); } }
/** * @param path * @return True if znode is in SPLIT or SPLITTING state. * @throws org.apache.zookeeper.KeeperException * Can happen if the znode went away in meantime. * @throws com.alibaba.wasp.DeserializationException */ private boolean isSplitOrSplitting(final String path) throws KeeperException, DeserializationException { boolean result = false; // This may fail if the SPLIT or SPLITTING znode gets cleaned up before we // can get data from it. byte[] data = ZKAssign.getData(watcher, path); if (data == null) return false; EntityGroupTransaction rt = EntityGroupTransaction.parseFrom(data); switch (rt.getEventType()) { case FSERVER_ZK_ENTITYGROUP_SPLIT: case FSERVER_ZK_ENTITYGROUP_SPLITTING: result = true; break; default: break; } return result; }
return transitionNodeOpening(zkw, entityGroup, serverName, EventType.M_ZK_ENTITYGROUP_OFFLINE);
final EntityGroup entityGroup) { try { if (ZKAssign.transitionNodeClosed(server.getZooKeeper(), entityGroupInfo, server.getServerName(), expectedVersion) == FAILED) { LOG.warn("Completed the CLOSE of a entityGroup but when transitioning from "