SOLR-10406: v2 API error messages list the URL request path as /solr/____v2/... when the original path was /v2/...

This commit is contained in:
Cao Manh Dat 2017-06-20 12:46:33 +07:00
parent 294026ffa8
commit b1b566f57b
5 changed files with 68 additions and 13 deletions

View File

@ -149,6 +149,8 @@ New Features
* SOLR-9989: Add support for PointFields in FacetModule (JSON Facets) (Cao Manh Dat) * SOLR-9989: Add support for PointFields in FacetModule (JSON Facets) (Cao Manh Dat)
* SOLR-10406: v2 API error messages list the URL request path as /solr/____v2/... when the original path was /v2/... (Cao Manh Dat, noble)
Bug Fixes Bug Fixes
---------------------- ----------------------
* SOLR-9262: Connection and read timeouts are being ignored by UpdateShardHandler after SOLR-4509. * SOLR-9262: Connection and read timeouts are being ignored by UpdateShardHandler after SOLR-4509.

View File

@ -56,7 +56,6 @@ import org.slf4j.LoggerFactory;
import static org.apache.solr.common.params.CommonParams.JSON; import static org.apache.solr.common.params.CommonParams.JSON;
import static org.apache.solr.common.params.CommonParams.WT; import static org.apache.solr.common.params.CommonParams.WT;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.ADMIN; import static org.apache.solr.servlet.SolrDispatchFilter.Action.ADMIN;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.PASSTHROUGH;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.PROCESS; import static org.apache.solr.servlet.SolrDispatchFilter.Action.PROCESS;
import static org.apache.solr.common.util.PathTrie.getPathSegments; import static org.apache.solr.common.util.PathTrie.getPathSegments;
@ -76,7 +75,7 @@ public class V2HttpCall extends HttpSolrCall {
protected void init() throws Exception { protected void init() throws Exception {
String path = this.path; String path = this.path;
String fullPath = path = path.substring(7);//strip off '/____v2' final String fullPath = path = path.substring(7);//strip off '/____v2'
try { try {
pieces = getPathSegments(path); pieces = getPathSegments(path);
if (pieces.size() == 0 || (pieces.size() == 1 && path.endsWith(CommonParams.INTROSPECT))) { if (pieces.size() == 0 || (pieces.size() == 1 && path.endsWith(CommonParams.INTROSPECT))) {
@ -159,7 +158,7 @@ public class V2HttpCall extends HttpSolrCall {
log.error("Error in init()", rte); log.error("Error in init()", rte);
throw rte; throw rte;
} finally { } finally {
if (api == null) action = PASSTHROUGH; if (api == null) action = PROCESS;
if (solrReq != null) solrReq.getContext().put(CommonParams.PATH, path); if (solrReq != null) solrReq.getContext().put(CommonParams.PATH, path);
} }
} }
@ -309,16 +308,28 @@ public class V2HttpCall extends HttpSolrCall {
@Override @Override
protected void handleAdmin(SolrQueryResponse solrResp) { protected void handleAdmin(SolrQueryResponse solrResp) {
api.call(this.solrReq, solrResp); try {
api.call(this.solrReq, solrResp);
} catch (Exception e) {
solrResp.setException(e);
}
} }
@Override @Override
protected void execute(SolrQueryResponse rsp) { protected void execute(SolrQueryResponse rsp) {
try { SolrCore.preDecorateResponse(solrReq, rsp);
api.call(solrReq, rsp); if (api == null) {
} catch (RuntimeException e) { rsp.setException(new SolrException(SolrException.ErrorCode.NOT_FOUND,
throw e; "Cannot find correspond api for the path : " + solrReq.getContext().get(CommonParams.PATH)));
} else {
try {
api.call(solrReq, rsp);
} catch (Exception e) {
rsp.setException(e);
}
} }
SolrCore.postDecorateResponse(handler, solrReq, rsp);
} }
@Override @Override

View File

@ -687,7 +687,7 @@ public class HttpSolrCall {
solrReq = new SolrQueryRequestBase(core, solrParams) { solrReq = new SolrQueryRequestBase(core, solrParams) {
}; };
} }
QueryResponseWriter writer = core.getQueryResponseWriter(solrReq); QueryResponseWriter writer = getResponseWriter();
writeResponse(solrResp, writer, Method.GET); writeResponse(solrResp, writer, Method.GET);
} catch (Exception e) { // This error really does not matter } catch (Exception e) { // This error really does not matter
exp = e; exp = e;

View File

@ -22,11 +22,15 @@ import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.BinaryResponseParser;
import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.V2Request; import org.apache.solr.client.solrj.request.V2Request;
import org.apache.solr.client.solrj.response.DelegationTokenResponse;
import org.apache.solr.client.solrj.response.V2Response; import org.apache.solr.client.solrj.response.V2Response;
import org.apache.solr.cloud.SolrCloudTestCase; import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ModifiableSolrParams;
@ -57,6 +61,40 @@ public class V2ApiIntegrationTest extends SolrCloudTestCase {
assertEquals(0, res.getStatus()); assertEquals(0, res.getStatus());
} }
private void testException(ResponseParser responseParser, int expectedCode, String path, String payload) throws IOException, SolrServerException {
V2Request v2Request = new V2Request.Builder(path)
.withMethod(SolrRequest.METHOD.POST)
.withPayload(payload)
.build();
v2Request.setResponseParser(responseParser);
V2Response response = v2Request.process(cluster.getSolrClient());
assertEquals(getStatus(response), expectedCode);
}
@Test
public void testException() throws Exception {
String notFoundPath = "/c/" + COLL_NAME + "/abccdef";
String incorrectPayload = "{rebalance-leaders: {maxAtOnce: abc, maxWaitSeconds: xyz}}";
testException(new XMLResponseParser(),404,
notFoundPath, incorrectPayload);
testException(new DelegationTokenResponse.JsonMapResponseParser(),404,
notFoundPath, incorrectPayload);
testException(new BinaryResponseParser(),404,
notFoundPath, incorrectPayload);
testException(new XMLResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
testException(new BinaryResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
testException(new DelegationTokenResponse.JsonMapResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
}
private long getStatus(V2Response response) {
Object header = response.getResponse().get("responseHeader");
if (header instanceof NamedList) {
return (int) ((NamedList) header).get("status");
} else {
return (long) ((Map) header).get("status");
}
}
@Test @Test
public void testIntrospect() throws Exception { public void testIntrospect() throws Exception {
ModifiableSolrParams params = new ModifiableSolrParams(); ModifiableSolrParams params = new ModifiableSolrParams();

View File

@ -228,7 +228,11 @@ public class HttpSolrClient extends SolrClient {
throws SolrServerException, IOException { throws SolrServerException, IOException {
HttpRequestBase method = createMethod(request, collection); HttpRequestBase method = createMethod(request, collection);
setBasicAuthHeader(request, method); setBasicAuthHeader(request, method);
return executeMethod(method, processor); return executeMethod(method, processor, isV2ApiRequest(request));
}
private boolean isV2ApiRequest(final SolrRequest request) {
return request instanceof V2Request || request.getPath().contains("/____v2");
} }
private void setBasicAuthHeader(SolrRequest request, HttpRequestBase method) throws UnsupportedEncodingException { private void setBasicAuthHeader(SolrRequest request, HttpRequestBase method) throws UnsupportedEncodingException {
@ -268,7 +272,7 @@ public class HttpSolrClient extends SolrClient {
ExecutorService pool = ExecutorUtil.newMDCAwareFixedThreadPool(1, new SolrjNamedThreadFactory("httpUriRequest")); ExecutorService pool = ExecutorUtil.newMDCAwareFixedThreadPool(1, new SolrjNamedThreadFactory("httpUriRequest"));
try { try {
MDC.put("HttpSolrClient.url", baseUrl); MDC.put("HttpSolrClient.url", baseUrl);
mrr.future = pool.submit(() -> executeMethod(method, processor)); mrr.future = pool.submit(() -> executeMethod(method, processor, isV2ApiRequest(request)));
} finally { } finally {
pool.shutdown(); pool.shutdown();
@ -473,7 +477,7 @@ public class HttpSolrClient extends SolrClient {
} }
protected NamedList<Object> executeMethod(HttpRequestBase method, final ResponseParser processor) throws SolrServerException { protected NamedList<Object> executeMethod(HttpRequestBase method, final ResponseParser processor, final boolean isV2Api) throws SolrServerException {
method.addHeader("User-Agent", AGENT); method.addHeader("User-Agent", AGENT);
org.apache.http.client.config.RequestConfig.Builder requestConfigBuilder = HttpClientUtil.createDefaultRequestConfigBuilder(); org.apache.http.client.config.RequestConfig.Builder requestConfigBuilder = HttpClientUtil.createDefaultRequestConfigBuilder();
@ -571,7 +575,7 @@ public class HttpSolrClient extends SolrClient {
} catch (Exception e) { } catch (Exception e) {
throw new RemoteSolrException(baseUrl, httpStatus, e.getMessage(), e); throw new RemoteSolrException(baseUrl, httpStatus, e.getMessage(), e);
} }
if (httpStatus != HttpStatus.SC_OK) { if (httpStatus != HttpStatus.SC_OK && !isV2Api) {
NamedList<String> metadata = null; NamedList<String> metadata = null;
String reason = null; String reason = null;
try { try {