Add cloud set/remove to cluster setup (#1783)
In this commit, the CloudConfig set and remove APIs have been added
to the cluster setup.
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
index 667cab7..ab236e0 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
@@ -27,6 +27,8 @@
import java.util.List;
import java.util.Map;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
@@ -72,6 +74,7 @@
import org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer;
import org.apache.helix.zookeeper.impl.client.FederatedZkClient;
import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.introspect.CodehausJacksonIntrospector;
import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -138,6 +141,11 @@
public static final String setConfig = "setConfig";
public static final String removeConfig = "removeConfig";
+ // set/remove cloud configs
+ public static final String setCloudConfig = "setCloudConfig";
+ public static final String removeCloudConfig = "removeCloudConfig";
+
+
// get/set/remove constraints
public static final String getConstraints = "getConstraints";
public static final String setConstraint = "setConstraint";
@@ -151,6 +159,10 @@
private final boolean _usesExternalZkClient;
private final HelixAdmin _admin;
+ protected static ObjectReader ZNRECORD_READER = new ObjectMapper()
+ .setAnnotationIntrospector(new CodehausJacksonIntrospector())
+ .readerFor(ZNRecord.class);
+
@Deprecated
public ClusterSetup(String zkServerAddress) {
// If the multi ZK config is enabled, use FederatedZkClient on multi-realm mode
@@ -624,6 +636,33 @@
}
/**
+ * set cloud configs
+ * @param clusterName
+ * @param cloudConfigManifest
+ */
+ public void setCloudConfig(String clusterName, String cloudConfigManifest) {
+ ZNRecord record;
+ try {
+ record = ZNRECORD_READER.readValue(cloudConfigManifest);
+ } catch (IOException e) {
+ _logger
+ .error("Failed to deserialize user's input " + cloudConfigManifest + ", Exception: " + e);
+ throw new IllegalArgumentException("Failed to deserialize user's input ");
+ }
+
+ CloudConfig cloudConfig = new CloudConfig.Builder(record).build();
+ _admin.addCloudConfig(clusterName, cloudConfig);
+ }
+
+ /**
+ * remove cloud configs
+ * @param clusterName
+ */
+ public void removeCloudConfig(String clusterName) {
+ _admin.removeCloudConfig(clusterName);
+ }
+
+ /**
* get configs
* @param type config-scope-type, e.g. CLUSTER, RESOURCE, etc.
* @param scopeArgsCsv csv-formatted scope-args, e.g myCluster,testDB
@@ -1058,6 +1097,19 @@
.withLongOpt(removeConstraint)
.withDescription("Remove a constraint associated with given id").create();
+ Option setCloudConfigOption = OptionBuilder.withLongOpt(setCloudConfig).withDescription(
+ "Set the Cloud Configuration of the cluster. Example:\n sh helix-admin.sh --zkSvr ZookeeperServerAddress --setCloudConfig ClusterName '{\"simpleFields\" : {\"CLOUD_ENABLED\" : \"true\",\"CLOUD_PROVIDER\": \"AZURE\"}}'")
+ .create();
+ setCloudConfigOption.setArgs(2);
+ setCloudConfigOption.setRequired(false);
+ setCloudConfigOption.setArgName("clusterName CloudConfigurationManifest");
+
+ Option removeCloudConfigOption = OptionBuilder.withLongOpt(removeCloudConfig)
+ .withDescription("Remove the Cloud Configuration of the cluster").create();
+ removeCloudConfigOption.setArgs(1);
+ removeCloudConfigOption.setRequired(false);
+ removeCloudConfigOption.setArgName("clusterName");
+
OptionGroup group = new OptionGroup();
group.setRequired(true);
group.addOption(rebalanceOption);
@@ -1108,6 +1160,10 @@
group.addOption(getConstraintsOption);
group.addOption(removeConstraintOption);
+ // set/remove cloud configs
+ group.addOption(setCloudConfigOption);
+ group.addOption(removeCloudConfigOption);
+
group.addOption(addInstanceTagOption);
group.addOption(removeInstanceTagOption);
group.addOption(instanceGroupTagOption);
@@ -1571,6 +1627,15 @@
setupTool.removeResourceProperty(clusterName, resourceName, propertyKey);
return 0;
+ } else if (cmd.hasOption(setCloudConfig)) {
+ String clusterName = cmd.getOptionValues(setCloudConfig)[0];
+ String cloudConfigManifest = cmd.getOptionValues(setCloudConfig)[1];
+ setupTool.setCloudConfig(clusterName, cloudConfigManifest);
+ return 0;
+ } else if (cmd.hasOption(removeCloudConfig)) {
+ String clusterName = cmd.getOptionValues(removeCloudConfig)[0];
+ setupTool.removeCloudConfig(clusterName);
+ return 0;
}
return 0;
}
diff --git a/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java b/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java
index 749ca2a..44cacc8 100644
--- a/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java
+++ b/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java
@@ -552,4 +552,34 @@
Assert.assertNull(cloudConfigFromZk.getCloudInfoProcessorName());
Assert.assertEquals(cloudConfigFromZk.getCloudProvider(), CloudProvider.AZURE.name());
}
+
+ @Test(dependsOnMethods = "testAddClusterAzureProvider")
+ public void testSetRemoveCloudConfig() throws Exception {
+ String className = TestHelper.getTestClassName();
+ String methodName = TestHelper.getTestMethodName();
+ String clusterName = className + "_" + methodName;
+
+ // Create Cluster without cloud config
+ _clusterSetup.addCluster(clusterName, false);
+
+ // Read CloudConfig from Zookeeper and check the content
+ ConfigAccessor _configAccessor = new ConfigAccessor(ZK_ADDR);
+ CloudConfig cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ Assert.assertNull(cloudConfigFromZk);
+
+ String cloudConfigManifest =
+ "{\"simpleFields\" : {\"CLOUD_ENABLED\" : \"true\",\"CLOUD_PROVIDER\": \"AZURE\"}}\"";
+ _clusterSetup.setCloudConfig(clusterName, cloudConfigManifest);
+
+ // Read cloud config from ZK and make sure the fields are accurate
+ cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ Assert.assertNotNull(cloudConfigFromZk);
+ Assert.assertEquals(CloudProvider.AZURE.name(), cloudConfigFromZk.getCloudProvider());
+ Assert.assertTrue(cloudConfigFromZk.isCloudEnabled());
+
+ // Remove cloud config and make sure it has been removed
+ _clusterSetup.removeCloudConfig(clusterName);
+ cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ Assert.assertNull(cloudConfigFromZk);
+ }
}