Получите доступ к значению URITemplate или RequestLine в Feign RequestInterceptor / RequestTemplate - PullRequest
8 голосов
/ 05 апреля 2019

Я разрабатываю приложение для облачного приложения с жесткими ограничениями скорости API. Чтобы моя команда почувствовала, насколько мы близки к этим ограничениям, я хочу подсчитывать все вызовы API, сделанные из нашего приложения.

Мы используем Feign в качестве уровня доступа, и я надеялся, что смогу использовать RequestInterceptor для подсчета различных конечных точек API, которые мы называем:

RequestInterceptor ri = rq -> addStatistics(rq.url());

Теперь это не работает, так как результирующие URL почти всегда считают "1", поскольку они уже содержат все разрешенные переменные пути, поэтому я получаю счет для

1 - /something/id1valueverycryptic/get
1 - /something/anothercrypticidkey/get

и т. Д.

Я надеялся как-то получить доступ либо к значению отображения @ResuqestLine (GET /something/{id}/get), либо по крайней мере к предварительному разрешению шаблона uri (/somethine/{id}/get)

Есть ли способ сделать это?

Спасибо!

1 Ответ

3 голосов
/ 13 апреля 2019

Может быть, вы могли бы попробовать использовать пользовательскую симуляцию InvocationHandlerFactory.

Мне удалось зарегистрировать RequestInterceptor, используя такой код:

  • изменить EnableFeignClients и добавить defaultConfiguration

    @EnableFeignClients(defaultConfiguration = FeignConfig.class)
    
  • добавить стандартную конфигурацию feign

    @Configuration
    public class FeignConfig {
    
    @Bean
    @ConditionalOnMissingBean
    public Retryer feignRetryer() {
        return Retryer.NEVER_RETRY;
    }
    
    @Bean
    @Scope("prototype")
    @ConditionalOnMissingBean
    public Feign.Builder feignBuilder(Retryer retryer) {
        return Feign.builder()
                .retryer(retryer)
                .invocationHandlerFactory((target, dispatch) -> new CountingFeignInvocationHandler(target, dispatch));
    }
    
    }
    
  • создать обработчик вызова (код, основанный на feign.ReflectiveFeign.FeignInvocationHandler)

    public class CountingFeignInvocationHandler implements InvocationHandler {
    
        private final Target target;
        private final Map<Method, MethodHandler> dispatch;
    
        public CountingFeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
            this.target = checkNotNull(target, "target");
            this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if ("equals".equals(method.getName())) {
                try {
                    Object otherHandler =
                            args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
                    return equals(otherHandler);
                } catch (IllegalArgumentException e) {
                    return false;
                }
            } else if ("hashCode".equals(method.getName())) {
                return hashCode();
            } else if ("toString".equals(method.getName())) {
                return toString();
            }
    
            RequestLine requestLine = method.getAnnotation(RequestLine.class);
            addStatistics(requestLine.value());
    
            return dispatch.get(method).invoke(args);
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof CountingFeignInvocationHandler) {
                CountingFeignInvocationHandler other = (CountingFeignInvocationHandler) obj;
                return target.equals(other.target);
            }
            return false;
        }
    
        @Override
        public int hashCode() {
            return target.hashCode();
        }
    
        @Override
        public String toString() {
            return target.toString();
        }
    }
    

Будьте осторожны и проверьте, не симулировали ли вы конфигурацию, и в этом случае расширьте классы по мере необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...