Integrate Spring Boot application with Amazon DocumentDB

a17affd60c5adb454a6f0720ef70d86c.gif

Amazon DocumentDB (compatible with MongoDB) is a scalable, highly durable, and fully managed database service for operating mission-critical MongoDB workloads. On Amazon DocumentDB, you can use the same MongoDB application code, drivers, and tools to run, manage, and scale workloads without having to worry about managing the underlying infrastructure. 

Spring Boot provides an easy and fast way to build production-grade applications based on the Spring framework. In order to do this, Spring Boot prepackages auto-configuration modules for most of the libraries commonly used with the Spring Framework. In short, open source Spring Boot follows conventions about configuration, adding auto-configuration capabilities on top of the Spring framework.

In this post, you'll explore the basics of integrating a Spring Boot application with Amazon DocumentDB using the Spring Data MongoDB API. You can also create sample data models and repository classes for performing database operations.

Solution overview

The configuration of Spring Boot and Amazon DocumentDB is relatively simple, involving only a few configuration steps.

Spring Boot allows applications to interact with Amazon DocumentDB using the MongoTemplate class and the MongoRepository interface. MongoTemplate follows the standard template pattern in Spring and provides a ready-made basic API for the underlying persistence engine. MongoTemplate provides out-of-the-box APIs for operations such as aggregation, streaming, updates, and custom queries. MongoRepository follows a Spring Data-centric approach, providing a more flexible and simpler API based on the well-known Create, Read, Update, and Delete (CRUD, Create, Read, Update, and Delete) access patterns in all Spring Data projects operate.

For both options, you first define dependencies for your Maven project in pom.xml.

This post focuses on how to use MongoRepository to interact with Amazon DocumentDB.

prerequisites

You need to meet the following prerequisites:

  • Amazon DocumentDB cluster  – This article starts with an existing Amazon DocumentDB cluster that you will integrate with your Spring Boot application. If you don't already have an Amazon DocumentDB cluster, see Get Started with Amazon DocumentDB (Getting Started with Amazon DocumentDB) to create a new cluster (https://docs.aws.amazon.com/documentdb/latest/developerguide/get-started-guide.html ).

  • Integrated Development Environment (IDE)  – For example, Eclipse or Amazon Cloud9. This demo uses Amazon Cloud9, a cloud-based IDE that lets you write, run, and debug code using just a browser. It includes code editors, debuggers, and terminals. Enable Enhanced support for Java development (https://docs.aws.amazon.com/cloud9/latest/user-guide/enhanced-java.html) to improve your development experience when using Java.

  • Java 17  – For information on installing or upgrading Java in Amazon Cloud9, see the Amazon Corretto 17 Installation Instructions (https://docs.aws.amazon.com/corretto/latest/corretto-17- ug/amazon-linux-install.html)

  • Maven  – See Setting Up Maven to Install Maven in Amazon Cloud9 (https://docs.aws.amazon.com/cloud9/latest/user-guide/sample-java.html#sample-java-sdk-maven)

  • Spring Initializr

Charges associated with Amazon DocumentDB and Amazon Cloud9 resources may accrue to your account. You can use the Amazon Web Services Pricing Calculator to estimate this cost (https://calculator.aws/).

Using Spring Initializr 

Create a Spring Boot application

Using the following steps, create a new Spring Boot application project that supports Spring Data MongoDB. As an alternative, you can use the spring-boot-docdb-sample application from the GitHub repository. (https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/docdb-springboot)

1. Browse to https://start.spring.io/.

2. Specify the following options:

  1. Select  Maven project (Maven project), and  Language (language) is  Java .

  2. Choose version 3.0.0 of Spring Boot.

  3. Specify a group and artifact name for the application.

  4. Specifies Java version 17.

  5. Select  ADD DEPENDENCIES (Add dependencies), then search for and select  Spring Data MongoDB . You can use the Spring Data MongoDB dependency to interact with an Amazon DocumentDB cluster from this application.

3. Choose  GENERATE to generate a Spring Boot project that contains all the files needed for bootstrapping.

4. Download the ZIP file to a path on your local computer and extract the file.

4a156081eecfd1641e40b31af9a4e673.png

If you are using the Amazon Cloud9 IDE, upload the ZIP file to the Amazon Cloud9 environment and unzip the file.

Verify Maven dependencies

Locate the pom.xml file in the application's directory, and verify that the Spring Data MongoDB dependency has been added as follows:

 XML 

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

Swipe left to see more

Define the data model

To store and retrieve data in an Amazon DocumentDB database, we first create a POJO model or entity class. This entity represents a collection in Amazon DocumentDB and uses annotations to define the collection name, properties, keys, and other aspects.

In this example, you create a collection of products and a corresponding model object that stores the details of the products in a catalog database. You create a product model with six attributes: id , name , sku , description , inventory , and category .

Amazon DocumentDB stores data in collections. By default, Spring Data maps a product class or model to a collection named product. If you want to change the name of the collection, you can use Spring Data MongoDB's @Document annotation on the class. In the following example, we use @Document(collection = "products") to specify the collection name as products .

You can specify the document's primary key _id with the @Id annotation. If you don't specify anything, Amazon DocumentDB will generate the _id field when creating the document. Other attributes are not commented. This assumes that they map to fields with the same names as the properties themselves. In the project's directory, create a Product.java file with the following content:

 Java 

@Id
    private String id;    
    
    /** 
     * 设置对应于 products 集合中字段的数据成员
     */
     
    private String name;
    private String sku;
    private String description;
    private int inventory;
    private String category;
    


    /**
     * @param id
     * @param name
     * @param sku
     * @param description
     * @param inventory
     * @param category
     */
    public Product(String name, String sku, String description, int inventory, String category) {
        
        this.name = name;
        this.sku = sku;
        this.description = description;
        this.inventory = inventory;
        this.category = category;
    }
}

Swipe left to see more

Add getter and setter methods for each property. You can generate getter and setter methods using IDE-specific shortcuts. For example, right-click the code editor pane, select  Refactoring (refactoring), and then select  Generate Getter and Setter in Cloud9 (Generate Getter and Setter in Cloud9).

Also, it is recommended to override  the toString  method to output the object, for example, right-click on the code editor pane, select  Refactoring , and then select  Generate toString() in Cloud9 (Generate toString() in Cloud9)

8e1688f7075559ce624a803662123243.png

Connect with TLS enabled

To connect to a TLS-enabled Amazon DocumentDB cluster from a Java-based Spring Boot application, your program must use a Certificate Authority (CA, Certificate Authority) file provided by Amazon Web Services to authenticate the connection. To use an Amazon RDS CA certificate:

1. Create a temporary certs folder under the tmp folder. You can create folders for storing certificates according to your organization's security policy. In this article, create a certs folder under tmp:

 Bash 

mkdir /tmp/certs/

2. Run the following command to create a trust store using the CA certificate contained in the file. Make sure to update <truststorePassword>. The following shell script example imports a certificate bundle into a trust store on a Linux operating system. For other options, see Connecting with TLS Enabled (https://docs.aws.amazon.com/documentdb/latest/developerguide/connect_programmatically.html#connect_programmatically-tls_enabled).

 Bash 

mydir=/tmp/certs
truststore=${mydir}/rds-truststore.jks
storepassword=<truststorePassword>


curl -sS "https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem" > ${mydir}/rds-combined-ca-bundle.pem
awk 'split_after == 1 {n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1}{print > "rds-ca-" n ".pem"}' < ${mydir}/rds-combined-ca-bundle.pem


for CERT in rds-ca-*; do
  alias=$(openssl x509 -noout -text -in $CERT | perl -ne 'next unless /Subject:/; s/.*(CN=|CN = )//; print')
  echo "Importing $alias"
  keytool -import -file ${CERT} -alias "${alias}" -storepass ${storepassword} -keystore ${truststore} -noprompt
  rm $CERT
done


rm ${mydir}/rds-combined-ca-bundle.pem


echo "Trust store content is: "


keytool -list -v -keystore "$truststore" -storepass ${storepassword} | grep Alias | cut -d " " -f3- | while read alias 
do
   expiry=`keytool -list -v -keystore "$truststore" -storepass ${storepassword} -alias "${alias}" | grep Valid | perl -ne 'if(/until: (.*?)\n/) { print "$1\n"; }'`
   echo " Certificate ${alias} expires in '$expiry'" 
done

Swipe left to see more

Database and connection configuration

Two configuration files are required to set up the connection details and SSL trust store. First, define your Amazon DocumentDB connection parameters such as database, URI or host, port, username, and password in application.properties. Then set the keystore in the configuration class.

Configure the Spring Boot application properties file

To connect a Spring Boot application to Amazon DocumentDB, we need to define the database configuration in the application.properties file. You need to configure properties such as database URI, database name or hostname, username, password, and other connection-related properties. To connect to an Amazon DocumentDB cluster, you need to specify the connection URI string in the application.properties file located in the src/main/resources folder.

To retrieve your Amazon DocumentDB cluster endpoint and configure application.properties , complete the following steps:

1. In the navigation pane of the Amazon DocumentDB console, choose  Clusters .

2. Find your cluster and choose the regional cluster identifier.

3. On  the Connectivity & security tab, copy the link used by the application.

1515929d1cc694e51e90c631765ccf3a.png

Command to connect to the cluster.

4. Remove &ssl_ca_certs=rds-combined-ca-bundle.pem from the copied connection string since you already imported the CA file provided by Amazon Web Technologies into the trust store.

5. Add the connection URI to the application.properties file located in your project's src/main/resources folder. The connection URI key is spring.data.mongodb.uri . Make sure the copied connection string is in the following format:

spring.data.mongodb.uri=mongodb://<用户名>:<密码>@<集群端点>: 27017/?ssl=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false

Swipe left to see more

Alternatively, you can provide connection details individually, including hostname, port, username, and password, and corresponding property keys, such as spring.data.mongodb.host or spring.data.mongodb.port . For a complete list of available Spring Boot parameter configuration options, see Data Properties under Common Application Properties (https://docs.spring.io/spring-boot/docs/current/ reference/html/application-properties.html#appendix.application-properties.data).

6. Optionally, specify the database name in the application.properties file:

spring.data.mongodb.database=catalog

Create a configuration class and set up the keystore

Now that the property configuration is complete, you need to define a configuration class to set keystore properties in order to establish a secure connection.

To use the keystore in your application, set the following system property in your configuration class:

javax.net.ssl.trustStore: <truststore>
javax.net.ssl.trustStorePassword: <truststorePassword>

Swipe left to see more

See the example configuration class below. Mark the class as a configuration class with the @Configuration annotation. Classes annotated with @Configuration are used by the Spring container as a source of bean definitions.

 Java 

@Bean
        public MongoClientSettings mongoClientSettings() { 
             setSslProperties();
       return MongoClientSettings.builder()
                    .applyToSslSettings(builder -> builder.enabled(true))
                    .build();
  }


        private static void setSslProperties() { 
            System.setProperty("javax.net.ssl.trustStore", KEY_STORE_TYPE);
            System.setProperty("javax.net.ssl.trustStorePassword",          
                    DEFAULT_KEY_STORE_PASSWORD);
        }
  @Bean
        public MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(final MongoProperties properties) {
      return new MongoPropertiesClientSettingsBuilderCustomizer(properties);
  }
}

Swipe left to see more

That's all for Amazon DocumentDB configuration in Spring Boot Now, you can start defining interface-based repository classes by extending MongoRepository .

Configure the repository interface

Now you can use MongoRepository to access the data in the database. MongoRepository provides common functionality such as Create, Read, Update, and Delete (CRUD, Create, Read, Update, and Delete) operations. It acts as a link between the model and the database. It gets the domain class (Product) to manage, and gets the ID type of the domain class as a type parameter. There are several methods you can write that let the repository generate the query for you.

Create a repository interface that queries Product documents as follows:

 Java 

public interface ProductRepository extends MongoRepository<Product, String> {


}

Swipe left to see more

 ProductRepository extends the MongoRepository interface. This interface contains many operations, including standard CRUD operations. You'll define other custom actions in the next section.

Define service class

The service classes make use of the Spring Data repository interface. We define it by referencing the repository you created in the previous step:

 Java 

@Service
public class ProductService {
    
    @Autowired
    private ProductRepository productRepo;
}

Swipe left to see more

You'll build on this class by adding additional methods in the next section, which also presents a CRUD example.

Use CrudRepository

When using a MongoRepository that extends CrudRepository , your repository can access basic functionality, including save , count , findAll , and delete methods, from classes that implement the CrudRepository interface. Your ProductRepository interface extends MongoRepository and has access to all basic CRUD operations.

Let's explore and test these operations one by one.

save or create

First, you add some documents to the collection using the save method. The save method takes a Product object as input and saves the product document to an Amazon DocumentDB collection. Add the following code snippet to your service class:

 Java 

public void saveProducts() {
 
  productRepo.save(new Product("RayBan Sunglass Pro", "1590234","RayBan Sunglasses for professional sports people", 100, "fashion"));
  productRepo.save(new Product("GUCCI Handbag", "3451290", "Fashion Hand bags for all ages", 75, "fashion"));
  productRepo.save(new Product("Round hat", "8976045", "", 200, "fashion"));
  productRepo.save(new Product("Polo shirt", "6497023", "Cool shirts for hot summer", 25, "cloth"));
  productRepo.save(new Product("Swim shorts", "8245352", "Designer swim shorts for athletes", 200, "cloth"));
  productRepo.save(new Product("Running shoes", "3243662", "Shoes for work out and trekking", 20, "footware"));
  
  System.out.println(" Save complete ");
        
}

Swipe left to see more

count

In the next example, if there are no methods in the repository, the count() method in the service class is called to count the documents in the collection.

 Java 

public long getCount() {
    long count = productRepo.count();
    System.out.println(" Total number of products : "+count);
    return count;
}

Swipe left to see more

read

In this example, you perform three different read operations. You can extract products by name or SKU, and find product listings based on category.

You added three simple methods to your repository ( ProductRepository ). The first method findProductByName queries the collection based on the name attribute. Query filters are defined using the annotation @Query , in this case @Query("{name:'?0'}") . The second method findProductBySKU queries the collection based on the sku attribute and outputs only the name and inventory attributes in the query response. The third method findAll retrieves all documents of a specific category. See the code below:

 Java 

public interface ProductRepository extends MongoRepository<Product, String> {
    
    @Query("{name:'?0'}")
    Product findProductByName(String name);
    
    @Query(value="{sku:'?0'}", fields="{'name' : 1, 'inventory' : 1}")
    Product findProductBySKU (String sku);   


    @Query("{category:'?0'}")
    List<Product> findAllByCategory(String category);
                                                        
}

Swipe left to see more

You can call these three methods in the service class from the repository to find documents by name, SKU, and category.

 Java 

public Product getProductByName(String name) {
  System.out.println(" Getting product by name : " + name);
  Product product = productRepo.findProductByName(name);
  System.out.println(product);
  return product; 
}


public Product getProductBySKU(String sku) {
  System.out.println(" Getting product by SKU : " + sku);
  Product product = productRepo.findProductBySKU(sku);
  System.out.println(product);
   return product; 
}


public List<Product> findAllProductsByCategory(String category) {
  List<Product> productList = productRepo.findAllByCategory(category);
  productList.forEach(product -> System.out.println(product));
  return productList;
}

Swipe left to see more

renew

You can use the save method to update an existing document by passing the updated entity object. In this example, you query for existing products by SKU and increase inventory by 10. Add the following method to your service:

 Java 

public void updateInventory(String sku) {
  Product product =  getProductBySKU(sku);
  System.out.println(" Updating Inventory for product by sku: " + sku);  
  product.setInventory(product.getInventory()+10);
  Product updatedProd = productRepo.save(product);
}

Swipe left to see more

delete

In this example, you will create two delete operations. First, you delete a product by ID; in the second approach, you delete all documents (products) in the collection. Add the following method to your service class:

 Java 

public void deleteProduct(String id) {
   productRepo.deleteById(id);
  System.out.println("Product with id " + id + " deleted");
}


public void deleteAll() {
  productRepo.deleteAll();
  System.out.println("All Products deleted.");
}

Swipe left to see more

Build a Spring Boot application

A default Spring Boot application is already created by Spring Initializr in a root package (eg com.example.documentdb ). Open the default application in the IDE:

 Java 

@SpringBootApplication
public class DocumentdbApplication {


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

Swipe left to see more

 The CommandLineRunner interface indicates that a bean should be run when it is included in a SpringApplication so that the output can be viewed on the console. Implement the CommandLineRunner interface and provide an implant for the run method. We define a reference to your service using the @Autowired annotation. Spring uses the @SpringBootApplication annotation to initialize the application context:

 Java 

@Override
  public void run(String... args) throws Exception {
    
    System.out.printf("%n Insert few products : %n");
    prodService.saveProducts();
    
    System.out.printf("%n Count all products : %n");
    prodService.getCount();
    
    
    System.out.printf("%n Get product by name : %n");
    prodService.getProductByName("GUCCI Handbag");
    
    System.out.printf("%n Get product by sku : %n");
    prodService.getProductBySKU("8976045");
    
    System.out.printf("%n Get all products by category : %n");
    prodService.findAllProductsByCategory("fashion");
    
    System.out.printf("%n Update Inventory for Product by sku :  %n");
    prodService.updateInventory("3451290");
    
    System.out.printf("%n Delete product id  %n");
    prodService.deleteProduct("639a0046efe46b7343dd5004"); 
    
    System.out.printf("%n Deleting all products/documents  %n");
    prodService.deleteAll(); 
  }
}

Swipe left to see more

Run and test your application

Run the Spring Boot application with the following Maven command:

 Bash 

mvn spring-boot:run

The following screenshot is a sample output of a Spring Boot application.

f806137d9235fd82d57a41276a934c5c.png

You did it! You have successfully connected to Amazon DocumentDB from your Spring Boot application.

Summarize

In this article, you learned how to integrate Amazon DocumentDB with a Spring Boot application through a simple application that uses Spring Data MongoDB to save and fetch objects to and from the database, all without writing Concrete repository implementation with simple configuration.

The samples used in this post are available as a sample project on GitHub (https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/docdb-springboot).

Original URL: 

https://aws.amazon.com/cn/blogs/database/integrate-your-spring-boot-application-with-amazon-documentdb/

The author of this article

807e227787a43bf8345bee117cb61e84.jpeg

Gururaj S Bayari 

Senior DocumentDB Expert Solution Architect at Amazon Cloud Technology. He enjoys helping customers adopt Amazon's dedicated databases. He helps clients design, evaluate and optimize Internet-scale high-performance workloads using NoSQL and/or relational databases.

91b1dc1d71fa1242408a345a4ba55046.gif

3cd3e8cdf4007ccef52841ec81df8f48.gif

I heard, click the 4 buttons below

You will not encounter bugs!

7ba2b75f617d9d90efd4f2679b47348d.gif

Guess you like

Origin blog.csdn.net/u012365585/article/details/132644875
Recommended