This is an automated email from the ASF dual-hosted git repository.
xiatian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/eventmesh.git
The following commit(s) were added to refs/heads/master by this push:
new 70f98923f [ISSUE #4834] Add protocol exclusive fields filter for
`/v2/configuration` endpoint (#4835)
70f98923f is described below
commit 70f98923fd81be37037414064cc5d534bcace556
Author: Pil0tXia <[email protected]>
AuthorDate: Mon Apr 29 19:54:44 2024 +0800
[ISSUE #4834] Add protocol exclusive fields filter for `/v2/configuration`
endpoint (#4835)
* Extract commonConfiguration out of subclasses
* Add configs param
* Unify return position
* Catch more exceptions
---
.../apache/eventmesh/common/utils/JsonUtils.java | 2 +-
.../runtime/admin/handler/AbstractHttpHandler.java | 57 ++++++++++-----
.../runtime/admin/handler/AdminHandlerManager.java | 6 +-
.../admin/handler/v2/ConfigurationHandler.java | 80 ++++++++++++++++++----
.../response/v2/GetConfigurationResponse.java | 3 +
5 files changed, 114 insertions(+), 34 deletions(-)
diff --git
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
index 71d42e345..cf07bdfbe 100644
---
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
+++
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
@@ -58,7 +58,7 @@ public class JsonUtils {
return null;
}
Object obj = OBJECT_MAPPER.convertValue(map, beanClass);
- return (T) obj;
+ return beanClass.cast(obj);
}
/**
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 0b0a6afed..cdfe4e163 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
@@ -35,7 +35,9 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+@Slf4j
@Data
public abstract class AbstractHttpHandler implements HttpHandler {
@@ -83,6 +85,12 @@ public abstract class AbstractHttpHandler implements
HttpHandler {
writeJson(ctx, json, HttpResponseStatus.UNAUTHORIZED);
}
+ protected void writeInternalServerError(ChannelHandlerContext ctx, String
message) {
+ Result<String> result = new Result<>(message);
+ String json = JSON.toJSONString(result, JSONWriter.Feature.WriteNulls);
+ writeJson(ctx, json, HttpResponseStatus.INTERNAL_SERVER_ERROR);
+ }
+
/**
* Use {@link HttpResponseUtils#buildHttpResponse} to build {@link
HttpResponse} param.
*/
@@ -92,25 +100,36 @@ public abstract class AbstractHttpHandler implements
HttpHandler {
@Override
public void handle(HttpRequest httpRequest, ChannelHandlerContext ctx)
throws Exception {
- switch (HttpMethod.valueOf(httpRequest.method().name())) {
- case OPTIONS:
- preflight(ctx);
- break;
- case GET:
- get(httpRequest, ctx);
- break;
- case POST:
- post(httpRequest, ctx);
- break;
- case PUT:
- put(httpRequest, ctx);
- break;
- case DELETE:
- delete(httpRequest, ctx);
- break;
- default:
- // do nothing
- break;
+ try {
+ switch (HttpMethod.valueOf(httpRequest.method().name())) {
+ case OPTIONS:
+ preflight(ctx);
+ break;
+ case GET:
+ get(httpRequest, ctx);
+ break;
+ case POST:
+ post(httpRequest, ctx);
+ break;
+ case PUT:
+ put(httpRequest, ctx);
+ break;
+ case DELETE:
+ delete(httpRequest, ctx);
+ break;
+ default: // do nothing
+ }
+ } catch (RuntimeException e) {
+ StackTraceElement element = e.getStackTrace()[0];
+ String className = element.getClassName();
+ String handlerName =
className.substring(className.lastIndexOf(".") + 1);
+ if (e instanceof IllegalArgumentException) {
+ log.warn("Admin endpoint {}:{} - {}", handlerName,
element.getLineNumber(), e.getMessage());
+ writeBadRequest(ctx, e.getMessage());
+ } else {
+ log.error("Admin endpoint {}:{} - {}", handlerName,
element.getLineNumber(), e.getMessage(), e);
+ writeInternalServerError(ctx, e.getMessage());
+ }
}
}
diff --git
a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AdminHandlerManager.java
b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AdminHandlerManager.java
index 4f81584b9..1da928dc1 100644
---
a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AdminHandlerManager.java
+++
b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AdminHandlerManager.java
@@ -58,6 +58,8 @@ import java.util.concurrent.ConcurrentHashMap;
public class AdminHandlerManager {
+ private EventMeshServer eventMeshServer;
+
private EventMeshTCPServer eventMeshTCPServer;
private EventMeshHTTPServer eventMeshHTTPServer;
@@ -71,9 +73,10 @@ public class AdminHandlerManager {
private final Map<String, HttpHandler> httpHandlerMap = new
ConcurrentHashMap<>();
public AdminHandlerManager(EventMeshServer eventMeshServer) {
+ this.eventMeshServer = eventMeshServer;
+ this.eventMeshTCPServer = eventMeshServer.getEventMeshTCPServer();
this.eventMeshGrpcServer = eventMeshServer.getEventMeshGrpcServer();
this.eventMeshHTTPServer = eventMeshServer.getEventMeshHTTPServer();
- this.eventMeshTCPServer = eventMeshServer.getEventMeshTCPServer();
this.eventMeshMetaStorage = eventMeshServer.getMetaStorage();
this.adminWebHookConfigOperationManage =
eventMeshTCPServer.getAdminWebHookConfigOperationManage();
}
@@ -112,6 +115,7 @@ public class AdminHandlerManager {
// v2 endpoints
initHandler(new ConfigurationHandler(
+ eventMeshServer.getConfiguration(),
eventMeshTCPServer.getEventMeshTCPConfiguration(),
eventMeshHTTPServer.getEventMeshHttpConfiguration(),
eventMeshGrpcServer.getEventMeshGrpcConfiguration()));
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 ce16b9574..1c149ca52 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
@@ -39,6 +39,7 @@ import io.netty.handler.codec.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.Filter;
import com.alibaba.fastjson2.filter.NameFilter;
+import com.alibaba.fastjson2.filter.PropertyFilter;
import com.alibaba.fastjson2.filter.ValueFilter;
import lombok.extern.slf4j.Slf4j;
@@ -56,6 +57,7 @@ import inet.ipaddr.IPAddress;
@EventMeshHttpHandler(path = "/v2/configuration")
public class ConfigurationHandler extends AbstractHttpHandler {
+ private final CommonConfiguration commonConfiguration;
private final EventMeshTCPConfiguration eventMeshTCPConfiguration;
private final EventMeshHTTPConfiguration eventMeshHTTPConfiguration;
private final EventMeshGrpcConfiguration eventMeshGrpcConfiguration;
@@ -68,10 +70,12 @@ public class ConfigurationHandler extends
AbstractHttpHandler {
* @param eventMeshGrpcConfiguration the gRPC configuration for EventMesh
*/
public ConfigurationHandler(
+ CommonConfiguration commonConfiguration,
EventMeshTCPConfiguration eventMeshTCPConfiguration,
EventMeshHTTPConfiguration eventMeshHTTPConfiguration,
EventMeshGrpcConfiguration eventMeshGrpcConfiguration) {
super();
+ this.commonConfiguration = commonConfiguration;
this.eventMeshTCPConfiguration = eventMeshTCPConfiguration;
this.eventMeshHTTPConfiguration = eventMeshHTTPConfiguration;
this.eventMeshGrpcConfiguration = eventMeshGrpcConfiguration;
@@ -85,34 +89,51 @@ public class ConfigurationHandler extends
AbstractHttpHandler {
* <p>When {@code properties}, the field names are returned in
Properties format;
* <p>When {@code bean}, the field names themselves are used as
json keys.
* </li>
+ * <li>
+ * {@code configs}: String; Optional, DefaultValue: {@code
exclusive}, SelectableValue: {@code all}.
+ * <p>When {@code exclusive}, protocol-specific configurations
will only contain protocol-exclusive fields
+ * and won't contain any {@link CommonConfiguration} fields;
+ * <p>When {@code all}, protocol-specific configurations will
contain all fields, including those in {@link CommonConfiguration}.
+ * </li>
* </ul>
*/
@Override
protected void get(HttpRequest httpRequest, ChannelHandlerContext ctx) {
String format = HttpRequestUtil.getQueryParam(httpRequest, "format",
"properties");
-
- Filter[] filters;
- if (format.equals("properties")) {
- filters = new Filter[] {new ConfigFieldFilter(), new
IPAddressToStringFilter()};
- } else if (format.equals("bean")) {
- filters = new Filter[] {new IPAddressToStringFilter()};
- } else {
- log.warn("Invalid format param: {}", format);
- writeBadRequest(ctx, "Invalid format param: " + format);
- return;
+ String configs = HttpRequestUtil.getQueryParam(httpRequest, "configs",
"exclusive");
+
+ List<Filter> filters = new ArrayList<>();
+ switch (configs) {
+ case "exclusive":
+ filters.add(new SuperClassFieldFilter());
+ break;
+ case "all": break;
+ default:
+ throw new IllegalArgumentException("Invalid param 'configs': "
+ configs);
+ }
+ switch (format) {
+ case "properties":
+ filters.add(new ConfigFieldFilter());
+ break;
+ case "bean": break;
+ default:
+ throw new IllegalArgumentException("Invalid param 'format': "
+ format);
}
+ filters.add(new IPAddressToStringFilter());
GetConfigurationResponse getConfigurationResponse = new
GetConfigurationResponse(
+ commonConfiguration,
eventMeshTCPConfiguration,
eventMeshHTTPConfiguration,
- eventMeshGrpcConfiguration
+ eventMeshGrpcConfiguration,
+ "v1.10.0-release" // TODO get version number after merging
https://github.com/apache/eventmesh/pull/4055
);
- String json =
JSON.toJSONString(Result.success(getConfigurationResponse), filters);
+ String json =
JSON.toJSONString(Result.success(getConfigurationResponse), filters.toArray(new
Filter[0]));
writeJson(ctx, json);
}
/**
- * For each member of {@link EventMeshTCPConfiguration}, {@link
EventMeshHTTPConfiguration}, and {@link EventMeshGrpcConfiguration},
+ * For each member of configuration classes,
* the value of the {@link ConfigField} annotation for each field is
obtained through reflection,
* and then concatenated with the configuration prefix in the {@link
Config} annotation to serve as the JSON key for this field.
* <p>
@@ -155,6 +176,39 @@ public class ConfigurationHandler extends
AbstractHttpHandler {
}
}
+ /**
+ * For each member of {@link EventMeshTCPConfiguration}, {@link
EventMeshHTTPConfiguration}, and {@link EventMeshGrpcConfiguration},
+ * if the {@code name} is a member that exists in {@link
CommonConfiguration} class, it will be skipped.
+ */
+ static class SuperClassFieldFilter implements PropertyFilter {
+ @Override
+ public boolean apply(Object object, String name, Object value) {
+ try {
+ Field field = findFieldInClassNonHierarchy(object.getClass(),
name);
+ return field != null;
+ } catch (NoSuchFieldException e) {
+ log.error("Failed to get field {} from object {}", name,
object, e);
+ }
+ return true;
+ }
+
+ /**
+ * If a field of a subclass exists in the superclass, return null,
causing FastJSON to skip this field.
+ */
+ private Field findFieldInClassNonHierarchy(Class<?> clazz, String
fieldName) throws NoSuchFieldException {
+ try {
+ return clazz.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ Class<?> superclass = clazz.getSuperclass();
+ if (superclass == null) {
+ throw e;
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+
/**
* {@link IPAddress} can't be serialized directly by FastJSON,
* so this filter converts {@link IPAddress} objects to their string
representation.
diff --git
a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/v2/GetConfigurationResponse.java
b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/v2/GetConfigurationResponse.java
index 40161cca7..5ae9eeb2d 100644
---
a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/v2/GetConfigurationResponse.java
+++
b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/v2/GetConfigurationResponse.java
@@ -17,6 +17,7 @@
package org.apache.eventmesh.runtime.admin.response.v2;
+import org.apache.eventmesh.common.config.CommonConfiguration;
import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration;
import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration;
import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration;
@@ -30,7 +31,9 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class GetConfigurationResponse {
+ private CommonConfiguration commonConfiguration;
private EventMeshTCPConfiguration eventMeshTCPConfiguration;
private EventMeshHTTPConfiguration eventMeshHTTPConfiguration;
private EventMeshGrpcConfiguration eventMeshGrpcConfiguration;
+ private String eventMeshVersion;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]