public static void addFakeBrokerInstancesToAutoJoinHelixCluster( String helixClusterName, String zkServer, int numInstances, boolean isSingleTenant) throws Exception { for (int i = 0; i < numInstances; ++i) { final String brokerId = "Broker_localhost_" + i; final HelixManager helixZkManager = HelixManagerFactory.getZKHelixManager( helixClusterName, brokerId, InstanceType.PARTICIPANT, zkServer); final StateMachineEngine stateMachineEngine = helixZkManager.getStateMachineEngine(); final StateModelFactory<?> stateModelFactory = new EmptyBrokerOnlineOfflineStateModelFactory(); stateMachineEngine.registerStateModelFactory( EmptyBrokerOnlineOfflineStateModelFactory.getStateModelDef(), stateModelFactory); helixZkManager.connect(); if (isSingleTenant) { helixZkManager .getClusterManagmentTool() .addInstanceTag( helixClusterName, brokerId, ControllerTenantNameBuilder.getBrokerTenantNameForTenant( ControllerTenantNameBuilder.DEFAULT_TENANT_NAME)); } else { helixZkManager .getClusterManagmentTool() .addInstanceTag(helixClusterName, brokerId, UNTAGGED_BROKER_INSTANCE); } Thread.sleep(1000); } }
private HelixManager createParticipant(String clusterName, String instanceName) { HelixManager participant = new ZKHelixManager(clusterName, instanceName, InstanceType.PARTICIPANT, ZK_ADDR); participant .getStateMachineEngine() .registerStateModelFactory("OnlineOffline", new MockStateModelFactory()); return participant; }
@Override public void broadcast( final String serviceId, final MessageType type, final Map<String, String> content, final int timeOut, final AsyncCallback callback) { participantManager .getMessagingService() .send( buildCriteria(), buildMessage(serviceId, type, content), new org.apache.helix.messaging.AsyncCallback() { @Override public void onTimeOut() { callback.onTimeOut(); } @Override public void onReplyMessage(final Message message) { final MessageType type = buildMessageTypeFromReply(message); final Map<String, String> map = getMessageContent(message); callback.onReply(type, map); } }, timeOut); }
void start() { try { participantManager .getMessagingService() .registerMessageHandlerFactory( Message.MessageType.USER_DEFINE_MSG.toString(), new MessageHandlerResolverWrapper().convert()); participantManager .getStateMachineEngine() .registerStateModelFactory("LeaderStandby", new LockTransitionalFactory()); participantManager.connect(); offlinePartition(); } catch (final Exception ex) { throw new RuntimeException(ex); } }
@BeforeMethod() public void setup() { String clusterName = "testCluster-" + UUID.randomUUID().toString(); manager = new Mocks.MockManager(clusterName); accessor = manager.getHelixDataAccessor(); event = new ClusterEvent("sampleEvent"); }
@Override public void broadcast( final String serviceId, final MessageType type, final Map<String, String> content) { participantManager .getMessagingService() .send(buildCriteria(), buildMessage(serviceId, type, content)); }
void setHealthData2(int[] val1) { for (int i = 0; i < NODE_NR; i++) { String instanceName = PARTICIPANT_PREFIX + "_" + (START_PORT + i); HelixManager manager = _startCMResultMap.get(instanceName)._manager; ZNRecord record = new ZNRecord(_stat); Map<String, String> valMap = new HashMap<String, String>(); valMap.put(metricName2, val1[i] + ""); record.setSimpleField("TimeStamp", new Date().getTime() + ""); record.setMapField("TestStat@DB=TestDB;Partition=TestDB_3", valMap); HelixDataAccessor helixDataAccessor = manager.getHelixDataAccessor(); Builder keyBuilder = helixDataAccessor.keyBuilder(); helixDataAccessor.setProperty( keyBuilder.healthReport(manager.getInstanceName(), record.getId()), new HealthStat(record)); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
@Test public void simpleIntegrationTest() throws Exception { // Logger.getRootLogger().setLevel(Level.INFO); String className = TestHelper.getTestClassName(); String methodName = TestHelper.getTestMethodName(); String clusterName = className + "_" + methodName; int n = 1; System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis())); TestHelper.setupCluster( clusterName, _zkaddr, 12918, // participant port "localhost", // participant name prefix "TestDB", // resource name prefix 1, // resources 4, // partitions per resource n, // number of nodes 1, // replicas "MasterSlave", true); // do rebalance HelixManager participant = new ZKHelixManager(clusterName, "localhost_12918", InstanceType.PARTICIPANT, _zkaddr); participant .getStateMachineEngine() .registerStateModelFactory(StateModelDefId.MasterSlave, new MockMSModelFactory()); participant.connect(); HelixManager controller = new ZKHelixManager(clusterName, "controller_0", InstanceType.CONTROLLER, _zkaddr); controller.connect(); boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(_zkaddr, clusterName)); Assert.assertTrue(result); // cleanup controller.disconnect(); participant.disconnect(); // verify all live-instances and leader nodes are gone ZKHelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, _baseAccessor); PropertyKey.Builder keyBuilder = accessor.keyBuilder(); Assert.assertNull(accessor.getProperty(keyBuilder.liveInstance("localhost_12918"))); Assert.assertNull(accessor.getProperty(keyBuilder.controllerLeader())); System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis())); }
private void enablePartition() { if ("LEADER".equals(getNodeStatus())) { return; } participantManager .getClusterManagmentTool() .enablePartition( true, clusterName, instanceName, resourceName, asList(resourceName + "_0")); while (!"LEADER".equals(getNodeStatus())) { try { Thread.sleep(10); } catch (InterruptedException e) { } } }
public static void addFakeDataInstancesToAutoJoinHelixCluster( String helixClusterName, String zkServer, int numInstances, boolean isSingleTenant, int adminPort) throws Exception { for (int i = 0; i < numInstances; ++i) { final String instanceId = "Server_localhost_" + i; final HelixManager helixZkManager = HelixManagerFactory.getZKHelixManager( helixClusterName, instanceId, InstanceType.PARTICIPANT, zkServer); final StateMachineEngine stateMachineEngine = helixZkManager.getStateMachineEngine(); final StateModelFactory<?> stateModelFactory = new EmptySegmentOnlineOfflineStateModelFactory(); stateMachineEngine.registerStateModelFactory( EmptySegmentOnlineOfflineStateModelFactory.getStateModelDef(), stateModelFactory); helixZkManager.connect(); if (isSingleTenant) { helixZkManager .getClusterManagmentTool() .addInstanceTag( helixClusterName, instanceId, TableNameBuilder.OFFLINE_TABLE_NAME_BUILDER.forTable( ControllerTenantNameBuilder.DEFAULT_TENANT_NAME)); helixZkManager .getClusterManagmentTool() .addInstanceTag( helixClusterName, instanceId, TableNameBuilder.REALTIME_TABLE_NAME_BUILDER.forTable( ControllerTenantNameBuilder.DEFAULT_TENANT_NAME)); } else { helixZkManager .getClusterManagmentTool() .addInstanceTag(helixClusterName, instanceId, UNTAGGED_SERVER_INSTANCE); } HelixConfigScope scope = new HelixConfigScopeBuilder( HelixConfigScope.ConfigScopeProperty.PARTICIPANT, helixClusterName) .forParticipant(instanceId) .build(); Map<String, String> props = new HashMap<>(); props.put(CommonConstants.Helix.Instance.ADMIN_PORT_KEY, String.valueOf(adminPort + i)); helixZkManager.getClusterManagmentTool().setConfig(scope, props); } }
private void addInstanceTagIfNeeded(String clusterName, String instanceName) { InstanceConfig instanceConfig = _helixAdmin.getInstanceConfig(clusterName, instanceName); List<String> instanceTags = instanceConfig.getTags(); if (instanceTags == null || instanceTags.isEmpty()) { if (ZKMetadataProvider.getClusterTenantIsolationEnabled( _helixManager.getHelixPropertyStore())) { _helixAdmin.addInstanceTag( clusterName, instanceName, ControllerTenantNameBuilder.getBrokerTenantNameForTenant( ControllerTenantNameBuilder.DEFAULT_TENANT_NAME)); } else { _helixAdmin.addInstanceTag( clusterName, instanceName, CommonConstants.Helix.UNTAGGED_BROKER_INSTANCE); } } }
private void disablePartition() { String nodeStatus = getNodeStatus(); if ("STANDBY".equals(nodeStatus) || "OFFLINE".equals(nodeStatus)) { return; } participantManager .getClusterManagmentTool() .enablePartition( false, clusterName, instanceName, resourceName, asList(resourceName + "_0")); while (!("STANDBY".equals(nodeStatus) || "OFFLINE".equals(nodeStatus))) { try { Thread.sleep(10); nodeStatus = getNodeStatus(); } catch (InterruptedException e) { } } }
@Override public void broadcastAndWait( final String serviceId, final MessageType type, final Map<String, String> content, int timeOut) { participantManager .getMessagingService() .sendAndWait( buildCriteria(), buildMessage(serviceId, type, content), new org.apache.helix.messaging.AsyncCallback(timeOut) { @Override public void onTimeOut() {} @Override public void onReplyMessage(final Message message) {} }, timeOut); }
@Override public void onCallback(NotificationContext context) { LOG.info( "START: MasterSlaveRebalancer.onCallback running at " + _context.getHelixManager().getInstanceName()); if (context.getType().equals(NotificationContext.Type.FINALIZE)) { LOG.info( "END: MasterSlaveRebalancer.onCallback FINALIZE callback invoked. Likely lost connection to Helix"); return; } HelixManager manager = context.getManager(); String clusterName = manager.getClusterName(); HelixAdmin helixAdmin = manager.getClusterManagmentTool(); IdealState idealState = helixAdmin.getResourceIdealState(clusterName, MySQLConstants.MASTER_SLAVE_RESOURCE_NAME); if (idealState == null) { LOG.info( "END: MasterSlaveRebalancer.onCallback. " + MySQLConstants.MASTER_SLAVE_RESOURCE_NAME + " is not yet created"); } PropertyKey.Builder builder = new PropertyKey.Builder(clusterName); Map<String, LiveInstance> liveInstancesMap = manager.getHelixDataAccessor().getChildValuesMap(builder.liveInstances()); Map<String, InstanceConfig> instanceConfigs = manager.getHelixDataAccessor().getChildValuesMap(builder.instanceConfigs()); IdealState newIdealState = new IdealState(idealState.getId()); newIdealState.getRecord().setSimpleFields(idealState.getRecord().getSimpleFields()); newIdealState.getRecord().setListFields(idealState.getRecord().getListFields()); for (String partition : idealState.getPartitionSet()) { Map<String, String> instanceStateMap = idealState.getInstanceStateMap(partition); String currMaster = null; Set<String> slaveSet = new TreeSet<String>(); for (String instance : instanceStateMap.keySet()) { if ("MASTER".equalsIgnoreCase(instanceStateMap.get(instance))) { currMaster = instance; } if ("SLAVE".equalsIgnoreCase(instanceStateMap.get(instance))) { slaveSet.add(instance); } } String newMaster = currMaster; if (!liveInstancesMap.containsKey(currMaster) || !instanceConfigs.get(currMaster).getInstanceEnabled()) { // need to find a new master. newMaster = findNewMaster(liveInstancesMap, instanceConfigs, currMaster, slaveSet); } for (String instance : instanceStateMap.keySet()) { if (instance.equalsIgnoreCase(newMaster)) { newIdealState.setPartitionState(partition, instance, "MASTER"); } else { newIdealState.setPartitionState(partition, instance, "SLAVE"); } } } if (!idealState.equals(newIdealState)) { LOG.info("New idealstate computed."); LOG.info(newIdealState.toString()); manager .getClusterManagmentTool() .setResourceIdealState( clusterName, MySQLConstants.MASTER_SLAVE_RESOURCE_NAME, newIdealState); } else { LOG.info("No change in IdealState"); } LOG.info("END: MasterSlaveRebalancer.onCallback"); }
@Test public void testZKReconnect() throws Exception { final AtomicReference<ZkServer> zkServerRef = new AtomicReference<ZkServer>(); final int zkPort = TestHelper.getRandomPort(); final String zkAddr = String.format("localhost:%d", zkPort); ZkServer zkServer = TestHelper.startZkServer(zkAddr); zkServerRef.set(zkServer); String className = TestHelper.getTestClassName(); String methodName = TestHelper.getTestMethodName(); String clusterName = className + "_" + methodName; // Setup cluster LOG.info("Setup clusters"); ClusterSetup clusterSetup = new ClusterSetup(zkAddr); clusterSetup.addCluster(clusterName, true); // Registers and starts controller LOG.info("Starts controller"); HelixManager controller = HelixManagerFactory.getZKHelixManager(clusterName, null, InstanceType.CONTROLLER, zkAddr); controller.connect(); // Registers and starts participant LOG.info("Starts participant"); String hostname = "localhost"; String instanceId = String.format("%s_%d", hostname, 1); clusterSetup.addInstanceToCluster(clusterName, instanceId); HelixManager participant = HelixManagerFactory.getZKHelixManager( clusterName, instanceId, InstanceType.PARTICIPANT, zkAddr); participant.connect(); LOG.info("Register state machine"); final CountDownLatch latch = new CountDownLatch(1); participant .getStateMachineEngine() .registerStateModelFactory( "OnlineOffline", new StateModelFactory<StateModel>() { @Override public StateModel createNewStateModel(String stateUnitKey) { return new SimpleStateModel(latch); } }, "test"); String resourceName = "test-resource"; LOG.info("Ideal state assignment"); HelixAdmin helixAdmin = participant.getClusterManagmentTool(); helixAdmin.addResource( clusterName, resourceName, 1, "OnlineOffline", IdealState.RebalanceMode.CUSTOMIZED.toString()); IdealState idealState = helixAdmin.getResourceIdealState(clusterName, resourceName); idealState.setReplicas("1"); idealState.setStateModelFactoryName("test"); idealState.setPartitionState(resourceName + "_0", instanceId, "ONLINE"); LOG.info("Shutdown ZK server"); TestHelper.stopZkServer(zkServerRef.get()); Executors.newSingleThreadScheduledExecutor() .schedule( new Runnable() { @Override public void run() { try { LOG.info("Restart ZK server"); // zkServer.set(TestUtils.startZookeeper(zkDir, zkPort)); zkServerRef.set(TestHelper.startZkServer(zkAddr, null, false)); } catch (Exception e) { LOG.error(e.getMessage(), e); } } }, 2L, TimeUnit.SECONDS); // future.get(); LOG.info("Before update ideal state"); helixAdmin.setResourceIdealState(clusterName, resourceName, idealState); LOG.info("After update ideal state"); LOG.info("Wait for OFFLINE->ONLINE state transition"); try { Assert.assertTrue(latch.await(10, TimeUnit.SECONDS)); // wait until stable state boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(zkAddr, clusterName)); Assert.assertTrue(result); } finally { participant.disconnect(); zkServerRef.get().shutdown(); } }
@Test public void testAlertActionDisableNode() throws InterruptedException { ConfigScope scope = new ConfigScopeBuilder().forCluster(CLUSTER_NAME).build(); Map<String, String> properties = new HashMap<String, String>(); properties.put("healthChange.enabled", "true"); _setupTool.getClusterManagementTool().setConfig(scope, properties); String alertStr1 = "EXP(decay(1.0)(localhost_*.TestStat@DB=db1.TestMetric1))CMP(GREATER)CON(20)ACTION(DISABLE_INSTANCE)"; String alertStr2 = "EXP(decay(1.0)(localhost_*.TestStat@DB=db1.TestMetric2))CMP(GREATER)CON(120)ACTION(DISABLE_INSTANCE)"; String alertStr3 = "EXP(decay(1.0)(localhost_*.TestStat@DB=TestDB;Partition=*.TestMetric2))CMP(GREATER)CON(160)ACTION(DISABLE_PARTITION)"; _setupTool.getClusterManagementTool().addAlert(CLUSTER_NAME, alertStr1); _setupTool.getClusterManagementTool().addAlert(CLUSTER_NAME, alertStr2); _setupTool.getClusterManagementTool().addAlert(CLUSTER_NAME, alertStr3); int[] metrics1 = {10, 15, 22, 12, 16}; int[] metrics2 = {22, 115, 22, 163, 16}; int[] metrics3 = {0, 0, 0, 0, 0}; setHealthData(metrics1, metrics2); String controllerName = CONTROLLER_PREFIX + "_0"; HelixManager manager = _startCMResultMap.get(controllerName)._manager; HealthStatsAggregationTask task = new HealthStatsAggregationTask(_startCMResultMap.get(controllerName)._manager); task.run(); Thread.sleep(4000); HelixDataAccessor helixDataAccessor = manager.getHelixDataAccessor(); Builder keyBuilder = helixDataAccessor.keyBuilder(); boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(ZK_ADDR, CLUSTER_NAME)); Assert.assertTrue(result); Builder kb = manager.getHelixDataAccessor().keyBuilder(); ExternalView externalView = manager.getHelixDataAccessor().getProperty(kb.externalView("TestDB")); // Test the DISABLE_INSTANCE alerts String participant1 = "localhost_" + (START_PORT + 3); String participant2 = "localhost_" + (START_PORT + 2); ConfigAccessor configAccessor = manager.getConfigAccessor(); scope = new ConfigScopeBuilder() .forCluster(manager.getClusterName()) .forParticipant(participant1) .build(); String isEnabled = configAccessor.get(scope, "HELIX_ENABLED"); Assert.assertFalse(Boolean.parseBoolean(isEnabled)); scope = new ConfigScopeBuilder() .forCluster(manager.getClusterName()) .forParticipant(participant2) .build(); isEnabled = configAccessor.get(scope, "HELIX_ENABLED"); Assert.assertFalse(Boolean.parseBoolean(isEnabled)); for (String partitionName : externalView.getRecord().getMapFields().keySet()) { for (String hostName : externalView.getRecord().getMapField(partitionName).keySet()) { if (hostName.equals(participant1) || hostName.equals(participant2)) { Assert.assertEquals( externalView.getRecord().getMapField(partitionName).get(hostName), "OFFLINE"); } } } // enable the disabled instances setHealthData(metrics3, metrics3); task.run(); Thread.sleep(1000); manager.getClusterManagmentTool().enableInstance(manager.getClusterName(), participant2, true); manager.getClusterManagmentTool().enableInstance(manager.getClusterName(), participant1, true); result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(ZK_ADDR, CLUSTER_NAME)); Assert.assertTrue(result); // Test the DISABLE_PARTITION case int[] metrics4 = {22, 115, 22, 16, 163}; setHealthData2(metrics4); task.run(); scope = new ConfigScopeBuilder() .forCluster(manager.getClusterName()) .forParticipant(participant1) .build(); isEnabled = configAccessor.get(scope, "HELIX_ENABLED"); Assert.assertTrue(Boolean.parseBoolean(isEnabled)); scope = new ConfigScopeBuilder() .forCluster(manager.getClusterName()) .forParticipant(participant2) .build(); isEnabled = configAccessor.get(scope, "HELIX_ENABLED"); Assert.assertTrue(Boolean.parseBoolean(isEnabled)); result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(ZK_ADDR, CLUSTER_NAME)); Assert.assertTrue(result); String participant3 = "localhost_" + (START_PORT + 4); externalView = manager.getHelixDataAccessor().getProperty(kb.externalView("TestDB")); Assert.assertTrue( externalView .getRecord() .getMapField("TestDB_3") .get(participant3) .equalsIgnoreCase("OFFLINE")); InstanceConfig nodeConfig = helixDataAccessor.getProperty(keyBuilder.instanceConfig(participant3)); Assert.assertTrue( nodeConfig .getRecord() .getListField(InstanceConfigProperty.HELIX_DISABLED_PARTITION.toString()) .contains("TestDB_3")); }
public HelixBrokerStarter( String helixClusterName, String zkServer, Configuration pinotHelixProperties) throws Exception { _liveInstancesListener = new LiveInstancesChangeListenerImpl(helixClusterName); _pinotHelixProperties = DefaultHelixBrokerConfig.getDefaultBrokerConf(pinotHelixProperties); final String brokerId = _pinotHelixProperties.getString( "instanceId", CommonConstants.Helix.PREFIX_OF_BROKER_INSTANCE + NetUtil.getHostAddress() + "_" + _pinotHelixProperties.getInt( CommonConstants.Helix.KEY_OF_BROKER_QUERY_PORT, CommonConstants.Helix.DEFAULT_BROKER_QUERY_PORT)); _pinotHelixProperties.addProperty("pinot.broker.id", brokerId); RoutingTableBuilder defaultOfflineRoutingTableBuilder = getRoutingTableBuilder( _pinotHelixProperties.subset(DEFAULT_OFFLINE_ROUTING_TABLE_BUILDER_KEY)); RoutingTableBuilder defaultRealtimeRoutingTableBuilder = getRoutingTableBuilder( _pinotHelixProperties.subset(DEFAULT_REALTIME_ROUTING_TABLE_BUILDER_KEY)); Map<String, RoutingTableBuilder> tableToRoutingTableBuilderMap = getTableToRoutingTableBuilderMap(_pinotHelixProperties.subset(ROUTING_TABLE_BUILDER_KEY)); ZkClient zkClient = new ZkClient( StringUtil.join( "/", StringUtils.chomp(zkServer, "/"), helixClusterName, "PROPERTYSTORE"), ZkClient.DEFAULT_SESSION_TIMEOUT, ZkClient.DEFAULT_CONNECTION_TIMEOUT, new ZNRecordSerializer()); _propertyStore = new ZkHelixPropertyStore<ZNRecord>(new ZkBaseDataAccessor<ZNRecord>(zkClient), "/", null); _helixExternalViewBasedRouting = new HelixExternalViewBasedRouting( defaultOfflineRoutingTableBuilder, defaultRealtimeRoutingTableBuilder, tableToRoutingTableBuilderMap, _propertyStore); // _brokerServerBuilder = startBroker(); _brokerServerBuilder = startBroker(_pinotHelixProperties); _helixManager = HelixManagerFactory.getZKHelixManager( helixClusterName, brokerId, InstanceType.PARTICIPANT, zkServer); final StateMachineEngine stateMachineEngine = _helixManager.getStateMachineEngine(); final StateModelFactory<?> stateModelFactory = new BrokerResourceOnlineOfflineStateModelFactory( _helixManager, _helixExternalViewBasedRouting); stateMachineEngine.registerStateModelFactory( BrokerResourceOnlineOfflineStateModelFactory.getStateModelDef(), stateModelFactory); _helixManager.connect(); _helixAdmin = _helixManager.getClusterManagmentTool(); _helixBrokerRoutingTable = new HelixBrokerRoutingTable(_helixExternalViewBasedRouting, brokerId, _helixManager); addInstanceTagIfNeeded(helixClusterName, brokerId); _helixManager.addExternalViewChangeListener(_helixBrokerRoutingTable); _helixManager.addInstanceConfigChangeListener(_helixBrokerRoutingTable); _helixManager.addLiveInstanceChangeListener(_liveInstancesListener); }
ExternalView getResourceExternalView() { return participantManager .getClusterManagmentTool() .getResourceExternalView(clusterName, resourceName); }
@Override public void dispose() { if (participantManager != null && participantManager.isConnected()) { participantManager.disconnect(); } }
@Test public void testBounceAll() throws Exception { // pick numbers that don't divide evenly final int NUM_PARTICIPANTS = 5; final int NUM_PARTITIONS = 123; final int NUM_REPLICAS = 1; final String RESOURCE_PREFIX = "TestDB"; final String RESOURCE_NAME = RESOURCE_PREFIX + "0"; // create a cluster name based on this test name String className = TestHelper.getTestClassName(); String methodName = TestHelper.getTestMethodName(); String clusterName = className + "_" + methodName; System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis())); // Set up cluster TestHelper.setupCluster( clusterName, ZK_ADDR, 12918, // participant port "localhost", // participant name prefix "TestDB", // resource name prefix 1, // resources NUM_PARTITIONS, // partitions per resource NUM_PARTICIPANTS, // number of nodes NUM_REPLICAS, // replicas "OnlineOffline", RebalanceMode.FULL_AUTO, // use FULL_AUTO mode to test node tagging true); // do rebalance // Start the participants HelixManager[] participants = new HelixManager[NUM_PARTICIPANTS]; for (int i = 0; i < NUM_PARTICIPANTS; i++) { final String instanceName = "localhost_" + (12918 + i); participants[i] = createParticipant(clusterName, instanceName); participants[i].connect(); } // Start the controller ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller"); controller.syncStart(); // get an admin and accessor HelixAdmin helixAdmin = new ZKHelixAdmin(_gZkClient); BaseDataAccessor<ZNRecord> baseAccessor = new ZkBaseDataAccessor<ZNRecord>(_gZkClient); HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, baseAccessor); PropertyKey.Builder keyBuilder = accessor.keyBuilder(); // do the test try { Thread.sleep(1000); // ensure that the external view coalesces boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName)); Assert.assertTrue(result); ExternalView stableExternalView = accessor.getProperty(keyBuilder.externalView(RESOURCE_NAME)); for (HelixManager participant : participants) { // disable the controller, bounce the node, re-enable the controller, verify assignments // remained the same helixAdmin.enableCluster(clusterName, false); participant.disconnect(); Thread.sleep(1000); participant = createParticipant(clusterName, participant.getInstanceName()); participant.connect(); Thread.sleep(1000); helixAdmin.enableCluster(clusterName, true); Thread.sleep(1000); result = ClusterStateVerifier.verifyByZkCallback( new MatchingExternalViewVerifier(stableExternalView, clusterName)); Assert.assertTrue(result); } } finally { // clean up controller.syncStop(); for (HelixManager participant : participants) { participant.disconnect(); } System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis())); } }
public static IdealState getTableIdealState(HelixManager manager, String resourceName) { final HelixDataAccessor accessor = manager.getHelixDataAccessor(); final Builder builder = accessor.keyBuilder(); return accessor.getProperty(builder.idealStates(resourceName)); }