001package io.freefair.spring.okhttp;
002
003import okhttp3.OkHttpClient;
004import org.springframework.beans.factory.ObjectProvider;
005import org.springframework.boot.autoconfigure.AutoConfiguration;
006import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
007import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
008import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
009import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
010import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
011import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
012import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
013import org.springframework.boot.web.client.RestTemplateBuilder;
014import org.springframework.boot.web.client.RestTemplateCustomizer;
015import org.springframework.boot.web.client.RestTemplateRequestCustomizer;
016import org.springframework.context.annotation.Bean;
017import org.springframework.context.annotation.Conditional;
018import org.springframework.context.annotation.Lazy;
019import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
020import org.springframework.web.client.RestTemplate;
021
022import java.util.Collection;
023import java.util.List;
024import java.util.function.BiFunction;
025import java.util.stream.Collectors;
026
027/**
028 * @author Lars Grefer
029 * @see RestTemplateAutoConfiguration
030 */
031@AutoConfiguration(before = RestTemplateAutoConfiguration.class, after = HttpMessageConvertersAutoConfiguration.class)
032@ConditionalOnClass({RestTemplateCustomizer.class, RestTemplate.class})
033@Conditional(OkHttpRestTemplateAutoConfiguration.NotReactiveWebApplicationCondition.class)
034public class OkHttpRestTemplateAutoConfiguration {
035
036    @Bean
037    @Lazy
038    @ConditionalOnMissingBean
039    public RestTemplateBuilder restTemplateBuilder(ObjectProvider<HttpMessageConverters> messageConverters,
040                                                   ObjectProvider<RestTemplateCustomizer> restTemplateCustomizers,
041                                                   ObjectProvider<RestTemplateRequestCustomizer<?>> restTemplateRequestCustomizers,
042                                                   OkHttpClient okHttpClient) {
043        RestTemplateBuilder builder = new RestTemplateBuilder();
044        HttpMessageConverters converters = messageConverters.getIfUnique();
045        if (converters != null) {
046            builder = builder.messageConverters(converters.getConverters());
047        }
048        builder = addCustomizers(builder, restTemplateCustomizers, RestTemplateBuilder::customizers);
049        builder = addCustomizers(builder, restTemplateRequestCustomizers, RestTemplateBuilder::requestCustomizers);
050
051        builder = builder.requestFactory(() -> new OkHttp3ClientHttpRequestFactory(okHttpClient));
052
053        return builder;
054    }
055
056    private <T> RestTemplateBuilder addCustomizers(RestTemplateBuilder builder, ObjectProvider<T> objectProvider,
057                                                   BiFunction<RestTemplateBuilder, Collection<T>, RestTemplateBuilder> method) {
058        List<T> customizers = objectProvider.orderedStream().collect(Collectors.toList());
059        if (!customizers.isEmpty()) {
060            return method.apply(builder, customizers);
061        }
062        return builder;
063    }
064
065    static class NotReactiveWebApplicationCondition extends NoneNestedConditions {
066
067        NotReactiveWebApplicationCondition() {
068            super(ConfigurationPhase.PARSE_CONFIGURATION);
069        }
070
071        @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
072        private static class ReactiveWebApplication {
073
074        }
075
076    }
077
078}