/** * This file is part of Graylog. * * Graylog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Graylog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Graylog. If not, see <http://www.gnu.org/licenses/>. */ package org.graylog2.bindings.providers; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.gson.Gson; import io.searchbox.client.JestClient; import io.searchbox.client.JestClientFactory; import io.searchbox.client.config.HttpClientConfig; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import java.net.URI; import java.time.Duration; import java.util.Iterator; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Singleton public class JestClientProvider implements Provider<JestClient> { private final JestClientFactory factory; private final CredentialsProvider credentialsProvider; @Inject public JestClientProvider(@Named("elasticsearch_hosts") List<URI> elasticsearchHosts, @Named("elasticsearch_connect_timeout") Duration elasticsearchConnectTimeout, @Named("elasticsearch_socket_timeout") Duration elasticsearchSocketTimeout, @Named("elasticsearch_idle_timeout") Duration elasticsearchIdleTimeout, @Named("elasticsearch_max_total_connections") int elasticsearchMaxTotalConnections, @Named("elasticsearch_max_total_connections_per_route") int elasticsearchMaxTotalConnectionsPerRoute, @Named("elasticsearch_discovery_enabled") boolean discoveryEnabled, @Named("elasticsearch_discovery_filter") @Nullable String discoveryFilter, @Named("elasticsearch_discovery_frequency") Duration discoveryFrequency, Gson gson) { this.factory = new JestClientFactory(); this.credentialsProvider = new BasicCredentialsProvider(); final List<String> hosts = elasticsearchHosts.stream() .map(hostUri -> { if (!Strings.isNullOrEmpty(hostUri.getUserInfo())) { final Iterator<String> splittedUserInfo = Splitter.on(":") .split(hostUri.getUserInfo()) .iterator(); if (splittedUserInfo.hasNext()) { final String username = splittedUserInfo.next(); final String password = splittedUserInfo.hasNext() ? splittedUserInfo.next() : null; credentialsProvider.setCredentials( new AuthScope(hostUri.getHost(), hostUri.getPort(), AuthScope.ANY_REALM, hostUri.getScheme()), new UsernamePasswordCredentials(username, password) ); } } return hostUri.toString(); }) .collect(Collectors.toList()); final HttpClientConfig.Builder httpClientConfigBuilder = new HttpClientConfig .Builder(hosts) .credentialsProvider(credentialsProvider) .connTimeout(Math.toIntExact(elasticsearchConnectTimeout.toMillis())) .readTimeout(Math.toIntExact(elasticsearchSocketTimeout.toMillis())) .maxConnectionIdleTime(elasticsearchIdleTimeout.getSeconds(), TimeUnit.SECONDS) .maxTotalConnection(elasticsearchMaxTotalConnections) .defaultMaxTotalConnectionPerRoute(elasticsearchMaxTotalConnectionsPerRoute) .multiThreaded(true) .discoveryEnabled(discoveryEnabled) .discoveryFilter(discoveryFilter) .discoveryFrequency(discoveryFrequency.getSeconds(), TimeUnit.SECONDS) .gson(gson); factory.setHttpClientConfig(httpClientConfigBuilder.build()); } @Override public JestClient get() { return factory.getObject(); } }