aboutsummaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorgjoranv <gv@verizonmedia.com>2020-01-23 12:39:19 +0100
committergjoranv <gv@verizonmedia.com>2020-01-23 12:40:04 +0100
commit6be753f4021e5ef8ece22d19898dbb18e0005bf4 (patch)
tree4bd83c8464b07d6234955964f37a2fb38637d895 /container-core
parentb492c6d6b5f46bc484d249ef5aa3768d7dd91c71 (diff)
Move metrics handler utilities to new package in container-core
Diffstat (limited to 'container-core')
-rw-r--r--container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java32
-rw-r--r--container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java78
-rw-r--r--container-core/src/main/java/com/yahoo/container/handler/metrics/JsonResponse.java30
-rw-r--r--container-core/src/main/java/com/yahoo/container/handler/metrics/package-info.java6
-rw-r--r--container-core/src/test/java/com/yahoo/container/handler/metrics/ErrorResponseTest.java25
5 files changed, 171 insertions, 0 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java b/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java
new file mode 100644
index 00000000000..321f7b3994a
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java
@@ -0,0 +1,32 @@
+// 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 java.util.Map;
+import java.util.logging.Logger;
+
+import static java.util.logging.Level.WARNING;
+
+/**
+ * @author gjoranv
+ */
+public class ErrorResponse extends JsonResponse {
+ private static Logger log = Logger.getLogger(ErrorResponse.class.getName());
+
+ private static ObjectMapper objectMapper = new ObjectMapper();
+
+ public ErrorResponse(int code, String message) {
+ super(code, asErrorJson(message));
+ }
+
+ static String asErrorJson(String message) {
+ try {
+ return objectMapper.writeValueAsString(Map.of("error", message));
+ } catch (JsonProcessingException e) {
+ log.log(WARNING, "Could not encode error message to json:", e);
+ return "Could not encode error message to json, check the log for details.";
+ }
+ }
+}
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
new file mode 100644
index 00000000000..92840cee48f
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java
@@ -0,0 +1,78 @@
+// 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.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;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR;
+import static com.yahoo.jdisc.Response.Status.METHOD_NOT_ALLOWED;
+import static com.yahoo.jdisc.Response.Status.NOT_FOUND;
+import static com.yahoo.jdisc.Response.Status.OK;
+import static com.yahoo.jdisc.http.HttpRequest.Method.GET;
+import static java.util.logging.Level.WARNING;
+
+/**
+ * @author gjoranv
+ */
+public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler {
+
+ protected HttpHandlerBase(Executor executor) {
+ super(executor);
+ }
+
+ protected abstract Optional<HttpResponse> doHandle(URI requestUri, Path apiPath, String consumer);
+
+ @Override
+ public final HttpResponse handle(HttpRequest request) {
+ if (request.getMethod() != GET) return new JsonResponse(METHOD_NOT_ALLOWED, "Only GET is supported");
+
+ Path path = new Path(request.getUri());
+
+ return doHandle(request.getUri(), path, getConsumer(request))
+ .orElse(new ErrorResponse(NOT_FOUND, "No content at given path"));
+ }
+
+ private String getConsumer(HttpRequest request) {
+ return request.getProperty("consumer");
+ }
+
+ protected JsonResponse resourceListResponse(URI requestUri, List<String> resources) {
+ try {
+ return new JsonResponse(OK, resourceList(requestUri, resources));
+ } 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.");
+ }
+ }
+
+ // 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://");
+ base.append(host);
+ if (port >= 0) {
+ base.append(":").append(port);
+ }
+ String uriBase = base.toString();
+ JSONArray linkList = new JSONArray();
+ for (String api : resources) {
+ JSONObject resource = new JSONObject();
+ resource.put("url", uriBase + api);
+ linkList.put(resource);
+ }
+ return new JSONObject().put("resources", linkList).toString(4);
+ }
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/handler/metrics/JsonResponse.java b/container-core/src/main/java/com/yahoo/container/handler/metrics/JsonResponse.java
new file mode 100644
index 00000000000..def06ce9de3
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/JsonResponse.java
@@ -0,0 +1,30 @@
+// 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.yahoo.container.jdisc.HttpResponse;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+/**
+ * @author gjoranv
+ */
+public class JsonResponse extends HttpResponse {
+ private final byte[] data;
+
+ public JsonResponse(int code, String data) {
+ super(code);
+ this.data = data.getBytes(Charset.forName(DEFAULT_CHARACTER_ENCODING));
+ }
+
+ @Override
+ public String getContentType() {
+ return "application/json";
+ }
+
+ @Override
+ public void render(OutputStream outputStream) throws IOException {
+ outputStream.write(data);
+ }
+}
diff --git a/container-core/src/main/java/com/yahoo/container/handler/metrics/package-info.java b/container-core/src/main/java/com/yahoo/container/handler/metrics/package-info.java
new file mode 100644
index 00000000000..031886afc94
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/package-info.java
@@ -0,0 +1,6 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/** Exported config package */
+@ExportPackage
+package com.yahoo.container.handler.metrics;
+
+import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/container-core/src/test/java/com/yahoo/container/handler/metrics/ErrorResponseTest.java b/container-core/src/test/java/com/yahoo/container/handler/metrics/ErrorResponseTest.java
new file mode 100644
index 00000000000..882f9044dce
--- /dev/null
+++ b/container-core/src/test/java/com/yahoo/container/handler/metrics/ErrorResponseTest.java
@@ -0,0 +1,25 @@
+// 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 org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author gjoranv
+ */
+public class ErrorResponseTest {
+
+ @Test
+ public void error_message_is_wrapped_in_json_object() {
+ var json = ErrorResponse.asErrorJson("bad");
+ assertEquals("{\"error\":\"bad\"}", json);
+ }
+
+ @Test
+ public void quotes_are_escaped() {
+ var json = ErrorResponse.asErrorJson("Message \" with \" embedded quotes.");
+ assertEquals("{\"error\":\"Message \\\" with \\\" embedded quotes.\"}", json);
+ }
+
+}