Skip to content
Permalink
Browse files
GERONIMO-6591 - Allow the fallback only execution mode via config.
Made config an optional dependency, use Geronimo Config for testing.
  • Loading branch information
johnament committed Oct 8, 2017
1 parent b70e077 commit a43eeec7d6facc6267bda529250a4bbb66ba8c49
Showing 7 changed files with 142 additions and 18 deletions.
12 pom.xml
@@ -91,6 +91,18 @@
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.config</groupId>
<artifactId>microprofile-config-api</artifactId>
<version>1.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.geronimo.config</groupId>
<artifactId>geronimo-config-impl</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.fault-tolerance</groupId>
<artifactId>microprofile-fault-tolerance-api</artifactId>
@@ -59,6 +59,10 @@
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-interceptor_1.2_spec</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.config</groupId>
<artifactId>microprofile-config-api</artifactId>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
@@ -67,5 +71,9 @@
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.config</groupId>
<artifactId>geronimo-config-impl</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,35 @@
/*
* 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.safeguard.impl.executionPlans;

import javax.interceptor.InvocationContext;
import java.util.concurrent.Callable;

public class BasicExecutionPlan implements ExecutionPlan {
@Override
public <T> T execute(Callable<T> callable, InvocationContext invocationContext) {
try {
return callable.call();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -23,5 +23,5 @@
import java.util.concurrent.Callable;

public interface ExecutionPlan {
<T> T execute(Callable<T> function, InvocationContext invocationContext);
<T> T execute(Callable<T> callable, InvocationContext invocationContext);
}
@@ -28,6 +28,8 @@
import org.apache.safeguard.impl.retry.FailsafeRetryManager;
import org.apache.safeguard.impl.util.AnnotationUtil;
import org.apache.safeguard.impl.util.NamingUtil;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.faulttolerance.Asynchronous;
import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
import org.eclipse.microprofile.faulttolerance.Fallback;
@@ -38,8 +40,8 @@
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.apache.safeguard.impl.executionPlans.MicroprofileAnnotationMapper.mapCircuitBreaker;
import static org.apache.safeguard.impl.executionPlans.MicroprofileAnnotationMapper.mapRetry;
@@ -48,10 +50,12 @@ public class ExecutionPlanFactory {
private final FailsafeCircuitBreakerManager circuitBreakerManager;
private final FailsafeRetryManager retryManager;
private Map<String, ExecutionPlan> executionPlanMap = new HashMap<>();
private boolean enableAllMicroProfileFeatures = false;

public ExecutionPlanFactory(FailsafeCircuitBreakerManager circuitBreakerManager, FailsafeRetryManager retryManager) {
this.circuitBreakerManager = circuitBreakerManager;
this.retryManager = retryManager;
this.enableAllMicroProfileFeatures = this.enableNonFallbacksForMicroProfile();
}

public ExecutionPlan locateExecutionPlan(String name, Duration timeout, boolean async) {
@@ -80,28 +84,47 @@ public ExecutionPlan locateExecutionPlan(Method method) {
boolean isAsync = isAsync(method);
Duration timeout = readTimeout(method);
FallbackRunner fallbackRunner = this.createFallback(method);
if(circuitBreaker == null && retryDefinition == null && isAsync) {
if(timeout == null) {
return new AsyncOnlyExecutionPlan(null);
}
else {
if(this.enableAllMicroProfileFeatures) {
if (circuitBreaker == null && retryDefinition == null && isAsync) {
if (timeout == null) {
return new AsyncOnlyExecutionPlan(null);
} else {
return new AsyncTimeoutExecutionPlan(timeout, Executors.newFixedThreadPool(5));
}
} else if (circuitBreaker == null && retryDefinition == null && timeout != null) {
// then its just timeout
return new AsyncTimeoutExecutionPlan(timeout, Executors.newFixedThreadPool(5));
}
}
else if(circuitBreaker == null && retryDefinition == null && timeout != null) {
// then its just timeout
return new AsyncTimeoutExecutionPlan(timeout, Executors.newFixedThreadPool(5));
}
else {
if (isAsync || timeout != null) {
return new AsyncFailsafeExecutionPlan(retryDefinition, circuitBreaker, fallbackRunner, Executors.newScheduledThreadPool(5), timeout);
} else {
return new SyncFailsafeExecutionPlan(retryDefinition, circuitBreaker, fallbackRunner);
if (isAsync || timeout != null) {
return new AsyncFailsafeExecutionPlan(retryDefinition, circuitBreaker, fallbackRunner, Executors.newScheduledThreadPool(5), timeout);
} else {
return new SyncFailsafeExecutionPlan(retryDefinition, circuitBreaker, fallbackRunner);
}
}
}else {
if(fallbackRunner == null) {
return new BasicExecutionPlan();
}
else {
return new FallbackOnlyExecutionPlan(fallbackRunner);
}
}
});
}

private boolean enableNonFallbacksForMicroProfile() {
try {
Class.forName("org.eclipse.microprofile.config.Config");
Config config = ConfigProvider.getConfig();
AtomicBoolean disableExecutions = new AtomicBoolean(true);
config.getOptionalValue("MP_Fault_Tolerance_NonFallback_Enabled", Boolean.class)
.ifPresent(disableExecutions::set);
return disableExecutions.get();
} catch (ClassNotFoundException e) {
return true;
}
}

private FailsafeRetryDefinition createDefinition(String name, Method method) {
Retry retry = AnnotationUtil.getAnnotation(method, Retry.class);
if (retry == null) {
@@ -0,0 +1,43 @@
/*
* 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.safeguard.impl.executionPlans;

import org.apache.safeguard.impl.fallback.FallbackRunner;

import javax.interceptor.InvocationContext;
import java.util.concurrent.Callable;

public class FallbackOnlyExecutionPlan implements ExecutionPlan {
private final FallbackRunner fallbackRunner;

public FallbackOnlyExecutionPlan(FallbackRunner fallbackRunner) {
this.fallbackRunner = fallbackRunner;
}

@Override
public <T> T execute(Callable<T> callable, InvocationContext invocationContext) {
try {
return callable.call();
}
catch (Exception e) {
return (T)fallbackRunner.executeFallback(invocationContext);
}
}
}
@@ -56,6 +56,10 @@
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-interceptor_1.2_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.config</groupId>
<artifactId>geronimo-config-impl</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
@@ -73,7 +77,6 @@
<exclude>org.eclipse.microprofile.fault.tolerance.tck.bulkhead.BulkheadFutureTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.bulkhead.BulkheadSynchRetryTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.bulkhead.BulkheadSynchTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.disableEnv.DisableTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.illegalConfig.IncompatibleFallbackMethodTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.illegalConfig.IncompatibleFallbackMethodWithArgsTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.illegalConfig.IncompatibleFallbackTest</exclude>

0 comments on commit a43eeec

Please sign in to comment.