aboutsummaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorHenrik <henrik.hoiness@online.no>2018-06-21 09:57:38 +0200
committerHenrik <henrik.hoiness@online.no>2018-06-22 09:21:06 +0200
commitd42507a3cffe99007b61f72d4c53bd43f9298c6e (patch)
tree11b9e178a3fe9dae007d10c35ec5c2a75c4a4c58 /container-search
parent0041440b22ea63f22d4848f62fa690babc2b872e (diff)
Added simple handling of JSON-queries.
Diffstat (limited to 'container-search')
-rw-r--r--container-search/pom.xml5
-rw-r--r--container-search/src/main/java/com/yahoo/search/Query.java32
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java90
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java10
4 files changed, 123 insertions, 14 deletions
diff --git a/container-search/pom.xml b/container-search/pom.xml
index cdfcdb2434a..f04520398af 100644
--- a/container-search/pom.xml
+++ b/container-search/pom.xml
@@ -61,6 +61,11 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>com.yahoo.vespa</groupId>
<artifactId>container-accesslogging</artifactId>
<version>${project.version}</version>
diff --git a/container-search/src/main/java/com/yahoo/search/Query.java b/container-search/src/main/java/com/yahoo/search/Query.java
index ab6976e29d9..2f6b2df1407 100644
--- a/container-search/src/main/java/com/yahoo/search/Query.java
+++ b/container-search/src/main/java/com/yahoo/search/Query.java
@@ -56,6 +56,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
* A search query containing all the information required to produce a Result.
@@ -270,6 +271,7 @@ public class Query extends com.yahoo.processing.Request implements Cloneable {
this("");
}
+
/**
* Construct a query from a string formatted in the http style, e.g <code>?query=test&amp;offset=10&amp;hits=13</code>
* The query must be uri encoded.
@@ -278,6 +280,16 @@ public class Query extends com.yahoo.processing.Request implements Cloneable {
this(query, null);
}
+
+ /**
+ * Creates a query from a request
+ *
+ * @param request the HTTP request from which this is created
+ */
+ public Query(HttpRequest request) {
+ this(request, null);
+ }
+
/**
* Construct a query from a string formatted in the http style, e.g <code>?query=test&amp;offset=10&amp;hits=13</code>
* The query must be uri encoded.
@@ -299,15 +311,27 @@ public class Query extends com.yahoo.processing.Request implements Cloneable {
}
/**
- * Creates a query from a request
+ * Creates a query from a request containing a JSON-query.
*
- * @param request the HTTP request from which this is created
+ * @param request the HTTP request from which this is created.
+ * @param requestMap the property map of the query.
+ * @param queryProfile the query profile to use for this query, or null if none.
*/
- public Query(HttpRequest request) {
- this(request, null);
+ public Query(HttpRequest request, Map<String, String> requestMap, CompiledQueryProfile queryProfile) {
+
+ super(new QueryPropertyAliases(propertyAliases));
+ this.httpRequest = request;
+ init(requestMap, queryProfile);
}
+
+
private void init(Map<String, String> requestMap, CompiledQueryProfile queryProfile) {
+ String content = requestMap.entrySet()
+ .stream()
+ .map(e -> e.getKey() + "=\"" + e.getValue() + "\"")
+ .collect(Collectors.joining(", "));
+ System.out.println(content);
startTime = System.currentTimeMillis();
if (queryProfile != null) {
// Move all request parameters to the query profile just to validate that the parameter settings are legal
diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
index e9e4e34727c..3b2ee2fd197 100644
--- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
+++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
@@ -55,15 +55,19 @@ import com.yahoo.statistics.Statistics;
import com.yahoo.statistics.Value;
import com.yahoo.vespa.configdefinition.SpecialtokensConfig;
import edu.umd.cs.findbugs.annotations.NonNull;
+import org.apache.commons.io.IOUtils;
+import org.json.*;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Optional;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
* Handles search request.
@@ -233,6 +237,9 @@ public class SearchHandler extends LoggingRequestHandler {
} catch (RuntimeException e) { // Make sure we generate a valid response even on unexpected errors
log.log(Level.WARNING, "Failed handling " + request, e);
return internalServerErrorResponse(request, e);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ return invalidJsonResponse(request, e);
}
} finally {
requestsInFlight.decrementAndGet();
@@ -275,14 +282,44 @@ public class SearchHandler extends LoggingRequestHandler {
return errorResponse(request, ErrorMessage.createInternalServerError(Exceptions.toMessageString(e)));
}
- private HttpSearchResponse handleBody(HttpRequest request) {
+ private HttpResponse invalidJsonResponse(HttpRequest request, JSONException e) {
+ return errorResponse(request, ErrorMessage.createBadRequest(Exceptions.toMessageString(e)));
+ }
+
+ private HttpSearchResponse handleBody(HttpRequest request) throws JSONException {
// Find query profile
String queryProfileName = request.getProperty("queryProfile");
CompiledQueryProfile queryProfile = queryProfileRegistry.findQueryProfile(queryProfileName);
boolean benchmarkOutput = VespaHeaders.benchmarkOutput(request);
+
// Create query
- Query query = new Query(request, queryProfile);
+ Query query;
+
+ //SLETT LINJE UNDER
+ Map<String, String> a = null;
+
+ if (checkJSON(request.getData()) && request.getMethod() == com.yahoo.jdisc.http.HttpRequest.Method.POST) {
+ JSONObject json = null;
+
+ try {
+
+ String jsonString = "{" + IOUtils.toString(request.getData(), StandardCharsets.UTF_8);
+ System.out.println("Received JSON: " + jsonString);
+ json = new JSONObject(jsonString);
+ } catch (IOException e) { e.printStackTrace();
+ }
+
+
+ Map<String, String> requestMap = createRequestMapping(json);
+ query = new Query(request, requestMap, queryProfile);
+
+
+ } else {
+ query = new Query(request, queryProfile);
+
+ }
+
boolean benchmarkCoverage = VespaHeaders.benchmarkCoverage(benchmarkOutput, request.getJDiscRequest().headers());
@@ -552,4 +589,47 @@ public class SearchHandler extends LoggingRequestHandler {
return searchChainRegistry;
}
+ private boolean checkJSON(InputStream inputStream) {
+ try {
+ byte[] bytes = new byte[1];
+
+ inputStream.read(bytes);
+ if (bytes[0] == 0x7B) {
+ // InputStream is believed to be JSON
+ return true;
+ }
+ } catch (IOException e) {
+ // Something went wrong
+ }
+
+ return false;
+
+ }
+
+ private Map<String, String> createRequestMapping(JSONObject json) {
+ // Create mapping
+ Map<String, String> requestMap = new HashMap<String, String>();
+ Iterator<?> keys = json.keys();
+
+ while( keys.hasNext() ){
+ String key = (String)keys.next();
+ String value = null;
+ try {
+ value = json.getString(key);
+ requestMap.put(key, value);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return requestMap;
+
+
+
+ }
+
+
+
}
+
+
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java
index ce40bd1f06b..30a5d637767 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java
@@ -23,6 +23,7 @@ import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.result.Hit;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase;
+import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@@ -30,12 +31,9 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
import java.net.URI;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.Executors;
import static org.hamcrest.CoreMatchers.containsString;
@@ -187,6 +185,8 @@ public class SearchHandlerTestCase {
}
}
+
+
// Query handling takes a different code path when a query profile is active, so we test both paths.
@Test
public void testInvalidQueryParamWithQueryProfile() throws Exception {