private void populateMetadataWithEncryptionParams(ObjectMetadata source, ObjectMetadata destination) { Map<String, String> userMetadataSource = source.getUserMetadata(); Map<String, String> userMetadataDestination = destination.getUserMetadata(); String[] headersToCopy = { Headers.CRYPTO_CEK_ALGORITHM, Headers.CRYPTO_IV, Headers.CRYPTO_KEY, Headers.CRYPTO_KEY_V2, Headers.CRYPTO_KEYWRAP_ALGORITHM, Headers.CRYPTO_TAG_LENGTH, Headers.MATERIALS_DESCRIPTION, Headers.UNENCRYPTED_CONTENT_LENGTH, Headers.UNENCRYPTED_CONTENT_MD5 }; if (userMetadataSource != null) { if(userMetadataDestination == null){ userMetadataDestination= new HashMap<String,String>(); destination.setUserMetadata(userMetadataDestination); } String headerValue; for(String header : headersToCopy){ headerValue = userMetadataSource.get(header); if(headerValue != null){ userMetadataDestination.put(header, headerValue); } } } }
@Override public AmazonWebServiceResponse<HeadBucketResult> handle(HttpResponse response) throws Exception { final AmazonWebServiceResponse<HeadBucketResult> awsResponse = new AmazonWebServiceResponse<HeadBucketResult>(); final HeadBucketResult result = new HeadBucketResult(); result.setBucketRegion(response.getHeaders().get(Headers.S3_BUCKET_REGION)); if (!StringUtils.isNullOrEmpty(response.getHeaders().get(Headers.IBM_SSE_KP_ENABLED))){ result.setIBMSSEKPEnabled(Boolean.parseBoolean(response.getHeaders().get(Headers.IBM_SSE_KP_ENABLED))); } if (!StringUtils.isNullOrEmpty(response.getHeaders().get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN))){ result.setIBMSSEKPCrk(response.getHeaders().get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN)); } awsResponse.setResult(result); return awsResponse; }
/** * <p> * Returns the content range of the object if response contains the Content-Range header. * </p> * <p> * If the request specifies a range or part number, then response returns the Content-Range range header. * Otherwise, the response does not return Content-Range header. * </p> * @return * Returns content range if the object is requested with specific range or part number, * null otherwise. */ public Long[] getContentRange() { String contentRange = (String) metadata.get(Headers.CONTENT_RANGE); Long[] range = null; if (contentRange != null) { String[] tokens = contentRange.split("[ -/]+"); try { range = new Long[] { Long.parseLong(tokens[1]), Long.parseLong(tokens[2]) }; } catch (NumberFormatException nfe) { throw new SdkClientException( "Unable to parse content range. Header 'Content-Range' has corrupted data" + nfe.getMessage(), nfe); } } return range; }
/** * Returns the json string in the latest format. */ private String toJsonString() { Map<String, String> map = new HashMap<String, String>(); byte[] encryptedCEK = getEncryptedCEK(); map.put(Headers.CRYPTO_KEY_V2, Base64.encodeAsString(encryptedCEK)); byte[] iv = cipherLite.getIV(); map.put(Headers.CRYPTO_IV, Base64.encodeAsString(iv)); map.put(Headers.MATERIALS_DESCRIPTION, kekMaterialDescAsJson()); // The CRYPTO_CEK_ALGORITHM, CRYPTO_TAG_LENGTH and // CRYPTO_KEYWRAP_ALGORITHM were not available in the Encryption Only // (EO) implementation ContentCryptoScheme scheme = getContentCryptoScheme(); map.put(Headers.CRYPTO_CEK_ALGORITHM, scheme.getCipherAlgorithm()); int tagLen = scheme.getTagLengthInBits(); if (tagLen > 0) map.put(Headers.CRYPTO_TAG_LENGTH, String.valueOf(tagLen)); String keyWrapAlgo = getKeyWrappingAlgorithm(); if (keyWrapAlgo != null) map.put(Headers.CRYPTO_KEYWRAP_ALGORITHM, keyWrapAlgo); return Jackson.toJsonString(map); }
private AmazonS3Exception createExceptionFromHeaders( HttpResponse errorResponse, String errorResponseXml) { final Map<String, String> headers = errorResponse.getHeaders(); final int statusCode = errorResponse.getStatusCode(); final AmazonS3ExceptionBuilder exceptionBuilder = new AmazonS3ExceptionBuilder(); exceptionBuilder.setErrorMessage(errorResponse.getStatusText()); exceptionBuilder.setErrorResponseXml(errorResponseXml); exceptionBuilder.setStatusCode(statusCode); exceptionBuilder .setExtendedRequestId(headers.get(Headers.EXTENDED_REQUEST_ID)); exceptionBuilder.setRequestId(headers.get(Headers.REQUEST_ID)); exceptionBuilder.setCloudFrontId(headers.get(Headers.CLOUD_FRONT_ID)); exceptionBuilder .setErrorCode(statusCode + " " + errorResponse.getStatusText()); exceptionBuilder.addAdditionalDetail(Headers.S3_BUCKET_REGION, errorResponse.getHeaders().get(Headers.S3_BUCKET_REGION)); return exceptionBuilder.build(); }
/** * @see com.amazonaws.http.HttpResponseHandler#handle(com.amazonaws.http.HttpResponse) */ public AmazonWebServiceResponse<T> handle(HttpResponse response) throws Exception { AmazonWebServiceResponse<T> awsResponse = parseResponseMetadata(response); responseHeaders = response.getHeaders(); if (responseUnmarshaller != null) { log.trace("Beginning to parse service response XML"); T result = responseUnmarshaller.unmarshall(response.getContent()); log.trace("Done parsing service response XML"); awsResponse.setResult(result); if (result instanceof ObjectListing) { if (!StringUtils.isNullOrEmpty(responseHeaders.get(Headers.IBM_SSE_KP_ENABLED))){ ((ObjectListing) result).setIBMSSEKPEnabled(Boolean.parseBoolean(responseHeaders.get(Headers.IBM_SSE_KP_ENABLED))); } if (!StringUtils.isNullOrEmpty(responseHeaders.get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN))) { ((ObjectListing) result).setIBMSSEKPCrk(responseHeaders.get(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN)); } } } return awsResponse; }
/** * Test the IBM_SSE_KP_ENABLED & IBM_SSE_KP_CRK are set in the ObjectLIsting * response object * @throws Exception * */ @Test public void testHeadersAddedToObjectListing() throws Exception { Unmarshaller<ObjectListing, InputStream> unmarshaller = new Unmarshallers.ListObjectsUnmarshaller(false); S3XmlResponseHandler xmlResponseHandler = new S3XmlResponseHandler<ObjectListing>(unmarshaller); HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_ENABLED, "True"); httpResponse.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, "123456"); InputStream is = new ByteArrayInputStream(getXmlContent().getBytes());; httpResponse.setContent(is); AmazonWebServiceResponse<ObjectListing> objectListing = xmlResponseHandler.handle(httpResponse); assertEquals(objectListing.getResult().getIBMSSEKPCrk(), "123456"); assertEquals(objectListing.getResult().getIBMSSEKPEnabled(), true); }
/** * Test the IBM_SSE_KP_ENABLED & IBM_SSE_KP_CRK null headers are handled * * @throws Exception * */ @Test public void testNullKPHeadersAreHandled() throws Exception { Unmarshaller<ObjectListing, InputStream> unmarshaller = new Unmarshallers.ListObjectsUnmarshaller(false); S3XmlResponseHandler xmlResponseHandler = new S3XmlResponseHandler<ObjectListing>(unmarshaller); HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_ENABLED, null); httpResponse.addHeader(Headers.IBM_SSE_KP_CRK, null); InputStream is = new ByteArrayInputStream(getXmlContent().getBytes());; httpResponse.setContent(is); AmazonWebServiceResponse<ObjectListing> objectListing = xmlResponseHandler.handle(httpResponse); assertEquals(objectListing.getResult().getIBMSSEKPCrk(), null); assertEquals(objectListing.getResult().getIBMSSEKPEnabled(), false); }
/** * Test the IBM_SSE_KP_CRK empty header is handled * * @throws Exception * */ @Test public void testOnlyKPEnabledHeaderIsSet() throws Exception { Unmarshaller<ObjectListing, InputStream> unmarshaller = new Unmarshallers.ListObjectsUnmarshaller(false); S3XmlResponseHandler xmlResponseHandler = new S3XmlResponseHandler<ObjectListing>(unmarshaller); HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_ENABLED, "True"); InputStream is = new ByteArrayInputStream(getXmlContent().getBytes());; httpResponse.setContent(is); AmazonWebServiceResponse<ObjectListing> objectListing = xmlResponseHandler.handle(httpResponse); assertEquals(objectListing.getResult().getIBMSSEKPCrk(), null); assertEquals(objectListing.getResult().getIBMSSEKPEnabled(), true); }
/** * Test the IBM_SSE_KP_CRK empty header is handled * * @throws Exception * */ @Test public void testOnlyCRKHeaderIsSet() throws Exception { Unmarshaller<ObjectListing, InputStream> unmarshaller = new Unmarshallers.ListObjectsUnmarshaller(false); S3XmlResponseHandler xmlResponseHandler = new S3XmlResponseHandler<ObjectListing>(unmarshaller); HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, "34567"); InputStream is = new ByteArrayInputStream(getXmlContent().getBytes());; httpResponse.setContent(is); AmazonWebServiceResponse<ObjectListing> objectListing = xmlResponseHandler.handle(httpResponse); assertEquals(objectListing.getResult().getIBMSSEKPCrk(), "34567"); assertEquals(objectListing.getResult().getIBMSSEKPEnabled(), false); }
@Test public void testRestoreObjects() { // Put a 1 byte Glacier storage class file in S3. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); metadata.setOngoingRestore(false); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, new ByteArrayInputStream(new byte[1]), metadata), null); // Initiate a restore request for the test S3 file. S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(TARGET_S3_KEY))); s3Dao.restoreObjects(params, S3_RESTORE_OBJECT_EXPIRATION_IN_DAYS); // Validate that there is an ongoing restore request for this object. ObjectMetadata objectMetadata = s3Operations.getObjectMetadata(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, null); assertTrue(objectMetadata.getOngoingRestore()); }
@Test public void testRestoreObjectsGlacierObjectAlreadyBeingRestored() { // Put a 1 byte Glacier storage class file in S3 flagged as already being restored. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); metadata.setOngoingRestore(true); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, new ByteArrayInputStream(new byte[1]), metadata), null); // Initiate a restore request for the test S3 file. S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(TARGET_S3_KEY))); s3Dao.restoreObjects(params, S3_RESTORE_OBJECT_EXPIRATION_IN_DAYS); // Validate that there is still an ongoing restore request for this object. ObjectMetadata objectMetadata = s3Operations.getObjectMetadata(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, null); assertTrue(objectMetadata.getOngoingRestore()); }
@Test public void testValidateGlacierS3FilesRestored() { // Put a 1 byte already restored Glacier storage class file in S3. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); metadata.setOngoingRestore(false); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, new ByteArrayInputStream(new byte[1]), metadata), null); // Validate the file. S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(TARGET_S3_KEY))); s3Dao.validateGlacierS3FilesRestored(params); }
@Test public void testValidateGlacierS3FilesRestoredGlacierObjectRestoreNotInitiated() { // Put a 1 byte Glacier storage class file in S3 that has no restore initiated (OngoingRestore flag is null). ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, new ByteArrayInputStream(new byte[1]), metadata), null); // Try to validate if the Glacier S3 file is already restored. try { S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(TARGET_S3_KEY))); s3Dao.validateGlacierS3FilesRestored(params); fail("Should throw an IllegalArgumentException when Glacier S3 file is not restored."); } catch (IllegalArgumentException e) { assertEquals(String .format("Archived Glacier S3 file \"%s\" is not restored. StorageClass {GLACIER}, OngoingRestore flag {null}, S3 bucket name {%s}", TARGET_S3_KEY, storageDaoTestHelper.getS3ManagedBucketName()), e.getMessage()); } }
static Map<String, Object> getMetaData(S3Object s3Object) { Map<String, Object> metaDataMap = new HashMap<>(); // put the metadata of S3 Object metaDataMap.put(Headers.CACHE_CONTROL, s3Object.getObjectMetadata().getCacheControl()); metaDataMap.put(Headers.CONTENT_DISPOSITION, s3Object.getObjectMetadata().getContentDisposition()); metaDataMap.put(Headers.CONTENT_ENCODING, s3Object.getObjectMetadata().getContentEncoding()); metaDataMap.put(Headers.CONTENT_LENGTH, s3Object.getObjectMetadata().getContentLength()); metaDataMap.put(Headers.CONTENT_RANGE, s3Object.getObjectMetadata().getInstanceLength()); metaDataMap.put(Headers.CONTENT_MD5, s3Object.getObjectMetadata().getContentMD5()); metaDataMap.put(Headers.CONTENT_TYPE, s3Object.getObjectMetadata().getContentType()); metaDataMap.put(Headers.EXPIRES, s3Object.getObjectMetadata().getExpirationTime()); metaDataMap.put(Headers.ETAG, s3Object.getObjectMetadata().getETag()); metaDataMap.put(Headers.LAST_MODIFIED, s3Object.getObjectMetadata().getLastModified()); // put user metadata Map<String, String> userMetaMap = s3Object.getObjectMetadata().getUserMetadata(); if(userMetaMap != null) { for (Map.Entry<String, String> entry : userMetaMap.entrySet()) { if (entry.getValue() != null) { metaDataMap.put(entry.getKey(), entry.getValue()); } } } return metaDataMap; }
private static Map<String, Object> getS3Metadata(S3Object s3Object) { Map<String, Object> metaDataMap = new HashMap<>(); metaDataMap.put(Headers.CACHE_CONTROL, s3Object.getObjectMetadata().getCacheControl()); metaDataMap.put(Headers.CONTENT_DISPOSITION, s3Object.getObjectMetadata().getContentDisposition()); metaDataMap.put(Headers.CONTENT_ENCODING, s3Object.getObjectMetadata().getContentEncoding()); metaDataMap.put(Headers.CONTENT_LENGTH, s3Object.getObjectMetadata().getContentLength()); metaDataMap.put(Headers.CONTENT_RANGE, s3Object.getObjectMetadata().getInstanceLength()); metaDataMap.put(Headers.CONTENT_MD5, s3Object.getObjectMetadata().getContentMD5()); metaDataMap.put(Headers.CONTENT_TYPE, s3Object.getObjectMetadata().getContentType()); metaDataMap.put(Headers.EXPIRES, s3Object.getObjectMetadata().getExpirationTime()); metaDataMap.put(Headers.ETAG, s3Object.getObjectMetadata().getETag()); metaDataMap.put(Headers.LAST_MODIFIED, s3Object.getObjectMetadata().getLastModified()); metaDataMap.put("bucket", s3Object.getBucketName()); metaDataMap.put("objectKey", s3Object.getKey()); metaDataMap.put("size", s3Object.getObjectMetadata().getContentLength()); return metaDataMap; }
/** * Returns the physical length of the entire object stored in S3. * This is useful during, for example, a range get operation. */ public long getInstanceLength() { // See Content-Range in // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html String contentRange = (String)metadata.get(Headers.CONTENT_RANGE); if (contentRange != null) { int pos = contentRange.lastIndexOf("/"); if (pos >= 0) return Long.parseLong(contentRange.substring(pos+1)); } return getContentLength(); }
/** * @return The storage class of the object. Returns null if the object is in STANDARD storage. * See {@link StorageClass} for possible values */ public String getStorageClass() { final Object storageClass = metadata.get(Headers.STORAGE_CLASS); if (storageClass == null) { return null; } return storageClass.toString(); }
@Override public void handle(T result, HttpResponse response) { String restoreHeader = response.getHeaders().get(Headers.RESTORE); if (restoreHeader != null) { result.setRestoreExpirationTime(parseDate(restoreHeader)); Boolean onGoingRestore = parseBoolean(restoreHeader); if (onGoingRestore != null) { result.setOngoingRestore(onGoingRestore); } } }
/** * Parses the S3 response metadata (ex: AWS request ID) from the specified * response, and returns a AmazonWebServiceResponse<T> object ready for the * result to be plugged in. * * @param response * The response containing the response metadata to pull out. * * @return A new, populated AmazonWebServiceResponse<T> object, ready for * the result to be plugged in. */ protected AmazonWebServiceResponse<T> parseResponseMetadata(HttpResponse response) { AmazonWebServiceResponse<T> awsResponse = new AmazonWebServiceResponse<T>(); String awsRequestId = response.getHeaders().get(Headers.REQUEST_ID); String hostId = response.getHeaders().get(Headers.EXTENDED_REQUEST_ID); String cloudFrontId = response.getHeaders().get(Headers.CLOUD_FRONT_ID); Map<String, String> metadataMap = new HashMap<String, String>(); metadataMap.put(ResponseMetadata.AWS_REQUEST_ID, awsRequestId); metadataMap.put(S3ResponseMetadata.HOST_ID, hostId); metadataMap.put(S3ResponseMetadata.CLOUD_FRONT_ID, cloudFrontId); awsResponse.setResponseMetadata(new S3ResponseMetadata(metadataMap)); return awsResponse; }
@Override public void handle(T result, HttpResponse response) { String expirationHeader = response.getHeaders().get(Headers.EXPIRATION); if ( expirationHeader != null ) { result.setExpirationTime(parseDate(expirationHeader)); result.setExpirationTimeRuleId(parseRuleId(expirationHeader)); } }
/** * Returns true if this S3 object has the encryption information stored * as user meta data; false otherwise. */ final boolean hasEncryptionInfo() { ObjectMetadata metadata = s3obj.getObjectMetadata(); Map<String, String> userMeta = metadata.getUserMetadata(); return userMeta != null && userMeta.containsKey(Headers.CRYPTO_IV) && (userMeta.containsKey(Headers.CRYPTO_KEY_V2) || userMeta.containsKey(Headers.CRYPTO_KEY)); }
/** * Returns the metadata in the latest format. */ private ObjectMetadata toObjectMetadata(ObjectMetadata metadata) { // If we generated a symmetric key to encrypt the data, store it in the // object metadata. byte[] encryptedCEK = getEncryptedCEK(); metadata.addUserMetadata(Headers.CRYPTO_KEY_V2, Base64.encodeAsString(encryptedCEK)); // Put the cipher initialization vector (IV) into the object metadata byte[] iv = cipherLite.getIV(); metadata.addUserMetadata(Headers.CRYPTO_IV, Base64.encodeAsString(iv)); // Put the materials description into the object metadata as JSON metadata.addUserMetadata(Headers.MATERIALS_DESCRIPTION, kekMaterialDescAsJson()); // The CRYPTO_CEK_ALGORITHM, CRYPTO_TAG_LENGTH and // CRYPTO_KEYWRAP_ALGORITHM were not available in the Encryption Only // (EO) implementation ContentCryptoScheme scheme = getContentCryptoScheme(); metadata.addUserMetadata(Headers.CRYPTO_CEK_ALGORITHM, scheme.getCipherAlgorithm()); int tagLen = scheme.getTagLengthInBits(); if (tagLen > 0) metadata.addUserMetadata(Headers.CRYPTO_TAG_LENGTH, String.valueOf(tagLen)); String keyWrapAlgo = getKeyWrappingAlgorithm(); if (keyWrapAlgo != null) metadata.addUserMetadata(Headers.CRYPTO_KEYWRAP_ALGORITHM, keyWrapAlgo); return metadata; }
/** * Returns the metadata in backward compatibility (old) format, so it can be * read by older version of the AWS SDK. */ private ObjectMetadata toObjectMetadataEO(ObjectMetadata metadata) { // If we generated a symmetric key to encrypt the data, store it in the // object metadata. byte[] encryptedCEK = getEncryptedCEK(); metadata.addUserMetadata(Headers.CRYPTO_KEY, Base64.encodeAsString(encryptedCEK)); // Put the cipher initialization vector (IV) into the object metadata byte[] iv = cipherLite.getIV(); metadata.addUserMetadata(Headers.CRYPTO_IV, Base64.encodeAsString(iv)); // Put the materials description into the object metadata as JSON metadata.addUserMetadata(Headers.MATERIALS_DESCRIPTION, kekMaterialDescAsJson()); return metadata; }
private String toJsonStringEO() { Map<String, String> map = new HashMap<String, String>(); byte[] encryptedCEK = getEncryptedCEK(); map.put(Headers.CRYPTO_KEY, Base64.encodeAsString(encryptedCEK)); byte[] iv = cipherLite.getIV(); map.put(Headers.CRYPTO_IV, Base64.encodeAsString(iv)); map.put(Headers.MATERIALS_DESCRIPTION, kekMaterialDescAsJson()); return Jackson.toJsonString(map); }
/** * Returns the plaintext length from the request and metadata; or -1 if * unknown. */ protected final long plaintextLength(AbstractPutObjectRequest request, ObjectMetadata metadata) { if (request.getFile() != null) { return request.getFile().length(); } else if (request.getInputStream() != null && metadata.getRawMetadataValue(Headers.CONTENT_LENGTH) != null) { return metadata.getContentLength(); } return -1; }
protected final PutObjectRequest createInstructionPutRequest( String bucketName, String key, ContentCryptoMaterial cekMaterial) { byte[] bytes = cekMaterial.toJsonString(cryptoConfig.getCryptoMode()) .getBytes(UTF8); InputStream is = new ByteArrayInputStream(bytes); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(bytes.length); metadata.addUserMetadata(Headers.CRYPTO_INSTRUCTION_FILE, ""); InstructionFileId ifileId = new S3ObjectId(bucketName, key) .instructionFileId(); return new PutObjectRequest(ifileId.getBucket(), ifileId.getKey(), is, metadata); }
/** * @see com.amazonaws.http.HttpResponseHandler#handle(com.amazonaws.http.HttpResponse) */ public AmazonWebServiceResponse<S3Object> handle(HttpResponse response) throws Exception { /* * TODO: It'd be nice to set the bucket name and key here, but the information isn't easy to * pull out of the response/request currently. */ S3Object object = new S3Object(); AmazonWebServiceResponse<S3Object> awsResponse = parseResponseMetadata(response); if (response.getHeaders().get(Headers.REDIRECT_LOCATION) != null) { object.setRedirectLocation(response.getHeaders().get(Headers.REDIRECT_LOCATION)); } // If the requester is charged when downloading a object from an // Requester Pays bucket, then this header is set. if (response.getHeaders().get(Headers.REQUESTER_CHARGED_HEADER) != null) { object.setRequesterCharged(true); } if (response.getHeaders().get(Headers.S3_TAGGING_COUNT) != null) { object.setTaggingCount(Integer.parseInt(response.getHeaders().get(Headers.S3_TAGGING_COUNT))); } ObjectMetadata metadata = object.getObjectMetadata(); populateObjectMetadata(response, metadata); object.setObjectContent(new S3ObjectInputStream(abortableIs(response), response.getHttpRequest())); awsResponse.setResult(object); return awsResponse; }
/** * Test the IBM_SSE_KP_ENABLED & IBM_SSE_KP_CRK are set in the HeadResult object * @throws Exception * */ @Test public void testHeadResultIsSetCorrect() throws Exception { HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_ENABLED, "True"); httpResponse.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, "123456"); HeadBucketResultHandler handler = new HeadBucketResultHandler(); AmazonWebServiceResponse<HeadBucketResult> result = handler.handle(httpResponse); assertEquals(result.getResult().getIBMSSEKPCrk(), "123456"); assertEquals(result.getResult().getIBMSSEKPEnabled(), true); }
/** * Test null IBM_SSE_KP_ENABLED & IBM_SSE_KP_CRK headers are handled * @throws Exception * */ @Test public void testNullHeadersAreHandled() throws Exception { HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_ENABLED, null); httpResponse.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, null); HeadBucketResultHandler handler = new HeadBucketResultHandler(); AmazonWebServiceResponse<HeadBucketResult> result = handler.handle(httpResponse); assertEquals(result.getResult().getIBMSSEKPCrk(), null); assertEquals(result.getResult().getIBMSSEKPEnabled(), false); }
/** * Test empty IBM_SSE_KP_ENABLED & IBM_SSE_KP_CRK headers are handled * @throws Exception * */ @Test public void testOnlyKPEnabledHeaderIsSet() throws Exception { HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_ENABLED, "True"); HeadBucketResultHandler handler = new HeadBucketResultHandler(); AmazonWebServiceResponse<HeadBucketResult> result = handler.handle(httpResponse); assertEquals(result.getResult().getIBMSSEKPCrk(), null); assertEquals(result.getResult().getIBMSSEKPEnabled(), true); }
/** * Test empty IBM_SSE_KP_ENABLED & IBM_SSE_KP_CRK headers are handled * @throws Exception * */ @Test public void testOnlyCRKHeaderIsSet() throws Exception { HttpResponse httpResponse = new HttpResponse(null, null); httpResponse.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, "12345"); HeadBucketResultHandler handler = new HeadBucketResultHandler(); AmazonWebServiceResponse<HeadBucketResult> result = handler.handle(httpResponse); assertEquals(result.getResult().getIBMSSEKPCrk(), "12345"); assertEquals(result.getResult().getIBMSSEKPEnabled(), false); }
private ObjectMetadata createObjectMetadata(final String mdMD5Hash16, final String contentType, final File file) { final ObjectMetadata objectMetadata = new ObjectMetadata(); final String mdMD5Hash64 = BaseEncoding.base64().encode(BaseEncoding.base16().lowerCase().decode(mdMD5Hash16)); objectMetadata.setContentMD5(mdMD5Hash64); objectMetadata.setContentType(contentType); objectMetadata.setContentLength(file.length()); if (s3Properties.isServerSideEncryption()) { objectMetadata.setHeader(Headers.SERVER_SIDE_ENCRYPTION, s3Properties.getServerSideEncryptionAlgorithm()); } return objectMetadata; }
/** * Prepares the object metadata for server side encryption and reduced redundancy storage. * * @param params the parameters. * @param metadata the metadata to prepare. */ private void prepareMetadata(final S3FileTransferRequestParamsDto params, ObjectMetadata metadata) { // Set the server side encryption if (params.getKmsKeyId() != null) { /* * TODO Use proper way to set KMS once AWS provides a way. * We are modifying the raw headers directly since TransferManager's uploadFileList operation does not provide a way to set a KMS key ID. * This would normally cause some issues when uploading where an MD5 checksum validation exception will be thrown, even though the object is * correctly uploaded. * To get around this, a system property defined at * com.amazonaws.services.s3.internal.SkipMd5CheckStrategy.DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY must be set. */ metadata.setSSEAlgorithm(SSEAlgorithm.KMS.getAlgorithm()); metadata.setHeader(Headers.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEYID, params.getKmsKeyId().trim()); } else { metadata.setSSEAlgorithm(SSEAlgorithm.AES256.getAlgorithm()); } // If specified, set the metadata to use RRS. if (Boolean.TRUE.equals(params.isUseRrs())) { // TODO: For upload File, we can set RRS on the putObjectRequest. For uploadDirectory, this is the only // way to do it. However, setHeader() is flagged as For Internal Use Only metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.ReducedRedundancy.toString()); } }
@Test public void testPrepareMetadataAssertSetKmsHeaders() { S3Operations originalS3Operations = (S3Operations) ReflectionTestUtils.getField(s3Dao, "s3Operations"); S3Operations mockS3Operations = mock(S3Operations.class); ReflectionTestUtils.setField(s3Dao, "s3Operations", mockS3Operations); try { String s3BucketName = "s3BucketName"; String s3KeyPrefix = "s3KeyPrefix"; String kmsKeyId = "kmsKeyId"; S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = new S3FileTransferRequestParamsDto(); s3FileTransferRequestParamsDto.setS3BucketName(s3BucketName); s3FileTransferRequestParamsDto.setS3KeyPrefix(s3KeyPrefix); s3FileTransferRequestParamsDto.setKmsKeyId(kmsKeyId); when(mockS3Operations.putObject(any(), any())).then(new Answer<PutObjectResult>() { @Override public PutObjectResult answer(InvocationOnMock invocation) throws Throwable { PutObjectRequest putObjectRequest = invocation.getArgument(0); ObjectMetadata metadata = putObjectRequest.getMetadata(); assertEquals("aws:kms", metadata.getSSEAlgorithm()); assertEquals(kmsKeyId, metadata.getRawMetadata().get(Headers.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEYID)); return new PutObjectResult(); } }); s3Dao.createDirectory(s3FileTransferRequestParamsDto); } finally { ReflectionTestUtils.setField(s3Dao, "s3Operations", originalS3Operations); } }
@Test public void testRestoreObjectsAmazonServiceException() { // Build a mock file path that triggers an Amazon service exception when we request to restore an object. String testKey = String.format("%s/%s", TEST_S3_KEY_PREFIX, MockS3OperationsImpl.MOCK_S3_FILE_NAME_SERVICE_EXCEPTION); // Put a 1 byte Glacier storage class file in S3. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); metadata.setOngoingRestore(false); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), testKey, new ByteArrayInputStream(new byte[1]), metadata), null); // Try to initiate a restore request for a mocked S3 file that would trigger an Amazon service exception when we request to restore an object. try { S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(testKey))); s3Dao.restoreObjects(params, S3_RESTORE_OBJECT_EXPIRATION_IN_DAYS); fail("Should throw an IllegalStateException when an S3 restore object operation fails."); } catch (IllegalStateException e) { assertEquals(String.format("Failed to initiate a restore request for \"%s\" key in \"%s\" bucket. " + "Reason: InternalError (Service: null; Status Code: 0; Error Code: InternalError; Request ID: null)", testKey, storageDaoTestHelper.getS3ManagedBucketName()), e.getMessage()); } }
@Test public void testRestoreObjectsNonGlacierObject() { // Put a 1 byte non-Glacier storage class file in S3. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Standard); metadata.setOngoingRestore(false); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, new ByteArrayInputStream(new byte[1]), metadata), null); // Try to initiate a restore request for a non-Glacier file. try { S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(TARGET_S3_KEY))); s3Dao.restoreObjects(params, S3_RESTORE_OBJECT_EXPIRATION_IN_DAYS); fail("Should throw an IllegalStateException when file has a non-Glacier storage class."); } catch (IllegalStateException e) { assertEquals(String.format("Failed to initiate a restore request for \"%s\" key in \"%s\" bucket. " + "Reason: object is not in Glacier (Service: null; Status Code: 0; Error Code: null; Request ID: null)", TARGET_S3_KEY, storageDaoTestHelper.getS3ManagedBucketName()), e.getMessage()); } }
@Test public void testValidateGlacierS3FilesRestoredAmazonServiceException() { // Build a mock file path that triggers an Amazon service exception when we request S3 metadata for the object. String testKey = String.format("%s/%s", TEST_S3_KEY_PREFIX, MockS3OperationsImpl.MOCK_S3_FILE_NAME_SERVICE_EXCEPTION); // Put a 1 byte Glacier storage class file in S3. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); metadata.setOngoingRestore(false); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), testKey, new ByteArrayInputStream(new byte[1]), metadata), null); // Try to validate if the Glacier S3 file is already restored for a mocked S3 file // that triggers an Amazon service exception when we request S3 metadata for the object. try { S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(testKey))); s3Dao.validateGlacierS3FilesRestored(params); fail("Should throw an IllegalStateException when Glacier S3 object validation fails due to an Amazon service exception."); } catch (IllegalStateException e) { assertEquals(String.format("Fail to check restore status for \"%s\" key in \"%s\" bucket. " + "Reason: InternalError (Service: null; Status Code: 0; Error Code: InternalError; Request ID: null)", testKey, storageDaoTestHelper.getS3ManagedBucketName()), e.getMessage()); } }
@Test public void testValidateGlacierS3FilesRestoredGlacierObjectRestoreInProgress() { // Put a 1 byte Glacier storage class file in S3 that is still being restored (OngoingRestore flag is true). ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier); metadata.setOngoingRestore(true); s3Operations .putObject(new PutObjectRequest(storageDaoTestHelper.getS3ManagedBucketName(), TARGET_S3_KEY, new ByteArrayInputStream(new byte[1]), metadata), null); // Try to validate if the Glacier S3 file is already restored. try { S3FileTransferRequestParamsDto params = new S3FileTransferRequestParamsDto(); params.setS3BucketName(storageDaoTestHelper.getS3ManagedBucketName()); params.setFiles(Arrays.asList(new File(TARGET_S3_KEY))); s3Dao.validateGlacierS3FilesRestored(params); fail("Should throw an IllegalArgumentException when Glacier S3 file is not restored."); } catch (IllegalArgumentException e) { assertEquals(String .format("Archived Glacier S3 file \"%s\" is not restored. StorageClass {GLACIER}, OngoingRestore flag {true}, S3 bucket name {%s}", TARGET_S3_KEY, storageDaoTestHelper.getS3ManagedBucketName()), e.getMessage()); } }
@Override public Date created() throws IOException { final Date dat; if (this.meta.getRawMetadataValue(Headers.DATE) == null) { dat = this.meta.getLastModified(); } else { dat = DateUtils.cloneDate( (Date) this.meta.getRawMetadataValue(Headers.DATE) ); } return dat; }