This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
commit bf6e0a4d9e04a61e0d95cddc428b0dc45e26b9a3 Author: liubao <[email protected]> AuthorDate: Tue Jan 5 16:18:46 2021 +0800 [SCB-2116]add configuration entity validation --- .../governance/entity/Configurable.java | 25 +++++++++++ .../servicecomb/governance/marker/Matcher.java | 8 ++++ .../governance/marker/TrafficMarker.java | 16 ++++++- .../governance/policy/AbstractPolicy.java | 20 +++++++-- .../governance/policy/BulkheadPolicy.java | 11 +++++ .../governance/policy/CircuitBreakerPolicy.java | 24 ++++++++++ .../governance/policy/GovernanceRule.java | 7 +++ .../governance/policy/RateLimitingPolicy.java | 14 ++++++ .../servicecomb/governance/policy/RetryPolicy.java | 51 +++++----------------- .../properties/GovernanceProperties.java | 13 ++++-- governance/src/test/resources/application.yaml | 17 +++++++- 11 files changed, 156 insertions(+), 50 deletions(-) diff --git a/governance/src/main/java/org/apache/servicecomb/governance/entity/Configurable.java b/governance/src/main/java/org/apache/servicecomb/governance/entity/Configurable.java new file mode 100644 index 0000000..987ddf0 --- /dev/null +++ b/governance/src/main/java/org/apache/servicecomb/governance/entity/Configurable.java @@ -0,0 +1,25 @@ +/* + * 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. + */ + +package org.apache.servicecomb.governance.entity; + +/** + * Indicates a object can be configure in configuration file or config center. + */ +public interface Configurable { + boolean isValid(); +} diff --git a/governance/src/main/java/org/apache/servicecomb/governance/marker/Matcher.java b/governance/src/main/java/org/apache/servicecomb/governance/marker/Matcher.java index 371460c..6b1b37a 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/marker/Matcher.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/marker/Matcher.java @@ -19,6 +19,7 @@ package org.apache.servicecomb.governance.marker; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.apache.servicecomb.governance.marker.operator.RawOperator; public class Matcher { @@ -30,6 +31,13 @@ public class Matcher { private String name; + public boolean isValid() { + if (StringUtils.isEmpty(name)) { + return false; + } + return true; + } + public Map<String, RawOperator> getHeaders() { return headers; } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/marker/TrafficMarker.java b/governance/src/main/java/org/apache/servicecomb/governance/marker/TrafficMarker.java index b64c168..90cb6e2 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/marker/TrafficMarker.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/marker/TrafficMarker.java @@ -20,8 +20,9 @@ import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.governance.entity.Configurable; -public class TrafficMarker { +public class TrafficMarker implements Configurable { private String services; @@ -31,6 +32,19 @@ public class TrafficMarker { return services; } + @Override + public boolean isValid() { + if (matches == null || matches.isEmpty()) { + return false; + } + for (Matcher matcher : matches) { + if (!matcher.isValid()) { + return false; + } + } + return true; + } + public void setServices(String services) { this.services = services; } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/policy/AbstractPolicy.java b/governance/src/main/java/org/apache/servicecomb/governance/policy/AbstractPolicy.java index 3e496c4..2f2aad5 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/policy/AbstractPolicy.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/policy/AbstractPolicy.java @@ -18,11 +18,14 @@ package org.apache.servicecomb.governance.policy; import java.util.List; -public abstract class AbstractPolicy implements Policy { +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.governance.entity.Configurable; - private String name; +public abstract class AbstractPolicy implements Policy, Configurable { - private GovernanceRule rules; + protected String name; + + protected GovernanceRule rules; public GovernanceRule getRules() { return rules; @@ -37,6 +40,17 @@ public abstract class AbstractPolicy implements Policy { } @Override + public boolean isValid() { + if (StringUtils.isEmpty(name)) { + return false; + } + if (rules == null) { + return false; + } + return rules.isValid(); + } + + @Override public boolean match(List<String> items) { if (rules == null) { return false; diff --git a/governance/src/main/java/org/apache/servicecomb/governance/policy/BulkheadPolicy.java b/governance/src/main/java/org/apache/servicecomb/governance/policy/BulkheadPolicy.java index e414e1d..57703b2 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/policy/BulkheadPolicy.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/policy/BulkheadPolicy.java @@ -46,6 +46,17 @@ public class BulkheadPolicy extends AbstractPolicy { } @Override + public boolean isValid() { + if (maxConcurrentCalls <= 0) { + return false; + } + if (maxWaitDuration < 0) { + return false; + } + return super.isValid(); + } + + @Override public String handler() { return BulkheadHandler.class.getSimpleName(); } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/policy/CircuitBreakerPolicy.java b/governance/src/main/java/org/apache/servicecomb/governance/policy/CircuitBreakerPolicy.java index 4353a25..6470299 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/policy/CircuitBreakerPolicy.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/policy/CircuitBreakerPolicy.java @@ -58,6 +58,30 @@ public class CircuitBreakerPolicy extends AbstractPolicy { public CircuitBreakerPolicy() { } + @Override + public boolean isValid() { + if (failureRateThreshold > 100 || failureRateThreshold <= 0) { + return false; + } + if (slowCallRateThreshold > 100 || slowCallRateThreshold <= 0) { + return false; + } + if (waitDurationInOpenState <= 0) { + return false; + } + if (slowCallDurationThreshold <= 0) { + return false; + } + if (permittedNumberOfCallsInHalfOpenState <= 0) { + return false; + } + if (minimumNumberOfCalls <= 0) { + return false; + } + + return super.isValid(); + } + public int getFailureRateThreshold() { return failureRateThreshold; } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/policy/GovernanceRule.java b/governance/src/main/java/org/apache/servicecomb/governance/policy/GovernanceRule.java index d75b250..480cf55 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/policy/GovernanceRule.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/policy/GovernanceRule.java @@ -47,6 +47,13 @@ public class GovernanceRule { this.precedence = precedence; } + public boolean isValid() { + if (StringUtils.isEmpty(match)) { + return false; + } + return true; + } + public boolean match(String name) { if (StringUtils.isEmpty(this.match)) { return false; diff --git a/governance/src/main/java/org/apache/servicecomb/governance/policy/RateLimitingPolicy.java b/governance/src/main/java/org/apache/servicecomb/governance/policy/RateLimitingPolicy.java index 2d82d76..8bb312a 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/policy/RateLimitingPolicy.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/policy/RateLimitingPolicy.java @@ -70,6 +70,20 @@ public class RateLimitingPolicy extends AbstractPolicy { } @Override + public boolean isValid() { + if (timeoutDuration < 0) { + return false; + } + if (limitRefreshPeriod <= 0) { + return false; + } + if (rate <= 0) { + return false; + } + return super.isValid(); + } + + @Override public String handler() { return RateLimitingHandler.class.getSimpleName(); } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/policy/RetryPolicy.java b/governance/src/main/java/org/apache/servicecomb/governance/policy/RetryPolicy.java index b6ec4b9..944b349 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/policy/RetryPolicy.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/policy/RetryPolicy.java @@ -16,16 +16,9 @@ */ package org.apache.servicecomb.governance.policy; -import org.springframework.util.StringUtils; - import org.apache.servicecomb.governance.handler.RetryHandler; +import org.springframework.util.StringUtils; -/** - * intervalFunction 失败时可以更改等待时间的函数 - * retryOnResultPredicate 根据返回结果决定是否进行重试 - * retryOnExceptionPredicate 根据失败异常决定是否进行重试 - * - */ public class RetryPolicy extends AbstractPolicy { public static final int DEFAULT_MAX_ATTEMPTS = 3; @@ -43,14 +36,6 @@ public class RetryPolicy extends AbstractPolicy { //需要重试的http status, 逗号分隔 private String retryOnResponseStatus; - //TODO: 需要进行重试的异常列表,反射取异常 - private String retryExceptions; - - //TODO: 需要进行忽略的异常列表 - private String ignoreExceptions; - - private boolean onSame; - public String getRetryOnResponseStatus() { if (StringUtils.isEmpty(retryOnResponseStatus)) { retryOnResponseStatus = DEFAULT_RETRY_ON_RESPONSE_STATUS; @@ -78,28 +63,15 @@ public class RetryPolicy extends AbstractPolicy { this.waitDuration = waitDuration; } - public String getRetryExceptions() { - return retryExceptions; - } - - public void setRetryExceptions(String retryExceptions) { - this.retryExceptions = retryExceptions; - } - - public String getIgnoreExceptions() { - return ignoreExceptions; - } - - public void setIgnoreExceptions(String ignoreExceptions) { - this.ignoreExceptions = ignoreExceptions; - } - - public boolean isOnSame() { - return onSame; - } - - public void setOnSame(boolean onSame) { - this.onSame = onSame; + @Override + public boolean isValid() { + if (maxAttempts < 1) { + return false; + } + if (waitDuration < 0) { + return false; + } + return super.isValid(); } @Override @@ -113,9 +85,6 @@ public class RetryPolicy extends AbstractPolicy { "maxAttempts=" + maxAttempts + ", waitDuration=" + waitDuration + ", retryOnResponseStatus='" + retryOnResponseStatus + '\'' + - ", retryExceptions='" + retryExceptions + '\'' + - ", ignoreExceptions='" + ignoreExceptions + '\'' + - ", onSame=" + onSame + '}'; } } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/properties/GovernanceProperties.java b/governance/src/main/java/org/apache/servicecomb/governance/properties/GovernanceProperties.java index ab852eb..695adb6 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/properties/GovernanceProperties.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/properties/GovernanceProperties.java @@ -23,6 +23,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.apache.servicecomb.governance.entity.Configurable; +import org.apache.servicecomb.governance.event.ConfigurationChangedEvent; +import org.apache.servicecomb.governance.event.EventManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; @@ -42,10 +45,7 @@ import org.yaml.snakeyaml.representer.Representer; import com.google.common.eventbus.Subscribe; -import org.apache.servicecomb.governance.event.ConfigurationChangedEvent; -import org.apache.servicecomb.governance.event.EventManager; - -public abstract class GovernanceProperties<T> implements InitializingBean { +public abstract class GovernanceProperties<T extends Configurable> implements InitializingBean { private static final Logger LOGGER = LoggerFactory.getLogger(GovernanceProperties.class); private final Representer representer = new Representer(); @@ -164,6 +164,11 @@ public abstract class GovernanceProperties<T> implements InitializingBean { Yaml entityParser = new Yaml(new Constructor(new TypeDescription(entityClass, entityClass)), representer); T result = entityParser.loadAs(value, entityClass); setName(result, key); + + if (!result.isValid()) { + LOGGER.warn("Entity configuration is not valid and ignored. Key [{}], value [{}]", key, value); + return null; + } return result; } catch (YAMLException e) { LOGGER.error("governance config yaml is illegal : {}", e.getMessage()); diff --git a/governance/src/test/resources/application.yaml b/governance/src/test/resources/application.yaml index 69925df..db4ff33 100644 --- a/governance/src/test/resources/application.yaml +++ b/governance/src/test/resources/application.yaml @@ -22,6 +22,8 @@ servicecomb: - apiPath: exact: "/hello" name: match0 + wrong-name-inogred: | + wrong: some demo-retry: | matches: - apiPath: @@ -42,21 +44,34 @@ servicecomb: rules: match: demo-rateLimiting.match0 rate: 1 + wrongIngored: | + rate: 0 retry: retry0: | rules: match: demo-retry.xx maxAttempts: 3 + wrongIngored: | + rules: + wrong: 0 circuitBreaker: circuitBreaker0: | rules: match: demo-circuitBreaker.xx minimumNumberOfCalls: 2 slidingWindowSize: 2 + wrongIngored: | + rules: + match: demo-circuitBreaker.xx + minimumNumberOfCalls: -1 bulkhead: bulkhead0: | rules: match: demo-bulkhead.xx precedence: 100 maxConcurrentCalls: 1 - maxWaitDuration: 3000 \ No newline at end of file + maxWaitDuration: 3000 + wrongIngored: | + rules: + match: demo-bulkhead.xx + maxWaitDuration: -1 \ No newline at end of file
