This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch 2.8.x in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/2.8.x by this push: new ee301b315 [SCB-2855]make ExceptionToProducerResponseConverters extensible (#4206) ee301b315 is described below commit ee301b315d1dfa2c1f91bc88c8e36aa59b446cd1 Author: liubao68 <bi...@qq.com> AuthorDate: Sat Jan 27 09:36:12 2024 +0800 [SCB-2855]make ExceptionToProducerResponseConverters extensible (#4206) --- ...aultExceptionToProducerResponseConverters.java} | 7 +-- .../invocation/exception/ExceptionFactory.java | 10 ++-- .../ExceptionToProducerResponseConverters.java | 57 ++-------------------- ...exception.ExceptionToProducerResponseConverters | 18 +++++++ ...aultExceptionToProducerResponseConverters.java} | 10 ++-- 5 files changed, 37 insertions(+), 65 deletions(-) diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/DefaultExceptionToProducerResponseConverters.java similarity index 90% copy from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java copy to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/DefaultExceptionToProducerResponseConverters.java index e5b307733..8f307460d 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/DefaultExceptionToProducerResponseConverters.java @@ -25,8 +25,8 @@ import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ExceptionToProducerResponseConverters { - private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionToProducerResponseConverters.class); +public class DefaultExceptionToProducerResponseConverters implements ExceptionToProducerResponseConverters { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExceptionToProducerResponseConverters.class); private final Map<Class<?>, ExceptionToProducerResponseConverter<Throwable>> exceptionToProducerResponseConverters = new HashMap<>(); @@ -38,7 +38,7 @@ public class ExceptionToProducerResponseConverters { * return smaller value takes higher priority. */ @SuppressWarnings("unchecked") - public ExceptionToProducerResponseConverters() { + public DefaultExceptionToProducerResponseConverters() { SPIServiceUtils.getSortedService(ExceptionToProducerResponseConverter.class).forEach(converter -> { if (converter.getExceptionClass() == null) { if (defaultConverter == null) { @@ -51,6 +51,7 @@ public class ExceptionToProducerResponseConverters { }); } + @Override public Response convertExceptionToResponse(SwaggerInvocation swaggerInvocation, Throwable e) { ExceptionToProducerResponseConverter<Throwable> converter = null; Class<?> clazz = e.getClass(); diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionFactory.java index eab0afdcf..8f9c37b56 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionFactory.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionFactory.java @@ -22,6 +22,7 @@ import java.util.concurrent.ExecutionException; import javax.ws.rs.core.Response.StatusType; +import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; import org.apache.servicecomb.swagger.invocation.context.HttpStatus; @@ -46,7 +47,8 @@ public final class ExceptionFactory { public static final String CONSUMER_INNER_REASON_PHRASE = "Unexpected consumer error, please check logs for details"; - private static final ExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new ExceptionToProducerResponseConverters(); + private static final ExceptionToProducerResponseConverters exceptionToProducerResponseConverters + = SPIServiceUtils.getPriorityHighestService(ExceptionToProducerResponseConverters.class); public static final StatusType CONSUMER_INNER_STATUS = new HttpStatus(CONSUMER_INNER_STATUS_CODE, CONSUMER_INNER_REASON_PHRASE); @@ -72,12 +74,12 @@ public final class ExceptionFactory { } private static InvocationException doCreate(StatusType status, - Object errorData) { + Object errorData) { return new InvocationException(status, errorData); } private static InvocationException doCreate(int statusCode, String reasonPhrase, CommonExceptionData data, - Throwable e) { + Throwable e) { return new InvocationException(statusCode, reasonPhrase, data, e); } @@ -113,7 +115,7 @@ public final class ExceptionFactory { // 则需要创建新的InvocationException实例,此时不允许使用e.getMessage,因为可能会涉及关键信息被传给远端 // 新创建的InvocationException,会使用errorMsg来构建CommonExceptionData private static InvocationException convertException(int statusCode, String reasonPhrase, Throwable e, - String errorMsg) { + String errorMsg) { e = unwrap(e); if (e instanceof InvocationException) { diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java index e5b307733..5ac627a67 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToProducerResponseConverters.java @@ -16,62 +16,13 @@ */ package org.apache.servicecomb.swagger.invocation.exception; -import java.util.HashMap; -import java.util.Map; - -import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ExceptionToProducerResponseConverters { - private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionToProducerResponseConverters.class); - - private final Map<Class<?>, ExceptionToProducerResponseConverter<Throwable>> exceptionToProducerResponseConverters = - new HashMap<>(); - private ExceptionToProducerResponseConverter<Throwable> defaultConverter; - - /** - * Load the {@link ExceptionToProducerResponseConverter} implementations. Ensure that those converters whose {@link ExceptionToProducerResponseConverter#getOrder()} - * return smaller value takes higher priority. - */ - @SuppressWarnings("unchecked") - public ExceptionToProducerResponseConverters() { - SPIServiceUtils.getSortedService(ExceptionToProducerResponseConverter.class).forEach(converter -> { - if (converter.getExceptionClass() == null) { - if (defaultConverter == null) { - defaultConverter = converter; - } - return; - } - - exceptionToProducerResponseConverters.putIfAbsent(converter.getExceptionClass(), converter); - }); - } +public interface ExceptionToProducerResponseConverters { + Response convertExceptionToResponse(SwaggerInvocation swaggerInvocation, Throwable e); - public Response convertExceptionToResponse(SwaggerInvocation swaggerInvocation, Throwable e) { - ExceptionToProducerResponseConverter<Throwable> converter = null; - Class<?> clazz = e.getClass(); - while (converter == null) { - converter = exceptionToProducerResponseConverters.get(clazz); - if (clazz == Throwable.class) { - break; - } - clazz = clazz.getSuperclass(); - } - if (converter == null) { - converter = defaultConverter; - } - try { - return converter.convert(swaggerInvocation, e); - } catch (Throwable throwable) { - // In case users do not implement correctly and maybe discovered at runtime to cause asycResponse callback hang. - LOGGER - .error("ExceptionToProducerResponseConverter {} cannot throw exception, please fix it.", converter.getClass(), - throwable); - return Response.failResp(swaggerInvocation.getInvocationType(), e); - } + default int getOrder() { + return 0; } } diff --git a/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverters b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverters new file mode 100644 index 000000000..919d820f6 --- /dev/null +++ b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverters @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +org.apache.servicecomb.swagger.invocation.exception.DefaultExceptionToProducerResponseConverters diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToProducerResponseConverters.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestDefaultExceptionToProducerResponseConverters.java similarity index 93% rename from swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToProducerResponseConverters.java rename to swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestDefaultExceptionToProducerResponseConverters.java index fe8eaf069..2747148e0 100644 --- a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToProducerResponseConverters.java +++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestDefaultExceptionToProducerResponseConverters.java @@ -25,12 +25,12 @@ import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import mockit.Expectations; import mockit.Mocked; -import org.junit.jupiter.api.Assertions; -public class TestExceptionToProducerResponseConverters { +public class TestDefaultExceptionToProducerResponseConverters { @Test public void convertExceptionToResponse( @Mocked ExceptionToProducerResponseConverter<Throwable> c1, @@ -58,7 +58,7 @@ public class TestExceptionToProducerResponseConverters { } }; - ExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new ExceptionToProducerResponseConverters(); + DefaultExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new DefaultExceptionToProducerResponseConverters(); Assertions.assertSame(r1, exceptionToProducerResponseConverters.convertExceptionToResponse(null, new Throwable())); @@ -103,7 +103,7 @@ public class TestExceptionToProducerResponseConverters { } }; - ExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new ExceptionToProducerResponseConverters(); + DefaultExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new DefaultExceptionToProducerResponseConverters(); Assertions.assertSame(r2, exceptionToProducerResponseConverters @@ -160,7 +160,7 @@ public class TestExceptionToProducerResponseConverters { } }; - ExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new ExceptionToProducerResponseConverters(); + DefaultExceptionToProducerResponseConverters exceptionToProducerResponseConverters = new DefaultExceptionToProducerResponseConverters(); Assertions.assertSame(rR0, exceptionToProducerResponseConverters.convertExceptionToResponse(null, new RuntimeException0_0()));