GH-41: Fix broken S3 File upload

Fixes GH-41 (https://github.com/spring-projects/spring-integration-aws/issues/41)
Fixes GH-43 (https://github.com/spring-projects/spring-integration-aws/issues/43)

- Prior upload() code was trying to reset() a
  FileInputStream and then upload to S3, which
  resulted in zero uploaded bytes.
- Added dependency on spring-cloud-aws-core
  to resolve ResourceIdResolver reference.
- Fail if InputStream payload does not support
  mark/reset.
- Add metadata for byte array payload.

GH-41: Fix assert order per PR comments.
This commit is contained in:
John Logan
2016-07-12 21:51:22 -07:00
committed by Artem Bilan
parent 07e8d59c1f
commit b5e6cdaa95
3 changed files with 104 additions and 46 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.aws.outbound;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.fail;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Matchers.any;
@@ -27,6 +28,7 @@ import static org.mockito.Mockito.verify;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
@@ -60,6 +62,7 @@ import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
@@ -98,6 +101,7 @@ import com.amazonaws.util.StringUtils;
/**
* @author Artem Bilan
* @author John Logan
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -143,8 +147,8 @@ public class S3MessageHandlerTests {
PutObjectRequest putObjectRequest = putObjectRequestArgumentCaptor.getValue();
assertThat(putObjectRequest.getBucketName()).isEqualTo("myBucket");
assertThat(putObjectRequest.getKey()).isEqualTo("foo.mp3");
assertThat(putObjectRequest.getFile()).isNull();
assertThat(putObjectRequest.getInputStream()).isNotNull();
assertThat(putObjectRequest.getFile()).isNotNull();
assertThat(putObjectRequest.getInputStream()).isNull();
ObjectMetadata metadata = putObjectRequest.getMetadata();
assertThat(metadata.getContentMD5()).isEqualTo(Md5Utils.md5AsBase64(file));
@@ -196,6 +200,52 @@ public class S3MessageHandlerTests {
assertThat(metadata.getContentDisposition()).isEqualTo("test.json");
}
@Test
public void testUploadInputStreamNoMarkSupported() throws IOException, InterruptedException {
File file = this.temporaryFolder.newFile("foo.mp3");
FileInputStream fileInputStream = new FileInputStream(file);
Message<?> message = MessageBuilder.withPayload(fileInputStream)
.setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name())
.setHeader("key", "myStream")
.build();
try {
this.s3SendChannel.send(message);
fail("Expected send() failure with FileInputStream, got success.");
}
catch (Exception e) {
assertThat(e).isInstanceOf(MessageHandlingException.class);
assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
}
}
@Test
public void testUploadByteArray() throws IOException {
byte[] payload = "b".getBytes("UTF-8");
Message<?> message = MessageBuilder.withPayload(payload)
.setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name())
.setHeader("key", "myStream")
.build();
this.s3SendChannel.send(message);
ArgumentCaptor<PutObjectRequest> putObjectRequestArgumentCaptor =
ArgumentCaptor.forClass(PutObjectRequest.class);
verify(this.amazonS3, atLeastOnce()).putObject(putObjectRequestArgumentCaptor.capture());
PutObjectRequest putObjectRequest = putObjectRequestArgumentCaptor.getValue();
assertThat(putObjectRequest.getBucketName()).isEqualTo("myBucket");
assertThat(putObjectRequest.getKey()).isEqualTo("myStream");
assertThat(putObjectRequest.getFile()).isNull();
assertThat(putObjectRequest.getInputStream()).isNotNull();
ObjectMetadata metadata = putObjectRequest.getMetadata();
assertThat(metadata.getContentMD5()).isEqualTo(Md5Utils.md5AsBase64(payload));
assertThat(metadata.getContentLength()).isEqualTo(1);
assertThat(metadata.getContentType()).isEqualTo(MediaType.APPLICATION_JSON_VALUE);
assertThat(metadata.getContentDisposition()).isEqualTo("test.json");
}
@Test
public void testDownloadDirectory() throws IOException {
File directoryForDownload = this.temporaryFolder.newFolder("myFolder");
@@ -368,7 +418,7 @@ public class S3MessageHandlerTests {
s3MessageHandler.setKeyExpression(keyExpression);
s3MessageHandler.setObjectAclExpression(new ValueExpression<>(CannedAccessControlList.PublicReadWrite));
s3MessageHandler.setUploadMetadataProvider((metadata, message) -> {
if (message.getPayload() instanceof InputStream) {
if (message.getPayload() instanceof InputStream || message.getPayload() instanceof byte[]) {
metadata.setContentLength(1);
metadata.setContentType(MediaType.APPLICATION_JSON_VALUE);
metadata.setContentDisposition("test.json");