summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorn.christian@seime.no>2021-02-01 23:51:00 +0100
committerGitHub <noreply@github.com>2021-02-01 23:51:00 +0100
commit42794e42e8ce223705e0a8e0e3e9293d65adaf6c (patch)
treea337188686fe568fd0dc04db5234c7ffa2ccbb63 /container-core
parent7f04da806204b7727f377b4099bd10571c61e5da (diff)
Revert "Remove org.json usage [run-systemtest]"
Diffstat (limited to 'container-core')
-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
14 files changed, 289 insertions, 218 deletions
diff --git a/container-core/pom.xml b/container-core/pom.xml
index 051b572b28f..7c98b524c73 100644
--- a/container-core/pom.xml
+++ b/container-core/pom.xml
@@ -42,7 +42,6 @@
<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 8c902f88e38..92840cee48f 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,14 +1,13 @@
// 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;
@@ -27,8 +26,6 @@ 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);
}
@@ -52,14 +49,15 @@ public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler {
protected JsonResponse resourceListResponse(URI requestUri, List<String> resources) {
try {
return new JsonResponse(OK, resourceList(requestUri, resources));
- } catch (JsonProcessingException e) {
+ } catch (JSONException 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.");
}
}
- private static String resourceList(URI requestUri, List<String> resources) throws JsonProcessingException {
+ // TODO: Use jackson with a "Resources" class instead of JSONObject
+ private static String resourceList(URI requestUri, List<String> resources) throws JSONException {
int port = requestUri.getPort();
String host = requestUri.getHost();
StringBuilder base = new StringBuilder("http://");
@@ -68,14 +66,13 @@ public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler {
base.append(":").append(port);
}
String uriBase = base.toString();
- ArrayNode linkList = jsonMapper.createArrayNode();
+ JSONArray linkList = new JSONArray();
for (String api : resources) {
- ObjectNode resource = jsonMapper.createObjectNode();
+ JSONObject resource = new JSONObject();
resource.put("url", uriBase + api);
- linkList.add(resource);
+ linkList.put(resource);
}
- return jsonMapper.writerWithDefaultPrettyPrinter()
- .writeValueAsString(jsonMapper.createObjectNode().set("resources", linkList));
+ return new JSONObject().put("resources", linkList).toString(4);
}
}
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 f1ef7894511..d105eaa9d98 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,16 +1,17 @@
// 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;
/**
@@ -18,17 +19,19 @@ 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 JsonNode gatherCoredumpMetrics(FileWrapper fileWrapper) {
+ public static JSONObject gatherCoredumpMetrics(FileWrapper fileWrapper) {
int coredumps = getNumberOfCoredumps(fileWrapper);
- 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");
+ 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) {}
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 28f99096d84..730f7bc13cd 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,9 +1,8 @@
// 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 org.json.JSONException;
+import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Path;
@@ -14,11 +13,9 @@ 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 JsonNode getHostLifePacket(FileWrapper fileWrapper) {
+ public static JSONObject getHostLifePacket(FileWrapper fileWrapper) {
long upTime;
int statusCode = 0;
String statusMessage = "OK";
@@ -32,15 +29,19 @@ public class HostLifeGatherer {
}
- 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);
+ 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) {}
+
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
new file mode 100644
index 00000000000..d22dd9d6f4b
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/JSONObjectWithLegibleException.java
@@ -0,0 +1,87 @@
+// 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 add69403455..6a06a6362f5 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 com.fasterxml.jackson.databind.JsonNode;
+import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@@ -13,9 +13,9 @@ import java.util.List;
*/
public class MetricGatherer {
- static List<JsonNode> getAdditionalMetrics() {
+ static List<JSONObject> getAdditionalMetrics() {
FileWrapper fileWrapper = new FileWrapper();
- List<JsonNode> packetList = new ArrayList<>();
+ List<JSONObject> 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 e8d829eafb1..3d3f0e4b677 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,11 +1,6 @@
// 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;
@@ -18,6 +13,9 @@ 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;
@@ -46,8 +44,6 @@ 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";
@@ -101,19 +97,19 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
}
String output = jsonToString(getStatusPacket()) + getAllMetricsPackets() + "\n";
return output.getBytes(StandardCharsets.UTF_8);
- } catch (JsonProcessingException e) {
+ } catch (JSONException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
- private byte[] getMetricsArray() throws JsonProcessingException {
- ObjectNode root = jsonMapper.createObjectNode();
- ArrayNode jsonArray = jsonMapper.createArrayNode();
- jsonArray.add(getStatusPacket());
+ private byte[] getMetricsArray() throws JSONException {
+ JSONObject root = new JSONObject();
+ JSONArray jsonArray = new JSONArray();
+ jsonArray.put(getStatusPacket());
getPacketsForSnapshot(getSnapshot(), applicationName, timer.currentTimeMillis())
- .forEach(jsonArray::add);
- MetricGatherer.getAdditionalMetrics().forEach(jsonArray::add);
- root.set("metrics", jsonArray);
+ .forEach(jsonArray::put);
+ MetricGatherer.getAdditionalMetrics().forEach(jsonArray::put);
+ root.put("metrics", jsonArray);
return jsonToString(root)
.getBytes(StandardCharsets.UTF_8);
}
@@ -121,8 +117,8 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
/**
* Exactly one status packet is added to the response.
*/
- private JsonNode getStatusPacket() {
- ObjectNode packet = jsonMapper.createObjectNode();
+ private JSONObject getStatusPacket() throws JSONException {
+ JSONObject packet = new JSONObjectWithLegibleException();
packet.put(APPLICATION_KEY, applicationName);
StateMonitor.Status status = monitor.status();
@@ -131,15 +127,14 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
return packet;
}
- private static String jsonToString(JsonNode jsonObject) throws JsonProcessingException {
- return jsonMapper.writerWithDefaultPrettyPrinter()
- .writeValueAsString(jsonObject);
+ private String jsonToString(JSONObject jsonObject) throws JSONException {
+ return jsonObject.toString(4);
}
- private String getAllMetricsPackets() throws JsonProcessingException {
+ private String getAllMetricsPackets() throws JSONException {
StringBuilder ret = new StringBuilder();
- List<JsonNode> metricsPackets = getPacketsForSnapshot(getSnapshot(), applicationName, timer.currentTimeMillis());
- for (JsonNode packet : metricsPackets) {
+ List<JSONObject> metricsPackets = getPacketsForSnapshot(getSnapshot(), applicationName, timer.currentTimeMillis());
+ for (JSONObject packet : metricsPackets) {
ret.append(PACKET_SEPARATOR); // For legibility and parsing in unit tests
ret.append(jsonToString(packet));
}
@@ -155,16 +150,16 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
}
}
- private List<JsonNode> getPacketsForSnapshot(MetricSnapshot metricSnapshot, String application, long timestamp) {
+ private List<JSONObject> getPacketsForSnapshot(MetricSnapshot metricSnapshot, String application, long timestamp) throws JSONException {
if (metricSnapshot == null) return Collections.emptyList();
- List<JsonNode> packets = new ArrayList<>();
+ List<JSONObject> packets = new ArrayList<>();
for (Map.Entry<MetricDimensions, MetricSet> snapshotEntry : metricSnapshot) {
MetricDimensions metricDimensions = snapshotEntry.getKey();
MetricSet metricSet = snapshotEntry.getValue();
- ObjectNode packet = jsonMapper.createObjectNode();
+ JSONObjectWithLegibleException packet = new JSONObjectWithLegibleException();
addMetaData(timestamp, application, packet);
addDimensions(metricDimensions, packet);
addMetrics(metricSet, packet);
@@ -173,27 +168,27 @@ public class MetricsPacketsHandler extends AbstractRequestHandler {
return packets;
}
- private void addMetaData(long timestamp, String application, ObjectNode packet) {
+ private void addMetaData(long timestamp, String application, JSONObjectWithLegibleException packet) {
packet.put(APPLICATION_KEY, application);
packet.put(TIMESTAMP_KEY, TimeUnit.MILLISECONDS.toSeconds(timestamp));
}
- private void addDimensions(MetricDimensions metricDimensions, ObjectNode packet) {
+ private void addDimensions(MetricDimensions metricDimensions, JSONObjectWithLegibleException packet) throws JSONException {
if (metricDimensions == null) return;
Iterator<Map.Entry<String, String>> dimensionsIterator = metricDimensions.iterator();
if (dimensionsIterator.hasNext()) {
- ObjectNode jsonDim = jsonMapper.createObjectNode();
- packet.set(DIMENSIONS_KEY, jsonDim);
+ JSONObject jsonDim = new JSONObjectWithLegibleException();
+ packet.put(DIMENSIONS_KEY, jsonDim);
for (Map.Entry<String, String> dimensionEntry : metricDimensions) {
jsonDim.put(dimensionEntry.getKey(), dimensionEntry.getValue());
}
}
}
- private void addMetrics(MetricSet metricSet, ObjectNode packet) {
- ObjectNode metrics = jsonMapper.createObjectNode();
- packet.set(METRICS_KEY, metrics);
+ private void addMetrics(MetricSet metricSet, JSONObjectWithLegibleException packet) throws JSONException {
+ JSONObjectWithLegibleException metrics = new JSONObjectWithLegibleException();
+ packet.put(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 1eb34e15258..b14dc50edcb 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,11 +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.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;
@@ -21,16 +16,21 @@ import com.yahoo.jdisc.handler.ResponseHandler;
import com.yahoo.jdisc.http.HttpHeaders;
import com.yahoo.metrics.MetricsPresentationConfig;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
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,8 +39,6 @@ import java.util.concurrent.TimeUnit;
*/
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";
@@ -126,16 +124,17 @@ public class StateHandler extends AbstractRequestHandler {
}
base.append(STATE_API_ROOT);
String uriBase = base.toString();
- ArrayNode linkList = jsonMapper.createArrayNode();
+ JSONArray linkList = new JSONArray();
for (String api : new String[] {METRICS_PATH, CONFIG_GENERATION_PATH, HEALTH_PATH, VERSION_PATH}) {
- ObjectNode resource = jsonMapper.createObjectNode();
+ JSONObject resource = new JSONObject();
resource.put("url", uriBase + "/" + api);
- linkList.add(resource);
+ linkList.put(resource);
}
- JsonNode resources = jsonMapper.createObjectNode().set("resources", linkList);
- return toPrettyString(resources);
- } catch (JsonProcessingException e) {
- throw new RuntimeException("Bad JSON construction", e);
+ return new JSONObjectWithLegibleException()
+ .put("resources", linkList)
+ .toString(4).getBytes(StandardCharsets.UTF_8);
+ } catch (JSONException e) {
+ throw new RuntimeException("Bad JSON construction.", e);
}
}
@@ -155,31 +154,31 @@ public class StateHandler extends AbstractRequestHandler {
private static byte[] buildConfigOutput(ApplicationMetadataConfig config) {
try {
- 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) {
+ 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) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
private static byte[] buildVersionOutput() {
try {
- return toPrettyString(
- jsonMapper.createObjectNode()
- .put("version", Vtag.currentVersion.toString()));
- } catch (JsonProcessingException e) {
+ return new JSONObjectWithLegibleException()
+ .put("version", Vtag.currentVersion)
+ .toString(4).getBytes(StandardCharsets.UTF_8);
+ } catch (JSONException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
private byte[] buildMetricOutput(String consumer) {
try {
- return toPrettyString(buildJsonForConsumer(consumer));
- } catch (JsonProcessingException e) {
+ return buildJsonForConsumer(consumer).toString(4).getBytes(StandardCharsets.UTF_8);
+ } catch (JSONException e) {
throw new RuntimeException("Bad JSON construction.", e);
}
}
@@ -192,11 +191,11 @@ public class StateHandler extends AbstractRequestHandler {
return baos.toByteArray();
}
- private ObjectNode buildJsonForConsumer(String consumer) {
- ObjectNode ret = jsonMapper.createObjectNode();
+ private JSONObjectWithLegibleException buildJsonForConsumer(String consumer) throws JSONException {
+ JSONObjectWithLegibleException ret = new JSONObjectWithLegibleException();
ret.put("time", timer.currentTimeMillis());
- ret.set("status", jsonMapper.createObjectNode().put("code", getStatus().name()));
- ret.set(METRICS_PATH, buildJsonForSnapshot(consumer, getSnapshot()));
+ ret.put("status", new JSONObjectWithLegibleException().put("code", getStatus().name()));
+ ret.put(METRICS_PATH, buildJsonForSnapshot(consumer, getSnapshot()));
return ret;
}
@@ -213,12 +212,12 @@ public class StateHandler extends AbstractRequestHandler {
return monitor.status();
}
- private ObjectNode buildJsonForSnapshot(String consumer, MetricSnapshot metricSnapshot) {
+ private JSONObjectWithLegibleException buildJsonForSnapshot(String consumer, MetricSnapshot metricSnapshot) throws JSONException {
if (metricSnapshot == null) {
- return jsonMapper.createObjectNode();
+ return new JSONObjectWithLegibleException();
}
- ObjectNode jsonMetric = jsonMapper.createObjectNode();
- jsonMetric.set("snapshot", jsonMapper.createObjectNode()
+ JSONObjectWithLegibleException jsonMetric = new JSONObjectWithLegibleException();
+ jsonMetric.put("snapshot", new JSONObjectWithLegibleException()
.put("from", metricSnapshot.getFromTime(TimeUnit.MILLISECONDS) / 1000.0)
.put("to", metricSnapshot.getToTime(TimeUnit.MILLISECONDS) / 1000.0));
@@ -226,16 +225,16 @@ public class StateHandler extends AbstractRequestHandler {
long periodInMillis = metricSnapshot.getToTime(TimeUnit.MILLISECONDS) -
metricSnapshot.getFromTime(TimeUnit.MILLISECONDS);
for (Tuple tuple : collapseMetrics(metricSnapshot, consumer)) {
- ObjectNode jsonTuple = jsonMapper.createObjectNode();
+ JSONObjectWithLegibleException jsonTuple = new JSONObjectWithLegibleException();
jsonTuple.put("name", tuple.key);
if (tuple.val instanceof CountMetric) {
CountMetric count = (CountMetric)tuple.val;
- jsonTuple.set("values", jsonMapper.createObjectNode()
+ jsonTuple.put("values", new JSONObjectWithLegibleException()
.put("count", count.getCount())
.put("rate", (count.getCount() * 1000.0) / periodInMillis));
} else if (tuple.val instanceof GaugeMetric) {
GaugeMetric gauge = (GaugeMetric) tuple.val;
- ObjectNode valueFields = jsonMapper.createObjectNode();
+ JSONObjectWithLegibleException valueFields = new JSONObjectWithLegibleException();
valueFields.put("average", gauge.getAverage())
.put("sum", gauge.getSum())
.put("count", gauge.getCount())
@@ -248,27 +247,22 @@ public class StateHandler extends AbstractRequestHandler {
valueFields.put(prefixAndValue.first + "percentile", prefixAndValue.second.doubleValue());
}
}
- jsonTuple.set("values", valueFields);
+ jsonTuple.put("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) {
- ObjectNode jsonDim = jsonMapper.createObjectNode();
+ JSONObjectWithLegibleException jsonDim = new JSONObjectWithLegibleException();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
jsonDim.put(entry.getKey(), entry.getValue());
}
- jsonTuple.set("dimensions", jsonDim);
+ jsonTuple.put("dimensions", jsonDim);
}
}
- ArrayNode values = (ArrayNode) jsonMetric.get("values");
- if (values == null) {
- values = jsonMapper.createArrayNode();
- jsonMetric.set("values", values);
- }
- values.add(jsonTuple);
+ jsonMetric.append("values", jsonTuple);
}
return jsonMetric;
}
@@ -322,12 +316,6 @@ 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 7ca9fe91e31..44630ad235a 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 ca4bec30322..9020ed91026 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,18 +1,17 @@
// 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;
@@ -35,8 +34,6 @@ 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;
@@ -82,29 +79,29 @@ public class MetricsV2HandlerTest {
@Test
public void v2_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(V2_URI).readAll();
- JsonNode root = jsonMapper.readTree(response);
+ JSONObject root = new JSONObject(response);
assertTrue(root.has("resources"));
- ArrayNode resources = (ArrayNode) root.get("resources");
- assertEquals(1, resources.size());
+ JSONArray resources = root.getJSONArray("resources");
+ assertEquals(1, resources.length());
- JsonNode valuesUri = resources.get(0);
- assertEquals(VALUES_URI, valuesUri.get("url").textValue());
+ JSONObject valuesUri = resources.getJSONObject(0);
+ assertEquals(VALUES_URI, valuesUri.getString("url"));
}
@Ignore
@Test
- public void visually_inspect_values_response() {
- JsonNode responseJson = getResponseAsJson(null);
- System.out.println(responseJson);
+ public void visually_inspect_values_response() throws Exception {
+ JSONObject responseJson = getResponseAsJson(null);
+ System.out.println(responseJson.toString(4));
}
@Test
public void invalid_path_yields_error_response() throws Exception {
String response = testDriver.sendRequest(V2_URI + "/invalid").readAll();
- JsonNode root = jsonMapper.readTree(response);
+ JSONObject root = new JSONObject(response);
assertTrue(root.has("error"));
- assertTrue(root.get("error" ).textValue().startsWith("No content"));
+ assertTrue(root.getString("error" ).startsWith("No content"));
}
@Test
@@ -114,23 +111,23 @@ public class MetricsV2HandlerTest {
}
@Test
- public void consumer_is_propagated_to_metrics_proxy_api() {
- JsonNode responseJson = getResponseAsJson(CUSTOM_CONSUMER);
+ public void consumer_is_propagated_to_metrics_proxy_api() throws JSONException {
+ JSONObject responseJson = getResponseAsJson(CUSTOM_CONSUMER);
- JsonNode firstNodeMetricsValues =
- responseJson.get("nodes").get(0)
- .get("node")
- .get("metrics").get(0)
- .get("values");
+ JSONObject firstNodeMetricsValues =
+ responseJson.getJSONArray("nodes").getJSONObject(0)
+ .getJSONObject("node")
+ .getJSONArray("metrics").getJSONObject(0)
+ .getJSONObject("values");
assertTrue(firstNodeMetricsValues.has(REPLACED_CPU_METRIC));
}
- private JsonNode getResponseAsJson(String consumer) {
+ private JSONObject getResponseAsJson(String consumer) {
String response = testDriver.sendRequest(VALUES_URI + consumerQuery(consumer)).readAll();
try {
- return jsonMapper.readTree(response);
- } catch (IOException e) {
+ return new JSONObject(response);
+ } catch (JSONException 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 9ffce6d1c28..a0e8c131c2b 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,11 +1,15 @@
// 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;
@@ -22,14 +26,13 @@ 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;
@@ -76,14 +79,14 @@ public class PrometheusV1HandlerTest {
@Test
public void v1_response_contains_values_uri() throws Exception {
String response = testDriver.sendRequest(V1_URI).readAll();
- JsonNode root = jsonMapper.readTree(response);
+ JSONObject root = new JSONObject(response);
assertTrue(root.has("resources"));
- ArrayNode resources = (ArrayNode) root.get("resources");
- assertEquals(1, resources.size());
+ JSONArray resources = root.getJSONArray("resources");
+ assertEquals(1, resources.length());
- JsonNode valuesUri = resources.get(0);
- assertEquals(VALUES_URI, valuesUri.get("url").asText());
+ JSONObject valuesUri = resources.getJSONObject(0);
+ assertEquals(VALUES_URI, valuesUri.getString("url"));
}
@Ignore
@@ -96,9 +99,9 @@ public class PrometheusV1HandlerTest {
@Test
public void invalid_path_yields_error_response() throws Exception {
String response = testDriver.sendRequest(V1_URI + "/invalid").readAll();
- JsonNode root = jsonMapper.readTree(response);
+ JSONObject root = new JSONObject(response);
assertTrue(root.has("error"));
- assertTrue(root.get("error" ).textValue().startsWith("No content"));
+ assertTrue(root.getString("error" ).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 8a3d0e837c5..c1f7d790fa5 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,7 +1,8 @@
// 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 org.json.JSONException;
+import org.json.JSONObject;
import org.junit.Test;
import java.nio.file.Path;
@@ -16,12 +17,12 @@ import static org.junit.Assert.assertEquals;
public class CoredumpGathererTest {
@Test
- public void finds_one_coredump() {
- JsonNode packet = CoredumpGatherer.gatherCoredumpMetrics(new MockFileWrapper());
+ public void finds_one_coredump() throws JSONException {
+ JSONObject packet = CoredumpGatherer.gatherCoredumpMetrics(new MockFileWrapper());
- 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());
+ assertEquals("system-coredumps-processing", packet.getString("application"));
+ assertEquals(1, packet.getInt("status_code"));
+ assertEquals("Found 1 coredump(s)", packet.getString("status_msg"));
}
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 12852c9d54c..d025b9662d2 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,7 +1,8 @@
// 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 org.json.JSONException;
+import org.json.JSONObject;
import org.junit.Test;
import java.nio.file.Path;
@@ -15,15 +16,15 @@ import static org.junit.Assert.assertEquals;
public class HostLifeGathererTest {
@Test
- 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());
+ 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"));
}
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 385eb627427..1258ecdc46f 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,38 +98,37 @@ public class StateHandlerTest extends StateHandlerTestBase {
snapshotProvider.setSnapshot(snapshot);
advanceToNextSnapshot();
assertEquals("{\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" +
- "}",
+ " \"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" +
+ "}",
requestAsString(V1_URI + "all"));
}