package org.zalando.nakadi.config;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.zalando.nakadi.metrics.MetricUtils;
import org.zalando.stups.oauth2.spring.server.TokenInfoResourceServerTokenServices;

@Configuration
@Profile("!test")
public class AuthenticationConfig {

    @Bean
    public ResourceServerTokenServices zalandoResourceTokenServices(final SecuritySettings settings,
                                                                    final MetricRegistry metricRegistry) {
        return new MeasuringTokenInfoResourceServerTokenServices(
                settings.getTokenInfoUrl(), settings.getClientId(), metricRegistry);
    }

    public static class MeasuringTokenInfoResourceServerTokenServices extends TokenInfoResourceServerTokenServices {
        private final Timer timer;

        public MeasuringTokenInfoResourceServerTokenServices(final String tokenInfoEndpointUrl, final String clientId,
                                                             final MetricRegistry metricRegistry) {
            super(tokenInfoEndpointUrl, clientId);
            timer = metricRegistry.timer(MetricUtils.NAKADI_PREFIX + "general.accessTokenValidation");
        }

        @Override
        public OAuth2Authentication loadAuthentication(final String accessToken) throws AuthenticationException {
            final Timer.Context context = timer.time();
            try {
                return super.loadAuthentication(accessToken);
            } finally {
                context.stop();
            }
        }
    }
}

@@ -108,16 +108,289 @@
 .Timer;%0A
+import org.apache.http.client.HttpClient;%0Aimport org.apache.http.client.config.RequestConfig;%0Aimport org.apache.http.impl.client.CloseableHttpClient;%0Aimport org.apache.http.impl.client.HttpClientBuilder;%0Aimport org.apache.http.impl.conn.PoolingHttpClientConnectionManager;%0A
 import o
@@ -549,16 +549,95 @@
 rofile;%0A
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;%0A
 import o
@@ -870,42 +870,251 @@
 org.
-zalando.nakadi.metrics.MetricUtils
+springframework.web.client.RestTemplate;%0Aimport org.zalando.nakadi.metrics.MetricUtils;%0Aimport org.zalando.stups.oauth2.spring.authorization.DefaultUserRolesProvider;%0Aimport org.zalando.stups.oauth2.spring.server.DefaultAuthenticationExtractor
 ;%0Aim
@@ -1472,32 +1472,133 @@
 y metricRegistry
+,%0A                                                                    final RestTemplate restTemplate
 ) %7B%0A        retu
@@ -1733,16 +1733,30 @@
 Registry
+, restTemplate
 );%0A    %7D
@@ -2005,16 +2005,77 @@
 ointUrl,
+%0A                                                            
  final S
@@ -2190,60 +2190,318 @@
 stry
-) %7B%0A            super(tokenInfoEndpointUrl, clientId
+,%0A                                                             final RestTemplate restTemplate) %7B%0A            super(tokenInfoEndpointUrl,%0A                    clientId,%0A                    new DefaultAuthenticationExtractor(),%0A                    new DefaultUserRolesProvider(),%0A                    restTemplate
 );%0A 
@@ -2966,11 +2966,1391 @@
  %7D%0A    %7D
+%0A%0A    @Bean%0A    public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() %7B%0A        final PoolingHttpClientConnectionManager result = new PoolingHttpClientConnectionManager();%0A        result.setMaxTotal(20);%0A        result.setDefaultMaxPerRoute(20);%0A        return result;%0A    %7D%0A%0A    @Bean%0A    public RequestConfig requestConfig() %7B%0A        final RequestConfig result = RequestConfig.custom()%0A                .setConnectionRequestTimeout(500)%0A                .setConnectTimeout(1000)%0A                .setSocketTimeout(2000)%0A                .build();%0A        return result;%0A    %7D%0A%0A    @Bean%0A    public CloseableHttpClient httpClient(final PoolingHttpClientConnectionManager poolingHttpClientConnectionManager,%0A                                          final RequestConfig requestConfig) %7B%0A        final CloseableHttpClient result = HttpClientBuilder%0A                .create()%0A                .setConnectionManager(poolingHttpClientConnectionManager)%0A                .setDefaultRequestConfig(requestConfig)%0A                .build();%0A        return result;%0A    %7D%0A%0A    @Bean%0A    public RestTemplate restTemplate(final HttpClient httpClient) %7B%0A        final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();%0A        requestFactory.setHttpClient(httpClient);%0A        return new RestTemplate(requestFactory);%0A    %7D
 %0A%7D%0A

set max per route open connections to 20