/**
* Copyright 2014 Opower, Inc.
* Licensed 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 com.opower.rest.client.generator.hystrix;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.netflix.hystrix.HystrixCommand;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import static com.google.common.base.Preconditions.checkArgument;
/**
*
* Generic HystrixCommand used by the HystrixClientBuilder to wrap ResourceInterface method invocations.
* Not for use outside this package.
*
*/
final class ProxyCommand extends HystrixCommand {
private final Method toinvoke;
private final Object[] args;
private final Optional<Callable<Object>> fallback;
private final Object target;
/**
* Creates a Proxy command with the specified settings.
* @param setter the HystrixCommand.Setter to use
* @param toinvoke the Method to be invoked
* @param args the arguments for the method to be invoked
* @param fallback the fallback Hystrix will use
* @param target this ProxyCommand will invoke the provided method on this target object
*/
ProxyCommand(Setter setter, Method toinvoke, Object[] args, Callable<Object> fallback, Object target) {
super(setter);
this.toinvoke = toinvoke;
this.args = args;
this.target = target;
this.fallback = Optional.fromNullable(fallback);
checkArgument(toinvoke.getDeclaringClass().isInstance(target), "The method to invoke must be present on the target object");
checkArgument(!getProperties().fallbackEnabled().get() || this.fallback.isPresent(),
String.format("You didn't provide a fallback for %s.%s. You must either provide a "
+ "fallback or disable fallbacks "
+ "in the HystrixCommandProperties for this method.",
toinvoke.getDeclaringClass().getCanonicalName(), toinvoke.getName()));
}
@Override
protected Object run() throws Exception {
try {
return this.toinvoke.invoke(this.target, this.args);
} catch (InvocationTargetException ex) {
throw Throwables.propagate(ex.getTargetException());
}
}
@Override
protected Object getFallback() {
if (this.fallback.isPresent()) {
try {
return this.fallback.get().call();
} catch (Exception e) {
throw Throwables.propagate(e);
}
} else {
return super.getFallback();
}
}
}