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]

Reply via email to