You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by jx...@apache.org on 2020/01/03 18:34:40 UTC
[helix] 01/02: Add CloudConfig code
This is an automated email from the ASF dual-hosted git repository.
jxue pushed a commit to branch helix-cloud
in repository https://gitbox.apache.org/repos/asf/helix.git
commit 1cf8295972542d835bf75162a15a1b66ff96e890
Author: Ali Reza Zamani Zadeh Najari <an...@linkedin.com>
AuthorDate: Mon Nov 11 11:28:32 2019 -0800
Add CloudConfig code
In order to move toward supporting cloud environments and autoregisterations,
we need to add CloudConfig to Zookeeper.
The code regarding CloudConfig is added.
A new test has been added to check the correctness of the code.
---
.../main/java/org/apache/helix/ConfigAccessor.java | 23 ++
.../main/java/org/apache/helix/PropertyKey.java | 11 +
.../helix/cloud/constants/CloudProvider.java | 25 ++
.../java/org/apache/helix/model/CloudConfig.java | 290 +++++++++++++++++++++
.../org/apache/helix/model/HelixConfigScope.java | 6 +-
.../model/builder/HelixConfigScopeBuilder.java | 3 +
.../apache/helix/model/cloud/TestCloudConfig.java | 204 +++++++++++++++
7 files changed, 561 insertions(+), 1 deletion(-)
diff --git a/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java b/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
index 018743d..264fd3f 100644
--- a/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
@@ -32,6 +32,7 @@ import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.client.HelixZkClient;
import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CloudConfig;
import org.apache.helix.model.ConfigScope;
import org.apache.helix.model.HelixConfigScope;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
@@ -585,6 +586,28 @@ public class ConfigAccessor {
}
/**
+ * Get CloudConfig of the given cluster.
+ * @param clusterName
+ * @return The instance of {@link CloudConfig}
+ */
+ public CloudConfig getCloudConfig(String clusterName) {
+ if (!ZKUtil.isClusterSetup(clusterName, zkClient)) {
+ throw new HelixException(
+ String.format("Failed to get config. cluster: %s is not setup.", clusterName));
+ }
+ HelixConfigScope scope =
+ new HelixConfigScopeBuilder(ConfigScopeProperty.CLOUD).forCluster(clusterName).build();
+ ZNRecord record = getConfigZnRecord(scope);
+
+ if (record == null) {
+ LOG.warn("No cloud config found at {}.", scope.getZkPath());
+ return null;
+ }
+
+ return new CloudConfig(record);
+ }
+
+ /**
* Get RestConfig of the given cluster.
*
* @param clusterName The cluster
diff --git a/helix-core/src/main/java/org/apache/helix/PropertyKey.java b/helix-core/src/main/java/org/apache/helix/PropertyKey.java
index 30305b8..73cc3f0 100644
--- a/helix-core/src/main/java/org/apache/helix/PropertyKey.java
+++ b/helix-core/src/main/java/org/apache/helix/PropertyKey.java
@@ -22,6 +22,7 @@ package org.apache.helix;
import java.util.Arrays;
import java.util.Objects;
+import org.apache.helix.model.CloudConfig;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ClusterConstraints;
import org.apache.helix.model.ControllerHistory;
@@ -233,6 +234,16 @@ public class PropertyKey {
_clusterName, ConfigScopeProperty.CLUSTER.toString(), _clusterName);
}
+
+ /**
+ * Get a property key associated with this Cloud configuration
+ * @return {@link PropertyKey}
+ */
+ public PropertyKey cloudConfig() {
+ return new PropertyKey(CONFIGS, ConfigScopeProperty.CLOUD, CloudConfig.class,
+ _clusterName, ConfigScopeProperty.CLOUD.name(), _clusterName);
+ }
+
/**
* Get a property key associated with {@link InstanceConfig}
* @return {@link PropertyKey}
diff --git a/helix-core/src/main/java/org/apache/helix/cloud/constants/CloudProvider.java b/helix-core/src/main/java/org/apache/helix/cloud/constants/CloudProvider.java
new file mode 100644
index 0000000..1cb836f
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/cloud/constants/CloudProvider.java
@@ -0,0 +1,25 @@
+package org.apache.helix.cloud.constants;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public enum CloudProvider {
+ AZURE,
+ CUSTOMIZED
+}
diff --git a/helix-core/src/main/java/org/apache/helix/model/CloudConfig.java b/helix-core/src/main/java/org/apache/helix/model/CloudConfig.java
new file mode 100644
index 0000000..c8ab6eb
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/model/CloudConfig.java
@@ -0,0 +1,290 @@
+package org.apache.helix.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.helix.HelixException;
+import org.apache.helix.HelixProperty;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.cloud.constants.CloudProvider;
+
+/**
+ * Cloud configurations
+ */
+public class CloudConfig extends HelixProperty {
+ /**
+ * Configurable characteristics of a cloud.
+ * NOTE: Do NOT use this field name directly, use its corresponding getter/setter in the
+ * CloudConfig.
+ */
+ public enum CloudConfigProperty {
+ CLOUD_ENABLED, // determine whether the cluster is inside cloud environment.
+ CLOUD_PROVIDER, // the environment the cluster is in, e.g. Azure, AWS, or Customized
+ CLOUD_ID, // the cloud Id that belongs to this cluster.
+
+ // If user uses Helix supported default provider, the below entries will not be shown in
+ // CloudConfig.
+ CLOUD_INFO_SOURCE, // the source for retrieving the cloud information.
+ CLOUD_INFO_PROCESSOR_NAME // the name of the function that processes the fetching and parsing of
+ // cloud information.
+ }
+
+ /* Default values */
+ private static final boolean DEFAULT_CLOUD_ENABLED = false;
+
+ /**
+ * Instantiate the CloudConfig for the cloud
+ * @param cluster
+ */
+ public CloudConfig(String cluster) {
+ super(cluster);
+ }
+
+ /**
+ * Instantiate with a pre-populated record
+ * @param record a ZNRecord corresponding to a cloud configuration
+ */
+ public CloudConfig(ZNRecord record) {
+ super(record);
+ }
+
+ /**
+ * Instantiate the config using each field individually.
+ * Users should use CloudConfig.Builder to create CloudConfig.
+ * @param cluster
+ * @param enabled
+ * @param cloudID
+ */
+ public CloudConfig(String cluster, boolean enabled, CloudProvider cloudProvider, String cloudID,
+ List<String> cloudInfoSource, String cloudProcessorName) {
+ super(cluster);
+ _record.setBooleanField(CloudConfigProperty.CLOUD_ENABLED.name(), enabled);
+ _record.setSimpleField(CloudConfigProperty.CLOUD_PROVIDER.name(), cloudProvider.name());
+ _record.setSimpleField(CloudConfigProperty.CLOUD_ID.name(), cloudID);
+ if (cloudProvider.equals(CloudProvider.CUSTOMIZED)) {
+ _record
+ .setSimpleField(CloudConfigProperty.CLOUD_INFO_PROCESSOR_NAME.name(), cloudProcessorName);
+ _record.setListField(CloudConfigProperty.CLOUD_INFO_SOURCE.name(), cloudInfoSource);
+ }
+ }
+
+ /**
+ * Enable/Disable the CLOUD_ENABLED field.
+ * @param enabled
+ */
+ public void setCloudEnabled(boolean enabled) {
+ _record.setBooleanField(CloudConfigProperty.CLOUD_ENABLED.name(), enabled);
+ }
+
+ /**
+ * Whether CLOUD_ENABLED field is enabled or not.
+ * @return
+ */
+ public boolean isCloudEnabled() {
+ return _record.getBooleanField(CloudConfigProperty.CLOUD_ENABLED.name(), false);
+ }
+
+ /**
+ * Set the cloudID field.
+ * @param cloudID
+ */
+ public void setCloudID(String cloudID) {
+ _record.setSimpleField(CloudConfigProperty.CLOUD_ID.name(), cloudID);
+ }
+
+ /**
+ * Get the CloudID field.
+ * @return CloudID
+ */
+ public String getCloudID() {
+ return _record.getSimpleField(CloudConfigProperty.CLOUD_ID.name());
+ }
+
+ /**
+ * Set the CLOUD_INFO_SOURCE field.
+ * @param cloudInfoSources
+ */
+ public void setCloudInfoSource(List<String> cloudInfoSources) {
+ _record.setListField(CloudConfigProperty.CLOUD_INFO_SOURCE.name(), cloudInfoSources);
+ }
+
+ /**
+ * Get the CLOUD_INFO_SOURCE field.
+ * @return CLOUD_INFO_SOURCE field.
+ */
+ public List<String> getCloudInfoSources() {
+ return _record.getListField(CloudConfigProperty.CLOUD_INFO_SOURCE.name());
+ }
+
+ /**
+ * Set the CLOUD_INFO_PROCESSOR_NAME field.
+ * @param cloudInfoProcessorName
+ */
+ public void setCloudInfoFProcessorName(String cloudInfoProcessorName) {
+ _record.setSimpleField(CloudConfigProperty.CLOUD_INFO_PROCESSOR_NAME.name(),
+ cloudInfoProcessorName);
+ }
+
+ /**
+ * Get the CLOUD_INFO_PROCESSOR_NAME field.
+ * @return CLOUD_INFO_PROCESSOR_NAME field.
+ */
+ public String getCloudInfoProcessorName() {
+ return _record.getSimpleField(CloudConfigProperty.CLOUD_INFO_PROCESSOR_NAME.name());
+ }
+
+ /**
+ * Set the CLOUD_PROVIDER field.
+ * @param cloudProvider
+ */
+ public void setCloudProvider(CloudProvider cloudProvider) {
+ _record.setSimpleField(CloudConfigProperty.CLOUD_PROVIDER.name(), cloudProvider.name());
+ }
+
+ /**
+ * Get the CLOUD_PROVIDER field.
+ * @return CLOUD_PROVIDER field.
+ */
+ public String getCloudProvider() {
+ return _record.getSimpleField(CloudConfigProperty.CLOUD_PROVIDER.name());
+ }
+
+ public static class Builder {
+ private String _clusterName = null;
+ private CloudProvider _cloudProvider;
+ private boolean _cloudEnabled = DEFAULT_CLOUD_ENABLED;
+ private String _cloudID;
+ private List<String> _cloudInfoSources;
+ private String _cloudInfoProcessorName;
+
+ public CloudConfig build() {
+ validate();
+ return new CloudConfig(_clusterName, _cloudEnabled, _cloudProvider, _cloudID,
+ _cloudInfoSources, _cloudInfoProcessorName);
+ }
+
+ /**
+ * Default constructor
+ */
+ public Builder() {
+ }
+
+ /**
+ * Constructor with Cluster Name as input
+ * @param clusterName
+ */
+ public Builder(String clusterName) {
+ _clusterName = clusterName;
+ }
+
+ /**
+ * Constructor with CloudConfig as input
+ * @param cloudConfig
+ */
+ public Builder(CloudConfig cloudConfig) {
+ _cloudEnabled = cloudConfig.isCloudEnabled();
+ _cloudProvider = CloudProvider.valueOf(cloudConfig.getCloudProvider());
+ _cloudID = cloudConfig.getCloudID();
+ _cloudInfoSources = cloudConfig.getCloudInfoSources();
+ _cloudInfoProcessorName = cloudConfig.getCloudInfoProcessorName();
+ }
+
+ public Builder setClusterName(String v) {
+ _clusterName = v;
+ return this;
+ }
+
+ public Builder setCloudEnabled(boolean isEnabled) {
+ _cloudEnabled = isEnabled;
+ return this;
+ }
+
+ public Builder setCloudProvider(CloudProvider cloudProvider) {
+ _cloudProvider = cloudProvider;
+ return this;
+ }
+
+ public Builder setCloudID(String v) {
+ _cloudID = v;
+ return this;
+ }
+
+ public Builder setCloudInfoSources(List<String> v) {
+ _cloudInfoSources = v;
+ return this;
+ }
+
+ public Builder addCloudInfoSource(String v) {
+ if (_cloudInfoSources == null) {
+ _cloudInfoSources = new ArrayList<String>();
+ }
+ _cloudInfoSources.add(v);
+ return this;
+ }
+
+ public Builder setCloudInfoProcessorName(String v) {
+ _cloudInfoProcessorName = v;
+ return this;
+ }
+
+ public String getClusterName() {
+ return _clusterName;
+ }
+
+ public CloudProvider getCloudProvider() {
+ return _cloudProvider;
+ }
+
+ public boolean getCloudEnabled() {
+ return _cloudEnabled;
+ }
+
+ public String getCloudID() {
+ return _cloudID;
+ }
+
+ public List<String> getCloudInfoSources() {
+ return _cloudInfoSources;
+ }
+
+ public String getCloudInfoProcessorName() {
+ return _cloudInfoProcessorName;
+ }
+
+ private void validate() {
+ if (_cloudEnabled) {
+ if (_cloudID == null) {
+ throw new HelixException(
+ "This Cloud Configuration is Invalid. The CloudID is missing from the config.");
+ }
+ if (_cloudProvider == null) {
+ throw new HelixException(
+ "This Cloud Configuration is Invalid. The Cloud Provider is missing from the config.");
+ } else if (_cloudProvider == CloudProvider.CUSTOMIZED) {
+ if (_cloudInfoProcessorName == null || _cloudInfoSources == null || _cloudInfoSources.size() == 0) {
+ throw new HelixException(
+ "This Cloud Configuration is Invalid. CUSTOMIZED provider has been chosen without defining CloudInfoProcessorName or CloudInfoSources");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/helix-core/src/main/java/org/apache/helix/model/HelixConfigScope.java b/helix-core/src/main/java/org/apache/helix/model/HelixConfigScope.java
index 7c5c91d..8d814c5 100644
--- a/helix-core/src/main/java/org/apache/helix/model/HelixConfigScope.java
+++ b/helix-core/src/main/java/org/apache/helix/model/HelixConfigScope.java
@@ -36,7 +36,8 @@ public class HelixConfigScope {
RESOURCE(2, 0),
PARTITION(2, 1),
CONSTRAINT(2, 0),
- REST(2, 0);
+ REST(2, 0),
+ CLOUD(2, 0);
final int _zkPathArgNum;
final int _mapKeyArgNum;
@@ -78,12 +79,15 @@ public class HelixConfigScope {
"/{clusterName}/CONFIGS/RESOURCE/{resourceName}");
template.addEntry(ConfigScopeProperty.PARTITION, 2,
"/{clusterName}/CONFIGS/RESOURCE/{resourceName}");
+ template.addEntry(ConfigScopeProperty.CLOUD, 2,
+ "/{clusterName}/CONFIGS/CLOUD/{clusterName}");
// get children
template.addEntry(ConfigScopeProperty.CLUSTER, 1, "/{clusterName}/CONFIGS/CLUSTER");
template.addEntry(ConfigScopeProperty.PARTICIPANT, 1, "/{clusterName}/CONFIGS/PARTICIPANT");
template.addEntry(ConfigScopeProperty.RESOURCE, 1, "/{clusterName}/CONFIGS/RESOURCE");
template.addEntry(ConfigScopeProperty.REST, 2, "/{clusterName}/CONFIGS/REST/{clusterName}");
+ template.addEntry(ConfigScopeProperty.CLOUD, 1, "/{clusterName}/CONFIGS/CLOUD");
}
final ConfigScopeProperty _type;
diff --git a/helix-core/src/main/java/org/apache/helix/model/builder/HelixConfigScopeBuilder.java b/helix-core/src/main/java/org/apache/helix/model/builder/HelixConfigScopeBuilder.java
index b1a7cf6..78ed074 100644
--- a/helix-core/src/main/java/org/apache/helix/model/builder/HelixConfigScopeBuilder.java
+++ b/helix-core/src/main/java/org/apache/helix/model/builder/HelixConfigScopeBuilder.java
@@ -126,6 +126,9 @@ public class HelixConfigScopeBuilder {
case REST:
scope = new HelixConfigScope(_type, Arrays.asList(_clusterName, _clusterName), null);
break;
+ case CLOUD:
+ scope = new HelixConfigScope(_type, Arrays.asList(_clusterName, _clusterName), null);
+ break;
default:
break;
}
diff --git a/helix-core/src/test/java/org/apache/helix/model/cloud/TestCloudConfig.java b/helix-core/src/test/java/org/apache/helix/model/cloud/TestCloudConfig.java
new file mode 100644
index 0000000..ee83011
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/model/cloud/TestCloudConfig.java
@@ -0,0 +1,204 @@
+package org.apache.helix.model.cloud;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import org.apache.helix.ConfigAccessor;
+import org.apache.helix.HelixException;
+import org.apache.helix.PropertyKey.Builder;
+import org.apache.helix.TestHelper;
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.manager.zk.ZKHelixDataAccessor;
+import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.model.CloudConfig;
+import org.apache.helix.cloud.constants.CloudProvider;
+import java.util.List;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class TestCloudConfig extends ZkUnitTestBase {
+
+ @Test(expectedExceptions = HelixException.class)
+ public void testCloudConfigNonExistentCluster() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ // Read CloudConfig from Zookeeper and get exception since cluster in not setup yet
+ ConfigAccessor _configAccessor = new ConfigAccessor(_gZkClient);
+ CloudConfig cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ }
+
+ @Test(dependsOnMethods = "testCloudConfigNonExistentCluster")
+ public void testCloudConfigNull() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+ // Read CloudConfig from Zookeeper
+ ConfigAccessor _configAccessor = new ConfigAccessor(_gZkClient);
+ CloudConfig cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ // since CloudConfig is not written to ZooKeeper, the output should be null
+ Assert.assertNull(cloudConfigFromZk);
+ }
+
+ @Test(dependsOnMethods = "testCloudConfigNull")
+ public void testCloudConfig() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+
+ // Create dummy CloudConfig object
+ CloudConfig cloudConfig = new CloudConfig(clusterName);
+ cloudConfig.setCloudEnabled(true);
+ cloudConfig.setCloudProvider(CloudProvider.AZURE);
+ cloudConfig.setCloudID("TestID");
+ List<String> infoURL = new ArrayList<String>();
+ infoURL.add("TestURL");
+ cloudConfig.setCloudInfoSource(infoURL);
+ cloudConfig.setCloudInfoFProcessorName("TestProcessor");
+
+ // Write the CloudConfig to Zookeeper
+ ZKHelixDataAccessor accessor =
+ new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+ accessor.setProperty(keyBuilder.cloudConfig(), cloudConfig);
+
+ // Read CloudConfig from Zookeeper and check the content
+ ConfigAccessor _configAccessor = new ConfigAccessor(_gZkClient);
+ CloudConfig cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ Assert.assertTrue(cloudConfigFromZk.isCloudEnabled());
+ Assert.assertEquals(cloudConfigFromZk.getCloudProvider(), CloudProvider.AZURE.name());
+ Assert.assertEquals(cloudConfigFromZk.getCloudID(), "TestID");
+ Assert.assertEquals(cloudConfigFromZk.getCloudInfoSources().size(), 1);
+ Assert.assertEquals(cloudConfigFromZk.getCloudInfoSources().get(0), "TestURL");
+ Assert.assertEquals(cloudConfigFromZk.getCloudInfoProcessorName(), "TestProcessor");
+ }
+
+ @Test(expectedExceptions = HelixException.class)
+ public void testUnverifiedCloudConfigBuilder() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ CloudConfig.Builder builder = new CloudConfig.Builder(clusterName);
+ builder.setCloudEnabled(true);
+ // Verify will fail because cloudID has net been defined.
+ CloudConfig cloudConfig = builder.build();
+ }
+
+ @Test(expectedExceptions = HelixException.class)
+ public void testUnverifiedCloudConfigBuilderEmptySources() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ CloudConfig.Builder builder = new CloudConfig.Builder(clusterName);
+ builder.setCloudEnabled(true);
+ builder.setCloudProvider(CloudProvider.CUSTOMIZED);
+ builder.setCloudID("TestID");
+ List<String> emptyList = new ArrayList<String>();
+ builder.setCloudInfoSources(emptyList);
+ builder.setCloudInfoProcessorName("TestProcessor");
+ CloudConfig cloudConfig = builder.build();
+ }
+
+ @Test(expectedExceptions = HelixException.class)
+ public void testUnverifiedCloudConfigBuilderWithoutProcessor() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ CloudConfig.Builder builder = new CloudConfig.Builder(clusterName);
+ builder.setCloudEnabled(true);
+ builder.setCloudProvider(CloudProvider.CUSTOMIZED);
+ builder.setCloudID("TestID");
+ List<String> testList = new ArrayList<String>();
+ builder.setCloudInfoSources(testList);
+ builder.addCloudInfoSource("TestURL");
+ CloudConfig cloudConfig = builder.build();
+ }
+
+ @Test(dependsOnMethods = "testCloudConfig")
+ public void testCloudConfigBuilder() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+ CloudConfig.Builder builder = new CloudConfig.Builder(clusterName);
+ builder.setCloudEnabled(true);
+ builder.setCloudProvider(CloudProvider.CUSTOMIZED);
+ builder.setCloudID("TestID");
+ builder.addCloudInfoSource("TestURL0");
+ builder.addCloudInfoSource("TestURL1");
+ builder.setCloudInfoProcessorName("TestProcessor");
+
+ // Check builder getter methods
+ Assert.assertTrue(builder.getCloudEnabled());
+ Assert.assertEquals(builder.getCloudProvider(), CloudProvider.CUSTOMIZED);
+ Assert.assertEquals(builder.getClusterName(), clusterName);
+ Assert.assertEquals(builder.getCloudID(), "TestID");
+ List<String> listUrlFromBuilder = builder.getCloudInfoSources();
+ Assert.assertEquals(listUrlFromBuilder.size(), 2);
+ Assert.assertEquals(listUrlFromBuilder.get(0), "TestURL0");
+ Assert.assertEquals(listUrlFromBuilder.get(1), "TestURL1");
+ Assert.assertEquals(builder.getCloudInfoProcessorName(), "TestProcessor");
+
+ CloudConfig cloudConfig = builder.build();
+
+ ZKHelixDataAccessor accessor =
+ new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+ accessor.setProperty(keyBuilder.cloudConfig(), cloudConfig);
+
+ // Read CloudConfig from Zookeeper and check the content
+ ConfigAccessor _configAccessor = new ConfigAccessor(_gZkClient);
+ CloudConfig cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ Assert.assertTrue(cloudConfigFromZk.isCloudEnabled());
+ Assert.assertEquals(cloudConfigFromZk.getCloudProvider(), CloudProvider.CUSTOMIZED.name());
+ Assert.assertEquals(cloudConfigFromZk.getCloudID(), "TestID");
+ List<String> listUrlFromZk = cloudConfigFromZk.getCloudInfoSources();
+ Assert.assertEquals(listUrlFromZk.get(0), "TestURL0");
+ Assert.assertEquals(listUrlFromZk.get(1), "TestURL1");
+ Assert.assertEquals(cloudConfigFromZk.getCloudInfoProcessorName(), "TestProcessor");
+ }
+
+ @Test(dependsOnMethods = "testCloudConfigBuilder")
+ public void testCloudConfigBuilderAzureProvider() {
+ String className = getShortClassName();
+ String clusterName = "CLUSTER_" + className;
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+ CloudConfig.Builder builder = new CloudConfig.Builder(clusterName);
+ builder.setCloudEnabled(true);
+ builder.setCloudProvider(CloudProvider.AZURE);
+ builder.setCloudID("TestID");
+ builder.setCloudInfoProcessorName("TestProcessor");
+
+ // Check builder getter methods
+ Assert.assertTrue(builder.getCloudEnabled());
+ Assert.assertEquals(builder.getCloudProvider(), CloudProvider.AZURE);
+
+ CloudConfig cloudConfig = builder.build();
+
+ ZKHelixDataAccessor accessor =
+ new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+ accessor.setProperty(keyBuilder.cloudConfig(), cloudConfig);
+
+ // Read CloudConfig from Zookeeper and check the content
+ ConfigAccessor _configAccessor = new ConfigAccessor(_gZkClient);
+ CloudConfig cloudConfigFromZk = _configAccessor.getCloudConfig(clusterName);
+ Assert.assertTrue(cloudConfigFromZk.isCloudEnabled());
+ Assert.assertEquals(cloudConfigFromZk.getCloudProvider(), CloudProvider.AZURE.name());
+
+ // Since CloudProvider is not CUSTOMIZED, CloudInfoProcessor will be null.
+ Assert.assertNull(cloudConfigFromZk.getCloudInfoProcessorName());
+ }
+}