Search in sources :

Example 1 with MethodHandler

use of feign.InvocationHandlerFactory.MethodHandler in project resilience4j by resilience4j.

the class DecoratorInvocationHandlerTest method setUp.

@Before
public void setUp() throws Throwable {
    target = new HardCodedTarget<TestService>(TestService.class, TestService.class.getSimpleName());
    testService = new TestServiceImpl();
    greetingMethod = testService.getClass().getDeclaredMethod("greeting");
    feignDecorator = new TestFeignDecorator();
    methodHandler = mock(MethodHandler.class);
    when(methodHandler.invoke(any())).thenReturn(testService.greeting());
    dispatch = new HashMap<>();
    dispatch.put(greetingMethod, methodHandler);
    testSubject = new DecoratorInvocationHandler(target, dispatch, feignDecorator);
}
Also used : MethodHandler(feign.InvocationHandlerFactory.MethodHandler) TestService(io.github.resilience4j.feign.test.TestService) TestFeignDecorator(io.github.resilience4j.feign.test.TestFeignDecorator) TestServiceImpl(io.github.resilience4j.feign.test.TestServiceImpl) Before(org.junit.Before)

Example 2 with MethodHandler

use of feign.InvocationHandlerFactory.MethodHandler in project ByteTCC by liuyangming.

the class CompensableHystrixBeanPostProcessor method createProxiedObject.

@SuppressWarnings("unchecked")
private Object createProxiedObject(Object origin) {
    InvocationHandler handler = Proxy.getInvocationHandler(origin);
    final CompensableHystrixFeignHandler feignHandler = new CompensableHystrixFeignHandler();
    feignHandler.setDelegate(handler);
    Class<?> clazz = origin.getClass();
    Class<?>[] interfaces = clazz.getInterfaces();
    ClassLoader loader = clazz.getClassLoader();
    try {
        Field dispatchField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_DISPATH);
        dispatchField.setAccessible(true);
        Map<Method, MethodHandler> dispatch = (Map<Method, MethodHandler>) dispatchField.get(handler);
        Field setterField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_SETTERS);
        setterField.setAccessible(true);
        Map<Method, Setter> setterMap = (Map<Method, Setter>) setterField.get(handler);
        Field groupKeyField = Setter.class.getDeclaredField(HYSTRIX_SETTER_GRPKEY);
        groupKeyField.setAccessible(true);
        Field fallbackField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_FALLBACK);
        fallbackField.setAccessible(true);
        Map<Method, Method> fallbackMap = (Map<Method, Method>) fallbackField.get(handler);
        Field targetField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_TARGET);
        targetField.setAccessible(true);
        Target<?> target = (Target<?>) targetField.get(handler);
        Field factoryField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_FACTORY);
        factoryField.setAccessible(true);
        FallbackFactory<?> factory = (FallbackFactory<?>) factoryField.get(handler);
        if (factory != null) {
            if (FallbackFactory.Default.class.isInstance(factory)) {
                Field constantField = FallbackFactory.Default.class.getDeclaredField(HYSTRIX_FIELD_CONSTANT);
                constantField.setAccessible(true);
                Object constant = constantField.get(factory);
                CompensableHystrixFallbackHandler fallback = new CompensableHystrixFallbackHandler(constant);
                Object proxy = Proxy.newProxyInstance(constant.getClass().getClassLoader(), new Class<?>[] { CompensableHystrixInvocationHandler.class, target.type() }, fallback);
                constantField.set(factory, proxy);
            } else {
                CompensableHystrixFallbackFactoryHandler factoryHandler = new CompensableHystrixFallbackFactoryHandler(factory, target.type());
                FallbackFactory<?> proxy = (FallbackFactory<?>) Proxy.newProxyInstance(factory.getClass().getClassLoader(), new Class<?>[] { FallbackFactory.class }, factoryHandler);
                factoryField.set(handler, proxy);
            }
        }
        // end-if (factory != null)
        HystrixCommandGroupKey hystrixCommandGroupKey = null;
        for (Iterator<Map.Entry<Method, Setter>> itr = setterMap.entrySet().iterator(); hystrixCommandGroupKey == null && itr.hasNext(); ) {
            Map.Entry<Method, Setter> entry = itr.next();
            Setter setter = entry.getValue();
            hystrixCommandGroupKey = setter == null ? hystrixCommandGroupKey : (HystrixCommandGroupKey) groupKeyField.get(setter);
        }
        final String commandGroupKeyName = hystrixCommandGroupKey == null ? null : hystrixCommandGroupKey.name();
        HystrixCommandGroupKey groupKey = new HystrixCommandGroupKey() {

            public String name() {
                return commandGroupKeyName;
            }
        };
        HystrixCommandKey commandKey = new HystrixCommandKey() {

            public String name() {
                return HYSTRIX_COMMAND_NAME;
            }
        };
        CompensableHystrixMethodHandler hystrixHandler = new CompensableHystrixMethodHandler(dispatch);
        hystrixHandler.setStatefully(this.statefully);
        Setter setter = Setter.withGroupKey(groupKey).andCommandKey(commandKey);
        Method key = CompensableHystrixInvocationHandler.class.getDeclaredMethod(HYSTRIX_INVOKER_NAME, new Class<?>[] { CompensableHystrixInvocation.class });
        setterMap.put(key, setter);
        dispatch.put(key, hystrixHandler);
        fallbackMap.put(key, key);
    } catch (Exception ex) {
        throw new IllegalStateException("Error occurred!");
    }
    return Proxy.newProxyInstance(loader, interfaces, feignHandler);
}
Also used : HystrixCommandKey(com.netflix.hystrix.HystrixCommandKey) Field(java.lang.reflect.Field) MethodHandler(feign.InvocationHandlerFactory.MethodHandler) Target(feign.Target) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler) HystrixCommandGroupKey(com.netflix.hystrix.HystrixCommandGroupKey) BeansException(org.springframework.beans.BeansException) FallbackFactory(feign.hystrix.FallbackFactory) Setter(com.netflix.hystrix.HystrixCommand.Setter) Map(java.util.Map)

Example 3 with MethodHandler

use of feign.InvocationHandlerFactory.MethodHandler in project feign by OpenFeign.

the class ReflectiveFeign method newInstance.

/**
 * creates an api binding to the {@code target}. As this invokes reflection, care should be taken
 * to cache the result.
 */
@SuppressWarnings("unchecked")
@Override
public <T> T newInstance(Target<T> target) {
    Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
    Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
    List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();
    for (Method method : target.type().getMethods()) {
        if (method.getDeclaringClass() == Object.class) {
            continue;
        } else if (Util.isDefault(method)) {
            DefaultMethodHandler handler = new DefaultMethodHandler(method);
            defaultMethodHandlers.add(handler);
            methodToHandler.put(method, handler);
        } else {
            methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
        }
    }
    InvocationHandler handler = factory.create(target, methodToHandler);
    T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[] { target.type() }, handler);
    for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
        defaultMethodHandler.bindTo(proxy);
    }
    return proxy;
}
Also used : MethodHandler(feign.InvocationHandlerFactory.MethodHandler) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler)

Example 4 with MethodHandler

use of feign.InvocationHandlerFactory.MethodHandler in project resilience4j by resilience4j.

the class DecoratorInvocationHandler method decorateMethodHandlers.

/**
 * Applies the specified {@link FeignDecorator} to all specified {@link MethodHandler}s and
 * returns the result as a map of {@link CheckedFunction}s. Invoking a {@link CheckedFunction}
 * will therefore invoke the decorator which, in turn, may invoke the corresponding {@link
 * MethodHandler}.
 *
 * @param dispatch            a map of the methods from the feign interface to the {@link
 *                            MethodHandler}s.
 * @param invocationDecorator the {@link FeignDecorator} with which to decorate the {@link
 *                            MethodHandler}s.
 * @param target              the target feign interface.
 * @return a new map where the {@link MethodHandler}s are decorated with the {@link
 * FeignDecorator}.
 */
private Map<Method, CheckedFunction<Object[], Object>> decorateMethodHandlers(Map<Method, MethodHandler> dispatch, FeignDecorator invocationDecorator, Target<?> target) {
    final Map<Method, CheckedFunction<Object[], Object>> map = new HashMap<>();
    for (final Map.Entry<Method, MethodHandler> entry : dispatch.entrySet()) {
        final Method method = entry.getKey();
        final MethodHandler methodHandler = entry.getValue();
        if (methodHandler != null) {
            CheckedFunction<Object[], Object> decorated = invocationDecorator.decorate(methodHandler::invoke, method, methodHandler, target);
            map.put(method, decorated);
        }
    }
    return map;
}
Also used : MethodHandler(feign.InvocationHandlerFactory.MethodHandler) HashMap(java.util.HashMap) Method(java.lang.reflect.Method) Map(java.util.Map) HashMap(java.util.HashMap) CheckedFunction(io.github.resilience4j.core.functions.CheckedFunction)

Aggregations

MethodHandler (feign.InvocationHandlerFactory.MethodHandler)4 Method (java.lang.reflect.Method)3 InvocationHandler (java.lang.reflect.InvocationHandler)2 Map (java.util.Map)2 Setter (com.netflix.hystrix.HystrixCommand.Setter)1 HystrixCommandGroupKey (com.netflix.hystrix.HystrixCommandGroupKey)1 HystrixCommandKey (com.netflix.hystrix.HystrixCommandKey)1 Target (feign.Target)1 FallbackFactory (feign.hystrix.FallbackFactory)1 CheckedFunction (io.github.resilience4j.core.functions.CheckedFunction)1 TestFeignDecorator (io.github.resilience4j.feign.test.TestFeignDecorator)1 TestService (io.github.resilience4j.feign.test.TestService)1 TestServiceImpl (io.github.resilience4j.feign.test.TestServiceImpl)1 Field (java.lang.reflect.Field)1 HashMap (java.util.HashMap)1 Before (org.junit.Before)1 BeansException (org.springframework.beans.BeansException)1