summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundle-plugin-test/integration-test/src/test/java/com/yahoo/container/plugin/BundleTest.java1
-rw-r--r--bundle-plugin-test/test-bundles/main/pom.xml5
-rw-r--r--bundle-plugin-test/test-bundles/main/src/main/java/com/yahoo/test/SimpleSearcher.java8
-rw-r--r--cloud-tenant-base-dependencies-enforcer/pom.xml2
-rw-r--r--container-core/pom.xml1
-rw-r--r--container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java23
-rw-r--r--container-core/src/main/java/com/yahoo/container/jdisc/state/CoredumpGatherer.java25
-rw-r--r--container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java31
-rw-r--r--container-core/src/main/java/com/yahoo/container/jdisc/state/JSONObjectWithLegibleException.java87
-rw-r--r--container-core/src/main/java/com/yahoo/container/jdisc/state/MetricGatherer.java6
-rw-r--r--container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java61
-rw-r--r--container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java98
-rw-r--r--container-core/src/main/java/org/json/package-info.java2
-rw-r--r--container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java49
-rw-r--r--container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java27
-rw-r--r--container-core/src/test/java/com/yahoo/container/jdisc/state/CoredumpGathererTest.java13
-rw-r--r--container-core/src/test/java/com/yahoo/container/jdisc/state/HostLifeGathererTest.java21
-rw-r--r--container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java63
-rw-r--r--container-dependency-versions/pom.xml2
-rw-r--r--container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java81
-rw-r--r--container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java198
-rw-r--r--container-search-gui/src/main/java/com/yahoo/search/query/gui/GUIHandler.java82
-rw-r--r--container-search/pom.xml5
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java10
-rw-r--r--container-search/src/test/java/com/yahoo/prelude/fastsearch/SlimeSummaryTestCase.java23
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java189
-rw-r--r--container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java42
-rw-r--r--container-search/src/test/java/com/yahoo/select/SelectTestCase.java196
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ProtonMetrics.java23
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java21
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java9
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/proton-metrics.json45
-rw-r--r--metrics-proxy/pom.xml5
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/node/NodeMetricGatherer.java36
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java16
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java49
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java25
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java18
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java17
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java19
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java79
-rw-r--r--metrics-proxy/src/test/java/ai/vespa/metricsproxy/service/ContainerServiceTest.java3
43 files changed, 812 insertions, 908 deletions
diff --git a/bundle-plugin-test/integration-test/src/test/java/com/yahoo/container/plugin/BundleTest.java b/bundle-plugin-test/integration-test/src/test/java/com/yahoo/container/plugin/BundleTest.java
index a46abce1dff..35a95ed3d89 100644
--- a/bundle-plugin-test/integration-test/src/test/java/com/yahoo/container/plugin/BundleTest.java
+++ b/bundle-plugin-test/integration-test/src/test/java/com/yahoo/container/plugin/BundleTest.java
@@ -91,7 +91,6 @@ public class BundleTest {
// From SimpleSearcher
assertThat(importPackage, containsString("com.yahoo.prelude.hitfield"));
- assertThat(importPackage, containsString("org.json"));
// From SimpleSearcher2
assertThat(importPackage, containsString("com.yahoo.processing"));
diff --git a/bundle-plugin-test/test-bundles/main/pom.xml b/bundle-plugin-test/test-bundles/main/pom.xml
index c9c9ea270eb..190e1c9d90f 100644
--- a/bundle-plugin-test/test-bundles/main/pom.xml
+++ b/bundle-plugin-test/test-bundles/main/pom.xml
@@ -16,11 +16,6 @@
<packaging>container-plugin</packaging>
<dependencies>
<dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>com.yahoo.vespa</groupId>
<artifactId>jrt</artifactId>
<version>${project.version}</version>
diff --git a/bundle-plugin-test/test-bundles/main/src/main/java/com/yahoo/test/SimpleSearcher.java b/bundle-plugin-test/test-bundles/main/src/main/java/com/yahoo/test/SimpleSearcher.java
index dddca3f4d59..ae9644aa010 100644
--- a/bundle-plugin-test/test-bundles/main/src/main/java/com/yahoo/test/SimpleSearcher.java
+++ b/bundle-plugin-test/test-bundles/main/src/main/java/com/yahoo/test/SimpleSearcher.java
@@ -8,8 +8,6 @@ import com.yahoo.search.Searcher;
import com.yahoo.search.result.Hit;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.text.BooleanParser;
-import org.json.JSONException;
-import org.json.JSONObject;
/**
* A searcher adding a new hit.
@@ -19,19 +17,13 @@ import org.json.JSONObject;
public class SimpleSearcher extends Searcher {
public Result search(Query query,Execution execution) {
- try {
BooleanParser.parseBoolean("true");
XMLString xmlString = new XMLString("<sampleXmlString/>");
Hit hit = new Hit("Hello world!");
- hit.setField("json", new JSONObject().put("price", 42).toString());
Result result = execution.search(query);
result.hits().add(hit);
return result;
-
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
}
}
diff --git a/cloud-tenant-base-dependencies-enforcer/pom.xml b/cloud-tenant-base-dependencies-enforcer/pom.xml
index a8655a82860..8bb7b75be89 100644
--- a/cloud-tenant-base-dependencies-enforcer/pom.xml
+++ b/cloud-tenant-base-dependencies-enforcer/pom.xml
@@ -34,7 +34,7 @@
<junit5.version>5.7.0</junit5.version>
<junit5.platform.version>1.7.0</junit5.platform.version>
<org.lz4.version>1.7.1</org.lz4.version>
- <org.json.version>20090211</org.json.version>
+ <org.json.version>20090211</org.json.version><!-- TODO Vespa 8: remove as provided dependency -->
<slf4j.version>1.7.5</slf4j.version>
<tensorflow.version>1.12.0</tensorflow.version>
<xml-apis.version>1.4.01</xml-apis.version>
diff --git a/container-core/pom.xml b/container-core/pom.xml
index 7c98b524c73..051b572b28f 100644
--- a/container-core/pom.xml
+++ b/container-core/pom.xml
@@ -42,6 +42,7 @@
<scope>test</scope>
</dependency>
<dependency>
+ <!-- TODO Vespa 8: stop providing org.json:json -->
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
diff --git a/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java b/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java
index 92840cee48f..8c902f88e38 100644
--- a/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java
+++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java
@@ -1,13 +1,14 @@
// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.handler.metrics;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
import com.yahoo.restapi.Path;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import java.net.URI;
import java.util.List;
@@ -26,6 +27,8 @@ import static java.util.logging.Level.WARNING;
*/
public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
protected HttpHandlerBase(Executor executor) {
super(executor);
}
@@ -49,15 +52,14 @@ public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler {
protected JsonResponse resourceListResponse(URI requestUri, List<String> resources) {
try {
return new JsonResponse(OK, resourceList(requestUri, resources));
- } catch (JSONException e) {
+ } catch (JsonProcessingException e) {
log.log(WARNING, "Bad JSON construction in generated resource list for " + requestUri.getPath(), e);
return new ErrorResponse(INTERNAL_SERVER_ERROR,
"An error occurred when generating the list of api resources.");
}
}
- // TODO: Use jackson with a "Resources" class instead of JSONObject
- private static String resourceList(URI requestUri, List<String> resources) throws JSONException {
+ private static String resourceList(URI requestUri, List<String> resources) throws JsonProcessingException {
int port = requestUri.getPort();
String host = requestUri.getHost();
StringBuilder base = new StringBuilder("http://");
@@ -66,13 +68,14 @@ public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler {
base.append(":").append(port);
}
String uriBase = base.toString();
- JSONArray linkList = new JSONArray();
+ ArrayNode linkList = jsonMapper.createArrayNode();
for (String api : resources) {
- JSONObject resource = new JSONObject();
+ ObjectNode resource = jsonMapper.createObjectNode();
resource.put("url", uriBase + api);
- linkList.put(resource);
+ linkList.add(resource);
}
- return new JSONObject().put("resources", linkList).toString(4);
+ return jsonMapper.writerWithDefaultPrettyPrinter()
+ .writeValueAsString(jsonMapper.createObjectNode().set("resources", linkList));
}
}
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/CoredumpGatherer.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/CoredumpGatherer.java
index d105eaa9d98..f1ef7894511 100644
--- a/container-core/src/main/java/com/yahoo/container/jdisc/state/CoredumpGatherer.java
+++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/CoredumpGatherer.java
@@ -1,17 +1,16 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yahoo.vespa.defaults.Defaults;
-import org.json.JSONException;
-import org.json.JSONObject;
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.time.Instant;
-import java.util.Set;
import java.util.stream.Stream;
/**
@@ -19,19 +18,17 @@ import java.util.stream.Stream;
*/
public class CoredumpGatherer {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final Path COREDUMP_PATH = Path.of(Defaults.getDefaults().underVespaHome("var/crash/processing"));
- public static JSONObject gatherCoredumpMetrics(FileWrapper fileWrapper) {
+ public static JsonNode gatherCoredumpMetrics(FileWrapper fileWrapper) {
int coredumps = getNumberOfCoredumps(fileWrapper);
- JSONObject packet = new JSONObject();
-
- try {
- packet.put("status_code", coredumps == 0 ? 0 : 1);
- packet.put("status_msg", coredumps == 0 ? "OK" : String.format("Found %d coredump(s)", coredumps));
- packet.put("timestamp", Instant.now().getEpochSecond());
- packet.put("application", "system-coredumps-processing");
-
- } catch (JSONException e) {}
+ ObjectNode packet = jsonMapper.createObjectNode();
+ packet.put("status_code", coredumps == 0 ? 0 : 1);
+ packet.put("status_msg", coredumps == 0 ? "OK" : String.format("Found %d coredump(s)", coredumps));
+ packet.put("timestamp", Instant.now().getEpochSecond());
+ packet.put("application", "system-coredumps-processing");
return packet;
}
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java
index 730f7bc13cd..28f99096d84 100644
--- a/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java
+++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java
@@ -1,8 +1,9 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.nio.file.Path;
@@ -13,9 +14,11 @@ import java.time.Instant;
*/
public class HostLifeGatherer {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final Path UPTIME_PATH = Path.of("/proc");
- public static JSONObject getHostLifePacket(FileWrapper fileWrapper) {
+ public static JsonNode getHostLifePacket(FileWrapper fileWrapper) {
long upTime;
int statusCode = 0;
String statusMessage = "OK";
@@ -29,19 +32,15 @@ public class HostLifeGatherer {
}
- JSONObject jsonObject = new JSONObject();
- try {
- jsonObject.put("status_code", statusCode);
- jsonObject.put("status_msg", statusMessage);
- jsonObject.put("timestamp", Instant.now().getEpochSecond());
- jsonObject.put("application", "host_life");
- JSONObject metrics = new JSONObject();
- metrics.put("uptime", upTime);
- metrics.put("alive", 1);
- jsonObject.put("metrics", metrics);
-
- } catch (JSONException e) {}
-
+ ObjectNode jsonObject = jsonMapper.createObjectNode();
+ jsonObject.put("status_code", statusCode);
+ jsonObject.put("status_msg", statusMessage);
+ jsonObject.put("timestamp", Instant.now().getEpochSecond());
+ jsonObject.put("application", "host_life");
+ ObjectNode metrics = jsonMapper.createObjectNode();
+ metrics.put("uptime", upTime);
+ metrics.put("alive", 1);
+ jsonObject.set("metrics", metrics);
return jsonObject;
}
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/JSONObjectWithLegibleException.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/JSONObjectWithLegibleException.java
deleted file mode 100644
index d22dd9d6f4b..00000000000
--- a/container-core/src/main/java/com/yahoo/container/jdisc/state/JSONObjectWithLegibleException.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.container.jdisc.state;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * A JSONObject that wraps the checked JSONException in a RuntimeException with a legible error message.
- *
- * @author gjoranv
- */
-class JSONObjectWithLegibleException extends JSONObject {
-
- @Override
- public JSONObject put(String s, boolean b) {
- try {
- return super.put(s, b);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, b, e), e);
- }
- }
-
- @Override
- public JSONObject put(String s, double v) {
- try {
- Double guardedVal = (((Double) v).isNaN() || ((Double) v).isInfinite()) ?
- 0.0 : v;
- return super.put(s, guardedVal);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, v, e), e);
- }
- }
-
- @Override
- public JSONObject put(String s, int i) {
- try {
- return super.put(s, i);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, i, e), e);
- }
- }
-
- @Override
- public JSONObject put(String s, long l) {
- try {
- return super.put(s, l);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, l, e), e);
- }
- }
-
- @Override
- public JSONObject put(String s, Collection collection) {
- try {
- return super.put(s, collection);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, collection, e), e);
- }
- }
-
- @Override
- public JSONObject put(String s, Map map) {
- try {
- return super.put(s, map);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, map, e), e);
- }
- }
-
- @Override
- public JSONObject put(String s, Object o) {
- try {
- return super.put(s, o);
- } catch (JSONException e) {
- throw new RuntimeException(getErrorMessage(s, o, e), e);
- }
- }
-
- private String getErrorMessage(String key, Object value, JSONException e) {
- return "Trying to add invalid JSON object with key '" + key +
- "' and value '" + value + "' - " + e.getMessage();
- }
-
-}
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricGatherer.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricGatherer.java
index 6a06a6362f5..add69403455 100644
--- a/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricGatherer.java
+++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricGatherer.java
@@ -1,7 +1,7 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
import java.util.ArrayList;
import java.util.List;
@@ -13,9 +13,9 @@ import java.util.List;
*/
public class MetricGatherer {
- static List<JSONObject> getAdditionalMetrics() {
+ static List<JsonNode> getAdditionalMetrics() {
FileWrapper fileWrapper = new FileWrapper();
- List<JSONObject> packetList = new ArrayList<>();
+ List<JsonNode> packetList = new ArrayList<>();
packetList.add(CoredumpGatherer.gatherCoredumpMetrics(fileWrapper));
if (System.getProperty("os.name").contains("nux"))
packetList.add(HostLifeGatherer.getHostLifePacket(fileWrapper));
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java
index 3d3f0e4b677..e8d829eafb1 100644
--- a/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java
+++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java
@@ -1,6 +1,11 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
import com.yahoo.collections.Tuple2;
import com.yahoo.component.provider.ComponentRegistry;
@@ -13,9 +18,6 @@ import com.yahoo.jdisc.handler.ResponseDispatch;
import com.yahoo.jdisc.handler.ResponseHandler;
import com.yahoo.jdisc.http.HttpHeaders;
import com.yahoo.metrics.MetricsPresentationConfig;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -44,6 +46,8 @@ import static com.yahoo.container.jdisc.state.StateHandler.getSnapshotPreprocess
*/
public class MetricsPacketsHandler extends AbstractRequestHandler {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
static final String APPLICATION_KEY = "application";
static final String TIMESTAMP_KEY = "timestamp";
static final String STATUS_CODE_KEY = "status_code";
@@ -97,19 +101,19 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
}
String output = jsonToString(getStatusPacket()) + getAllMetricsPackets() + "\n";
return output.getBytes(StandardCharsets.UTF_8);
- } catch (JSONException e) {
+ } catch (JsonProcessingException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
- private byte[] getMetricsArray() throws JSONException {
- JSONObject root = new JSONObject();
- JSONArray jsonArray = new JSONArray();
- jsonArray.put(getStatusPacket());
+ private byte[] getMetricsArray() throws JsonProcessingException {
+ ObjectNode root = jsonMapper.createObjectNode();
+ ArrayNode jsonArray = jsonMapper.createArrayNode();
+ jsonArray.add(getStatusPacket());
getPacketsForSnapshot(getSnapshot(), applicationName, timer.currentTimeMillis())
- .forEach(jsonArray::put);
- MetricGatherer.getAdditionalMetrics().forEach(jsonArray::put);
- root.put("metrics", jsonArray);
+ .forEach(jsonArray::add);
+ MetricGatherer.getAdditionalMetrics().forEach(jsonArray::add);
+ root.set("metrics", jsonArray);
return jsonToString(root)
.getBytes(StandardCharsets.UTF_8);
}
@@ -117,8 +121,8 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
/**
* Exactly one status packet is added to the response.
*/
- private JSONObject getStatusPacket() throws JSONException {
- JSONObject packet = new JSONObjectWithLegibleException();
+ private JsonNode getStatusPacket() {
+ ObjectNode packet = jsonMapper.createObjectNode();
packet.put(APPLICATION_KEY, applicationName);
StateMonitor.Status status = monitor.status();
@@ -127,14 +131,15 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
return packet;
}
- private String jsonToString(JSONObject jsonObject) throws JSONException {
- return jsonObject.toString(4);
+ private static String jsonToString(JsonNode jsonObject) throws JsonProcessingException {
+ return jsonMapper.writerWithDefaultPrettyPrinter()
+ .writeValueAsString(jsonObject);
}
- private String getAllMetricsPackets() throws JSONException {
+ private String getAllMetricsPackets() throws JsonProcessingException {
StringBuilder ret = new StringBuilder();
- List<JSONObject> metricsPackets = getPacketsForSnapshot(getSnapshot(), applicationName, timer.currentTimeMillis());
- for (JSONObject packet : metricsPackets) {
+ List<JsonNode> metricsPackets = getPacketsForSnapshot(getSnapshot(), applicationName, timer.currentTimeMillis());
+ for (JsonNode packet : metricsPackets) {
ret.append(PACKET_SEPARATOR); // For legibility and parsing in unit tests
ret.append(jsonToString(packet));
}
@@ -150,16 +155,16 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
}
}
- private List<JSONObject> getPacketsForSnapshot(MetricSnapshot metricSnapshot, String application, long timestamp) throws JSONException {
+ private List<JsonNode> getPacketsForSnapshot(MetricSnapshot metricSnapshot, String application, long timestamp) {
if (metricSnapshot == null) return Collections.emptyList();
- List<JSONObject> packets = new ArrayList<>();
+ List<JsonNode> packets = new ArrayList<>();
for (Map.Entry<MetricDimensions, MetricSet> snapshotEntry : metricSnapshot) {
MetricDimensions metricDimensions = snapshotEntry.getKey();
MetricSet metricSet = snapshotEntry.getValue();
- JSONObjectWithLegibleException packet = new JSONObjectWithLegibleException();
+ ObjectNode packet = jsonMapper.createObjectNode();
addMetaData(timestamp, application, packet);
addDimensions(metricDimensions, packet);
addMetrics(metricSet, packet);
@@ -168,27 +173,27 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
return packets;
}
- private void addMetaData(long timestamp, String application, JSONObjectWithLegibleException packet) {
+ private void addMetaData(long timestamp, String application, ObjectNode packet) {
packet.put(APPLICATION_KEY, application);
packet.put(TIMESTAMP_KEY, TimeUnit.MILLISECONDS.toSeconds(timestamp));
}
- private void addDimensions(MetricDimensions metricDimensions, JSONObjectWithLegibleException packet) throws JSONException {
+ private void addDimensions(MetricDimensions metricDimensions, ObjectNode packet) {
if (metricDimensions == null) return;
Iterator<Map.Entry<String, String>> dimensionsIterator = metricDimensions.iterator();
if (dimensionsIterator.hasNext()) {
- JSONObject jsonDim = new JSONObjectWithLegibleException();
- packet.put(DIMENSIONS_KEY, jsonDim);
+ ObjectNode jsonDim = jsonMapper.createObjectNode();
+ packet.set(DIMENSIONS_KEY, jsonDim);
for (Map.Entry<String, String> dimensionEntry : metricDimensions) {
jsonDim.put(dimensionEntry.getKey(), dimensionEntry.getValue());
}
}
}
- private void addMetrics(MetricSet metricSet, JSONObjectWithLegibleException packet) throws JSONException {
- JSONObjectWithLegibleException metrics = new JSONObjectWithLegibleException();
- packet.put(METRICS_KEY, metrics);
+ private void addMetrics(MetricSet metricSet, ObjectNode packet) {
+ ObjectNode metrics = jsonMapper.createObjectNode();
+ packet.set(METRICS_KEY, metrics);
for (Map.Entry<String, MetricValue> metric : metricSet) {
String name = metric.getKey();
MetricValue value = metric.getValue();
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java
index b14dc50edcb..1eb34e15258 100644
--- a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java
+++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java
@@ -1,6 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
import com.yahoo.collections.Tuple2;
import com.yahoo.component.Vtag;
@@ -16,21 +21,16 @@ import com.yahoo.jdisc.handler.ResponseHandler;
import com.yahoo.jdisc.http.HttpHeaders;
import com.yahoo.metrics.MetricsPresentationConfig;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
import java.net.URI;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import java.io.PrintStream;
-import java.io.ByteArrayOutputStream;
/**
* A handler which returns state (health) information from this container instance: Status, metrics and vespa version.
@@ -39,6 +39,8 @@ import java.io.ByteArrayOutputStream;
*/
public class StateHandler extends AbstractRequestHandler {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
public static final String STATE_API_ROOT = "/state/v1";
private static final String METRICS_PATH = "metrics";
private static final String HISTOGRAMS_PATH = "metrics/histograms";
@@ -124,17 +126,16 @@ public class StateHandler extends AbstractRequestHandler {
}
base.append(STATE_API_ROOT);
String uriBase = base.toString();
- JSONArray linkList = new JSONArray();
+ ArrayNode linkList = jsonMapper.createArrayNode();
for (String api : new String[] {METRICS_PATH, CONFIG_GENERATION_PATH, HEALTH_PATH, VERSION_PATH}) {
- JSONObject resource = new JSONObject();
+ ObjectNode resource = jsonMapper.createObjectNode();
resource.put("url", uriBase + "/" + api);
- linkList.put(resource);
+ linkList.add(resource);
}
- return new JSONObjectWithLegibleException()
- .put("resources", linkList)
- .toString(4).getBytes(StandardCharsets.UTF_8);
- } catch (JSONException e) {
- throw new RuntimeException("Bad JSON construction.", e);
+ JsonNode resources = jsonMapper.createObjectNode().set("resources", linkList);
+ return toPrettyString(resources);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("Bad JSON construction", e);
}
}
@@ -154,31 +155,31 @@ public class StateHandler extends AbstractRequestHandler {
private static byte[] buildConfigOutput(ApplicationMetadataConfig config) {
try {
- return new JSONObjectWithLegibleException()
- .put(CONFIG_GENERATION_PATH, new JSONObjectWithLegibleException()
- .put("generation", config.generation())
- .put("container", new JSONObjectWithLegibleException()
- .put("generation", config.generation())))
- .toString(4).getBytes(StandardCharsets.UTF_8);
- } catch (JSONException e) {
+ return toPrettyString(
+ jsonMapper.createObjectNode()
+ .set(CONFIG_GENERATION_PATH, jsonMapper.createObjectNode()
+ .put("generation", config.generation())
+ .set("container", jsonMapper.createObjectNode()
+ .put("generation", config.generation()))));
+ } catch (JsonProcessingException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
private static byte[] buildVersionOutput() {
try {
- return new JSONObjectWithLegibleException()
- .put("version", Vtag.currentVersion)
- .toString(4).getBytes(StandardCharsets.UTF_8);
- } catch (JSONException e) {
+ return toPrettyString(
+ jsonMapper.createObjectNode()
+ .put("version", Vtag.currentVersion.toString()));
+ } catch (JsonProcessingException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
private byte[] buildMetricOutput(String consumer) {
try {
- return buildJsonForConsumer(consumer).toString(4).getBytes(StandardCharsets.UTF_8);
- } catch (JSONException e) {
+ return toPrettyString(buildJsonForConsumer(consumer));
+ } catch (JsonProcessingException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
@@ -191,11 +192,11 @@ public class StateHandler extends AbstractRequestHandler {
return baos.toByteArray();
}
- private JSONObjectWithLegibleException buildJsonForConsumer(String consumer) throws JSONException {
- JSONObjectWithLegibleException ret = new JSONObjectWithLegibleException();
+ private ObjectNode buildJsonForConsumer(String consumer) {
+ ObjectNode ret = jsonMapper.createObjectNode();
ret.put("time", timer.currentTimeMillis());
- ret.put("status", new JSONObjectWithLegibleException().put("code", getStatus().name()));
- ret.put(METRICS_PATH, buildJsonForSnapshot(consumer, getSnapshot()));
+ ret.set("status", jsonMapper.createObjectNode().put("code", getStatus().name()));
+ ret.set(METRICS_PATH, buildJsonForSnapshot(consumer, getSnapshot()));
return ret;
}
@@ -212,12 +213,12 @@ public class StateHandler extends AbstractRequestHandler {
return monitor.status();
}
- private JSONObjectWithLegibleException buildJsonForSnapshot(String consumer, MetricSnapshot metricSnapshot) throws JSONException {
+ private ObjectNode buildJsonForSnapshot(String consumer, MetricSnapshot metricSnapshot) {
if (metricSnapshot == null) {
- return new JSONObjectWithLegibleException();
+ return jsonMapper.createObjectNode();
}
- JSONObjectWithLegibleException jsonMetric = new JSONObjectWithLegibleException();
- jsonMetric.put("snapshot", new JSONObjectWithLegibleException()
+ ObjectNode jsonMetric = jsonMapper.createObjectNode();
+ jsonMetric.set("snapshot", jsonMapper.createObjectNode()
.put("from", metricSnapshot.getFromTime(TimeUnit.MILLISECONDS) / 1000.0)
.put("to", metricSnapshot.getToTime(TimeUnit.MILLISECONDS) / 1000.0));
@@ -225,16 +226,16 @@ public class StateHandler extends AbstractRequestHandler {
long periodInMillis = metricSnapshot.getToTime(TimeUnit.MILLISECONDS) -
metricSnapshot.getFromTime(TimeUnit.MILLISECONDS);
for (Tuple tuple : collapseMetrics(metricSnapshot, consumer)) {
- JSONObjectWithLegibleException jsonTuple = new JSONObjectWithLegibleException();
+ ObjectNode jsonTuple = jsonMapper.createObjectNode();
jsonTuple.put("name", tuple.key);
if (tuple.val instanceof CountMetric) {
CountMetric count = (CountMetric)tuple.val;
- jsonTuple.put("values", new JSONObjectWithLegibleException()
+ jsonTuple.set("values", jsonMapper.createObjectNode()
.put("count", count.getCount())
.put("rate", (count.getCount() * 1000.0) / periodInMillis));
} else if (tuple.val instanceof GaugeMetric) {
GaugeMetric gauge = (GaugeMetric) tuple.val;
- JSONObjectWithLegibleException valueFields = new JSONObjectWithLegibleException();
+ ObjectNode valueFields = jsonMapper.createObjectNode();
valueFields.put("average", gauge.getAverage())
.put("sum", gauge.getSum())
.put("count", gauge.getCount())
@@ -247,22 +248,27 @@ public class StateHandler extends AbstractRequestHandler {
valueFields.put(prefixAndValue.first + "percentile", prefixAndValue.second.doubleValue());
}
}
- jsonTuple.put("values", valueFields);
+ jsonTuple.set("values", valueFields);
} else {
throw new UnsupportedOperationException(tuple.val.getClass().getName());
}
if (tuple.dim != null) {
Iterator<Map.Entry<String, String>> it = tuple.dim.iterator();
if (it.hasNext() && includeDimensions) {
- JSONObjectWithLegibleException jsonDim = new JSONObjectWithLegibleException();
+ ObjectNode jsonDim = jsonMapper.createObjectNode();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
jsonDim.put(entry.getKey(), entry.getValue());
}
- jsonTuple.put("dimensions", jsonDim);
+ jsonTuple.set("dimensions", jsonDim);
}
}
- jsonMetric.append("values", jsonTuple);
+ ArrayNode values = (ArrayNode) jsonMetric.get("values");
+ if (values == null) {
+ values = jsonMapper.createArrayNode();
+ jsonMetric.set("values", values);
+ }
+ values.add(jsonTuple);
}
return jsonMetric;
}
@@ -316,6 +322,12 @@ public class StateHandler extends AbstractRequestHandler {
return metrics;
}
+ private static byte[] toPrettyString(JsonNode resources) throws JsonProcessingException {
+ return jsonMapper.writerWithDefaultPrettyPrinter()
+ .writeValueAsString(resources)
+ .getBytes();
+ }
+
static class Tuple {
final MetricDimensions dim;
diff --git a/container-core/src/main/java/org/json/package-info.java b/container-core/src/main/java/org/json/package-info.java
index 44630ad235a..7ca9fe91e31 100644
--- a/container-core/src/main/java/org/json/package-info.java
+++ b/container-core/src/main/java/org/json/package-info.java
@@ -1,5 +1,5 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
@ExportPackage
package org.json;
-
+// TODO Vespa 8: stop providing org.json
import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java b/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java
index 9020ed91026..ca4bec30322 100644
--- a/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java
+++ b/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java
@@ -1,17 +1,18 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.handler.metrics;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.yahoo.container.jdisc.RequestHandlerTestDriver;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Executors;
@@ -34,6 +35,8 @@ import static org.junit.Assert.fail;
*/
public class MetricsV2HandlerTest {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String URI_BASE = "http://localhost";
private static final String V2_URI = URI_BASE + V2_PATH;
@@ -79,29 +82,29 @@ public class MetricsV2HandlerTest {
@Test
public void v2_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(V2_URI).readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("resources"));
- JSONArray resources = root.getJSONArray("resources");
- assertEquals(1, resources.length());
+ ArrayNode resources = (ArrayNode) root.get("resources");
+ assertEquals(1, resources.size());
- JSONObject valuesUri = resources.getJSONObject(0);
- assertEquals(VALUES_URI, valuesUri.getString("url"));
+ JsonNode valuesUri = resources.get(0);
+ assertEquals(VALUES_URI, valuesUri.get("url").textValue());
}
@Ignore
@Test
- public void visually_inspect_values_response() throws Exception {
- JSONObject responseJson = getResponseAsJson(null);
- System.out.println(responseJson.toString(4));
+ public void visually_inspect_values_response() {
+ JsonNode responseJson = getResponseAsJson(null);
+ System.out.println(responseJson);
}
@Test
public void invalid_path_yields_error_response() throws Exception {
String response = testDriver.sendRequest(V2_URI + "/invalid").readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("error"));
- assertTrue(root.getString("error" ).startsWith("No content"));
+ assertTrue(root.get("error" ).textValue().startsWith("No content"));
}
@Test
@@ -111,23 +114,23 @@ public class MetricsV2HandlerTest {
}
@Test
- public void consumer_is_propagated_to_metrics_proxy_api() throws JSONException {
- JSONObject responseJson = getResponseAsJson(CUSTOM_CONSUMER);
+ public void consumer_is_propagated_to_metrics_proxy_api() {
+ JsonNode responseJson = getResponseAsJson(CUSTOM_CONSUMER);
- JSONObject firstNodeMetricsValues =
- responseJson.getJSONArray("nodes").getJSONObject(0)
- .getJSONObject("node")
- .getJSONArray("metrics").getJSONObject(0)
- .getJSONObject("values");
+ JsonNode firstNodeMetricsValues =
+ responseJson.get("nodes").get(0)
+ .get("node")
+ .get("metrics").get(0)
+ .get("values");
assertTrue(firstNodeMetricsValues.has(REPLACED_CPU_METRIC));
}
- private JSONObject getResponseAsJson(String consumer) {
+ private JsonNode getResponseAsJson(String consumer) {
String response = testDriver.sendRequest(VALUES_URI + consumerQuery(consumer)).readAll();
try {
- return new JSONObject(response);
- } catch (JSONException e) {
+ return jsonMapper.readTree(response);
+ } catch (IOException e) {
fail("Failed to create json object: " + e.getMessage());
throw new RuntimeException(e);
}
diff --git a/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java b/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java
index a0e8c131c2b..9ffce6d1c28 100644
--- a/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java
+++ b/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java
@@ -1,15 +1,11 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.handler.metrics;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.yahoo.container.jdisc.RequestHandlerTestDriver;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.stream.Collectors;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
@@ -26,13 +22,14 @@ import static com.yahoo.container.handler.metrics.MetricsV2Handler.consumerQuery
import static com.yahoo.container.handler.metrics.MetricsV2HandlerTest.getFileContents;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
/**
* @author gjoranv
*/
public class PrometheusV1HandlerTest {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String URI_BASE = "http://localhost";
private static final String V1_URI = URI_BASE + PrometheusV1Handler.V1_PATH;
@@ -79,14 +76,14 @@ public class PrometheusV1HandlerTest {
@Test
public void v1_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(V1_URI).readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("resources"));
- JSONArray resources = root.getJSONArray("resources");
- assertEquals(1, resources.length());
+ ArrayNode resources = (ArrayNode) root.get("resources");
+ assertEquals(1, resources.size());
- JSONObject valuesUri = resources.getJSONObject(0);
- assertEquals(VALUES_URI, valuesUri.getString("url"));
+ JsonNode valuesUri = resources.get(0);
+ assertEquals(VALUES_URI, valuesUri.get("url").asText());
}
@Ignore
@@ -99,9 +96,9 @@ public class PrometheusV1HandlerTest {
@Test
public void invalid_path_yields_error_response() throws Exception {
String response = testDriver.sendRequest(V1_URI + "/invalid").readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("error"));
- assertTrue(root.getString("error" ).startsWith("No content"));
+ assertTrue(root.get("error" ).textValue().startsWith("No content"));
}
@Test
diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/CoredumpGathererTest.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/CoredumpGathererTest.java
index c1f7d790fa5..8a3d0e837c5 100644
--- a/container-core/src/test/java/com/yahoo/container/jdisc/state/CoredumpGathererTest.java
+++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/CoredumpGathererTest.java
@@ -1,8 +1,7 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
import org.junit.Test;
import java.nio.file.Path;
@@ -17,12 +16,12 @@ import static org.junit.Assert.assertEquals;
public class CoredumpGathererTest {
@Test
- public void finds_one_coredump() throws JSONException {
- JSONObject packet = CoredumpGatherer.gatherCoredumpMetrics(new MockFileWrapper());
+ public void finds_one_coredump() {
+ JsonNode packet = CoredumpGatherer.gatherCoredumpMetrics(new MockFileWrapper());
- assertEquals("system-coredumps-processing", packet.getString("application"));
- assertEquals(1, packet.getInt("status_code"));
- assertEquals("Found 1 coredump(s)", packet.getString("status_msg"));
+ assertEquals("system-coredumps-processing", packet.get("application").textValue());
+ assertEquals(1, packet.get("status_code").intValue());
+ assertEquals("Found 1 coredump(s)", packet.get("status_msg").textValue());
}
diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/HostLifeGathererTest.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/HostLifeGathererTest.java
index d025b9662d2..12852c9d54c 100644
--- a/container-core/src/test/java/com/yahoo/container/jdisc/state/HostLifeGathererTest.java
+++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/HostLifeGathererTest.java
@@ -1,8 +1,7 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
import org.junit.Test;
import java.nio.file.Path;
@@ -16,15 +15,15 @@ import static org.junit.Assert.assertEquals;
public class HostLifeGathererTest {
@Test
- public void host_is_alive() throws JSONException {
- JSONObject packet = HostLifeGatherer.getHostLifePacket(new MockFileWrapper());
- JSONObject metrics = packet.getJSONObject("metrics");
- assertEquals("host_life", packet.getString("application"));
- assertEquals(0, packet.getInt("status_code"));
- assertEquals("OK", packet.getString("status_msg"));
-
- assertEquals(123l, metrics.getLong("uptime"));
- assertEquals(1, metrics.getInt("alive"));
+ public void host_is_alive() {
+ JsonNode packet = HostLifeGatherer.getHostLifePacket(new MockFileWrapper());
+ JsonNode metrics = packet.get("metrics");
+ assertEquals("host_life", packet.get("application").textValue());
+ assertEquals(0, packet.get("status_code").intValue());
+ assertEquals("OK", packet.get("status_msg").textValue());
+
+ assertEquals(123L, metrics.get("uptime").longValue());
+ assertEquals(1, metrics.get("alive").intValue());
}
diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java
index 1258ecdc46f..385eb627427 100644
--- a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java
+++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java
@@ -98,37 +98,38 @@ public class StateHandlerTest extends StateHandlerTestBase {
snapshotProvider.setSnapshot(snapshot);
advanceToNextSnapshot();
assertEquals("{\n" +
- " \"metrics\": {\n" +
- " \"snapshot\": {\n" +
- " \"from\": 0,\n" +
- " \"to\": 300\n" +
- " },\n" +
- " \"values\": [\n" +
- " {\n" +
- " \"name\": \"foo\",\n" +
- " \"values\": {\n" +
- " \"count\": 1,\n" +
- " \"rate\": 0.0033333333333333335\n" +
- " }\n" +
- " },\n" +
- " {\n" +
- " \"dimensions\": {\"component\": \"test\"},\n" +
- " \"name\": \"bar\",\n" +
- " \"values\": {\n" +
- " \"average\": 3.5,\n" +
- " \"count\": 4,\n" +
- " \"last\": 5,\n" +
- " \"max\": 5,\n" +
- " \"min\": 2,\n" +
- " \"rate\": 0.013333333333333334,\n" +
- " \"sum\": 14\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- " },\n" +
- " \"status\": {\"code\": \"up\"},\n" +
- " \"time\": 300000\n" +
- "}",
+ " \"time\" : 300000,\n" +
+ " \"status\" : {\n" +
+ " \"code\" : \"up\"\n" +
+ " },\n" +
+ " \"metrics\" : {\n" +
+ " \"snapshot\" : {\n" +
+ " \"from\" : 0.0,\n" +
+ " \"to\" : 300.0\n" +
+ " },\n" +
+ " \"values\" : [ {\n" +
+ " \"name\" : \"foo\",\n" +
+ " \"values\" : {\n" +
+ " \"count\" : 1,\n" +
+ " \"rate\" : 0.0033333333333333335\n" +
+ " }\n" +
+ " }, {\n" +
+ " \"name\" : \"bar\",\n" +
+ " \"values\" : {\n" +
+ " \"average\" : 3.5,\n" +
+ " \"sum\" : 14.0,\n" +
+ " \"count\" : 4,\n" +
+ " \"last\" : 5.0,\n" +
+ " \"max\" : 5.0,\n" +
+ " \"min\" : 2.0,\n" +
+ " \"rate\" : 0.013333333333333334\n" +
+ " },\n" +
+ " \"dimensions\" : {\n" +
+ " \"component\" : \"test\"\n" +
+ " }\n" +
+ " } ]\n" +
+ " }\n" +
+ "}",
requestAsString(V1_URI + "all"));
}
diff --git a/container-dependency-versions/pom.xml b/container-dependency-versions/pom.xml
index 8691d9a7ffb..08d6e0103bf 100644
--- a/container-dependency-versions/pom.xml
+++ b/container-dependency-versions/pom.xml
@@ -313,7 +313,7 @@
<artifactId>javassist</artifactId>
<version>${javassist.version}</version>
</dependency>
- <dependency> <!-- TODO Vespa 8: upgrade to newest version. Consider removing as provided dependency -->
+ <dependency> <!-- TODO Vespa 8: remove as provided dependency -->
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${org.json.version}</version>
diff --git a/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java b/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java
index 709441999d0..df7cacdc768 100644
--- a/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java
+++ b/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java
@@ -1,9 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.usability;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
import com.yahoo.component.ComponentId;
-import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.container.Container;
import com.yahoo.container.jdisc.JdiscBindingsConfig;
import com.yahoo.jdisc.handler.AbstractRequestHandler;
@@ -15,16 +19,11 @@ import com.yahoo.jdisc.handler.ResponseDispatch;
import com.yahoo.jdisc.handler.ResponseHandler;
import com.yahoo.jdisc.http.HttpRequest;
import com.yahoo.jdisc.http.HttpRequest.Method;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -33,6 +32,8 @@ import java.util.Map;
*/
public class BindingsOverviewHandler extends AbstractRequestHandler {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private final JdiscBindingsConfig bindingsConfig;
@Inject
@@ -42,7 +43,7 @@ public class BindingsOverviewHandler extends AbstractRequestHandler {
@Override
public ContentChannel handleRequest(com.yahoo.jdisc.Request request, ResponseHandler handler) {
- JSONObject json;
+ JsonNode json;
int statusToReturn;
if (request instanceof HttpRequest && ((HttpRequest) request).getMethod() != Method.GET) {
@@ -63,7 +64,9 @@ public class BindingsOverviewHandler extends AbstractRequestHandler {
}.connect(handler));
try {
- writer.write(json.toString());
+ writer.write(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(json));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
} finally {
writer.close();
}
@@ -71,63 +74,58 @@ public class BindingsOverviewHandler extends AbstractRequestHandler {
return new IgnoredContent();
}
- private JSONObject errorMessageInJson() {
- JSONObject error = new JSONObject();
- try {
- error.put("error", "This API, "
- + this.getClass().getSimpleName()
- + ", only supports HTTP GET."
- + " You are probably looking for another API/path.");
- } catch (org.json.JSONException e) {
- // just ignore it
- }
+ private static JsonNode errorMessageInJson() {
+ ObjectNode error = jsonMapper.createObjectNode();
+ error.put("error", "This API, "
+ + BindingsOverviewHandler.class.getSimpleName()
+ + ", only supports HTTP GET."
+ + " You are probably looking for another API/path.");
return error;
}
- static JSONArray renderRequestHandlers(JdiscBindingsConfig bindingsConfig,
+ static ArrayNode renderRequestHandlers(JdiscBindingsConfig bindingsConfig,
Map<ComponentId, ? extends RequestHandler> handlersById) {
- JSONArray ret = new JSONArray();
+ ArrayNode ret = jsonMapper.createArrayNode();
for (Map.Entry<ComponentId, ? extends RequestHandler> handlerEntry : handlersById.entrySet()) {
String id = handlerEntry.getKey().stringValue();
RequestHandler handler = handlerEntry.getValue();
- JSONObject handlerJson = renderComponent(handler, handlerEntry.getKey());
+ ObjectNode handlerJson = renderComponent(handler, handlerEntry.getKey());
addBindings(bindingsConfig, id, handlerJson);
- ret.put(handlerJson);
+ ret.add(handlerJson);
}
return ret;
}
- private static void addBindings(JdiscBindingsConfig bindingsConfig, String id, JSONObject handlerJson) {
+ private static void addBindings(JdiscBindingsConfig bindingsConfig, String id, ObjectNode handlerJson) {
List<String> serverBindings = new ArrayList<>();
JdiscBindingsConfig.Handlers handlerConfig = bindingsConfig.handlers(id);
if (handlerConfig != null) {
serverBindings = handlerConfig.serverBindings();
}
- putJson(handlerJson, "serverBindings", renderBindings(serverBindings));
+ handlerJson.set("serverBindings", renderBindings(serverBindings));
}
- private static JSONArray renderBindings(List<String> bindings) {
- JSONArray array = new JSONArray();
+ private static JsonNode renderBindings(List<String> bindings) {
+ ArrayNode array = jsonMapper.createArrayNode();
for (String binding : bindings)
- array.put(binding);
+ array.add(binding);
return array;
}
- private static JSONObject renderComponent(Object component, ComponentId id) {
- JSONObject jc = new JSONObject();
- putJson(jc, "id", id.stringValue());
+ private static ObjectNode renderComponent(Object component, ComponentId id) {
+ ObjectNode jc = jsonMapper.createObjectNode();
+ jc.put("id", id.stringValue());
addBundleInfo(jc, component);
return jc;
}
- private static void addBundleInfo(JSONObject jsonObject, Object component) {
+ private static void addBundleInfo(ObjectNode jsonObject, Object component) {
BundleInfo bundleInfo = bundleInfo(component);
- putJson(jsonObject, "class", bundleInfo.className);
- putJson(jsonObject, "bundle", bundleInfo.bundleName);
-
+ jsonObject.put("class", bundleInfo.className);
+ jsonObject.put("bundle", bundleInfo.bundleName);
}
private static BundleInfo bundleInfo(Object component) {
@@ -143,15 +141,6 @@ public class BindingsOverviewHandler extends AbstractRequestHandler {
}
}
- private static void putJson(JSONObject json, String key, Object value) {
- try {
- json.put(key, value);
- } catch (JSONException e) {
- // The original JSONException lacks key-value info.
- throw new RuntimeException("Trying to add invalid JSON object with key '" + key + "' and value '" + value + "' - " + e.getMessage(), e);
- }
- }
-
static final class BundleInfo {
public final String className;
@@ -172,10 +161,10 @@ public class BindingsOverviewHandler extends AbstractRequestHandler {
this.bindingsConfig = bindingsConfig;
}
- public JSONObject render() {
- JSONObject root = new JSONObject();
+ public JsonNode render() {
+ ObjectNode root = jsonMapper.createObjectNode();
- putJson(root, "handlers",
+ root.set("handlers",
renderRequestHandlers(bindingsConfig, Container.get().getRequestHandlerRegistry().allComponentsById()));
return root;
diff --git a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
index 57c5e768cfb..943eef1e0bf 100644
--- a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
+++ b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
@@ -1,6 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.handler.observability;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
import com.yahoo.component.AbstractComponent;
import com.yahoo.component.ComponentId;
@@ -29,15 +34,11 @@ import com.yahoo.processing.execution.chain.ChainRegistry;
import com.yahoo.processing.handler.ProcessingHandler;
import com.yahoo.search.handler.SearchHandler;
import com.yahoo.search.searchchain.SearchChainRegistry;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@@ -51,11 +52,13 @@ import java.util.Map;
*/
public class ApplicationStatusHandler extends AbstractRequestHandler {
- private final JSONObject applicationJson;
- private final JSONArray clientsJson;
- private final JSONArray serversJson;
- private final JSONArray requestFiltersJson;
- private final JSONArray responseFiltersJson;
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
+ private final JsonNode applicationJson;
+ private final JsonNode clientsJson;
+ private final JsonNode serversJson;
+ private final JsonNode requestFiltersJson;
+ private final JsonNode responseFiltersJson;
private final JdiscBindingsConfig bindingsConfig;
@Inject
@@ -78,7 +81,7 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
@Override
public ContentChannel handleRequest(com.yahoo.jdisc.Request request, ResponseHandler handler) {
- JSONObject json = new StatusResponse(applicationJson, clientsJson, serversJson,
+ JsonNode json = new StatusResponse(applicationJson, clientsJson, serversJson,
requestFiltersJson, responseFiltersJson, bindingsConfig)
.render();
@@ -91,62 +94,66 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
}
}.connect(handler));
- writer.write(json.toString());
+ try {
+ writer.write(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(json));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("Invalid JSON: " + e.getMessage(), e);
+ }
writer.close();
return new IgnoredContent();
}
- static JSONObject renderApplicationConfigs(ApplicationMetadataConfig metaConfig,
+ static JsonNode renderApplicationConfigs(ApplicationMetadataConfig metaConfig,
ApplicationUserdataConfig userConfig) {
- JSONObject vespa = new JSONObject();
- putJson(vespa, "version", Vtag.currentVersion);
-
- JSONObject meta = new JSONObject();
- putJson(meta, "name", metaConfig.name());
- putJson(meta, "user", metaConfig.user());
- putJson(meta, "path", metaConfig.path());
- putJson(meta, "generation", metaConfig.generation());
- putJson(meta, "timestamp", metaConfig.timestamp());
- putJson(meta, "date", new Date(metaConfig.timestamp()).toString());
- putJson(meta, "checksum", metaConfig.checksum());
-
- JSONObject user = new JSONObject();
- putJson(user, "version", userConfig.version());
-
- JSONObject application = new JSONObject();
- putJson(application, "vespa", vespa);
- putJson(application, "meta", meta);
- putJson(application, "user", user);
+ ObjectNode vespa = jsonMapper.createObjectNode();
+ vespa.put("version", Vtag.currentVersion.toString());
+
+ ObjectNode meta = jsonMapper.createObjectNode();
+ meta.put("name", metaConfig.name());
+ meta.put("user", metaConfig.user());
+ meta.put("path", metaConfig.path());
+ meta.put("generation", metaConfig.generation());
+ meta.put("timestamp", metaConfig.timestamp());
+ meta.put("date", new Date(metaConfig.timestamp()).toString());
+ meta.put("checksum", metaConfig.checksum());
+
+ ObjectNode user = jsonMapper.createObjectNode();
+ user.put("version", userConfig.version());
+
+ ObjectNode application = jsonMapper.createObjectNode();
+ application.set("vespa", vespa);
+ application.set("meta", meta);
+ application.set("user", user);
return application;
}
- static JSONArray renderObjectComponents(Map<ComponentId, ?> componentsById) {
- JSONArray ret = new JSONArray();
+ static JsonNode renderObjectComponents(Map<ComponentId, ?> componentsById) {
+ ArrayNode ret = jsonMapper.createArrayNode();
for (Map.Entry<ComponentId, ?> componentEntry : componentsById.entrySet()) {
- JSONObject jc = renderComponent(componentEntry.getValue(), componentEntry.getKey());
- ret.put(jc);
+ JsonNode jc = renderComponent(componentEntry.getValue(), componentEntry.getKey());
+ ret.add(jc);
}
return ret;
}
- static JSONArray renderRequestHandlers(JdiscBindingsConfig bindingsConfig,
+ static JsonNode renderRequestHandlers(JdiscBindingsConfig bindingsConfig,
Map<ComponentId, ? extends RequestHandler> handlersById) {
- JSONArray ret = new JSONArray();
+ ArrayNode ret = jsonMapper.createArrayNode();
for (Map.Entry<ComponentId, ? extends RequestHandler> handlerEntry : handlersById.entrySet()) {
String id = handlerEntry.getKey().stringValue();
RequestHandler handler = handlerEntry.getValue();
- JSONObject handlerJson = renderComponent(handler, handlerEntry.getKey());
+ ObjectNode handlerJson = renderComponent(handler, handlerEntry.getKey());
addBindings(bindingsConfig, id, handlerJson);
- ret.put(handlerJson);
+ ret.add(handlerJson);
}
return ret;
}
- private static void addBindings(JdiscBindingsConfig bindingsConfig, String id, JSONObject handlerJson) {
+ private static void addBindings(JdiscBindingsConfig bindingsConfig, String id, ObjectNode handlerJson) {
List<String> serverBindings = new ArrayList<>();
List<String> clientBindings = new ArrayList<>();
@@ -155,40 +162,40 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
serverBindings = handlerConfig.serverBindings();
clientBindings = handlerConfig.clientBindings();
}
- putJson(handlerJson, "serverBindings", renderBindings(serverBindings));
- putJson(handlerJson, "clientBindings", renderBindings(clientBindings));
+ handlerJson.set("serverBindings", renderBindings(serverBindings));
+ handlerJson.set("clientBindings", renderBindings(clientBindings));
}
- private static JSONArray renderBindings(List<String> bindings) {
- JSONArray ret = new JSONArray();
+ private static JsonNode renderBindings(List<String> bindings) {
+ ArrayNode ret = jsonMapper.createArrayNode();
for (String binding : bindings)
- ret.put(binding);
+ ret.add(binding);
return ret;
}
- private static JSONArray renderAbstractComponents(List<? extends AbstractComponent> components) {
- JSONArray ret = new JSONArray();
+ private static JsonNode renderAbstractComponents(List<? extends AbstractComponent> components) {
+ ArrayNode ret = jsonMapper.createArrayNode();
for (AbstractComponent c : components) {
- JSONObject jc = renderComponent(c, c.getId());
- ret.put(jc);
+ JsonNode jc = renderComponent(c, c.getId());
+ ret.add(jc);
}
return ret;
}
- private static JSONObject renderComponent(Object component, ComponentId id) {
- JSONObject jc = new JSONObject();
- putJson(jc, "id", id.stringValue());
+ private static ObjectNode renderComponent(Object component, ComponentId id) {
+ ObjectNode jc = jsonMapper.createObjectNode();
+ jc.put("id", id.stringValue());
addBundleInfo(jc, component);
return jc;
}
- private static void addBundleInfo(JSONObject jsonObject, Object component) {
+ private static void addBundleInfo(ObjectNode jsonObject, Object component) {
BundleInfo bundleInfo = bundleInfo(component);
- putJson(jsonObject, "class", bundleInfo.className);
- putJson(jsonObject, "bundle", bundleInfo.bundleName);
+ jsonObject.put("class", bundleInfo.className);
+ jsonObject.put("bundle", bundleInfo.bundleName);
}
@@ -205,15 +212,6 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
}
}
- private static void putJson(JSONObject json, String key, Object value) {
- try {
- json.put(key, value);
- } catch (JSONException e) {
- // The original JSONException lacks key-value info.
- throw new RuntimeException("Trying to add invalid JSON object with key '" + key + "' and value '" + value + "' - " + e.getMessage(), e);
- }
- }
-
static final class BundleInfo {
public final String className;
public final String bundleName;
@@ -224,18 +222,18 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
}
static final class StatusResponse {
- private final JSONObject applicationJson;
- private final JSONArray clientsJson;
- private final JSONArray serversJson;
- private final JSONArray requestFiltersJson;
- private final JSONArray responseFiltersJson;
+ private final JsonNode applicationJson;
+ private final JsonNode clientsJson;
+ private final JsonNode serversJson;
+ private final JsonNode requestFiltersJson;
+ private final JsonNode responseFiltersJson;
private final JdiscBindingsConfig bindingsConfig;
- StatusResponse(JSONObject applicationJson,
- JSONArray clientsJson,
- JSONArray serversJson,
- JSONArray requestFiltersJson,
- JSONArray responseFiltersJson,
+ StatusResponse(JsonNode applicationJson,
+ JsonNode clientsJson,
+ JsonNode serversJson,
+ JsonNode requestFiltersJson,
+ JsonNode responseFiltersJson,
JdiscBindingsConfig bindingsConfig) {
this.applicationJson = applicationJson;
this.clientsJson = clientsJson;
@@ -245,52 +243,52 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
this.bindingsConfig = bindingsConfig;
}
- public JSONObject render() {
- JSONObject root = new JSONObject();
+ public JsonNode render() {
+ ObjectNode root = jsonMapper.createObjectNode();
- putJson(root, "application", applicationJson);
- putJson(root, "abstractComponents",
+ root.set("application", applicationJson);
+ root.set("abstractComponents",
renderAbstractComponents(Container.get().getComponentRegistry().allComponents()));
- putJson(root, "handlers",
+ root.set("handlers",
renderRequestHandlers(bindingsConfig, Container.get().getRequestHandlerRegistry().allComponentsById()));
- putJson(root, "clients", clientsJson);
- putJson(root, "servers", serversJson);
- putJson(root, "httpRequestFilters", requestFiltersJson);
- putJson(root, "httpResponseFilters", responseFiltersJson);
+ root.set("clients", clientsJson);
+ root.set("servers", serversJson);
+ root.set("httpRequestFilters", requestFiltersJson);
+ root.set("httpResponseFilters", responseFiltersJson);
- putJson(root, "searchChains", renderSearchChains(Container.get()));
- putJson(root, "docprocChains", renderDocprocChains(Container.get()));
- putJson(root, "processingChains", renderProcessingChains(Container.get()));
+ root.set("searchChains", renderSearchChains(Container.get()));
+ root.set("docprocChains", renderDocprocChains(Container.get()));
+ root.set("processingChains", renderProcessingChains(Container.get()));
return root;
}
- private static JSONObject renderSearchChains(Container container) {
+ private static JsonNode renderSearchChains(Container container) {
for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
if (h instanceof SearchHandler) {
SearchChainRegistry scReg = ((SearchHandler) h).getSearchChainRegistry();
return renderChains(scReg);
}
}
- return new JSONObject();
+ return jsonMapper.createObjectNode();
}
- private static JSONObject renderDocprocChains(Container container) {
- JSONObject ret = new JSONObject();
+ private static JsonNode renderDocprocChains(Container container) {
+ ObjectNode ret = jsonMapper.createObjectNode();
for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
if (h instanceof DocumentProcessingHandler) {
ComponentRegistry<DocprocService> registry = ((DocumentProcessingHandler) h).getDocprocServiceRegistry();
for (DocprocService service : registry.allComponents()) {
- putJson(ret, service.getId().stringValue(), renderCalls(service.getCallStack().iterator()));
+ ret.set(service.getId().stringValue(), renderCalls(service.getCallStack().iterator()));
}
}
}
return ret;
}
- private static JSONObject renderProcessingChains(Container container) {
- JSONObject ret = new JSONObject();
+ private static JsonNode renderProcessingChains(Container container) {
+ JsonNode ret = jsonMapper.createObjectNode();
for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
if (h instanceof ProcessingHandler) {
ChainRegistry<Processor> registry = ((ProcessingHandler) h).getChainRegistry();
@@ -301,20 +299,20 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
}
// Note the generic param here! The key to make this work is '? extends Chain', but why?
- static JSONObject renderChains(ComponentRegistry<? extends Chain<?>> chains) {
- JSONObject ret = new JSONObject();
+ static JsonNode renderChains(ComponentRegistry<? extends Chain<?>> chains) {
+ ObjectNode ret = jsonMapper.createObjectNode();
for (Chain<?> chain : chains.allComponents()) {
- putJson(ret, chain.getId().stringValue(), renderAbstractComponents(chain.components()));
+ ret.set(chain.getId().stringValue(), renderAbstractComponents(chain.components()));
}
return ret;
}
- private static JSONArray renderCalls(Iterator<Call> components) {
- JSONArray ret = new JSONArray();
+ private static JsonNode renderCalls(Iterator<Call> components) {
+ ArrayNode ret = jsonMapper.createArrayNode();
while (components.hasNext()) {
Call c = components.next();
- JSONObject jc = renderComponent(c.getDocumentProcessor(), c.getDocumentProcessor().getId());
- ret.put(jc);
+ JsonNode jc = renderComponent(c.getDocumentProcessor(), c.getDocumentProcessor().getId());
+ ret.add(jc);
}
return ret;
}
diff --git a/container-search-gui/src/main/java/com/yahoo/search/query/gui/GUIHandler.java b/container-search-gui/src/main/java/com/yahoo/search/query/gui/GUIHandler.java
index 9ddcc7a7e69..3132f3744c9 100644
--- a/container-search-gui/src/main/java/com/yahoo/search/query/gui/GUIHandler.java
+++ b/container-search-gui/src/main/java/com/yahoo/search/query/gui/GUIHandler.java
@@ -1,8 +1,10 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.query.gui;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
-
import com.yahoo.container.QrSearchersConfig;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
@@ -11,6 +13,7 @@ import com.yahoo.prelude.IndexModel;
import com.yahoo.prelude.querytransform.RecallSearcher;
import com.yahoo.restapi.Path;
import com.yahoo.search.Query;
+import com.yahoo.search.config.IndexInfoConfig;
import com.yahoo.search.query.Model;
import com.yahoo.search.query.Presentation;
import com.yahoo.search.query.Ranking;
@@ -19,19 +22,12 @@ import com.yahoo.search.query.ranking.MatchPhase;
import com.yahoo.search.query.restapi.ErrorResponse;
import com.yahoo.search.yql.MinimalQueryInserter;
import com.yahoo.vespa.config.search.RankProfilesConfig;
-import com.yahoo.search.config.IndexInfoConfig;
import com.yahoo.yolean.Exceptions;
-import org.json.JSONException;
-import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
import java.util.logging.Level;
@@ -42,6 +38,8 @@ import java.util.logging.Level;
*/
public class GUIHandler extends LoggingRequestHandler {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private final IndexModel indexModel;
private final RankProfilesConfig rankProfilesConfig;
@@ -112,7 +110,7 @@ public class GUIHandler extends LoggingRequestHandler {
InputStream is;
if (this.path.equals("config.json")){
String json = "{}";
- try { json = getGUIConfig(); } catch (JSONException e) { /*Something happened while parsing JSON */ }
+ try { json = getGUIConfig(); } catch (IOException e) { /*Something happened while parsing JSON */ }
is = new ByteArrayInputStream(json.getBytes());
} else{
is = GUIHandler.class.getClassLoader().getResourceAsStream("gui/"+this.path);
@@ -160,50 +158,50 @@ public class GUIHandler extends LoggingRequestHandler {
return "text/html";
}
- private String getGUIConfig() throws JSONException {
- JSONObject json = new JSONObject();
- json.put("ranking_properties", Arrays.asList("propertyname"));
- json.put("ranking_features", Arrays.asList("featurename"));
+ private String getGUIConfig() throws IOException {
+ ObjectNode json = jsonMapper.createObjectNode();
+ json.set("ranking_properties", jsonMapper.createArrayNode().add("propertyname"));
+ json.set("ranking_features", jsonMapper.createArrayNode().add("featurename"));
- List<String> sources = new ArrayList<>();
+ ArrayNode sources = jsonMapper.createArrayNode();
try {
- sources = new ArrayList<>(indexModel.getMasterClusters().keySet());
+ indexModel.getMasterClusters().keySet().forEach(sources::add);
} catch (NullPointerException ex){ /* clusters are not set */ }
- json.put("model_sources", sources);
+ json.set("model_sources", sources);
- List<String> rankProfiles = new ArrayList<>();
+ ArrayNode rankProfiles = jsonMapper.createArrayNode();
try {
rankProfilesConfig.rankprofile().forEach(rankProfile -> rankProfiles.add(rankProfile.name()));
} catch (NullPointerException ex){ /* rankprofiles are not set*/ }
- json.put("ranking_profile", rankProfiles);
+ json.set("ranking_profile", rankProfiles);
// Creating map from parent to children for GUI: parameter --> child-parameters
- HashMap<String, List<String>> childMap = new HashMap<>();
- childMap.put(Model.MODEL, Arrays.asList(Model.DEFAULT_INDEX, Model.ENCODING, Model.LANGUAGE, Model.QUERY_STRING, Model.RESTRICT, Model.SEARCH_PATH, Model.SOURCES, Model.TYPE));
- childMap.put(Ranking.RANKING, Arrays.asList(Ranking.LOCATION, Ranking.FEATURES, Ranking.LIST_FEATURES, Ranking.PROFILE, Ranking.PROPERTIES, Ranking.SORTING, Ranking.FRESHNESS, Ranking.QUERYCACHE, Ranking.MATCH_PHASE));
- childMap.put(Ranking.RANKING +"."+ Ranking.MATCH_PHASE, Arrays.asList(MatchPhase.MAX_HITS, MatchPhase.ATTRIBUTE, MatchPhase.ASCENDING, Ranking.DIVERSITY));
- childMap.put(Ranking.RANKING +"."+ Ranking.MATCH_PHASE +"."+Ranking.DIVERSITY, Arrays.asList(Diversity.ATTRIBUTE, Diversity.MINGROUPS));
- childMap.put(Presentation.PRESENTATION, Arrays.asList(Presentation.BOLDING, Presentation.FORMAT, Presentation.SUMMARY, "template", Presentation.TIMING ));
- childMap.put("trace", Arrays.asList("timestamps"));
- childMap.put("tracelevel", Arrays.asList("rules"));
- childMap.put("metrics", Arrays.asList("ignore"));
- childMap.put("collapse", Arrays.asList("summary"));
- childMap.put("pos", Arrays.asList("ll", "radius", "bb", "attribute"));
- childMap.put("streaming", Arrays.asList("userid", "groupname", "selection", "priority", "maxbucketspervisitor"));
- childMap.put("rules", Arrays.asList("off", "rulebase"));
- json.put("childMap", childMap);
-
- List<String> levelZeroParameters = Arrays.asList(MinimalQueryInserter.YQL.toString(), Query.HITS.toString(), Query.OFFSET.toString(),
- "queryProfile", Query.NO_CACHE.toString(), Query.GROUPING_SESSION_CACHE.toString(),
- Query.SEARCH_CHAIN.toString(), Query.TIMEOUT.toString(), "trace", "tracelevel",
- Query.TRACE_LEVEL.toString(), Query.EXPLAIN_LEVEL.toString(), "explainlevel", Model.MODEL, Ranking.RANKING, "collapse", "collapsesize","collapsefield",
- Presentation.PRESENTATION, "pos", "streaming", "rules", RecallSearcher.recallName.toString(), "user",
- "metrics", "");
- json.put("levelZeroParameters", levelZeroParameters);
-
- return json.toString();
+ ObjectNode childMap = jsonMapper.createObjectNode();
+ childMap.set(Model.MODEL, jsonMapper.createArrayNode().add(Model.DEFAULT_INDEX).add(Model.ENCODING).add(Model.LANGUAGE).add(Model.QUERY_STRING).add(Model.RESTRICT).add(Model.SEARCH_PATH).add(Model.SOURCES).add(Model.TYPE));
+ childMap.set(Ranking.RANKING, jsonMapper.createArrayNode().add(Ranking.LOCATION).add(Ranking.FEATURES).add(Ranking.LIST_FEATURES).add(Ranking.PROFILE).add(Ranking.PROPERTIES).add(Ranking.SORTING).add(Ranking.FRESHNESS).add(Ranking.QUERYCACHE).add(Ranking.MATCH_PHASE));
+ childMap.set(Ranking.RANKING +"."+ Ranking.MATCH_PHASE, jsonMapper.createArrayNode().add(MatchPhase.MAX_HITS).add(MatchPhase.ATTRIBUTE).add(MatchPhase.ASCENDING).add(Ranking.DIVERSITY));
+ childMap.set(Ranking.RANKING +"."+ Ranking.MATCH_PHASE +"."+Ranking.DIVERSITY, jsonMapper.createArrayNode().add(Diversity.ATTRIBUTE).add(Diversity.MINGROUPS));
+ childMap.set(Presentation.PRESENTATION, jsonMapper.createArrayNode().add(Presentation.BOLDING).add(Presentation.FORMAT).add(Presentation.SUMMARY).add("template").add(Presentation.TIMING ));
+ childMap.set("trace", jsonMapper.createArrayNode().add("timestamps"));
+ childMap.set("tracelevel", jsonMapper.createArrayNode().add("rules"));
+ childMap.set("metrics", jsonMapper.createArrayNode().add("ignore"));
+ childMap.set("collapse", jsonMapper.createArrayNode().add("summary"));
+ childMap.set("pos", jsonMapper.createArrayNode().add("ll").add("radius").add("bb").add("attribute"));
+ childMap.set("streaming", jsonMapper.createArrayNode().add("userid").add("groupname").add("selection").add("priority").add("maxbucketspervisitor"));
+ childMap.set("rules", jsonMapper.createArrayNode().add("off").add("rulebase"));
+ json.set("childMap", childMap);
+
+ ArrayNode levelZeroParameters = jsonMapper.createArrayNode().add(MinimalQueryInserter.YQL.toString()).add(Query.HITS.toString()).add(Query.OFFSET.toString())
+ .add("queryProfile").add(Query.NO_CACHE.toString()).add(Query.GROUPING_SESSION_CACHE.toString())
+ .add(Query.SEARCH_CHAIN.toString()).add(Query.TIMEOUT.toString()).add("trace").add("tracelevel")
+ .add(Query.TRACE_LEVEL.toString()).add(Query.EXPLAIN_LEVEL.toString()).add("explainlevel").add(Model.MODEL).add(Ranking.RANKING).add("collapse").add("collapsesize").add("collapsefield")
+ .add(Presentation.PRESENTATION).add("pos").add("streaming").add("rules").add(RecallSearcher.recallName.toString()).add("user")
+ .add("metrics").add("");
+ json.set("levelZeroParameters", levelZeroParameters);
+
+ return jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
}
}
} \ No newline at end of file
diff --git a/container-search/pom.xml b/container-search/pom.xml
index 074f5827122..014b7dda14f 100644
--- a/container-search/pom.xml
+++ b/container-search/pom.xml
@@ -150,6 +150,11 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java b/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java
index 209bfd08e6b..55438aa35ba 100644
--- a/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java
+++ b/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java
@@ -21,6 +21,7 @@ import java.util.Iterator;
*
* @author Steinar Knutsen
*/
+// TODO Vespa 8: remove methods leaking org.json types (replace with Slime equivalent?)
public class JSONString implements Inspectable {
private Inspector value;
@@ -436,6 +437,8 @@ public class JSONString implements Inspectable {
return content;
}
+ /** @deprecated Use {@link #getContent()} instead and parse content yourself */
+ @Deprecated(forRemoval = true, since = "7")
public Object getParsedJSON() {
initContent();
if (parsedJSON == null) {
@@ -444,6 +447,7 @@ public class JSONString implements Inspectable {
return parsedJSON;
}
+ @Deprecated(forRemoval = true, since = "7")
public void setParsedJSON(Object parsedJSON) {
this.parsedJSON = parsedJSON;
}
diff --git a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
index 31f8194b3b7..c4f850307ae 100644
--- a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
+++ b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
@@ -45,8 +45,6 @@ import com.yahoo.search.result.Hit;
import com.yahoo.search.result.HitGroup;
import com.yahoo.search.result.NanNumber;
import com.yahoo.tensor.Tensor;
-import org.json.JSONArray;
-import org.json.JSONObject;
import java.io.IOException;
import java.io.OutputStream;
@@ -671,14 +669,6 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
} else if (field instanceof FieldValue) {
// the null below is the field which has already been written
((FieldValue) field).serialize(null, new JsonWriter(generator));
- } else if (field instanceof JSONArray || field instanceof JSONObject) {
- // org.json returns null if the object would not result in syntactically correct JSON
- String s = field.toString();
- if (s == null) {
- generator.writeNull();
- } else {
- generator.writeRawValue(s);
- }
} else {
generator.writeString(field.toString());
}
diff --git a/container-search/src/test/java/com/yahoo/prelude/fastsearch/SlimeSummaryTestCase.java b/container-search/src/test/java/com/yahoo/prelude/fastsearch/SlimeSummaryTestCase.java
index d1399cabc75..49df321e581 100644
--- a/container-search/src/test/java/com/yahoo/prelude/fastsearch/SlimeSummaryTestCase.java
+++ b/container-search/src/test/java/com/yahoo/prelude/fastsearch/SlimeSummaryTestCase.java
@@ -4,16 +4,21 @@ package com.yahoo.prelude.fastsearch;
import com.google.common.collect.ImmutableSet;
import com.yahoo.config.subscription.ConfigGetter;
import com.yahoo.data.access.slime.SlimeAdapter;
+import com.yahoo.prelude.hitfield.JSONString;
import com.yahoo.prelude.hitfield.RawData;
import com.yahoo.prelude.hitfield.XMLString;
-import com.yahoo.prelude.hitfield.JSONString;
import com.yahoo.search.result.FeatureData;
import com.yahoo.search.result.Hit;
-import com.yahoo.search.result.NanNumber;
import com.yahoo.search.result.StructuredData;
+import com.yahoo.slime.BinaryFormat;
+import com.yahoo.slime.Cursor;
+import com.yahoo.slime.Slime;
+import com.yahoo.tensor.Tensor;
+import com.yahoo.tensor.serialization.TypedBinaryFormat;
+import org.junit.Test;
+
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
@@ -21,14 +26,6 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
-import com.yahoo.slime.BinaryFormat;
-import com.yahoo.slime.Cursor;
-import com.yahoo.slime.Inspector;
-import com.yahoo.slime.Slime;
-import com.yahoo.tensor.Tensor;
-import com.yahoo.tensor.serialization.TypedBinaryFormat;
-import org.junit.Test;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -102,7 +99,7 @@ public class SlimeSummaryTestCase {
if (hit.getField("jsonstring_field") instanceof JSONString) {
JSONString jstr = (JSONString) hit.getField("jsonstring_field");
assertEquals("{\"foo\":1,\"bar\":2}", jstr.getContent());
- assertNotNull(jstr.getParsedJSON());
+ assertNotNull(getParsedJSON(jstr));
com.yahoo.data.access.Inspector value = jstr.inspect();
assertEquals(1L, value.field("foo").asLong());
@@ -126,6 +123,8 @@ public class SlimeSummaryTestCase {
assertEquals(tensor2, featureData.getTensor("tensor2_feature"));
}
+ @SuppressWarnings("removal") private static Object getParsedJSON(JSONString jstr) { return jstr.getParsedJSON(); }
+
@Test
public void testFieldAccessAPI() {
DocsumDefinitionSet partialDocsum1 = createDocsumDefinitionSet(partial_summary1_cf);
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java
index 3cca053d0e5..80e629ca4cb 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java
@@ -1,10 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.handler.test;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yahoo.container.Container;
import com.yahoo.container.core.config.testutil.HandlersConfigurerTestWrapper;
import com.yahoo.container.jdisc.HttpRequest;
-
import com.yahoo.container.jdisc.RequestHandlerTestDriver;
import com.yahoo.container.protect.Error;
import com.yahoo.io.IOUtils;
@@ -13,8 +16,8 @@ import com.yahoo.search.handler.SearchHandler;
import com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.SlimeUtils;
-import org.json.JSONArray;
-import org.json.JSONObject;
+import com.yahoo.test.json.JsonTestHelper;
+import org.assertj.core.api.Assertions;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -23,13 +26,19 @@ import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
-import java.util.Map;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
+import java.util.Map;
import static com.yahoo.jdisc.http.HttpRequest.Method.GET;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
/**
* Tests submitting the query as JSON.
@@ -38,6 +47,8 @@ import static org.junit.Assert.*;
*/
public class JSONSearchHandlerTestCase {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String testDir = "src/test/java/com/yahoo/search/handler/test/config";
private static final String myHostnameHeader = "my-hostname-header";
private static final String selfHostname = HostName.getLocalhost();
@@ -97,8 +108,8 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testFailing() throws Exception {
- JSONObject json = new JSONObject();
+ public void testFailing() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "test");
json.put("searchChain", "classLoadingError");
assertTrue(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE).readAll().contains("NoClassDefFoundError"));
@@ -106,16 +117,16 @@ public class JSONSearchHandlerTestCase {
@Test
- public synchronized void testPluginError() throws Exception {
- JSONObject json = new JSONObject();
+ public synchronized void testPluginError() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "test");
json.put("searchChain", "exceptionInPlugin");
assertTrue(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE).readAll().contains("NullPointerException"));
}
@Test
- public synchronized void testWorkingReconfiguration() throws Exception {
- JSONObject json = new JSONObject();
+ public synchronized void testWorkingReconfiguration() throws IOException {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
assertJsonResult(json, driver);
@@ -135,7 +146,7 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testInvalidYqlQuery() throws Exception {
+ public void testInvalidYqlQuery() throws IOException {
IOUtils.copyDirectory(new File(testDir, "config_yql"), new File(tempDir), 1);
generateComponentsConfigForActive();
configurer.reloadConfig();
@@ -143,7 +154,7 @@ public class JSONSearchHandlerTestCase {
SearchHandler newSearchHandler = fetchSearchHandler(configurer);
assertTrue("Do I have a new instance of the search handler?", searchHandler != newSearchHandler);
try (RequestHandlerTestDriver newDriver = new RequestHandlerTestDriver(newSearchHandler)) {
- JSONObject json = new JSONObject();
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("yql", "select * from foo where bar > 1453501295");
RequestHandlerTestDriver.MockResponseHandler responseHandler = newDriver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE);
responseHandler.readAll();
@@ -153,14 +164,14 @@ public class JSONSearchHandlerTestCase {
// Query handling takes a different code path when a query profile is active, so we test both paths.
@Test
- public void testInvalidQueryParamWithQueryProfile() throws Exception {
+ public void testInvalidQueryParamWithQueryProfile() throws IOException {
try (RequestHandlerTestDriver newDriver = driverWithConfig("config_invalid_param")) {
testInvalidQueryParam(newDriver);
}
}
- private void testInvalidQueryParam(final RequestHandlerTestDriver testDriver) throws Exception {
- JSONObject json = new JSONObject();
+ private void testInvalidQueryParam(final RequestHandlerTestDriver testDriver) {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "status_code:0");
json.put("hits", 20);
json.put("offset", -20);
@@ -173,16 +184,16 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testNormalResultJsonAliasRendering() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNormalResultJsonAliasRendering() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("format", "json");
json.put("query", "abc");
assertJsonResult(json, driver);
}
@Test
- public void testNullQuery() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNullQuery() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("format", "xml");
assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
@@ -195,8 +206,8 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testWebServiceStatus() throws Exception {
- JSONObject json = new JSONObject();
+ public void testWebServiceStatus() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "web_service_status_code");
RequestHandlerTestDriver.MockResponseHandler responseHandler =
driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE);
@@ -206,39 +217,39 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testNormalResultImplicitDefaultRendering() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNormalResultImplicitDefaultRendering() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
assertJsonResult(json, driver);
}
@Test
- public void testNormalResultExplicitDefaultRendering() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNormalResultExplicitDefaultRendering() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
json.put("format", "default");
assertJsonResult(json, driver);
}
@Test
- public void testNormalResultXmlAliasRendering() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNormalResultXmlAliasRendering() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
json.put("format", "xml");
assertXmlResult(json, driver);
}
@Test
- public void testNormalResultExplicitDefaultRenderingFullRendererName1() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNormalResultExplicitDefaultRenderingFullRendererName1() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
json.put("format", "XmlRenderer");
assertXmlResult(json, driver);
}
@Test
- public void testNormalResultExplicitDefaultRenderingFullRendererName2() throws Exception {
- JSONObject json = new JSONObject();
+ public void testNormalResultExplicitDefaultRenderingFullRendererName2() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
json.put("format", "JsonRenderer");
assertJsonResult(json, driver);
@@ -253,7 +264,7 @@ public class JSONSearchHandlerTestCase {
" </hit>\n" +
"</result>\n";
- private void assertXmlResult(JSONObject json, RequestHandlerTestDriver driver) {
+ private void assertXmlResult(JsonNode json, RequestHandlerTestDriver driver) {
assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), xmlResult);
}
@@ -263,7 +274,7 @@ public class JSONSearchHandlerTestCase {
+ "{\"id\":\"testHit\",\"relevance\":1.0,\"fields\":{\"uri\":\"testHit\"}}"
+ "]}}";
- private void assertJsonResult(JSONObject json, RequestHandlerTestDriver driver) {
+ private void assertJsonResult(JsonNode json, RequestHandlerTestDriver driver) {
assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), jsonResult);
}
@@ -288,7 +299,7 @@ public class JSONSearchHandlerTestCase {
}
- private RequestHandlerTestDriver driverWithConfig(String configDirectory) throws Exception {
+ private RequestHandlerTestDriver driverWithConfig(String configDirectory) throws IOException {
IOUtils.copyDirectory(new File(testDir, configDirectory), new File(tempDir), 1);
generateComponentsConfigForActive();
configurer.reloadConfig();
@@ -299,44 +310,44 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testSelectParameters() throws Exception {
- JSONObject json = new JSONObject();
+ public void testSelectParameters() throws IOException {
+ ObjectNode json = jsonMapper.createObjectNode();
- JSONObject select = new JSONObject();
+ ObjectNode select = jsonMapper.createObjectNode();
- JSONObject where = new JSONObject();
+ ObjectNode where = jsonMapper.createObjectNode();
where.put("where", "where");
- JSONObject grouping = new JSONObject();
+ ObjectNode grouping = jsonMapper.createObjectNode();
grouping.put("grouping", "grouping");
- select.put("where", where);
- select.put("grouping", grouping);
+ select.set("where", where);
+ select.set("grouping", grouping);
- json.put("select", select);
+ json.set("select", select);
- Inspector inspector = SlimeUtils.jsonToSlime(json.toString().getBytes("utf-8")).get();
+ Inspector inspector = SlimeUtils.jsonToSlime(json.toString().getBytes(StandardCharsets.UTF_8)).get();
Map<String, String> map = new HashMap<>();
searchHandler.createRequestMapping(inspector, map, "");
- JSONObject processedWhere = new JSONObject(map.get("select.where"));
- assertEquals(where.toString(), processedWhere.toString());
+ JsonNode processedWhere = jsonMapper.readTree(map.get("select.where"));
+ JsonTestHelper.assertJsonEquals(where.toString(), processedWhere.toString());
- JSONObject processedGrouping = new JSONObject(map.get("select.grouping"));
- assertEquals(grouping.toString(), processedGrouping.toString());
+ JsonNode processedGrouping = jsonMapper.readTree(map.get("select.grouping"));
+ JsonTestHelper.assertJsonEquals(grouping.toString(), processedGrouping.toString());
}
@Test
- public void testJsonQueryWithSelectWhere() throws Exception {
- JSONObject root = new JSONObject();
- JSONObject select = new JSONObject();
- JSONObject where = new JSONObject();
- JSONArray term = new JSONArray();
- term.put("default");
- term.put("bad");
- where.put("contains", term);
- select.put("where", where);
- root.put("select", select);
+ public void testJsonQueryWithSelectWhere() {
+ ObjectNode root = jsonMapper.createObjectNode();
+ ObjectNode select = jsonMapper.createObjectNode();
+ ObjectNode where = jsonMapper.createObjectNode();
+ ArrayNode term = jsonMapper.createArrayNode();
+ term.add("default");
+ term.add("bad");
+ where.set("contains", term);
+ select.set("where", where);
+ root.set("select", select);
// Run query
String result = driver.sendRequest(uri + "searchChain=echoingQuery", com.yahoo.jdisc.http.HttpRequest.Method.POST, root.toString(), JSON_CONTENT_TYPE).readAll();
@@ -393,8 +404,8 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testJsonQueryWithYQL() throws Exception {
- JSONObject root = new JSONObject();
+ public void testJsonQueryWithYQL() {
+ ObjectNode root = jsonMapper.createObjectNode();
root.put("yql", "select * from sources * where default contains 'bad';");
// Run query
@@ -404,10 +415,10 @@ public class JSONSearchHandlerTestCase {
}
@Test
- public void testRequestMapping() throws Exception {
- JSONObject json = new JSONObject();
+ public void testRequestMapping() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("yql", "select * from sources * where sddocname contains \"blog_post\" limit 0 | all(group(date) max(3) order(-count())each(output(count())));");
- json.put("hits", 10.0);
+ json.put("hits", 10);
json.put("offset", 5);
json.put("queryProfile", "foo");
json.put("nocache", false);
@@ -417,7 +428,7 @@ public class JSONSearchHandlerTestCase {
json.put("select", "_all");
- JSONObject model = new JSONObject();
+ ObjectNode model = jsonMapper.createObjectNode();
model.put("defaultIndex", 1);
model.put("encoding", "json");
model.put("filter", "default");
@@ -427,9 +438,9 @@ public class JSONSearchHandlerTestCase {
model.put("searchPath", "node1");
model.put("sources", "source1,source2");
model.put("type", "yql");
- json.put("model", model);
+ json.set("model", model);
- JSONObject ranking = new JSONObject();
+ ObjectNode ranking = jsonMapper.createObjectNode();
ranking.put("location", "123789.89123N;128123W");
ranking.put("features", "none");
ranking.put("listFeatures", false);
@@ -439,61 +450,61 @@ public class JSONSearchHandlerTestCase {
ranking.put("freshness", "0.05");
ranking.put("queryCache", false);
- JSONObject matchPhase = new JSONObject();
+ ObjectNode matchPhase = jsonMapper.createObjectNode();
matchPhase.put("maxHits", "100");
matchPhase.put("attribute", "title");
matchPhase.put("ascending", true);
- JSONObject diversity = new JSONObject();
+ ObjectNode diversity = jsonMapper.createObjectNode();
diversity.put("attribute", "title");
diversity.put("minGroups", 1);
- matchPhase.put("diversity", diversity);
- ranking.put("matchPhase", matchPhase);
- json.put("ranking", ranking);
+ matchPhase.set("diversity", diversity);
+ ranking.set("matchPhase", matchPhase);
+ json.set("ranking", ranking);
- JSONObject presentation = new JSONObject();
+ ObjectNode presentation = jsonMapper.createObjectNode();
presentation.put("bolding", true);
presentation.put("format", "json");
presentation.put("summary", "none");
presentation.put("template", "json");
presentation.put("timing", false);
- json.put("presentation", presentation);
+ json.set("presentation", presentation);
- JSONObject collapse = new JSONObject();
+ ObjectNode collapse = jsonMapper.createObjectNode();
collapse.put("field", "none");
collapse.put("size", 2);
collapse.put("summary", "default");
- json.put("collapse", collapse);
+ json.set("collapse", collapse);
- JSONObject trace = new JSONObject();
+ ObjectNode trace = jsonMapper.createObjectNode();
trace.put("level", 1);
trace.put("timestamps", false);
trace.put("rules", "none");
- json.put("trace", trace);
+ json.set("trace", trace);
- JSONObject pos = new JSONObject();
+ ObjectNode pos = jsonMapper.createObjectNode();
pos.put("ll", "1263123N;1231.9W");
pos.put("radius", "71234m");
pos.put("bb", "1237123W;123218N");
pos.put("attribute", "default");
- json.put("pos", pos);
+ json.set("pos", pos);
- JSONObject streaming = new JSONObject();
+ ObjectNode streaming = jsonMapper.createObjectNode();
streaming.put("userid", 123);
streaming.put("groupname", "abc");
streaming.put("selection", "none");
streaming.put("priority", 10);
streaming.put("maxbucketspervisitor", 5);
- json.put("streaming", streaming);
+ json.set("streaming", streaming);
- JSONObject rules = new JSONObject();
+ ObjectNode rules = jsonMapper.createObjectNode();
rules.put("off", false);
rules.put("rulebase", "default");
- json.put("rules", rules);
+ json.set("rules", rules);
- JSONObject metrics = new JSONObject();
+ ObjectNode metrics = jsonMapper.createObjectNode();
metrics.put("ignore", "_all");
- json.put("metrics", metrics);
+ json.set("metrics", metrics);
json.put("recall", "none");
json.put("user", 123);
@@ -501,7 +512,7 @@ public class JSONSearchHandlerTestCase {
json.put("hitcountestimate", true);
// Create mapping
- Inspector inspector = SlimeUtils.jsonToSlime(json.toString().getBytes("utf-8")).get();
+ Inspector inspector = SlimeUtils.jsonToSlime(json.toString().getBytes(StandardCharsets.UTF_8)).get();
Map<String, String> map = new HashMap<>();
searchHandler.createRequestMapping(inspector, map, "");
@@ -518,12 +529,12 @@ public class JSONSearchHandlerTestCase {
// Get mapping
Map<String, String> propertyMap = request.propertyMap();
- assertEquals("Should have same mapping for properties", map, propertyMap);
+ Assertions.assertThat(propertyMap).isEqualTo(map);
}
@Test
- public void testContentTypeParsing() throws Exception {
- JSONObject json = new JSONObject();
+ public void testContentTypeParsing() {
+ ObjectNode json = jsonMapper.createObjectNode();
json.put("query", "abc");
assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), "Application/JSON; charset=utf-8"), jsonResult);
}
diff --git a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java
index c4d49c11f5e..48003f6586f 100644
--- a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.rendering;
-import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.ListenableFuture;
@@ -56,9 +55,6 @@ import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.serialization.TypedBinaryFormat;
import com.yahoo.text.Utf8;
import com.yahoo.yolean.trace.TraceNode;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
@@ -67,7 +63,6 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@@ -83,6 +78,8 @@ import static org.junit.Assert.assertTrue;
*/
public class JsonRendererTestCase {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private JsonRenderer originalRenderer;
private JsonRenderer renderer;
@@ -959,7 +956,7 @@ public class JsonRendererTestCase {
}
@Test
- public void testJsonObjects() throws InterruptedException, ExecutionException, IOException, JSONException {
+ public void testJsonObjects() throws InterruptedException, ExecutionException, IOException {
String expected = "{"
+ " \"root\": {"
+ " \"children\": ["
@@ -973,14 +970,6 @@ public class JsonRendererTestCase {
+ " },"
+ " \"json producer\": {"
+ " \"long in structured\": 7809531904"
- + " },"
- + " \"org.json array\": ["
- + " true,"
- + " true,"
- + " false"
- + " ],"
- + " \"org.json object\": {"
- + " \"forty-two\": 42"
+ " }"
+ " },"
+ " \"id\": \"json objects\","
@@ -996,26 +985,17 @@ public class JsonRendererTestCase {
+ "}";
Result r = newEmptyResult();
Hit h = new Hit("json objects");
- JSONObject o = new JSONObject();
- JSONArray a = new JSONArray();
- ObjectMapper mapper = new ObjectMapper();
- JsonNode j = mapper.createObjectNode();
+ ObjectNode j = jsonMapper.createObjectNode();
JSONString s = new JSONString("{\"a\": \"b\"}");
Slime slime = new Slime();
Cursor c = slime.setObject();
c.setLong("long in structured", 7809531904L);
SlimeAdapter slimeInit = new SlimeAdapter(slime.get());
StructuredData struct = new StructuredData(slimeInit);
- ((ObjectNode) j).put("Nineteen-eighty-four", 1984);
- o.put("forty-two", 42);
- a.put(true);
- a.put(true);
- a.put(false);
+ j.put("Nineteen-eighty-four", 1984);
h.setField("inspectable", s);
h.setField("jackson", j);
h.setField("json producer", struct);
- h.setField("org.json array", a);
- h.setField("org.json object", o);
r.hits().add(h);
String summary = render(r);
assertEqualJson(expected, summary);
@@ -1236,11 +1216,13 @@ public class JsonRendererTestCase {
public void testThatTheJsonValidatorCanCatchErrors() {
String json = "{"
+ " \"root\": {"
- + " \"duplicate\": 1,"
- + " \"duplicate\": 2"
+ + " \"invalidvalue\": 1adsf,"
+ " }"
+ "}";
- assertEquals("Duplicate key \"duplicate\"", validateJSON(json));
+ assertEquals(
+ "Unexpected character ('a' (code 97)): was expecting comma to separate Object entries\n" +
+ " at [Source: { \"root\": { \"invalidvalue\": 1adsf, }}; line: 1, column: 41]",
+ validateJSON(json));
}
@Test
@@ -1316,9 +1298,9 @@ public class JsonRendererTestCase {
private String validateJSON(String presumablyValidJson) {
try {
- new JSONObject(presumablyValidJson);
+ jsonMapper.readTree(presumablyValidJson);
return "";
- } catch (JSONException e) {
+ } catch (IOException e) {
return e.getMessage();
}
}
diff --git a/container-search/src/test/java/com/yahoo/select/SelectTestCase.java b/container-search/src/test/java/com/yahoo/select/SelectTestCase.java
index 3239a97a094..9bcd3addd92 100644
--- a/container-search/src/test/java/com/yahoo/select/SelectTestCase.java
+++ b/container-search/src/test/java/com/yahoo/select/SelectTestCase.java
@@ -1,6 +1,9 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.select;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yahoo.prelude.query.AndItem;
import com.yahoo.prelude.query.ExactStringItem;
import com.yahoo.prelude.query.Item;
@@ -17,19 +20,15 @@ import com.yahoo.prelude.query.WordItem;
import com.yahoo.processing.IllegalInputException;
import com.yahoo.search.Query;
import com.yahoo.search.grouping.GroupingRequest;
-import com.yahoo.search.grouping.request.AllOperation;
import com.yahoo.search.query.QueryTree;
import com.yahoo.search.query.Select;
import com.yahoo.search.query.SelectParser;
import com.yahoo.search.query.parser.Parsable;
import com.yahoo.search.query.parser.ParserEnvironment;
import com.yahoo.search.yql.VespaGroupingStep;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.Test;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -48,15 +47,18 @@ import static org.junit.Assert.fail;
*/
public class SelectTestCase {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private final SelectParser parser = new SelectParser(new ParserEnvironment());
//------------------------------------------------------------------- "where" tests
@Test
- public void test_contains() throws Exception {
- JSONObject json = new JSONObject();
- List<String> contains = Arrays.asList("default", "foo");
- json.put("contains", contains);
+ public void test_contains() {
+ ObjectNode json = jsonMapper.createObjectNode();
+ ArrayNode arrayNode = jsonMapper.createArrayNode();
+ arrayNode.add("default").add("foo");
+ json.set("contains", arrayNode);
assertParse(json.toString(), "default:foo");
}
@@ -77,21 +79,21 @@ public class SelectTestCase {
@Test
public void testOr() throws Exception {
- JSONObject json_two_or = new JSONObject();
- JSONObject json_three_or = new JSONObject();
- List<String> contains1 = Arrays.asList("title", "madonna");
- List<String> contains2 = Arrays.asList("title", "saint");
- List<String> contains3 = Arrays.asList("title", "angel");
-
- JSONObject contains_json1 = new JSONObject();
- JSONObject contains_json2 = new JSONObject();
- JSONObject contains_json3 = new JSONObject();
- contains_json1.put("contains", contains1);
- contains_json2.put("contains", contains2);
- contains_json3.put("contains", contains3);
-
- json_two_or.put("or", Arrays.asList(contains_json1, contains_json2));
- json_three_or.put("or", Arrays.asList(contains_json1, contains_json2, contains_json3));
+ ObjectNode json_two_or = jsonMapper.createObjectNode();
+ ObjectNode json_three_or = jsonMapper.createObjectNode();
+ ArrayNode contains1 = jsonMapper.createArrayNode().add("title").add("madonna");
+ ArrayNode contains2 = jsonMapper.createArrayNode().add("title").add("saint");
+ ArrayNode contains3 = jsonMapper.createArrayNode().add("title").add("angel");
+
+ ObjectNode contains_json1 = jsonMapper.createObjectNode();
+ ObjectNode contains_json2 = jsonMapper.createObjectNode();
+ ObjectNode contains_json3 = jsonMapper.createObjectNode();
+ contains_json1.set("contains", contains1);
+ contains_json2.set("contains", contains2);
+ contains_json3.set("contains", contains3);
+
+ json_two_or.set("or", jsonMapper.createArrayNode().add(contains_json1).add(contains_json2));
+ json_three_or.set("or", jsonMapper.createArrayNode().add(contains_json1).add(contains_json2).add(contains_json3));
assertParse(json_two_or.toString(), "OR title:madonna title:saint");
assertParse(json_three_or.toString(), "OR title:madonna title:saint title:angel");
@@ -99,178 +101,178 @@ public class SelectTestCase {
@Test
public void testAnd() throws Exception{
- JSONObject json_two_and = new JSONObject();
- JSONObject json_three_and = new JSONObject();
- List<String> contains1 = Arrays.asList("title", "madonna");
- List<String> contains2 = Arrays.asList("title", "saint");
- List<String> contains3 = Arrays.asList("title", "angel");
-
- JSONObject contains_json1 = new JSONObject();
- JSONObject contains_json2 = new JSONObject();
- JSONObject contains_json3 = new JSONObject();
- contains_json1.put("contains", contains1);
- contains_json2.put("contains", contains2);
- contains_json3.put("contains", contains3);
-
- json_two_and.put("and", Arrays.asList(contains_json1, contains_json2));
- json_three_and.put("and", Arrays.asList(contains_json1, contains_json2, contains_json3));
+ ObjectNode json_two_and = jsonMapper.createObjectNode();
+ ObjectNode json_three_and = jsonMapper.createObjectNode();
+ ArrayNode contains1 = jsonMapper.createArrayNode().add("title").add("madonna");
+ ArrayNode contains2 = jsonMapper.createArrayNode().add("title").add("saint");
+ ArrayNode contains3 = jsonMapper.createArrayNode().add("title").add("angel");
+
+ ObjectNode contains_json1 = jsonMapper.createObjectNode();
+ ObjectNode contains_json2 = jsonMapper.createObjectNode();
+ ObjectNode contains_json3 = jsonMapper.createObjectNode();
+ contains_json1.set("contains", contains1);
+ contains_json2.set("contains", contains2);
+ contains_json3.set("contains", contains3);
+
+ json_two_and.set("and", jsonMapper.createArrayNode().add(contains_json1).add(contains_json2));
+ json_three_and.set("and", jsonMapper.createArrayNode().add(contains_json1).add(contains_json2).add(contains_json3));
assertParse(json_two_and.toString(), "AND title:madonna title:saint");
assertParse(json_three_and.toString(), "AND title:madonna title:saint title:angel");
}
@Test
- public void testAndNot() throws JSONException {
- JSONObject json_and_not = new JSONObject();
- List<String> contains1 = Arrays.asList("title", "madonna");
- List<String> contains2 = Arrays.asList("title", "saint");
+ public void testAndNot() {
+ ObjectNode json_and_not = jsonMapper.createObjectNode();
+ ArrayNode contains1 = jsonMapper.createArrayNode().add("title").add("madonna");
+ ArrayNode contains2 = jsonMapper.createArrayNode().add("title").add("saint");
- JSONObject contains_json1 = new JSONObject();
- JSONObject contains_json2 = new JSONObject();
- contains_json1.put("contains", contains1);
- contains_json2.put("contains", contains2);
+ ObjectNode contains_json1 = jsonMapper.createObjectNode();
+ ObjectNode contains_json2 = jsonMapper.createObjectNode();
+ contains_json1.set("contains", contains1);
+ contains_json2.set("contains", contains2);
- json_and_not.put("and_not", Arrays.asList(contains_json1, contains_json2));
+ json_and_not.set("and_not", jsonMapper.createArrayNode().add(contains_json1).add(contains_json2));
assertParse(json_and_not.toString(),
"+title:madonna -title:saint");
}
@Test
- public void testLessThan() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testLessThan() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put("<", 500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:<500");
}
@Test
- public void testGreaterThan() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testGreaterThan() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put(">", 500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:>500");
}
@Test
- public void testLessThanOrEqual() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testLessThanOrEqual() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put("<=", 500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:[;500]");
}
@Test
- public void testGreaterThanOrEqual() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testGreaterThanOrEqual() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put(">=", 500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:[500;]");
}
@Test
- public void testEquality() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testEquality() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put("=", 500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:500");
}
@Test
- public void testNegativeLessThan() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testNegativeLessThan() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put("<", -500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:<-500");
}
@Test
- public void testNegativeGreaterThan() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testNegativeGreaterThan() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put(">", -500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:>-500");
}
@Test
- public void testNegativeLessThanOrEqual() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testNegativeLessThanOrEqual() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put("<=", -500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:[;-500]");
}
@Test
- public void testNegativeGreaterThanOrEqual() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testNegativeGreaterThanOrEqual() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put(">=", -500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:[-500;]");
}
@Test
- public void testNegativeEquality() throws JSONException {
- JSONObject range_json = new JSONObject();
- JSONObject operators = new JSONObject();
+ public void testNegativeEquality() {
+ ObjectNode range_json = jsonMapper.createObjectNode();
+ ObjectNode operators = jsonMapper.createObjectNode();
operators.put("=", -500);
- List<Object> range = Arrays.asList("price", operators);
+ ArrayNode range = jsonMapper.createArrayNode().add("price").add(operators);
- range_json.put("range", range);
+ range_json.set("range", range);
assertParse(range_json.toString(),
"price:-500");
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ProtonMetrics.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ProtonMetrics.java
index c6d907ec7fc..ed88902e094 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ProtonMetrics.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ProtonMetrics.java
@@ -1,14 +1,19 @@
package com.yahoo.vespa.hosted.controller.api.application.v4.model;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import java.util.HashMap;
import java.util.Map;
+import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
public class ProtonMetrics {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final Logger logger = LogManager.getLogManager().getLogger(ProtonMetrics.class.getName());
public static final String DOCUMENTS_ACTIVE_COUNT = "documentsActiveCount";
@@ -45,19 +50,19 @@ public class ProtonMetrics {
return this;
}
- public JSONObject toJson() {
+ public JsonNode toJson() {
try {
- JSONObject protonMetrics = new JSONObject();
+ ObjectNode protonMetrics = jsonMapper.createObjectNode();
protonMetrics.put("clusterId", clusterId);
- JSONObject jsonMetrics = new JSONObject();
+ ObjectNode jsonMetrics = jsonMapper.createObjectNode();
for (Map.Entry<String, Double> entry : metrics.entrySet()) {
jsonMetrics.put(entry.getKey(), entry.getValue());
}
- protonMetrics.put("metrics", jsonMetrics);
+ protonMetrics.set("metrics", jsonMetrics);
return protonMetrics;
- } catch (JSONException e) {
- logger.severe("Unable to convert Proton Metrics to JSON Object");
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, "Unable to convert Proton Metrics to JSON Object: " + e.getMessage(), e);
}
- return new JSONObject();
+ return jsonMapper.createObjectNode();
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 5a1496bf507..431a694fcd8 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -2,6 +2,8 @@
package com.yahoo.vespa.hosted.controller.restapi.application;
import ai.vespa.hosted.api.Signatures;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
@@ -100,9 +102,6 @@ import com.yahoo.vespa.hosted.controller.versions.VersionStatus;
import com.yahoo.vespa.hosted.controller.versions.VespaVersion;
import com.yahoo.vespa.serviceview.bindings.ApplicationView;
import com.yahoo.yolean.Exceptions;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.InternalServerErrorException;
@@ -151,6 +150,8 @@ import static java.util.stream.Collectors.toUnmodifiableList;
@SuppressWarnings("unused") // created by injection
public class ApplicationApiHandler extends LoggingRequestHandler {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String OPTIONAL_PREFIX = "/api";
private final Controller controller;
@@ -789,15 +790,15 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
private JsonResponse buildResponseFromProtonMetrics(List<ProtonMetrics> protonMetrics) {
try {
- var jsonObject = new JSONObject();
- var jsonArray = new JSONArray();
+ var jsonObject = jsonMapper.createObjectNode();
+ var jsonArray = jsonMapper.createArrayNode();
for (ProtonMetrics metrics : protonMetrics) {
- jsonArray.put(metrics.toJson());
+ jsonArray.add(metrics.toJson());
}
- jsonObject.put("metrics", jsonArray);
- return new JsonResponse(200, jsonObject.toString());
- } catch (JSONException e) {
- log.severe("Unable to build JsonResponse with Proton data");
+ jsonObject.set("metrics", jsonArray);
+ return new JsonResponse(200, jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject));
+ } catch (JsonProcessingException e) {
+ log.log(Level.SEVERE, "Unable to build JsonResponse with Proton data: " + e.getMessage(), e);
return new JsonResponse(500, "");
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java
index 828e2856cae..c43abf276c5 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.application;
import com.yahoo.component.Version;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.test.json.JsonTestHelper;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
@@ -12,8 +13,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.TestReport;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -180,12 +179,10 @@ public class JobControllerApiHandlerHelperTest {
"jobs-direct-deployment.json");
}
- private void compare(HttpResponse response, String expected) throws JSONException, IOException {
+ private void compare(HttpResponse response, String expected) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.render(baos);
- JSONObject actualJSON = new JSONObject(new String(baos.toByteArray()));
- JSONObject expectedJSON = new JSONObject(expected);
- assertEquals(expectedJSON.toString(), actualJSON.toString());
+ JsonTestHelper.assertJsonEquals(expected, baos.toString());
}
private void assertResponse(HttpResponse response, String fileName) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/proton-metrics.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/proton-metrics.json
index a7e5b3918d8..3fba9b3c91c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/proton-metrics.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/proton-metrics.json
@@ -1,23 +1,26 @@
{
- "metrics": [{
- "clusterId": "content/doc/",
- "metrics": {
- "resourceMemoryUsageAverage": 0.103482,
- "documentsReadyCount": 11430,
- "documentDiskUsage": 44021,
- "resourceDiskUsageAverage": 0.0168421,
- "documentsTotalCount": 11430,
- "documentsActiveCount": 11430
+ "metrics": [
+ {
+ "clusterId": "content/doc/",
+ "metrics": {
+ "resourceMemoryUsageAverage": 0.103482,
+ "documentsReadyCount": 11430.0,
+ "documentDiskUsage": 44021.0,
+ "resourceDiskUsageAverage": 0.0168421,
+ "documentsTotalCount": 11430.0,
+ "documentsActiveCount": 11430.0
+ }
+ },
+ {
+ "clusterId": "content/music/",
+ "metrics": {
+ "resourceMemoryUsageAverage": 0.00912,
+ "documentsReadyCount": 32000.0,
+ "documentDiskUsage": 90113.0,
+ "resourceDiskUsageAverage": 0.23912,
+ "documentsTotalCount": 32210.0,
+ "documentsActiveCount": 32210.0
+ }
}
- }, {
- "clusterId": "content/music/",
- "metrics": {
- "resourceMemoryUsageAverage": 0.00912,
- "documentsReadyCount": 32000,
- "documentDiskUsage": 90113,
- "resourceDiskUsageAverage": 0.23912,
- "documentsTotalCount": 32210,
- "documentsActiveCount": 32210
- }
- }]
-} \ No newline at end of file
+ ]
+}
diff --git a/metrics-proxy/pom.xml b/metrics-proxy/pom.xml
index 8bf5a30e584..90d9f093da1 100644
--- a/metrics-proxy/pom.xml
+++ b/metrics-proxy/pom.xml
@@ -101,11 +101,6 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <scope>provided</scope>
- </dependency>
<!-- compile scope -->
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/node/NodeMetricGatherer.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/node/NodeMetricGatherer.java
index 3cd9f526387..60e8e3deee5 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/node/NodeMetricGatherer.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/node/NodeMetricGatherer.java
@@ -9,13 +9,11 @@ import ai.vespa.metricsproxy.metric.model.MetricsPacket;
import ai.vespa.metricsproxy.metric.model.ServiceId;
import ai.vespa.metricsproxy.service.SystemPollerProvider;
import ai.vespa.metricsproxy.service.VespaServices;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.inject.Inject;
import com.yahoo.container.jdisc.state.CoredumpGatherer;
import com.yahoo.container.jdisc.state.FileWrapper;
import com.yahoo.container.jdisc.state.HostLifeGatherer;
-import com.yahoo.yolean.Exceptions;
-import org.json.JSONException;
-import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
@@ -54,10 +52,10 @@ public class NodeMetricGatherer {
List<MetricsPacket.Builder> metricPacketBuilders = new ArrayList<>();
metricPacketBuilders.addAll(gatherServiceHealthMetrics(vespaServices));
- JSONObject coredumpPacket = CoredumpGatherer.gatherCoredumpMetrics(fileWrapper);
+ JsonNode coredumpPacket = CoredumpGatherer.gatherCoredumpMetrics(fileWrapper);
addObjectToBuilders(metricPacketBuilders, coredumpPacket);
if (SystemPollerProvider.runningOnLinux()) {
- JSONObject packet = HostLifeGatherer.getHostLifePacket(fileWrapper);
+ JsonNode packet = HostLifeGatherer.getHostLifePacket(fileWrapper);
addObjectToBuilders(metricPacketBuilders, packet);
}
@@ -69,24 +67,20 @@ public class NodeMetricGatherer {
).collect(Collectors.toList());
}
- protected static void addObjectToBuilders(List<MetricsPacket.Builder> builders, JSONObject object) {
- try {
- MetricsPacket.Builder builder = new MetricsPacket.Builder(ServiceId.toServiceId(object.getString("application")));
- builder.timestamp(object.getLong("timestamp"));
- if (object.has("status_code")) builder.statusCode(object.getInt("status_code"));
- if (object.has("status_msg")) builder.statusMessage(object.getString("status_msg"));
- if (object.has("metrics")) {
- JSONObject metrics = object.getJSONObject("metrics");
- Iterator<?> keys = metrics.keys();
- while(keys.hasNext()) {
- String key = (String) keys.next();
- builder.putMetric(MetricId.toMetricId(key), metrics.getLong(key));
- }
+ protected static void addObjectToBuilders(List<MetricsPacket.Builder> builders, JsonNode object) {
+ MetricsPacket.Builder builder = new MetricsPacket.Builder(ServiceId.toServiceId(object.get("application").textValue()));
+ builder.timestamp(object.get("timestamp").longValue());
+ if (object.has("status_code")) builder.statusCode(object.get("status_code").intValue());
+ if (object.has("status_msg")) builder.statusMessage(object.get("status_msg").textValue());
+ if (object.has("metrics")) {
+ JsonNode metrics = object.get("metrics");
+ Iterator<?> keys = metrics.fieldNames();
+ while(keys.hasNext()) {
+ String key = (String) keys.next();
+ builder.putMetric(MetricId.toMetricId(key), metrics.get(key).longValue());
}
- builders.add(builder);
- } catch (JSONException e) {
- Exceptions.toMessageString(e);
}
+ builders.add(builder);
}
}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java
index 1cab1a859a9..6e7bb37d761 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java
@@ -2,9 +2,10 @@
package ai.vespa.metricsproxy.service;
import ai.vespa.metricsproxy.metric.HealthMetric;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import java.util.logging.Level;
-import org.json.JSONException;
-import org.json.JSONObject;
import java.io.IOException;
import java.util.logging.Logger;
@@ -15,6 +16,7 @@ import java.util.logging.Logger;
* @author Jo Kristian Bergum
*/
public class RemoteHealthMetricFetcher extends HttpMetricFetcher {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
private final static Logger log = Logger.getLogger(RemoteHealthMetricFetcher.class.getPackage().getName());
private final static String HEALTH_PATH = STATE_PATH + "health";
@@ -54,16 +56,16 @@ public class RemoteHealthMetricFetcher extends HttpMetricFetcher {
return HealthMetric.getUnknown("Empty response from status page");
}
try {
- JSONObject o = new JSONObject(data);
- JSONObject status = o.getJSONObject("status");
- String code = status.getString("code");
+ JsonNode o = jsonMapper.readTree(data);
+ JsonNode status = o.get("status");
+ String code = status.get("code").textValue();
String message = "";
if (status.has("message")) {
- message = status.getString("message");
+ message = status.get("message").textValue();
}
return HealthMetric.get(code, message);
- } catch (JSONException e) {
+ } catch (IOException e) {
log.log(Level.FINE, "Failed to parse json response from metrics page:" + e + ":" + data);
return HealthMetric.getUnknown("Not able to parse json from status page");
}
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
index 442ebc0d38d..c2935761179 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteMetricsFetcher.java
@@ -4,9 +4,9 @@ package ai.vespa.metricsproxy.service;
import ai.vespa.metricsproxy.metric.Metric;
import ai.vespa.metricsproxy.metric.Metrics;
import ai.vespa.metricsproxy.metric.model.DimensionId;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.IOException;
import java.util.Collections;
@@ -23,6 +23,8 @@ import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId;
*/
public class RemoteMetricsFetcher extends HttpMetricFetcher {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
final static String METRICS_PATH = STATE_PATH + "metrics";
RemoteMetricsFetcher(VespaService service, int port) {
@@ -57,21 +59,21 @@ public class RemoteMetricsFetcher extends HttpMetricFetcher {
return remoteMetrics;
}
- private Metrics parse(String data) throws JSONException {
- JSONObject o = new JSONObject(data);
+ private Metrics parse(String data) throws IOException {
+ JsonNode o = jsonMapper.readTree(data);
if (!(o.has("metrics"))) {
return new Metrics(); //empty
}
- JSONObject metrics = o.getJSONObject("metrics");
- JSONArray values;
+ JsonNode metrics = o.get("metrics");
+ ArrayNode values;
long timestamp;
try {
- JSONObject snapshot = metrics.getJSONObject("snapshot");
- timestamp = (long) snapshot.getDouble("to");
- values = metrics.getJSONArray("values");
- } catch (JSONException e) {
+ JsonNode snapshot = metrics.get("snapshot");
+ timestamp = (long) snapshot.get("to").doubleValue();
+ values = (ArrayNode) metrics.get("values");
+ } catch (Exception e) {
// snapshot might not have been produced. Do not throw exception into log
return new Metrics();
}
@@ -81,29 +83,29 @@ public class RemoteMetricsFetcher extends HttpMetricFetcher {
Map<DimensionId, String> noDims = Collections.emptyMap();
Map<String, Map<DimensionId, String>> uniqueDimensions = new HashMap<>();
- for (int i = 0; i < values.length(); i++) {
- JSONObject metric = values.getJSONObject(i);
- String name = metric.getString("name");
+ for (int i = 0; i < values.size(); i++) {
+ JsonNode metric = values.get(i);
+ String name = metric.get("name").textValue();
String description = "";
if (metric.has("description")) {
- description = metric.getString("description");
+ description = metric.get("description").textValue();
}
Map<DimensionId, String> dim = noDims;
if (metric.has("dimensions")) {
- JSONObject dimensions = metric.getJSONObject("dimensions");
+ JsonNode dimensions = metric.get("dimensions");
StringBuilder sb = new StringBuilder();
- for (Iterator<?> it = dimensions.keys(); it.hasNext(); ) {
+ for (Iterator<?> it = dimensions.fieldNames(); it.hasNext(); ) {
String k = (String) it.next();
- String v = dimensions.getString(k);
+ String v = dimensions.get(k).textValue();
sb.append(toDimensionId(k)).append(v);
}
if ( ! uniqueDimensions.containsKey(sb.toString())) {
dim = new HashMap<>();
- for (Iterator<?> it = dimensions.keys(); it.hasNext(); ) {
+ for (Iterator<?> it = dimensions.fieldNames(); it.hasNext(); ) {
String k = (String) it.next();
- String v = dimensions.getString(k);
+ String v = dimensions.get(k).textValue();
dim.put(toDimensionId(k), v);
}
uniqueDimensions.put(sb.toString(), Collections.unmodifiableMap(dim));
@@ -111,10 +113,11 @@ public class RemoteMetricsFetcher extends HttpMetricFetcher {
dim = uniqueDimensions.get(sb.toString());
}
- JSONObject aggregates = metric.getJSONObject("values");
- for (Iterator<?> it = aggregates.keys(); it.hasNext(); ) {
+ JsonNode aggregates = metric.get("values");
+ for (Iterator<?> it = aggregates.fieldNames(); it.hasNext(); ) {
String aggregator = (String) it.next();
- Number value = (Number) aggregates.get(aggregator);
+ Number value = aggregates.get(aggregator).numberValue();
+ if (value == null) throw new IllegalArgumentException("Value for aggregator '" + aggregator + "' is missing");
StringBuilder metricName = (new StringBuilder()).append(name).append(".").append(aggregator);
m.add(new Metric(metricName.toString(), value, timestamp, dim, description));
}
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java
index d7576718e8a..cf1eac3c691 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java
@@ -8,13 +8,11 @@ import ai.vespa.metricsproxy.metric.model.json.GenericApplicationModel;
import ai.vespa.metricsproxy.metric.model.json.GenericJsonModel;
import ai.vespa.metricsproxy.metric.model.json.GenericMetrics;
import ai.vespa.metricsproxy.metric.model.json.GenericService;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.yahoo.container.jdisc.RequestHandlerTestDriver;
-import java.util.regex.Pattern;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
@@ -24,6 +22,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Executors;
+import java.util.regex.Pattern;
import static ai.vespa.metricsproxy.TestUtil.getFileContents;
import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId;
@@ -49,6 +48,8 @@ import static org.junit.Assert.fail;
@SuppressWarnings("UnstableApiUsage")
public class ApplicationMetricsHandlerTest {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String HOST = "localhost";
private static final String URI_BASE = "http://" + HOST;
private static final String METRICS_V1_URI = URI_BASE + METRICS_V1_PATH;
@@ -102,16 +103,16 @@ public class ApplicationMetricsHandlerTest {
@Test
public void v1_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(METRICS_V1_URI).readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("resources"));
- JSONArray resources = root.getJSONArray("resources");
- assertEquals(2, resources.length());
+ ArrayNode resources = (ArrayNode) root.get("resources");
+ assertEquals(2, resources.size());
- JSONObject valuesUrl = resources.getJSONObject(0);
- assertEquals(METRICS_VALUES_URI, valuesUrl.getString("url"));
- JSONObject prometheusUrl = resources.getJSONObject(1);
- assertEquals(PROMETHEUS_VALUES_URI, prometheusUrl.getString("url"));
+ JsonNode valuesUrl = resources.get(0);
+ assertEquals(METRICS_VALUES_URI, valuesUrl.get("url").textValue());
+ JsonNode prometheusUrl = resources.get(1);
+ assertEquals(PROMETHEUS_VALUES_URI, prometheusUrl.get("url").textValue());
}
@Ignore
@@ -199,7 +200,7 @@ public class ApplicationMetricsHandlerTest {
@Test
public void invalid_path_yields_error_response() throws Exception {
String response = testDriver.sendRequest(METRICS_V1_URI + "/invalid").readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("error"));
}
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java
index 1c5ce695155..379ef04d38d 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java
@@ -6,9 +6,9 @@ import ai.vespa.metricsproxy.metric.model.json.GenericJsonModel;
import ai.vespa.metricsproxy.metric.model.json.GenericMetrics;
import ai.vespa.metricsproxy.metric.model.json.GenericService;
import ai.vespa.metricsproxy.service.DownService;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.json.JSONArray;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import org.junit.Ignore;
import org.junit.Test;
@@ -32,6 +32,8 @@ import static org.junit.Assert.fail;
*/
public abstract class MetricsHandlerTestBase<MODEL> extends HttpHandlerTestBase {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
static String rootUri;
static String valuesUri;
@@ -56,21 +58,21 @@ public abstract class MetricsHandlerTestBase<MODEL> extends HttpHandlerTestBase
@Test
public void invalid_path_yields_error_response() throws Exception {
String response = testDriver.sendRequest(rootUri + "/invalid").readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("error"));
}
@Test
public void root_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(rootUri).readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("resources"));
- JSONArray resources = root.getJSONArray("resources");
- assertEquals(1, resources.length());
+ ArrayNode resources = (ArrayNode) root.get("resources");
+ assertEquals(1, resources.size());
- JSONObject valuesUrl = resources.getJSONObject(0);
- assertEquals(valuesUri, valuesUrl.getString("url"));
+ JsonNode valuesUrl = resources.get(0);
+ assertEquals(valuesUri, valuesUrl.get("url").textValue());
}
@Ignore
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java
index a224c4090b3..89186e63b93 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java
@@ -3,9 +3,10 @@ package ai.vespa.metricsproxy.http.prometheus;
import ai.vespa.metricsproxy.http.HttpHandlerTestBase;
import ai.vespa.metricsproxy.service.DummyService;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.yahoo.container.jdisc.RequestHandlerTestDriver;
-import org.json.JSONArray;
-import org.json.JSONObject;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -22,6 +23,8 @@ import static org.junit.Assert.assertTrue;
@SuppressWarnings("UnstableApiUsage")
public class PrometheusHandlerTest extends HttpHandlerTestBase {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String V1_URI = URI_BASE + PrometheusHandler.V1_PATH;
private static final String VALUES_URI = URI_BASE + PrometheusHandler.VALUES_PATH;
@@ -40,14 +43,14 @@ public class PrometheusHandlerTest extends HttpHandlerTestBase {
@Test
public void v1_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(V1_URI).readAll();
- JSONObject root = new JSONObject(response);
+ JsonNode root = jsonMapper.readTree(response);
assertTrue(root.has("resources"));
- JSONArray resources = root.getJSONArray("resources");
- assertEquals(1, resources.length());
+ ArrayNode resources = (ArrayNode) root.get("resources");
+ assertEquals(1, resources.size());
- JSONObject valuesUrl = resources.getJSONObject(0);
- assertEquals(VALUES_URI, valuesUrl.getString("url"));
+ JsonNode valuesUrl = resources.get(0);
+ assertEquals(VALUES_URI, valuesUrl.get("url").textValue());
}
@Ignore
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java
index e2ad0ccd504..c2fc23a878d 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java
@@ -3,8 +3,9 @@ package ai.vespa.metricsproxy.node;
import ai.vespa.metricsproxy.metric.model.MetricId;
import ai.vespa.metricsproxy.metric.model.MetricsPacket;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Test;
import java.util.ArrayList;
@@ -17,10 +18,12 @@ import static org.junit.Assert.assertEquals;
*/
public class NodeMetricGathererTest {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
@Test
- public void testJSONObjectIsCorrectlyConvertedToMetricsPacket() throws JSONException {
+ public void testJSONObjectIsCorrectlyConvertedToMetricsPacket() {
List<MetricsPacket.Builder> builders = new ArrayList<>();
- JSONObject hostLifePacket = generateHostLifePacket();
+ JsonNode hostLifePacket = generateHostLifePacket();
NodeMetricGatherer.addObjectToBuilders(builders, hostLifePacket);
MetricsPacket packet = builders.remove(0).build();
@@ -32,17 +35,17 @@ public class NodeMetricGathererTest {
assertEquals(1l, packet.metrics().get(MetricId.toMetricId("alive")));
}
- private JSONObject generateHostLifePacket() throws JSONException {
+ private JsonNode generateHostLifePacket() {
- JSONObject jsonObject = new JSONObject();
+ ObjectNode jsonObject = jsonMapper.createObjectNode();
jsonObject.put("status_code", 0);
jsonObject.put("status_msg", "OK");
jsonObject.put("timestamp", 123);
jsonObject.put("application", "host_life");
- JSONObject metrics = new JSONObject();
+ ObjectNode metrics = jsonMapper.createObjectNode();
metrics.put("uptime", 12);
metrics.put("alive", 1);
- jsonObject.put("metrics", metrics);
+ jsonObject.set("metrics", metrics);
return jsonObject;
}
}
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java
index 8d5bba77844..70970bfe8da 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java
@@ -5,17 +5,18 @@ import ai.vespa.metricsproxy.metric.Metric;
import ai.vespa.metricsproxy.metric.Metrics;
import ai.vespa.metricsproxy.metric.model.ConsumerId;
import ai.vespa.metricsproxy.service.VespaService;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.yahoo.jrt.Request;
import com.yahoo.jrt.Spec;
import com.yahoo.jrt.StringValue;
import com.yahoo.jrt.Supervisor;
import com.yahoo.jrt.Target;
import com.yahoo.jrt.Transport;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.Test;
+import java.io.IOException;
import java.util.List;
import static ai.vespa.metricsproxy.TestUtil.getFileContents;
@@ -40,6 +41,8 @@ import static org.junit.Assert.assertTrue;
*/
public class RpcMetricsTest {
+ private static final ObjectMapper jsonMapper = new ObjectMapper();
+
private static final String METRICS_RESPONSE = getFileContents("metrics-storage-simple.json").trim();
private static final String EXTRA_APP = "extra";
@@ -67,9 +70,9 @@ public class RpcMetricsTest {
String allServicesResponse = getMetricsForYamas(ALL_SERVICES, rpcClient).trim();
// Verify that application is used as serviceId, and that metric exists.
- JSONObject extraMetrics = findExtraMetricsObject(allServicesResponse);
- assertThat(extraMetrics.getJSONObject("metrics").getInt("foo.count"), is(3));
- assertThat(extraMetrics.getJSONObject("dimensions").getString("role"), is("extra-role"));
+ JsonNode extraMetrics = findExtraMetricsObject(allServicesResponse);
+ assertThat(extraMetrics.get("metrics").get("foo.count").intValue(), is(3));
+ assertThat(extraMetrics.get("dimensions").get("role").textValue(), is("extra-role"));
}
}
}
@@ -85,7 +88,7 @@ public class RpcMetricsTest {
// Verify that no extra metrics exists
String allServicesResponse = getMetricsForYamas(ALL_SERVICES, rpcClient).trim();
- JSONObject extraMetrics = findExtraMetricsObject(allServicesResponse);
+ JsonNode extraMetrics = findExtraMetricsObject(allServicesResponse);
assertEquals(extraMetrics.toString(), "{}");
}
}
@@ -130,28 +133,28 @@ public class RpcMetricsTest {
}
}
- private static void verifyMetricsFromRpcRequest(VespaService service, RpcClient client) throws JSONException {
+ private static void verifyMetricsFromRpcRequest(VespaService service, RpcClient client) throws IOException {
String jsonResponse = getMetricsForYamas(service.getMonitoringName(), client).trim();
- JSONArray metrics = new JSONObject(jsonResponse).getJSONArray("metrics");
- assertThat("Expected 3 metric messages", metrics.length(), is(3));
- for (int i = 0; i < metrics.length() - 1; i++) { // The last "metric message" contains only status code/message
- JSONObject jsonObject = metrics.getJSONObject(i);
+ ArrayNode metrics = (ArrayNode) jsonMapper.readTree(jsonResponse).get("metrics");
+ assertThat("Expected 3 metric messages", metrics.size(), is(3));
+ for (int i = 0; i < metrics.size() - 1; i++) { // The last "metric message" contains only status code/message
+ JsonNode jsonObject = metrics.get(i);
assertFalse(jsonObject.has("status_code"));
assertFalse(jsonObject.has("status_msg"));
- assertThat(jsonObject.getJSONObject("dimensions").getString("foo"), is("bar"));
- assertThat(jsonObject.getJSONObject("dimensions").getString("bar"), is("foo"));
- assertThat(jsonObject.getJSONObject("dimensions").getString("serviceDim"), is("serviceDimValue"));
- assertThat(jsonObject.getJSONObject("routing").getJSONObject("yamas").getJSONArray("namespaces").length(), is(1));
- if (jsonObject.getJSONObject("metrics").has("foo_count")) {
- assertThat(jsonObject.getJSONObject("metrics").getInt("foo_count"), is(1));
- assertThat(jsonObject.getJSONObject("routing").getJSONObject("yamas").getJSONArray("namespaces").get(0), is(vespaMetricsConsumerId.id));
+ assertThat(jsonObject.get("dimensions").get("foo").textValue(), is("bar"));
+ assertThat(jsonObject.get("dimensions").get("bar").textValue(), is("foo"));
+ assertThat(jsonObject.get("dimensions").get("serviceDim").textValue(), is("serviceDimValue"));
+ assertThat(jsonObject.get("routing").get("yamas").get("namespaces").size(), is(1));
+ if (jsonObject.get("metrics").has("foo_count")) {
+ assertThat(jsonObject.get("metrics").get("foo_count").intValue(), is(1));
+ assertThat(jsonObject.get("routing").get("yamas").get("namespaces").get(0).textValue(), is(vespaMetricsConsumerId.id));
} else {
- assertThat(jsonObject.getJSONObject("metrics").getInt("foo.count"), is(1));
- assertThat(jsonObject.getJSONObject("routing").getJSONObject("yamas").getJSONArray("namespaces").get(0), is(CUSTOM_CONSUMER_ID.id));
+ assertThat(jsonObject.get("metrics").get("foo.count").intValue(), is(1));
+ assertThat(jsonObject.get("routing").get("yamas").get("namespaces").get(0).textValue(), is(CUSTOM_CONSUMER_ID.id));
}
}
- verifyStatusMessage(metrics.getJSONObject(metrics.length() - 1));
+ verifyStatusMessage(metrics.get(metrics.size() - 1));
}
private void verfiyMetricsFromServiceObject(VespaService service) {
@@ -166,15 +169,15 @@ public class RpcMetricsTest {
assertThat("Metric foo did not contain correct dimension for key = bar", foo.getDimensions().get(toDimensionId("bar")), is("foo"));
}
- private void verifyMetricsFromRpcRequestForAllServices(RpcClient client) throws JSONException {
+ private void verifyMetricsFromRpcRequestForAllServices(RpcClient client) throws IOException {
// Verify that metrics for all services can be retrieved in one request.
String allServicesResponse = getMetricsForYamas(ALL_SERVICES, client).trim();
- JSONArray allServicesMetrics = new JSONObject(allServicesResponse).getJSONArray("metrics");
- assertThat(allServicesMetrics.length(), is(5));
+ ArrayNode allServicesMetrics = (ArrayNode) jsonMapper.readTree(allServicesResponse).get("metrics");
+ assertThat(allServicesMetrics.size(), is(5));
}
@Test
- public void testGetAllMetricNames() throws Exception {
+ public void testGetAllMetricNames() {
try (IntegrationTester tester = new IntegrationTester()) {
tester.httpServer().setResponse(METRICS_RESPONSE);
@@ -205,14 +208,14 @@ public class RpcMetricsTest {
invoke(req, rpcClient, false);
}
- private JSONObject findExtraMetricsObject(String jsonResponse) throws JSONException {
- JSONArray metrics = new JSONObject(jsonResponse).getJSONArray("metrics");
- for (int i = 0; i < metrics.length(); i++) {
- JSONObject jsonObject = metrics.getJSONObject(i);
+ private JsonNode findExtraMetricsObject(String jsonResponse) throws IOException {
+ ArrayNode metrics = (ArrayNode) jsonMapper.readTree(jsonResponse).get("metrics");
+ for (int i = 0; i < metrics.size(); i++) {
+ JsonNode jsonObject = metrics.get(i);
assertTrue(jsonObject.has("application"));
- if (jsonObject.getString("application").equals(EXTRA_APP)) return jsonObject;
+ if (jsonObject.get("application").textValue().equals(EXTRA_APP)) return jsonObject;
}
- return new JSONObject();
+ return jsonMapper.createObjectNode();
}
private static String getMetricsForYamas(String service, RpcClient client) {
@@ -250,12 +253,12 @@ public class RpcMetricsTest {
return returnValue;
}
- private static void verifyStatusMessage(JSONObject jsonObject) throws JSONException {
- assertThat(jsonObject.getInt("status_code"), is(0));
- assertThat(jsonObject.getString("status_msg"), notNullValue());
- assertThat(jsonObject.getString("application"), notNullValue());
- assertThat(jsonObject.getString("routing"), notNullValue());
- assertThat(jsonObject.length(), is(4));
+ private static void verifyStatusMessage(JsonNode jsonObject) {
+ assertThat(jsonObject.get("status_code").intValue(), is(0));
+ assertThat(jsonObject.get("status_msg").textValue(), notNullValue());
+ assertThat(jsonObject.get("application").textValue(), notNullValue());
+ assertThat(jsonObject.get("routing"), notNullValue());
+ assertThat(jsonObject.size(), is(4));
}
}
diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/service/ContainerServiceTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/service/ContainerServiceTest.java
index 0d53f988ac7..7ff179e5528 100644
--- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/service/ContainerServiceTest.java
+++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/service/ContainerServiceTest.java
@@ -2,7 +2,6 @@
package ai.vespa.metricsproxy.service;
import ai.vespa.metricsproxy.metric.Metric;
-import org.json.JSONException;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -37,7 +36,7 @@ public class ContainerServiceTest {
}
@Test
- public void testMultipleQueryDimensions() throws JSONException {
+ public void testMultipleQueryDimensions() {
int count = 0;
VespaService service = VespaService.create("service1", "id", httpServer.port());
for (Metric m : service.getMetrics().getMetrics()) {