SOLR-9503: NPE in Replica Placement Rules when using Overseer Role with other rules

This commit is contained in:
Noble Paul 2017-01-07 01:40:47 +10:30
parent b32cd82318
commit cd4f908d5b
4 changed files with 10 additions and 29 deletions

View File

@ -335,6 +335,8 @@ Bug Fixes
* SOLR-9931: JSON Facet API hll (hyper-log-log) function returned 0 for non-empty buckets with no field values
in local mode, but nothing for distributed mode. Both modes now return 0. (yonik)
* SOLR-9503: NPE in Replica Placement Rules when using Overseer Role with other rules (Tim Owen via noble)
Other Changes
----------------------

View File

@ -17,7 +17,6 @@
package org.apache.solr.cloud.rule;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
@ -39,7 +38,6 @@ import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.rule.ImplicitSnitch;
import org.apache.solr.common.cloud.rule.Snitch;
import org.apache.solr.common.cloud.rule.SnitchContext;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.CoreContainer;
import org.slf4j.Logger;
@ -48,7 +46,6 @@ import org.slf4j.LoggerFactory;
import static java.util.Collections.singletonList;
import static org.apache.solr.cloud.rule.Rule.MatchStatus.*;
import static org.apache.solr.cloud.rule.Rule.Phase.*;
import static org.apache.solr.common.util.StrUtils.formatString;
import static org.apache.solr.common.util.Utils.getDeepCopy;
public class ReplicaAssigner {
@ -103,7 +100,6 @@ public class ReplicaAssigner {
this.participatingLiveNodes = new ArrayList<>(participatingLiveNodes);
this.nodeVsTags = getTagsForNodes(cc, snitches);
this.shardVsNodes = getDeepCopy(shardVsNodes, 2);
validateTags(nodeVsTags);
if (clusterState != null) {
Map<String, DocCollection> collections = clusterState.getCollectionsMap();
@ -284,21 +280,6 @@ public class ReplicaAssigner {
return result;
}
private void validateTags(Map<String, Map<String, Object>> nodeVsTags) {
List<String> errors = new ArrayList<>();
for (Rule rule : rules) {
for (Map.Entry<String, Map<String, Object>> e : nodeVsTags.entrySet()) {
if (e.getValue().get(rule.tag.name) == null) {
errors.add(formatString("The value for tag {0} is not available for node {1}", rule.tag.name, e.getKey()));
}
}
}
if (!errors.isEmpty()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, StrUtils.join(errors, ','));
}
}
/**
* get all permutations for the int[] whose items are 0..level
*/
@ -422,14 +403,12 @@ public class ReplicaAssigner {
context.exception = new SolrException(SolrException.ErrorCode.SERVER_ERROR,
"Not all tags were obtained from node " + node);
} else {
if (context.getTags().keySet().containsAll(context.snitchInfo.getTagNames())) {
Map<String, Object> tags = result.get(node);
if (tags == null) {
tags = new HashMap<>();
result.put(node, tags);
}
tags.putAll(context.getTags());
Map<String, Object> tags = result.get(node);
if (tags == null) {
tags = new HashMap<>();
result.put(node, tags);
}
tags.putAll(context.getTags());
}
}
}

View File

@ -202,7 +202,7 @@ public class Rule {
@Override
public boolean canMatch(Object ruleVal, Object testVal) {
return compareNum(ruleVal, testVal) == 1;
return testVal != null && compareNum(ruleVal, testVal) == 1;
}
},
@ -214,7 +214,7 @@ public class Rule {
@Override
public boolean canMatch(Object ruleVal, Object testVal) {
return compareNum(ruleVal, testVal) == -1;
return testVal != null && compareNum(ruleVal, testVal) == -1;
}
@Override

View File

@ -85,7 +85,7 @@ public class RuleEngineTest extends SolrTestCaseJ4{
new HashMap(), new ArrayList<>(MockSnitch.nodeVsTags.keySet()), null, null ).getNodeMappings();
assertNotNull(mapping);
rules = parseRules("[{role:'!overseer'}]" );
rules = parseRules("[{role:'!overseer'}, {'freedisk':'>1'}]" );
Map<String, Object> snitchSession = new HashMap<>();
List<String> preferredOverseerNodes = ImmutableList.of("127.0.0.1:49947_", "127.0.0.1:49952_");
ReplicaAssigner replicaAssigner = new ReplicaAssigner(