AWS Lambda Starter & Consistency Models

This commit is contained in:
Kenny Bastani
2016-12-20 11:47:44 -08:00
parent 58c0a03e05
commit 9f4535b986
49 changed files with 949 additions and 313 deletions

View File

@@ -0,0 +1,52 @@
<?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>
<artifactId>spring-boot-starter-aws-lambda</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.kbastani</groupId>
<artifactId>event-stream-processing-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-lambda</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.11.67</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.11.67</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@@ -0,0 +1,88 @@
package amazon.aws;
import com.amazonaws.auth.*;
import com.amazonaws.services.lambda.AWSLambdaClientBuilder;
import com.amazonaws.services.lambda.invoke.LambdaInvokerFactory;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.amazonaws.services.securitytoken.model.GetSessionTokenRequest;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* This class is a client for interacting with Amazon S3 bucket resources.
*
* @author kbastani
*/
@Component
public class AWSLambdaConfigurerAdapter {
private String accessKeyId;
private String accessKeySecret;
private Credentials sessionCredentials;
/**
* Create a new instance of the {@link AWSLambdaConfigurerAdapter} with the bucket name and access credentials
*
* @param accessKeyId is the access key id credential for the specified bucket name
* @param accessKeySecret is the access key secret for the specified bucket name
*/
public AWSLambdaConfigurerAdapter(String accessKeyId,
String accessKeySecret) {
this.accessKeyId = accessKeyId;
this.accessKeySecret = accessKeySecret;
}
/**
* Gets an instance of a function interface
* @param type
* @param <T>
* @return
*/
public <T> T getFunctionInstance(Class<T> type) {
return LambdaInvokerFactory.builder()
.lambdaClient(AWSLambdaClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(
getBasicSessionCredentials()))
.build())
.build(type);
}
/**
* Get the basic session credentials for the template's configured IAM authentication keys
*
* @return a {@link BasicSessionCredentials} instance with a valid authenticated session token
*/
private BasicSessionCredentials getBasicSessionCredentials() {
// Create a new session token if the session is expired or not initialized
if (sessionCredentials == null || sessionCredentials.getExpiration().before(new Date()))
sessionCredentials = getSessionCredentials();
// Create basic session credentials using the generated session token
return new BasicSessionCredentials(sessionCredentials.getAccessKeyId(),
sessionCredentials.getSecretAccessKey(),
sessionCredentials.getSessionToken());
}
/**
* Creates a new session credential that is valid for 12 hours
*
* @return an authenticated {@link Credentials} for the new session token
*/
private Credentials getSessionCredentials() {
// Create a new session with the user credentials for the service instance
AWSSecurityTokenServiceClient stsClient =
new AWSSecurityTokenServiceClient(new BasicAWSCredentials(accessKeyId, accessKeySecret));
// Start a new session for managing a service instance's bucket
GetSessionTokenRequest getSessionTokenRequest =
new GetSessionTokenRequest().withDurationSeconds(43200);
// Get the session token for the service instance's bucket
sessionCredentials = stsClient.getSessionToken(getSessionTokenRequest).getCredentials();
return sessionCredentials;
}
}

View File

@@ -0,0 +1,28 @@
package amazon.aws;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* This class auto-configures a {@link AWSLambdaConfigurerAdapter} bean.
*
* @author kbastani
*/
@Configuration
@ConditionalOnMissingBean(AWSLambdaConfigurerAdapter.class)
@EnableConfigurationProperties(AmazonProperties.class)
public class AmazonAutoConfiguration {
@Autowired
private AmazonProperties amazonProperties;
@Bean
protected AWSLambdaConfigurerAdapter lambdaAdapter() {
return new AWSLambdaConfigurerAdapter(
amazonProperties.getAws().getAccessKeyId(),
amazonProperties.getAws().getAccessKeySecret());
}
}

View File

@@ -0,0 +1,89 @@
package amazon.aws;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.context.annotation.Configuration;
/**
* Configuration property group for Amazon S3 and AWS
*
* @author kbastani
*/
@Configuration
@ConfigurationProperties(prefix = "amazon")
public class AmazonProperties {
@NestedConfigurationProperty
private Aws aws;
/**
* A property group for Amazon Web Service (AWS) configurations
*
* @return a property group for AWS configurations
*/
public Aws getAws() {
return aws;
}
/**
* A property group for Amazon Web Service (AWS) configurations
*
* @param aws is a property group for AWS configurations
*/
public void setAws(Aws aws) {
this.aws = aws;
}
/**
* A property group for Amazon Web Service (AWS) configurations
*/
public static class Aws {
private String accessKeyId;
private String accessKeySecret;
/**
* A valid AWS account's access key id.
*
* @return an AWS access key id
*/
public String getAccessKeyId() {
return accessKeyId;
}
/**
* A valid AWS account's access key id.
*
* @param accessKeyId is a valid AWS account's access key id.
*/
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
/**
* A valid AWS account's secret access token.
*
* @return an AWS account's secret access key
*/
public String getAccessKeySecret() {
return accessKeySecret;
}
/**
* A valid AWS account's secret access token.
*
* @param accessKeySecret is a valid AWS account's secret access token.
*/
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
@Override
public String toString() {
return "Aws{" +
"accessKeyId='" + accessKeyId + '\'' +
", accessKeySecret='" + accessKeySecret + '\'' +
'}';
}
}
}

View File

@@ -0,0 +1,9 @@
{
"groups": [
{
"name": "amazon",
"type": "amazon.aws.AmazonProperties",
"sourceType": "amazon.aws.AmazonProperties"
}
]
}

View File

@@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=amazon.aws.AmazonAutoConfiguration

View File

@@ -0,0 +1,2 @@
amazon.aws.access-key-id=replace
amazon.aws.access-key-secret=replace

View File

@@ -0,0 +1,44 @@
package amazon.aws;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import static junit.framework.TestCase.assertNotNull;
public class AmazonConfigurationTest {
private AnnotationConfigApplicationContext context;
@After
public void tearDown() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void defaultAdapter() {
load(EmptyConfiguration.class,
"amazon.aws.access-key-id=AJGLDLSXKDFLS",
"amazon.aws.access-key-secret=XSDFSDFLKKHASDFJALASDF");
AWSLambdaConfigurerAdapter amazonS3Template = this.context.getBean(AWSLambdaConfigurerAdapter.class);
assertNotNull(amazonS3Template);
}
@Configuration
static class EmptyConfiguration {
}
private void load(Class<?> config, String... environment) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
applicationContext.register(config);
applicationContext.register(AmazonAutoConfiguration.class);
applicationContext.refresh();
this.context = applicationContext;
}
}