From dc6684d51f459d06c3344e074aef6ad5c2c3e175 Mon Sep 17 00:00:00 2001 From: Martin Polden Date: Thu, 19 Sep 2019 15:24:08 +0200 Subject: Move general REST API classes to com.yahoo.restapi --- .../main/java/com/yahoo/restapi/ErrorResponse.java | 66 ++++++++++++++++++++++ .../java/com/yahoo/restapi/MessageResponse.java | 31 ++++++++++ .../java/com/yahoo/restapi/ResourceResponse.java | 42 ++++++++++++++ .../java/com/yahoo/restapi/SlimeJsonResponse.java | 38 +++++++++++++ .../java/com/yahoo/restapi/StringResponse.java | 27 +++++++++ .../src/main/java/com/yahoo/restapi/Uri.java | 64 +++++++++++++++++++++ 6 files changed, 268 insertions(+) create mode 100644 container-core/src/main/java/com/yahoo/restapi/ErrorResponse.java create mode 100644 container-core/src/main/java/com/yahoo/restapi/MessageResponse.java create mode 100644 container-core/src/main/java/com/yahoo/restapi/ResourceResponse.java create mode 100644 container-core/src/main/java/com/yahoo/restapi/SlimeJsonResponse.java create mode 100644 container-core/src/main/java/com/yahoo/restapi/StringResponse.java create mode 100644 container-core/src/main/java/com/yahoo/restapi/Uri.java (limited to 'container-core/src') diff --git a/container-core/src/main/java/com/yahoo/restapi/ErrorResponse.java b/container-core/src/main/java/com/yahoo/restapi/ErrorResponse.java new file mode 100644 index 00000000000..d3e81a10720 --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/ErrorResponse.java @@ -0,0 +1,66 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Slime; + +import static com.yahoo.jdisc.Response.Status.BAD_REQUEST; +import static com.yahoo.jdisc.Response.Status.FORBIDDEN; +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.UNAUTHORIZED; + +/** + * A HTTP JSON response containing an error code and a message + * + * @author bratseth + */ +public class ErrorResponse extends SlimeJsonResponse { + + public enum errorCodes { + NOT_FOUND, + BAD_REQUEST, + FORBIDDEN, + METHOD_NOT_ALLOWED, + INTERNAL_SERVER_ERROR, + UNAUTHORIZED + } + + public ErrorResponse(int statusCode, String errorType, String message) { + super(statusCode, asSlimeMessage(errorType, message)); + } + + private static Slime asSlimeMessage(String errorType, String message) { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + root.setString("error-code", errorType); + root.setString("message", message); + return slime; + } + + public static ErrorResponse notFoundError(String message) { + return new ErrorResponse(NOT_FOUND, errorCodes.NOT_FOUND.name(), message); + } + + public static ErrorResponse internalServerError(String message) { + return new ErrorResponse(INTERNAL_SERVER_ERROR, errorCodes.INTERNAL_SERVER_ERROR.name(), message); + } + + public static ErrorResponse badRequest(String message) { + return new ErrorResponse(BAD_REQUEST, errorCodes.BAD_REQUEST.name(), message); + } + + public static ErrorResponse forbidden(String message) { + return new ErrorResponse(FORBIDDEN, errorCodes.FORBIDDEN.name(), message); + } + + public static ErrorResponse unauthorized(String message) { + return new ErrorResponse(UNAUTHORIZED, errorCodes.UNAUTHORIZED.name(), message); + } + + public static ErrorResponse methodNotAllowed(String message) { + return new ErrorResponse(METHOD_NOT_ALLOWED, errorCodes.METHOD_NOT_ALLOWED.name(), message); + } + +} diff --git a/container-core/src/main/java/com/yahoo/restapi/MessageResponse.java b/container-core/src/main/java/com/yahoo/restapi/MessageResponse.java new file mode 100644 index 00000000000..8669d4f9b0c --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/MessageResponse.java @@ -0,0 +1,31 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.slime.JsonFormat; +import com.yahoo.slime.Slime; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author bratseth + */ +public class MessageResponse extends HttpResponse { + + private final Slime slime = new Slime(); + + public MessageResponse(String message) { + super(200); + slime.setObject().setString("message", message); + } + + @Override + public void render(OutputStream stream) throws IOException { + new JsonFormat(true).encode(stream, slime); + } + + @Override + public String getContentType() { return "application/json"; } + +} diff --git a/container-core/src/main/java/com/yahoo/restapi/ResourceResponse.java b/container-core/src/main/java/com/yahoo/restapi/ResourceResponse.java new file mode 100644 index 00000000000..4852bfafa60 --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/ResourceResponse.java @@ -0,0 +1,42 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.JsonFormat; +import com.yahoo.slime.Slime; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Returns a response containing an array of links to sub-resources + * + * @author bratseth + */ +public class ResourceResponse extends HttpResponse { + + private final Slime slime = new Slime(); + + public ResourceResponse(HttpRequest request, String ... subResources) { + super(200); + Cursor resourceArray = slime.setObject().setArray("resources"); + for (String subResource : subResources) { + Cursor resourceEntry = resourceArray.addObject(); + resourceEntry.setString("url", new Uri(request.getUri()) + .append(subResource) + .withTrailingSlash() + .toString()); + } + } + + @Override + public void render(OutputStream stream) throws IOException { + new JsonFormat(true).encode(stream, slime); + } + + @Override + public String getContentType() { return "application/json"; } + +} diff --git a/container-core/src/main/java/com/yahoo/restapi/SlimeJsonResponse.java b/container-core/src/main/java/com/yahoo/restapi/SlimeJsonResponse.java new file mode 100644 index 00000000000..2473da3578d --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/SlimeJsonResponse.java @@ -0,0 +1,38 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.slime.JsonFormat; +import com.yahoo.slime.Slime; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A generic Json response using Slime for JSON encoding + * + * @author bratseth + */ +public class SlimeJsonResponse extends HttpResponse { + + private final Slime slime; + + public SlimeJsonResponse(Slime slime) { + super(200); + this.slime = slime; + } + + public SlimeJsonResponse(int statusCode, Slime slime) { + super(statusCode); + this.slime = slime; + } + + @Override + public void render(OutputStream stream) throws IOException { + new JsonFormat(true).encode(stream, slime); + } + + @Override + public String getContentType() { return "application/json"; } + +} diff --git a/container-core/src/main/java/com/yahoo/restapi/StringResponse.java b/container-core/src/main/java/com/yahoo/restapi/StringResponse.java new file mode 100644 index 00000000000..55ea22880de --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/StringResponse.java @@ -0,0 +1,27 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import com.yahoo.container.jdisc.HttpResponse; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +/** + * @author bratseth + */ +public class StringResponse extends HttpResponse { + + private final String message; + + public StringResponse(String message) { + super(200); + this.message = message; + } + + @Override + public void render(OutputStream stream) throws IOException { + stream.write(message.getBytes(StandardCharsets.UTF_8)); + } + +} diff --git a/container-core/src/main/java/com/yahoo/restapi/Uri.java b/container-core/src/main/java/com/yahoo/restapi/Uri.java new file mode 100644 index 00000000000..c1b0d19eb3e --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/Uri.java @@ -0,0 +1,64 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * A Uri which provides convenience methods for creating various manipulated copies. + * This is immutable. + * + * @author bratseth + */ +public class Uri { + + /** The URI instance wrapped by this */ + private final URI uri; + + public Uri(URI uri) { + this.uri = uri; + } + + public Uri(String uri) { + try { + this.uri = new URI(uri); + } + catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid URI", e); + } + } + + /** Returns a uri with the given path appended and all parameters removed */ + public Uri append(String pathElement) { + return new Uri(withoutParameters().withTrailingSlash() + pathElement); + } + + public Uri withoutParameters() { + int parameterStart = uri.toString().indexOf("?"); + if (parameterStart < 0) + return new Uri(uri.toString()); + else + return new Uri(uri.toString().substring(0, parameterStart)); + } + + public Uri withPath(String path) { + try { + return new Uri(new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), + uri.getPort(), path, uri.getQuery(), uri.getFragment())); + } + catch (URISyntaxException e) { + throw new IllegalArgumentException("Could not add path '" + path + "' to " + this); + } + } + + public Uri withTrailingSlash() { + if (toString().endsWith("/")) return this; + return new Uri(toString() + "/"); + } + + public URI toURI() { return uri; } + + @Override + public String toString() { return uri.toString(); } + +} -- cgit v1.2.3