Skip to content

V2 #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 19, 2020
Merged

V2 #6

Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,22 @@
</developers>

<properties>
<aws-java-sdk.version>1.11.817</aws-java-sdk.version>
<aws-java-sdk.version>2.13.64</aws-java-sdk.version>
<commons.logging.version>1.1.3</commons.logging.version>
</properties>

<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>${aws-java-sdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>utils</artifactId>
<version>${aws-java-sdk.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/software/amazon/payloadoffloading/AwsManagedCmk.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package software.amazon.payloadoffloading;

import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.ServerSideEncryption;

public class AwsManagedCmk implements ServerSideEncryptionStrategy {
@Override
public void decorate(PutObjectRequest.Builder putObjectRequestBuilder) {
putObjectRequestBuilder.serverSideEncryption(ServerSideEncryption.AWS_KMS);
}
}
18 changes: 18 additions & 0 deletions src/main/java/software/amazon/payloadoffloading/CustomerKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package software.amazon.payloadoffloading;

import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.ServerSideEncryption;

public class CustomerKey implements ServerSideEncryptionStrategy {
private final String awsKmsKeyId;

public CustomerKey(String awsKmsKeyId) {
this.awsKmsKeyId = awsKmsKeyId;
}

@Override
public void decorate(PutObjectRequest.Builder putObjectRequestBuilder) {
putObjectRequestBuilder.serverSideEncryption(ServerSideEncryption.AWS_KMS);
putObjectRequestBuilder.ssekmsKeyId(awsKmsKeyId);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package software.amazon.payloadoffloading;

import com.amazonaws.AmazonClientException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.exception.SdkClientException;

/**
* This class is used for carrying pointer to Amazon S3 objects which contain payloads.
*/
public class PayloadS3Pointer {
private static final Log LOG = LogFactory.getLog(PayloadS3Pointer.class);
private static final Logger LOG = LoggerFactory.getLogger(PayloadS3Pointer.class);
private String s3BucketName;
private String s3Key;

Expand Down Expand Up @@ -38,7 +38,7 @@ public String toJson() {
} catch (Exception e) {
String errorMessage = "Failed to convert S3 object pointer to text.";
LOG.error(errorMessage, e);
throw new AmazonClientException(errorMessage, e);
throw SdkClientException.create(errorMessage, e);
}
return s3PointerStr;
}
Expand All @@ -52,7 +52,7 @@ public static PayloadS3Pointer fromJson(String s3PointerJson) {
} catch (Exception e) {
String errorMessage = "Failed to read the S3 object pointer from given string.";
LOG.error(errorMessage, e);
throw new AmazonClientException(errorMessage, e);
throw SdkClientException.create(errorMessage, e);
}
return s3Pointer;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
package software.amazon.payloadoffloading;

import com.amazonaws.AmazonClientException;
import com.amazonaws.annotation.NotThreadSafe;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.NotThreadSafe;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.services.s3.S3Client;

/**
* Amazon payload storage configuration options such as Amazon S3 client,
* bucket name, and payload size threshold for payloads.
*/
@NotThreadSafe
public class PayloadStorageConfiguration {
private static final Log LOG = LogFactory.getLog(PayloadStorageConfiguration.class);
private static final Logger LOG = LoggerFactory.getLogger(PayloadStorageConfiguration.class);

private AmazonS3 s3;
private S3Client s3;
private String s3BucketName;
private int payloadSizeThreshold = 0;
private boolean alwaysThroughS3 = false;
private boolean payloadSupport = false;
/**
* This field is optional, it is set only when we want to configure S3 Server Side Encryption with KMS.
*/
private SSEAwsKeyManagementParams sseAwsKeyManagementParams;
private ServerSideEncryptionStrategy serverSideEncryptionStrategy;

public PayloadStorageConfiguration() {
s3 = null;
s3BucketName = null;
sseAwsKeyManagementParams = null;
serverSideEncryptionStrategy = null;
}

public PayloadStorageConfiguration(PayloadStorageConfiguration other) {
this.s3 = other.getAmazonS3Client();
this.s3 = other.getS3Client();
this.s3BucketName = other.getS3BucketName();
this.sseAwsKeyManagementParams = other.getSSEAwsKeyManagementParams();
this.payloadSupport = other.isPayloadSupportEnabled();
this.alwaysThroughS3 = other.isAlwaysThroughS3();
this.payloadSizeThreshold = other.getPayloadSizeThreshold();
this.serverSideEncryptionStrategy = other.getServerSideEncryptionStrategy();
}

/**
Expand All @@ -47,11 +46,11 @@ public PayloadStorageConfiguration(PayloadStorageConfiguration other) {
* @param s3BucketName Name of the bucket which is going to be used for storing payload.
* The bucket must be already created and configured in s3.
*/
public void setPayloadSupportEnabled(AmazonS3 s3, String s3BucketName) {
public void setPayloadSupportEnabled(S3Client s3, String s3BucketName) {
if (s3 == null || s3BucketName == null) {
String errorMessage = "S3 client and/or S3 bucket name cannot be null.";
LOG.error(errorMessage);
throw new AmazonClientException(errorMessage);
throw SdkClientException.create(errorMessage);
}
if (isPayloadSupportEnabled()) {
LOG.warn("Payload support is already enabled. Overwriting AmazonS3Client and S3BucketName.");
Expand All @@ -70,7 +69,7 @@ public void setPayloadSupportEnabled(AmazonS3 s3, String s3BucketName) {
* The bucket must be already created and configured in s3.
* @return the updated PayloadStorageConfiguration object.
*/
public PayloadStorageConfiguration withPayloadSupportEnabled(AmazonS3 s3, String s3BucketName) {
public PayloadStorageConfiguration withPayloadSupportEnabled(S3Client s3, String s3BucketName) {
setPayloadSupportEnabled(s3, s3BucketName);
return this;
}
Expand Down Expand Up @@ -109,7 +108,7 @@ public boolean isPayloadSupportEnabled() {
*
* @return Reference to the Amazon S3 client which is being used.
*/
public AmazonS3 getAmazonS3Client() {
public S3Client getS3Client() {
return s3;
}

Expand All @@ -122,35 +121,6 @@ public String getS3BucketName() {
return s3BucketName;
}

/**
* Gets the S3 SSE-KMS encryption params of S3 objects under configured S3 bucket name.
*
* @return The S3 SSE-KMS params used for encryption.
*/
public SSEAwsKeyManagementParams getSSEAwsKeyManagementParams() {
return sseAwsKeyManagementParams;
}

/**
* Sets the the S3 SSE-KMS encryption params of S3 objects under configured S3 bucket name.
*
* @param sseAwsKeyManagementParams The S3 SSE-KMS params used for encryption.
*/
public void setSSEAwsKeyManagementParams(SSEAwsKeyManagementParams sseAwsKeyManagementParams) {
this.sseAwsKeyManagementParams = sseAwsKeyManagementParams;
}

/**
* Sets the the S3 SSE-KMS encryption params of S3 objects under configured S3 bucket name.
*
* @param sseAwsKeyManagementParams The S3 SSE-KMS params used for encryption.
* @return the updated PayloadStorageConfiguration object
*/
public PayloadStorageConfiguration withSSEAwsKeyManagementParams(SSEAwsKeyManagementParams sseAwsKeyManagementParams) {
setSSEAwsKeyManagementParams(sseAwsKeyManagementParams);
return this;
}

/**
* Sets the payload size threshold for storing payloads in Amazon S3.
*
Expand Down Expand Up @@ -212,4 +182,18 @@ public boolean isAlwaysThroughS3() {
public void setAlwaysThroughS3(boolean alwaysThroughS3) {
this.alwaysThroughS3 = alwaysThroughS3;
}

public PayloadStorageConfiguration withServiceSideEncryption(ServerSideEncryptionStrategy serverSideEncryptionStrategy) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get some comments on these new methods

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I've also added a description of the usage in the class docs.

setServerSideEncryptionStrategy(serverSideEncryptionStrategy);
return this;
}

public void setServerSideEncryptionStrategy(ServerSideEncryptionStrategy serverSideEncryptionStrategy) {
this.serverSideEncryptionStrategy = serverSideEncryptionStrategy;
}

public ServerSideEncryptionStrategy getServerSideEncryptionStrategy() {
return this.serverSideEncryptionStrategy;
}

}
19 changes: 9 additions & 10 deletions src/main/java/software/amazon/payloadoffloading/PayloadStore.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package software.amazon.payloadoffloading;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.services.s3.model.S3Exception;

/**
* An AWS storage service that supports saving high payload sizes.
Expand All @@ -11,26 +11,25 @@ public interface PayloadStore {
* Stores payload in a store that has higher payload size limit than that is supported by original payload store.
*
* @param payload
* @param payloadContentSize
* @return a pointer that must be used to retrieve the original payload later.
* @throws AmazonClientException If any internal errors are encountered on the client side while
* @throws SdkClientException If any internal errors are encountered on the client side while
* attempting to make the request or handle the response. For example
* if a network connection is not available.
* @throws AmazonServiceException If an error response is returned by actual PayloadStore indicating
* @throws S3Exception If an error response is returned by actual PayloadStore indicating
* either a problem with the data in the request, or a server side issue.
*/
String storeOriginalPayload(String payload, Long payloadContentSize);
String storeOriginalPayload(String payload);

/**
* Retrieves the original payload using the given payloadPointer. The pointer must
* have been obtained using {@link storeOriginalPayload}
*
* @param payloadPointer
* @return original payload
* @throws AmazonClientException If any internal errors are encountered on the client side while
* @throws SdkClientException If any internal errors are encountered on the client side while
* attempting to make the request or handle the response. For example
* if payloadPointer is invalid or a network connection is not available.
* @throws AmazonServiceException If an error response is returned by actual PayloadStore indicating
* @throws S3Exception If an error response is returned by actual PayloadStore indicating
* a server side issue.
*/
String getOriginalPayload(String payloadPointer);
Expand All @@ -40,10 +39,10 @@ public interface PayloadStore {
* have been obtained using {@link storeOriginalPayload}
*
* @param payloadPointer
* @throws AmazonClientException If any internal errors are encountered on the client side while
* @throws SdkClientException If any internal errors are encountered on the client side while
* attempting to make the request or handle the response to/from PayloadStore.
* For example, if payloadPointer is invalid or a network connection is not available.
* @throws AmazonServiceException If an error response is returned by actual PayloadStore indicating
* @throws S3Exception If an error response is returned by actual PayloadStore indicating
* a server side issue.
*/
void deleteOriginalPayload(String payloadPointer);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
package software.amazon.payloadoffloading;

import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;

/**
* S3 based implementation for PayloadStore.
*/
public class S3BackedPayloadStore implements PayloadStore {
private static final Log LOG = LogFactory.getLog(S3BackedPayloadStore.class);
private static final Logger LOG = LoggerFactory.getLogger(S3BackedPayloadStore.class);

private final String s3BucketName;
private final S3Dao s3Dao;
private final SSEAwsKeyManagementParams sseAwsKeyManagementParams;
private final ServerSideEncryptionStrategy serverSideEncryptionStrategy;

public S3BackedPayloadStore(S3Dao s3Dao, String s3BucketName) {
this(s3Dao, s3BucketName, null);
}

public S3BackedPayloadStore(S3Dao s3Dao, String s3BucketName,
SSEAwsKeyManagementParams sseAwsKeyManagementParams) {
public S3BackedPayloadStore(S3Dao s3Dao, String s3BucketName, ServerSideEncryptionStrategy serverSideEncryptionStrategy) {
this.s3BucketName = s3BucketName;
this.s3Dao = s3Dao;
this.sseAwsKeyManagementParams = sseAwsKeyManagementParams;
this.serverSideEncryptionStrategy = serverSideEncryptionStrategy;
}

@Override
public String storeOriginalPayload(String payload, Long payloadContentSize) {
public String storeOriginalPayload(String payload) {
String s3Key = UUID.randomUUID().toString();

// Store the payload content in S3.
s3Dao.storeTextInS3(s3BucketName, s3Key, sseAwsKeyManagementParams, payload, payloadContentSize);
s3Dao.storeTextInS3(s3BucketName, s3Key, serverSideEncryptionStrategy, payload);
LOG.info("S3 object created, Bucket name: " + s3BucketName + ", Object key: " + s3Key + ".");

// Convert S3 pointer (bucket name, key, etc) to JSON string
Expand Down
Loading