| /* |
| * 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.policy; |
| |
| import java.time.Duration; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.springframework.util.CollectionUtils; |
| |
| public class RetryPolicy extends AbstractPolicy { |
| |
| public static final int DEFAULT_MAX_ATTEMPTS = 3; |
| |
| public static final Duration DEFAULT_WAIT_DURATION = Duration.ofMillis(10); |
| |
| public static final String DEFAULT_RETRY_ON_RESPONSE_STATUS = "502"; |
| |
| private static final Duration INITIAL_INTERVAL = Duration.ofMillis(1000); |
| |
| private static final float MULTIPLIER = 2; |
| |
| private static final double RANDOMIZATION_FACTOR = 0.5; |
| |
| private static final String DEFAULT_RETRY_STRATEGY = "FixedInterval"; |
| |
| //max retry attempts |
| private int maxAttempts = DEFAULT_MAX_ATTEMPTS; |
| |
| //wait duration for each retry |
| private String waitDuration = DEFAULT_WAIT_DURATION.toString(); |
| |
| //status code that need retry |
| private List<String> retryOnResponseStatus = new ArrayList<>(); |
| |
| //retry strategy |
| private String retryStrategy = DEFAULT_RETRY_STRATEGY; |
| |
| // initial interval for backoff retry |
| private String initialInterval = INITIAL_INTERVAL.toString(); |
| |
| // multiplier for backoff retry |
| private float multiplier = MULTIPLIER; |
| |
| // randomization factor for backoff retry |
| private double randomizationFactor = RANDOMIZATION_FACTOR; |
| |
| private boolean failAfterMaxAttempts = false; |
| |
| public List<String> getRetryOnResponseStatus() { |
| if (CollectionUtils.isEmpty(retryOnResponseStatus)) { |
| this.retryOnResponseStatus.add(DEFAULT_RETRY_ON_RESPONSE_STATUS); |
| } |
| return retryOnResponseStatus; |
| } |
| |
| public void setRetryOnResponseStatus(List<String> retryOnResponseStatus) { |
| this.retryOnResponseStatus = retryOnResponseStatus; |
| } |
| |
| public int getMaxAttempts() { |
| return maxAttempts; |
| } |
| |
| public void setMaxAttempts(int maxAttempts) { |
| this.maxAttempts = maxAttempts; |
| } |
| |
| public String getWaitDuration() { |
| return Duration.parse(waitDuration).toMillis() < 10 ? DEFAULT_WAIT_DURATION.toString() : waitDuration; |
| } |
| |
| public void setWaitDuration(String waitDuration) { |
| this.waitDuration = stringOfDuration(waitDuration, DEFAULT_WAIT_DURATION); |
| } |
| |
| public String getRetryStrategy() { |
| if (StringUtils.isEmpty(retryStrategy)) { |
| retryStrategy = DEFAULT_RETRY_STRATEGY; |
| } |
| return retryStrategy; |
| } |
| |
| public void setRetryStrategy(String retryStrategy) { |
| this.retryStrategy = retryStrategy; |
| } |
| |
| public String getInitialInterval() { |
| return initialInterval; |
| } |
| |
| public void setInitialInterval(String initialInterval) { |
| this.initialInterval = stringOfDuration(initialInterval, INITIAL_INTERVAL); |
| } |
| |
| public float getMultiplier() { |
| return multiplier; |
| } |
| |
| public void setMultiplier(float multiplier) { |
| this.multiplier = multiplier; |
| } |
| |
| public double getRandomizationFactor() { |
| return randomizationFactor; |
| } |
| |
| public void setRandomizationFactor(double randomizationFactor) { |
| this.randomizationFactor = randomizationFactor; |
| } |
| |
| public boolean isFailAfterMaxAttempts() { |
| return failAfterMaxAttempts; |
| } |
| |
| public RetryPolicy setFailAfterMaxAttempts(boolean failAfterMaxAttempts) { |
| this.failAfterMaxAttempts = failAfterMaxAttempts; |
| return this; |
| } |
| |
| @Override |
| public boolean isValid() { |
| if (maxAttempts < 1) { |
| return false; |
| } |
| if (Duration.parse(waitDuration).toMillis() < 0) { |
| return false; |
| } |
| if (Duration.parse(initialInterval).toMillis() < 10) { |
| return false; |
| } |
| return super.isValid(); |
| } |
| |
| @Override |
| public String toString() { |
| return "RetryPolicy{" + |
| "maxAttempts=" + maxAttempts + |
| ", waitDuration=" + waitDuration + |
| ", retryOnResponseStatus='" + retryOnResponseStatus + '\'' + |
| '}'; |
| } |
| } |