I'm not able to connect my spring boot application to aws document db. Please tell me where am I going wrong.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.mercedes-benz.xdrs</groupId>
<artifactId>xdrs_data_service_api</artifactId>
<version>1.0.0.0</version>
<name>xdrs_data_service_api</name>
<description>xdrs data service api</description>
<packaging>jar</packaging>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.2</spring-cloud.version>
<log4j2.version>2.19.0</log4j2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.10</version> <!-- Use the latest version -->
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.4.1</version> <!-- Use the latest version -->
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.986</version> <!-- Use the latest version -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Beta2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>3.11.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>xdrs-data-service-api</finalName>
</build>
DocumentDBConf.java
package com.mercedesBenz.xdrs.dataService.config;
import java.io.File;
import java.security.Security;
import javax.net.ssl.SSLContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
public class DocumentDBConf {
@Value("${documentdb.connectionString}")
private String connectionString;
@Value("${documentdb.pemFile}")
private String pemFile;
@Bean
public MongoClient mongoClient() throws Exception {
// Load the .pem certificate file
File pemCertificate = new File(pemFile);
// Enable AWS DocumentDB TLS
System.setProperty("javax.net.ssl.trustStore", pemCertificate.getAbsolutePath());
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); // The default trust store password
System.setProperty("javax.net.debug", "ssl");
// Enable strong cryptography
// Security.setProperty("crypto.policy", "unlimited");
ConnectionString connString = new ConnectionString(connectionString);
MongoClientSettings settings = MongoClientSettings.builder()
.applyToSslSettings(sslSettingsBuilder -> {
try {
sslSettingsBuilder.enabled(true)
.context(SSLContext.getDefault()); // Use the default SSLContext
} catch (Exception e) {
throw new RuntimeException("Error creating SSL context", e);
}
})
.applyConnectionString(connString)
.build();
return MongoClients.create(settings);
}
@Bean
public MongoTemplate mongoTemplate(MongoClient mongoClient) {
return new MongoTemplate(mongoClient, "test"); // Replace 'your_database_name' with your actual database name
}
}
application.properties
documentdb.connectionString=mongodb://user:pwd@xdrs-int-docdb-
cluster-identifier.cluster-c6wywertyiq6.eu-central-1.docdb.amazonaws.com:27017/test?tls=true
documentdb.pemFile=/xdrs_data_service_api/src/main/resources/global-bundle.pem
#documentdb.pemFile=classpath:docdb.cert
#documentdb.pemFile=classpath:rds-truststore.jks
management.metrics.mongo.command.enabled=false
management.metrics.mongo.connectionpool.enabled=false
XdrsDataServiceApplication.java
package com.mercedesBenz.xdrs.dataService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
@SpringBootApplication(exclude = {MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class})
public class XdrsDataServiceApplication {
public static void main(String[] args) {
SpringApplication.run(XdrsDataServiceApplication.class, args);
}
}
Image of where my pem file is stored
In local I am getting following error
When I deploy the same code in AWS ECS Fargate, I see the following logs
There are two issues here:
.pem
certificate file isn't directly usable as a Java trust store. Instead, it contains the certificates which should be imported into a Java trust store (using thekeytool
Java utility), so that your program can then reference that trust store (via thejavax.net.ssl.trustStore
system property) in verifying the identity of the DocumentDB server.sun.security.*
packages (referenced in the Fargate logs you posted) verify the DocumentDB server's identity by attempting to build a valid PKIX certification path from the root CA certificates found in the Java trust store to the certificate presented by the particular DocumentDB server you are targeting. If the Java trust store found atjavax.net.ssl.trustStore
is either invalid (e.g., because it's a.pem
file instead of a valid.jks
file), or if it doesn't contain the necessary certificates (e.g., because the root CA certificates found inglobal-bundle.pem
were never imported using the Javakeytool
utility), PKIX path building fails, meaning the identity of the DocumentDB server cannot be established. See Connecting with TLS Enabled for more details (and be sure to select the "Java" tab to see Java-specific instructions.)