From 53c0e389108e5c10ca8be190d40345683c352225 Mon Sep 17 00:00:00 2001 From: Susheel Kumar Date: Fri, 7 Oct 2016 15:16:34 -0400 Subject: [PATCH] adding routingRule changes --- .../client/solrj/impl/CloudSolrClient.java | 26 ++++++++++++- .../cloud/rule/ClientSnitchContext.java | 39 +++++++++++++++++++ .../solr/common/params/CommonParams.java | 2 + .../solrj/impl/CloudSolrClientTest.java | 21 ++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 solr/solrj/src/java/org/apache/solr/common/cloud/rule/ClientSnitchContext.java diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java index 9bc45294b3ca..81e18c2ae4bd 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java @@ -69,6 +69,10 @@ import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.cloud.ZooKeeperException; +import org.apache.solr.common.cloud.rule.ClientSnitchContext; +import org.apache.solr.common.cloud.rule.ImplicitSnitch; +import org.apache.solr.common.cloud.rule.SnitchContext; +import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ShardParams; import org.apache.solr.common.params.SolrParams; @@ -1160,6 +1164,8 @@ protected NamedList sendRequest(SolrRequest request, String collection) connect(); ClusterState clusterState = zkStateReader.getClusterState(); + ImplicitSnitch snitch = new ImplicitSnitch(); + SnitchContext context = new ClientSnitchContext(null, null, new HashMap<>()); boolean sendToLeaders = false; List replicas = null; @@ -1199,7 +1205,8 @@ protected NamedList sendRequest(SolrRequest request, String collection) } String shardKeys = reqParams.get(ShardParams._ROUTE_); - + String []routingRules = reqParams.getParams(CommonParams.ROUTING_RULE); + // TODO: not a big deal because of the caching, but we could avoid looking // at every shard // when getting leaders if we tweaked some things @@ -1227,6 +1234,8 @@ protected NamedList sendRequest(SolrRequest request, String collection) for (ZkNodeProps nodeProps : slice.getReplicasMap().values()) { ZkCoreNodeProps coreNodeProps = new ZkCoreNodeProps(nodeProps); String node = coreNodeProps.getNodeName(); + if((routingRules!=null && routingRules.length!=0) && !nodeMatchRoutingRule(node,routingRules,snitch,context)) + continue; if (!liveNodes.contains(coreNodeProps.getNodeName()) || Replica.State.getState(coreNodeProps.getState()) != Replica.State.ACTIVE) continue; if (nodes.put(node, nodeProps) == null) { @@ -1289,6 +1298,21 @@ protected NamedList sendRequest(SolrRequest request, String collection) return rsp.getResponse(); } + private boolean nodeMatchRoutingRule(String node, String[] routingRules, ImplicitSnitch snitch, + SnitchContext context) { + //get tags associated with this node + snitch.getTags(node, new HashSet<>(ImplicitSnitch.IP_SNITCHES) , context); + Map tags = context.getTags(); + for(String routingRule : routingRules) + { + String []rule = routingRule.split(":"); + String ip = (String) tags.get(rule[0]); + if(!ip.equals(rule[1])) + return false; + } + return true; + } + private Set getCollectionNames(ClusterState clusterState, String collection) { // Extract each comma separated collection name and store in a List. diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/rule/ClientSnitchContext.java b/solr/solrj/src/java/org/apache/solr/common/cloud/rule/ClientSnitchContext.java new file mode 100644 index 000000000000..cffeca68d2f9 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/rule/ClientSnitchContext.java @@ -0,0 +1,39 @@ +/* + * 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. + */ +package org.apache.solr.common.cloud.rule; + +import java.util.Map; + +import org.apache.solr.common.params.ModifiableSolrParams; + +public class ClientSnitchContext extends SnitchContext { + + public ClientSnitchContext(SnitchInfo perSnitch, String node, Map session) { + super(perSnitch, node, session); + } + + @Override + public Map getZkJson(String path) { + return null; + } + + @Override + public void invokeRemote(String node, ModifiableSolrParams params, String klas, RemoteCallback callback) {} + + + +} diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java index 411d40d6177e..f6d5eb0b352d 100644 --- a/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java +++ b/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java @@ -257,5 +257,7 @@ public static EchoParamStyle get( String v ) { String NAME = "name"; String VALUE_LONG = "val"; + + String ROUTING_RULE = "routingRule"; } diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java index 5e8f6ce29155..15dccf25d50b 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java @@ -607,6 +607,26 @@ public void customHttpClientTest() throws IOException { HttpClientUtil.close(client); } } + + @Test + public void routingRuleTest() throws Exception { + + + + //TBD to look into mocking / create a cluster with some shards matching + //routing rule and other do not. + // String collectionName = "CollectionWithSomeReplicasMatchingRoutingRules"; + // CloudSolrClient solrClient = cluster.getSolrClient(); + + // SolrQuery query = new SolrQuery("*:*"); + // query.add("routingRule","ip_4:11"); + // query.add("routingRule","ip_3:16"); + // QueryResponse response = solrClient.query(collectionName,query); + + //TBD to add assertions to check only matching shards gets added to + // urlList for LoadBalancer to query + + } private static void checkSingleServer(NamedList response) { final CloudSolrClient.RouteResponse rr = (CloudSolrClient.RouteResponse) response; @@ -619,5 +639,6 @@ private static void checkSingleServer(NamedList response) { 1, entry.getValue().getServers().size()); } } + }