001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.elasticsearch.jest; 018 019import java.time.Duration; 020 021import com.google.gson.Gson; 022import io.searchbox.client.JestClient; 023import io.searchbox.client.JestClientFactory; 024import io.searchbox.client.config.HttpClientConfig; 025import org.apache.http.HttpHost; 026 027import org.springframework.beans.factory.ObjectProvider; 028import org.springframework.boot.autoconfigure.AutoConfigureAfter; 029import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 030import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 031import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 032import org.springframework.boot.autoconfigure.elasticsearch.jest.JestProperties.Proxy; 033import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; 034import org.springframework.boot.context.properties.EnableConfigurationProperties; 035import org.springframework.boot.context.properties.PropertyMapper; 036import org.springframework.context.annotation.Bean; 037import org.springframework.context.annotation.Configuration; 038import org.springframework.util.Assert; 039 040/** 041 * {@link EnableAutoConfiguration Auto-configuration} for Jest. 042 * 043 * @author Stephane Nicoll 044 * @since 1.4.0 045 */ 046@Configuration 047@ConditionalOnClass(JestClient.class) 048@EnableConfigurationProperties(JestProperties.class) 049@AutoConfigureAfter(GsonAutoConfiguration.class) 050public class JestAutoConfiguration { 051 052 private final JestProperties properties; 053 054 private final ObjectProvider<Gson> gsonProvider; 055 056 private final ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers; 057 058 public JestAutoConfiguration(JestProperties properties, ObjectProvider<Gson> gson, 059 ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers) { 060 this.properties = properties; 061 this.gsonProvider = gson; 062 this.builderCustomizers = builderCustomizers; 063 } 064 065 @Bean(destroyMethod = "shutdownClient") 066 @ConditionalOnMissingBean 067 public JestClient jestClient() { 068 JestClientFactory factory = new JestClientFactory(); 069 factory.setHttpClientConfig(createHttpClientConfig()); 070 return factory.getObject(); 071 } 072 073 protected HttpClientConfig createHttpClientConfig() { 074 HttpClientConfig.Builder builder = new HttpClientConfig.Builder( 075 this.properties.getUris()); 076 PropertyMapper map = PropertyMapper.get(); 077 map.from(this.properties::getUsername).whenHasText().to((username) -> builder 078 .defaultCredentials(username, this.properties.getPassword())); 079 Proxy proxy = this.properties.getProxy(); 080 map.from(proxy::getHost).whenHasText().to((host) -> { 081 Assert.notNull(proxy.getPort(), "Proxy port must not be null"); 082 builder.proxy(new HttpHost(host, proxy.getPort())); 083 }); 084 map.from(this.gsonProvider::getIfUnique).whenNonNull().to(builder::gson); 085 map.from(this.properties::isMultiThreaded).to(builder::multiThreaded); 086 map.from(this.properties::getConnectionTimeout).whenNonNull() 087 .asInt(Duration::toMillis).to(builder::connTimeout); 088 map.from(this.properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis) 089 .to(builder::readTimeout); 090 customize(builder); 091 return builder.build(); 092 } 093 094 private void customize(HttpClientConfig.Builder builder) { 095 this.builderCustomizers.orderedStream() 096 .forEach((customizer) -> customizer.customize(builder)); 097 } 098 099}