BAEL-1173 - Add spring-cloud-aws module (#3046)
This commit is contained in:
parent
6211154062
commit
dba132f7de
|
@ -18,6 +18,7 @@
|
||||||
<module>spring-cloud-gateway</module>
|
<module>spring-cloud-gateway</module>
|
||||||
<module>spring-cloud-stream</module>
|
<module>spring-cloud-stream</module>
|
||||||
<module>spring-cloud-connectors-heroku</module>
|
<module>spring-cloud-connectors-heroku</module>
|
||||||
|
<module>spring-cloud-aws</module>
|
||||||
</modules>
|
</modules>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Spring Cloud AWS
|
||||||
|
|
||||||
|
#### Running the Integration Tests
|
||||||
|
|
||||||
|
To run the Integration Tests, we need to have an AWS account and have API keys generated for programmatic access. Edit
|
||||||
|
the `application.properties` file to add the following properties:
|
||||||
|
|
||||||
|
```
|
||||||
|
cloud.aws.credentials.accessKey=YourAccessKey
|
||||||
|
cloud.aws.credentials.secretKey=YourSecretKey
|
||||||
|
cloud.aws.region.static=us-east-1
|
||||||
|
```
|
||||||
|
|
||||||
|
To test automatic DataSource creation from RDS instance, we also need to create an RDS instance in the AWS account.
|
||||||
|
Let's say that the RDS instance is called `spring-cloud-test-db` having the master password `se3retpass`, then we need
|
||||||
|
to write the following in `application.properties`:
|
||||||
|
|
||||||
|
```
|
||||||
|
cloud.aws.rds.spring-cloud-test-db
|
||||||
|
cloud.aws.rds.spring-cloud-test-db.password=se3retpass
|
||||||
|
```
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung.spring.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-aws</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Spring Cloud AWS</name>
|
||||||
|
<description>Spring Cloud AWS Examples</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<spring-cloud.version>Dalston.SR4</spring-cloud.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-aws</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-aws-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-aws-messaging</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.spring.cloud.aws;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SpringCloudAwsApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringCloudAwsApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.config;
|
||||||
|
|
||||||
|
import com.amazonaws.services.sns.AmazonSNS;
|
||||||
|
import com.amazonaws.services.sqs.AmazonSQSAsync;
|
||||||
|
import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate;
|
||||||
|
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class SpringCloudAwsConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSQSAsync) {
|
||||||
|
return new QueueMessagingTemplate(amazonSQSAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public NotificationMessagingTemplate notificationMessagingTemplate(AmazonSNS amazonSNS) {
|
||||||
|
return new NotificationMessagingTemplate(amazonSNS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.s3;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.core.io.WritableResource;
|
||||||
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SpringCloudS3 {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ResourceLoader resourceLoader;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ResourcePatternResolver resourcePatternResolver;
|
||||||
|
|
||||||
|
public void downloadS3Object(String s3Url) throws IOException {
|
||||||
|
Resource resource = resourceLoader.getResource(s3Url);
|
||||||
|
File downloadedS3Object = new File(resource.getFilename());
|
||||||
|
try (InputStream inputStream = resource.getInputStream()) {
|
||||||
|
Files.copy(inputStream, downloadedS3Object.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uploadFileToS3(File file, String s3Url) throws IOException {
|
||||||
|
WritableResource resource = (WritableResource) resourceLoader.getResource(s3Url);
|
||||||
|
try (OutputStream outputStream = resource.getOutputStream()) {
|
||||||
|
Files.copy(file.toPath(), outputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadMultipleS3Objects(String s3UrlPattern) throws IOException {
|
||||||
|
Resource[] allFileMatchingPatten = this.resourcePatternResolver.getResources(s3UrlPattern);
|
||||||
|
for (Resource resource : allFileMatchingPatten) {
|
||||||
|
String fileName = resource.getFilename();
|
||||||
|
fileName = fileName.substring(0, fileName.lastIndexOf("/") + 1);
|
||||||
|
File downloadedS3Object = new File(fileName);
|
||||||
|
try (InputStream inputStream = resource.getInputStream()) {
|
||||||
|
Files.copy(inputStream, downloadedS3Object.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sns;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage;
|
||||||
|
import org.springframework.cloud.aws.messaging.config.annotation.NotificationSubject;
|
||||||
|
import org.springframework.cloud.aws.messaging.endpoint.NotificationStatus;
|
||||||
|
import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationMessageMapping;
|
||||||
|
import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationSubscriptionMapping;
|
||||||
|
import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationUnsubscribeConfirmationMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/topic-subscriber")
|
||||||
|
public class SNSEndpointController {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SNSEndpointController.class);
|
||||||
|
|
||||||
|
@NotificationMessageMapping
|
||||||
|
public void receiveNotification(@NotificationMessage String message, @NotificationSubject String subject) {
|
||||||
|
logger.info("Received message: {}, having subject: {}", message, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotificationUnsubscribeConfirmationMapping
|
||||||
|
public void confirmSubscriptionMessage(NotificationStatus notificationStatus) {
|
||||||
|
logger.info("Unsubscribed from Topic");
|
||||||
|
notificationStatus.confirmSubscription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotificationSubscriptionMapping
|
||||||
|
public void confirmUnsubscribeMessage(NotificationStatus notificationStatus) {
|
||||||
|
logger.info("Subscribed to Topic");
|
||||||
|
notificationStatus.confirmSubscription();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sns;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SNSMessageSender {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
NotificationMessagingTemplate notificationMessagingTemplate;
|
||||||
|
|
||||||
|
public void send(String topicName, Object message, String subject) {
|
||||||
|
notificationMessagingTemplate.sendNotification(topicName, message, subject);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sqs;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
|
||||||
|
import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.messaging.handler.annotation.Header;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class SpringCloudSQS {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQS.class);
|
||||||
|
|
||||||
|
static final String QUEUE_NAME = "spring-cloud-test-queue";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CountDownLatch is added to wait for messages
|
||||||
|
* during integration test
|
||||||
|
*/
|
||||||
|
CountDownLatch countDownLatch;
|
||||||
|
|
||||||
|
public void setCountDownLatch(CountDownLatch countDownLatch) {
|
||||||
|
this.countDownLatch = countDownLatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
QueueMessagingTemplate queueMessagingTemplate;
|
||||||
|
|
||||||
|
@SqsListener(QUEUE_NAME)
|
||||||
|
public void receiveMessage(String message, @Header("SenderId") String senderId) {
|
||||||
|
logger.info("Received message: {}, having SenderId: {}", message, senderId);
|
||||||
|
if (countDownLatch != null) {
|
||||||
|
countDownLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(String queueName, Object message) {
|
||||||
|
queueMessagingTemplate.convertAndSend(queueName, message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
cloud.aws.credentials.accessKey=YourAccessKey
|
||||||
|
cloud.aws.credentials.secretKey=YourSecretKey
|
||||||
|
cloud.aws.region.static=us-east-1
|
||||||
|
|
||||||
|
cloud.aws.rds.spring-cloud-test-db
|
||||||
|
cloud.aws.rds.spring-cloud-test-db.password=se3retpass
|
||||||
|
|
||||||
|
# These 3 properties are optional
|
||||||
|
cloud.aws.rds.spring-cloud-test-db.username=testuser
|
||||||
|
cloud.aws.rds.spring-cloud-test-db.readReplicaSupport=true
|
||||||
|
cloud.aws.rds.spring-cloud-test-db.databaseName=test
|
||||||
|
|
||||||
|
# Disable auto cloudfromation
|
||||||
|
cloud.aws.stack.auto=false
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.baeldung.spring.cloud.aws;
|
||||||
|
|
||||||
|
import com.amazonaws.auth.AWSCredentials;
|
||||||
|
import com.amazonaws.auth.AWSCredentialsProvider;
|
||||||
|
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||||
|
import com.amazonaws.auth.BasicAWSCredentials;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||||
|
import com.amazonaws.services.sns.AmazonSNS;
|
||||||
|
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
|
||||||
|
import com.amazonaws.services.sqs.AmazonSQS;
|
||||||
|
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is needed only for testing. This is because we need to
|
||||||
|
* create AWS resources before Spring's Application context is created
|
||||||
|
* in a {@link BeforeClass} method. Since Autowired dependencies don't
|
||||||
|
* work in static context, we will use this class for AWS clients.
|
||||||
|
*/
|
||||||
|
public class SpringCloudAwsTestUtil {
|
||||||
|
|
||||||
|
private static String awsAccessKey;
|
||||||
|
private static String awsSecretKey;
|
||||||
|
private static String defaultRegion;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
InputStream is = SpringCloudAwsTestUtil.class.getResourceAsStream("/application.properties");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(is);
|
||||||
|
awsAccessKey = properties.getProperty("cloud.aws.credentials.accessKey");
|
||||||
|
awsSecretKey = properties.getProperty("cloud.aws.credentials.secretKey");
|
||||||
|
defaultRegion = properties.getProperty("cloud.aws.region.static");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AWSCredentials awsCredentials() {
|
||||||
|
return new BasicAWSCredentials(awsAccessKey, awsSecretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AWSCredentialsProvider awsCredentialsProvider() {
|
||||||
|
return new AWSStaticCredentialsProvider(awsCredentials());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmazonS3 amazonS3() {
|
||||||
|
return AmazonS3ClientBuilder.standard()
|
||||||
|
.withCredentials(awsCredentialsProvider())
|
||||||
|
.withRegion(defaultRegion)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmazonSNS amazonSNS() {
|
||||||
|
return AmazonSNSClientBuilder.standard()
|
||||||
|
.withCredentials(awsCredentialsProvider())
|
||||||
|
.withRegion(defaultRegion)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmazonSQS amazonSQS() {
|
||||||
|
return AmazonSQSClientBuilder.standard()
|
||||||
|
.withCredentials(awsCredentialsProvider())
|
||||||
|
.withRegion(defaultRegion)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.rds;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
public class SpringCloudRDSIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DataSource dataSource;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDataSourceCreated_thenSuccess() {
|
||||||
|
assertThat(dataSource).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDataSource_whenConnectionCreated_thenSuccess() throws SQLException {
|
||||||
|
Connection connection = dataSource.getConnection();
|
||||||
|
assertThat(connection).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenConnection_whenQueryExecuted_thenSuccess() throws SQLException {
|
||||||
|
Connection connection = dataSource.getConnection();
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
ResultSet resultSet = statement.executeQuery("SELECT 1");
|
||||||
|
while (resultSet.next()) {
|
||||||
|
int result = resultSet.getInt(1);
|
||||||
|
assertThat(result).isEqualTo(1);
|
||||||
|
}
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.s3;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
|
import com.amazonaws.services.s3.model.ListObjectsV2Result;
|
||||||
|
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||||
|
import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@TestPropertySource("classpath:application-test.properties")
|
||||||
|
public class SpringCloudS3IntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SpringCloudS3 springCloudS3;
|
||||||
|
|
||||||
|
private static String bucketName;
|
||||||
|
private static String testFileToDownload;
|
||||||
|
private static String testFileToUpload;
|
||||||
|
|
||||||
|
private static String[] filesWithSimilarName;
|
||||||
|
private static List<File> similarNameFiles;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setupResources() throws IOException {
|
||||||
|
|
||||||
|
bucketName = UUID.randomUUID().toString();
|
||||||
|
testFileToDownload = "test-file-download.txt";
|
||||||
|
testFileToUpload = "test-file-upload.txt";
|
||||||
|
|
||||||
|
filesWithSimilarName = new String[] { "foo/hello-apple.txt", "foo/hello-orange.txt", "bar/hello-grapes.txt", };
|
||||||
|
|
||||||
|
similarNameFiles = new ArrayList<>();
|
||||||
|
for (String name : filesWithSimilarName) {
|
||||||
|
similarNameFiles.add(new File(name.substring(0, name.lastIndexOf("/") + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.write(Paths.get(testFileToUpload), "Hello World Uploaded!".getBytes());
|
||||||
|
|
||||||
|
AmazonS3 amazonS3 = SpringCloudAwsTestUtil.amazonS3();
|
||||||
|
amazonS3.createBucket(bucketName);
|
||||||
|
|
||||||
|
amazonS3.putObject(bucketName, testFileToDownload, "Hello World");
|
||||||
|
|
||||||
|
for (String s3Key : filesWithSimilarName) {
|
||||||
|
amazonS3.putObject(bucketName, s3Key, "Hello World");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenS3ObjectDownloaded_thenSuccess() throws IOException {
|
||||||
|
String s3Url = "s3://" + bucketName + "/" + testFileToDownload;
|
||||||
|
springCloudS3.downloadS3Object(s3Url);
|
||||||
|
assertThat(new File(testFileToDownload)).exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenS3ObjectUploaded_thenSuccess() throws IOException {
|
||||||
|
String s3Url = "s3://" + bucketName + "/" + testFileToUpload;
|
||||||
|
File file = new File(testFileToUpload);
|
||||||
|
springCloudS3.uploadFileToS3(file, s3Url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMultipleS3ObjectsDownloaded_thenSuccess() throws IOException {
|
||||||
|
String s3Url = "s3://" + bucketName + "/**/hello-*.txt";
|
||||||
|
springCloudS3.downloadMultipleS3Objects(s3Url);
|
||||||
|
similarNameFiles.forEach(f -> assertThat(f).exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanUpResources() {
|
||||||
|
AmazonS3 amazonS3 = SpringCloudAwsTestUtil.amazonS3();
|
||||||
|
ListObjectsV2Result listObjectsV2Result = amazonS3.listObjectsV2(bucketName);
|
||||||
|
for (S3ObjectSummary objectSummary : listObjectsV2Result.getObjectSummaries()) {
|
||||||
|
amazonS3.deleteObject(bucketName, objectSummary.getKey());
|
||||||
|
}
|
||||||
|
amazonS3.deleteBucket(bucketName);
|
||||||
|
|
||||||
|
new File(testFileToDownload).delete();
|
||||||
|
new File(testFileToUpload).delete();
|
||||||
|
similarNameFiles.forEach(File::delete);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sns;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.cloud.aws.messaging.endpoint.NotificationStatus;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
public class SNSEndpointControllerUnitTest {
|
||||||
|
|
||||||
|
SNSEndpointController snsEndpointController;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
snsEndpointController = new SNSEndpointController();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenReceivedNotificationInvoked_thenSuccess() {
|
||||||
|
snsEndpointController.receiveNotification("Message", "Subject");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenConfirmUnsubscribeReturned_thenSuccess() {
|
||||||
|
NotificationStatus notificationStatus = mock(NotificationStatus.class);
|
||||||
|
doNothing().when(notificationStatus).confirmSubscription();
|
||||||
|
snsEndpointController.confirmUnsubscribeMessage(notificationStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenConfirmSubscriptionReturned_thenSuccess() {
|
||||||
|
NotificationStatus notificationStatus = mock(NotificationStatus.class);
|
||||||
|
doNothing().when(notificationStatus).confirmSubscription();
|
||||||
|
snsEndpointController.confirmSubscriptionMessage(notificationStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sns;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import com.amazonaws.services.sns.AmazonSNS;
|
||||||
|
import com.amazonaws.services.sns.model.CreateTopicResult;
|
||||||
|
import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil;
|
||||||
|
import com.baeldung.spring.cloud.aws.sqs.Greeting;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@TestPropertySource("classpath:application-test.properties")
|
||||||
|
public class SpringCloudSNSIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SNSMessageSender snsMessageSender;
|
||||||
|
|
||||||
|
private static String topicName;
|
||||||
|
private static String topicArn;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setupAwsResources() {
|
||||||
|
|
||||||
|
topicName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
AmazonSNS amazonSNS = SpringCloudAwsTestUtil.amazonSNS();
|
||||||
|
|
||||||
|
CreateTopicResult result = amazonSNS.createTopic(topicName);
|
||||||
|
topicArn = result.getTopicArn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMessagePublished_thenSuccess() {
|
||||||
|
String subject = "Test Message";
|
||||||
|
String message = "Hello World";
|
||||||
|
snsMessageSender.send(topicName, message, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenConvertedMessagePublished_thenSuccess() {
|
||||||
|
String subject = "Test Message";
|
||||||
|
Greeting message = new Greeting("Helo", "World");
|
||||||
|
snsMessageSender.send(topicName, message, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanupAwsResources() {
|
||||||
|
AmazonSNS amazonSNS = SpringCloudAwsTestUtil.amazonSNS();
|
||||||
|
amazonSNS.deleteTopic(topicArn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sqs;
|
||||||
|
|
||||||
|
public class Greeting {
|
||||||
|
private String message;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Greeting() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Greeting(String mesage, String name) {
|
||||||
|
this.message = mesage;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((message == null) ? 0 : message.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Greeting other = (Greeting) obj;
|
||||||
|
if (message == null) {
|
||||||
|
if (other.message != null)
|
||||||
|
return false;
|
||||||
|
} else if (!message.equals(other.message))
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
package com.baeldung.spring.cloud.aws.sqs;
|
||||||
|
|
||||||
|
import com.amazonaws.services.sqs.AmazonSQS;
|
||||||
|
import com.amazonaws.services.sqs.model.CreateQueueResult;
|
||||||
|
import com.amazonaws.services.sqs.model.PurgeQueueRequest;
|
||||||
|
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
|
||||||
|
import com.amazonaws.services.sqs.model.ReceiveMessageResult;
|
||||||
|
import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@TestPropertySource("classpath:application-test.properties")
|
||||||
|
public class SpringCloudSQSIntegrationTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQSIntegrationTest.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private SpringCloudSQS springCloudSQS;
|
||||||
|
|
||||||
|
private static String receiveQueueName;
|
||||||
|
private static String receiveQueueUrl;
|
||||||
|
|
||||||
|
private static String sendQueueName;
|
||||||
|
private static String sendQueueURl;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setupAwsResources() {
|
||||||
|
|
||||||
|
sendQueueName = UUID.randomUUID().toString();
|
||||||
|
receiveQueueName = SpringCloudSQS.QUEUE_NAME;
|
||||||
|
|
||||||
|
AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS();
|
||||||
|
|
||||||
|
CreateQueueResult receiveQueue = amazonSQS.createQueue(receiveQueueName);
|
||||||
|
receiveQueueUrl = receiveQueue.getQueueUrl();
|
||||||
|
|
||||||
|
CreateQueueResult sendQueue = amazonSQS.createQueue(sendQueueName);
|
||||||
|
sendQueueURl = sendQueue.getQueueUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMessageSentAndVerified_thenSuccess() throws InterruptedException {
|
||||||
|
|
||||||
|
String message = "Hello World";
|
||||||
|
springCloudSQS.send(sendQueueName, message);
|
||||||
|
|
||||||
|
AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS();
|
||||||
|
|
||||||
|
ReceiveMessageRequest request = new ReceiveMessageRequest(sendQueueURl);
|
||||||
|
request.setMaxNumberOfMessages(1);
|
||||||
|
|
||||||
|
ReceiveMessageResult result = null;
|
||||||
|
do {
|
||||||
|
result = amazonSQS.receiveMessage(request);
|
||||||
|
if (result.getMessages().size() == 0) {
|
||||||
|
logger.info("Message not received at first time, waiting for 1 second");
|
||||||
|
}
|
||||||
|
} while (result.getMessages().size() == 0);
|
||||||
|
assertThat(result.getMessages().get(0).getBody()).isEqualTo(message);
|
||||||
|
|
||||||
|
// Delete message so that it doen't interfere with other test
|
||||||
|
amazonSQS.deleteMessage(sendQueueURl, result.getMessages().get(0).getReceiptHandle());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenConvertedMessageSentAndVerified_thenSuccess() throws InterruptedException, IOException {
|
||||||
|
|
||||||
|
Greeting message = new Greeting("Hello", "World");
|
||||||
|
springCloudSQS.send(sendQueueName, message);
|
||||||
|
|
||||||
|
AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS();
|
||||||
|
|
||||||
|
ReceiveMessageRequest request = new ReceiveMessageRequest(sendQueueURl);
|
||||||
|
request.setMaxNumberOfMessages(1);
|
||||||
|
|
||||||
|
ReceiveMessageResult result = null;
|
||||||
|
do {
|
||||||
|
result = amazonSQS.receiveMessage(request);
|
||||||
|
if (result.getMessages().size() == 0) {
|
||||||
|
logger.info("Message not received at first time, waiting for 1 second");
|
||||||
|
}
|
||||||
|
} while (result.getMessages().size() == 0);
|
||||||
|
assertThat(new ObjectMapper().readValue(result.getMessages().get(0).getBody(), Greeting.class)).isEqualTo(message);
|
||||||
|
|
||||||
|
// Delete message so that it doen't interfere with other test
|
||||||
|
amazonSQS.deleteMessage(sendQueueURl, result.getMessages().get(0).getReceiptHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMessageSent_whenMessageReceived_thenSuccess() throws InterruptedException {
|
||||||
|
CountDownLatch countDownLatch = new CountDownLatch(5);
|
||||||
|
springCloudSQS.setCountDownLatch(countDownLatch);
|
||||||
|
|
||||||
|
AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
amazonSQS.sendMessage(receiveQueueUrl, "Hello World " + i);
|
||||||
|
logger.info("Sent message {}, waiting for 1 second", i + 1);
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
}
|
||||||
|
countDownLatch.await();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanupAwsResources() {
|
||||||
|
AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS();
|
||||||
|
PurgeQueueRequest receiveQueuePurge = new PurgeQueueRequest(receiveQueueUrl);
|
||||||
|
amazonSQS.purgeQueue(receiveQueuePurge);
|
||||||
|
amazonSQS.deleteQueue(receiveQueueUrl);
|
||||||
|
|
||||||
|
PurgeQueueRequest sendQueuePurge = new PurgeQueueRequest(sendQueueURl);
|
||||||
|
amazonSQS.purgeQueue(sendQueuePurge);
|
||||||
|
amazonSQS.deleteQueue(sendQueueURl);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Don't try to create DataSouce when running tests which don't need a DataSource
|
||||||
|
spring.autoconfigure.exclude=\
|
||||||
|
org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration,\
|
||||||
|
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
|
Loading…
Reference in New Issue