Search in sources :

Example 21 with ZKHelixAdmin

use of org.apache.helix.manager.zk.ZKHelixAdmin in project helix by apache.

the class TestFullAutoNodeTagging method testSafeAssignment.

/**
 * Basic test for tagging behavior. 10 participants, of which 4 are tagged. Launch all 10,
 * checking external view every time a tagged node is started. Then shut down all 10, checking
 * external view every time a tagged node is killed.
 */
@Test
public void testSafeAssignment() throws Exception {
    final int NUM_PARTICIPANTS = 10;
    final int NUM_PARTITIONS = 4;
    final int NUM_REPLICAS = 2;
    final String RESOURCE_NAME = "TestDB0";
    final String TAG = "ASSIGNABLE";
    final String[] TAGGED_NODES = { "localhost_12920", "localhost_12922", "localhost_12924", "localhost_12925" };
    Set<String> taggedNodes = Sets.newHashSet(TAGGED_NODES);
    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
    // participant port
    TestHelper.setupCluster(// participant port
    clusterName, // participant port
    ZK_ADDR, // participant port
    12918, // participant name prefix
    "localhost", // resource name prefix
    "TestDB", // resources
    1, // partitions per resource
    NUM_PARTITIONS, // number of nodes
    NUM_PARTICIPANTS, // replicas
    NUM_REPLICAS, // use FULL_AUTO mode to test node tagging
    "MasterSlave", // use FULL_AUTO mode to test node tagging
    RebalanceMode.FULL_AUTO, // do rebalance
    true);
    // tag the resource and participants
    HelixAdmin helixAdmin = new ZKHelixAdmin(ZK_ADDR);
    for (String taggedNode : TAGGED_NODES) {
        helixAdmin.addInstanceTag(clusterName, taggedNode, TAG);
    }
    IdealState idealState = helixAdmin.getResourceIdealState(clusterName, RESOURCE_NAME);
    idealState.setInstanceGroupTag(TAG);
    helixAdmin.setResourceIdealState(clusterName, RESOURCE_NAME, idealState);
    // start controller
    ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller");
    controller.syncStart();
    // start participants
    MockParticipantManager[] participants = new MockParticipantManager[NUM_PARTICIPANTS];
    for (int i = 0; i < NUM_PARTICIPANTS; i++) {
        final String instanceName = "localhost_" + (12918 + i);
        participants[i] = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
        participants[i].syncStart();
        // ensure that everything is valid if this is a tagged node that is starting
        if (taggedNodes.contains(instanceName)) {
            // make sure that the best possible matches the external view
            Thread.sleep(500);
            boolean result = ClusterStateVerifier.verifyByZkCallback(new BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
            Assert.assertTrue(result);
            // make sure that the tagged state of the nodes is still balanced
            result = ClusterStateVerifier.verifyByZkCallback(new TaggedZkVerifier(clusterName, RESOURCE_NAME, TAGGED_NODES, false));
            Assert.assertTrue(result, "initial assignment with all tagged nodes live is invalid");
        }
    }
    // cleanup
    for (int i = 0; i < NUM_PARTICIPANTS; i++) {
        String participantName = participants[i].getInstanceName();
        participants[i].syncStop();
        if (taggedNodes.contains(participantName)) {
            // check that the external view is still correct even after removing tagged nodes
            taggedNodes.remove(participantName);
            Thread.sleep(500);
            boolean result = ClusterStateVerifier.verifyByZkCallback(new TaggedZkVerifier(clusterName, RESOURCE_NAME, TAGGED_NODES, taggedNodes.isEmpty()));
            Assert.assertTrue(result, "incorrect state after removing " + participantName + ", " + taggedNodes + " remain");
        }
    }
    controller.syncStop();
    System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
Also used : MockParticipantManager(org.apache.helix.integration.manager.MockParticipantManager) HelixAdmin(org.apache.helix.HelixAdmin) ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin) BestPossAndExtViewZkVerifier(org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier) Date(java.util.Date) IdealState(org.apache.helix.model.IdealState) ClusterControllerManager(org.apache.helix.integration.manager.ClusterControllerManager) ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin) Test(org.testng.annotations.Test)

Example 22 with ZKHelixAdmin

use of org.apache.helix.manager.zk.ZKHelixAdmin in project ambry by linkedin.

the class HelixBootstrapUpgradeToolTest method verifyIdealStateForPartition.

/**
 * A helper method to verify IdealState for given replica's partition. It checks number of replicas (represented by
 * instances) under certain partition and verifies new added replica exists or removed old replica is no longer present.
 * @param replica the replica to check if it exists (could be either added replica or removed replica)
 * @param shouldExist if {@code true}, it means the given replica is newly added and should exist in IdealState.
 *                    {@code false} otherwise.
 * @param expectedReplicaCountForPartition expected number of replicas under certain partition
 * @param expectedResourceCount expected total number resource count in this cluster.
 */
private void verifyIdealStateForPartition(ReplicaId replica, boolean shouldExist, int expectedReplicaCountForPartition, long expectedResourceCount) {
    String dcName = replica.getDataNodeId().getDatacenterName();
    ZkInfo zkInfo = dcsToZkInfo.get(dcName);
    String clusterName = CLUSTER_NAME_PREFIX + CLUSTER_NAME_IN_STATIC_CLUSTER_MAP;
    ZKHelixAdmin admin = new ZKHelixAdmin("localhost:" + zkInfo.getPort());
    if (!activeDcSet.contains(dcName)) {
        Assert.assertFalse("Cluster should not be present, as dc " + dcName + " is not enabled", admin.getClusters().contains(clusterName));
    } else {
        List<String> resources = admin.getResourcesInCluster(clusterName);
        assertEquals("Resource count mismatch", expectedResourceCount, resources.size());
        String partitionName = replica.getPartitionId().toPathString();
        boolean resourceFound = false;
        for (String resource : resources) {
            IdealState idealState = admin.getResourceIdealState(clusterName, resource);
            if (idealState.getPartitionSet().contains(partitionName)) {
                resourceFound = true;
                Set<String> instances = idealState.getInstanceSet(partitionName);
                assertEquals("Replica number is not expected", expectedReplicaCountForPartition, instances.size());
                String instanceNameOfNewReplica = getInstanceName(replica.getDataNodeId());
                if (shouldExist) {
                    assertTrue("Instance set doesn't include new instance that holds added replica", instances.contains(instanceNameOfNewReplica));
                } else {
                    assertFalse("Instance that holds deleted replica should not exist in the set", instances.contains(instanceNameOfNewReplica));
                }
                break;
            }
        }
        assertTrue("No corresponding resource found for partition " + partitionName, resourceFound);
    }
}
Also used : ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin) IdealState(org.apache.helix.model.IdealState)

Example 23 with ZKHelixAdmin

use of org.apache.helix.manager.zk.ZKHelixAdmin in project ambry by linkedin.

the class HelixBootstrapUpgradeToolTest method verifyResourceCount.

/**
 * Verify that the number of resources in Helix is as expected.
 * @param hardwareLayout the {@link HardwareLayout} of the static clustermap.
 * @param expectedResourceCount the expected number of resources in Helix.
 */
private void verifyResourceCount(HardwareLayout hardwareLayout, long expectedResourceCount) {
    for (Datacenter dc : hardwareLayout.getDatacenters()) {
        ZkInfo zkInfo = dcsToZkInfo.get(dc.getName());
        ZKHelixAdmin admin = new ZKHelixAdmin("localhost:" + zkInfo.getPort());
        if (!activeDcSet.contains(dc.getName())) {
            Assert.assertFalse("Cluster should not be present, as dc " + dc.getName() + " is not enabled", admin.getClusters().contains(CLUSTER_NAME_PREFIX + CLUSTER_NAME_IN_STATIC_CLUSTER_MAP));
        } else {
            assertEquals("Resource count mismatch", expectedResourceCount, admin.getResourcesInCluster(CLUSTER_NAME_PREFIX + CLUSTER_NAME_IN_STATIC_CLUSTER_MAP).size());
        }
    }
}
Also used : ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin)

Example 24 with ZKHelixAdmin

use of org.apache.helix.manager.zk.ZKHelixAdmin in project ambry by linkedin.

the class HelixBootstrapUpgradeToolTest method testEnablePartitionAdminOp.

/**
 * Test that partition is correctly enabled on given node. The partition is first disabled and then enabled.
 * @throws Exception
 */
@Test
public void testEnablePartitionAdminOp() throws Exception {
    assumeTrue(!dcStr.equals("DC1") && !dcStr.equals("DC0"));
    String clusterName = CLUSTER_NAME_PREFIX + CLUSTER_NAME_IN_STATIC_CLUSTER_MAP;
    // Test regular bootstrap.
    long expectedResourceCount = (testPartitionLayout.getPartitionLayout().getPartitionCount() - 1) / DEFAULT_MAX_PARTITIONS_PER_RESOURCE + 1;
    writeBootstrapOrUpgrade(expectedResourceCount, false);
    int totalPartitionCount = testPartitionLayout.getPartitionCount();
    // Randomly pick a partition to disable/enable
    Partition testPartition = (Partition) testPartitionLayout.getPartitionLayout().getPartitions(null).get(RANDOM.nextInt(totalPartitionCount));
    // Randomly pick a replica from this partition
    List<ReplicaId> replicaIds = testPartition.getReplicaIds();
    DataNodeId dataNodeId = replicaIds.get(RANDOM.nextInt(replicaIds.size())).getDataNodeId();
    // Disable partition on chosen node
    HelixBootstrapUpgradeUtil.controlPartitionState(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath, CLUSTER_NAME_PREFIX, dataNodeId.getDatacenterName(), dataNodeId.getHostname(), dataNodeId.getPort(), DisablePartition, testPartition.toPathString());
    // Verify the InstanceConfig is changed only in MapFields (Disabled partition is added to this field)
    ZkInfo zkInfo = dcsToZkInfo.get(dataNodeId.getDatacenterName());
    ZKHelixAdmin admin = new ZKHelixAdmin("localhost:" + zkInfo.getPort());
    InstanceConfig currentInstanceConfig = admin.getInstanceConfig(clusterName, getInstanceName(dataNodeId));
    assertTrue("There should be additional string in InstanceConfig due to disabling partition", currentInstanceConfig.getRecord().getMapFields().keySet().stream().anyMatch(k -> !k.startsWith("/mnt")));
    // Verify given partition is indeed disabled on specified node
    String resourceName = getResourceNameOfPartition(admin, clusterName, testPartition.toPathString());
    List<String> disabledPartitions = currentInstanceConfig.getDisabledPartitions(resourceName);
    assertEquals("Disabled partition is not expected", Collections.singletonList(testPartition.toPathString()), disabledPartitions);
    // Enable the same partition on same node
    HelixBootstrapUpgradeUtil.controlPartitionState(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath, CLUSTER_NAME_PREFIX, dataNodeId.getDatacenterName(), dataNodeId.getHostname(), dataNodeId.getPort(), EnablePartition, testPartition.toPathString());
    // Verify instanceConfig has been updated (disabled partition is removed)
    currentInstanceConfig = admin.getInstanceConfig(clusterName, getInstanceName(dataNodeId));
    assertFalse("There shouldn't be any additional string in InstanceConfig", currentInstanceConfig.getRecord().getMapFields().keySet().stream().anyMatch(k -> !k.startsWith("/mnt")));
    // Verify there is no disabled partition
    assertNull("There shouldn't be any disabled partition", currentInstanceConfig.getDisabledPartitions(resourceName));
}
Also used : CoreMatchers(org.hamcrest.CoreMatchers) Arrays(java.util.Arrays) IdealState(org.apache.helix.model.IdealState) ClusterMapUtils(com.github.ambry.clustermap.ClusterMapUtils) BeforeClass(org.junit.BeforeClass) RunWith(org.junit.runner.RunWith) CommonUtils(com.github.ambry.commons.CommonUtils) HashMap(java.util.HashMap) Random(java.util.Random) HelixException(org.apache.helix.HelixException) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) HelixPropertyStore(org.apache.helix.store.HelixPropertyStore) TestUtils(com.github.ambry.clustermap.TestUtils) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject) HelixBootstrapUpgradeUtil.getInstanceName(com.github.ambry.clustermap.HelixBootstrapUpgradeUtil.getInstanceName) HelixAdminOperation(com.github.ambry.clustermap.HelixBootstrapUpgradeUtil.HelixAdminOperation) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) After(org.junit.After) AccessOption(org.apache.helix.AccessOption) Assume(org.junit.Assume) Parameterized(org.junit.runners.Parameterized) AfterClass(org.junit.AfterClass) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Utils(com.github.ambry.utils.Utils) IOException(java.io.IOException) Test(org.junit.Test) HelixPropertyStoreConfig(com.github.ambry.config.HelixPropertyStoreConfig) Collectors(java.util.stream.Collectors) InstanceConfig(org.apache.helix.model.InstanceConfig) TimeUnit(java.util.concurrent.TimeUnit) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) ClusterMapConfig(com.github.ambry.config.ClusterMapConfig) ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin) HelixBootstrapUpgradeUtil(com.github.ambry.clustermap.HelixBootstrapUpgradeUtil) Assert(org.junit.Assert) Collections(java.util.Collections) JSONArray(org.json.JSONArray) ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin) InstanceConfig(org.apache.helix.model.InstanceConfig) Test(org.junit.Test)

Example 25 with ZKHelixAdmin

use of org.apache.helix.manager.zk.ZKHelixAdmin in project ambry by linkedin.

the class HelixBootstrapUpgradeToolTest method clear.

@After
public void clear() {
    for (ZkInfo zkInfo : dcsToZkInfo.values()) {
        ZKHelixAdmin admin = new ZKHelixAdmin("localhost:" + zkInfo.getPort());
        admin.dropCluster(CLUSTER_NAME_PREFIX + CLUSTER_NAME_IN_STATIC_CLUSTER_MAP);
    }
}
Also used : ZKHelixAdmin(org.apache.helix.manager.zk.ZKHelixAdmin) After(org.junit.After)

Aggregations

ZKHelixAdmin (org.apache.helix.manager.zk.ZKHelixAdmin)70 HelixAdmin (org.apache.helix.HelixAdmin)31 IdealState (org.apache.helix.model.IdealState)25 Test (org.testng.annotations.Test)23 Date (java.util.Date)21 InstanceConfig (org.apache.helix.model.InstanceConfig)16 ClusterControllerManager (org.apache.helix.integration.manager.ClusterControllerManager)14 ZNRecord (org.apache.helix.ZNRecord)13 MockParticipantManager (org.apache.helix.integration.manager.MockParticipantManager)13 ZNRecordSerializer (org.apache.helix.manager.zk.ZNRecordSerializer)12 ZkClient (org.apache.helix.manager.zk.ZkClient)12 ClusterStateVerifier (org.apache.helix.tools.ClusterStateVerifier)12 ZKHelixDataAccessor (org.apache.helix.manager.zk.ZKHelixDataAccessor)11 StateModelDefinition (org.apache.helix.model.StateModelDefinition)11 HashMap (java.util.HashMap)10 HashSet (java.util.HashSet)10 HelixDataAccessor (org.apache.helix.HelixDataAccessor)8 ExternalView (org.apache.helix.model.ExternalView)8 Test (org.junit.Test)8 BestPossAndExtViewZkVerifier (org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier)7