Облачная платформаAdvanced

Подключение к кластеру через Spring Boot

Язык статьи: Русский
Показать оригинал
Страница переведена автоматически и может содержать неточности. Рекомендуем сверяться с английской версией.

Работа напрямую с базовыми API Elasticsearch может увеличить сложность разработки, например, дополнительные задачи по обслуживанию кода. Кластеры CSS Elasticsearch поддерживают запросы данных и управление через Spring Data Elasticsearch (интегрированный компонент Elasticsearch в экосистеме Spring Boot). Этот компонент инкапсулирует официальные Elasticsearch Java API. Разработчики могут использовать Spring repository API или native query DSL для эффективного доступа к кластерам без работы с базовыми API. Для получения подробной информации о том, как использовать Spring Boot, см. Spring Boot.

Требования

  • Целевой кластер Elasticsearch доступен.
  • Сервер, на котором выполняется код Java, может взаимодействовать с кластером Elasticsearch.
  • В зависимости от используемого метода настройки сети получите адрес доступа к кластеру. Для получения подробной информации см. Obtaining the Cluster Access Address.
  • Java установлен на сервере, а версия JDK — 1.8 или новее. Скачайте JDK 1.8 с Java Downloads.
  • Версия Spring Boot подтверждена. Чтобы обеспечить лучшую совместимость, используйте Java‑клиент той же версии, что и целевой кластер Elasticsearch.

    В этом документе в качестве примера используется Spring Boot 2.5.5. Соответствующая версия Spring Data Elasticsearch — 4.2.x, а версия целевого кластера Elasticsearch — 7.10.2.

Подготовка

  1. Проверьте, что используемая версия Spring Boot соответствует требованиям совместимости. Для получения подробной информации см. official compatibility list.

    В этом документе в качестве примера используется Spring Boot 2.5.5. Соответствующая версия Spring Data Elasticsearch — 4.2.x, а версия целевого кластера Elasticsearch — 7.10.2.

  2. Создайте проект Spring Boot.
  3. Объявите зависимости Java. Укажите версию Apache в режиме Maven.
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.5</version>
    </parent>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.10.2</version>
    </dependency>
    </dependencies>

Подключение к кластеру

Пример кода зависит от настроек режима безопасности целевого кластера Elasticsearch. Выберите соответствующий справочный документ в зависимости от сценария вашего сервиса.

Table 1 Cluster access scenarios

Elasticsearch Cluster Security-Mode Settings

Whether to Load a Security Certificate

Details

Non-security mode

Security mode + HTTP

-

Connecting to a Cluster That Uses HTTP Through Spring Boot

Security mode + HTTPS

No

Connecting to a Cluster That Uses HTTPS via Spring Boot (Without a Certificate)

Security mode + HTTPS

Yes

Connecting to a Cluster That Uses HTTPS via Spring Boot (With a Certificate)

Connecting to a Cluster That Uses HTTP Through Spring Boot

Ниже приведены шаги по использованию Spring Boot для подключения к кластеру Elasticsearch в режиме без безопасности; либо к кластеру в режиме безопасности, использующему HTTP вместо HTTPS.

  1. Настройте application.properties файл.
    1
    2
    3
    4elasticsearch.url=host1:9200,host2:9200
    // You do not need to configure the following two lines for a non-security cluster.
    elasticsearch.username=username
    elasticsearch.password=password
    Table 2 Параметры конфигурации

    Параметр

    Описание

    host

    Адрес для доступа к кластеру.

    username

    Имя пользователя для доступа к кластеру.

    password

    Пароль пользователя.

  2. Настройте клиентский код.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45package com.xxx.configuration;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.elasticsearch.client.ClientConfiguration;
    import org.springframework.data.elasticsearch.client.RestClients;
    import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
    import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
    @Configuration
    // com.xxx.repository is the repository directory, which is defined by extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository.
    @EnableElasticsearchRepositories(basePackages = "com.xxx.repository")
    // com.xxx indicates the project directory, for example, com.company.project.
    @ComponentScan(basePackages = "com.xxx")
    public class Config extends AbstractElasticsearchConfiguration {
    @Value("${elasticsearch.url}")
    public String elasticsearchUrl;
    // There is no need to set the following two parameters for a non-security cluster.
    @Value("${elasticsearch.username}")
    public String elasticsearchUsername;
    @Value("${elasticsearch.password}")
    public String elasticsearchPassword;
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
    final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
    .connectedTo(StringHostParse(elasticsearchUrl))
    // For a non-security cluster, there is no need to configure withBasicAuth.
    .withBasicAuth(elasticsearchUsername, elasticsearchPassword)
    .build();
    return RestClients.create(clientConfiguration).rest();
    }
    private String[] StringHostParse(String hostAndPorts) {
    return hostAndPorts.split(",");
    }
    }
  3. Если Spring Boot запускается корректно, соединение с кластером установлено.

Подключение к кластеру, использующему HTTPS, через Spring Boot (без сертификата)

Ниже приведены шаги по использованию Spring Boot для подключения к кластеру Elasticsearch в режиме безопасности + HTTPS без загрузки сертификата безопасности.

  1. Настройте файл application.properties.
    1
    2
    3elasticsearch.url=host1:9200,host2:9200
    elasticsearch.username=username
    elasticsearch.password=password
    Таблица 3 Параметры конфигурации

    Параметр

    Описание

    host

    Адрес для доступа к кластеру.

    username

    Имя пользователя для доступа к кластеру.

    password

    Пароль пользователя.

  2. Настройте клиентский код.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73package com.xxx.configuration;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.elasticsearch.client.ClientConfiguration;
    import org.springframework.data.elasticsearch.client.RestClients;
    import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
    import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    @Configuration
    // com.xxx.repository is the repository directory, which is defined by extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository.
    @EnableElasticsearchRepositories(basePackages = "com.xxx.repository")
    // com.xxx indicates the project directory, for example, com.company.project.
    @ComponentScan(basePackages = "com.xxx")
    public class Config extends AbstractElasticsearchConfiguration {
    @Value("${elasticsearch.url}")
    public String elasticsearchUrl;
    @Value("${elasticsearch.username}")
    public String elasticsearchUsername;
    @Value("${elasticsearch.password}")
    public String elasticsearchPassword;
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
    SSLContext sc = null;
    try {
    sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    } catch (KeyManagementException | NoSuchAlgorithmException e) {
    e.printStackTrace();
    }
    final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
    .connectedTo(StringHostParse(elasticsearchUrl))
    .usingSsl(sc, new NullHostNameVerifier())
    .withBasicAuth(elasticsearchUsername, elasticsearchPassword)
    .build();
    return RestClients.create(clientConfiguration).rest();
    }
    private String[] StringHostParse(String hostAndPorts) {
    return hostAndPorts.split(",");
    }
    public static TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    @Override
    public X509Certificate[] getAcceptedIssuers() {
    return null;
    }
    }
    };
    public static class NullHostNameVerifier implements HostnameVerifier {
    @Override
    public boolean verify(String arg0, SSLSession arg1) {
    return true;
    }
    }
    }
  3. Если Spring Boot запущен корректно, кластер подключён.

Подключение к кластеру, использующему HTTPS, через Spring Boot (с сертификатом)

Ниже приведены шаги по использованию Spring Boot для подключения к кластеру Elasticsearch в режиме безопасности + HTTPS с загрузкой сертификата безопасности.

  1. Получение и загрузка сертификата безопасности.
  2. Настройте файл application.properties.
    1
    2
    3elasticsearch.url=host1:9200,host2:9200
    elasticsearch.username=username
    elasticsearch.password=password
    Table 4 Параметры конфигурации

    Параметр

    Описание

    host

    Адрес для доступа к кластеру.

    username

    Имя пользователя для доступа к кластеру.

    password

    Пароль пользователя.

  3. Настройте клиентский код.
    Note
    • com.xxx указывает на каталог проекта, например, com.company.project.
    • com.xxx.repository является каталогом репозитория, который определяется extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99package com.xxx.configuration;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.elasticsearch.client.ClientConfiguration;
    import org.springframework.data.elasticsearch.client.RestClients;
    import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
    import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    @Configuration
    // com.xxx.repository is the repository directory, which is defined by extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository.
    @EnableElasticsearchRepositories(basePackages = "com.xxx.repository")
    // com.xxx indicates the project directory, for example, com.company.project.
    @ComponentScan(basePackages = "com.xxx")
    public class Config extends AbstractElasticsearchConfiguration {
    @Value("${elasticsearch.url}")
    public String elasticsearchUrl;
    @Value("${elasticsearch.username}")
    public String elasticsearchUsername;
    @Value("${elasticsearch.password}")
    public String elasticsearchPassword;
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
    SSLContext sc = null;
    try {
    // certFilePath and certPassword are the path and password of the security certificate.
    TrustManager[] tm = {new MyX509TrustManager(certFilePath, certPassword)};
    sc = SSLContext.getInstance("SSL", "SunJSSE");
    sc.init(null, tm, new SecureRandom());
    } catch (Exception e) {
    e.printStackTrace();
    }
    final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
    .connectedTo(StringHostParse(elasticsearchUrl))
    .usingSsl(sc, new NullHostNameVerifier())
    .withBasicAuth(elasticsearchUsername, elasticsearchPassword)
    .build();
    return RestClients.create(clientConfiguration).rest();
    }
    private String[] StringHostParse(String hostAndPorts) {
    return hostAndPorts.split(",");
    }
    public static class MyX509TrustManager implements X509TrustManager {
    X509TrustManager sunJSSEX509TrustManager;
    MyX509TrustManager(String certFilePath, String certPassword) throws Exception {
    File file = new File(certFilePath);
    if (!file.isFile()) {
    throw new Exception("Wrong Certification Path");
    }
    System.out.println("Loading KeyStore " + file + "...");
    InputStream in = new FileInputStream(file);
    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(in, certPassword.toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
    tmf.init(ks);
    TrustManager[] tms = tmf.getTrustManagers();
    for (TrustManager tm : tms) {
    if (tm instanceof X509TrustManager) {
    sunJSSEX509TrustManager = (X509TrustManager) tm;
    return;
    }
    }
    throw new Exception("Couldn't initialize");
    }
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    @Override
    public X509Certificate[] getAcceptedIssuers() {
    return new X509Certificate[0];
    }
    }
    public static class NullHostNameVerifier implements HostnameVerifier {
    @Override
    public boolean verify(String arg0, SSLSession arg1) {
    return true;
    }
    }
    }
  4. Если Spring Boot запускается корректно, кластер подключён.

Получение и загрузка сертификата безопасности

Чтобы получить доступ к кластеру Elasticsearch в режиме безопасности, использующему HTTPS, выполните следующие действия для получения сертификата безопасности, если он требуется, и загрузите его в клиент.

  1. Получите сертификат безопасности CloudSearchService.cer.
    1. Войдите в консоль управления CSS.
    2. В панели навигации слева выберите Clusters > Elasticsearch.
    3. В списке кластеров нажмите имя целевого кластера. Отобразится страница информации о кластере.
    4. Нажмите вкладку Overview. В области Network Information нажмите Download Certificate под HTTPS Access.
  2. Преобразуйте сертификат безопасности CloudSearchService.cer. Загрузите загруженный сертификат безопасности в клиент и используйте keytool для преобразования сертификата .cer в сертификат .jks, который может быть прочитан Java.
    • В Linux выполните следующую команду для преобразования сертификата:
      keytool -import -alias newname -keystore ./truststore.jks -file ./CloudSearchService.cer
    • В Windows выполните следующую команду для преобразования сертификата:
      keytool -import -alias newname -keystore .\truststore.jks -file .\CloudSearchService.cer

    В приведённой выше команде newname указывает пользовательское имя сертификата.

    После выполнения этой команды вам будет предложено задать пароль сертификата и подтвердить его. Надёжно сохраните пароль. Он будет использоваться для доступа к кластеру.