Как я уже упоминал в комментариях, я не знаю, как именно IBM Compose для Elasticsearch устанавливает безопасность соединения; мои настройки для этого сценария следующие:
Elasticsearch
- Elasticsearch 6.6.2 работает на моей машине
- NGINX работает как прокси перед Elasticsearch с
- Базовая аутентификация активирована
- только SSL
- Требуются клиентские сертификаты SSL
Maven и версии
Чтобы иметь возможность общаться через HTTPS, вам нужно использовать RestClient
, который доступен в Spring Data Elasticsearch начиная с версии 3.2 (которая в настоящее время доступна в версии 3.2.0.M4). Spring Boot 2.1.5 загружает Spring Data Elasticsearch 3.1.8, поэтому вам необходимо переопределить версию. Вам также необходимо указать версию Elasticsearch для соответствия Spring Boot Data 3.2.0.M4, поэтому вашему pom.xml нужны следующие записи:
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>6.7.2</elasticsearch.version>
<spring-data-elasticsearch>3.2.0.M4</spring-data-elasticsearch>
</properties>
<repositories>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/libs-milestones</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>${spring-data-elasticsearch}</version>
</dependency>
</dependencies>
Конфигурация бина
В вашей программе вы можете настроить Beans для Spring Data Elasticsearch с реализацией AbstractElasticsearchConfiguration
:
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(RestClientConfig.class);
private static final String CERT_FILE = "client.p12";
private static final String CERT_PASSWORD = "topsecret";
private static final String USER_NAME = "user";
private static final String USER_PASS = "password";
@Override
public RestHighLevelClient elasticsearchClient() {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(USER_NAME, USER_PASS);
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:443") // set the address of the Elasticsearch cluster
.usingSsl(createSSLContext()) // use the SSLContext with the client cert
.withDefaultHeaders(headers) // use the headers for authentication
.build();
return RestClients.create(clientConfiguration).rest();
}
private SSLContext createSSLContext() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManager[] keyManagers = getKeyManagers();
sslContext.init(keyManagers, null, null);
return sslContext;
} catch (Exception e) {
LOG.error("cannot create SSLContext", e);
}
return null;
}
private KeyManager[] getKeyManagers()
throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException, UnrecoverableKeyException {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(CERT_FILE)) {
KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
clientKeyStore.load(inputStream, CERT_PASSWORD.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(clientKeyStore, CERT_PASSWORD.toCharArray());
return kmf.getKeyManagers();
}
}
@Bean
@Primary
public ElasticsearchOperations elasticsearchTemplate() {
return elasticsearchOperations();
}
}
С этой настройкой я могу запустить мое приложение Spring Boot для кластера Elasticsearch, используя ElasticsearchRestTemplate
и ElasticsearchRepository
.
Возможно, вам нужно изменить код в методе getKeyManagers()
, чтобы он соответствовал тому, что вы получили в Compose, но это должно дать вам некоторое представление о том, с чего начать.