diff options
author | Bjørn Christian Seime <bjorn.christian@seime.no> | 2021-02-01 23:51:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-01 23:51:00 +0100 |
commit | 42794e42e8ce223705e0a8e0e3e9293d65adaf6c (patch) | |
tree | a337188686fe568fd0dc04db5234c7ffa2ccbb63 /container-core | |
parent | 7f04da806204b7727f377b4099bd10571c61e5da (diff) |
Revert "Remove org.json usage [run-systemtest]"
Diffstat (limited to 'container-core')
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")); } |