ZkBaseDataAccessor<ZNRecord> baseDataAccessor = new ZkBaseDataAccessor<>(zkClient); ZKHelixDataAccessor zkHelixDataAccessor = new ZKHelixDataAccessor(_clusterName, baseDataAccessor); PropertyKey property = zkHelixDataAccessor.keyBuilder().liveInstances(); List<String> liveInstances = zkHelixDataAccessor.getChildNames(property); PropertyKey controllerLeaderKey = zkHelixDataAccessor.keyBuilder().controllerLeader(); LiveInstance controllerLeaderLiveInstance = zkHelixDataAccessor.getProperty(controllerLeaderKey); ControllerInfo controllerInfo = new ControllerInfo();
ZkBaseDataAccessor zkBaseDataAccessor = (ZkBaseDataAccessor) dataAccessor.getBaseDataAccessor(); PropertyKey idealStateKey = dataAccessor.keyBuilder().idealStates(tableName); IdealState previousIdealState = dataAccessor.getProperty(idealStateKey);
PropertyKey liveInstanceKey = _keyBuilder.liveInstance(instanceName); LiveInstance liveInstance = _helixDataAccessor.getProperty(liveInstanceKey); if (liveInstance == null) { return toggle ? PinotResourceManagerResponse.FAILURE : PinotResourceManagerResponse.SUCCESS; PropertyKey instanceCurrentStatesKey = _keyBuilder.currentStates(instanceName, liveInstance.getSessionId()); List<CurrentState> instanceCurrentStates = _helixDataAccessor.getChildValues(instanceCurrentStatesKey); if (instanceCurrentStates == null) {
private void refreshCurrentStatesCache(HelixDataAccessor accessor, Map<String, LiveInstance> liveInstanceMap) { long start = System.currentTimeMillis(); PropertyKey.Builder keyBuilder = accessor.keyBuilder(); Set<PropertyKey> currentStateKeys = new HashSet<>(); for (String instanceName : liveInstanceMap.keySet()) { LiveInstance liveInstance = liveInstanceMap.get(instanceName); String sessionId = liveInstance.getSessionId(); List<String> currentStateNames = accessor.getChildNames(keyBuilder.currentStates(instanceName, sessionId)); for (String currentStateName : currentStateNames) { currentStateKeys.add(keyBuilder.currentState(instanceName, sessionId, currentStateName)); } } // All new entries from zk not cached locally yet should be read from ZK. Set<PropertyKey> reloadKeys = new HashSet<>(currentStateKeys); reloadKeys.removeAll(_currentStateCache.keySet()); Set<PropertyKey> cachedKeys = new HashSet<>(_currentStateCache.keySet()); cachedKeys.retainAll(currentStateKeys); _currentStateCache = Collections.unmodifiableMap( refreshProperties(accessor, new ArrayList<>(reloadKeys), new ArrayList<>(cachedKeys), _currentStateCache)); if (LOG.isDebugEnabled()) { LogUtil.logDebug(LOG, getEventId(), "# of CurrentStates reload: " + reloadKeys.size() + ", skipped:" + ( currentStateKeys.size() - reloadKeys.size()) + ". took " + (System.currentTimeMillis() - start) + " ms to reload new current states for cluster: " + _clusterName); } }
@Override public void addStateModelDef(String clusterName, String stateModelDef, StateModelDefinition stateModel, boolean recreateIfExists) { logger .info("Add StateModelDef {} in cluster {} with StateModel {}.", stateModelDef, clusterName, stateModel == null ? "NULL" : stateModel.toString()); if (!ZKUtil.isClusterSetup(clusterName, _zkClient)) { throw new HelixException("cluster " + clusterName + " is not setup yet"); } String stateModelDefPath = PropertyPathBuilder.stateModelDef(clusterName); String stateModelPath = stateModelDefPath + "/" + stateModelDef; if (_zkClient.exists(stateModelPath)) { if (recreateIfExists) { logger.info( "Operation.State Model directory exists:" + stateModelPath + ", remove and recreate."); _zkClient.deleteRecursively(stateModelPath); } else { logger.info("Skip the operation. State Model directory exists:" + stateModelPath); return; } } HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_zkClient)); Builder keyBuilder = accessor.keyBuilder(); accessor.setProperty(keyBuilder.stateModelDef(stateModelDef), stateModel); }
@Test public void testGroupCommitAddCurrentStateBack() throws InterruptedException { HelixDataAccessor accessor = _manager.getHelixDataAccessor(); Message initMessage = generateMessage("OFFLINE", "ONLINE"); accessor.setProperty( accessor.keyBuilder().message(_participant.getInstanceName(), initMessage.getMsgId()), initMessage); Assert.assertTrue(waitForMessageProcessed(accessor, initMessage.getMsgId())); Message toOffline = generateMessage("ONLINE", "OFFLINE"); accessor.setProperty( accessor.keyBuilder().message(_participant.getInstanceName(), toOffline.getMsgId()), toOffline); Assert.assertTrue(waitForMessageProcessed(accessor, toOffline.getMsgId())); // Consequential 10 messages for (int i = 0; i < 10; i++) { Message dropped = generateMessage("OFFLINE", "DROPPED"); accessor.setProperty( accessor.keyBuilder().message(_participant.getInstanceName(), dropped.getMsgId()), dropped); Assert.assertTrue(waitForMessageProcessed(accessor, dropped.getMsgId())); Assert.assertFalse(accessor.getBaseDataAccessor().exists(accessor.keyBuilder() .currentState(_participant.getInstanceName(), _participant.getSessionId(), WorkflowGenerator.DEFAULT_TGT_DB).getPath(), 0)); } }
@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; }
@Override public boolean verify() throws Exception { for (BuiltInStateModelDefinitions def : BuiltInStateModelDefinitions.values()) { String path = keyBuilder.stateModelDef(def.getStateModelDefinition().getId()).getPath(); boolean exist = baseAccessor.exists(path, 0); if (!exist) { return false; } // make sure MasterSlave is not over-written if (def == BuiltInStateModelDefinitions.MasterSlave) { Stat stat = new Stat(); baseAccessor.get(path, stat, 0); if (stat.getVersion() != 0) { return false; } } } return true; } }, 10 * 1000);
@Test public void testAddedFieldsInCurrentState() { String instanceName = PARTICIPANT_PREFIX + "_" + _startPort; HelixDataAccessor accessor = _manager.getHelixDataAccessor(); LiveInstance liveInstance = accessor.getProperty(accessor.keyBuilder().liveInstance(instanceName)); CurrentState currentState = accessor.getProperty(accessor.keyBuilder() .currentState(instanceName, liveInstance.getSessionId(), WorkflowGenerator.DEFAULT_TGT_DB)); // Test start time should happen after test start time Assert.assertTrue( currentState.getStartTime(WorkflowGenerator.DEFAULT_TGT_DB + "_0") >= _testStartTime); // Test end time is always larger than start time Assert.assertTrue( currentState.getEndTime(WorkflowGenerator.DEFAULT_TGT_DB + "_0") >= currentState .getStartTime(WorkflowGenerator.DEFAULT_TGT_DB + "_0")); // Final state is MASTER, so SLAVE will be the previous state Assert.assertEquals(currentState.getPreviousState(WorkflowGenerator.DEFAULT_TGT_DB + "_0"), "SLAVE"); } }
@Override public boolean createStateModelDef(StateModelDefinition stateModelDef) { String path = PropertyPathBuilder.stateModelDef(_clusterName, stateModelDef.getId()); HelixProperty property = getProperty(new PropertyKey.Builder(_clusterName).stateModelDef(stateModelDef.getId())); // Set new StateModelDefinition if it is different from old one. if (property != null) { // StateModelDefinition need to be updated if (!new StateModelDefinition(property.getRecord()).equals(stateModelDef)) { return stateModelDef.isValid() && _baseDataAccessor .set(path, stateModelDef.getRecord(), AccessOption.PERSISTENT); } } else { // StateModeDefinition does not exist return stateModelDef.isValid() && _baseDataAccessor .create(path, stateModelDef.getRecord(), AccessOption.PERSISTENT); } // StateModelDefinition exists but not need to be updated return true; }
@Override public boolean createStateModelDef(StateModelDefinition stateModelDef) { String path = PropertyPathBuilder.stateModelDef(_clusterName, stateModelDef.getId()); HelixProperty property = getProperty(new PropertyKey.Builder(_clusterName).stateModelDef(stateModelDef.getId())); // Set new StateModelDefinition if it is different from old one. if (property != null) { // StateModelDefinition need to be updated if (!new StateModelDefinition(property.getRecord()).equals(stateModelDef)) { return stateModelDef.isValid() && _baseDataAccessor .set(path, stateModelDef.getRecord(), AccessOption.PERSISTENT); } } else { // StateModeDefinition does not exist return stateModelDef.isValid() && _baseDataAccessor .create(path, stateModelDef.getRecord(), AccessOption.PERSISTENT); } // StateModelDefinition exists but not need to be updated return true; }
@GET @Path("{instanceName}/resources/{resourceName}") public Response getResourceOnInstance(@PathParam("clusterId") String clusterId, @PathParam("instanceName") String instanceName, @PathParam("resourceName") String resourceName) throws IOException { HelixDataAccessor accessor = getDataAccssor(clusterId); List<String> sessionIds = accessor.getChildNames(accessor.keyBuilder().sessions(instanceName)); if (sessionIds == null || sessionIds.size() == 0) { return notFound(); } // Only get resource list from current session id String currentSessionId = sessionIds.get(0); CurrentState resourceCurrentState = accessor .getProperty(accessor.keyBuilder().currentState(instanceName, currentSessionId, resourceName)); if (resourceCurrentState != null) { return JSONRepresentation(resourceCurrentState.getRecord()); } return notFound(); }
private void acquireLeadership(final HelixManager manager, ControllerManagerHelper controllerHelper) { LOG.info(manager.getInstanceName() + " is trying to acquire leadership for cluster: " + manager .getClusterName()); HelixDataAccessor accessor = manager.getHelixDataAccessor(); Builder keyBuilder = accessor.keyBuilder(); while (accessor.getProperty(keyBuilder.controllerLeader()) == null) { if (tryCreateController(manager)) { LOG.info("{} with session {} acquired leadership for cluster: {}", manager.getInstanceName(), manager.getSessionId(), manager.getClusterName()); updateHistory(manager); manager.getHelixDataAccessor().getBaseDataAccessor().reset(); controllerHelper.addListenersToController(_controller); controllerHelper.startControllerTimerTasks(); } } }
@Override public void addInstanceTag(String clusterName, String instanceName, String tag) { logger .info("Add instance tag {} for instance {} in cluster {}.", tag, instanceName, clusterName); if (!ZKUtil.isClusterSetup(clusterName, _zkClient)) { throw new HelixException("cluster " + clusterName + " is not setup yet"); } if (!ZKUtil.isInstanceSetup(_zkClient, clusterName, instanceName, InstanceType.PARTICIPANT)) { throw new HelixException("cluster " + clusterName + " instance " + instanceName + " is not setup yet"); } HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_zkClient)); Builder keyBuilder = accessor.keyBuilder(); InstanceConfig config = accessor.getProperty(keyBuilder.instanceConfig(instanceName)); config.addTag(tag); accessor.setProperty(keyBuilder.instanceConfig(instanceName), config); }
StringRepresentation getSchedulerTasksRepresentation() throws JsonGenerationException, JsonMappingException, IOException { String clusterName = (String) getRequest().getAttributes().get("clusterName"); String instanceName = (String) getRequest().getAttributes().get("instanceName"); ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); List<String> instances = setupTool.getClusterManagementTool().getInstancesInCluster(clusterName); HelixDataAccessor accessor = ClusterRepresentationUtil.getClusterDataAccessor(zkClient, clusterName); LiveInstance liveInstance = accessor.getProperty(accessor.keyBuilder().liveInstance(instanceName)); String sessionId = liveInstance.getSessionId(); StringRepresentation representation = new StringRepresentation("");// (ClusterRepresentationUtil.ObjectToJson(instanceConfigs), // MediaType.APPLICATION_JSON); return representation; }
@Override public boolean verify() { // Newly created node should have a new creating time but with old session. LiveInstance invalidLeaderNode = accessor.getProperty(keyBuilder.controllerLeader()); // node exist if (invalidLeaderNode == null) return false; // node is newly created if (invalidLeaderNode.getStat().getCreationTime() == originalCreationTime) return false; // node has the same session as the old one, so it's invalid if (!invalidLeaderNode.getSessionId().equals(originalSessionId)) return false; return true; } }, 2000));
StringRepresentation getInstanceCurrentStateRepresentation(String clusterName, String instanceName, String resourceGroup) throws JsonGenerationException, JsonMappingException, IOException { ZkClient zkClient = (ZkClient) getRequest().getAttributes().get(RestAdminApplication.ZKCLIENT); String instanceSessionId = ClusterRepresentationUtil.getInstanceSessionId(zkClient, clusterName, instanceName); Builder keyBuilder = new PropertyKey.Builder(clusterName); String message = ClusterRepresentationUtil.getInstancePropertyAsString(zkClient, clusterName, keyBuilder.currentState(instanceName, instanceSessionId, resourceGroup), MediaType.APPLICATION_JSON); StringRepresentation representation = new StringRepresentation(message, MediaType.APPLICATION_JSON); return representation; } }
/** * Assert externalView and currentState for each participant are empty * @param clusterName * @param db * @param participants */ private void assertEmptyCSandEV(String clusterName, String db, MockParticipantManager[] participants) { HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_gZkClient)); PropertyKey.Builder keyBuilder = accessor.keyBuilder(); Assert.assertNull(accessor.getProperty(keyBuilder.externalView(db))); for (MockParticipantManager participant : participants) { String instanceName = participant.getInstanceName(); String sessionId = participant.getSessionId(); Assert.assertNull(accessor.getProperty(keyBuilder.currentState(instanceName, sessionId, db))); } }
@Override public void dropCluster(String clusterName) { logger.info("Deleting cluster {}.", clusterName); HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_zkClient)); Builder keyBuilder = accessor.keyBuilder(); String root = "/" + clusterName; if (accessor.getChildNames(keyBuilder.liveInstances()).size() > 0) { throw new HelixException( "There are still live instances in the cluster, shut them down first."); } if (accessor.getProperty(keyBuilder.controllerLeader()) != null) { throw new HelixException("There are still LEADER in the cluster, shut them down first."); } _zkClient.deleteRecursively(root); }
@Override public void dropCluster(String clusterName) { logger.info("Deleting cluster {}.", clusterName); HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_zkClient)); Builder keyBuilder = accessor.keyBuilder(); String root = "/" + clusterName; if (accessor.getChildNames(keyBuilder.liveInstances()).size() > 0) { throw new HelixException( "There are still live instances in the cluster, shut them down first."); } if (accessor.getProperty(keyBuilder.controllerLeader()) != null) { throw new HelixException("There are still LEADER in the cluster, shut them down first."); } _zkClient.deleteRecursively(root); }