io.apiman.gateway.engine.es.DefaultESClientFactory.java Source code

Java tutorial

Introduction

Here is the source code for io.apiman.gateway.engine.es.DefaultESClientFactory.java

Source

/*
 * Copyright 2015 JBoss Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.apiman.gateway.engine.es;

import io.apiman.common.util.ssl.KeyStoreUtil;
import io.apiman.common.util.ssl.KeyStoreUtil.Info;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.client.config.HttpClientConfig.Builder;

import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;

/**
 * Factory for creating elasticsearch clients.
 *
 * @author eric.wittmann@redhat.com
 */
public class DefaultESClientFactory extends AbstractClientFactory implements IESClientFactory {

    /**
     * Clears all the clients from the cache.  Useful for unit testing.
     */
    public static void clearClientCache() {
        clients.clear();
    }

    /**
     * Constructor.
     */
    public DefaultESClientFactory() {
    }

    /**
     * Creates a client from information in the config map.
     * @param config the configuration
     * @param defaultIndexName the default index to use if not specified in the config
     * @return the ES client
     */
    public JestClient createClient(Map<String, String> config, String defaultIndexName) {
        JestClient client;
        String indexName = config.get("client.index"); //$NON-NLS-1$
        if (indexName == null) {
            indexName = defaultIndexName;
        }
        client = createJestClient(config, indexName, defaultIndexName);
        return client;
    }

    /**
     * Creates a transport client from a configuration map.
     * @param config the configuration
     * @param indexName the name of the index
     * @param defaultIndexName the default index name
     * @return the ES client
     */
    protected JestClient createJestClient(Map<String, String> config, String indexName, String defaultIndexName) {
        String host = config.get("client.host"); //$NON-NLS-1$
        String port = config.get("client.port"); //$NON-NLS-1$
        String protocol = config.get("client.protocol"); //$NON-NLS-1$
        String initialize = config.get("client.initialize"); //$NON-NLS-1$

        if (initialize == null) {
            initialize = "true"; //$NON-NLS-1$
        }

        if (StringUtils.isBlank(host)) {
            throw new RuntimeException("Missing client.host configuration for ESRegistry."); //$NON-NLS-1$
        }
        if (StringUtils.isBlank(port)) {
            throw new RuntimeException("Missing client.port configuration for ESRegistry."); //$NON-NLS-1$
        }
        if (StringUtils.isBlank(protocol)) {
            protocol = "http"; //$NON-NLS-1$
        }

        String clientKey = "jest:" + host + ':' + port + '/' + indexName; //$NON-NLS-1$
        synchronized (clients) {
            if (clients.containsKey(clientKey)) {
                return clients.get(clientKey);
            } else {
                StringBuilder builder = new StringBuilder();
                builder.append(protocol);
                builder.append("://"); //$NON-NLS-1$
                builder.append(host);
                builder.append(":"); //$NON-NLS-1$
                builder.append(String.valueOf(port));
                String connectionUrl = builder.toString();

                JestClientFactory factory = new JestClientFactory();
                Builder httpClientConfig = new HttpClientConfig.Builder(connectionUrl);
                updateHttpConfig(httpClientConfig, config);
                factory.setHttpClientConfig(httpClientConfig.build());
                updateJestClientFactory(factory, config);

                JestClient client = factory.getObject();
                clients.put(clientKey, client);
                if ("true".equals(initialize)) { //$NON-NLS-1$
                    initializeClient(client, indexName, defaultIndexName);
                }
                return client;
            }
        }
    }

    /**
     * Update the http client config.
     * @param httpClientConfig
     * @param config 
     */
    protected void updateHttpConfig(Builder httpClientConfig, Map<String, String> config) {
        String username = config.get("client.username"); //$NON-NLS-1$
        String password = config.get("client.password"); //$NON-NLS-1$
        String timeout = config.get("client.timeout"); //$NON-NLS-1$
        if (StringUtils.isBlank(timeout)) {
            timeout = "10000"; //$NON-NLS-1$
        }

        httpClientConfig.connTimeout(new Integer(timeout)).readTimeout(new Integer(timeout)).maxTotalConnection(75)
                .defaultMaxTotalConnectionPerRoute(75).multiThreaded(true);
        if (!StringUtils.isBlank(username)) {
            httpClientConfig.defaultCredentials(username, password);
        }

        if ("https".equals(config.get("protocol"))) { //$NON-NLS-1$ //$NON-NLS-2$
            updateSslConfig(httpClientConfig, config);
        }
    }

    /**
     * @param httpConfig
     * @param config 
     */
    @SuppressWarnings("nls")
    private void updateSslConfig(Builder httpConfig, Map<String, String> config) {
        try {
            String clientKeystorePath = config.get("client-keystore");
            String clientKeystorePassword = config.get("client-keystore.password");
            String trustStorePath = config.get("trust-store");
            String trustStorePassword = config.get("trust-store.password");

            SSLContext sslContext = SSLContext.getInstance("TLS");
            Info kPathInfo = new Info(clientKeystorePath, clientKeystorePassword);
            Info tPathInfo = new Info(trustStorePath, trustStorePassword);
            sslContext.init(KeyStoreUtil.getKeyManagers(kPathInfo), KeyStoreUtil.getTrustManagers(tPathInfo), null);
            HostnameVerifier hostnameVerifier = new DefaultHostnameVerifier();
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,
                    hostnameVerifier);
            SchemeIOSessionStrategy httpsIOSessionStrategy = new SSLIOSessionStrategy(sslContext, hostnameVerifier);

            httpConfig.defaultSchemeForDiscoveredNodes("https");
            httpConfig.sslSocketFactory(sslSocketFactory); // for sync calls
            httpConfig.httpsIOSessionStrategy(httpsIOSessionStrategy); // for async calls

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Update the jest client factory with any settings.
     * @param factory
     * @param config 
     */
    protected void updateJestClientFactory(JestClientFactory factory, Map<String, String> config) {
    }

}