You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by ka...@apache.org on 2013/11/06 00:07:37 UTC
git commit: [HELIX-209] Make UserConfig and RebalancerConfig backward
compatible
Updated Branches:
refs/heads/helix-logical-model 842035a4b -> 26a9413f6
[HELIX-209] Make UserConfig and RebalancerConfig backward compatible
Project: http://git-wip-us.apache.org/repos/asf/incubator-helix/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-helix/commit/26a9413f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-helix/tree/26a9413f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-helix/diff/26a9413f
Branch: refs/heads/helix-logical-model
Commit: 26a9413f6c04c8b9eabd8f091ddffb76374e5722
Parents: 842035a
Author: Kanak Biscuitwala <ka...@apache.org>
Authored: Tue Nov 5 15:07:25 2013 -0800
Committer: Kanak Biscuitwala <ka...@apache.org>
Committed: Tue Nov 5 15:07:25 2013 -0800
----------------------------------------------------------------------
helix-core/pom.xml | 2 +-
.../helix/api/accessor/ClusterAccessor.java | 14 +--
.../helix/api/accessor/ParticipantAccessor.java | 8 +-
.../helix/api/accessor/ResourceAccessor.java | 14 ++-
.../helix/api/config/NamespacedConfig.java | 8 +-
.../rebalancer/context/RebalancerConfig.java | 30 ++++---
.../helix/model/ClusterConfiguration.java | 40 ++++++++-
.../java/org/apache/helix/model/IdealState.java | 18 ++++
.../org/apache/helix/model/InstanceConfig.java | 38 ++++++++-
.../helix/model/ResourceConfiguration.java | 41 +++++++++
.../apache/helix/api/TestNamespacedConfig.java | 89 ++++++++++++++++++++
11 files changed, 264 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/pom.xml
----------------------------------------------------------------------
diff --git a/helix-core/pom.xml b/helix-core/pom.xml
index af04d85..99763fb 100644
--- a/helix-core/pom.xml
+++ b/helix-core/pom.xml
@@ -148,7 +148,7 @@ under the License.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
- <version>r09</version>
+ <version>15.0</version>
</dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/api/accessor/ClusterAccessor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/api/accessor/ClusterAccessor.java b/helix-core/src/main/java/org/apache/helix/api/accessor/ClusterAccessor.java
index 85b8432..c48f4f2 100644
--- a/helix-core/src/main/java/org/apache/helix/api/accessor/ClusterAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/api/accessor/ClusterAccessor.java
@@ -69,10 +69,10 @@ import org.apache.helix.model.ResourceAssignment;
import org.apache.helix.model.ResourceConfiguration;
import org.apache.helix.model.StateModelDefinition;
import org.apache.log4j.Logger;
-import org.testng.internal.annotations.Sets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
public class ClusterAccessor {
private static Logger LOG = Logger.getLogger(ClusterAccessor.class);
@@ -247,12 +247,12 @@ public class ClusterAccessor {
PauseSignal pauseSignal = _accessor.getProperty(_keyBuilder.pause());
boolean isPaused = pauseSignal != null;
- ClusterConfiguration clusterUserConfig = _accessor.getProperty(_keyBuilder.clusterConfig());
+ ClusterConfiguration clusterConfig = _accessor.getProperty(_keyBuilder.clusterConfig());
boolean autoJoinAllowed = false;
UserConfig userConfig;
- if (clusterUserConfig != null) {
- userConfig = UserConfig.from(clusterUserConfig);
- autoJoinAllowed = clusterUserConfig.autoJoinAllowed();
+ if (clusterConfig != null) {
+ userConfig = clusterConfig.getUserConfig();
+ autoJoinAllowed = clusterConfig.autoJoinAllowed();
} else {
userConfig = new UserConfig(Scope.cluster(_clusterId));
}
@@ -384,7 +384,7 @@ public class ClusterAccessor {
Map<ParticipantId, Participant> participantMap = Maps.newHashMap();
for (String participantName : instanceConfigMap.keySet()) {
InstanceConfig instanceConfig = instanceConfigMap.get(participantName);
- UserConfig userConfig = UserConfig.from(instanceConfig);
+ UserConfig userConfig = instanceConfig.getUserConfig();
LiveInstance liveInstance = liveInstanceMap.get(participantName);
Map<String, Message> instanceMsgMap = messageMap.get(participantName);
@@ -429,7 +429,7 @@ public class ClusterAccessor {
*/
public UserConfig readUserConfig() {
ClusterConfiguration clusterConfig = _accessor.getProperty(_keyBuilder.clusterConfig());
- return clusterConfig != null ? UserConfig.from(clusterConfig) : null;
+ return clusterConfig != null ? clusterConfig.getUserConfig() : null;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/api/accessor/ParticipantAccessor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/api/accessor/ParticipantAccessor.java b/helix-core/src/main/java/org/apache/helix/api/accessor/ParticipantAccessor.java
index 83dd53e..07fec9e 100644
--- a/helix-core/src/main/java/org/apache/helix/api/accessor/ParticipantAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/api/accessor/ParticipantAccessor.java
@@ -403,7 +403,7 @@ public class ParticipantAccessor {
public UserConfig readUserConfig(ParticipantId participantId) {
InstanceConfig instanceConfig =
_accessor.getProperty(_keyBuilder.instanceConfig(participantId.stringify()));
- return instanceConfig != null ? UserConfig.from(instanceConfig) : null;
+ return instanceConfig != null ? instanceConfig.getUserConfig() : null;
}
/**
@@ -528,8 +528,8 @@ public class ParticipantAccessor {
RunningInstance runningInstance = null;
if (liveInstance != null) {
runningInstance =
- new RunningInstance(liveInstance.getTypedSessionId(), liveInstance.getTypedHelixVersion(),
- liveInstance.getProcessId());
+ new RunningInstance(liveInstance.getTypedSessionId(),
+ liveInstance.getTypedHelixVersion(), liveInstance.getProcessId());
}
Map<MessageId, Message> msgMap = new HashMap<MessageId, Message>();
@@ -568,7 +568,7 @@ public class ParticipantAccessor {
return null;
}
- UserConfig userConfig = UserConfig.from(instanceConfig);
+ UserConfig userConfig = instanceConfig.getUserConfig();
LiveInstance liveInstance = _accessor.getProperty(_keyBuilder.liveInstance(participantName));
Map<String, Message> instanceMsgMap = Collections.emptyMap();
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/api/accessor/ResourceAccessor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/api/accessor/ResourceAccessor.java b/helix-core/src/main/java/org/apache/helix/api/accessor/ResourceAccessor.java
index 517c8c4..670d167 100644
--- a/helix-core/src/main/java/org/apache/helix/api/accessor/ResourceAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/api/accessor/ResourceAccessor.java
@@ -416,20 +416,28 @@ public class ResourceAccessor {
ResourceConfiguration resourceConfiguration, IdealState idealState,
ExternalView externalView, ResourceAssignment resourceAssignment) {
UserConfig userConfig;
+ RebalancerContext rebalancerContext = null;
ResourceType type = ResourceType.DATA;
if (resourceConfiguration != null) {
- userConfig = UserConfig.from(resourceConfiguration);
+ userConfig = resourceConfiguration.getUserConfig();
type = resourceConfiguration.getType();
} else {
userConfig = new UserConfig(Scope.resource(resourceId));
}
int bucketSize = 0;
boolean batchMessageMode = false;
- RebalancerContext rebalancerContext = null;
if (idealState != null) {
- rebalancerContext = PartitionedRebalancerContext.from(idealState);
+ if (resourceConfiguration != null) {
+ rebalancerContext =
+ resourceConfiguration.getRebalancerContext(PartitionedRebalancerContext.class);
+ }
+ if (rebalancerContext == null) {
+ // fallback: get rebalancer context from ideal state
+ rebalancerContext = PartitionedRebalancerContext.from(idealState);
+ }
bucketSize = idealState.getBucketSize();
batchMessageMode = idealState.getBatchMessageMode();
+ idealState.updateUserConfig(userConfig);
} else if (resourceConfiguration != null) {
bucketSize = resourceConfiguration.getBucketSize();
batchMessageMode = resourceConfiguration.getBatchMessageMode();
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/api/config/NamespacedConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/api/config/NamespacedConfig.java b/helix-core/src/main/java/org/apache/helix/api/config/NamespacedConfig.java
index c6f9d19..4ea0ace 100644
--- a/helix-core/src/main/java/org/apache/helix/api/config/NamespacedConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/api/config/NamespacedConfig.java
@@ -35,7 +35,7 @@ import com.google.common.collect.Maps;
* Generic configuration of Helix components prefixed with a namespace
*/
public class NamespacedConfig extends ZNRecord {
- private static final char PREFIX_CHAR = '!';
+ public static final char PREFIX_CHAR = '!';
private final String _prefix;
/**
@@ -176,7 +176,7 @@ public class NamespacedConfig extends ZNRecord {
* Get all map fields with prefixed keys
* @return prefixed map fields
*/
- private Map<String, Map<String, String>> getPrefixedMapFields() {
+ public Map<String, Map<String, String>> getPrefixedMapFields() {
return super.getMapFields();
}
@@ -184,7 +184,7 @@ public class NamespacedConfig extends ZNRecord {
* Get all list fields with prefixed keys
* @return prefixed list fields
*/
- private Map<String, List<String>> getPrefixedListFields() {
+ public Map<String, List<String>> getPrefixedListFields() {
return super.getListFields();
}
@@ -192,7 +192,7 @@ public class NamespacedConfig extends ZNRecord {
* Get all simple fields with prefixed keys
* @return prefixed simple fields
*/
- private Map<String, String> getPrefixedSimpleFields() {
+ public Map<String, String> getPrefixedSimpleFields() {
return super.getSimpleFields();
}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/controller/rebalancer/context/RebalancerConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/context/RebalancerConfig.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/context/RebalancerConfig.java
index 64f70c3..aa872c4 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/context/RebalancerConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/context/RebalancerConfig.java
@@ -100,15 +100,17 @@ public final class RebalancerConfig {
private RebalancerContext getContext() {
String className = _config.getSimpleField(Fields.REBALANCER_CONTEXT_CLASS.toString());
- try {
- Class<? extends RebalancerContext> contextClass =
- HelixUtil.loadClass(getClass(), className).asSubclass(RebalancerContext.class);
- String serialized = _config.getSimpleField(Fields.REBALANCER_CONTEXT.toString());
- return _serializer.deserialize(contextClass, serialized);
- } catch (ClassNotFoundException e) {
- LOG.error(className + " is not a valid class");
- } catch (ClassCastException e) {
- LOG.error(className + " does not implement RebalancerContext");
+ if (className != null) {
+ try {
+ Class<? extends RebalancerContext> contextClass =
+ HelixUtil.loadClass(getClass(), className).asSubclass(RebalancerContext.class);
+ String serialized = _config.getSimpleField(Fields.REBALANCER_CONTEXT.toString());
+ return _serializer.deserialize(contextClass, serialized);
+ } catch (ClassNotFoundException e) {
+ LOG.error(className + " is not a valid class");
+ } catch (ClassCastException e) {
+ LOG.error(className + " does not implement RebalancerContext");
+ }
}
return null;
}
@@ -134,10 +136,12 @@ public final class RebalancerConfig {
* @return RebalancerContext subclass instance, or null if conversion is not possible
*/
public <T extends RebalancerContext> T getRebalancerContext(Class<T> contextClass) {
- try {
- return contextClass.cast(_context);
- } catch (ClassCastException e) {
- LOG.warn(contextClass + " is incompatible with context class: " + _context.getClass());
+ if (_context != null) {
+ try {
+ return contextClass.cast(_context);
+ } catch (ClassCastException e) {
+ LOG.warn(contextClass + " is incompatible with context class: " + _context.getClass());
+ }
}
return null;
}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/model/ClusterConfiguration.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/model/ClusterConfiguration.java b/helix-core/src/main/java/org/apache/helix/model/ClusterConfiguration.java
index d733a5c..8386d6c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ClusterConfiguration.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ClusterConfiguration.java
@@ -1,10 +1,11 @@
package org.apache.helix.model;
-import org.apache.helix.HelixManager;
import org.apache.helix.HelixProperty;
import org.apache.helix.ZNRecord;
+import org.apache.helix.api.config.NamespacedConfig;
import org.apache.helix.api.config.UserConfig;
import org.apache.helix.api.id.ClusterId;
+import org.apache.helix.manager.zk.ZKHelixManager;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -46,11 +47,19 @@ public class ClusterConfiguration extends HelixProperty {
}
/**
+ * Get a typed cluster id
+ * @return ClusterId
+ */
+ public ClusterId getClusterId() {
+ return ClusterId.from(getId());
+ }
+
+ /**
* Determine if participants can automatically join the cluster
* @return true if allowed, false if disallowed
*/
public boolean autoJoinAllowed() {
- return _record.getBooleanField(HelixManager.ALLOW_PARTICIPANT_AUTO_JOIN, false);
+ return _record.getBooleanField(ZKHelixManager.ALLOW_PARTICIPANT_AUTO_JOIN, false);
}
/**
@@ -58,7 +67,32 @@ public class ClusterConfiguration extends HelixProperty {
* @param autoJoinAllowed true if allowed, false if disallowed
*/
public void setAutoJoinAllowed(boolean autoJoinAllowed) {
- _record.setBooleanField(HelixManager.ALLOW_PARTICIPANT_AUTO_JOIN, autoJoinAllowed);
+ _record.setBooleanField(ZKHelixManager.ALLOW_PARTICIPANT_AUTO_JOIN, autoJoinAllowed);
+ }
+
+ /**
+ * Get a backward-compatible cluster user config
+ * @return UserConfig
+ */
+ public UserConfig getUserConfig() {
+ UserConfig userConfig = UserConfig.from(this);
+ for (String simpleField : _record.getSimpleFields().keySet()) {
+ if (!simpleField.contains(NamespacedConfig.PREFIX_CHAR + "")
+ && !simpleField.equals(ZKHelixManager.ALLOW_PARTICIPANT_AUTO_JOIN)) {
+ userConfig.setSimpleField(simpleField, _record.getSimpleField(simpleField));
+ }
+ }
+ for (String listField : _record.getListFields().keySet()) {
+ if (!listField.contains(NamespacedConfig.PREFIX_CHAR + "")) {
+ userConfig.setListField(listField, _record.getListField(listField));
+ }
+ }
+ for (String mapField : _record.getMapFields().keySet()) {
+ if (!mapField.contains(NamespacedConfig.PREFIX_CHAR + "")) {
+ userConfig.setMapField(mapField, _record.getMapField(mapField));
+ }
+ }
+ return userConfig;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/model/IdealState.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/model/IdealState.java b/helix-core/src/main/java/org/apache/helix/model/IdealState.java
index 09aed50..173e251 100644
--- a/helix-core/src/main/java/org/apache/helix/model/IdealState.java
+++ b/helix-core/src/main/java/org/apache/helix/model/IdealState.java
@@ -33,6 +33,8 @@ import org.apache.helix.HelixDefinedState;
import org.apache.helix.HelixProperty;
import org.apache.helix.ZNRecord;
import org.apache.helix.api.State;
+import org.apache.helix.api.config.NamespacedConfig;
+import org.apache.helix.api.config.UserConfig;
import org.apache.helix.api.id.ParticipantId;
import org.apache.helix.api.id.PartitionId;
import org.apache.helix.api.id.ResourceId;
@@ -42,7 +44,9 @@ import org.apache.helix.controller.rebalancer.HelixRebalancer;
import org.apache.helix.controller.rebalancer.RebalancerRef;
import org.apache.log4j.Logger;
+import com.google.common.base.Enums;
import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
@@ -752,6 +756,20 @@ public class IdealState extends HelixProperty {
}
/**
+ * Get the non-Helix simple fields from this property and add them to a UserConfig
+ * @param userConfig the user config to update
+ */
+ public void updateUserConfig(UserConfig userConfig) {
+ for (String simpleField : _record.getSimpleFields().keySet()) {
+ Optional<IdealStateProperty> enumField =
+ Enums.getIfPresent(IdealStateProperty.class, simpleField);
+ if (!simpleField.contains(NamespacedConfig.PREFIX_CHAR + "") && !enumField.isPresent()) {
+ userConfig.setSimpleField(simpleField, _record.getSimpleField(simpleField));
+ }
+ }
+ }
+
+ /**
* Convert a preference list of strings into a preference list of participants
* @param rawPreferenceList the list of strings representing participant names
* @return converted list
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java b/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
index 8f776a0..35b4bd4 100644
--- a/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
@@ -27,9 +27,13 @@ import java.util.Set;
import org.apache.helix.HelixProperty;
import org.apache.helix.ZNRecord;
+import org.apache.helix.api.config.NamespacedConfig;
+import org.apache.helix.api.config.UserConfig;
import org.apache.helix.api.id.ParticipantId;
import org.apache.helix.api.id.PartitionId;
-import org.apache.log4j.Logger;
+
+import com.google.common.base.Enums;
+import com.google.common.base.Optional;
/**
* Instance configurations
@@ -46,8 +50,6 @@ public class InstanceConfig extends HelixProperty {
TAG_LIST
}
- private static final Logger _logger = Logger.getLogger(InstanceConfig.class.getName());
-
/**
* Instantiate for a specific instance
* @param instanceId the instance identifier
@@ -265,6 +267,36 @@ public class InstanceConfig extends HelixProperty {
return ParticipantId.from(getInstanceName());
}
+ /**
+ * Get a backward-compatible participant user config
+ * @return UserConfig
+ */
+ public UserConfig getUserConfig() {
+ UserConfig userConfig = UserConfig.from(this);
+ for (String simpleField : _record.getSimpleFields().keySet()) {
+ Optional<InstanceConfigProperty> enumField =
+ Enums.getIfPresent(InstanceConfigProperty.class, simpleField);
+ if (!simpleField.contains(NamespacedConfig.PREFIX_CHAR + "") && !enumField.isPresent()) {
+ userConfig.setSimpleField(simpleField, _record.getSimpleField(simpleField));
+ }
+ }
+ for (String listField : _record.getListFields().keySet()) {
+ Optional<InstanceConfigProperty> enumField =
+ Enums.getIfPresent(InstanceConfigProperty.class, listField);
+ if (!listField.contains(NamespacedConfig.PREFIX_CHAR + "") && !enumField.isPresent()) {
+ userConfig.setListField(listField, _record.getListField(listField));
+ }
+ }
+ for (String mapField : _record.getMapFields().keySet()) {
+ Optional<InstanceConfigProperty> enumField =
+ Enums.getIfPresent(InstanceConfigProperty.class, mapField);
+ if (!mapField.contains(NamespacedConfig.PREFIX_CHAR + "") && !enumField.isPresent()) {
+ userConfig.setMapField(mapField, _record.getMapField(mapField));
+ }
+ }
+ return userConfig;
+ }
+
@Override
public boolean isValid() {
// HELIX-65: remove check for hostname/port existence
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/main/java/org/apache/helix/model/ResourceConfiguration.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/model/ResourceConfiguration.java b/helix-core/src/main/java/org/apache/helix/model/ResourceConfiguration.java
index 230a78b..f32649f 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ResourceConfiguration.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ResourceConfiguration.java
@@ -2,8 +2,15 @@ package org.apache.helix.model;
import org.apache.helix.HelixProperty;
import org.apache.helix.ZNRecord;
+import org.apache.helix.api.config.NamespacedConfig;
import org.apache.helix.api.config.ResourceConfig.ResourceType;
+import org.apache.helix.api.config.UserConfig;
import org.apache.helix.api.id.ResourceId;
+import org.apache.helix.controller.rebalancer.context.RebalancerConfig;
+import org.apache.helix.controller.rebalancer.context.RebalancerContext;
+
+import com.google.common.base.Enums;
+import com.google.common.base.Optional;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -71,4 +78,38 @@ public class ResourceConfiguration extends HelixProperty {
public ResourceType getType() {
return _record.getEnumField(Fields.TYPE.toString(), ResourceType.class, ResourceType.DATA);
}
+
+ /**
+ * Get a backward-compatible resource user config
+ * @return UserConfig
+ */
+ public UserConfig getUserConfig() {
+ UserConfig userConfig = UserConfig.from(this);
+ for (String simpleField : _record.getSimpleFields().keySet()) {
+ Optional<Fields> enumField = Enums.getIfPresent(Fields.class, simpleField);
+ if (!simpleField.contains(NamespacedConfig.PREFIX_CHAR + "") && !enumField.isPresent()) {
+ userConfig.setSimpleField(simpleField, _record.getSimpleField(simpleField));
+ }
+ }
+ for (String listField : _record.getListFields().keySet()) {
+ if (!listField.contains(NamespacedConfig.PREFIX_CHAR + "")) {
+ userConfig.setListField(listField, _record.getListField(listField));
+ }
+ }
+ for (String mapField : _record.getMapFields().keySet()) {
+ if (!mapField.contains(NamespacedConfig.PREFIX_CHAR + "")) {
+ userConfig.setMapField(mapField, _record.getMapField(mapField));
+ }
+ }
+ return userConfig;
+ }
+
+ /**
+ * Get a RebalancerContext if available
+ * @return RebalancerContext, or null
+ */
+ public RebalancerContext getRebalancerContext(Class<? extends RebalancerContext> clazz) {
+ RebalancerConfig config = new RebalancerConfig(this);
+ return config.getRebalancerContext(clazz);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/26a9413f/helix-core/src/test/java/org/apache/helix/api/TestNamespacedConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/api/TestNamespacedConfig.java b/helix-core/src/test/java/org/apache/helix/api/TestNamespacedConfig.java
index 5a14287..761ffe2 100644
--- a/helix-core/src/test/java/org/apache/helix/api/TestNamespacedConfig.java
+++ b/helix-core/src/test/java/org/apache/helix/api/TestNamespacedConfig.java
@@ -3,10 +3,18 @@ package org.apache.helix.api;
import java.util.List;
import java.util.Map;
+import org.apache.helix.api.config.ResourceConfig.ResourceType;
import org.apache.helix.api.config.UserConfig;
+import org.apache.helix.api.id.ClusterId;
import org.apache.helix.api.id.ParticipantId;
+import org.apache.helix.api.id.ResourceId;
+import org.apache.helix.manager.zk.ZKHelixManager;
+import org.apache.helix.model.ClusterConfiguration;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.InstanceConfig.InstanceConfigProperty;
+import org.apache.helix.model.ResourceConfiguration;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -85,4 +93,85 @@ public class TestNamespacedConfig {
Assert.assertEquals(instanceConfig.getRecord().getListField(prefixedKey), testListValue);
Assert.assertEquals(instanceConfig.getRecord().getMapField(prefixedKey), testMapValue);
}
+
+ @Test
+ public void testResourceUserConfigCompatibility() {
+ final String KEY1 = "key1";
+ final String VALUE1 = "value1";
+ final String KEY2 = "key2";
+ final String VALUE2 = "value2";
+ final String KEY3 = "key3";
+ final String VALUE3 = "value3";
+
+ // add key1 through user config, key2 through resource config, key3 through ideal state,
+ // resource type through resource config, rebalance mode through ideal state
+ ResourceId resourceId = ResourceId.from("resourceId");
+ UserConfig userConfig = new UserConfig(Scope.resource(resourceId));
+ userConfig.setSimpleField(KEY1, VALUE1);
+ ResourceConfiguration resourceConfig = new ResourceConfiguration(resourceId);
+ resourceConfig.setType(ResourceType.DATA);
+ resourceConfig.addNamespacedConfig(userConfig);
+ resourceConfig.getRecord().setSimpleField(KEY2, VALUE2);
+ IdealState idealState = new IdealState(resourceId);
+ idealState.setRebalanceMode(RebalanceMode.USER_DEFINED);
+ idealState.getRecord().setSimpleField(KEY3, VALUE3);
+
+ // should have key1, key2, and key3, not type or rebalance mode
+ UserConfig result = resourceConfig.getUserConfig();
+ idealState.updateUserConfig(result);
+ Assert.assertEquals(result.getSimpleField(KEY1), VALUE1);
+ Assert.assertEquals(result.getSimpleField(KEY2), VALUE2);
+ Assert.assertEquals(result.getSimpleField(KEY3), VALUE3);
+ Assert.assertNull(result.getSimpleField(ResourceConfiguration.Fields.TYPE.toString()));
+ Assert
+ .assertNull(result.getSimpleField(IdealState.IdealStateProperty.REBALANCE_MODE.toString()));
+ }
+
+ @Test
+ public void testParticipantUserConfigCompatibility() {
+ final String KEY1 = "key1";
+ final String VALUE1 = "value1";
+ final String KEY2 = "key2";
+ final String VALUE2 = "value2";
+
+ // add key1 through user config, key2 through instance config, hostname through user config
+ ParticipantId participantId = ParticipantId.from("participantId");
+ UserConfig userConfig = new UserConfig(Scope.participant(participantId));
+ userConfig.setSimpleField(KEY1, VALUE1);
+ InstanceConfig instanceConfig = new InstanceConfig(participantId);
+ instanceConfig.setHostName("localhost");
+ instanceConfig.addNamespacedConfig(userConfig);
+ instanceConfig.getRecord().setSimpleField(KEY2, VALUE2);
+
+ // should have key1 and key2, not hostname
+ UserConfig result = instanceConfig.getUserConfig();
+ Assert.assertEquals(result.getSimpleField(KEY1), VALUE1);
+ Assert.assertEquals(result.getSimpleField(KEY2), VALUE2);
+ Assert.assertNull(result.getSimpleField(InstanceConfig.InstanceConfigProperty.HELIX_HOST
+ .toString()));
+ }
+
+ @Test
+ public void testClusterUserConfigCompatibility() {
+ final String KEY1 = "key1";
+ final String VALUE1 = "value1";
+ final String KEY2 = "key2";
+ final String VALUE2 = "value2";
+
+ // add the following: key1 straight to user config, key2 to cluster configuration,
+ // allow auto join to cluster configuration
+ ClusterId clusterId = ClusterId.from("clusterId");
+ UserConfig userConfig = new UserConfig(Scope.cluster(clusterId));
+ userConfig.setSimpleField(KEY1, VALUE1);
+ ClusterConfiguration clusterConfiguration = new ClusterConfiguration(clusterId);
+ clusterConfiguration.addNamespacedConfig(userConfig);
+ clusterConfiguration.getRecord().setSimpleField(KEY2, VALUE2);
+ clusterConfiguration.setAutoJoinAllowed(true);
+
+ // there should be key1 and key2, but not auto join
+ UserConfig result = clusterConfiguration.getUserConfig();
+ Assert.assertEquals(result.getSimpleField(KEY1), VALUE1);
+ Assert.assertEquals(result.getSimpleField(KEY2), VALUE2);
+ Assert.assertNull(result.getSimpleField(ZKHelixManager.ALLOW_PARTICIPANT_AUTO_JOIN));
+ }
}