Created
July 19, 2023 08:08
-
-
Save AlrikG/823f83c309e1cd63256e68522af7a38a to your computer and use it in GitHub Desktop.
Elasticsearch SSL Client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.osp.adapter.elasticsearch; | |
import java.io.ByteArrayInputStream; | |
import java.io.Closeable; | |
import java.io.File; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.nio.charset.StandardCharsets; | |
import java.security.KeyStore; | |
import java.security.cert.CertificateFactory; | |
import java.security.cert.X509Certificate; | |
import javax.net.ssl.SSLContext; | |
import org.apache.http.HttpHost; | |
import org.apache.http.auth.AuthScope; | |
import org.apache.http.auth.UsernamePasswordCredentials; | |
import org.apache.http.client.CredentialsProvider; | |
import org.apache.http.conn.ssl.TrustSelfSignedStrategy; | |
import org.apache.http.impl.client.BasicCredentialsProvider; | |
import org.apache.http.impl.client.CloseableHttpClient; | |
import org.apache.http.impl.client.HttpClients; | |
import org.apache.http.ssl.SSLContextBuilder; | |
import lombok.EqualsAndHashCode; | |
import lombok.Getter; | |
import lombok.Setter; | |
import lombok.extern.log4j.Log4j2; | |
import de.osp.adapter.Config; | |
@Getter | |
@Setter | |
@EqualsAndHashCode | |
@Log4j2 | |
public final class ElasticsearchClient implements Closeable | |
{ | |
private static final boolean GENERATE_TRUSTSTORE = true; | |
private static final boolean SAVE_GENERATED_TRUSTSTORE = false; | |
private static final SSLContext SSL_CONTEXT; | |
private final CloseableHttpClient httpClient; | |
private final HttpHost httpHost; | |
private ElasticsearchClient(CloseableHttpClient httpClient, HttpHost httpHost) | |
{ | |
this.httpClient = httpClient; | |
this.httpHost = httpHost; | |
} | |
static | |
{ | |
SSL_CONTEXT = GENERATE_TRUSTSTORE ? createTruststore(Config.ES_CERT, Config.CERTIFICATE_ALIAS, Config.TRUSTSTORE_PASSWORD) : loadTruststore(Config.TRUSTSTORE_FILE, Config.TRUSTSTORE_PASSWORD); | |
} | |
private static SSLContext loadTruststore(String truststoreFile, String truststorePassword) | |
{ | |
// generation: keytool -import -file es01.crt -alias elastic -keystore truststore.jks | |
try | |
{ | |
return SSLContextBuilder.create().loadTrustMaterial(new File(truststoreFile), truststorePassword.toCharArray()).build(); | |
} | |
catch (Exception e) | |
{ | |
log.error("Could not create truststore", e); | |
throw new RuntimeException("Could not create truststore", e); | |
} | |
} | |
private static SSLContext createTruststore(String pemFile, String certificateAlias, String truststorePassword) | |
{ | |
// Load the PEM certificate | |
try (InputStream inputStream = new ByteArrayInputStream(pemFile.getBytes(StandardCharsets.UTF_8))) | |
{ | |
CertificateFactory cf = CertificateFactory.getInstance("X.509"); | |
X509Certificate certificate = (X509Certificate) cf.generateCertificate(inputStream); | |
// Create a new KeyStore | |
KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType()); | |
truststore.load(null, truststorePassword.toCharArray()); | |
// Add the certificate to the truststore | |
truststore.setCertificateEntry(certificateAlias, certificate); | |
// Save the truststore to a file | |
if (SAVE_GENERATED_TRUSTSTORE) | |
{ | |
String truststoreFile = "truststore_generated.jks"; | |
try (FileOutputStream outputStream = new FileOutputStream(truststoreFile)) | |
{ | |
truststore.store(outputStream, truststorePassword.toCharArray()); | |
} | |
} | |
log.info("Truststore created successfully!"); | |
return SSLContextBuilder.create().loadTrustMaterial(truststore, TrustSelfSignedStrategy.INSTANCE).build(); | |
} | |
catch (Exception e) | |
{ | |
log.error("Could not create truststore", e); | |
throw new RuntimeException("Could not create truststore", e); | |
} | |
} | |
private static CloseableHttpClient https() | |
{ | |
// Create the credentials provider | |
CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); | |
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(Config.ES_USER, Config.ES_PASSWORD)); | |
// Create the SSLContext with the truststore | |
return HttpClients.custom().setMaxConnPerRoute(100).setMaxConnTotal(100).setDefaultCredentialsProvider(credentialsProvider).setSSLContext(SSL_CONTEXT).build(); | |
} | |
private static CloseableHttpClient http() | |
{ | |
return HttpClients.custom().setMaxConnPerRoute(100).setMaxConnTotal(100).build(); | |
} | |
public static ElasticsearchClient build() | |
{ | |
CloseableHttpClient httpClient = "https".equals(Config.ES_SCHEME) ? https() : http(); | |
HttpHost httpHost = new HttpHost(Config.ES_HOST, Config.ES_PORT, Config.ES_SCHEME); | |
return new ElasticsearchClient(httpClient, httpHost); | |
} | |
@Override | |
public void close() throws IOException | |
{ | |
httpClient.close(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment