use of com.github.ambry.utils.HelixControllerManager in project ambry by linkedin.
the class VcrTestUtil method populateZkInfoAndStartController.
/**
* Populate info on ZooKeeper server and start {@link HelixControllerManager}.
* @param zkConnectString zk connect string to zk server.
* @param vcrClusterName the vcr cluster name.
* @param clusterMap the {@link ClusterMap} to use.
* @param vcrHelixStateModel the state model to use for helix cluster events.
* @return the created {@link HelixControllerManager}.
*/
public static HelixControllerManager populateZkInfoAndStartController(String zkConnectString, String vcrClusterName, ClusterMap clusterMap, String vcrHelixStateModel) {
HelixZkClient zkClient = DedicatedZkClientFactory.getInstance().buildZkClient(new HelixZkClient.ZkConnectionConfig(zkConnectString), new HelixZkClient.ZkClientConfig());
try {
zkClient.setZkSerializer(new ZNRecordSerializer());
ClusterSetup clusterSetup = new ClusterSetup(zkClient);
clusterSetup.addCluster(vcrClusterName, true);
HelixAdmin admin = new ZKHelixAdmin(zkClient);
// set ALLOW_PARTICIPANT_AUTO_JOIN
HelixConfigScope configScope = new HelixConfigScopeBuilder(HelixConfigScope.ConfigScopeProperty.CLUSTER).forCluster(vcrClusterName).build();
Map<String, String> helixClusterProperties = new HashMap<>();
helixClusterProperties.put(ZKHelixManager.ALLOW_PARTICIPANT_AUTO_JOIN, String.valueOf(true));
admin.setConfig(configScope, helixClusterProperties);
// set PersistBestPossibleAssignment
ConfigAccessor configAccessor = new ConfigAccessor(zkClient);
ClusterConfig clusterConfig = configAccessor.getClusterConfig(vcrClusterName);
clusterConfig.setPersistBestPossibleAssignment(true);
configAccessor.setClusterConfig(vcrClusterName, clusterConfig);
FullAutoModeISBuilder builder = new FullAutoModeISBuilder(helixResource);
builder.setStateModel(vcrHelixStateModel);
for (PartitionId partitionId : clusterMap.getAllPartitionIds(null)) {
builder.add(partitionId.toPathString());
}
builder.setMinActiveReplica(MIN_ACTIVE_REPLICAS);
builder.setRebalanceDelay((int) REBALANCE_DELAY_MS);
builder.setRebalancerClass(DelayedAutoRebalancer.class.getName());
builder.setRebalanceStrategy(CrushEdRebalanceStrategy.class.getName());
IdealState idealState = builder.build();
admin.addResource(vcrClusterName, helixResource, idealState);
admin.rebalance(vcrClusterName, helixResource, NUM_REPLICAS, "", "");
HelixControllerManager helixControllerManager = new HelixControllerManager(zkConnectString, vcrClusterName);
helixControllerManager.syncStart();
return helixControllerManager;
} finally {
zkClient.close();
}
}
use of com.github.ambry.utils.HelixControllerManager in project ambry by linkedin.
the class VcrServerTest method testVCRServerWithHelixCluster.
/**
* Bring up the VCR server and then shut it down with {@link HelixVcrClusterParticipant}.
* @throws Exception
*/
@Test
public void testVCRServerWithHelixCluster() throws Exception {
Properties serverSSLProps = new Properties();
File trustStoreFile = File.createTempFile("truststore", ".jks");
TestSSLUtils.addSSLProperties(serverSSLProps, "DC1,DC2,DC3", SSLFactory.Mode.SERVER, trustStoreFile, "server");
TestSSLUtils.addHttp2Properties(serverSSLProps, SSLFactory.Mode.SERVER, true);
int zkPort = 31999;
String zkConnectString = "localhost:" + zkPort;
String vcrClusterName = "vcrTestCluster";
TestUtils.ZkInfo zkInfo = new TestUtils.ZkInfo(TestUtils.getTempDir("helixVcr"), "DC1", (byte) 1, zkPort, true);
HelixControllerManager helixControllerManager = VcrTestUtil.populateZkInfoAndStartController(zkConnectString, vcrClusterName, mockClusterMap);
Properties props = VcrTestUtil.createVcrProperties("DC1", vcrClusterName, zkConnectString, 12300, 12400, 12500, serverSSLProps);
CloudDestinationFactory cloudDestinationFactory = new LatchBasedInMemoryCloudDestinationFactory(new LatchBasedInMemoryCloudDestination(Collections.emptyList(), mockClusterMap));
VerifiableProperties verifiableProperties = new VerifiableProperties(props);
VcrServer vcrServer = new VcrServer(verifiableProperties, mockClusterAgentsFactory, notificationSystem, cloudDestinationFactory, null);
vcrServer.startup();
Assert.assertNotNull("Expected compactor", vcrServer.getVcrReplicationManager().getCloudStorageCompactor());
vcrServer.shutdown();
helixControllerManager.syncStop();
zkInfo.shutdown();
}
use of com.github.ambry.utils.HelixControllerManager in project ambry by linkedin.
the class ServerTestUtil method endToEndCloudBackupTest.
/**
* Tests blobs put to dataNode can be backed up by {@link com.github.ambry.cloud.VcrReplicationManager}.
* @param cluster the {@link MockCluster} of dataNodes.
* @param zkConnectString ZK endpoint to establish VCR cluster
* @param vcrClusterName the name of VCR cluster
* @param dataNode the datanode where blobs are originally put.
* @param clientSSLConfig the {@link SSLConfig}.
* @param clientSSLSocketFactory the {@link SSLSocketFactory}.
* @param notificationSystem the {@link MockNotificationSystem} to track blobs event in {@link MockCluster}.
* @param vcrSSLProps SSL related properties for VCR. Can be {@code null}.
* @param doTtlUpdate Do ttlUpdate request if {@code true}.
*/
static void endToEndCloudBackupTest(MockCluster cluster, String zkConnectString, String vcrClusterName, DataNodeId dataNode, SSLConfig clientSSLConfig, SSLSocketFactory clientSSLSocketFactory, MockNotificationSystem notificationSystem, Properties vcrSSLProps, boolean doTtlUpdate) throws Exception {
int blobBackupCount = 10;
int blobSize = 100;
int userMetaDataSize = 100;
ClusterAgentsFactory clusterAgentsFactory = cluster.getClusterAgentsFactory();
// Send blobs to DataNode
byte[] userMetadata = new byte[userMetaDataSize];
byte[] data = new byte[blobSize];
short accountId = Utils.getRandomShort(TestUtils.RANDOM);
short containerId = Utils.getRandomShort(TestUtils.RANDOM);
long ttl = doTtlUpdate ? TimeUnit.DAYS.toMillis(1) : Utils.Infinite_Time;
BlobProperties properties = new BlobProperties(blobSize, "serviceid1", null, null, false, ttl, cluster.time.milliseconds(), accountId, containerId, false, null, null, null);
TestUtils.RANDOM.nextBytes(userMetadata);
TestUtils.RANDOM.nextBytes(data);
Port port;
if (clientSSLConfig == null) {
port = new Port(dataNode.getPort(), PortType.PLAINTEXT);
} else {
port = new Port(dataNode.getSSLPort(), PortType.SSL);
}
ConnectedChannel channel = getBlockingChannelBasedOnPortType(port, "localhost", clientSSLSocketFactory, clientSSLConfig);
channel.connect();
CountDownLatch latch = new CountDownLatch(1);
DirectSender runnable = new DirectSender(cluster, channel, blobBackupCount, data, userMetadata, properties, null, latch);
Thread threadToRun = new Thread(runnable);
threadToRun.start();
assertTrue("Did not put all blobs in 2 minutes", latch.await(2, TimeUnit.MINUTES));
// TODO: remove this temp fix after fixing race condition in MockCluster/MockNotificationSystem
Thread.sleep(3000);
List<BlobId> blobIds = runnable.getBlobIds();
for (BlobId blobId : blobIds) {
notificationSystem.awaitBlobCreations(blobId.getID());
if (doTtlUpdate) {
updateBlobTtl(channel, blobId, cluster.time.milliseconds());
}
}
HelixControllerManager helixControllerManager = VcrTestUtil.populateZkInfoAndStartController(zkConnectString, vcrClusterName, cluster.getClusterMap());
// Start the VCR and CloudBackupManager
Properties props = VcrTestUtil.createVcrProperties(dataNode.getDatacenterName(), vcrClusterName, zkConnectString, 12310, 12410, 12510, vcrSSLProps);
LatchBasedInMemoryCloudDestination latchBasedInMemoryCloudDestination = new LatchBasedInMemoryCloudDestination(blobIds, clusterAgentsFactory.getClusterMap());
CloudDestinationFactory cloudDestinationFactory = new LatchBasedInMemoryCloudDestinationFactory(latchBasedInMemoryCloudDestination);
VcrServer vcrServer = VcrTestUtil.createVcrServer(new VerifiableProperties(props), clusterAgentsFactory, notificationSystem, cloudDestinationFactory);
vcrServer.startup();
// Waiting for backup done
assertTrue("Did not backup all blobs in 2 minutes", latchBasedInMemoryCloudDestination.awaitUpload(2, TimeUnit.MINUTES));
Map<String, CloudBlobMetadata> cloudBlobMetadataMap = latchBasedInMemoryCloudDestination.getBlobMetadata(blobIds);
for (BlobId blobId : blobIds) {
CloudBlobMetadata cloudBlobMetadata = cloudBlobMetadataMap.get(blobId.toString());
assertNotNull("cloudBlobMetadata should not be null", cloudBlobMetadata);
assertEquals("AccountId mismatch", accountId, cloudBlobMetadata.getAccountId());
assertEquals("ContainerId mismatch", containerId, cloudBlobMetadata.getContainerId());
assertEquals("Expiration time mismatch", Utils.Infinite_Time, cloudBlobMetadata.getExpirationTime());
// TODO: verify other metadata and blob data
}
vcrServer.shutdown();
helixControllerManager.syncStop();
}
use of com.github.ambry.utils.HelixControllerManager in project ambry by linkedin.
the class VcrAutomationTest method testSimpleVcrAutomation.
/**
* Test basic partition add and remove cases.
*/
@Test
public void testSimpleVcrAutomation() throws Exception {
List<ZkInfo> zkInfoList = new ArrayList<>();
String mainClusterStateModelDef = ClusterMapConfig.AMBRY_STATE_MODEL_DEF;
DataNodeConfigSourceType dataNodeConfigSourceType = DataNodeConfigSourceType.INSTANCE_CONFIG;
int zkPort = 2100;
int numberOfDataNode = 3;
int partitionCount = 9;
int newPartitionCount = 13;
String zkHostName = "localhost";
String zkConnectString = zkHostName + ":" + zkPort;
String clusterPrefix = "";
String clusterName = "MainCluster";
String vcrClusterName = "VcrCluster";
String dcName = "DC0";
TestHardwareLayout testHardwareLayout;
TestPartitionLayout testPartitionLayout;
String hardwareLayoutPath;
String partitionLayoutPath;
String zkLayoutPath;
zkInfoList.add(new ZkInfo(TestUtils.getTempDir("tempZk"), "DC0", (byte) 0, zkPort, true));
String tempDirPath = getTempDir(clusterName + "-");
hardwareLayoutPath = tempDirPath + "/hardwareLayoutTest.json";
partitionLayoutPath = tempDirPath + "/partitionLayoutTest.json";
zkLayoutPath = tempDirPath + "/zkLayoutPath.json";
testHardwareLayout = new TestHardwareLayout(clusterName, 1, 10737418240L, numberOfDataNode, 1, 18088, 20, false);
testPartitionLayout = constructInitialPartitionLayoutJSON(testHardwareLayout, partitionCount, null);
JSONObject zkJson = constructZkLayoutJSON(zkInfoList);
Utils.writeJsonObjectToFile(zkJson, zkLayoutPath);
Utils.writeJsonObjectToFile(testHardwareLayout.getHardwareLayout().toJSONObject(), hardwareLayoutPath);
Utils.writeJsonObjectToFile(testPartitionLayout.getPartitionLayout().toJSONObject(), partitionLayoutPath);
Properties props = VcrTestUtil.createVcrProperties("DC0", vcrClusterName, zkConnectString, 12300, 12400, 12510, null);
props.setProperty("clustermap.host.name", "localhost");
props.setProperty("clustermap.port", "1100");
props.setProperty("clustermap.cluster.name", clusterName);
props.setProperty("clustermap.datacenter.name", dcName);
props.setProperty("clustermap.dcs.zk.connect.strings", zkJson.toString(2));
props.setProperty("clustermap.state.model.definition", mainClusterStateModelDef);
props.setProperty("clustermap.data.node.config.source.type", dataNodeConfigSourceType.name());
props.setProperty("clustermap.cluster.change.handler.type", "DynamicClusterChangeHandler");
props.setProperty("vcr.helix.updater.partition.id", "1");
props.setProperty("vcr.helix.update.delay.time.in.seconds", "1");
HelixBootstrapUpgradeUtil.bootstrapOrUpgrade(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath, clusterPrefix, dcName, 10, false, false, new HelixAdminFactory(), false, mainClusterStateModelDef, HelixBootstrapUpgradeUtil.HelixAdminOperation.BootstrapCluster, dataNodeConfigSourceType, false);
HelixControllerManager helixControllerManager = new HelixControllerManager(zkConnectString, clusterPrefix + clusterName);
helixControllerManager.syncStart();
// Main cluster helix setup done.
HelixVcrUtil.VcrHelixConfig vcrHelixConfig;
String vcConfigData = CloudConfig.DEFAULT_VCR_HELIX_UPDATE_CONFIG;
try (InputStream input = new ByteArrayInputStream(vcConfigData.getBytes())) {
vcrHelixConfig = new ObjectMapper().readValue(input, HelixVcrUtil.VcrHelixConfig.class);
} catch (IOException ex) {
throw new IllegalStateException("Could not load config from config data: " + vcConfigData);
}
HelixVcrUtil.createCluster(zkConnectString, vcrClusterName, vcrHelixConfig);
HelixVcrUtil.updateResourceAndPartition(zkConnectString, clusterPrefix + clusterName, zkConnectString, vcrClusterName, vcrHelixConfig, false);
Assert.assertTrue("Dest and Src should be same", isSrcDestSync(zkConnectString, clusterPrefix + clusterName, zkConnectString, vcrClusterName));
HelixControllerManager vcrHelixControllerManager = new HelixControllerManager(zkConnectString, vcrClusterName);
vcrHelixControllerManager.syncStart();
StrictMatchExternalViewVerifier helixBalanceVerifier = new StrictMatchExternalViewVerifier(zkConnectString, vcrClusterName, Collections.singleton(VcrTestUtil.helixResource), null);
// VCR cluster helix setup done.
VerifiableProperties verifiableProperties = new VerifiableProperties(props);
ClusterMapConfig clusterMapConfig = new ClusterMapConfig(verifiableProperties);
HelixClusterAgentsFactory helixClusterAgentsFactory = new HelixClusterAgentsFactory(clusterMapConfig, null, null);
VcrServer vcrServer = new VcrServer(verifiableProperties, helixClusterAgentsFactory, null, new CloudDestinationFactory() {
@Override
public CloudDestination getCloudDestination() throws IllegalStateException {
return mock(CloudDestination.class);
}
}, null);
vcrServer.startup();
makeSureHelixBalance(vcrServer, helixBalanceVerifier);
Assert.assertTrue("Partition assignment is not correct.", TestUtils.checkAndSleep(partitionCount, () -> vcrServer.getVcrClusterParticipant().getAssignedPartitionIds().size(), 5000));
// vcr server start up done.
// Partition add case:
testPartitionLayout = constructInitialPartitionLayoutJSON(testHardwareLayout, partitionCount + newPartitionCount, null);
Utils.writeJsonObjectToFile(testPartitionLayout.getPartitionLayout().toJSONObject(), partitionLayoutPath);
HelixBootstrapUpgradeUtil.bootstrapOrUpgrade(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath, clusterPrefix, dcName, 10, false, false, new HelixAdminFactory(), false, mainClusterStateModelDef, HelixBootstrapUpgradeUtil.HelixAdminOperation.BootstrapCluster, dataNodeConfigSourceType, false);
makeSureHelixBalance(vcrServer, helixBalanceVerifier);
Assert.assertTrue("Partition assignment is not correct.", TestUtils.checkAndSleep(partitionCount + newPartitionCount, () -> vcrServer.getVcrClusterParticipant().getAssignedPartitionIds().size(), 5000));
// Partition remove case:
testPartitionLayout = constructInitialPartitionLayoutJSON(testHardwareLayout, partitionCount, null);
Utils.writeJsonObjectToFile(testPartitionLayout.getPartitionLayout().toJSONObject(), partitionLayoutPath);
HelixBootstrapUpgradeUtil.bootstrapOrUpgrade(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath, clusterPrefix, dcName, 10, false, true, new HelixAdminFactory(), false, mainClusterStateModelDef, HelixBootstrapUpgradeUtil.HelixAdminOperation.BootstrapCluster, dataNodeConfigSourceType, false);
makeSureHelixBalance(vcrServer, helixBalanceVerifier);
Assert.assertTrue("Partition assignment is not correct.", TestUtils.checkAndSleep(partitionCount, () -> vcrServer.getVcrClusterParticipant().getAssignedPartitionIds().size(), 5000));
helixControllerManager.syncStop();
vcrHelixControllerManager.syncStop();
zkInfoList.get(0).shutdown();
}
Aggregations