order
This paper focuses on springboot jet autoconfigure
JestProperties
spring-boot-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/elasticsearch/jest/JestProperties.java
@ConfigurationProperties(prefix = "spring.elasticsearch.jest") public class JestProperties { /** * Comma-separated list of the Elasticsearch instances to use. */ private List<String> uris = new ArrayList<>( Collections.singletonList("http://localhost:9200")); /** * Login username. */ private String username; /** * Login password. */ private String password; /** * Whether to enable connection requests from multiple execution threads. */ private boolean multiThreaded = true; /** * Connection timeout. */ private Duration connectionTimeout = Duration.ofSeconds(3); /** * Read timeout. */ private Duration readTimeout = Duration.ofSeconds(3); /** * Proxy settings. */ private final Proxy proxy = new Proxy(); //...... public static class Proxy { /** * Proxy host the HTTP client should use. */ private String host; /** * Proxy port the HTTP client should use. */ private Integer port; public String getHost() { return this.host; } public void setHost(String host) { this.host = host; } public Integer getPort() { return this.port; } public void setPort(Integer port) { this.port = port; } } }
- JestProperties provides the configuration of uris, username, password, multithreaded (default true), connectiontimeout (default 3s), readtimeout (default 3s), proxy
JestAutoConfiguration
spring-boot-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfiguration.java
@Configuration @ConditionalOnClass(JestClient.class) @EnableConfigurationProperties(JestProperties.class) @AutoConfigureAfter(GsonAutoConfiguration.class) public class JestAutoConfiguration { private final JestProperties properties; private final ObjectProvider<Gson> gsonProvider; private final ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers; public JestAutoConfiguration(JestProperties properties, ObjectProvider<Gson> gson, ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers) { this.properties = properties; this.gsonProvider = gson; this.builderCustomizers = builderCustomizers; } @Bean(destroyMethod = "shutdownClient") @ConditionalOnMissingBean public JestClient jestClient() { JestClientFactory factory = new JestClientFactory(); factory.setHttpClientConfig(createHttpClientConfig()); return factory.getObject(); } protected HttpClientConfig createHttpClientConfig() { HttpClientConfig.Builder builder = new HttpClientConfig.Builder( this.properties.getUris()); PropertyMapper map = PropertyMapper.get(); map.from(this.properties::getUsername).whenHasText().to((username) -> builder .defaultCredentials(username, this.properties.getPassword())); Proxy proxy = this.properties.getProxy(); map.from(proxy::getHost).whenHasText().to((host) -> { Assert.notNull(proxy.getPort(), "Proxy port must not be null"); builder.proxy(new HttpHost(host, proxy.getPort())); }); map.from(this.gsonProvider::getIfUnique).whenNonNull().to(builder::gson); map.from(this.properties::isMultiThreaded).to(builder::multiThreaded); map.from(this.properties::getConnectionTimeout).whenNonNull() .asInt(Duration::toMillis).to(builder::connTimeout); map.from(this.properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis) .to(builder::readTimeout); customize(builder); return builder.build(); } private void customize(HttpClientConfig.Builder builder) { this.builderCustomizers.orderedStream() .forEach((customizer) -> customizer.customize(builder)); } }
- Jestuautoconfiguration creates HttpClientConfig through JestProperties without a jestclient bean, then uses JestClientFactory to create jestclient, and marks its destroyMethod as shutdown client method
JestClientFactory
jest-6.3.1-sources.jar!/io/searchbox/client/JestClientFactory.java
public class JestClientFactory { final static Logger log = LoggerFactory.getLogger(JestClientFactory.class); private HttpClientConfig httpClientConfig; public JestClient getObject() { JestHttpClient client = new JestHttpClient(); if (httpClientConfig == null) { log.debug("There is no configuration to create http client. Going to create simple client with default values"); httpClientConfig = new HttpClientConfig.Builder("http://localhost:9200").build(); } client.setRequestCompressionEnabled(httpClientConfig.isRequestCompressionEnabled()); client.setServers(httpClientConfig.getServerList()); final HttpClientConnectionManager connectionManager = getConnectionManager(); final NHttpClientConnectionManager asyncConnectionManager = getAsyncConnectionManager(); client.setHttpClient(createHttpClient(connectionManager)); client.setAsyncClient(createAsyncHttpClient(asyncConnectionManager)); // set custom gson instance Gson gson = httpClientConfig.getGson(); if (gson == null) { log.info("Using default GSON instance"); } else { log.info("Using custom GSON instance"); client.setGson(gson); } // set discovery (should be set after setting the httpClient on jestClient) if (httpClientConfig.isDiscoveryEnabled()) { log.info("Node Discovery enabled..."); if (!Strings.isNullOrEmpty(httpClientConfig.getDiscoveryFilter())) { log.info("Node Discovery filtering nodes on \"{}\"", httpClientConfig.getDiscoveryFilter()); } NodeChecker nodeChecker = createNodeChecker(client, httpClientConfig); client.setNodeChecker(nodeChecker); nodeChecker.startAsync(); nodeChecker.awaitRunning(); } else { log.info("Node Discovery disabled..."); } // schedule idle connection reaping if configured if (httpClientConfig.getMaxConnectionIdleTime() > 0) { log.info("Idle connection reaping enabled..."); IdleConnectionReaper reaper = new IdleConnectionReaper(httpClientConfig, new HttpReapableConnectionManager(connectionManager, asyncConnectionManager)); client.setIdleConnectionReaper(reaper); reaper.startAsync(); reaper.awaitRunning(); } else { log.info("Idle connection reaping disabled..."); } Set<HttpHost> preemptiveAuthTargetHosts = httpClientConfig.getPreemptiveAuthTargetHosts(); if (!preemptiveAuthTargetHosts.isEmpty()) { log.info("Authentication cache set for preemptive authentication"); client.setHttpClientContextTemplate(createPreemptiveAuthContext(preemptiveAuthTargetHosts)); } client.setElasticsearchVersion(httpClientConfig.getElasticsearchVersion()); return client; } public void setHttpClientConfig(HttpClientConfig httpClientConfig) { this.httpClientConfig = httpClientConfig; } //...... }
- The getObject method of JestClientFactory first creates JestHttpClient, and then sets HttpClient and AsyncClient
- If isDiscoveryEnabled is true, NodeChecker is created and Node Discovery is performed
- If maxConnectionIdleTime is greater than 0, idlecononnectionreaper will be created for idleconnection reating
Summary
- JestProperties provides the configuration of uris, username, password, multithreaded (default true), connectiontimeout (default 3s), readtimeout (default 3s), proxy
- Jestuautoconfiguration creates HttpClientConfig through JestProperties without a jestclient bean, then uses JestClientFactory to create jestclient, and marks its destroyMethod as shutdown client method
- The getObject method of JestClientFactory first creates JestHttpClient, then sets HttpClient and AsyncClient; if isDiscoveryEnabled is true, NodeChecker will be created and Node Discovery will be executed; if maxConnectionIdleTime is greater than 0, idlecononnectionreaper will be created and idleconnection reaching will be executed