Merge pull request #691 from anataliocs/BAEL-223-Integrate-DynamoDB-into-a-Spring-Boot-Application-using-Spring-Data
BAEL-223 - Integrate DynamoDB into a Spring Boot Application using Sp…
This commit is contained in:
commit
bc290f1166
|
@ -0,0 +1,4 @@
|
|||
/target/
|
||||
.settings/
|
||||
.classpath
|
||||
.project
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,177 @@
|
|||
<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-dynamodb</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>com.baeldung.Application</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>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-releasetrain</artifactId>
|
||||
<version>Gosling-SR1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</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.webjars</groupId>
|
||||
<artifactId>bootstrap</artifactId>
|
||||
<version>3.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-dynamodb</artifactId>
|
||||
<version>1.11.34</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.derjust</groupId>
|
||||
<artifactId>spring-data-dynamodb</artifactId>
|
||||
<version>4.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.2</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>
|
||||
</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>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = { "com.baeldung" })
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.spring.data.es.config;
|
||||
|
||||
import com.amazonaws.auth.AWSCredentials;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
|
||||
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@Configuration
|
||||
@EnableDynamoDBRepositories(basePackages = "com.baeldung.spring.data.es.repositories")
|
||||
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.isEmpty(amazonDynamoDBEndpoint)) {
|
||||
amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
|
||||
}
|
||||
return amazonDynamoDB;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AWSCredentials amazonAWSCredentials() {
|
||||
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
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;
|
||||
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
|
||||
|
||||
@DynamoDBTable(tableName = "ProductInfo")
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.spring.data.es.repositories;
|
||||
|
||||
import com.baeldung.spring.data.es.model.ProductInfo;
|
||||
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EnableScan
|
||||
public interface ProductInfoRepository extends CrudRepository<ProductInfo, String> {
|
||||
List<ProductInfo> findById(String id);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
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
|
||||
|
||||
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
|
||||
|
||||
#AWS Keys
|
||||
amazon.dynamodb.endpoint=http://localhost:8000/
|
||||
amazon.aws.accesskey=test1
|
||||
amazon.aws.secretkey=test1
|
|
@ -0,0 +1,6 @@
|
|||
spring.output.ansi.enabled=never
|
||||
server.port=7070
|
||||
|
||||
# Security
|
||||
security.user.name=admin
|
||||
security.user.password=password
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,74 @@
|
|||
package com.baeldung.spring.data.es.repository;
|
||||
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
|
||||
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
|
||||
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
|
||||
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
|
||||
import com.amazonaws.services.dynamodbv2.model.ResourceInUseException;
|
||||
import com.baeldung.Application;
|
||||
import com.baeldung.spring.data.es.model.ProductInfo;
|
||||
import com.baeldung.spring.data.es.repositories.ProductInfoRepository;
|
||||
import org.junit.Before;
|
||||
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 java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@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 AmazonDynamoDB amazonDynamoDB;
|
||||
|
||||
@Autowired
|
||||
ProductInfoRepository repository;
|
||||
|
||||
private static final String EXPECTED_COST = "20";
|
||||
private static final String EXPECTED_PRICE = "50";
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
|
||||
try {
|
||||
dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
|
||||
|
||||
CreateTableRequest tableRequest = dynamoDBMapper.generateCreateTableRequest(ProductInfo.class);
|
||||
|
||||
tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
|
||||
|
||||
amazonDynamoDB.createTable(tableRequest);
|
||||
} 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>) repository.findAll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenItemWithExpectedCost_whenRunFindAll_thenItemIsFound() {
|
||||
|
||||
ProductInfo productInfo = new ProductInfo(EXPECTED_COST, EXPECTED_PRICE);
|
||||
repository.save(productInfo);
|
||||
|
||||
List<ProductInfo> result = (List<ProductInfo>) repository.findAll();
|
||||
assertTrue("Not empty", result.size() > 0);
|
||||
assertTrue("Contains item with expected cost", result.get(0).getCost().equals(EXPECTED_COST));
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
spring.profiles.active=exception
|
||||
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
|
|
@ -0,0 +1,6 @@
|
|||
# Security
|
||||
security.user.name=admin
|
||||
security.user.password=password
|
||||
|
||||
spring.dao.exceptiontranslation.enabled=false
|
||||
spring.profiles.active=exception
|
Loading…
Reference in New Issue