diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java index 831f8e4e80..cab9c01a71 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java @@ -18,43 +18,56 @@ package org.apache.eventmesh.runtime.admin.handler; import org.apache.eventmesh.common.enums.HttpMethod; +import org.apache.eventmesh.runtime.admin.response.Result; import org.apache.eventmesh.runtime.constants.EventMeshConstants; import org.apache.eventmesh.runtime.util.HttpResponseUtils; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.DefaultHttpHeaders; -import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONWriter; + import lombok.Data; @Data public abstract class AbstractHttpHandler implements HttpHandler { - protected void writeText(ChannelHandlerContext ctx, String result) { - HttpHeaders responseHeaders = new DefaultHttpHeaders(); - responseHeaders.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_HTML); - responseHeaders.add(EventMeshConstants.HANDLER_ORIGIN, "*"); - write(ctx, HttpResponseUtils.buildHttpResponse(result, ctx, responseHeaders, HttpResponseStatus.OK)); + protected void writeText(ChannelHandlerContext ctx, String text) { + HttpHeaders responseHeaders = HttpResponseUtils.buildDefaultHttpHeaders(HttpHeaderValues.TEXT_HTML); + write(ctx, HttpResponseUtils.buildHttpResponse(text, ctx, responseHeaders, HttpResponseStatus.OK)); } - protected void writeJson(ChannelHandlerContext ctx, String result) { - HttpHeaders responseHeaders = new DefaultHttpHeaders(); - responseHeaders.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON); - responseHeaders.add(EventMeshConstants.HANDLER_ORIGIN, "*"); - write(ctx, HttpResponseUtils.buildHttpResponse(result, ctx, responseHeaders, HttpResponseStatus.OK)); + protected void writeJson(ChannelHandlerContext ctx, String json) { + HttpHeaders responseHeaders = HttpResponseUtils.buildDefaultHttpHeaders(HttpHeaderValues.APPLICATION_JSON); + write(ctx, HttpResponseUtils.buildHttpResponse(json, ctx, responseHeaders, HttpResponseStatus.OK)); } - protected void writeUnauthorized(ChannelHandlerContext ctx, String result) { - HttpHeaders responseHeaders = new DefaultHttpHeaders(); - responseHeaders.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON); - responseHeaders.add(EventMeshConstants.HANDLER_ORIGIN, "*"); - write(ctx, HttpResponseUtils.buildHttpResponse(result, ctx, responseHeaders, HttpResponseStatus.UNAUTHORIZED)); + protected void writeSuccess(ChannelHandlerContext ctx, Object data) { + HttpHeaders responseHeaders = HttpResponseUtils.buildDefaultHttpHeaders(HttpHeaderValues.APPLICATION_JSON); + Result result = Result.success(data); + String json = JSON.toJSONString(result, JSONWriter.Feature.WriteNulls); + write(ctx, HttpResponseUtils.buildHttpResponse(json, ctx, responseHeaders, HttpResponseStatus.OK)); + } + + protected void writeBadRequest(ChannelHandlerContext ctx, String message) { + HttpHeaders responseHeaders = HttpResponseUtils.buildDefaultHttpHeaders(HttpHeaderValues.APPLICATION_JSON); + Result result = new Result<>(message); + String json = JSON.toJSONString(result, JSONWriter.Feature.WriteNulls); + write(ctx, HttpResponseUtils.buildHttpResponse(json, ctx, responseHeaders, HttpResponseStatus.BAD_REQUEST)); + } + + protected void writeUnauthorized(ChannelHandlerContext ctx, String message) { + HttpHeaders responseHeaders = HttpResponseUtils.buildDefaultHttpHeaders(HttpHeaderValues.APPLICATION_JSON); + Result result = new Result<>(message); + String json = JSON.toJSONString(result, JSONWriter.Feature.WriteNulls); + write(ctx, HttpResponseUtils.buildHttpResponse(json, ctx, responseHeaders, HttpResponseStatus.UNAUTHORIZED)); } /** diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/EventHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/EventHandler.java index f0341eee51..658fcac5fc 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/EventHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/EventHandler.java @@ -111,6 +111,6 @@ protected void post(HttpRequest httpRequest, ChannelHandlerContext ctx) throws E .getInstance() .resolveFormat(JsonFormat.CONTENT_TYPE)).deserialize(rawRequest); admin.publish(event); - writeJson(ctx, ""); + writeText(ctx, ""); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/GrpcClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/GrpcClientHandler.java index c0a47f2567..af48aea960 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/GrpcClientHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/GrpcClientHandler.java @@ -81,7 +81,7 @@ protected void delete(HttpRequest httpRequest, ChannelHandlerContext ctx) throws } } } - writeJson(ctx, ""); + writeText(ctx, ""); } @Override diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/HTTPClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/HTTPClientHandler.java index 58edd57fa8..2a72241949 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/HTTPClientHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/HTTPClientHandler.java @@ -75,7 +75,7 @@ protected void delete(HttpRequest httpRequest, ChannelHandlerContext ctx) throws clientList.removeIf(client -> Objects.equals(client.getUrl(), url)); } // Set the response headers and send a 200 status code empty response - writeJson(ctx, ""); + writeText(ctx, ""); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TCPClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TCPClientHandler.java index d2bffc15d1..429ce426ed 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TCPClientHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TCPClientHandler.java @@ -93,7 +93,7 @@ protected void delete(HttpRequest httpRequest, ChannelHandlerContext ctx) throws } // Set the response headers and send a 200 status code empty response - writeJson(ctx, ""); + writeText(ctx, ""); } @Override diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TopicHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TopicHandler.java index fc567ca69b..b536150354 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TopicHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v1/TopicHandler.java @@ -90,7 +90,7 @@ protected void post(HttpRequest httpRequest, ChannelHandlerContext ctx) throws E CreateTopicRequest createTopicRequest = JsonUtils.mapToObject(body, CreateTopicRequest.class); String topicName = Objects.requireNonNull(createTopicRequest).getName(); admin.createTopic(topicName); - writeJson(ctx, ""); + writeText(ctx, ""); } @Override @@ -103,6 +103,6 @@ protected void delete(HttpRequest httpRequest, ChannelHandlerContext ctx) throws DeleteTopicRequest deleteTopicRequest = JsonUtils.mapToObject(body, DeleteTopicRequest.class); String topicName = Objects.requireNonNull(deleteTopicRequest).getName(); admin.deleteTopic(topicName); - writeJson(ctx, ""); + writeText(ctx, ""); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v2/ConfigurationHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v2/ConfigurationHandler.java index 1e6d653a9f..ce16b95749 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v2/ConfigurationHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/v2/ConfigurationHandler.java @@ -21,6 +21,7 @@ import org.apache.eventmesh.common.config.Config; import org.apache.eventmesh.common.config.ConfigField; import org.apache.eventmesh.runtime.admin.handler.AbstractHttpHandler; +import org.apache.eventmesh.runtime.admin.response.Result; import org.apache.eventmesh.runtime.admin.response.v2.GetConfigurationResponse; import org.apache.eventmesh.runtime.common.EventMeshHttpHandler; import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; @@ -97,7 +98,7 @@ protected void get(HttpRequest httpRequest, ChannelHandlerContext ctx) { filters = new Filter[] {new IPAddressToStringFilter()}; } else { log.warn("Invalid format param: {}", format); - writeJson(ctx, "Invalid format param: " + format); + writeBadRequest(ctx, "Invalid format param: " + format); return; } @@ -106,8 +107,8 @@ protected void get(HttpRequest httpRequest, ChannelHandlerContext ctx) { eventMeshHTTPConfiguration, eventMeshGrpcConfiguration ); - String result = JSON.toJSONString(getConfigurationResponse, filters); - writeJson(ctx, result); + String json = JSON.toJSONString(Result.success(getConfigurationResponse), filters); + writeJson(ctx, json); } /** diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/Error.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/Result.java similarity index 65% rename from eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/Error.java rename to eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/Result.java index 4b03a07ba8..f8ba718e94 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/Error.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/Result.java @@ -17,22 +17,35 @@ package org.apache.eventmesh.runtime.admin.response; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * A RESTful response DTO. + */ @Data -public class Error { +@NoArgsConstructor +@AllArgsConstructor +public class Result { - private String message; + private T data; - private String stackTrace; + private String message; - @JsonCreator - public Error(@JsonProperty("message") String message, @JsonProperty("stackTrace") String stackTrace) { - super(); + public Result(String message) { this.message = message; - this.stackTrace = stackTrace; + } + + /** + * The request is valid and the result is wrapped in {@link Result}. + */ + public static Result success() { + return new Result<>("Success"); + } + + public static Result success(T data) { + return new Result<>(data, "Success"); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpRequestUtil.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpRequestUtil.java index b363e9679b..a8e1288f79 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpRequestUtil.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpRequestUtil.java @@ -100,12 +100,18 @@ public static Map queryStringToMap(String queryString) { return result; } + /** + * Get the value of a query parameter in URI query string. + */ public static String getQueryParam(HttpRequest httpRequest, String key, String defaultValue) { List values = new QueryStringDecoder(httpRequest.uri()).parameters().get(key); return values != null ? values.get(0) : defaultValue; } - public static String getPostParam(HttpRequest httpRequest, String key) throws IOException { + /** + * Get the value of a query parameter in body. + */ + public static String getBodyParam(HttpRequest httpRequest, String key) throws IOException { HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(httpRequest); Attribute attribute = (Attribute) decoder.getBodyHttpData(key); return attribute.getValue(); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java index e9e22dfd56..b24cfeab89 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java @@ -18,6 +18,7 @@ package org.apache.eventmesh.runtime.util; import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; @@ -66,6 +67,13 @@ public static HttpResponse buildHttpResponse(String body, ChannelHandlerContext return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, createByteBuf(ctx, body), responseHeaders, responseHeaders); } + public static HttpHeaders buildDefaultHttpHeaders(AsciiString contentType) { + HttpHeaders responseHeaders = new DefaultHttpHeaders(); + responseHeaders.add(HttpHeaderNames.CONTENT_TYPE, contentType); + responseHeaders.add(EventMeshConstants.HANDLER_ORIGIN, "*"); + return responseHeaders; + } + private static ByteBuf createByteBuf(ChannelHandlerContext ctx, String body) { byte[] bytes = body.getBytes(Constants.DEFAULT_CHARSET); ByteBuf byteBuf = ctx.alloc().buffer(bytes.length);