Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2019-2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://github.com/payara/Payara/blob/main/LICENSE.txt
* See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* The Payara Foundation designates this particular file as subject to the "Classpath"
* exception as provided by the Payara Foundation in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package fish.payara.microprofile.faulttolerance.policy;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import jakarta.interceptor.InvocationContext;
import org.eclipse.microprofile.faulttolerance.exceptions.BulkheadException;
import org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException;
import org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceDefinitionException;
import org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceException;
import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
import fish.payara.microprofile.faulttolerance.FaultToleranceConfig;
import fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext;
import fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture;
import fish.payara.microprofile.faulttolerance.FaultToleranceService;
import fish.payara.microprofile.faulttolerance.FaultToleranceMetrics;
import fish.payara.microprofile.faulttolerance.state.CircuitBreakerState;
/**
* The {@link FaultTolerancePolicy} describes the effective aggregated policies to use for a particular {@link Method}
* when adding fault tolerant behaviour to it.
*
* The policies are extracted from FT annotations and the {@link FaultToleranceConfig}.
*
* In contrast to the plain annotations the policies do consider configuration overrides and include validation of the
* effective values.
*
* The policy class also reduces the need to analyse FT annotations for each invocation and works as a consistent source
* of truth throughout the processing of FT behaviour that is convenient to pass around as a single immutable value.
*
* @author Jan Bernitt
*/
public final class FaultTolerancePolicy implements Serializable {
static final Logger logger = Logger.getLogger(FaultTolerancePolicy.class.getName());
private static final long TTL = 60 * 1000;
/**
* A simple cache with a fix {@link #TTL} with a policy for each target method.
*/
private static final ConcurrentHashMap, Map> POLICY_BY_METHOD
= new ConcurrentHashMap<>();
/**
* Removes all expired policies from the cache.
*/
public static void clean() {
long now = System.currentTimeMillis();
POLICY_BY_METHOD.forEachValue(Long.MAX_VALUE,
map -> map.entrySet().removeIf(entry -> now > entry.getValue().expiresMillis));
}
/**
* Removes all expired policies from the cache and all policies related to this classloader
*/
public static void clean(ClassLoader appClassLoader) {
long now = System.currentTimeMillis();
POLICY_BY_METHOD.entrySet().removeIf(entry -> entry.getKey().getClassLoader().equals(appClassLoader));
clean();
}
public static FaultTolerancePolicy asAnnotated(Class> target, Method annotated) {
return create(new StaticAnalysisContext(target, annotated),
FaultToleranceConfig.asAnnotated(target, annotated));
}
/**
* Returns the {@link FaultTolerancePolicy} to use for the method invoked in the current context.
*
* @param context current context
* @param configSpplier supplies the configuration (if needed, in case returned policy needs to be created with help
* of the {@link FaultToleranceConfig})
* @return the policy to apply
* @throws FaultToleranceDefinitionException in case the effective policy contains illegal values
*/
public static FaultTolerancePolicy get(InvocationContext context, Supplier configSpplier)
throws FaultToleranceDefinitionException {
return POLICY_BY_METHOD.computeIfAbsent(context.getTarget().getClass(), target -> new ConcurrentHashMap<>())
.compute(context.getMethod(), (method, policy) ->
policy != null && !policy.isExpired() ? policy : create(context, configSpplier.get()));
}
private static FaultTolerancePolicy create(InvocationContext context, FaultToleranceConfig config) {
return new FaultTolerancePolicy(
config.isNonFallbackEnabled(),
config.isMetricsEnabled(),
AsynchronousPolicy.create(context, config),
BulkheadPolicy.create(context, config),
CircuitBreakerPolicy.create(context, config),
FallbackPolicy.create(context, config),
RetryPolicy.create(context, config),
TimeoutPolicy.create(context, config));
}
private final long expiresMillis;
public final boolean isPresent;
public final boolean isNonFallbackEnabled;
public final boolean isMetricsEnabled;
public final AsynchronousPolicy asynchronous;
public final BulkheadPolicy bulkhead;
public final CircuitBreakerPolicy circuitBreaker;
public final FallbackPolicy fallback;
public final RetryPolicy retry;
public final TimeoutPolicy timeout;
public FaultTolerancePolicy(boolean isNonFallbackEnabled, boolean isMetricsEnabled, AsynchronousPolicy asynchronous,
BulkheadPolicy bulkhead, CircuitBreakerPolicy circuitBreaker, FallbackPolicy fallback, RetryPolicy retry,
TimeoutPolicy timeout) {
this.expiresMillis = System.currentTimeMillis() + TTL;
this.isNonFallbackEnabled = isNonFallbackEnabled;
this.isMetricsEnabled = isMetricsEnabled;
this.asynchronous = asynchronous;
this.bulkhead = bulkhead;
this.circuitBreaker = circuitBreaker;
this.fallback = fallback;
this.retry = retry;
this.timeout = timeout;
this.isPresent = isAsynchronous() || isBulkheadPresent() || isCircuitBreakerPresent()
|| isFallbackPresent() || isRetryPresent() || isTimeoutPresent();
}
private boolean isExpired() {
return System.currentTimeMillis() > expiresMillis;
}
public boolean isAsynchronous() {
return asynchronous != null;
}
public boolean isBulkheadPresent() {
return bulkhead != null;
}
public boolean isCircuitBreakerPresent() {
return circuitBreaker != null;
}
public boolean isFallbackPresent() {
return fallback != null;
}
public boolean isRetryPresent() {
return retry != null;
}
public boolean isTimeoutPresent() {
return timeout != null;
}
static final class FaultToleranceInvocation {
final FaultToleranceMethodContext context;
final FaultToleranceMetrics metrics;
final CompletableFuture