BAEL-223 - Integrate DynamoDB into a Spring Boot Application using Spring Data

This commit is contained in:
chris.anatalio 2016-09-17 22:51:06 -07:00
parent fa059546e5
commit b02d83df22
15 changed files with 480 additions and 0 deletions

4
spring-boot-data-dynamodb/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/target/
.settings/
.classpath
.project

View File

@ -0,0 +1,2 @@
###The Course
The "REST With Spring" Classes: http://bit.ly/restwithspring

View File

@ -0,0 +1,189 @@
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spring Boot Actuator</name>
<description>This is simple boot application for Spring boot actuator test</description>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>1.2.3.RELEASE</version>
<relativePath/>
</parent>
<properties>
<!-- The main class to start by executing java -jar -->
<start-class>org.baeldung.boot.DemoApplication</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<spring.version>4.3.1.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.subethamail</groupId>
<artifactId>subethasmtp</artifactId>
<version>3.1.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.11.34</version>
</dependency>
<dependency>
<groupId>org.socialsignin</groupId>
<artifactId>spring-data-dynamodb</artifactId>
<version>4.2.1</version>
</dependency>
</dependencies>
<build>
<finalName>spring-boot</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>opensourceagility-release</id>
<url>http://repo.opensourceagility.com/release/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@ -0,0 +1,41 @@
package com.baeldung.spring.data.es.config;
import org.apache.commons.lang3.StringUtils;
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 com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
@Configuration
@ComponentScan(basePackages = { "com.baeldung.spring.data.es.service" })
public class DynamoDBConfig {
@Value("${amazon.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
@Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
@Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
@Bean
public AmazonDynamoDB amazonDynamoDB() {
AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
if (StringUtils.isNotEmpty(amazonDynamoDBEndpoint)) {
amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
}
return amazonDynamoDB;
}
@Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.spring.data.es.model;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
public class ProductInfo {
private String id;
private String msrp;
private String cost;
public ProductInfo() {
}
public ProductInfo(String cost, String msrp) {
this.msrp = msrp;
this.cost = cost;
}
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
@DynamoDBAttribute
public String getMsrp() {
return msrp;
}
@DynamoDBAttribute
public String getCost() {
return cost;
}
public void setId(String id) {
this.id = id;
}
public void setMsrp(String msrp) {
this.msrp = msrp;
}
public void setCost(String cost) {
this.cost = cost;
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.spring.data.es.repository;
import java.util.List;
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;
import com.baeldung.spring.data.es.model.ProductInfo;
@EnableScan
public interface ProductInfoRepository extends CrudRepository<ProductInfo, String> {
List<ProductInfo> findById(String id);
}

View File

@ -0,0 +1,13 @@
package org.baeldung;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
@org.springframework.boot.autoconfigure.SpringBootApplication
public class Application {
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,31 @@
server.port=8080
server.contextPath=/springbootapp
management.port=8081
management.address=127.0.0.1
endpoints.shutdown.enabled=true
endpoints.jmx.domain=Spring Sample Application
endpoints.jmx.uniqueNames=true
##jolokia.config.debug=true
##endpoints.jolokia.enabled=true
##endpoints.jolokia.path=jolokia
spring.jmx.enabled=true
endpoints.jmx.enabled=true
## for pretty printing of json when endpoints accessed over HTTP
http.mappers.jsonPrettyPrint=true
## Configuring info endpoint
info.app.name=Spring Sample Application
info.app.description=This is my first spring boot application G1
info.app.version=1.0.0
## Spring Security Configurations
security.user.name=admin1
security.user.password=secret1
management.security.role=SUPERUSER
logging.level.org.springframework=INFO

View File

@ -0,0 +1,6 @@
spring.output.ansi.enabled=never
server.port=7070
# Security
security.user.name=admin
security.user.password=password

View File

@ -0,0 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,19 @@
<html>
<head>
<title>WebJars Demo</title>
<link rel="stylesheet" href="/webjars/bootstrap/3.3.4/css/bootstrap.min.css" />
</head>
<body>
<div class="container"><br/>
<div class="alert alert-success">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
<strong>Success!</strong> It is working as we expected.
</div>
</div>
<script src="/webjars/jquery/2.1.4/jquery.min.js"></script>
<script src="/webjars/bootstrap/3.3.4/js/bootstrap.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,85 @@
package com.baeldung.spring.data.es.repository;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.baeldung.Application;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ResourceInUseException;
import com.baeldung.spring.data.es.model.ProductInfo;
import com.baeldung.spring.data.es.repository.ProductInfoRepository;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@ActiveProfiles("local")
@TestPropertySource(properties = { "amazon.dynamodb.endpoint=http://localhost:8000/", "amazon.aws.accesskey=test1", "amazon.aws.secretkey=test231" })
public class ProductInfoRepositoryIntegrationTest {
private DynamoDBMapper dynamoDBMapper;
@Autowired
private DynamoDB dynamoDB;
@Autowired
private AmazonDynamoDB amazonDynamoDB;
@Autowired
ProductInfoRepository ProductInfoRepository;
private static final String EXPECTED_COST = "20";
private static final String EXPECTED_PRICE = "50";
@Before
@Ignore
public void setUp() throws Exception {
try {
dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
CreateTableRequest tableRequest = dynamoDBMapper.generateCreateTableRequest(ProductInfo.class); // 1
tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L)); // 2
Table table = dynamoDB.createTable(tableRequest); // 3
table.waitForActive(); // 4
} catch (ResourceInUseException e) {
// Do nothing, table already created
}
// TODO How to handle different environments. i.e. AVOID deleting all entries in ProductInfoion table
dynamoDBMapper.batchDelete((List<ProductInfo>) ProductInfoRepository.findAll());
}
@Ignore
@Test
public void sampleTestCase() {
ProductInfo dave = new ProductInfo(EXPECTED_COST, EXPECTED_PRICE);
ProductInfoRepository.save(dave);
List<ProductInfo> result = (List<ProductInfo>) ProductInfoRepository.findAll();
assertTrue("Not empty", result.size() > 0);
assertTrue("Contains item with expected cost", result.get(0).getCost().equals(EXPECTED_COST));
}
}

View File

@ -0,0 +1,7 @@
spring.mail.host=localhost
spring.mail.port=8025
spring.mail.properties.mail.smtp.auth=false
amazon.dynamodb.endpoint=http://localhost:8000/
amazon.aws.accesskey=key
amazon.aws.secretkey=key2

View File

@ -0,0 +1,2 @@
spring.profiles.active=exception
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

View File

@ -0,0 +1,6 @@
# Security
security.user.name=admin
security.user.password=password
spring.dao.exceptiontranslation.enabled=false
spring.profiles.active=exception