use of org.apache.solr.common.params.MultiMapSolrParams in project lucene-solr by apache.
the class SolrRequestParserTest method testStreamBody.
@Test
public void testStreamBody() throws Exception {
String body1 = "AMANAPLANPANAMA";
String body2 = "qwertasdfgzxcvb";
String body3 = "1234567890";
SolrCore core = h.getCore();
Map<String, String[]> args = new HashMap<>();
args.put(CommonParams.STREAM_BODY, new String[] { body1 });
// Make sure it got a single stream in and out ok
List<ContentStream> streams = new ArrayList<>();
SolrQueryRequest req = parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
assertEquals(1, streams.size());
assertEquals(body1, IOUtils.toString(streams.get(0).getReader()));
req.close();
// Now add three and make sure they come out ok
streams = new ArrayList<>();
args.put(CommonParams.STREAM_BODY, new String[] { body1, body2, body3 });
req = parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
assertEquals(3, streams.size());
ArrayList<String> input = new ArrayList<>();
ArrayList<String> output = new ArrayList<>();
input.add(body1);
input.add(body2);
input.add(body3);
output.add(IOUtils.toString(streams.get(0).getReader()));
output.add(IOUtils.toString(streams.get(1).getReader()));
output.add(IOUtils.toString(streams.get(2).getReader()));
// sort them so the output is consistent
Collections.sort(input);
Collections.sort(output);
assertEquals(input.toString(), output.toString());
req.close();
// set the contentType and make sure tat gets set
String ctype = "text/xxx";
streams = new ArrayList<>();
args.put(CommonParams.STREAM_CONTENTTYPE, new String[] { ctype });
req = parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams);
for (ContentStream s : streams) {
assertEquals(ctype, s.getContentType());
}
req.close();
}
use of org.apache.solr.common.params.MultiMapSolrParams in project lucene-solr by apache.
the class SolrTestCaseJ4 method addDoc.
public static void addDoc(String doc, String updateRequestProcessorChain) throws Exception {
Map<String, String[]> params = new HashMap<>();
MultiMapSolrParams mmparams = new MultiMapSolrParams(params);
params.put(UpdateParams.UPDATE_CHAIN, new String[] { updateRequestProcessorChain });
SolrQueryRequestBase req = new SolrQueryRequestBase(h.getCore(), (SolrParams) mmparams) {
};
UpdateRequestHandler handler = new UpdateRequestHandler();
handler.init(null);
ArrayList<ContentStream> streams = new ArrayList<>(2);
streams.add(new ContentStreamBase.StringStream(doc));
req.setContentStreams(streams);
handler.handleRequestBody(req, new SolrQueryResponse());
req.close();
}
use of org.apache.solr.common.params.MultiMapSolrParams in project lucene-solr by apache.
the class RequestUtil method processParams.
/**
* Set default-ish params on a SolrQueryRequest as well as do standard macro processing and JSON request parsing.
*
* @param handler The search handler this is for (may be null if you don't want this method touching the content streams)
* @param req The request whose params we are interested in
* @param defaults values to be used if no values are specified in the request params
* @param appends values to be appended to those from the request (or defaults) when dealing with multi-val params, or treated as another layer of defaults for singl-val params.
* @param invariants values which will be used instead of any request, or default values, regardless of context.
*/
public static void processParams(SolrRequestHandler handler, SolrQueryRequest req, SolrParams defaults, SolrParams appends, SolrParams invariants) {
boolean searchHandler = handler instanceof SearchHandler;
SolrParams params = req.getParams();
// Handle JSON stream for search requests
if (searchHandler && req.getContentStreams() != null) {
Map<String, String[]> map = MultiMapSolrParams.asMultiMap(params, false);
if (!(params instanceof MultiMapSolrParams || params instanceof ModifiableSolrParams)) {
// need to set params on request since we weren't able to access the original map
params = new MultiMapSolrParams(map);
req.setParams(params);
}
// params from the query string should come after (and hence override) JSON content streams
String[] jsonFromParams = map.remove(JSON);
for (ContentStream cs : req.getContentStreams()) {
String contentType = cs.getContentType();
if (contentType == null || !contentType.contains("/json")) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Bad contentType for search handler :" + contentType + " request=" + req);
}
try {
String jsonString = IOUtils.toString(cs.getReader());
if (jsonString != null) {
MultiMapSolrParams.addParam(JSON, jsonString, map);
}
} catch (IOException e) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Exception reading content stream for request:" + req, e);
}
}
// append existing "json" params
if (jsonFromParams != null) {
for (String json : jsonFromParams) {
MultiMapSolrParams.addParam(JSON, json, map);
}
}
}
String[] jsonS = params.getParams(JSON);
boolean hasAdditions = defaults != null || invariants != null || appends != null || jsonS != null;
// short circuit processing
if (!hasAdditions && !params.getBool("expandMacros", true)) {
// nothing to do...
return;
}
boolean isShard = params.getBool("isShard", false);
Map<String, String[]> newMap = MultiMapSolrParams.asMultiMap(params, hasAdditions);
// The parameters we extract will be propagated anyway.
if (jsonS != null && !isShard) {
for (String json : jsonS) {
getParamsFromJSON(newMap, json);
}
}
// first populate defaults, etc..
if (defaults != null) {
Map<String, String[]> defaultsMap = MultiMapSolrParams.asMultiMap(defaults);
for (Map.Entry<String, String[]> entry : defaultsMap.entrySet()) {
String key = entry.getKey();
if (!newMap.containsKey(key)) {
newMap.put(key, entry.getValue());
}
}
}
if (appends != null) {
Map<String, String[]> appendsMap = MultiMapSolrParams.asMultiMap(appends);
for (Map.Entry<String, String[]> entry : appendsMap.entrySet()) {
String key = entry.getKey();
String[] arr = newMap.get(key);
if (arr == null) {
newMap.put(key, entry.getValue());
} else {
String[] appendArr = entry.getValue();
String[] newArr = new String[arr.length + appendArr.length];
System.arraycopy(arr, 0, newArr, 0, arr.length);
System.arraycopy(appendArr, 0, newArr, arr.length, appendArr.length);
newMap.put(key, newArr);
}
}
}
if (invariants != null) {
newMap.putAll(MultiMapSolrParams.asMultiMap(invariants));
}
if (!isShard) {
// Don't expand macros in shard requests
String[] doMacrosStr = newMap.get("expandMacros");
boolean doMacros = true;
if (doMacrosStr != null) {
doMacros = "true".equals(doMacrosStr[0]);
}
if (doMacros) {
newMap = MacroExpander.expand(newMap);
}
}
// Set these params as soon as possible so if there is an error processing later, things like
// "wt=json" will take effect from the defaults.
// newMap may still change below, but that should be OK
SolrParams newParams = new MultiMapSolrParams(newMap);
req.setParams(newParams);
// For example json.command started to be used in SOLR-6294, and that caused errors here.
if (!searchHandler)
return;
Map<String, Object> json = null;
// Handle JSON body first, so query params will always overlay on that
jsonS = newMap.get(JSON);
if (jsonS != null) {
if (json == null) {
json = new LinkedHashMap<>();
}
mergeJSON(json, JSON, jsonS, new ObjectUtil.ConflictHandler());
}
for (String key : newMap.keySet()) {
// json.nl, json.wrf are existing query parameters
if (key.startsWith("json.") && !("json.nl".equals(key) || "json.wrf".equals(key))) {
if (json == null) {
json = new LinkedHashMap<>();
}
mergeJSON(json, key, newMap.get(key), new ObjectUtil.ConflictHandler());
}
}
// implement compat for existing components...
if (json != null && !isShard) {
for (Map.Entry<String, Object> entry : json.entrySet()) {
String key = entry.getKey();
String out = null;
boolean arr = false;
if ("query".equals(key)) {
out = "q";
} else if ("filter".equals(key)) {
out = "fq";
arr = true;
} else if ("fields".equals(key)) {
out = "fl";
arr = true;
} else if ("offset".equals(key)) {
out = "start";
} else if ("limit".equals(key)) {
out = "rows";
} else if (SORT.equals(key)) {
out = SORT;
} else if ("params".equals(key) || "facet".equals(key)) {
// handled elsewhere
continue;
} else {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unknown top-level key in JSON request : " + key);
}
Object val = entry.getValue();
if (arr) {
String[] existing = newMap.get(out);
List lst = val instanceof List ? (List) val : null;
int existingSize = existing == null ? 0 : existing.length;
int jsonSize = lst == null ? 1 : lst.size();
String[] newval = new String[existingSize + jsonSize];
for (int i = 0; i < existingSize; i++) {
newval[i] = existing[i];
}
if (lst != null) {
for (int i = 0; i < jsonSize; i++) {
Object v = lst.get(i);
newval[existingSize + i] = v.toString();
}
} else {
newval[newval.length - 1] = val.toString();
}
newMap.put(out, newval);
} else {
newMap.put(out, new String[] { val.toString() });
}
}
}
if (json != null) {
req.setJSON(json);
}
}
use of org.apache.solr.common.params.MultiMapSolrParams in project lucene-solr by apache.
the class SolrRequestParsers method autodetect.
/** Returns the parameter map if a different content type was auto-detected */
private static SolrParams autodetect(HttpServletRequest req, ArrayList<ContentStream> streams, FastInputStream in) throws IOException {
String detectedContentType = null;
boolean shouldClose = true;
try {
// should cause some bytes to be read
in.peek();
byte[] arr = in.getBuffer();
int pos = in.getPositionInBuffer();
int end = in.getEndInBuffer();
for (int i = pos; i < end - 1; i++) {
// we do "end-1" because we check "arr[i+1]" sometimes in the loop body
int ch = arr[i];
boolean isWhitespace = ((WS_MASK >> ch) & 0x01) != 0 && (ch <= ' ' || ch == 0xa0);
if (!isWhitespace) {
// first non-whitespace chars
if (// single line comment
ch == '#' || // single line or multi-line comment
(ch == '/' && (arr[i + 1] == '/' || arr[i + 1] == '*')) || // start of JSON object
(ch == '{' || ch == '[')) {
detectedContentType = "application/json";
}
if (ch == '<') {
detectedContentType = "text/xml";
}
break;
}
}
if (detectedContentType == null) {
shouldClose = false;
return null;
}
Long size = null;
String v = req.getHeader("Content-Length");
if (v != null) {
size = Long.valueOf(v);
}
streams.add(new InputStreamContentStream(in, detectedContentType, size));
final Map<String, String[]> map = new HashMap<>();
// also add possible URL parameters and include into the map (parsed using UTF-8):
final String qs = req.getQueryString();
if (qs != null) {
parseQueryString(qs, map);
}
return new MultiMapSolrParams(map);
} catch (IOException ioe) {
throw new SolrException(ErrorCode.BAD_REQUEST, ioe);
} catch (IllegalStateException ise) {
throw (SolrException) FormDataRequestParser.getParameterIncompatibilityException().initCause(ise);
} finally {
if (shouldClose) {
IOUtils.closeWhileHandlingException(in);
}
}
}
use of org.apache.solr.common.params.MultiMapSolrParams in project lucene-solr by apache.
the class SolrRequestParserTest method testStreamURL.
@Test
public void testStreamURL() throws Exception {
URL url = getClass().getResource("/README");
assertNotNull("Missing file 'README' in test-resources root folder.", url);
byte[] bytes = IOUtils.toByteArray(url);
SolrCore core = h.getCore();
Map<String, String[]> args = new HashMap<>();
args.put(CommonParams.STREAM_URL, new String[] { url.toExternalForm() });
// Make sure it got a single stream in and out ok
List<ContentStream> streams = new ArrayList<>();
try (SolrQueryRequest req = parser.buildRequestFrom(core, new MultiMapSolrParams(args), streams)) {
assertEquals(1, streams.size());
try (InputStream in = streams.get(0).getStream()) {
assertArrayEquals(bytes, IOUtils.toByteArray(in));
}
}
}
Aggregations