All Downloads are FREE. Search and download functionalities are using the official Maven repository.

feign.hystrix.HystrixFeign Maven / Gradle / Ivy

There is a newer version: 9.2.0
Show newest version
/*
 * Copyright © 2012 The Feign Authors ([email protected])
 *
 * 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 feign.hystrix;

import com.netflix.hystrix.HystrixCommand;
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.InvocationHandlerFactory;
import feign.Logger;
import feign.Request;
import feign.RequestInterceptor;
import feign.ResponseMapper;
import feign.Retryer;
import feign.Target;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Allows Feign interfaces to return HystrixCommand or rx.Observable or rx.Single objects. Also
 * decorates normal Feign methods with circuit breakers, but calls {@link HystrixCommand#execute()}
 * directly.
 */
public final class HystrixFeign {

  public static Builder builder() {
    return new Builder();
  }

  public static final class Builder extends Feign.Builder {

    private Contract contract = new Contract.Default();
    private SetterFactory setterFactory = new SetterFactory.Default();

    /** Allows you to override hystrix properties such as thread pools and command keys. */
    public Builder setterFactory(SetterFactory setterFactory) {
      this.setterFactory = setterFactory;
      return this;
    }

    /**
     * @see #target(Class, String, Object)
     */
    public  T target(Target target, T fallback) {
      return build(fallback != null ? new FallbackFactory.Default(fallback) : null)
          .newInstance(target);
    }

    /**
     * @see #target(Class, String, FallbackFactory)
     */
    public  T target(Target target, FallbackFactory fallbackFactory) {
      return build(fallbackFactory).newInstance(target);
    }

    /**
     * Like {@link Feign#newInstance(Target)}, except with {@link HystrixCommand#getFallback()
     * fallback} support.
     *
     * 

Fallbacks are known values, which you return when there's an error invoking an http * method. For example, you can return a cached result as opposed to raising an error to the * caller. To use this feature, pass a safe implementation of your target interface as the last * parameter. * *

Here's an example: * *

{@code
     * // When dealing with fallbacks, it is less tedious to keep interfaces small.
     * interface GitHub {
     *   @RequestLine("GET /repos/{owner}/{repo}/contributors")
     *   List contributors(@Param("owner") String owner, @Param("repo") String repo);
     * }
     *
     * // This instance will be invoked if there are errors of any kind.
     * GitHub fallback = (owner, repo) -> {
     *   if (owner.equals("Netflix") && repo.equals("feign")) {
     *     return Arrays.asList("stuarthendren"); // inspired this approach!
     *   } else {
     *     return Collections.emptyList();
     *   }
     * };
     *
     * GitHub github = HystrixFeign.builder()
     *                             ...
     *                             .target(GitHub.class, "https://api.github.com", fallback);
     * }
* * @see #target(Target, Object) */ public T target(Class apiType, String url, T fallback) { return target(new Target.HardCodedTarget(apiType, url), fallback); } /** * Same as {@link #target(Class, String, T)}, except you can inspect a source exception before * creating a fallback object. */ public T target( Class apiType, String url, FallbackFactory fallbackFactory) { return target(new Target.HardCodedTarget(apiType, url), fallbackFactory); } @Override public Feign.Builder invocationHandlerFactory( InvocationHandlerFactory invocationHandlerFactory) { throw new UnsupportedOperationException(); } @Override public Builder contract(Contract contract) { this.contract = contract; return this; } @Override public Feign internalBuild() { return build(null); } /** Configures components needed for hystrix integration. */ Feign build(final FallbackFactory nullableFallbackFactory) { super.invocationHandlerFactory( new InvocationHandlerFactory() { @Override public InvocationHandler create(Target target, Map dispatch) { return new HystrixInvocationHandler( target, dispatch, setterFactory, nullableFallbackFactory); } }); super.contract(new HystrixDelegatingContract(contract)); return super.internalBuild(); } // Covariant overrides to support chaining to new fallback method. @Override public Builder logLevel(Logger.Level logLevel) { return (Builder) super.logLevel(logLevel); } @Override public Builder client(Client client) { return (Builder) super.client(client); } @Override public Builder retryer(Retryer retryer) { return (Builder) super.retryer(retryer); } @Override public Builder logger(Logger logger) { return (Builder) super.logger(logger); } @Override public Builder encoder(Encoder encoder) { return (Builder) super.encoder(encoder); } @Override public Builder decoder(Decoder decoder) { return (Builder) super.decoder(decoder); } @Override public Builder mapAndDecode(ResponseMapper mapper, Decoder decoder) { return (Builder) super.mapAndDecode(mapper, decoder); } @Override public Builder decode404() { return (Builder) super.decode404(); } @Override public Builder dismiss404() { return (Builder) super.dismiss404(); } @Override public Builder errorDecoder(ErrorDecoder errorDecoder) { return (Builder) super.errorDecoder(errorDecoder); } @Override public Builder options(Request.Options options) { return (Builder) super.options(options); } @Override public Builder requestInterceptor(RequestInterceptor requestInterceptor) { return (Builder) super.requestInterceptor(requestInterceptor); } @Override public Builder requestInterceptors(Iterable requestInterceptors) { return (Builder) super.requestInterceptors(requestInterceptors); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy