package com.netflix.ribbon.hystrix; import com.netflix.hystrix.HystrixObservableCommand; import rx.Observable; import rx.functions.Func1; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * This class implements chaining mechanism for Hystrix commands. If a command in a chain fails, the next one * is run. If all commands in the chain failed, the error from the last one is reported. * To be able to identify the Hystrix command for which request was executed, an {@link ResultCommandPair} event * stream is returned by {@link #toResultCommandPairObservable()} method. * If information about Hystrix command is not important, {@link #toObservable()} method shall be used, which * is more efficient. * * @author Tomasz Bak */ public class HystrixObservableCommandChain<T> { private final List<HystrixObservableCommand<T>> hystrixCommands; public HystrixObservableCommandChain(List<HystrixObservableCommand<T>> hystrixCommands) { this.hystrixCommands = hystrixCommands; } public HystrixObservableCommandChain(HystrixObservableCommand<T>... commands) { hystrixCommands = new ArrayList<HystrixObservableCommand<T>>(commands.length); Collections.addAll(hystrixCommands, commands); } public Observable<ResultCommandPair<T>> toResultCommandPairObservable() { Observable<ResultCommandPair<T>> rootObservable = null; for (final HystrixObservableCommand<T> command : hystrixCommands) { Observable<ResultCommandPair<T>> observable = command.toObservable().map(new Func1<T, ResultCommandPair<T>>() { @Override public ResultCommandPair<T> call(T result) { return new ResultCommandPair<T>(result, command); } }); rootObservable = rootObservable == null ? observable : rootObservable.onErrorResumeNext(observable); } return rootObservable; } public Observable<T> toObservable() { Observable<T> rootObservable = null; for (final HystrixObservableCommand<T> command : hystrixCommands) { Observable<T> observable = command.toObservable(); rootObservable = rootObservable == null ? observable : rootObservable.onErrorResumeNext(observable); } return rootObservable; } public List<HystrixObservableCommand<T>> getCommands() { return Collections.unmodifiableList(hystrixCommands); } public HystrixObservableCommand getLastCommand() { return hystrixCommands.get(hystrixCommands.size() - 1); } }