/*
* 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.search.json;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.JSONTestUtil;
import org.apache.solr.SolrTestCaseHS;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@LuceneTestCase.SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Lucene45","Appending"})
public class TestJsonRequest extends SolrTestCaseHS {
private static SolrInstances servers; // for distributed testing
@BeforeClass
public static void beforeTests() throws Exception {
JSONTestUtil.failRepeatedKeys = true;
initCore("solrconfig-tlog.xml","schema_latest.xml");
}
public static void initServers() throws Exception {
if (servers == null) {
servers = new SolrInstances(3, "solrconfig-tlog.xml","schema_latest.xml");
}
}
@AfterClass
public static void afterTests() throws Exception {
JSONTestUtil.failRepeatedKeys = false;
if (servers != null) {
servers.stop();
servers = null;
}
}
@Test
public void testLocalJsonRequest() throws Exception {
doJsonRequest(Client.localClient);
}
@Test
public void testDistribJsonRequest() throws Exception {
initServers();
initServers();
Client client = servers.getClient( random().nextInt() );
client.queryDefaults().set( "shards", servers.getShards() );
doJsonRequest(client);
}
public static void doJsonRequest(Client client) throws Exception {
client.deleteByQuery("*:*", null);
client.add(sdoc("id", "1", "cat_s", "A", "where_s", "NY"), null);
client.add(sdoc("id", "2", "cat_s", "B", "where_s", "NJ"), null);
client.add(sdoc("id", "3"), null);
client.commit();
client.add(sdoc("id", "4", "cat_s", "A", "where_s", "NJ"), null);
client.add(sdoc("id", "5", "cat_s", "B", "where_s", "NJ"), null);
client.commit();
client.add(sdoc("id", "6", "cat_s", "B", "where_s", "NY"), null);
client.commit();
// test json param
client.testJQ( params("json","{query:'cat_s:A'}")
, "response/numFound==2"
);
// test multiple json params
client.testJQ( params("json","{query:'cat_s:A'}", "json","{filter:'where_s:NY'}")
, "response/numFound==1"
);
// test multiple json params with one being zero length
client.testJQ( params("json","{query:'cat_s:A'}", "json","{filter:'where_s:NY'}", "json","")
, "response/numFound==1"
);
// test multiple json params with one being a comment
client.testJQ( params("json","{query:'cat_s:A'}", "json","{filter:'where_s:NY'}", "json","/* */")
, "response/numFound==1"
);
// test merging multi-valued params into list
client.testJQ( params("json","{query:'*:*'}", "json","{filter:'where_s:NY'}", "json","{filter:'cat_s:A'}")
, "response/numFound==1"
);
// test merging multi-valued params into list, second value is already list
client.testJQ( params("json","{query:'*:*'}", "json","{filter:'where_s:NY'}", "json","{filter:['cat_s:A']}")
, "response/numFound==1"
);
// test merging multi-valued params into list, first value is already list
client.testJQ( params("json","{query:'*:*'}", "json","{filter:['where_s:NY']}", "json","{filter:'cat_s:A'}")
, "response/numFound==1"
);
// test merging multi-valued params into list, both values are already list
client.testJQ( params("json","{query:'*:*'}", "json","{filter:['where_s:NY']}", "json","{filter:['cat_s:A']}")
, "response/numFound==1"
);
// test inserting and merging with paths
client.testJQ( params("json.query","'*:*'", "json.filter","'where_s:NY'", "json.filter","'cat_s:A'")
, "response/numFound==1"
);
// test inserting and merging with paths with an empty string and a comment
client.testJQ( params("json.query","'*:*'", "json.filter","'where_s:NY'", "json.filter","'cat_s:A'", "json.filter","", "json.filter","/* */")
, "response/numFound==1"
);
// test overwriting of non-multivalued params
client.testJQ( params("json.query","'foo_s:NONE'", "json.filter","'where_s:NY'", "json.filter","'cat_s:A'", "json.query","'*:*'")
, "response/numFound==1"
);
// normal parameter specified in the params block, including numeric params cast back to string
client.testJQ( params("json","{params:{q:'*:*', fq:['cat_s:A','where_s:NY'], start:0, rows:5, fl:id}}")
, "response/docs==[{id:'1'}]"
);
client.testJQ( params("json","{params:{q:'*:*', fq:['cat_s:A','where_s:(NY OR NJ)'], start:0, rows:1, fl:id, sort:'where_s asc'}}")
, "response/numFound==2"
, "response/docs==[{id:'4'}]"
);
client.testJQ( params("json","{params:{q:'*:*', fq:['cat_s:A','where_s:(NY OR NJ)'], start:0, rows:1, fl:[id,'x:5.5'], sort:'where_s asc'}}")
, "response/numFound==2"
, "response/docs==[{id:'4', x:5.5}]"
);
// test merge params
client.testJQ( params("json","{params:{q:'*:*'}}", "json","{params:{fq:['cat_s:A','where_s:(NY OR NJ)'], start:0, rows:1, fl:[id,'x:5.5']}}", "json","{params:{sort:'where_s asc'}}")
, "response/numFound==2"
, "response/docs==[{id:'4', x:5.5}]"
);
// test offset/limit/sort/fields
client.testJQ( params("json.query","'*:*'", "json.offset","1", "json.limit","2", "json.sort","'id desc'", "json.fields","'id'")
, "response/docs==[{id:'5'},{id:'4'}]"
);
// test offset/limit/sort/fields, multi-valued json.fields
client.testJQ( params("json.query","'*:*'", "json.offset","1", "json.limit","2", "json.sort","'id desc'", "json.fields","'id'", "json.fields","'x:5.5'")
, "response/docs==[{id:'5', x:5.5},{id:'4', x:5.5}]"
);
// test offset/limit/sort/fields, overwriting non-multivalued params
client.testJQ( params("json.query","'*:*'", "json.offset","17", "json.offset","1", "json.limit","42", "json.limit","2", "json.sort","'id asc'", "json.sort","'id desc'", "json.fields","'id'", "json.fields","'x:5.5'")
, "response/docs==[{id:'5', x:5.5},{id:'4', x:5.5}]"
);
// test templating before parsing JSON
client.testJQ( params("json","${OPENBRACE} query:'cat_s:A' ${CLOSEBRACE}", "json","${OPENBRACE} filter:'where_s:NY'${CLOSEBRACE}", "OPENBRACE","{", "CLOSEBRACE","}")
, "response/numFound==1"
);
// test templating with params defined in the JSON itself! Do we want to keep this functionality?
client.testJQ( params("json","{params:{V1:A,V2:NY}, query:'cat_s:${V1}'}", "json","{filter:'where_s:${V2}'}")
, "response/numFound==1"
);
//
// with body
//
client.testJQ(params("stream.body", "{query:'cat_s:A'}", "stream.contentType", "application/json")
, "response/numFound==2"
);
// test body in conjunction with query params
client.testJQ(params("stream.body", "{query:'cat_s:A'}", "stream.contentType", "application/json", "json.filter", "'where_s:NY'")
, "response/numFound==1"
);
// test that json body in params come "after" (will overwrite)
client.testJQ(params("stream.body", "{query:'*:*', filter:'where_s:NY'}", "stream.contentType", "application/json", "json","{query:'cat_s:A'}")
, "response/numFound==1"
);
// test that json.x params come after body
client.testJQ(params("stream.body", "{query:'*:*', filter:'where_s:NY'}", "stream.contentType", "application/json", "json.query","'cat_s:A'")
, "response/numFound==1"
);
// test facet with json body
client.testJQ(params("stream.body", "{query:'*:*', facet:{x:'unique(where_s)'}}", "stream.contentType", "application/json")
, "facets=={count:6,x:2}"
);
// test facet with json body, insert additional facets via query parameter
client.testJQ(params("stream.body", "{query:'*:*', facet:{x:'unique(where_s)'}}", "stream.contentType", "application/json", "json.facet.y","{terms:{field:where_s}}", "json.facet.z","'unique(where_s)'")
, "facets=={count:6,x:2, y:{buckets:[{val:NJ,count:3},{val:NY,count:2}]}, z:2}"
);
// test debug
client.testJQ( params("json","{query:'cat_s:A'}", "json.filter","'where_s:NY'", "debug","true")
, "debug/json=={query:'cat_s:A', filter:'where_s:NY'}"
);
try {
// test failure on unknown parameter
client.testJQ(params("json", "{query:'cat_s:A', foobar_ignore_exception:5}")
, "response/numFound==2"
);
fail();
} catch (Exception e) {
assertTrue(e.getMessage().contains("foobar"));
}
}
}