xucaiqin 2 лет назад
Родитель
Сommit
8952609e9a

+ 25 - 0
sckw-common/sckw-common-remote/src/main/java/com/sckw/remote/config/AllowClassList.java

@@ -0,0 +1,25 @@
+package com.sckw.remote.config;
+
+import com.sckw.remote.constant.DubboAllow;
+import jakarta.annotation.PostConstruct;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.springframework.stereotype.Component;
+
+/**
+ * dubbo接口放行处理
+ *
+ * @author xucaiqin
+ */
+@Component
+public class AllowClassList {
+    @PostConstruct
+    public void init() {
+        SerializeSecurityManager serializeSecurityManager = FrameworkModel.defaultModel().getBeanFactory().getBean(SerializeSecurityManager.class);
+        for (String s : DubboAllow.getPacks()) {
+            serializeSecurityManager.addToAllowed(s);
+        }
+
+    }
+
+}

+ 32 - 0
sckw-common/sckw-common-remote/src/main/java/com/sckw/remote/constant/DubboAllow.java

@@ -0,0 +1,32 @@
+package com.sckw.remote.constant;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author xucaiqin
+ */
+public enum DubboAllow {
+    EXCEPTION("com.sckw.core.exception", "异常放行包");
+    private final String pack;
+    private final String desc;
+
+    DubboAllow(String pack, String desc) {
+        this.pack = pack;
+        this.desc = desc;
+    }
+
+    public String getPack() {
+        return pack;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public static List<String> getPacks() {
+        return Arrays.stream(DubboAllow.values()).map(DubboAllow::getPack).toList();
+    }
+
+
+}

+ 89 - 0
sckw-common/sckw-common-remote/src/main/java/com/sckw/remote/filter/DubboExceptionFilter.java

@@ -0,0 +1,89 @@
+package com.sckw.remote.filter;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.*;
+import org.apache.dubbo.rpc.filter.ExceptionFilter;
+import org.apache.dubbo.rpc.service.GenericService;
+
+import java.lang.reflect.Method;
+
+import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FILTER_VALIDATION_EXCEPTION;
+
+@Activate(group = CommonConstants.PROVIDER)
+public class DubboExceptionFilter implements Filter, Filter.Listener {
+    private ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ExceptionFilter.class);
+
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        return invoker.invoke(invocation);
+    }
+
+    @Override
+    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
+        if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
+            try {
+                Throwable exception = appResponse.getException();
+
+                // directly throw if it's checked exception
+                if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
+                    return;
+                }
+                // directly throw if the exception appears in the signature
+                try {
+                    Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
+                    Class<?>[] exceptionClasses = method.getExceptionTypes();
+                    for (Class<?> exceptionClass : exceptionClasses) {
+                        if (exception.getClass().equals(exceptionClass)) {
+                            return;
+                        }
+                    }
+                } catch (NoSuchMethodException e) {
+                    return;
+                }
+
+                // for the exception not found in method's signature, print ERROR message in server's log.
+                logger.error(CONFIG_FILTER_VALIDATION_EXCEPTION, "", "", "Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
+
+                // directly throw if exception class and interface class are in the same jar file.
+                String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
+                String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
+                if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
+                    return;
+                }
+                // directly throw if it's JDK exception
+                String className = exception.getClass().getName();
+                if (className.startsWith("java.") || className.startsWith("javax.")) {
+                    return;
+                }
+                //自定义异常处理
+                if (className.startsWith("com.sckw.core.exception")) {
+                    return;
+                }
+                // directly throw if it's dubbo exception
+                if (exception instanceof RpcException) {
+                    return;
+                }
+
+                // otherwise, wrap with RuntimeException and throw back to the client
+                appResponse.setException(new RuntimeException(StringUtils.toString(exception)));
+            } catch (Throwable e) {
+                logger.warn(CONFIG_FILTER_VALIDATION_EXCEPTION, "", "", "Fail to ExceptionFilter when called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
+            }
+        }
+    }
+
+    @Override
+    public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
+        logger.error(CONFIG_FILTER_VALIDATION_EXCEPTION, "", "", "Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
+    }
+
+    // For test purpose
+    public void setLogger(ErrorTypeAwareLogger logger) {
+        this.logger = logger;
+    }
+}

+ 1 - 0
sckw-common/sckw-common-remote/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter

@@ -0,0 +1 @@
+dubboExceptionFilter=com.sckw.remote.filter.DubboExceptionFilter

+ 1 - 0
sckw-common/sckw-common-remote/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.sckw.remote.config.AllowClassList