SOLR-5550: shards.info is not returned by a short circuited distributed query

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1578078 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shalin Shekhar Mangar 2014-03-16 14:11:07 +00:00
parent f44831feb9
commit e790ae64c0
7 changed files with 114 additions and 28 deletions

View File

@ -181,6 +181,9 @@ Bug Fixes
* SOLR-5866: UpdateShardHandler needs to use the system default scheme registry to
properly handle https via javax.net.ssl.* properties. (Steve Davids via shalin)
* SOLR-5550: shards.info is not returned by a short circuited distributed query.
(Timothy Potter, shalin)
Optimizations
----------------------
* SOLR-1880: Distributed Search skips GET_FIELDS stage if EXECUTE_QUERY

View File

@ -340,6 +340,7 @@ public class HttpShardHandler extends ShardHandler {
if (shortCircuit) {
rb.isDistrib = false;
rb.shortCircuitedURL = ZkCoreNodeProps.getCoreUrl(zkController.getBaseUrl(), coreDescriptor.getName());
return;
}
// We shouldn't need to do anything to handle "shard.rows" since it was previously meant to be an optimization?

View File

@ -129,7 +129,7 @@ public class ResponseBuilder
public int shards_start = -1;
public List<ShardRequest> outgoing; // requests to be sent
public List<ShardRequest> finished; // requests that have received responses from all shards
public String shortCircuitedURL;
public int getShardNum(String shard) {
for (int i = 0; i < shards.length; i++) {

View File

@ -17,16 +17,21 @@
package org.apache.solr.handler.component;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
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.util.ContentStream;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.CloseHook;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrCore;
@ -231,8 +236,7 @@ public class SearchHandler extends RequestHandlerBase implements SolrCoreAware ,
if (rb.isDebugTimings()) {
rb.addDebugInfo("timing", timer.asNamedList() );
}
}
}
} else {
// a distributed request
@ -332,6 +336,37 @@ public class SearchHandler extends RequestHandlerBase implements SolrCoreAware ,
// we are done when the next stage is MAX_VALUE
} while (nextStage != Integer.MAX_VALUE);
}
// SOLR-5550: still provide shards.info if requested even for a short circuited distrib request
if(!rb.isDistrib && req.getParams().getBool(ShardParams.SHARDS_INFO, false) && rb.shortCircuitedURL != null) {
NamedList<Object> shardInfo = new SimpleOrderedMap<Object>();
SimpleOrderedMap<Object> nl = new SimpleOrderedMap<Object>();
if (rsp.getException() != null) {
Throwable cause = rsp.getException();
if (cause instanceof SolrServerException) {
cause = ((SolrServerException)cause).getRootCause();
} else {
if (cause.getCause() != null) {
cause = cause.getCause();
}
}
nl.add("error", cause.toString() );
StringWriter trace = new StringWriter();
cause.printStackTrace(new PrintWriter(trace));
nl.add("trace", trace.toString() );
}
else {
nl.add("numFound", rb.getResults().docList.matches());
nl.add("maxScore", rb.getResults().docList.maxScore());
}
nl.add("shardAddress", rb.shortCircuitedURL);
nl.add("time", rsp.getEndTime()-req.getStartTime()); // elapsed time of this request so far
int pos = rb.shortCircuitedURL.indexOf("://");
String shardInfoName = pos != -1 ? rb.shortCircuitedURL.substring(pos+3) : rb.shortCircuitedURL;
shardInfo.add(shardInfoName, nl);
rsp.getValues().add(ShardParams.SHARDS_INFO,shardInfo);
}
}
//////////////////////// SolrInfoMBeans methods //////////////////////

View File

@ -339,31 +339,8 @@ public class ShardRoutingTest extends AbstractFullDistribZkTestBase {
// todo - target diff servers and use cloud clients as well as non-cloud clients
}
// TODO: refactor some of this stuff up into a base class for use by other tests
void doQuery(String expectedDocs, String... queryParams) throws Exception {
Set<String> expectedIds = new HashSet<>( StrUtils.splitSmart(expectedDocs, ",", true) );
QueryResponse rsp = cloudClient.query(params(queryParams));
Set<String> obtainedIds = new HashSet<>();
for (SolrDocument doc : rsp.getResults()) {
obtainedIds.add((String) doc.get("id"));
}
assertEquals(expectedIds, obtainedIds);
}
void doRTG(String ids) throws Exception {
cloudClient.query(params("qt","/get", "ids",ids));
Set<String> expectedIds = new HashSet<>( StrUtils.splitSmart(ids, ",", true) );
QueryResponse rsp = cloudClient.query(params("qt","/get", "ids",ids));
Set<String> obtainedIds = new HashSet<>();
for (SolrDocument doc : rsp.getResults()) {
obtainedIds.add((String) doc.get("id"));
}
assertEquals(expectedIds, obtainedIds);
doQuery(ids, "qt", "/get", "ids", ids);
}
// TODO: refactor some of this stuff into the SolrJ client... it should be easier to use

View File

@ -0,0 +1,58 @@
package org.apache.solr.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 org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.util.NamedList;
public class TestShortCircuitedRequests extends AbstractFullDistribZkTestBase {
public TestShortCircuitedRequests() {
schemaString = "schema15.xml"; // we need a string id
super.sliceCount = 4;
super.shardCount = 4;
super.fixShardCount = true; // we only want to test with exactly 4 slices.
}
@Override
public void doTest() throws Exception {
waitForRecoveriesToFinish(false);
assertEquals(4, cloudClient.getZkStateReader().getClusterState().getCollection(DEFAULT_COLLECTION).getSlices().size());
index("id", "a!doc1"); // shard3
index("id", "b!doc1"); // shard1
index("id", "c!doc1"); // shard2
index("id", "e!doc1"); // shard4
commit();
doQuery("a!doc1", "q", "*:*", ShardParams._ROUTE_, "a!"); // can go to any random node
// query shard3 directly with _route_=a! so that we trigger the short circuited request path
Replica shard3 = cloudClient.getZkStateReader().getClusterState().getLeader(DEFAULT_COLLECTION, "shard3");
String nodeName = shard3.getNodeName();
SolrServer shard3Client = getClient(nodeName);
QueryResponse response = shard3Client.query(new SolrQuery("*:*").add(ShardParams._ROUTE_, "a!").add(ShardParams.SHARDS_INFO, "true"));
assertEquals("Could not find doc", 1, response.getResults().getNumFound());
NamedList<?> sinfo = (NamedList<?>) response.getResponse().get(ShardParams.SHARDS_INFO);
assertNotNull("missing shard info for short circuited request", sinfo);
}
}

View File

@ -1516,7 +1516,19 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
Thread.sleep(2000);
} while (retry);
}
void doQuery(String expectedDocs, String... queryParams) throws Exception {
Set<String> expectedIds = new HashSet<>( StrUtils.splitSmart(expectedDocs, ",", true) );
QueryResponse rsp = cloudClient.query(params(queryParams));
Set<String> obtainedIds = new HashSet<>();
for (SolrDocument doc : rsp.getResults()) {
obtainedIds.add((String) doc.get("id"));
}
assertEquals(expectedIds, obtainedIds);
}
@Override
@After
public void tearDown() throws Exception {