Присоединение AWS documentDB к приложению Spring Boot

Недавно я пытался использовать новый сервис AWS DocumentDB в качестве базы данных в приложении Spring.

Кластер был создан в том же VPC, что и EKS, на котором я развернул свое приложение. Группы безопасности разрешают соединения между всеми узлами в VPC.

AWS предоставляет такой моно URI для моего кластера БД:

mongodb://<my-user>:<insertYourPassword>@<my-cluster-endpoint>:27017/?ssl_ca_certs=rds-combined-ca-bundle.pem&replicaSet=rs0

Мой вопрос:

Как мне заставить мой код Spring работать с этим типом соединения?

Я попытался добавить подписку к моему application.properties файл:

spring.data.mongodb.uri=mongodb://<my-user>:<insertYourPassword>@<my-cluster-endpoint>:27017/admin?ssl_ca_certs=rds-combined-ca-bundle.pem&replicaSet=rs00
spring.data.mongodb.database=admin
server.ssl.key-store=classpath:rds-combined-ca-bundle.pem

И поместив файл PEM в /src/main/resources

Однако код все еще не может подключиться к кластеру БД.

Я получаю это сообщение как ошибку: No server chosen by com.mongodb.client.internal.MongoClientDelegate

Вслед за Exception in monitor thread while connecting to server ...

И, наконец, исключение тайм-аута: com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message

Это похоже на проблему группы безопасности, но у меня нет проблем с подключением к оболочке mongo из того же EC2, на котором запущен модуль Spring.

Есть идеи?

7 ответов

Как указано в документации,

По своей сути вы получаете доступ к ресурсам Amazon DocumentDB (с совместимостью с MongoDB) из экземпляра Amazon EC2 в том же Amazon VPC, что и ресурсы Amazon DocumentDB. Однако предположим, что ваш вариант использования требует, чтобы вы или ваше приложение обращались к ресурсам Amazon DocumentDB из-за пределов кластера Amazon VPC. В этом случае вы можете использовать SSH-туннелирование (также известное как "переадресация портов") для доступа к вашим ресурсам Amazon DocumentDB.

Подключение извне VPC

Ваш кластер Amazon DocumentDB должен работать в виртуальном частном облаке по умолчанию (VPC). Для взаимодействия с кластером Amazon DocumentDB необходимо запустить экземпляр Amazon Elastic Compute Cloud (Amazon EC2) в свой VPC по умолчанию, в том же регионе AWS, где вы создали кластер Amazon DocumentDB.

Следуйте инструкциям по подключению к кластеру AWS DocumentDB cluster

Обновление:

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

Это можно скачать из сертификатов SSL и скопировать его в базовый каталог. В качестве альтернативы вы можете указать абсолютный путь к переменной SSL_CERTIFICATE.

     private static final String SSL_CERTIFICATE = "rds-ca-2015-us-east-1.pem";
     private static final String KEY_STORE_TYPE = "JKS";
     private static final String KEY_STORE_PROVIDER = "SUN";
     private static final String KEY_STORE_FILE_PREFIX = "sys-connect-via-ssl-test-cacerts";
     private static final String KEY_STORE_FILE_SUFFIX = ".jks";
     private static final String DEFAULT_KEY_STORE_PASSWORD = "changeit";

    public static void main(String[] args) {
        SSLContextHelper.setSslProperties();
        SpringApplication.run(Application.class, args);
    }


    protected static class SSLContextHelper{
    /**
     * This method sets the SSL properties which specify the key store file, its type and password:
     * @throws Exception
     */
    private static void setSslProperties()  {

        try {
            System.setProperty("javax.net.ssl.trustStore", createKeyStoreFile());
        } catch (Exception e) {

            e.printStackTrace();
        }
        System.setProperty("javax.net.ssl.trustStoreType", KEY_STORE_TYPE);
        System.setProperty("javax.net.ssl.trustStorePassword", DEFAULT_KEY_STORE_PASSWORD);
    }


    private static String createKeyStoreFile() throws Exception {
        return createKeyStoreFile(createCertificate()).getPath();
    }

    /**
     *  This method generates the SSL certificate
     * @return
     * @throws Exception
     */
    private static X509Certificate createCertificate() throws Exception {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        URL url = new File(SSL_CERTIFICATE).toURI().toURL();
        if (url == null) {
            throw new Exception();
        }
        try (InputStream certInputStream = url.openStream()) {
            return (X509Certificate) certFactory.generateCertificate(certInputStream);
        }
    }

    /**
     * This method creates the Key Store File
     * @param rootX509Certificate - the SSL certificate to be stored in the KeyStore
     * @return
     * @throws Exception
     */
    private static File createKeyStoreFile(X509Certificate rootX509Certificate) throws Exception {
        File keyStoreFile = File.createTempFile(KEY_STORE_FILE_PREFIX, KEY_STORE_FILE_SUFFIX);
        try (FileOutputStream fos = new FileOutputStream(keyStoreFile.getPath())) {
            KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE, KEY_STORE_PROVIDER);
            ks.load(null);
            ks.setCertificateEntry("rootCaCertificate", rootX509Certificate);
            ks.store(fos, DEFAULT_KEY_STORE_PASSWORD.toCharArray());
        }
        return keyStoreFile;
    }


    }

выход подключения:

019-01-17 13:33:22.316  INFO 3598 --- [onaws.com:27017] org.mongodb.driver.cluster               : Canonical address mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017 does not match server address.  Removing mongodb.cluster-cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017 from client view of cluster
2019-01-17 13:33:22.401  INFO 3598 --- [onaws.com:27017] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:2}] to mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017
2019-01-17 13:33:22.403  INFO 3598 --- [onaws.com:27017] org.mongodb.driver.cluster               : Monitor thread successfully connected to server with description ServerDescription{address=mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017, type=REPLICA_SET_PRIMARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 6, 0]}, minWireVersion=0, maxWireVersion=6, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=null, roundTripTimeNanos=2132149, setName='rs0', canonicalAddress=mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017, hosts=[mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017], passives=[], arbiters=[], primary='mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017', tagSet=TagSet{[]}, electionId=7fffffff0000000000000001, setVersion=null, lastWriteDate=Thu Jan 17 13:33:21 UTC 2019, lastUpdateTimeNanos=516261208876}
2019-01-17 13:33:22.406  INFO 3598 --- [onaws.com:27017] org.mongodb.driver.cluster               : Discovered replica set primary mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017
2019-01-17 13:33:22.595  INFO 3598 --- [           main] com.barath.app.CustomerService           : Saving the customer with customer details com.barath.app.Customer@6c130c45
2019-01-17 13:33:22.912  INFO 3598 --- [           main] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:3}] to mongodb.cktoiipu3bbd.us-east-1.docdb.amazonaws.com:27017
2019-01-17 13:33:23.936  INFO 3598 --- [           main] pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]

Ссылка: aws-documentdb

Ответ, предоставленный Sunny Pelletier сработал для меня с гибридом Frank в нашей настройке Java.

Поэтому мне нужно было решение, которое работало бы для нашей локальной настройки докеров и для любой из наших сред AWS, в которых есть активные профили и другие переменные окружения, установленные в нашей среде через CDK.

Сначала я начал с простого POJO конфигурации, чтобы настроить свои свойства за пределами spring.data.mongo.*парадигма. Вам не обязательно этого делать, и вы можете просто позволить Spring обработать это, как обычно, для создания.

Мой локальный разработчик по умолчанию application.yml и соответствующий класс конфигурации.

      mongo:
  user: mongo
  password: mongo
  host: localhost
  port: 27017
  database: my-service

      @Data
@Configuration
@ConfigurationProperties(prefix = "mongo")
public class MongoConnectConfig {

    private int port;

    private String host;

    private String user;

    private String database;

    private String password;

}

Затем я создал два AbstractMongoClientConfigurationдетские классы; один для местного и один для неместного. Ключевым моментом здесь является то, что я не создавал свой собственный. Причина в том, что мне нужны все хорошие вещи для инициализации Spring Boot, которые вы получаете с фреймворком. Например, авторегистрация всех конвертеров и тому подобное.

Вместо этого я использовал крючок настройки, предоставляемый AbstractMongoClientConfiguration.configureClientSettings(MongoClientSettings.Builder builder) чтобы затем объединить пользовательские настройки, такие как .pem кусок.

Другая часть заключается в том, что я использовал профили для включения / отключения конфигураций, чтобы сделать их «бесшовными» для местных разработчиков; мы не используем никаких профилей кроме default для локальной разработки, так что проще приступить к настройке, не «зная» так много с самого начала.

      import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Slf4j
@Configuration
@RequiredArgsConstructor
@Profile({"!dev && !qa && !prod"})
@EnableMongoRepositories(basePackages = "co.my.data.repositories")
public class LocalDevMongoConfig extends AbstractMongoClientConfiguration {
    
    private final MongoConnectConfig config;
    
    @Override
    public String getDatabaseName() {
        return config.getDatabase();
    }
    
    @Override
    protected void configureClientSettings(MongoClientSettings.Builder builder) {
        log.info("Applying Local Dev MongoDB Configuration");
        builder.applyConnectionString(new ConnectionString(getConnectionString()));
    }

    //mongodb://${mongo.user}:${mongo.password}@${mongo.host}:${mongo.port}/${mongo.database}?authSource=admin
    private String getConnectionString() {
        return String.format("mongodb://%s:%s@%s:%s/%s?authSource=admin",
                config.getUser(),
                config.getPassword(),
                config.getHost(),
                config.getPort(),
                config.getDatabase()
        );
    }
}

      
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.nio.file.Files;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.stream.Collectors;

@Slf4j
@Configuration
@RequiredArgsConstructor
@Profile({"dev || qa || prod"})
@EnableMongoRepositories(basePackages = "co.my.data.repositories")
public class DocumentDbMongoConfig extends AbstractMongoClientConfiguration {

    private final MongoConnectConfig config;

    @Override
    public String getDatabaseName() {
        return config.getDatabase();
    }

    @SneakyThrows
    @Override
    protected void configureClientSettings(MongoClientSettings.Builder builder) {
        log.info("Applying AWS DocumentDB Configuration");
        builder.applyConnectionString(new ConnectionString(getConnectionString()));
        var endOfCertificateDelimiter = "-----END CERTIFICATE-----";
        File resource = new ClassPathResource("certs/rds-combined-ca-bundle.pem").getFile();
        String pemContents = new String(Files.readAllBytes(resource.toPath()));
        var allCertificates = Arrays.stream(pemContents
                .split(endOfCertificateDelimiter))
                .filter(line -> !line.isBlank())
                .map(line -> line + endOfCertificateDelimiter)
                .collect(Collectors.toUnmodifiableList());


        var certificateFactory = CertificateFactory.getInstance("X.509");
        var keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        // This allows us to use an in-memory key-store
        keyStore.load(null);

        for (int i = 0; i < allCertificates.size(); i++) {
            var certString = allCertificates.get(i);
            var caCert = certificateFactory.generateCertificate(new ByteArrayInputStream(certString.getBytes()));
            keyStore.setCertificateEntry(String.format("AWS-certificate-%s", i), caCert);
        }

        var trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);

        var sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

        builder.applyToSslSettings(ssl -> {
            ssl.enabled(true).context(sslContext);
        });
    }

    /**
     * Partly based on the AWS Console "Connectivity & security " section in the DocumentDB Cluster View.
     *   Since we register the pem above, we don't need to add the ssl & sslCAFile piece
     *   mongodb://${user}:${password}@${host}:${port}/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
     */
    private String getConnectionString() {
        return String.format("mongodb://%s:%s@%s:%s/%s?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false",
                config.getUser(),
                config.getPassword(),
                config.getHost(),
                config.getPort(),
                config.getDatabase()
        );
    }
}

Наконец, мы размещаем rds-combined-ca-bundle.pem в src/main/resources/certs/ папка.

Боковые примечания:

  • Опять же, я считаю, что вы сможете обойтись без использования значения по умолчанию spring.data* свойства и ваш MongoClient должен был их использовать.
  • Игнорировать @SneakyThrows здесь я сделал это только для краткости кода, обрабатывайте отмеченные исключения так, как считаете нужным.
  • Думаю, мы можем понять, почему синтаксис Kotlin можно считать «чище», да? :)

Я могу подтвердить, что решение, предоставленное @Barath, позволяет защитить TLS-соединение AWS DocumentDB внутри самого приложения Java. Это намного более чистый подход по сравнению с подходом, описанным AWS на https://docs.aws.amazon.com/documentdb/latest/developerguide/connect_programmatically.html, который требует, чтобы вы запускали сценарий на своем сервере, который является более сложным и сложно для автоматического развертывания и т. д.

Для дальнейшей настройки самого соединения в приложении Spring я использовал следующий класс @Configuration, который позволяет подключаться к локальной MongoDB для тестирования во время разработки, и один AWS, развернутый с настройками из файла свойств.

      import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
    
@Configuration
@EnableMongoRepositories(basePackages = "YOUR.PACKAGE.WITH.repository")
public class MongoDbConfig extends AbstractMongoClientConfiguration {
    
    @Value("${spring.profiles.active}")
    private String activeProfile;
    
    @Value("${mongodb.host:localhost}")
    private String dbUri;
    @Value("${mongodb.port:27017}")
    private int dbPort;
    @Value("${mongodb.database.name:YOUR_DOCUMENTDB_NAME}")
    private String dbName;
    @Value("${mongodb.username:}")
    private String dbUser;
    @Value("${mongodb.password:}")
    private String dbPassword;
    
    @Override
    public String getDatabaseName() {
        return dbName;
    }
    
    @Override
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString(getConnectionString());
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
               .applyConnectionString(connectionString)
               .build();
        return MongoClients.create(mongoClientSettings);
    }
    
    private String getConnectionString() {
        if (activeProfile.contains("local")) {
            return String.format("mongodb://%s:%s/%s", dbUri, dbPort, dbName);
        }
        return String.format("mongodb://%s:%s@%s:%s/%s?ssl=true&replicaSet=rs0&readpreference=secondaryPreferred&retrywrites=false",
                dbUser, dbPassword, dbUri, dbPort, dbName);
    }
}

На самом деле я столкнулся с той же проблемой, что и вы, но теперь AWS использует, который объединяет множество сертификатов в один.

Если вы не хотите создавать трастовое хранилище, используя их устаревшую документацию, вы можете сделать это самостоятельно и получить rds-combined-ca-bundle.pem в ваше приложение, генерирующее хранилище ключей во время выполнения.

Мне удалось заставить это работать с этим образцом кода. Это было протестировано с spring:2.4, mongo-driver: 4.1.1 и documentDB, используя mongo 4.0 совместимость.

      val endOfCertificateDelimiter = "-----END CERTIFICATE-----"

// rds-combined-ca-bundle.pem contains more than one certificate. We need to add them all to the trust-store independantly. 

val allCertificates = ClassPathResource("certificates/rds-combined-ca-bundle.pem").file.readText()
    .split(endOfCertificateDelimiter)
    .filter { it.isNotBlank() }
    .map { it + endOfCertificateDelimiter }

val certificateFactory = CertificateFactory.getInstance("X.509")
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keyStore.load(null) // This allows us to use an in-memory key-store

allCertificates.forEachIndexed { index, certificate ->
    val caCert = certificateFactory.generateCertificate(certificate.byteInputStream()) as X509Certificate
    keyStore.setCertificateEntry("AWS-certificate-$index", caCert)
}

val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
trustManagerFactory.init(keyStore)

val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustManagerFactory.trustManagers, null)

builder.applyToSslSettings {
    it.enabled(true)
        .context(sslContext)
}

Как отметил @mmr25 в комментариях к ответу @Barath, решение работает только в том случае, когда сервису нужно только подключиться к documentDB. Вы начинаете получать «Сбой при построении пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенного» для других HTTP-запросов.

Чтобы решить эту проблему, нам нужно включить sslcontext только для соединений documentdb. Для этого мы можем использовать Netty в качестве HttpClient для соединений mongodb. Чтобы включить netty, нам нужно добавить следующую зависимость maven в ваш проект весенней загрузки:

          <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-tcnative-boringssl-static</artifactId>
        <version>2.0.53.Final</version>
    </dependency>

и поместите файл pem в папку ресурсов и определите следующие bean-компоненты в одном из классов, аннотированных аннотациями @Configutation.

      @Slf4j
@Configuration
public class MongoDbConfiguration {

    private static final String AWS_PUBLIC_KEY_NAME = "rds-ca-2019-root.pem";

    private final String mongoConnectionUri;

    private final String databaseName;

    public MongoDbConfiguration(@Value("${spring.data.mongodb.uri}") String mongoConnectionUri, @Value("${spring.data.mongodb.database}") String databaseName) {
        this.mongoConnectionUri = mongoConnectionUri;
        this.databaseName = databaseName;
    }


    @Bean
    @Primary
    @SneakyThrows
    @Profile("!default")
    public MongoClient mongoClient() {

        SslContext sslContext = SslContextBuilder.forClient()
                .sslProvider(SslProvider.OPENSSL)
                .trustManager(new ClassPathResource(AWS_PUBLIC_KEY_NAME).getInputStream())
                .build();

        ConnectionString connectionString = new ConnectionString(mongoConnectionUri);

        return MongoClients.create(
                MongoClientSettings.builder()
                        .applyConnectionString(connectionString)
                        .applyToSslSettings(builder -> {
                            builder.enabled((null == connectionString.getSslEnabled()) ? false : connectionString.getSslEnabled());
                            builder.invalidHostNameAllowed((null == connectionString.getSslInvalidHostnameAllowed()) ? false : connectionString.getSslInvalidHostnameAllowed());
                        })
                        .streamFactoryFactory(NettyStreamFactoryFactory.builder()
                                .sslContext(sslContext)
                                .build())
                        .build());
    }
}

Заявления об импорте:

      import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.connection.netty.NettyStreamFactoryFactory;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;

Теперь вы сможете подключиться к своей базе данных документов, и другие http-соединения также должны работать должным образом.

Ссылка: https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/connection/tls/#customize-tls-ssl-configuration-through-the-netty-sslcontext

Вот решение, которое сработало для меня, просто вызовите метод setSslProperties перед подключением к своей базе данных документа.

          /**
 * This method sets the SSL properties which specify the key store file, its type and password.
 *
 * @throws Exception
 */
private static void setSslProperties() throws Exception {

    System.setProperty("javax.net.ssl.trustStore", createKeyStoreFile());
    System.setProperty("javax.net.ssl.trustStoreType", KEY_STORE_TYPE);
    System.setProperty("javax.net.ssl.trustStorePassword", DEFAULT_KEY_STORE_PASSWORD);
}

/**
 * This method returns the path of the Key Store File needed for the SSL verification during the IAM Database Authentication to
 * the db instance.
 *
 * @return
 * @throws Exception
 */
private static String createKeyStoreFile() throws Exception {
    return createKeyStoreFile(createCertificate()).getPath();
}

/**
 * This method generates the SSL certificate.
 *
 * @return
 * @throws Exception
 */
private static X509Certificate createCertificate() throws Exception {
    final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    final ClassLoader classLoader = MyClass.class.getClassLoader();
    final InputStream is = classLoader.getResourceAsStream(SSL_CERTIFICATE);
    return (X509Certificate) certFactory.generateCertificate(is);

}

/**
 * This method creates the Key Store File.
 *
 * @param rootX509Certificate - the SSL certificate to be stored in the KeyStore
 * @return
 * @throws Exception
 */
private static File createKeyStoreFile(final X509Certificate rootX509Certificate) throws Exception {
    final File keyStoreFile = File.createTempFile(KEY_STORE_FILE_PREFIX, KEY_STORE_FILE_SUFFIX);
    try (final FileOutputStream fos = new FileOutputStream(keyStoreFile.getPath())) {
        final KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE, KEY_STORE_PROVIDER);
        ks.load(null);
        ks.setCertificateEntry("rootCaCertificate", rootX509Certificate);
        ks.store(fos, DEFAULT_KEY_STORE_PASSWORD.toCharArray());
    }
    return keyStoreFile;
}

Вот константы.

      public static final String SSL_CERTIFICATE = "rds-ca-2019-root.pem";
public static final String KEY_STORE_TYPE = "JKS";
public static final String KEY_STORE_PROVIDER = "SUN";
public static final String KEY_STORE_FILE_PREFIX = "sys-connect-via-ssl-test-cacerts";
public static final String KEY_STORE_FILE_SUFFIX = ".jks";
public static final String DEFAULT_KEY_STORE_PASSWORD = "changeit";

Вот ссылка на файл rds-ca-2019-root.pem, помещающий этот файл в папку ресурсов.

дайте мне знать, что это работает для вас.

Вот образец

             setSslProperties();
        final MongoCredential credential = MongoCredential.createCredential(userName, mongoProps.getDatabaseName(), password.toCharArray());
        final MongoClientSettings settings = MongoClientSettings.builder()
                .credential(credential)
                .readPreference(ReadPreference.secondaryPreferred())
                .retryWrites(false)
                .applyToSslSettings(builder -> builder.enabled(true))
                .applyToConnectionPoolSettings(connPoolBuilder ->
                        ConnectionPoolSettings.builder().
                                maxSize(1).build())
                .applyToClusterSettings(builder ->
                        builder.hosts(Arrays.asList(new ServerAddress(clusterEndPoint, 27017))))
                .build();
        mongoClient = MongoClients.create(settings);

Простое решение - вы можете удалить опцию TLS (SSL) в AWS, а затем удалить "ssl_ca_certs=rds-comdated-ca-bundle.pem" из строки подключения. Но если приложению требуется подключение к базе данных SSL, вы можете использовать Руководство AWS.

Другие вопросы по тегам