diff options
10 files changed, 173 insertions, 186 deletions
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java index 822f4e0b5d5..10b3cc3077b 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasHandler.java @@ -61,7 +61,7 @@ public class YamasHandler extends HttpHandlerBase { try { List<MetricsPacket> metrics = consumer == null ? valuesFetcher.fetchAllMetrics() : valuesFetcher.fetch(consumer); metrics.addAll(nodeMetricGatherer.gatherMetrics()); // TODO: Currently only add these metrics in this handler. Eventually should be included in all handlers - return new YamasResponse(OK, YamasJsonUtil.toYamasArray(metrics, true)); + return new YamasResponse(OK, metrics); } catch (JsonRenderingException e) { return new ErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage()); } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java index 23b56e94ae4..49f5036b3fd 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/http/yamas/YamasResponse.java @@ -1,24 +1,25 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.metricsproxy.http.yamas; -import ai.vespa.metricsproxy.metric.model.json.JacksonUtil; -import ai.vespa.metricsproxy.metric.model.json.YamasArrayJsonModel; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.metricsproxy.metric.model.MetricsPacket; +import ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil; import com.yahoo.container.jdisc.HttpResponse; import java.io.IOException; import java.io.OutputStream; +import java.util.List; + /** * @author olaa */ public class YamasResponse extends HttpResponse { - private final YamasArrayJsonModel data; + private final List<MetricsPacket> metrics; - public YamasResponse(int code, YamasArrayJsonModel data) { + public YamasResponse(int code, List<MetricsPacket> metrics) { super(code); - this.data = data; + this.metrics = metrics; } @Override @@ -28,8 +29,7 @@ public class YamasResponse extends HttpResponse { @Override public void render(OutputStream outputStream) throws IOException { - ObjectMapper mapper = JacksonUtil.createObjectMapper(); - mapper.writeValue(outputStream, data); + YamasJsonUtil.toJson(metrics, outputStream, true); } } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java index 4ac2cc4dec8..c4f2b7198a4 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java @@ -19,6 +19,12 @@ import java.util.Locale; */ public class JacksonUtil { + private static final DecimalFormat decimalFormat = createDecimalFormat(); + private static DecimalFormat createDecimalFormat() { + DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.ENGLISH)); + df.setMaximumFractionDigits(13); + return df; + } /** * Returns an object mapper with a custom floating point serializer to avoid scientific notation */ @@ -30,14 +36,17 @@ public class JacksonUtil { mapper.registerModule(module); return mapper; } + /** + * Returns an object mapper with a custom floating point serializer to avoid scientific notation + */ + public static void writeDouble(JsonGenerator jgen, Double value) throws IOException { + jgen.writeNumber(decimalFormat.format(value)); + } public static class DoubleSerializer extends JsonSerializer<Double> { @Override - public void serialize(Double value, JsonGenerator jgen, - SerializerProvider provider) throws IOException { - DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.ENGLISH)); - df.setMaximumFractionDigits(13); - jgen.writeNumber(df.format(value)); + public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + writeDouble(jgen, value); } } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java deleted file mode 100644 index 539e3b851ae..00000000000 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasArrayJsonModel.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package ai.vespa.metricsproxy.metric.model.json; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.ArrayList; -import java.util.List; - -/** - * Datamodel for the metricsproxy representation of multiple yamas checks. - */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class YamasArrayJsonModel { - @JsonProperty("metrics") - public final List<YamasJsonModel> metrics = new ArrayList<>(); - - public void add(List<YamasJsonModel> results) { - metrics.addAll(results); - } - - public void add(YamasJsonModel result) { - metrics.add(result); - } - - public void add(YamasArrayJsonModel array) { - metrics.addAll(array.metrics); - } - - /** - * Convenience method to serialize. - * <p> - * Custom floating point serializer to avoid scientifc notation - * - * @return Serialized json - */ - public String serialize() { - ObjectMapper mapper = JacksonUtil.createObjectMapper(); - - if (metrics.size() > 0) { - try { - return mapper.writeValueAsString(this); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - } - return "{}"; // Backwards compatibility - } - -} diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java index d2be7be25d1..911c772c0e4 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModel.java @@ -10,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java index 602879aa0b6..b5b8e30a218 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java @@ -5,21 +5,21 @@ import ai.vespa.metricsproxy.metric.model.ConsumerId; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import ai.vespa.metricsproxy.metric.model.ServiceId; import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.StreamWriteFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.yahoo.concurrent.CopyOnWriteHashMap; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; -import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.logging.Logger; import java.util.stream.Collectors; import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId; -import static com.yahoo.stream.CustomCollectors.toLinkedMap; import static java.util.Collections.emptyList; import static java.util.logging.Level.WARNING; @@ -28,10 +28,12 @@ import static java.util.logging.Level.WARNING; */ public class YamasJsonUtil { private static final Logger log = Logger.getLogger(YamasJsonUtil.class.getName()); + private static final JsonFactory factory = JsonFactory.builder() + .enable(StreamWriteFeature.WRITE_BIGDECIMAL_AS_PLAIN) + .build(); static final String YAMAS_ROUTING = "yamas"; - private static final Map<Set<ConsumerId>, Map<String, YamasJsonModel.YamasJsonNamespace>> globalNameSpaces = new CopyOnWriteHashMap<>(); public static MetricsPacket.Builder toMetricsPacketBuilder(YamasJsonModel jsonModel) { if (jsonModel.application == null) throw new IllegalArgumentException("Service id cannot be null"); @@ -45,21 +47,6 @@ public class YamasJsonUtil { .addConsumers(jsonModel.getYamasConsumers()); } - public static YamasArrayJsonModel toYamasArray(Collection<MetricsPacket> metricsPackets) { - YamasArrayJsonModel yamasArray = toYamasArray(metricsPackets, false); - - // Add a single status object at the end - yamasArray.metrics.stream().findFirst().map(YamasJsonModel::getYamasConsumers) - .ifPresent(consumers -> yamasArray.add(getStatusYamasModel("Data collected successfully", 0, consumers))); - return yamasArray; - } - - public static YamasArrayJsonModel toYamasArray(Collection<MetricsPacket> metricsPackets, boolean addStatus) { - YamasArrayJsonModel yamasArray = new YamasArrayJsonModel(); - metricsPackets.forEach(packet -> yamasArray.add(toYamasModel(packet, addStatus))); - return yamasArray; - } - /** * Converts the given json formatted string to a list of metrics packet builders. * Note that this method returns an empty list if an IOException occurs, @@ -81,58 +68,91 @@ public class YamasJsonUtil { } } - private static YamasJsonModel getStatusYamasModel(String statusMessage, int statusCode, Set<ConsumerId> consumers) { - YamasJsonModel model = new YamasJsonModel(); - model.status_code = statusCode; - model.status_msg = statusMessage; - model.application = "yms_check_vespa"; - model.routing = computeIfAbsent(consumers); - return model; + public static List<MetricsPacket> appendOptionalStatusPacket(List<MetricsPacket> packets) { + if (packets.isEmpty()) return packets; + + Set<ConsumerId> consumers = extractSetForRouting(packets.get(0).consumers()); + if (consumers.isEmpty()) return packets; + List<MetricsPacket> withStatus = new ArrayList<>(packets); + withStatus.add(new MetricsPacket.Builder(ServiceId.toServiceId("yms_check_vespa")) + .statusCode(0) + .statusMessage("Data collected successfully") + .addConsumers(consumers).build()); + return withStatus; } - private static YamasJsonModel toYamasModel(MetricsPacket packet, boolean addStatus) { - YamasJsonModel model = new YamasJsonModel(); - - if (addStatus) { - model.status_code = packet.statusCode; - model.status_msg = packet.statusMessage; + public static String toJson(List<MetricsPacket> metrics, boolean addStatus) { + try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { + toJson(metrics, output, addStatus); + output.flush(); + return output.toString(); + } catch (IOException e) { + return "{}"; } - - model.application = packet.service.id; - model.timestamp = (packet.timestamp == 0L) ? null : packet.timestamp; - - model.metrics = (packet.metrics().isEmpty()) - ? null - : packet.metrics().entrySet().stream().collect( - toLinkedMap(id2metric -> id2metric.getKey().id, - id2metric -> id2metric.getValue().doubleValue())); - - model.dimensions = (packet.dimensions().isEmpty()) - ? null - : packet.dimensions().entrySet() - .stream() - .filter(entry -> entry.getKey() != null && entry.getValue() != null) - .collect(toLinkedMap(id2dim -> id2dim.getKey().id, Map.Entry::getValue)); - - model.routing = computeIfAbsent(packet.consumers()); - - return model; } - - private static Map<String, YamasJsonModel.YamasJsonNamespace> computeIfAbsent(Set<ConsumerId> consumers) { - return globalNameSpaces.computeIfAbsent(consumers, YamasJsonUtil::createYamasJson); + private static Set<ConsumerId> extractSetForRouting(Set<ConsumerId> consumers) { + return consumers.stream() + .filter(consumerId -> consumerId != defaultMetricsConsumerId) + .collect(Collectors.toSet()); + } + public static void toJson(List<MetricsPacket> metrics, OutputStream outputStream, boolean addStatus) throws IOException { + JsonGenerator generator = factory.createGenerator(outputStream); + generator.writeStartObject(); + if (metrics.isEmpty()) { + generator.writeEndObject(); + return; + } + generator.writeArrayFieldStart("metrics"); + for (int i = 0; i < metrics.size() - 1; i++) { + toJson(metrics.get(i), generator, addStatus); + } + toJson(metrics.get(metrics.size() - 1), generator, true); + generator.writeEndArray(); + generator.writeEndObject(); + generator.close(); } - private static Map<String, YamasJsonModel.YamasJsonNamespace> createYamasJson(Set<ConsumerId> consumers) { - List<String> namespaces = consumers.stream() - .filter(consumerId -> consumerId != defaultMetricsConsumerId) - .map(consumer -> consumer.id) - .collect(Collectors.toList()); - if (namespaces.isEmpty()) return null; + private static void toJson(MetricsPacket metric, JsonGenerator generator, boolean addStatus) throws IOException { + generator.writeStartObject(); + if (addStatus) { + generator.writeNumberField("status_code", metric.statusCode); + } + if (metric.timestamp != 0) { + generator.writeNumberField("timestamp", metric.timestamp); + } + generator.writeStringField("application", metric.service.id); - YamasJsonModel.YamasJsonNamespace yamasJsonNamespace = new YamasJsonModel.YamasJsonNamespace(); - yamasJsonNamespace.namespaces = namespaces; - return Map.of(YAMAS_ROUTING, yamasJsonNamespace); - } + if ( ! metric.metrics().isEmpty()) { + generator.writeObjectFieldStart("metrics"); + for (var m : metric.metrics().entrySet()) { + generator.writeFieldName(m.getKey().id); + JacksonUtil.writeDouble(generator, m.getValue().doubleValue()); + } + generator.writeEndObject(); + } + if ( ! metric.dimensions().isEmpty()) { + generator.writeObjectFieldStart("dimensions"); + for (var m : metric.dimensions().entrySet()) { + generator.writeStringField(m.getKey().id, m.getValue()); + } + generator.writeEndObject(); + } + Set<ConsumerId> routing = extractSetForRouting(metric.consumers()); + if (!routing.isEmpty()) { + generator.writeObjectFieldStart("routing"); + generator.writeObjectFieldStart(YAMAS_ROUTING); + generator.writeArrayFieldStart("namespaces"); + for (ConsumerId consumer : routing) { + generator.writeString(consumer.id); + } + generator.writeEndArray(); + generator.writeEndObject(); + generator.writeEndObject(); + } + if (addStatus) { + generator.writeStringField("status_msg", metric.statusMessage); + } + generator.writeEndObject(); + } } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java index 3a0a9e9cf73..63672e7e600 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcServer.java @@ -4,6 +4,7 @@ package ai.vespa.metricsproxy.rpc; import ai.vespa.metricsproxy.core.MetricsManager; import ai.vespa.metricsproxy.metric.model.ConsumerId; import ai.vespa.metricsproxy.metric.model.MetricsPacket; +import ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil; import ai.vespa.metricsproxy.service.VespaService; import ai.vespa.metricsproxy.service.VespaServices; import com.yahoo.jrt.ErrorCode; @@ -17,11 +18,10 @@ import java.util.logging.Level; import java.util.logging.Logger; import static ai.vespa.metricsproxy.metric.model.ConsumerId.toConsumerId; +import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toJson; import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toMetricsPackets; -import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toYamasArray; import static com.yahoo.collections.CollectionUtil.mkString; import static java.util.logging.Level.FINE; -import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; /** @@ -125,9 +125,9 @@ public class RpcServer { log.log(FINE, () -> "Getting metrics for services: " + mkString(services, "[", ", ", "]")); if (services.isEmpty()) setNoServiceError(req, service); else withExceptionHandling(req, () -> { - List<MetricsPacket> packets = metricsManager.getMetrics(services, startTime); + List<MetricsPacket> packets = YamasJsonUtil.appendOptionalStatusPacket(metricsManager.getMetrics(services, startTime)); log.log(FINE,() -> "Returning metrics packets:\n" + mkString(packets, "\n")); - req.returnValues().add(new StringValue(toYamasArray(packets).serialize())); + req.returnValues().add(new StringValue(toJson(packets, false))); }); req.returnRequest(); } @@ -138,8 +138,8 @@ public class RpcServer { List<VespaService> services = vespaServices.getMonitoringServices(service); if (services.isEmpty()) setNoServiceError(req, service); else withExceptionHandling(req, () -> { - List<MetricsPacket> packets = metricsManager.getHealthMetrics(services); - req.returnValues().add(new StringValue(toYamasArray(packets, true).serialize())); + List<MetricsPacket> packets = YamasJsonUtil.appendOptionalStatusPacket(metricsManager.getHealthMetrics(services)); + req.returnValues().add(new StringValue(toJson(packets, true))); }); req.returnRequest(); } diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java index 540445fba5b..a5bc7a0877a 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java @@ -1,15 +1,17 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.metricsproxy.metric.model.json; +import ai.vespa.metricsproxy.http.yamas.YamasResponse; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Collections; +import java.util.List; import static ai.vespa.metricsproxy.metric.model.ConsumerId.toConsumerId; import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId; @@ -32,10 +34,11 @@ public class YamasJsonModelTest { public void array_definition_creates_correct_json() throws IOException { YamasJsonModel jsonModel = getYamasJsonModel("yamas-array.json"); - YamasArrayJsonModel yamasData = new YamasArrayJsonModel(); - yamasData.add(jsonModel); - - assertEquals(EXPECTED_JSON, yamasData.serialize()); + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + YamasResponse response = new YamasResponse(200, List.of(YamasJsonUtil.toMetricsPacketBuilder(jsonModel).build())); + response.render(outputStream); + assertEquals(EXPECTED_JSON, outputStream.toString()); + } } @Test @@ -48,10 +51,11 @@ public class YamasJsonModelTest { assertEquals(5.555555555E9, jsonModel.metrics.get("memory_rss"), 0.1d); //Not using custom double renderer // Serialize and verify - YamasArrayJsonModel yamasArray = new YamasArrayJsonModel(); - yamasArray.add(jsonModel); - String string = yamasArray.serialize(); - assertEquals(EXPECTED_JSON, string); + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + YamasResponse response = new YamasResponse(200, List.of(YamasJsonUtil.toMetricsPacketBuilder(jsonModel).build())); + response.render(outputStream); + assertEquals(EXPECTED_JSON, outputStream.toString()); + } } @Test @@ -65,8 +69,7 @@ public class YamasJsonModelTest { assertEquals(5.555555555E9, metricsPacket.metrics().get(toMetricId("memory_rss")).doubleValue(), 0.1d); //Not using custom double rendrer // Serialize and verify - YamasArrayJsonModel yamasArray = YamasJsonUtil.toYamasArray(Collections.singleton(metricsPacket), true); - String string = yamasArray.serialize(); + String string = YamasJsonUtil.toJson(List.of(metricsPacket), true); assertEquals(EXPECTED_JSON, string); } diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java index 1a0d5c3e149..ebd80b38a42 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java @@ -2,8 +2,12 @@ package ai.vespa.metricsproxy.metric.model.json; import ai.vespa.metricsproxy.metric.model.MetricsPacket; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import org.junit.Test; +import java.io.IOException; import java.util.List; import java.util.Set; @@ -12,69 +16,75 @@ import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId; import static ai.vespa.metricsproxy.metric.model.ServiceId.toServiceId; import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.YAMAS_ROUTING; import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toMetricsPackets; -import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * @author gjoranv */ public class YamasJsonUtilTest { + private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static JsonNode metrics(MetricsPacket packet, boolean addStatus) throws IOException { + return metrics(List.of(packet), addStatus).get(0); + } + private static ArrayNode metrics(List<MetricsPacket> packets, boolean addStatus) throws IOException { + return (ArrayNode) jsonMapper.readTree(YamasJsonUtil.toJson(packets, addStatus)).get("metrics"); + } @Test - public void json_model_gets_null_status_by_default() { - MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")) - .build(); - YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0); - assertNull(jsonModel.status_code); - assertNull(jsonModel.status_msg); + public void json_model_gets_null_status_by_default() throws IOException { + ArrayNode json = metrics(List.of(new MetricsPacket.Builder(toServiceId("foo")).build(), + new MetricsPacket.Builder(toServiceId("bar")).build()), false); + assertFalse(json.get(0).has("status_code")); + assertFalse(json.get(0).has("status_msg")); + assertTrue(json.get(1).has("status_code")); + assertTrue(json.get(1).has("status_msg")); } @Test - public void status_is_included_in_json_model_when_explicitly_asked_for() { - MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")) - .build(); - YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet), true).metrics.get(0); - assertNotNull(jsonModel.status_code); - assertNotNull(jsonModel.status_msg); + public void status_is_included_in_json_model_when_explicitly_asked_for() throws IOException { + ArrayNode json = metrics(List.of(new MetricsPacket.Builder(toServiceId("foo")).build(), + new MetricsPacket.Builder(toServiceId("bar")).build()), true); + assertTrue(json.get(0).has("status_code")); + assertTrue(json.get(0).has("status_msg")); + assertTrue(json.get(1).has("status_code")); + assertTrue(json.get(1).has("status_msg")); } @Test - public void timestamp_0_in_packet_is_translated_to_null_in_json_model() { - MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")) - .timestamp(0L) - .build(); - YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0); - assertNull(jsonModel.timestamp); + public void timestamp_0_in_packet_is_translated_to_null_in_json_model() throws IOException { + MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")).timestamp(0L).build(); + JsonNode json = metrics(packet, true); + assertFalse(json.has("timestamp")); } @Test - public void empty_consumers_is_translated_to_null_routing_in_json_model() { - MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")) - .build(); - YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0); - assertNull(jsonModel.routing); + public void empty_consumers_is_translated_to_null_routing_in_json_model() throws IOException { + MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")).build(); + JsonNode json = metrics(packet, true); + assertFalse(json.has("routing")); } @Test - public void default_public_consumer_is_filtered_from_yamas_routing() { + public void default_public_consumer_is_filtered_from_yamas_routing() throws IOException { MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")) .addConsumers(Set.of(vespaMetricsConsumerId, defaultMetricsConsumerId)) .build(); - YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0); - List<String> namespaces = jsonModel.routing.get(YAMAS_ROUTING).namespaces; + JsonNode json = metrics(packet, false); + JsonNode routing = json.get("routing"); + JsonNode yamas = routing.get(YAMAS_ROUTING); + ArrayNode namespaces = (ArrayNode) yamas.get("namespaces"); assertEquals(1, namespaces.size()); - assertEquals(vespaMetricsConsumerId.id, namespaces.get(0)); + assertEquals(vespaMetricsConsumerId.id, namespaces.get(0).asText()); } @Test - public void only_default_public_consumer_yields_null_routing_in_json_model() { + public void only_default_public_consumer_yields_null_routing_in_json_model() throws IOException { MetricsPacket packet = new MetricsPacket.Builder(toServiceId("foo")) .addConsumers(Set.of(defaultMetricsConsumerId)) .build(); - YamasJsonModel jsonModel = YamasJsonUtil.toYamasArray(singleton(packet)).metrics.get(0); - assertNull(jsonModel.routing); + JsonNode json = metrics(packet, false); + assertFalse(json.has(YAMAS_ROUTING)); } @Test 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 214df36d6a1..8a489ac70c7 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 @@ -150,7 +150,7 @@ public class RpcMetricsTest { JsonNode jsonObject = metrics.get(i); assertFalse(jsonObject.has("status_code")); assertFalse(jsonObject.has("status_msg")); - assertThat(jsonObject.get("dimensions").get("foo").textValue(), is("bar")); + assertEquals("bar", jsonObject.get("dimensions").get("foo").textValue()); 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)); |