| /* |
| * 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.handler.component; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Random; |
| import java.util.stream.Stream; |
| |
| import org.apache.solr.BaseDistributedSearchTestCase; |
| import org.apache.solr.client.solrj.ResponseParser; |
| import org.apache.solr.client.solrj.SolrClient; |
| import org.apache.solr.client.solrj.SolrServerException; |
| import org.apache.solr.client.solrj.impl.BinaryResponseParser; |
| import org.apache.solr.client.solrj.impl.XMLResponseParser; |
| import org.apache.solr.client.solrj.request.QueryRequest; |
| import org.apache.solr.client.solrj.response.DelegationTokenResponse; |
| import org.apache.solr.client.solrj.response.QueryResponse; |
| import org.apache.solr.common.params.ModifiableSolrParams; |
| import org.apache.solr.common.params.SolrParams; |
| import org.apache.solr.common.util.NamedList; |
| import org.junit.Test; |
| |
| /** |
| * Test for TermsComponent distributed querying |
| * |
| * |
| * @since solr 1.5 |
| */ |
| public class DistributedTermsComponentTest extends BaseDistributedSearchTestCase { |
| |
| @Test |
| public void test() throws Exception { |
| Random random = random(); |
| del("*:*"); |
| |
| index(id, random.nextInt(), "b_t", "snake a,b spider shark snail slug seal", "foo_i_p", "1"); |
| query("qt", "/terms", "terms.fl", "foo_i_p"); |
| del("*:*"); |
| |
| // verify point field on empty index |
| query("qt", "/terms", "terms.fl", "foo_i_p"); |
| |
| index(id, random.nextInt(), "b_t", "snake a,b spider shark snail slug seal", "foo_i", "1"); |
| index(id, random.nextInt(), "b_t", "snake spider shark snail slug", "foo_i", "2", "foo_date_p", "2015-01-03T14:30:00Z"); |
| index(id, random.nextInt(), "b_t", "snake spider shark snail", "foo_i", "3"); |
| index(id, random.nextInt(), "b_t", "snake spider shark", "foo_i", "2", "foo_date_p", "2014-03-15T12:00:00Z"); |
| index(id, random.nextInt(), "b_t", "snake spider", "c_t", "snake spider", "foo_date_p", "2014-03-15T12:00:00Z"); |
| index(id, random.nextInt(), "b_t", "snake", "c_t", "snake", "foo_date_p", "2014-03-15T12:00:00Z"); |
| index(id, random.nextInt(), "b_t", "ant zebra", "c_t", "ant zebra", "foo_date_p", "2015-01-03T14:30:00Z"); |
| index(id, random.nextInt(), "b_t", "zebra", "c_t", "zebra", "foo_date_p", "2015-01-03T14:30:00Z"); |
| commit(); |
| |
| handle.clear(); |
| handle.put("terms", UNORDERED); |
| |
| query("qt", "/terms", "terms.fl", "b_t"); |
| query("qt", "/terms", "terms.limit", 5, "terms.fl", "b_t", "terms.lower", "s"); |
| query("qt", "/terms", "terms.limit", 5, "terms.fl", "b_t", "terms.prefix", "sn", "terms.lower", "sn"); |
| query("qt", "/terms", "terms.limit", 5, "terms.fl", "b_t", "terms.prefix", "s", "terms.lower", "s", "terms.upper", "sn"); |
| // terms.sort |
| query("qt", "/terms", "terms.limit", 5, "terms.fl", "b_t", "terms.prefix", "s", "terms.lower", "s", "terms.sort", "index"); |
| query("qt", "/terms", "terms.limit", 5, "terms.fl", "b_t", "terms.prefix", "s", "terms.lower", "s", "terms.upper", "sn", "terms.sort", "index"); |
| query("qt", "/terms", "terms.fl", "b_t", "terms.sort", "index"); |
| // terms.list |
| query("qt", "/terms", "terms.fl", "b_t", "terms.list", "snake,zebra,ant,bad"); |
| query("qt", "/terms", "terms.fl", "foo_i", "terms.list", "2,3,1"); |
| query("qt", "/terms", "terms.fl", "foo_i", "terms.stats", "true","terms.list", "2,3,1"); |
| query("qt", "/terms", "terms.fl", "b_t", "terms.list", "snake,zebra", "terms.ttf", "true"); |
| query("qt", "/terms", "terms.fl", "b_t", "terms.fl", "c_t", "terms.list", "snake,ant,zebra", "terms.ttf", "true"); |
| |
| // for date point field |
| query("qt", "/terms", "terms.fl", "foo_date_p"); |
| // terms.ttf=true doesn't work for point fields |
| //query("qt", "/terms", "terms.fl", "foo_date_p", "terms.ttf", "true"); |
| } |
| |
| protected QueryResponse query(Object... q) throws Exception { |
| if (Stream.of(q).noneMatch(s->s.equals("terms.list"))) { |
| // SOLR-9243 doesn't support max/min count |
| for (int i = 0; i < q.length; i+=2) { |
| if (q[i].equals("terms.sort") && q[i+1].equals("index") || rarely()) { |
| List<Object> params = new ArrayList<Object>(Arrays.asList(q)); |
| if (usually()) { |
| params.add("terms.mincount"); |
| params.add(random().nextInt(4)-1); |
| } |
| if (usually()) { |
| params.add("terms.maxcount"); |
| params.add(random().nextInt(4)-1); |
| } |
| q = params.toArray(new Object[params.size()]); |
| break; |
| } |
| } |
| } |
| return super.query(q); |
| } |
| |
| @Override |
| protected QueryResponse query(boolean setDistribParams, SolrParams p) throws Exception { |
| QueryResponse queryResponse = super.query(setDistribParams, p); |
| |
| final ModifiableSolrParams params = new ModifiableSolrParams(p); |
| // TODO: look into why passing true causes fails |
| params.set("distrib", "false"); |
| |
| for (ResponseParser responseParser : getResponseParsers()) { |
| final NamedList<Object> controlRsp = queryClient(controlClient, params, responseParser); |
| params.remove("distrib"); |
| if (setDistribParams) { |
| setDistributedParams(params); |
| } |
| |
| // query a random server |
| int which = r.nextInt(clients.size()); |
| SolrClient client = clients.get(which); |
| NamedList<Object> rsp = queryClient(client, params, responseParser); |
| |
| // flags needs to be called here since only terms response is passed to compare |
| // other way is to pass whole response to compare |
| assertNull(compare(rsp.findRecursive("terms"), |
| controlRsp.findRecursive("terms"), flags(handle, "terms"), handle)); |
| } |
| return queryResponse; |
| } |
| |
| /** |
| * Returns a {@link NamedList} containing server |
| * response deserialization is based on the {@code responseParser} |
| */ |
| private NamedList<Object> queryClient(SolrClient solrClient, final ModifiableSolrParams params, |
| ResponseParser responseParser) throws SolrServerException, IOException { |
| QueryRequest queryRequest = new QueryRequest(params); |
| queryRequest.setResponseParser(responseParser); |
| return solrClient.request(queryRequest); |
| } |
| |
| private ResponseParser[] getResponseParsers() { |
| // can't use junit parameters as this would also require RunWith |
| return new ResponseParser[]{ |
| new BinaryResponseParser(), new DelegationTokenResponse.JsonMapResponseParser(), |
| new XMLResponseParser() |
| }; |
| } |
| } |