From 04d19ac8ef8cabbede57d805eec54b658dc74c12 Mon Sep 17 00:00:00 2001 From: hanbingleixue Date: Fri, 7 Feb 2025 17:15:27 +0800 Subject: [PATCH] Fix the issues of XDS flow control Signed-off-by: hanbingleixue --- .../xds/utils/CdsProtocolTransformer.java | 12 ++- .../xds/utils/RdsProtocolTransformer.java | 10 +- .../common/config/CommonConst.java | 10 ++ .../common/handler/retry/AbstractRetry.java | 30 ++++-- .../common/xds/retry/RetryCondition.java | 2 +- .../common/xds/retry/RetryConditionType.java | 94 ++++++++++++++----- ...java => ConnectFailureRetryCondition.java} | 14 ++- ...n.java => GatewayErrorRetryCondition.java} | 4 +- ... => ResetBeforeRequestRetryCondition.java} | 6 +- ...ondition.java => ResetRetryCondition.java} | 27 ++++-- ...n.java => Retriable4xxRetryCondition.java} | 4 +- ...va => RetriableHeadersRetryCondition.java} | 10 +- ...> RetriableStatusCodesRetryCondition.java} | 4 +- ...on.java => ServerErrorRetryCondition.java} | 19 ++-- .../xds/retry/RetryConditionManagerTest.java | 46 ++++----- ...rlConnectionResponseStreamInterceptor.java | 21 +++-- ...HttpClientInterceptorChainInterceptor.java | 6 +- .../dubbo/handler/TagRouteHandlerTest.java | 10 ++ .../strategy/RuleStrategyHandlerTest.java | 30 ++++++ 19 files changed, 256 insertions(+), 103 deletions(-) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{ConnectErrorRetryCondition.java => ConnectFailureRetryCondition.java} (80%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{GatewayErrorCondition.java => GatewayErrorRetryCondition.java} (89%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{ResetBeforeRequestErrorCondition.java => ResetBeforeRequestRetryCondition.java} (79%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{ResetErrorCondition.java => ResetRetryCondition.java} (63%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{ClientErrorCondition.java => Retriable4xxRetryCondition.java} (89%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{SpecificHeaderNameErrorRetryCondition.java => RetriableHeadersRetryCondition.java} (77%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{SpecificStatusCodeErrorRetryCondition.java => RetriableStatusCodesRetryCondition.java} (90%) rename sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/{ServerErrorCondition.java => ServerErrorRetryCondition.java} (58%) diff --git a/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/CdsProtocolTransformer.java b/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/CdsProtocolTransformer.java index 061e197131..b165847a07 100644 --- a/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/CdsProtocolTransformer.java +++ b/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/CdsProtocolTransformer.java @@ -28,6 +28,7 @@ import io.sermant.core.utils.CollectionUtils; import io.sermant.core.utils.StringUtils; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -139,11 +140,8 @@ private static XdsInstanceCircuitBreakers parseInstanceCircuitBreakers(Cluster c xdsInstanceCircuitBreakers.setConsecutiveGatewayFailure(outlierDetection.getConsecutiveGatewayFailure() .getValue()); xdsInstanceCircuitBreakers.setConsecutive5xxFailure(outlierDetection.getConsecutive5Xx().getValue()); - long interval = java.time.Duration.ofSeconds(outlierDetection.getInterval().getSeconds()).toMillis(); - xdsInstanceCircuitBreakers.setInterval(interval); - long ejectionTime = java.time.Duration.ofSeconds(outlierDetection.getBaseEjectionTime().getSeconds()) - .toMillis(); - xdsInstanceCircuitBreakers.setBaseEjectionTime(ejectionTime); + xdsInstanceCircuitBreakers.setInterval(getDurationInMillis(outlierDetection.getInterval())); + xdsInstanceCircuitBreakers.setBaseEjectionTime(getDurationInMillis(outlierDetection.getBaseEjectionTime())); xdsInstanceCircuitBreakers.setMaxEjectionPercent(outlierDetection.getMaxEjectionPercent().getValue()); xdsInstanceCircuitBreakers.setFailurePercentageMinimumHosts(outlierDetection.getFailurePercentageMinimumHosts() .getValue()); @@ -151,4 +149,8 @@ private static XdsInstanceCircuitBreakers parseInstanceCircuitBreakers(Cluster c getHealthyPanicThreshold().getValue()); return xdsInstanceCircuitBreakers; } + + private static long getDurationInMillis(com.google.protobuf.Duration duration) { + return Duration.ofSeconds(duration.getSeconds()).toMillis() + Duration.ofNanos(duration.getNanos()).toMillis(); + } } diff --git a/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/RdsProtocolTransformer.java b/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/RdsProtocolTransformer.java index 6ca3502659..d019d46fc9 100644 --- a/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/RdsProtocolTransformer.java +++ b/sermant-agentcore/sermant-agentcore-implement/src/main/java/io/sermant/implement/service/xds/utils/RdsProtocolTransformer.java @@ -270,8 +270,7 @@ private static XdsRetryPolicy parseRetryPolicy(RetryPolicy retryPolicy) { xdsRetryPolicy.setRetryConditions(Arrays.asList(retryPolicy.getRetryOn().split(CommonConstant.COMMA))); } xdsRetryPolicy.setMaxAttempts(retryPolicy.getNumRetries().getValue()); - long perTryTimeout = Duration.ofSeconds(retryPolicy.getPerTryTimeout().getSeconds()).toMillis(); - xdsRetryPolicy.setPerTryTimeout(perTryTimeout); + xdsRetryPolicy.setPerTryTimeout(getDurationInMillis(retryPolicy.getPerTryTimeout())); return xdsRetryPolicy; } @@ -307,8 +306,7 @@ private static XdsAbort parseAbort(FaultAbort faultAbort) { private static XdsDelay parseDelay(FaultDelay faultDelay) { XdsDelay xdsDelay = new XdsDelay(); - long fixedDelay = Duration.ofSeconds(faultDelay.getFixedDelay().getSeconds()).toMillis(); - xdsDelay.setFixedDelay(fixedDelay); + xdsDelay.setFixedDelay(getDurationInMillis(faultDelay.getFixedDelay())); io.sermant.core.service.xds.entity.FractionalPercent fractionalPercent = new io.sermant.core.service.xds.entity.FractionalPercent(); fractionalPercent.setNumerator(faultDelay.getPercentage().getNumerator()); @@ -448,4 +446,8 @@ private static Optional parseTokenBucket(Struct tokenBucketStruc xdsTokenBucket.setTokensPerFill((int) tokensPerFill); return Optional.of(xdsTokenBucket); } + + private static long getDurationInMillis(com.google.protobuf.Duration duration) { + return Duration.ofSeconds(duration.getSeconds()).toMillis() + Duration.ofNanos(duration.getNanos()).toMillis(); + } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/config/CommonConst.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/config/CommonConst.java index 44b4bb974f..67a1a0d980 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/config/CommonConst.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/config/CommonConst.java @@ -299,6 +299,16 @@ public class CommonConst { */ public static final String DEFAULT_CONTENT_TYPE = "text/plain"; + /** + * Minimum response code for a successful request + */ + public static final int MIN_SUCCESS_STATUS_CODE = 200; + + /** + * Maximum response code for a successful request + */ + public static final int MAX_SUCCESS_STATUS_CODE = 399; + private CommonConst() { } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/handler/retry/AbstractRetry.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/handler/retry/AbstractRetry.java index 9c9e6fc696..f6b2102fc9 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/handler/retry/AbstractRetry.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/handler/retry/AbstractRetry.java @@ -21,6 +21,8 @@ import io.sermant.core.plugin.config.PluginConfigManager; import io.sermant.core.service.xds.entity.XdsRetryPolicy; import io.sermant.core.utils.CollectionUtils; +import io.sermant.core.utils.StringUtils; +import io.sermant.flowcontrol.common.config.CommonConst; import io.sermant.flowcontrol.common.config.FlowControlConfig; import io.sermant.flowcontrol.common.support.ReflectMethodCacheSupport; import io.sermant.flowcontrol.common.xds.retry.RetryCondition; @@ -89,15 +91,16 @@ public boolean isNeedRetry(Object result, XdsRetryPolicy retryPolicy) { return false; } String statusCode = statusCodeOptional.get(); - if (conditions.contains(statusCode)) { - return true; + if (isSuccess(statusCode)) { + return false; } for (String conditionName : conditions) { - Optional retryConditionOptional = RetryConditionType.getRetryConditionByName(conditionName); + Optional retryConditionOptional = RetryConditionType + .getRetryConditionWithResultByName(conditionName); if (!retryConditionOptional.isPresent()) { continue; } - if (retryConditionOptional.get().needRetry(this, null, statusCode, result)) { + if (retryConditionOptional.get().isNeedRetry(this, null, statusCode, result)) { return true; } } @@ -110,17 +113,32 @@ public boolean isNeedRetry(Throwable ex, XdsRetryPolicy retryPolicy) { return false; } for (String conditionName : retryPolicy.getRetryConditions()) { - Optional retryConditionOptional = RetryConditionType.getRetryConditionByName(conditionName); + Optional retryConditionOptional = RetryConditionType + .getRetryConditionWithExceptionByName(conditionName); if (!retryConditionOptional.isPresent()) { continue; } - if (retryConditionOptional.get().needRetry(this, ex, null, null)) { + if (retryConditionOptional.get().isNeedRetry(this, ex, null, null)) { return true; } } return false; } + /** + * Determine if the request is successful + * + * @param statusCode status code + * @return if the request is successful,true : success false: failure + */ + public static boolean isSuccess(String statusCode) { + if (StringUtils.isEmpty(statusCode)) { + return false; + } + int code = Integer.parseInt(statusCode); + return code >= CommonConst.MIN_SUCCESS_STATUS_CODE && code <= CommonConst.MAX_SUCCESS_STATUS_CODE; + } + /** * implemented by subclasses, if subclass implement {@link #isNeedRetry(Set, Object)}, no need to implement the get * code method diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryCondition.java index 677055b438..dbb694fb41 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryCondition.java @@ -34,5 +34,5 @@ public interface RetryCondition { * @param statusCode response status code * @return The result of the decision */ - boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result); + boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result); } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionType.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionType.java index f212f377fc..ecb43b3cec 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionType.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionType.java @@ -16,16 +16,17 @@ package io.sermant.flowcontrol.common.xds.retry; -import io.sermant.core.utils.StringUtils; -import io.sermant.flowcontrol.common.xds.retry.condition.ClientErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ConnectErrorRetryCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.GatewayErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ResetBeforeRequestErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ResetErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ServerErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.SpecificHeaderNameErrorRetryCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.SpecificStatusCodeErrorRetryCondition; - +import io.sermant.flowcontrol.common.xds.retry.condition.ConnectFailureRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.GatewayErrorRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ResetBeforeRequestRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ResetRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.Retriable4xxRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.RetriableHeadersRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.RetriableStatusCodesRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ServerErrorRetryCondition; + +import java.util.HashMap; +import java.util.Map; import java.util.Optional; /** @@ -38,42 +39,45 @@ public enum RetryConditionType { /** * The type of conditional judgment for server errors */ - SERVER_ERROR("5xx", new ServerErrorCondition()), + FIVE_XX("5xx", new ServerErrorRetryCondition(), 2), /** * The type of conditional judgment for client errors */ - CLIENT_ERROR("retriable-4xx", new ClientErrorCondition()), + RETRIABLE_4XX("retriable-4xx", new Retriable4xxRetryCondition(), 0), /** * The type of conditional judgment for gateway errors */ - GATEWAY_ERROR("gateway-error", new GatewayErrorCondition()), + GATEWAY_ERROR("gateway-error", new GatewayErrorRetryCondition(), 0), /** * The type of conditional judgment for reset errors */ - RESET_ERROR("reset", new ResetErrorCondition()), + RESET("reset", new ResetRetryCondition(), 1), /** * The type of conditional judgment for resetting errors before request */ - RESET_BEFORE_REQUEST_ERROR("reset-before-request", new ResetBeforeRequestErrorCondition()), + RESET_BEFORE_REQUEST("reset-before-request", new ResetBeforeRequestRetryCondition(), 1), /** * The type of conditional judgment for connect errors */ - CONNECT_ERROR("connect-failure", new ConnectErrorRetryCondition()), + CONNECT_FAILURE("connect-failure", new ConnectFailureRetryCondition(), 1), /** * The type of conditional judgment for Specify response code */ - SPECIFIC_STATUS_CODE_ERROR("retriable-status-codes", new SpecificStatusCodeErrorRetryCondition()), + RETRIABLE_STATUS_CODES("retriable-status-codes", new RetriableStatusCodesRetryCondition(), 0), /** * The type of conditional judgment for Specify response headers */ - SPECIFIC_HEADER_NAME_ERROR("retriable-headers", new SpecificHeaderNameErrorRetryCondition()); + RETRIABLE_HEADERS("retriable-headers", new RetriableHeadersRetryCondition(), 0); + + private static final Map RETRY_CONDITION_TYPE_ENUM_MAP + = new HashMap<>(); /** * the name of retry condition @@ -85,9 +89,24 @@ public enum RetryConditionType { */ private final RetryCondition retryCondition; - RetryConditionType(String conditionName, RetryCondition retryCondition) { + /** + * condition Type, + * 0: Retry condition based on the result. + * 1: Retry condition based on the exception. + * 2: Retry condition based on both the status code and the exception. + */ + private final int type; + + static { + for (RetryConditionType retryConditionType : RetryConditionType.values()) { + RETRY_CONDITION_TYPE_ENUM_MAP.put(retryConditionType.conditionName, retryConditionType); + } + } + + RetryConditionType(String conditionName, RetryCondition retryCondition, int type) { this.conditionName = conditionName; this.retryCondition = retryCondition; + this.type = type; } public String getConditionName() { @@ -99,16 +118,43 @@ public RetryCondition getRetryCondition() { } /** - * get the instance of implements class by condition name + * get the instance of Retry condition by condition name * * @param conditionName condition name * @return instance of implements class for retry condition */ public static Optional getRetryConditionByName(String conditionName) { - for (RetryConditionType retryConditionType : RetryConditionType.values()) { - if (StringUtils.equals(retryConditionType.getConditionName(), conditionName)) { - return Optional.of(retryConditionType.getRetryCondition()); - } + RetryConditionType retryConditionType = RETRY_CONDITION_TYPE_ENUM_MAP.get(conditionName); + if (retryConditionType != null) { + return Optional.of(retryConditionType.getRetryCondition()); + } + return Optional.empty(); + } + + /** + * get the instance of Retry condition based on the result by condition name + * + * @param conditionName condition name + * @return instance of implements class for retry condition + */ + public static Optional getRetryConditionWithResultByName(String conditionName) { + RetryConditionType retryConditionType = RETRY_CONDITION_TYPE_ENUM_MAP.get(conditionName); + if (retryConditionType != null && retryConditionType.type != 1) { + return Optional.of(retryConditionType.getRetryCondition()); + } + return Optional.empty(); + } + + /** + * get the instance of Retry condition based on the result by condition name + * + * @param conditionName condition name + * @return instance of implements class for retry condition + */ + public static Optional getRetryConditionWithExceptionByName(String conditionName) { + RetryConditionType retryConditionType = RETRY_CONDITION_TYPE_ENUM_MAP.get(conditionName); + if (retryConditionType != null && retryConditionType.type != 0) { + return Optional.of(retryConditionType.getRetryCondition()); } return Optional.empty(); } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ConnectErrorRetryCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ConnectFailureRetryCondition.java similarity index 80% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ConnectErrorRetryCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ConnectFailureRetryCondition.java index 9da562c166..5896b74b77 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ConnectErrorRetryCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ConnectFailureRetryCondition.java @@ -21,7 +21,6 @@ import io.sermant.flowcontrol.common.util.StringUtils; import io.sermant.flowcontrol.common.xds.retry.RetryCondition; -import java.io.InterruptedIOException; import java.net.ConnectException; import java.net.NoRouteToHostException; import java.net.SocketTimeoutException; @@ -34,9 +33,9 @@ * @author zhp * @since 2024-11-29 */ -public class ConnectErrorRetryCondition implements RetryCondition { +public class ConnectFailureRetryCondition implements RetryCondition { @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { if (ex == null) { return false; } @@ -51,10 +50,15 @@ public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object re } private boolean isConnectErrorException(Throwable ex) { - if (ex instanceof InterruptedIOException && StringUtils.contains(ex.getMessage(), "timeout")) { - return true; + if (isRequestTimeoutException(ex)) { + return false; } return ex instanceof SocketTimeoutException || ex instanceof ConnectException || ex instanceof TimeoutException || ex instanceof NoRouteToHostException; } + + private boolean isRequestTimeoutException(Throwable ex) { + return (ex instanceof SocketTimeoutException || ex instanceof TimeoutException) + && !StringUtils.isEmpty(ex.getMessage()) && ex.getMessage().contains("Read timed out"); + } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/GatewayErrorCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/GatewayErrorRetryCondition.java similarity index 89% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/GatewayErrorCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/GatewayErrorRetryCondition.java index b42c66c330..bdf7cd2ae8 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/GatewayErrorCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/GatewayErrorRetryCondition.java @@ -31,11 +31,11 @@ * @author zhp * @since 2024-11-29 */ -public class GatewayErrorCondition implements RetryCondition { +public class GatewayErrorRetryCondition implements RetryCondition { private static final Set GATE_WAY_FAILURE_CODE = new HashSet<>(Arrays.asList("502", "503", "504")); @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { return !StringUtils.isEmpty(statusCode) && GATE_WAY_FAILURE_CODE.contains(statusCode); } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetBeforeRequestErrorCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetBeforeRequestRetryCondition.java similarity index 79% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetBeforeRequestErrorCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetBeforeRequestRetryCondition.java index 448963523a..37f0de1a42 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetBeforeRequestErrorCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetBeforeRequestRetryCondition.java @@ -26,9 +26,9 @@ * @author zhp * @since 2024-11-29 */ -public class ResetBeforeRequestErrorCondition extends ResetErrorCondition { +public class ResetBeforeRequestRetryCondition extends ResetRetryCondition { @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { - return XdsThreadLocalUtil.getSendByteFlag() && super.needRetry(retry, ex, statusCode, result); + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { + return XdsThreadLocalUtil.getSendByteFlag() && super.isNeedRetry(retry, ex, statusCode, result); } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetErrorCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetRetryCondition.java similarity index 63% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetErrorCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetRetryCondition.java index 9c1a3ee9d6..3875486563 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetErrorCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ResetRetryCondition.java @@ -21,8 +21,10 @@ import io.sermant.flowcontrol.common.handler.retry.Retry; import io.sermant.flowcontrol.common.xds.retry.RetryCondition; -import java.net.SocketException; +import java.io.IOException; import java.net.SocketTimeoutException; +import java.util.Locale; +import java.util.concurrent.TimeoutException; /** * Retry condition check, determine if the current error is a connect reset error, and trigger a retry if @@ -31,9 +33,12 @@ * @author zhp * @since 2024-11-29 */ -public class ResetErrorCondition implements RetryCondition { +public class ResetRetryCondition implements RetryCondition { @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { + if (ex == null) { + return false; + } Throwable realException = ex; if (ex instanceof InvokerWrapperException) { InvokerWrapperException invokerWrapperException = (InvokerWrapperException) ex; @@ -41,11 +46,19 @@ public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object re realException = invokerWrapperException.getRealException(); } } - if (realException instanceof SocketTimeoutException && !StringUtils.isEmpty(ex.getMessage()) - && realException.getMessage().contains("Read timed out")) { + String message = realException.getMessage(); + if (StringUtils.isEmpty(message)) { + return false; + } + if (isRequestTimeoutException(ex, message)) { return true; } - return realException instanceof SocketException && !StringUtils.isEmpty(realException.getMessage()) - && (realException.getMessage().contains("reset") || ex.getMessage().contains("disconnection")); + return realException instanceof IOException + && (message.contains("Connection reset") || message.toLowerCase(Locale.ROOT).contains("broken pipe")); + } + + private static boolean isRequestTimeoutException(Throwable ex, String message) { + return (ex instanceof SocketTimeoutException || ex instanceof TimeoutException) + && message.contains("Read timed out"); } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ClientErrorCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/Retriable4xxRetryCondition.java similarity index 89% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ClientErrorCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/Retriable4xxRetryCondition.java index 6fe07a865b..0bd678e7d9 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ClientErrorCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/Retriable4xxRetryCondition.java @@ -27,13 +27,13 @@ * @author zhp * @since 2024-11-29 */ -public class ClientErrorCondition implements RetryCondition { +public class Retriable4xxRetryCondition implements RetryCondition { private static final int MIN_4XX_FAILURE = 400; private static final int MAX_4XX_FAILURE = 499; @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { if (StringUtils.isEmpty(statusCode)) { return false; } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/SpecificHeaderNameErrorRetryCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/RetriableHeadersRetryCondition.java similarity index 77% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/SpecificHeaderNameErrorRetryCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/RetriableHeadersRetryCondition.java index 9a9d912c99..39bb9fe584 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/SpecificHeaderNameErrorRetryCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/RetriableHeadersRetryCondition.java @@ -18,6 +18,8 @@ import io.sermant.core.plugin.config.PluginConfigManager; import io.sermant.core.utils.CollectionUtils; +import io.sermant.core.utils.StringUtils; +import io.sermant.flowcontrol.common.config.CommonConst; import io.sermant.flowcontrol.common.config.XdsFlowControlConfig; import io.sermant.flowcontrol.common.handler.retry.Retry; import io.sermant.flowcontrol.common.xds.retry.RetryCondition; @@ -32,14 +34,18 @@ * @author zhp * @since 2024-11-29 */ -public class SpecificHeaderNameErrorRetryCondition implements RetryCondition { +public class RetriableHeadersRetryCondition implements RetryCondition { private static final XdsFlowControlConfig CONFIG = PluginConfigManager.getPluginConfig(XdsFlowControlConfig.class); @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { if (CollectionUtils.isEmpty(CONFIG.getRetryHeaderNames())) { return false; } + int code = StringUtils.isEmpty(statusCode) ? CommonConst.DEFAULT_RESPONSE_CODE : Integer.parseInt(statusCode); + if (code >= CommonConst.MIN_SUCCESS_STATUS_CODE && code <= CommonConst.MAX_SUCCESS_STATUS_CODE) { + return false; + } Optional> headerNames = retry.getHeaderNames(result); if (!headerNames.isPresent()) { return false; diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/SpecificStatusCodeErrorRetryCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/RetriableStatusCodesRetryCondition.java similarity index 90% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/SpecificStatusCodeErrorRetryCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/RetriableStatusCodesRetryCondition.java index 3d91f484c7..c20ce63a56 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/SpecificStatusCodeErrorRetryCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/RetriableStatusCodesRetryCondition.java @@ -30,11 +30,11 @@ * @author zhp * @since 2024-11-29 */ -public class SpecificStatusCodeErrorRetryCondition implements RetryCondition { +public class RetriableStatusCodesRetryCondition implements RetryCondition { private static final XdsFlowControlConfig CONFIG = PluginConfigManager.getPluginConfig(XdsFlowControlConfig.class); @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { if (CollectionUtils.isEmpty(CONFIG.getRetryStatusCodes()) || StringUtils.isEmpty(statusCode)) { return false; } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ServerErrorCondition.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ServerErrorRetryCondition.java similarity index 58% rename from sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ServerErrorCondition.java rename to sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ServerErrorRetryCondition.java index f57b3a6e12..8161d92156 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ServerErrorCondition.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/main/java/io/sermant/flowcontrol/common/xds/retry/condition/ServerErrorRetryCondition.java @@ -19,6 +19,7 @@ import io.sermant.flowcontrol.common.handler.retry.Retry; import io.sermant.flowcontrol.common.util.StringUtils; import io.sermant.flowcontrol.common.xds.retry.RetryCondition; +import io.sermant.flowcontrol.common.xds.retry.RetryConditionType; /** * Retry condition check, determine if the current error is a server error, and trigger a retry if it is. @@ -26,17 +27,23 @@ * @author zhp * @since 2024-11-29 */ -public class ServerErrorCondition implements RetryCondition { +public class ServerErrorRetryCondition implements RetryCondition { private static final int MIN_5XX_FAILURE = 500; private static final int MAX_5XX_FAILURE = 599; @Override - public boolean needRetry(Retry retry, Throwable ex, String statusCode, Object result) { - if (StringUtils.isEmpty(statusCode)) { - return true; + public boolean isNeedRetry(Retry retry, Throwable ex, String statusCode, Object result) { + if (StringUtils.isEmpty(statusCode) && ex == null) { + return false; } - int code = Integer.parseInt(statusCode); - return code >= MIN_5XX_FAILURE && code <= MAX_5XX_FAILURE; + if (!StringUtils.isEmpty(statusCode)) { + int code = Integer.parseInt(statusCode); + return code >= MIN_5XX_FAILURE && code <= MAX_5XX_FAILURE; + } + RetryCondition connectFailure = RetryConditionType.CONNECT_FAILURE.getRetryCondition(); + RetryCondition resetErrorCondition = RetryConditionType.RESET.getRetryCondition(); + return resetErrorCondition.isNeedRetry(retry, ex, statusCode, result) + || connectFailure.isNeedRetry(retry, ex, statusCode, result); } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/test/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionManagerTest.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/test/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionManagerTest.java index d48e769bde..29a811053d 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/test/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionManagerTest.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-common/src/test/java/io/sermant/flowcontrol/common/xds/retry/RetryConditionManagerTest.java @@ -16,14 +16,14 @@ package io.sermant.flowcontrol.common.xds.retry; -import io.sermant.flowcontrol.common.xds.retry.condition.ClientErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ConnectErrorRetryCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.GatewayErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ResetBeforeRequestErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ResetErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.ServerErrorCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.SpecificHeaderNameErrorRetryCondition; -import io.sermant.flowcontrol.common.xds.retry.condition.SpecificStatusCodeErrorRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ResetBeforeRequestRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.Retriable4xxRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ConnectFailureRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.GatewayErrorRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ResetRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.ServerErrorRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.RetriableHeadersRetryCondition; +import io.sermant.flowcontrol.common.xds.retry.condition.RetriableStatusCodesRetryCondition; import org.junit.Test; import java.util.Optional; @@ -40,28 +40,28 @@ public class RetryConditionManagerTest { @Test public void testRetryCondition() { Optional result = RetryConditionType.getRetryConditionByName( - RetryConditionType.SERVER_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof ServerErrorCondition); + RetryConditionType.FIVE_XX.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof ServerErrorRetryCondition); result = RetryConditionType.getRetryConditionByName( - RetryConditionType.CLIENT_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof ClientErrorCondition); + RetryConditionType.RETRIABLE_4XX.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof Retriable4xxRetryCondition); result = RetryConditionType.getRetryConditionByName( - RetryConditionType.CONNECT_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof ConnectErrorRetryCondition); + RetryConditionType.CONNECT_FAILURE.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof ConnectFailureRetryCondition); result = RetryConditionType.getRetryConditionByName( - RetryConditionType.RESET_BEFORE_REQUEST_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof ResetBeforeRequestErrorCondition); + RetryConditionType.RESET_BEFORE_REQUEST.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof ResetBeforeRequestRetryCondition); result = RetryConditionType.getRetryConditionByName( RetryConditionType.GATEWAY_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof GatewayErrorCondition); + assertTrue(result.isPresent() && result.get() instanceof GatewayErrorRetryCondition); result = RetryConditionType.getRetryConditionByName( - RetryConditionType.RESET_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof ResetErrorCondition); + RetryConditionType.RESET.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof ResetRetryCondition); result = RetryConditionType.getRetryConditionByName( - RetryConditionType.SPECIFIC_HEADER_NAME_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof SpecificHeaderNameErrorRetryCondition); + RetryConditionType.RETRIABLE_HEADERS.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof RetriableHeadersRetryCondition); result = RetryConditionType.getRetryConditionByName( - RetryConditionType.SPECIFIC_STATUS_CODE_ERROR.getConditionName()); - assertTrue(result.isPresent() && result.get() instanceof SpecificStatusCodeErrorRetryCondition); + RetryConditionType.RETRIABLE_STATUS_CODES.getConditionName()); + assertTrue(result.isPresent() && result.get() instanceof RetriableStatusCodesRetryCondition); } } diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/HttpUrlConnectionResponseStreamInterceptor.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/HttpUrlConnectionResponseStreamInterceptor.java index 33bcdf1a8f..e7a02a9bd0 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/HttpUrlConnectionResponseStreamInterceptor.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/HttpUrlConnectionResponseStreamInterceptor.java @@ -121,6 +121,8 @@ protected void preRetry(Object obj, Method method, Object[] allArguments, Object HttpURLConnection connection = (HttpURLConnection) obj; ReflectUtils.setFieldValue(connection,"inputStream", null); ReflectUtils.setFieldValue(connection,"cachedInputStream", null); + ReflectUtils.setFieldValue(connection, "cachedHeaders", null); + ReflectUtils.setFieldValue(connection, "filteredHeaders", null); Optional serviceInstanceOptional = chooseServiceInstanceForXds(); if (!serviceInstanceOptional.isPresent()) { return; @@ -207,6 +209,11 @@ public Optional getCode(Object result) { } } + @Override + public boolean isNeedRetry(Object result, XdsRetryPolicy retryPolicy) { + return this.isNeedRetry((Throwable) null, retryPolicy); + } + @Override public boolean isNeedRetry(Throwable throwable, XdsRetryPolicy retryPolicy) { List conditions = retryPolicy.getRetryConditions(); @@ -215,24 +222,22 @@ public boolean isNeedRetry(Throwable throwable, XdsRetryPolicy retryPolicy) { } Optional statusCodeOptional = this.getCode(null); String statusCode = statusCodeOptional.orElse(StringUtils.EMPTY); + if (isSuccess(statusCode)) { + return false; + } for (String conditionName : conditions) { - Optional retryConditionOptional = RetryConditionType. - getRetryConditionByName(conditionName); + Optional retryConditionOptional = + RetryConditionType.getRetryConditionByName(conditionName); if (!retryConditionOptional.isPresent()) { continue; } - if (retryConditionOptional.get().needRetry(this, throwable, statusCode, null)) { + if (retryConditionOptional.get().isNeedRetry(this, throwable, statusCode, null)) { return true; } } return false; } - @Override - public boolean isNeedRetry(Object result, XdsRetryPolicy retryPolicy) { - return this.isNeedRetry((Throwable) null, retryPolicy); - } - @Override public Optional> getHeaderNames(Object result) { HttpURLConnection connection = XdsThreadLocalUtil.getHttpUrlConnection(); diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/OkHttpClientInterceptorChainInterceptor.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/OkHttpClientInterceptorChainInterceptor.java index f80ddcfae1..b36f6865a6 100644 --- a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/OkHttpClientInterceptorChainInterceptor.java +++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/io/sermant/flowcontrol/retry/client/OkHttpClientInterceptorChainInterceptor.java @@ -105,15 +105,15 @@ protected ExecuteContext doBefore(ExecuteContext context) throws Exception { } private Optional convertToValidHttpEntity(Request httpRequest) { - HttpUrl uri = httpRequest.httpUrl(); - String serviceName = uri.host().split(CommonConst.ESCAPED_POINT)[0]; + URL uri = httpRequest.url(); + String serviceName = uri.getHost().split(CommonConst.ESCAPED_POINT)[0]; if (!XdsRouterUtils.isXdsRouteRequired(serviceName)) { return Optional.empty(); } final Map headers = getHeaders(httpRequest); return Optional.of(new HttpRequestEntity.Builder() .setRequestType(RequestEntity.RequestType.CLIENT) - .setApiPath(uri.encodedPath()).setHeaders(headers) + .setApiPath(uri.getPath()).setHeaders(headers) .setMethod(httpRequest.method()) .setServiceName(serviceName) .build()); diff --git a/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/handler/TagRouteHandlerTest.java b/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/handler/TagRouteHandlerTest.java index d6dae6bac8..19cde2a54e 100644 --- a/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/handler/TagRouteHandlerTest.java +++ b/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/handler/TagRouteHandlerTest.java @@ -18,7 +18,9 @@ import io.sermant.core.config.ConfigManager; import io.sermant.core.event.config.EventConfig; +import io.sermant.core.plugin.config.PluginConfigManager; import io.sermant.router.common.cache.DubboCache; +import io.sermant.router.common.config.RouterConfig; import io.sermant.router.common.constants.RouterConstant; import io.sermant.router.config.cache.ConfigCache; import io.sermant.router.dubbo.ApacheInvoker; @@ -26,8 +28,10 @@ import io.sermant.router.dubbo.service.AbstractDirectoryServiceTest.ApacheInvocation; import org.apache.dubbo.rpc.Invocation; +import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.MockedStatic; @@ -52,6 +56,8 @@ public class TagRouteHandlerTest { private static MockedStatic mockConfigManager; + private static MockedStatic mockPluginConfigManager; + /** * Mock before UT execution */ @@ -62,6 +68,9 @@ public static void before() { mockConfigManager = Mockito.mockStatic(ConfigManager.class); mockConfigManager.when(() -> ConfigManager.getConfig(EventConfig.class)).thenReturn(config); tagRouteHandler = new TagRouteHandler(); + mockPluginConfigManager = Mockito.mockStatic(PluginConfigManager.class); + mockPluginConfigManager.when(() -> PluginConfigManager.getPluginConfig(RouterConfig.class)) + .thenReturn(Mockito.mock(RouterConfig.class)); } /** @@ -71,6 +80,7 @@ public static void before() { public static void after() { mockConfigManager.close(); DubboCache.INSTANCE.clear(); + mockPluginConfigManager.close(); } /** diff --git a/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/strategy/RuleStrategyHandlerTest.java b/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/strategy/RuleStrategyHandlerTest.java index fad04b9bd7..b72841db0c 100644 --- a/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/strategy/RuleStrategyHandlerTest.java +++ b/sermant-plugins/sermant-router/dubbo-router-service/src/test/java/io/sermant/router/dubbo/strategy/RuleStrategyHandlerTest.java @@ -16,14 +16,24 @@ package io.sermant.router.dubbo.strategy; +import io.sermant.core.config.ConfigManager; +import io.sermant.core.event.config.EventConfig; +import io.sermant.core.plugin.config.PluginConfigManager; +import io.sermant.router.common.cache.DubboCache; +import io.sermant.router.common.config.RouterConfig; import io.sermant.router.common.constants.RouterConstant; import io.sermant.router.config.entity.Route; import io.sermant.router.config.entity.Rule; import io.sermant.router.dubbo.AlibabaInvoker; import io.sermant.router.dubbo.ApacheInvoker; +import io.sermant.router.dubbo.handler.TagRouteHandler; +import org.junit.AfterClass; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import java.util.ArrayList; import java.util.Collections; @@ -42,6 +52,26 @@ public class RuleStrategyHandlerTest { private final Rule rule; + private static MockedStatic mockPluginConfigManager; + + /** + * Mock before UT execution + */ + @BeforeClass + public static void before() { + mockPluginConfigManager = Mockito.mockStatic(PluginConfigManager.class); + mockPluginConfigManager.when(() -> PluginConfigManager.getPluginConfig(RouterConfig.class)) + .thenReturn(Mockito.mock(RouterConfig.class)); + } + + /** + * Release resources after UT execution + */ + @AfterClass + public static void after() { + mockPluginConfigManager.close(); + } + /** * constructor */