mirror of https://github.com/apache/jclouds.git
Issue 35: moved more common logic one layer up
git-svn-id: http://jclouds.googlecode.com/svn/trunk@844 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
4eced672f1
commit
8cc04bc588
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws;
|
||||||
|
|
||||||
|
import org.jclouds.aws.domain.AWSError;
|
||||||
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates an AWS Error from Amazon.
|
||||||
|
*
|
||||||
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html" />
|
||||||
|
* @see AWSError
|
||||||
|
* @see org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AWSResponseException extends HttpResponseException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private AWSError error = new AWSError();
|
||||||
|
|
||||||
|
public AWSResponseException(HttpFutureCommand<?> command, HttpResponse response, AWSError error) {
|
||||||
|
super(error.toString(), command, response);
|
||||||
|
this.setError(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AWSResponseException(HttpFutureCommand<?> command, HttpResponse response, AWSError error,
|
||||||
|
Throwable cause) {
|
||||||
|
super(error.toString(), command, response, cause);
|
||||||
|
this.setError(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AWSResponseException(String message, HttpFutureCommand<?> command, HttpResponse response,
|
||||||
|
AWSError error) {
|
||||||
|
super(message, command, response);
|
||||||
|
this.setError(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AWSResponseException(String message, HttpFutureCommand<?> command, HttpResponse response,
|
||||||
|
AWSError error, Throwable cause) {
|
||||||
|
super(message, command, response, cause);
|
||||||
|
this.setError(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(AWSError error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AWSError getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.domain;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -33,7 +33,7 @@ import java.util.Map;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class S3Error {
|
public class AWSError {
|
||||||
private String code;
|
private String code;
|
||||||
private String message;
|
private String message;
|
||||||
private String requestId;
|
private String requestId;
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws.reference;
|
||||||
|
|
||||||
|
import org.jclouds.command.pool.PoolConstants;
|
||||||
|
import org.jclouds.http.HttpConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration properties and constants used in AWS connections.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public interface AWSConstants extends HttpConstants, PoolConstants {
|
||||||
|
|
||||||
|
public static final String PROPERTY_AWS_SECRETACCESSKEY = "jclouds.aws.secretaccesskey";
|
||||||
|
public static final String PROPERTY_AWS_ACCESSKEYID = "jclouds.aws.accesskeyid";
|
||||||
|
|
||||||
|
}
|
|
@ -11,8 +11,10 @@ import java.security.NoSuchProviderException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.bouncycastle.crypto.Digest;
|
||||||
import org.bouncycastle.crypto.digests.MD5Digest;
|
import org.bouncycastle.crypto.digests.MD5Digest;
|
||||||
import org.bouncycastle.crypto.digests.SHA1Digest;
|
import org.bouncycastle.crypto.digests.SHA1Digest;
|
||||||
|
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||||
import org.bouncycastle.crypto.macs.HMac;
|
import org.bouncycastle.crypto.macs.HMac;
|
||||||
import org.bouncycastle.crypto.params.KeyParameter;
|
import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
import org.bouncycastle.util.encoders.Base64;
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
|
@ -52,9 +54,14 @@ public class AWSUtils extends Utils {
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String hmacSha1Base64(String toEncode, byte[] key)
|
public static String hmacSha256Base64(String toEncode, byte[] key)
|
||||||
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
|
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
|
||||||
HMac hmac = new HMac(new SHA1Digest());
|
Digest digest = new SHA256Digest();
|
||||||
|
return hmacBase64(toEncode, key, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String hmacBase64(String toEncode, byte[] key, Digest digest) {
|
||||||
|
HMac hmac = new HMac(digest);
|
||||||
byte[] resBuf = new byte[hmac.getMacSize()];
|
byte[] resBuf = new byte[hmac.getMacSize()];
|
||||||
byte[] plainBytes = toEncode.getBytes();
|
byte[] plainBytes = toEncode.getBytes();
|
||||||
byte[] keyBytes = key;
|
byte[] keyBytes = key;
|
||||||
|
@ -64,6 +71,12 @@ public class AWSUtils extends Utils {
|
||||||
return toBase64String(resBuf);
|
return toBase64String(resBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String hmacSha1Base64(String toEncode, byte[] key)
|
||||||
|
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
|
||||||
|
Digest digest = new SHA1Digest();
|
||||||
|
return hmacBase64(toEncode, key, digest);
|
||||||
|
}
|
||||||
|
|
||||||
public static String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException,
|
public static String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException,
|
||||||
NoSuchProviderException, InvalidKeyException, UnsupportedEncodingException {
|
NoSuchProviderException, InvalidKeyException, UnsupportedEncodingException {
|
||||||
byte[] resBuf = md5(toEncode);
|
byte[] resBuf = md5(toEncode);
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws.xml;
|
||||||
|
|
||||||
|
import org.jclouds.aws.domain.AWSError;
|
||||||
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the error from the Amazon S3 REST API.
|
||||||
|
*
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingRESTError.html"
|
||||||
|
* />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ErrorHandler extends ParseSax.HandlerWithResult<AWSError> {
|
||||||
|
|
||||||
|
private AWSError error = new AWSError();
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
public AWSError getResult() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endElement(String uri, String name, String qName) {
|
||||||
|
|
||||||
|
if (qName.equals("Code")) {
|
||||||
|
error.setCode(currentText.toString());
|
||||||
|
} else if (qName.equals("Message")) {
|
||||||
|
error.setMessage(currentText.toString());
|
||||||
|
} else if (qName.equalsIgnoreCase("RequestId")) {
|
||||||
|
error.setRequestId(currentText.toString());
|
||||||
|
} else if (!qName.equals("Error")) {
|
||||||
|
error.getDetails().put(qName, currentText.toString());
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,82 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.aws.s3;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.jclouds.http.HttpResponseException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encapsulates an S3 Error from Amazon.
|
|
||||||
*
|
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html" />
|
|
||||||
* @see S3Error
|
|
||||||
* @see org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class S3ResponseException extends HttpResponseException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private S3Error error = new S3Error();
|
|
||||||
|
|
||||||
public S3ResponseException(HttpFutureCommand<?> command,
|
|
||||||
HttpResponse response, S3Error error) {
|
|
||||||
super(error.toString(), command, response);
|
|
||||||
this.setError(error);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public S3ResponseException(HttpFutureCommand<?> command,
|
|
||||||
HttpResponse response, S3Error error, Throwable cause) {
|
|
||||||
super(error.toString(), command, response, cause);
|
|
||||||
this.setError(error);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public S3ResponseException(String message, HttpFutureCommand<?> command,
|
|
||||||
HttpResponse response, S3Error error) {
|
|
||||||
super(message, command, response);
|
|
||||||
this.setError(error);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public S3ResponseException(String message, HttpFutureCommand<?> command,
|
|
||||||
HttpResponse response, S3Error error, Throwable cause) {
|
|
||||||
super(message, command, response, cause);
|
|
||||||
this.setError(error);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setError(S3Error error) {
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public S3Error getError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public class DeleteBucket extends S3FutureCommand<Boolean> {
|
||||||
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||||
if (e.getCause() != null
|
if (e.getCause() != null
|
||||||
&& e.getCause() instanceof HttpResponseException) {
|
&& e.getCause() instanceof HttpResponseException) {
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
AWSResponseException responseException = (AWSResponseException) e
|
||||||
.getCause();
|
.getCause();
|
||||||
if (responseException.getResponse().getStatusCode() == 404) {
|
if (responseException.getResponse().getStatusCode() == 404) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
import org.jclouds.aws.s3.commands.callables.ParseObjectFromHeadersAndHttpContent;
|
import org.jclouds.aws.s3.commands.callables.ParseObjectFromHeadersAndHttpContent;
|
||||||
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
@ -40,20 +40,16 @@ import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the S3Object associated with the Key or {@link S3Object#NOT_FOUND}
|
* Retrieves the S3Object associated with the Key or {@link S3Object#NOT_FOUND} if not available;
|
||||||
* if not available;
|
|
||||||
*
|
*
|
||||||
* <p/>
|
* <p/>
|
||||||
* To use GET, you must have READ access to the object. If READ access is
|
* To use GET, you must have READ access to the object. If READ access is granted to the anonymous
|
||||||
* granted to the anonymous user, you can request the object without an
|
* user, you can request the object without an authorization header.
|
||||||
* authorization header.
|
|
||||||
* <p />
|
* <p />
|
||||||
* <p/>
|
* <p/>
|
||||||
* This command allows you to specify {@link GetObjectOptions} to control
|
* This command allows you to specify {@link GetObjectOptions} to control delivery of content.
|
||||||
* delivery of content.
|
|
||||||
*
|
*
|
||||||
* <h2>Note</h2> If you specify any of the below options, you will receive
|
* <h2>Note</h2> If you specify any of the below options, you will receive partial content:
|
||||||
* partial content:
|
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link GetObjectOptions#range}</li>
|
* <li>{@link GetObjectOptions#range}</li>
|
||||||
* <li>{@link GetObjectOptions#startAt}</li>
|
* <li>{@link GetObjectOptions#startAt}</li>
|
||||||
|
@ -61,15 +57,16 @@ import com.google.inject.name.Named;
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see GetObjectOptions
|
* @see GetObjectOptions
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET.html" />
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET.html"
|
||||||
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class GetObject extends S3FutureCommand<S3Object> {
|
public class GetObject extends S3FutureCommand<S3Object> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GetObject(@Named("jclouds.http.address") String amazonHost,
|
public GetObject(@Named("jclouds.http.address") String amazonHost,
|
||||||
ParseObjectFromHeadersAndHttpContent callable,
|
ParseObjectFromHeadersAndHttpContent callable, @Assisted("bucketName") String s3Bucket,
|
||||||
@Assisted("bucketName") String s3Bucket,
|
|
||||||
@Assisted("key") String key, @Assisted GetObjectOptions options) {
|
@Assisted("key") String key, @Assisted GetObjectOptions options) {
|
||||||
super("GET", "/" + checkNotNull(key), callable, amazonHost, s3Bucket);
|
super("GET", "/" + checkNotNull(key), callable, amazonHost, s3Bucket);
|
||||||
this.getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
this.getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
||||||
|
@ -87,9 +84,8 @@ public class GetObject extends S3FutureCommand<S3Object> {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
S3Object attemptNotFound(ExecutionException e) throws ExecutionException {
|
S3Object attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||||
if (e.getCause() != null && e.getCause() instanceof S3ResponseException) {
|
if (e.getCause() != null && e.getCause() instanceof AWSResponseException) {
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
AWSResponseException responseException = (AWSResponseException) e.getCause();
|
||||||
.getCause();
|
|
||||||
if ("NoSuchKey".equals(responseException.getError().getCode())) {
|
if ("NoSuchKey".equals(responseException.getError().getCode())) {
|
||||||
return S3Object.NOT_FOUND;
|
return S3Object.NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -98,8 +94,8 @@ public class GetObject extends S3FutureCommand<S3Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public S3Object get(long l, TimeUnit timeUnit) throws InterruptedException,
|
public S3Object get(long l, TimeUnit timeUnit) throws InterruptedException, ExecutionException,
|
||||||
ExecutionException, TimeoutException {
|
TimeoutException {
|
||||||
try {
|
try {
|
||||||
return super.get(l, timeUnit);
|
return super.get(l, timeUnit);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||||
|
@ -40,15 +40,15 @@ import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GET request operation using a bucket URI lists information about the
|
* A GET request operation using a bucket URI lists information about the objects in the bucket.
|
||||||
* objects in the bucket.
|
|
||||||
* <p />
|
* <p />
|
||||||
* To list the keys of a bucket, you must have READ access to the bucket.
|
* To list the keys of a bucket, you must have READ access to the bucket.
|
||||||
* <p/>
|
* <p/>
|
||||||
* List output is controllable via {@link ListBucketOptions}
|
* List output is controllable via {@link ListBucketOptions}
|
||||||
*
|
*
|
||||||
* @see ListBucketOptions
|
* @see ListBucketOptions
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
|
@ -59,10 +59,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
||||||
public ListBucket(@Named("jclouds.http.address") String amazonHost,
|
public ListBucket(@Named("jclouds.http.address") String amazonHost,
|
||||||
ParseSax<S3Bucket> bucketParser, @Assisted String bucket,
|
ParseSax<S3Bucket> bucketParser, @Assisted String bucket,
|
||||||
@Assisted ListBucketOptions options) {
|
@Assisted ListBucketOptions options) {
|
||||||
super("GET", "/" + options.buildQueryString(), bucketParser,
|
super("GET", "/" + options.buildQueryString(), bucketParser, amazonHost, bucket);
|
||||||
amazonHost, bucket);
|
ListBucketHandler handler = (ListBucketHandler) bucketParser.getHandler();
|
||||||
ListBucketHandler handler = (ListBucketHandler) bucketParser
|
|
||||||
.getHandler();
|
|
||||||
handler.setBucketName(bucket);
|
handler.setBucketName(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,10 +75,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
S3Bucket attemptNotFound(ExecutionException e) throws ExecutionException {
|
S3Bucket attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||||
if (e.getCause() != null
|
if (e.getCause() != null && e.getCause() instanceof HttpResponseException) {
|
||||||
&& e.getCause() instanceof HttpResponseException) {
|
AWSResponseException responseException = (AWSResponseException) e.getCause();
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
|
||||||
.getCause();
|
|
||||||
if ("NoSuchBucket".equals(responseException.getError().getCode())) {
|
if ("NoSuchBucket".equals(responseException.getError().getCode())) {
|
||||||
return S3Bucket.NOT_FOUND;
|
return S3Bucket.NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -89,8 +85,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public S3Bucket get(long l, TimeUnit timeUnit) throws InterruptedException,
|
public S3Bucket get(long l, TimeUnit timeUnit) throws InterruptedException, ExecutionException,
|
||||||
ExecutionException, TimeoutException {
|
TimeoutException {
|
||||||
try {
|
try {
|
||||||
return super.get(l, timeUnit);
|
return super.get(l, timeUnit);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import javax.annotation.Resource;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||||
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
|
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
||||||
import org.jclouds.aws.s3.internal.LiveS3Connection;
|
import org.jclouds.aws.s3.internal.LiveS3Connection;
|
||||||
import org.jclouds.http.HttpConstants;
|
import org.jclouds.http.HttpConstants;
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
@ -74,9 +74,9 @@ public class LiveS3ConnectionModule extends AbstractModule {
|
||||||
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class).to(
|
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class).to(
|
||||||
CloseContentAndSetExceptionHandler.class).in(Scopes.SINGLETON);
|
CloseContentAndSetExceptionHandler.class).in(Scopes.SINGLETON);
|
||||||
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class).to(
|
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class).to(
|
||||||
ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
ParseAWSErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||||
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class).to(
|
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class).to(
|
||||||
ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
ParseAWSErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||||
requestInjection(this);
|
requestInjection(this);
|
||||||
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https" : "http"), address, port);
|
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https" : "http"), address, port);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.aws.s3.handlers;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
|
||||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
|
||||||
import org.jclouds.aws.s3.reference.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will parse and set an appropriate exception on the command object.
|
|
||||||
*
|
|
||||||
* @see S3Error
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ParseS3ErrorFromXmlContent implements HttpResponseHandler {
|
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
private final S3ParserFactory parserFactory;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ParseS3ErrorFromXmlContent(S3ParserFactory parserFactory) {
|
|
||||||
this.parserFactory = parserFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handle(HttpFutureCommand<?> command, HttpResponse response) {
|
|
||||||
S3Error error = new S3Error();
|
|
||||||
error.setRequestId(response.getFirstHeaderOrNull(S3Headers.REQUEST_ID));
|
|
||||||
error.setRequestToken(response
|
|
||||||
.getFirstHeaderOrNull(S3Headers.REQUEST_TOKEN));
|
|
||||||
InputStream errorStream = response.getContent();
|
|
||||||
try {
|
|
||||||
if (errorStream != null) {
|
|
||||||
error = parserFactory.createErrorParser().parse(errorStream);
|
|
||||||
if ("SignatureDoesNotMatch".equals(error.getCode()))
|
|
||||||
error.setStringSigned(RequestAuthorizeSignature
|
|
||||||
.createStringToSign(command.getRequest()));
|
|
||||||
error.setRequestToken(response
|
|
||||||
.getFirstHeaderOrNull(S3Headers.REQUEST_TOKEN));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn(e, "error parsing XML reponse: %1$s", response);
|
|
||||||
} finally {
|
|
||||||
command.setException(new S3ResponseException(command, response,
|
|
||||||
error));
|
|
||||||
IOUtils.closeQuietly(errorStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,18 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.reference;
|
package org.jclouds.aws.s3.reference;
|
||||||
|
|
||||||
import org.jclouds.command.pool.PoolConstants;
|
import org.jclouds.aws.reference.AWSConstants;
|
||||||
import org.jclouds.http.HttpConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties and constants used in S3 connections.
|
* Configuration properties and constants used in S3 connections.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface S3Constants extends HttpConstants, PoolConstants, S3Headers {
|
public interface S3Constants extends AWSConstants, S3Headers {
|
||||||
|
|
||||||
public static final String PROPERTY_AWS_SECRETACCESSKEY = "jclouds.aws.secretaccesskey";
|
|
||||||
public static final String PROPERTY_AWS_ACCESSKEYID = "jclouds.aws.accesskeyid";
|
|
||||||
/**
|
/**
|
||||||
* longest time a single Map operation can take before throwing an exception.
|
* longest time a single Map operation can take before throwing an exception.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,9 +25,10 @@ package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.aws.domain.AWSError;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.xml.ErrorHandler;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -88,7 +89,7 @@ public class S3ParserFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GenericParseFactory<S3Error> parseErrorFactory;
|
private GenericParseFactory<AWSError> parseErrorFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Provider<ErrorHandler> errorHandlerProvider;
|
Provider<ErrorHandler> errorHandlerProvider;
|
||||||
|
@ -96,7 +97,7 @@ public class S3ParserFactory {
|
||||||
/**
|
/**
|
||||||
* @return a parser used to handle error conditions.
|
* @return a parser used to handle error conditions.
|
||||||
*/
|
*/
|
||||||
public ParseSax<S3Error> createErrorParser() {
|
public ParseSax<AWSError> createErrorParser() {
|
||||||
return parseErrorFactory.create(errorHandlerProvider.get());
|
return parseErrorFactory.create(errorHandlerProvider.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,14 @@ package org.jclouds.aws.s3.xml.config;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.aws.domain.AWSError;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.xml.CopyObjectHandler;
|
import org.jclouds.aws.s3.xml.CopyObjectHandler;
|
||||||
import org.jclouds.aws.s3.xml.ErrorHandler;
|
|
||||||
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
||||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||||
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
||||||
|
import org.jclouds.aws.xml.ErrorHandler;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import org.jclouds.http.commands.callables.xml.config.SaxModule;
|
import org.jclouds.http.commands.callables.xml.config.SaxModule;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public class S3ParserModule extends AbstractModule {
|
||||||
};
|
};
|
||||||
private final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>> objectMetadataTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>>() {
|
private final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>> objectMetadataTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>>() {
|
||||||
};
|
};
|
||||||
private final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>>() {
|
private final TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>>() {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -63,14 +63,13 @@ public class S3ParserModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindParserImplementationsToReturnTypes() {
|
private void bindParserImplementationsToReturnTypes() {
|
||||||
bind(
|
bind(new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
|
||||||
new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
|
|
||||||
}).to(ListAllMyBucketsHandler.class);
|
}).to(ListAllMyBucketsHandler.class);
|
||||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Bucket>>() {
|
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Bucket>>() {
|
||||||
}).to(ListBucketHandler.class);
|
}).to(ListBucketHandler.class);
|
||||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Object.Metadata>>() {
|
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Object.Metadata>>() {
|
||||||
}).to(CopyObjectHandler.class);
|
}).to(CopyObjectHandler.class);
|
||||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Error>>() {
|
bind(new TypeLiteral<ParseSax.HandlerWithResult<AWSError>>() {
|
||||||
}).to(ErrorHandler.class);
|
}).to(ErrorHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,16 +79,14 @@ public class S3ParserModule extends AbstractModule {
|
||||||
new TypeLiteral<ParseSax<List<S3Bucket.Metadata>>>() {
|
new TypeLiteral<ParseSax<List<S3Bucket.Metadata>>>() {
|
||||||
}));
|
}));
|
||||||
bind(bucketTypeLiteral).toProvider(
|
bind(bucketTypeLiteral).toProvider(
|
||||||
FactoryProvider.newFactory(bucketTypeLiteral,
|
FactoryProvider.newFactory(bucketTypeLiteral, new TypeLiteral<ParseSax<S3Bucket>>() {
|
||||||
new TypeLiteral<ParseSax<S3Bucket>>() {
|
|
||||||
}));
|
}));
|
||||||
bind(objectMetadataTypeLiteral).toProvider(
|
bind(objectMetadataTypeLiteral).toProvider(
|
||||||
FactoryProvider.newFactory(objectMetadataTypeLiteral,
|
FactoryProvider.newFactory(objectMetadataTypeLiteral,
|
||||||
new TypeLiteral<ParseSax<S3Object.Metadata>>() {
|
new TypeLiteral<ParseSax<S3Object.Metadata>>() {
|
||||||
}));
|
}));
|
||||||
bind(errorTypeLiteral).toProvider(
|
bind(errorTypeLiteral).toProvider(
|
||||||
FactoryProvider.newFactory(errorTypeLiteral,
|
FactoryProvider.newFactory(errorTypeLiteral, new TypeLiteral<ParseSax<AWSError>>() {
|
||||||
new TypeLiteral<ParseSax<S3Error>>() {
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,9 +130,9 @@ public class S3IntegrationTest {
|
||||||
protected String bucketPrefix = (System.getProperty("user.name") + "." + this.getClass()
|
protected String bucketPrefix = (System.getProperty("user.name") + "." + this.getClass()
|
||||||
.getSimpleName()).toLowerCase();
|
.getSimpleName()).toLowerCase();
|
||||||
|
|
||||||
private static final String sysAWSAccessKeyId = System
|
protected static final String sysAWSAccessKeyId = System
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
||||||
private static final String sysAWSSecretAccessKey = System
|
protected static final String sysAWSSecretAccessKey = System
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||||
|
|
||||||
@BeforeClass(inheritGroups = false, groups = { "integration", "live" })
|
@BeforeClass(inheritGroups = false, groups = { "integration", "live" })
|
||||||
|
|
|
@ -304,34 +304,43 @@ public class StubS3Connection implements S3Connection {
|
||||||
contents.remove(lastMarkerMetadata);
|
contents.remove(lastMarkerMetadata);
|
||||||
returnVal.setMarker(marker);
|
returnVal.setMarker(marker);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
if (options.getPrefix() != null) {
|
if (options.getPrefix() != null) {
|
||||||
contents = Sets.newTreeSet(Iterables.filter(contents,
|
contents = Sets.newTreeSet(Iterables.filter(contents,
|
||||||
new Predicate<S3Object.Metadata>() {
|
new Predicate<S3Object.Metadata>() {
|
||||||
|
|
||||||
public boolean apply(S3Object.Metadata o) {
|
public boolean apply(S3Object.Metadata o) {
|
||||||
|
try {
|
||||||
return (o != null && o.getKey().startsWith(
|
return (o != null && o.getKey().startsWith(
|
||||||
URLDecoder.decode(options.getPrefix())));
|
URLDecoder.decode(options.getPrefix(), "UTF-8")));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
returnVal.setPrefix(URLDecoder.decode(options.getPrefix()));
|
returnVal.setPrefix(URLDecoder.decode(options.getPrefix(), "UTF-8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.getDelimiter() != null) {
|
if (options.getDelimiter() != null) {
|
||||||
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(options
|
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(
|
||||||
.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null,
|
options.getPrefix() != null ? URLDecoder.decode(options.getPrefix(),
|
||||||
URLDecoder.decode(options.getDelimiter())));
|
"UTF-8") : null, URLDecoder.decode(options.getDelimiter(),
|
||||||
|
"UTF-8")));
|
||||||
Set<String> commonPrefixes = iterable != null ? Sets.newTreeSet(iterable)
|
Set<String> commonPrefixes = iterable != null ? Sets.newTreeSet(iterable)
|
||||||
: new HashSet<String>();
|
: new HashSet<String>();
|
||||||
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
|
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
|
||||||
|
|
||||||
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(options
|
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(options
|
||||||
.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null,
|
.getPrefix() != null ? URLDecoder.decode(options.getPrefix(), "UTF-8")
|
||||||
URLDecoder.decode(options.getDelimiter()))));
|
: null, URLDecoder.decode(options.getDelimiter(), "UTF-8"))));
|
||||||
|
|
||||||
returnVal.setCommonPrefixes(commonPrefixes);
|
returnVal.setCommonPrefixes(commonPrefixes);
|
||||||
returnVal.setDelimiter(URLDecoder.decode(options.getDelimiter()));
|
returnVal.setDelimiter(URLDecoder.decode(options.getDelimiter(), "UTF-8"));
|
||||||
}
|
}
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
if (options.getMaxKeys() != null) {
|
if (options.getMaxKeys() != null) {
|
||||||
contents = firstSliceOfSize(contents, Integer.parseInt(options.getMaxKeys()));
|
contents = firstSliceOfSize(contents, Integer.parseInt(options.getMaxKeys()));
|
||||||
returnVal.setMaxKeys(Integer.parseInt(options.getMaxKeys()));
|
returnVal.setMaxKeys(Integer.parseInt(options.getMaxKeys()));
|
||||||
|
@ -344,7 +353,8 @@ public class StubS3Connection implements S3Connection {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Comparable> SortedSet<T> firstSliceOfSize(Iterable<T> elements, int size) {
|
public static <T extends Comparable<?>> SortedSet<T> firstSliceOfSize(Iterable<T> elements,
|
||||||
|
int size) {
|
||||||
List<List<T>> slices = Lists.partition(Lists.newArrayList(elements), size);
|
List<List<T>> slices = Lists.partition(Lists.newArrayList(elements), size);
|
||||||
return Sets.newTreeSet(slices.get(0));
|
return Sets.newTreeSet(slices.get(0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,34 +23,31 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
import org.testng.annotations.BeforeMethod;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all bucketExists commands.
|
* Tests integrated functionality of all bucketExists commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||||
* in parallel.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = {"integration", "live"}, testName = "s3.BucketExistsIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.BucketExistsIntegrationTest")
|
||||||
public class BucketExistsIntegrationTest extends S3IntegrationTest {
|
public class BucketExistsIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void bucketDoesntExist() throws Exception {
|
void bucketDoesntExist() throws Exception {
|
||||||
String bucketName= bucketPrefix+"be";
|
String bucketName = bucketPrefix + "be";
|
||||||
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void bucketExists() throws Exception {
|
void bucketExists() throws Exception {
|
||||||
String bucketName= bucketPrefix+"bde";
|
String bucketName = bucketPrefix + "bde";
|
||||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
assert client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,30 +23,32 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
||||||
import com.google.common.collect.Multimap;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
|
||||||
import org.jclouds.aws.s3.reference.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
|
||||||
import org.jclouds.http.HttpResponseException;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all copyObject commands.
|
* Tests integrated functionality of all copyObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||||
* in parallel.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -55,7 +57,7 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
String sourceKey = "apples";
|
String sourceKey = "apples";
|
||||||
String destinationKey = "pears";
|
String destinationKey = "pears";
|
||||||
|
|
||||||
@Test(groups = {"integration","live"})
|
@Test(groups = { "integration", "live" })
|
||||||
void testCopyObject() throws Exception {
|
void testCopyObject() throws Exception {
|
||||||
|
|
||||||
String destinationBucket = bucketName + "dest";
|
String destinationBucket = bucketName + "dest";
|
||||||
|
@ -63,126 +65,116 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
addToBucketAndValidate(bucketName, sourceKey);
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey).get(10,
|
||||||
destinationKey).get(10, TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void addToBucketAndValidate(String bucketName, String sourceKey)
|
private void addToBucketAndValidate(String bucketName, String sourceKey)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||||
IOException {
|
|
||||||
addObjectToBucket(bucketName, sourceKey);
|
addObjectToBucket(bucketName, sourceKey);
|
||||||
validateContent(bucketName, sourceKey);
|
validateContent(bucketName, sourceKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled= false, groups = {"integration","live"})//TODO: fails on linux and windows
|
@Test(enabled = false, groups = { "integration", "live" })
|
||||||
void testCopyIfModifiedSince() throws InterruptedException,
|
// TODO: fails on linux and windows
|
||||||
ExecutionException, TimeoutException, IOException {
|
void testCopyIfModifiedSince() throws InterruptedException, ExecutionException,
|
||||||
|
|
||||||
String destinationBucket = bucketName + "dest";
|
|
||||||
|
|
||||||
DateTime before = new DateTime();
|
|
||||||
addToBucketAndValidate(bucketName, sourceKey);
|
|
||||||
DateTime after = new DateTime().plusSeconds(1);
|
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
|
||||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
|
||||||
|
|
||||||
try {
|
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
|
||||||
destinationKey, ifSourceModifiedSince(after)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled= false, groups = {"integration","live"})//TODO: fails on linux and windows
|
|
||||||
void testCopyIfUnmodifiedSince() throws InterruptedException,
|
|
||||||
ExecutionException, TimeoutException, IOException {
|
|
||||||
|
|
||||||
String destinationBucket = bucketName + "dest";
|
|
||||||
|
|
||||||
DateTime before = new DateTime();
|
|
||||||
addToBucketAndValidate(bucketName, sourceKey);
|
|
||||||
DateTime after = new DateTime().plusSeconds(1);
|
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
|
||||||
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
|
||||||
|
|
||||||
try {
|
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
|
||||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(groups = {"integration","live"})
|
|
||||||
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
|
|
||||||
|
|
||||||
String destinationBucket = bucketName + "dest";
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
|
DateTime before = new DateTime();
|
||||||
addToBucketAndValidate(bucketName, sourceKey);
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
|
ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
ifSourceModifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(groups = {"integration","live"})
|
@Test(enabled = false, groups = { "integration", "live" })
|
||||||
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
// TODO: fails on linux and windows
|
||||||
ExecutionException, TimeoutException {
|
void testCopyIfUnmodifiedSince() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
|
||||||
String destinationBucket = bucketName + "dest";
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
|
DateTime before = new DateTime();
|
||||||
addToBucketAndValidate(bucketName, sourceKey);
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
|
ifSourceUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
|
ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(groups = {"integration","live"})
|
@Test(groups = { "integration", "live" })
|
||||||
void testCopyWithMetadata() throws InterruptedException,
|
void testCopyIfMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
ExecutionException, TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
|
ifSourceMd5Matches(goodMd5)).get(10, TimeUnit.SECONDS);
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
|
ifSourceMd5Matches(badMd5)).get(10, TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = { "integration", "live" })
|
||||||
|
void testCopyIfNoneMatch() throws IOException, InterruptedException, ExecutionException,
|
||||||
|
TimeoutException {
|
||||||
|
|
||||||
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
|
ifSourceMd5DoesntMatch(badMd5)).get(10, TimeUnit.SECONDS);
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
|
ifSourceMd5DoesntMatch(goodMd5)).get(10, TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = { "integration", "live" })
|
||||||
|
void testCopyWithMetadata() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
|
IOException {
|
||||||
|
|
||||||
String destinationBucket = bucketName + "dest";
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
|
@ -192,14 +184,13 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||||
destinationKey, overrideMetadataWith(metadata)).get(10,
|
overrideMetadataWith(metadata)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
|
S3Object.Metadata objectMeta = client.headObject(destinationBucket, destinationKey).get(10,
|
||||||
destinationKey).get(10, TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
assertEquals(objectMeta.getUserMetadata(), metadata);
|
assertEquals(objectMeta.getUserMetadata(), metadata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,24 +23,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.aws.AWSResponseException;
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all deleteObject commands.
|
* Tests integrated functionality of all deleteObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||||
* in parallel.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = {"integration", "live"}, testName = "s3.DeleteObjectIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.DeleteObjectIntegrationTest")
|
||||||
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
|
@ -48,8 +48,7 @@ public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||||
String bucketName = bucketPrefix + "donf";
|
String bucketName = bucketPrefix + "donf";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
addObjectToBucket(bucketName, "test");
|
addObjectToBucket(bucketName, "test");
|
||||||
assert client.deleteObject(bucketName, "test")
|
assert client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||||
.get(10, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -58,9 +57,8 @@ public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||||
try {
|
try {
|
||||||
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
assert e.getCause() instanceof S3ResponseException;
|
assert e.getCause() instanceof AWSResponseException;
|
||||||
assertEquals(((S3ResponseException) e.getCause()).getResponse()
|
assertEquals(((AWSResponseException) e.getCause()).getResponse().getStatusCode(), 404);
|
||||||
.getStatusCode(), 404);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +67,7 @@ public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||||
String bucketName = bucketPrefix + "do";
|
String bucketName = bucketPrefix + "do";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
addObjectToBucket(bucketName, "test");
|
addObjectToBucket(bucketName, "test");
|
||||||
assert client.deleteObject(bucketName, "test")
|
assert client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||||
.get(10, TimeUnit.SECONDS);
|
|
||||||
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
|
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,35 +23,41 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5DoesntMatch;
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5Matches;
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifModifiedSince;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifUnmodifiedSince;
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.range;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.startAt;
|
||||||
import org.joda.time.DateTime;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.tail;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all GetObject commands.
|
* Tests integrated functionality of all GetObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||||
* in parallel.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = {"integration", "live"}, testName = "s3.GetObjectIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.GetObjectIntegrationTest")
|
||||||
public class GetObjectIntegrationTest extends S3IntegrationTest {
|
public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test(enabled=false )//TODO: fails on linux and windows
|
@Test(enabled = false)
|
||||||
void testGetIfModifiedSince() throws InterruptedException,
|
// TODO: fails on linux and windows
|
||||||
ExecutionException, TimeoutException, IOException {
|
void testGetIfModifiedSince() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
|
@ -59,13 +65,11 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
DateTime after = new DateTime().plusSeconds(1);
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
|
||||||
client.getObject(bucketName, key, ifModifiedSince(before)).get(10,
|
client.getObject(bucketName, key, ifModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getObject(bucketName, key, ifModifiedSince(after)).get(10,
|
client.getObject(bucketName, key, ifModifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
if (e.getCause() instanceof HttpResponseException) {
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
|
@ -78,9 +82,10 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled=false )//TODO: fails on linux and windows
|
@Test(enabled = false)
|
||||||
void testGetIfUnmodifiedSince() throws InterruptedException,
|
// TODO: fails on linux and windows
|
||||||
ExecutionException, TimeoutException, IOException {
|
void testGetIfUnmodifiedSince() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
|
@ -88,13 +93,11 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
DateTime after = new DateTime().plusSeconds(1);
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
|
||||||
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10,
|
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10,
|
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
if (e.getCause() instanceof HttpResponseException) {
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
|
@ -108,20 +111,18 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetIfMatch() throws InterruptedException, ExecutionException,
|
void testGetIfMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
|
|
||||||
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10,
|
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10,
|
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
if (e.getCause() instanceof HttpResponseException) {
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
|
@ -134,20 +135,18 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetIfNoneMatch() throws InterruptedException, ExecutionException,
|
void testGetIfNoneMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
|
|
||||||
client.getObject(bucketName, key, ifMd5DoesntMatch(badMd5)).get(10,
|
client.getObject(bucketName, key, ifMd5DoesntMatch(badMd5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getObject(bucketName, key, ifMd5DoesntMatch(goodMd5)).get(10,
|
client.getObject(bucketName, key, ifMd5DoesntMatch(goodMd5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(bucketName, key);
|
validateContent(bucketName, key);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
if (e.getCause() instanceof HttpResponseException) {
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
|
@ -160,71 +159,65 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetRange() throws InterruptedException, ExecutionException,
|
void testGetRange() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10,
|
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING.substring(0, 6));
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
|
|
||||||
.substring(0, 6));
|
|
||||||
|
|
||||||
S3Object object2 = client.getObject(bucketName, key,
|
S3Object object2 = client.getObject(bucketName, key, range(6, TEST_STRING.length())).get(10,
|
||||||
range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
|
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING.substring(6,
|
||||||
.substring(6, TEST_STRING.length()));
|
TEST_STRING.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
void testGetTwoRanges() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
S3Object object = client.getObject(bucketName, key,
|
S3Object object = client.getObject(bucketName, key,
|
||||||
range(0, 5).range(6, TEST_STRING.length())).get(10,
|
range(0, 5).range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTail() throws InterruptedException, ExecutionException,
|
void testGetTail() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
S3Object object = client.getObject(bucketName, key, tail(5)).get(10,
|
S3Object object = client.getObject(bucketName, key, tail(5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING.substring(TEST_STRING
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
.length() - 5));
|
||||||
.substring(TEST_STRING.length() - 5));
|
|
||||||
assertEquals(object.getContentLength(), 5);
|
assertEquals(object.getContentLength(), 5);
|
||||||
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetStartAt() throws InterruptedException, ExecutionException,
|
void testGetStartAt() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
TimeoutException, IOException {
|
IOException {
|
||||||
|
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
addObjectAndValidateContent(bucketName, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10,
|
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10, TimeUnit.SECONDS);
|
||||||
TimeUnit.SECONDS);
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING.substring(5, TEST_STRING
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
.length()));
|
||||||
.substring(5, TEST_STRING.length()));
|
|
||||||
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
||||||
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addObjectAndValidateContent(String sourcebucketName, String sourceKey)
|
private void addObjectAndValidateContent(String sourcebucketName, String sourceKey)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||||
IOException {
|
|
||||||
addObjectToBucket(sourcebucketName, sourceKey);
|
addObjectToBucket(sourcebucketName, sourceKey);
|
||||||
validateContent(sourcebucketName, sourceKey);
|
validateContent(sourcebucketName, sourceKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,32 +23,27 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
|
||||||
import org.jclouds.aws.s3.reference.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import org.testng.annotations.DataProvider;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all PutObject commands.
|
* Tests integrated functionality of all PutObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||||
* in parallel.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -59,38 +54,31 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
|
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
|
||||||
|
|
||||||
return new Object[][]{
|
return new Object[][] { { "file", "text/xml", new File("pom.xml"), realObject },
|
||||||
{"file", "text/xml", new File("pom.xml"), realObject},
|
{ "string", "text/xml", realObject, realObject },
|
||||||
{"string", "text/xml", realObject, realObject},
|
{ "bytes", "application/octet-stream", realObject.getBytes(), realObject } };
|
||||||
{"bytes", "application/octet-stream", realObject.getBytes(),
|
|
||||||
realObject}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "putTests", groups = {"integration", "live"})
|
@Test(dataProvider = "putTests", groups = { "integration", "live" })
|
||||||
void testPutObject(String key, String type, Object content,
|
void testPutObject(String key, String type, Object content, Object realObject) throws Exception {
|
||||||
Object realObject) throws Exception {
|
|
||||||
String bucketName = bucketPrefix + "tpo";
|
String bucketName = bucketPrefix + "tpo";
|
||||||
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
context.createS3ObjectMap(bucketName).clear();
|
context.createS3ObjectMap(bucketName).clear();
|
||||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS).getContents().size(), 0);
|
||||||
.getContents().size(), 0);
|
|
||||||
S3Object object = new S3Object(key);
|
S3Object object = new S3Object(key);
|
||||||
object.getMetadata().setContentType(type);
|
object.getMetadata().setContentType(type);
|
||||||
object.setData(content);
|
object.setData(content);
|
||||||
if (content instanceof InputStream) {
|
if (content instanceof InputStream) {
|
||||||
object.generateMd5();
|
object.generateMd5();
|
||||||
}
|
}
|
||||||
assertNotNull(client.putObject(bucketName, object).get(10,
|
assertNotNull(client.putObject(bucketName, object).get(10, TimeUnit.SECONDS));
|
||||||
TimeUnit.SECONDS));
|
object = client.getObject(bucketName, object.getKey()).get(10, TimeUnit.SECONDS);
|
||||||
object = client.getObject(bucketName, object.getKey()).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
String returnedString = S3Utils.getContentAsStringAndClose(object);
|
String returnedString = S3Utils.getContentAsStringAndClose(object);
|
||||||
assertEquals(returnedString, realObject);
|
assertEquals(returnedString, realObject);
|
||||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS).getContents().size(), 1);
|
||||||
.getContents().size(), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(groups = {"integration", "live"})
|
@Test(groups = { "integration", "live" })
|
||||||
void testMetadata() throws Exception {
|
void testMetadata() throws Exception {
|
||||||
String bucketName = bucketPrefix + "tmd";
|
String bucketName = bucketPrefix + "tmd";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
@ -101,27 +89,24 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||||
object.getMetadata().setContentType("text/plain");
|
object.getMetadata().setContentType("text/plain");
|
||||||
object.getMetadata().setContentEncoding("x-compress");
|
object.getMetadata().setContentEncoding("x-compress");
|
||||||
object.getMetadata().setSize(TEST_STRING.length());
|
object.getMetadata().setSize(TEST_STRING.length());
|
||||||
object.getMetadata().setContentDisposition(
|
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||||
"attachment; filename=hello.txt");
|
object.getMetadata().getUserMetadata().put(S3Headers.USER_METADATA_PREFIX + "adrian",
|
||||||
object.getMetadata().getUserMetadata().put(
|
"powderpuff");
|
||||||
S3Headers.USER_METADATA_PREFIX + "adrian", "powderpuff");
|
|
||||||
object.getMetadata().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
|
object.getMetadata().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
|
||||||
|
|
||||||
addObjectToBucket(bucketName, object);
|
addObjectToBucket(bucketName, object);
|
||||||
S3Object newObject = validateContent(bucketName, key);
|
S3Object newObject = validateContent(bucketName, key);
|
||||||
|
|
||||||
// TODO.. why does this come back as binary/octetstring
|
// TODO.. why does this come back as binary/octetstring
|
||||||
assertEquals(newObject.getMetadata().getContentType(),
|
assertEquals(newObject.getMetadata().getContentType(), "binary/octet-stream");
|
||||||
"binary/octet-stream");
|
|
||||||
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||||
assertEquals(newObject.getMetadata().getContentDisposition(),
|
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||||
"attachment; filename=hello.txt");
|
"attachment; filename=hello.txt");
|
||||||
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||||
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
|
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
|
||||||
assertEquals(newObject.getMetadata().getUserMetadata().values()
|
assertEquals(newObject.getMetadata().getUserMetadata().values().iterator().next(),
|
||||||
.iterator().next(), "powderpuff");
|
"powderpuff");
|
||||||
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
|
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING.getBytes()));
|
||||||
.getBytes()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -27,7 +27,7 @@ import com.google.inject.Guice;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.name.Names;
|
import com.google.inject.name.Names;
|
||||||
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
|
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
import org.jclouds.http.annotation.ClientErrorHandler;
|
import org.jclouds.http.annotation.ClientErrorHandler;
|
||||||
|
@ -46,37 +46,23 @@ import org.testng.annotations.Test;
|
||||||
@Test(groups = "unit", testName = "s3.S3ContextModuleTest")
|
@Test(groups = "unit", testName = "s3.S3ContextModuleTest")
|
||||||
public class S3ContextModuleTest {
|
public class S3ContextModuleTest {
|
||||||
|
|
||||||
Injector injector = null;
|
Injector createInjector() {
|
||||||
|
return Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
|
||||||
@BeforeMethod
|
|
||||||
void setUpInjector() {
|
|
||||||
injector = Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||||
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
|
||||||
"localhost");
|
"localhost");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to(
|
||||||
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
|
||||||
.to("localhost");
|
|
||||||
bindConstant().annotatedWith(
|
|
||||||
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
|
||||||
"localhost");
|
"localhost");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
||||||
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
"localhost");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
||||||
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
|
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to("false");
|
||||||
"false");
|
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
}, new JavaUrlHttpFutureCommandClientModule());
|
}, new JavaUrlHttpFutureCommandClientModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
|
||||||
void tearDownInjector() {
|
|
||||||
injector = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ClientErrorHandlerTest {
|
private static class ClientErrorHandlerTest {
|
||||||
@Inject
|
@Inject
|
||||||
@ClientErrorHandler
|
@ClientErrorHandler
|
||||||
|
@ -85,10 +71,8 @@ public class S3ContextModuleTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testClientErrorHandler() {
|
void testClientErrorHandler() {
|
||||||
ClientErrorHandlerTest error = injector
|
ClientErrorHandlerTest error = createInjector().getInstance(ClientErrorHandlerTest.class);
|
||||||
.getInstance(ClientErrorHandlerTest.class);
|
assertEquals(error.errorHandler.getClass(), ParseAWSErrorFromXmlContent.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
|
||||||
ParseS3ErrorFromXmlContent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ServerErrorHandlerTest {
|
private static class ServerErrorHandlerTest {
|
||||||
|
@ -99,10 +83,8 @@ public class S3ContextModuleTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testServerErrorHandler() {
|
void testServerErrorHandler() {
|
||||||
ServerErrorHandlerTest error = injector
|
ServerErrorHandlerTest error = createInjector().getInstance(ServerErrorHandlerTest.class);
|
||||||
.getInstance(ServerErrorHandlerTest.class);
|
assertEquals(error.errorHandler.getClass(), ParseAWSErrorFromXmlContent.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
|
||||||
ParseS3ErrorFromXmlContent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class RedirectHandlerTest {
|
private static class RedirectHandlerTest {
|
||||||
|
@ -113,10 +95,8 @@ public class S3ContextModuleTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRedirectHandler() {
|
void testRedirectHandler() {
|
||||||
RedirectHandlerTest error = injector
|
RedirectHandlerTest error = createInjector().getInstance(RedirectHandlerTest.class);
|
||||||
.getInstance(RedirectHandlerTest.class);
|
assertEquals(error.errorHandler.getClass(), CloseContentAndSetExceptionHandler.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
|
||||||
CloseContentAndSetExceptionHandler.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -82,6 +82,7 @@ public class BaseS3MapTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
|
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
BaseS3Map<String> map = new MockBaseS3Map();
|
BaseS3Map<String> map = new MockBaseS3Map();
|
||||||
|
@ -101,6 +102,7 @@ public class BaseS3MapTest {
|
||||||
assert !objects.contains(S3Object.NOT_FOUND);
|
assert !objects.contains(S3Object.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
|
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
BaseS3Map<String> map = new MockBaseS3Map();
|
BaseS3Map<String> map = new MockBaseS3Map();
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
import org.jclouds.aws.domain.AWSError;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
@ -37,8 +37,8 @@ public class ErrorHandlerTest extends BaseHandlerTest {
|
||||||
@Test
|
@Test
|
||||||
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader()
|
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader()
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
ParseSax<S3Error> parser = parserFactory.createErrorParser();
|
ParseSax<AWSError> parser = parserFactory.createErrorParser();
|
||||||
S3Error error = parser
|
AWSError error = parser
|
||||||
.parse(IOUtils
|
.parse(IOUtils
|
||||||
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
|
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
|
||||||
assertEquals(error.getCode(), "NotImplemented");
|
assertEquals(error.getCode(), "NotImplemented");
|
||||||
|
|
|
@ -23,11 +23,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -35,20 +36,19 @@ import org.testng.annotations.Test;
|
||||||
public class ListBucketHandlerTest extends BaseHandlerTest {
|
public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>"c82e6a0025c31c5de5947fda62ac51ab"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"944fab2c5a9a6bacf07db5e688310d7a"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"a227b8888045c8fd159fb495214000f0"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"c9caa76c3dec53e2a192608ce73eef03"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"1ce5d0dcc6154a647ea90c7bdf82a224"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"79433524d87462ee05708a8ef894ed55"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"dd00a060b28ddca8bc5a21a49e306f67"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"8cd06eca6e819a927b07a285d750b100"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"174495094d0633b92cbe46603eee6bad"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"cd8a19b26fea8a827276df0ad11c580d"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>";
|
public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>"c82e6a0025c31c5de5947fda62ac51ab"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"944fab2c5a9a6bacf07db5e688310d7a"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"a227b8888045c8fd159fb495214000f0"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"c9caa76c3dec53e2a192608ce73eef03"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"1ce5d0dcc6154a647ea90c7bdf82a224"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"79433524d87462ee05708a8ef894ed55"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"dd00a060b28ddca8bc5a21a49e306f67"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"8cd06eca6e819a927b07a285d750b100"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"174495094d0633b92cbe46603eee6bad"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"cd8a19b26fea8a827276df0ad11c580d"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>";
|
||||||
public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
|
public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
|
||||||
ParseSax<S3Bucket> parser;
|
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUpParser() {
|
ParseSax<S3Bucket> createParser() {
|
||||||
parser = parserFactory.createListBucketParser();
|
ParseSax<S3Bucket> parser = parserFactory.createListBucketParser();
|
||||||
((ListBucketHandler) parser.getHandler()).setBucketName("test");
|
((ListBucketHandler) parser.getHandler()).setBucketName("test");
|
||||||
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash()
|
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash() throws HttpException {
|
||||||
throws HttpException {
|
|
||||||
|
|
||||||
S3Bucket bucket = parser.parse(IOUtils
|
S3Bucket bucket = createParser().parse(
|
||||||
.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
|
IOUtils.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
|
||||||
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
|
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
|
||||||
assertEquals(bucket.getDelimiter(), "/");
|
assertEquals(bucket.getDelimiter(), "/");
|
||||||
assert bucket.getMarker() == null;
|
assert bucket.getMarker() == null;
|
||||||
|
@ -57,8 +57,7 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
@Test
|
@Test
|
||||||
public void testListMyBucketsWithPrefixAppsSlash() throws HttpException {
|
public void testListMyBucketsWithPrefixAppsSlash() throws HttpException {
|
||||||
|
|
||||||
S3Bucket bucket = parser.parse(IOUtils
|
S3Bucket bucket = createParser().parse(IOUtils.toInputStream(listBucketWithPrefixAppsSlash));
|
||||||
.toInputStream(listBucketWithPrefixAppsSlash));
|
|
||||||
assertEquals(bucket.getPrefix(), "apps/");
|
assertEquals(bucket.getPrefix(), "apps/");
|
||||||
assertEquals(bucket.getMaxKeys(), 1000);
|
assertEquals(bucket.getMaxKeys(), 1000);
|
||||||
assert bucket.getMarker() == null;
|
assert bucket.getMarker() == null;
|
||||||
|
|
|
@ -85,7 +85,6 @@
|
||||||
<url>http://jclouds.googlecode.com/svn/trunk/s3core/perftest</url>
|
<url>http://jclouds.googlecode.com/svn/trunk/s3core/perftest</url>
|
||||||
</scm>
|
</scm>
|
||||||
<build>
|
<build>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -32,8 +34,8 @@ import java.util.TreeMap;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.testng.ITestContext;
|
import org.jets3t.service.S3ServiceException;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Optional;
|
import org.testng.annotations.Optional;
|
||||||
import org.testng.annotations.Parameters;
|
import org.testng.annotations.Parameters;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -49,13 +51,14 @@ import com.amazon.s3.AWSAuthConnection;
|
||||||
public class AmazonPerformanceLiveTest extends BasePerformance {
|
public class AmazonPerformanceLiveTest extends BasePerformance {
|
||||||
private AWSAuthConnection amzClient;
|
private AWSAuthConnection amzClient;
|
||||||
|
|
||||||
@Override
|
@BeforeClass(inheritGroups = false, groups = { "live" })
|
||||||
@BeforeTest
|
|
||||||
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID, S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID, S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
||||||
protected void setUpCredentials(@Optional String AWSAccessKeyId,
|
public void setUpJetS3t(@Optional String AWSAccessKeyId, @Optional String AWSSecretAccessKey)
|
||||||
@Optional String AWSSecretAccessKey, ITestContext context) throws Exception {
|
throws S3ServiceException {
|
||||||
super.setUpCredentials(AWSAccessKeyId, AWSSecretAccessKey, context);
|
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId : sysAWSAccessKeyId;
|
||||||
amzClient = new AWSAuthConnection(AWSAccessKeyId, AWSSecretAccessKey, false);
|
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey : sysAWSSecretAccessKey;
|
||||||
|
amzClient = new AWSAuthConnection(checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"),
|
||||||
|
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,8 @@ package org.jclouds.aws.s3;
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
@ -32,8 +34,9 @@ import org.jets3t.service.S3Service;
|
||||||
import org.jets3t.service.S3ServiceException;
|
import org.jets3t.service.S3ServiceException;
|
||||||
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
|
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
|
||||||
import org.jets3t.service.security.AWSCredentials;
|
import org.jets3t.service.security.AWSCredentials;
|
||||||
import org.testng.ITestContext;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.Optional;
|
||||||
|
import org.testng.annotations.Parameters;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,13 +48,14 @@ import org.testng.annotations.Test;
|
||||||
public class Jets3tPerformanceLiveTest extends BasePerformance {
|
public class Jets3tPerformanceLiveTest extends BasePerformance {
|
||||||
private S3Service jetClient;
|
private S3Service jetClient;
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeClass(inheritGroups = false, groups = { "live" })
|
||||||
public void setUpJetS3t(ITestContext testContext) throws S3ServiceException {
|
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID, S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
||||||
String AWSAccessKeyId = (String) testContext
|
public void setUpJetS3t(@Optional String AWSAccessKeyId, @Optional String AWSSecretAccessKey)
|
||||||
.getAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
throws S3ServiceException {
|
||||||
String AWSSecretAccessKey = (String) testContext
|
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId : sysAWSAccessKeyId;
|
||||||
.getAttribute(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey : sysAWSSecretAccessKey;
|
||||||
jetClient = new RestS3Service(new AWSCredentials(AWSAccessKeyId, AWSSecretAccessKey));
|
jetClient = new RestS3Service(new AWSCredentials(checkNotNull(AWSAccessKeyId,
|
||||||
|
"AWSAccessKeyId"), checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
under the License.
|
under the License.
|
||||||
====================================================================
|
====================================================================
|
||||||
====
|
====
|
||||||
This samples uses the Google App Engine for Java SDK located at http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.0.zip
|
This samples uses the Google App Engine for Java SDK located at http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.1.zip
|
||||||
|
|
||||||
Please unzip the above file and modify your maven settings.xml like below before attempting to run 'mvn install'
|
Please unzip the above file and modify your maven settings.xml like below before attempting to run 'mvn -Plive install'
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
<id>appengine</id>
|
<id>appengine</id>
|
||||||
|
@ -31,7 +31,7 @@ Please unzip the above file and modify your maven settings.xml like below before
|
||||||
<activeByDefault>true</activeByDefault>
|
<activeByDefault>true</activeByDefault>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<appengine.home>/path/to/appengine-java-sdk-1.2.0</appengine.home>
|
<appengine.home>/path/to/appengine-java-sdk-1.2.1</appengine.home>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
|
|
|
@ -23,22 +23,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.samples.googleappengine;
|
package org.jclouds.samples.googleappengine;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import java.io.IOException;
|
||||||
import com.google.inject.Singleton;
|
import java.io.Writer;
|
||||||
import org.jclouds.aws.s3.S3Context;
|
import java.util.List;
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
import org.jclouds.aws.s3.S3Context;
|
||||||
import java.util.List;
|
import org.jclouds.aws.s3.AWSResponseException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows an example of how to use @{link S3Connection} injected with Guice.
|
* Shows an example of how to use @{link S3Connection} injected with Guice.
|
||||||
|
@ -49,6 +51,17 @@ import java.util.concurrent.TimeUnit;
|
||||||
public class JCloudsServlet extends HttpServlet {
|
public class JCloudsServlet extends HttpServlet {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final static String className;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests google's behaviour in static context
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
StackTraceElement[] sTrace = new Exception().getStackTrace();
|
||||||
|
// sTrace[0] will be always there
|
||||||
|
className = sTrace[0].getClassName();
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
S3Context context;
|
S3Context context;
|
||||||
|
|
||||||
|
@ -57,22 +70,21 @@ public class JCloudsServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest httpServletRequest,
|
protected void doGet(HttpServletRequest httpServletRequest,
|
||||||
HttpServletResponse httpServletResponse) throws ServletException,
|
HttpServletResponse httpServletResponse) throws ServletException, IOException {
|
||||||
IOException {
|
|
||||||
httpServletResponse.setContentType("text/plain");
|
httpServletResponse.setContentType("text/plain");
|
||||||
Writer writer = httpServletResponse.getWriter();
|
Writer writer = httpServletResponse.getWriter();
|
||||||
|
writer.write(className + "\n");
|
||||||
try {
|
try {
|
||||||
List<S3Bucket.Metadata> myBuckets = context.getConnection()
|
List<S3Bucket.Metadata> myBuckets = context.getConnection().listOwnedBuckets().get(10,
|
||||||
.listOwnedBuckets().get(10, TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
writer.write("List:\n");
|
writer.write("List:\n");
|
||||||
for (S3Bucket.Metadata bucket : myBuckets) {
|
for (S3Bucket.Metadata bucket : myBuckets) {
|
||||||
writer.write(String.format(" %1$s", bucket));
|
writer.write(String.format(" %1$s", bucket));
|
||||||
try {
|
try {
|
||||||
writer.write(String.format(": %1$s entries%n", context
|
writer.write(String.format(": %1$s entries%n", context.createInputStreamMap(
|
||||||
.createInputStreamMap(bucket.getName()).size()));
|
bucket.getName()).size()));
|
||||||
} catch (S3ResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
String message = String.format(
|
String message = String.format(": unable to list entries due to: %1$s%n", e
|
||||||
": unable to list entries due to: %1$s%n", e
|
|
||||||
.getError().getCode());
|
.getError().getCode());
|
||||||
writer.write(message);
|
writer.write(message);
|
||||||
logger.warn(e, "message");
|
logger.warn(e, "message");
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.http.options;
|
package org.jclouds.http.options;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
|
@ -58,6 +62,14 @@ public class BaseHttpRequestOptions implements HttpRequestOptions {
|
||||||
headers.put(key, value);
|
headers.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void encodeAndReplaceParameter(String parameter, String value) {
|
||||||
|
try {
|
||||||
|
parameters.put(parameter, URLEncoder.encode(checkNotNull(value, parameter), "UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new IllegalArgumentException("bad encoding on " + parameter + ": " + value, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue