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.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
package org.jclouds.aws.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -33,7 +33,7 @@ import java.util.Map;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class S3Error {
|
||||
public class AWSError {
|
||||
private String code;
|
||||
private String message;
|
||||
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 org.apache.commons.io.IOUtils;
|
||||
import org.bouncycastle.crypto.Digest;
|
||||
import org.bouncycastle.crypto.digests.MD5Digest;
|
||||
import org.bouncycastle.crypto.digests.SHA1Digest;
|
||||
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||
import org.bouncycastle.crypto.macs.HMac;
|
||||
import org.bouncycastle.crypto.params.KeyParameter;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
@ -52,9 +54,14 @@ public class AWSUtils extends Utils {
|
|||
return bytes;
|
||||
}
|
||||
|
||||
public static String hmacSha1Base64(String toEncode, byte[] key)
|
||||
public static String hmacSha256Base64(String toEncode, byte[] key)
|
||||
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[] plainBytes = toEncode.getBytes();
|
||||
byte[] keyBytes = key;
|
||||
|
@ -64,6 +71,12 @@ public class AWSUtils extends Utils {
|
|||
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,
|
||||
NoSuchProviderException, InvalidKeyException, UnsupportedEncodingException {
|
||||
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.TimeoutException;
|
||||
|
||||
import org.jclouds.aws.s3.S3ResponseException;
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class DeleteBucket extends S3FutureCommand<Boolean> {
|
|||
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||
if (e.getCause() != null
|
||||
&& e.getCause() instanceof HttpResponseException) {
|
||||
S3ResponseException responseException = (S3ResponseException) e
|
||||
AWSResponseException responseException = (AWSResponseException) e
|
||||
.getCause();
|
||||
if (responseException.getResponse().getStatusCode() == 404) {
|
||||
return true;
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
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.options.GetObjectOptions;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
|
@ -40,20 +40,16 @@ import com.google.inject.assistedinject.Assisted;
|
|||
import com.google.inject.name.Named;
|
||||
|
||||
/**
|
||||
* Retrieves the S3Object associated with the Key or {@link S3Object#NOT_FOUND}
|
||||
* if not available;
|
||||
* Retrieves the S3Object associated with the Key or {@link S3Object#NOT_FOUND} if not available;
|
||||
*
|
||||
* <p/>
|
||||
* To use GET, you must have READ access to the object. If READ access is
|
||||
* granted to the anonymous user, you can request the object without an
|
||||
* authorization header.
|
||||
* To use GET, you must have READ access to the object. If READ access is granted to the anonymous
|
||||
* user, you can request the object without an authorization header.
|
||||
* <p />
|
||||
* <p/>
|
||||
* This command allows you to specify {@link GetObjectOptions} to control
|
||||
* delivery of content.
|
||||
* This command allows you to specify {@link GetObjectOptions} to control delivery of content.
|
||||
*
|
||||
* <h2>Note</h2> If you specify any of the below options, you will receive
|
||||
* partial content:
|
||||
* <h2>Note</h2> If you specify any of the below options, you will receive partial content:
|
||||
* <ul>
|
||||
* <li>{@link GetObjectOptions#range}</li>
|
||||
* <li>{@link GetObjectOptions#startAt}</li>
|
||||
|
@ -61,15 +57,16 @@ import com.google.inject.name.Named;
|
|||
* </ul>
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public class GetObject extends S3FutureCommand<S3Object> {
|
||||
|
||||
@Inject
|
||||
public GetObject(@Named("jclouds.http.address") String amazonHost,
|
||||
ParseObjectFromHeadersAndHttpContent callable,
|
||||
@Assisted("bucketName") String s3Bucket,
|
||||
ParseObjectFromHeadersAndHttpContent callable, @Assisted("bucketName") String s3Bucket,
|
||||
@Assisted("key") String key, @Assisted GetObjectOptions options) {
|
||||
super("GET", "/" + checkNotNull(key), callable, amazonHost, s3Bucket);
|
||||
this.getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
||||
|
@ -87,9 +84,8 @@ public class GetObject extends S3FutureCommand<S3Object> {
|
|||
|
||||
@VisibleForTesting
|
||||
S3Object attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||
if (e.getCause() != null && e.getCause() instanceof S3ResponseException) {
|
||||
S3ResponseException responseException = (S3ResponseException) e
|
||||
.getCause();
|
||||
if (e.getCause() != null && e.getCause() instanceof AWSResponseException) {
|
||||
AWSResponseException responseException = (AWSResponseException) e.getCause();
|
||||
if ("NoSuchKey".equals(responseException.getError().getCode())) {
|
||||
return S3Object.NOT_FOUND;
|
||||
}
|
||||
|
@ -98,8 +94,8 @@ public class GetObject extends S3FutureCommand<S3Object> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public S3Object get(long l, TimeUnit timeUnit) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
public S3Object get(long l, TimeUnit timeUnit) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
try {
|
||||
return super.get(l, timeUnit);
|
||||
} catch (ExecutionException e) {
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
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.domain.S3Bucket;
|
||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||
|
@ -40,15 +40,15 @@ import com.google.inject.assistedinject.Assisted;
|
|||
import com.google.inject.name.Named;
|
||||
|
||||
/**
|
||||
* A GET request operation using a bucket URI lists information about the
|
||||
* objects in the bucket.
|
||||
* A GET request operation using a bucket URI lists information about the objects in the bucket.
|
||||
* <p />
|
||||
* To list the keys of a bucket, you must have READ access to the bucket.
|
||||
* <p/>
|
||||
* List output is controllable via {@link 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
|
||||
*
|
||||
|
@ -59,10 +59,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
|||
public ListBucket(@Named("jclouds.http.address") String amazonHost,
|
||||
ParseSax<S3Bucket> bucketParser, @Assisted String bucket,
|
||||
@Assisted ListBucketOptions options) {
|
||||
super("GET", "/" + options.buildQueryString(), bucketParser,
|
||||
amazonHost, bucket);
|
||||
ListBucketHandler handler = (ListBucketHandler) bucketParser
|
||||
.getHandler();
|
||||
super("GET", "/" + options.buildQueryString(), bucketParser, amazonHost, bucket);
|
||||
ListBucketHandler handler = (ListBucketHandler) bucketParser.getHandler();
|
||||
handler.setBucketName(bucket);
|
||||
}
|
||||
|
||||
|
@ -77,10 +75,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
|||
|
||||
@VisibleForTesting
|
||||
S3Bucket attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||
if (e.getCause() != null
|
||||
&& e.getCause() instanceof HttpResponseException) {
|
||||
S3ResponseException responseException = (S3ResponseException) e
|
||||
.getCause();
|
||||
if (e.getCause() != null && e.getCause() instanceof HttpResponseException) {
|
||||
AWSResponseException responseException = (AWSResponseException) e.getCause();
|
||||
if ("NoSuchBucket".equals(responseException.getError().getCode())) {
|
||||
return S3Bucket.NOT_FOUND;
|
||||
}
|
||||
|
@ -89,8 +85,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public S3Bucket get(long l, TimeUnit timeUnit) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
public S3Bucket get(long l, TimeUnit timeUnit) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
try {
|
||||
return super.get(l, timeUnit);
|
||||
} catch (ExecutionException e) {
|
||||
|
|
|
@ -30,7 +30,7 @@ import javax.annotation.Resource;
|
|||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
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.http.HttpConstants;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
|
@ -74,9 +74,9 @@ public class LiveS3ConnectionModule extends AbstractModule {
|
|||
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class).to(
|
||||
CloseContentAndSetExceptionHandler.class).in(Scopes.SINGLETON);
|
||||
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class).to(
|
||||
ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||
ParseAWSErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class).to(
|
||||
ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||
ParseAWSErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||
requestInjection(this);
|
||||
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;
|
||||
|
||||
import org.jclouds.command.pool.PoolConstants;
|
||||
import org.jclouds.http.HttpConstants;
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
|
||||
/**
|
||||
* Configuration properties and constants used in S3 connections.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
|
|
|
@ -25,9 +25,10 @@ package org.jclouds.aws.s3.xml;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
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.xml.ErrorHandler;
|
||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -88,7 +89,7 @@ public class S3ParserFactory {
|
|||
}
|
||||
|
||||
@Inject
|
||||
private GenericParseFactory<S3Error> parseErrorFactory;
|
||||
private GenericParseFactory<AWSError> parseErrorFactory;
|
||||
|
||||
@Inject
|
||||
Provider<ErrorHandler> errorHandlerProvider;
|
||||
|
@ -96,7 +97,7 @@ public class S3ParserFactory {
|
|||
/**
|
||||
* @return a parser used to handle error conditions.
|
||||
*/
|
||||
public ParseSax<S3Error> createErrorParser() {
|
||||
public ParseSax<AWSError> createErrorParser() {
|
||||
return parseErrorFactory.create(errorHandlerProvider.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@ package org.jclouds.aws.s3.xml.config;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
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.xml.CopyObjectHandler;
|
||||
import org.jclouds.aws.s3.xml.ErrorHandler;
|
||||
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||
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.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<S3Error>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>>() {
|
||||
private final TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>>() {
|
||||
};
|
||||
|
||||
@Override
|
||||
|
@ -63,14 +63,13 @@ public class S3ParserModule extends AbstractModule {
|
|||
}
|
||||
|
||||
private void bindParserImplementationsToReturnTypes() {
|
||||
bind(
|
||||
new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
|
||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
|
||||
}).to(ListAllMyBucketsHandler.class);
|
||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Bucket>>() {
|
||||
}).to(ListBucketHandler.class);
|
||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Object.Metadata>>() {
|
||||
}).to(CopyObjectHandler.class);
|
||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Error>>() {
|
||||
bind(new TypeLiteral<ParseSax.HandlerWithResult<AWSError>>() {
|
||||
}).to(ErrorHandler.class);
|
||||
}
|
||||
|
||||
|
@ -80,16 +79,14 @@ public class S3ParserModule extends AbstractModule {
|
|||
new TypeLiteral<ParseSax<List<S3Bucket.Metadata>>>() {
|
||||
}));
|
||||
bind(bucketTypeLiteral).toProvider(
|
||||
FactoryProvider.newFactory(bucketTypeLiteral,
|
||||
new TypeLiteral<ParseSax<S3Bucket>>() {
|
||||
FactoryProvider.newFactory(bucketTypeLiteral, new TypeLiteral<ParseSax<S3Bucket>>() {
|
||||
}));
|
||||
bind(objectMetadataTypeLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectMetadataTypeLiteral,
|
||||
new TypeLiteral<ParseSax<S3Object.Metadata>>() {
|
||||
}));
|
||||
bind(errorTypeLiteral).toProvider(
|
||||
FactoryProvider.newFactory(errorTypeLiteral,
|
||||
new TypeLiteral<ParseSax<S3Error>>() {
|
||||
FactoryProvider.newFactory(errorTypeLiteral, new TypeLiteral<ParseSax<AWSError>>() {
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -130,9 +130,9 @@ public class S3IntegrationTest {
|
|||
protected String bucketPrefix = (System.getProperty("user.name") + "." + this.getClass()
|
||||
.getSimpleName()).toLowerCase();
|
||||
|
||||
private static final String sysAWSAccessKeyId = System
|
||||
protected static final String sysAWSAccessKeyId = System
|
||||
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
||||
private static final String sysAWSSecretAccessKey = System
|
||||
protected static final String sysAWSSecretAccessKey = System
|
||||
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||
|
||||
@BeforeClass(inheritGroups = false, groups = { "integration", "live" })
|
||||
|
|
|
@ -304,34 +304,43 @@ public class StubS3Connection implements S3Connection {
|
|||
contents.remove(lastMarkerMetadata);
|
||||
returnVal.setMarker(marker);
|
||||
}
|
||||
try {
|
||||
|
||||
if (options.getPrefix() != null) {
|
||||
contents = Sets.newTreeSet(Iterables.filter(contents,
|
||||
new Predicate<S3Object.Metadata>() {
|
||||
|
||||
public boolean apply(S3Object.Metadata o) {
|
||||
try {
|
||||
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) {
|
||||
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(options
|
||||
.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null,
|
||||
URLDecoder.decode(options.getDelimiter())));
|
||||
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(
|
||||
options.getPrefix() != null ? URLDecoder.decode(options.getPrefix(),
|
||||
"UTF-8") : null, URLDecoder.decode(options.getDelimiter(),
|
||||
"UTF-8")));
|
||||
Set<String> commonPrefixes = iterable != null ? Sets.newTreeSet(iterable)
|
||||
: new HashSet<String>();
|
||||
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
|
||||
|
||||
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(options
|
||||
.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null,
|
||||
URLDecoder.decode(options.getDelimiter()))));
|
||||
.getPrefix() != null ? URLDecoder.decode(options.getPrefix(), "UTF-8")
|
||||
: null, URLDecoder.decode(options.getDelimiter(), "UTF-8"))));
|
||||
|
||||
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) {
|
||||
contents = firstSliceOfSize(contents, 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);
|
||||
return Sets.newTreeSet(slices.get(0));
|
||||
}
|
||||
|
|
|
@ -23,34 +23,31 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all bucketExists commands.
|
||||
* <p/>
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||
* in parallel.
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.BucketExistsIntegrationTest")
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.BucketExistsIntegrationTest")
|
||||
public class BucketExistsIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test
|
||||
void bucketDoesntExist() throws Exception {
|
||||
String bucketName= bucketPrefix+"be";
|
||||
String bucketName = bucketPrefix + "be";
|
||||
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bucketExists() throws Exception {
|
||||
String bucketName= bucketPrefix+"bde";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
String bucketName = bucketPrefix + "bde";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,30 +23,32 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*;
|
||||
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 org.jclouds.http.HttpResponseException;
|
||||
import org.joda.time.DateTime;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
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.
|
||||
* <p/>
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||
* in parallel.
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -55,7 +57,7 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
String sourceKey = "apples";
|
||||
String destinationKey = "pears";
|
||||
|
||||
@Test(groups = {"integration","live"})
|
||||
@Test(groups = { "integration", "live" })
|
||||
void testCopyObject() throws Exception {
|
||||
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
@ -63,126 +65,116 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey).get(10, TimeUnit.SECONDS);
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void addToBucketAndValidate(String bucketName, String sourceKey)
|
||||
throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
addObjectToBucket(bucketName, sourceKey);
|
||||
validateContent(bucketName, sourceKey);
|
||||
}
|
||||
|
||||
@Test(enabled= false, groups = {"integration","live"})//TODO: fails on linux and windows
|
||||
void testCopyIfModifiedSince() 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, 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,
|
||||
@Test(enabled = false, groups = { "integration", "live" })
|
||||
// TODO: fails on linux and windows
|
||||
void testCopyIfModifiedSince() 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, ifSourceMd5Matches(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||
ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
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(groups = {"integration","live"})
|
||||
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
|
||||
@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, ifSourceMd5DoesntMatch(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||
ifSourceUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
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 testCopyWithMetadata() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
@Test(groups = { "integration", "live" })
|
||||
void testCopyIfMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
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";
|
||||
|
||||
|
@ -192,14 +184,13 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, overrideMetadataWith(metadata)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket, destinationKey,
|
||||
overrideMetadataWith(metadata)).get(10, TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
|
||||
destinationKey).get(10, TimeUnit.SECONDS);
|
||||
S3Object.Metadata objectMeta = client.headObject(destinationBucket, destinationKey).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(objectMeta.getUserMetadata(), metadata);
|
||||
}
|
||||
|
|
|
@ -23,24 +23,24 @@
|
|||
*/
|
||||
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 org.testng.annotations.Test;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
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.
|
||||
* <p/>
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||
* in parallel.
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.DeleteObjectIntegrationTest")
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.DeleteObjectIntegrationTest")
|
||||
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
|
@ -48,8 +48,7 @@ public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
|||
String bucketName = bucketPrefix + "donf";
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
addObjectToBucket(bucketName, "test");
|
||||
assert client.deleteObject(bucketName, "test")
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assert client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -58,9 +57,8 @@ public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
|||
try {
|
||||
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
assert e.getCause() instanceof S3ResponseException;
|
||||
assertEquals(((S3ResponseException) e.getCause()).getResponse()
|
||||
.getStatusCode(), 404);
|
||||
assert e.getCause() instanceof AWSResponseException;
|
||||
assertEquals(((AWSResponseException) e.getCause()).getResponse().getStatusCode(), 404);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,8 +67,7 @@ public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
|||
String bucketName = bucketPrefix + "do";
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
addObjectToBucket(bucketName, "test");
|
||||
assert client.deleteObject(bucketName, "test")
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assert client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
|
||||
|
||||
}
|
||||
|
|
|
@ -23,35 +23,41 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import org.jclouds.aws.s3.S3ResponseException;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
|
||||
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 static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5DoesntMatch;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5Matches;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifModifiedSince;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifUnmodifiedSince;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.range;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.startAt;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.tail;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
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.
|
||||
* <p/>
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||
* in parallel.
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.GetObjectIntegrationTest")
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.GetObjectIntegrationTest")
|
||||
public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test(enabled=false )//TODO: fails on linux and windows
|
||||
void testGetIfModifiedSince() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
@Test(enabled = false)
|
||||
// TODO: fails on linux and windows
|
||||
void testGetIfModifiedSince() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
|
@ -59,13 +65,11 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
addObjectAndValidateContent(bucketName, key);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.getObject(bucketName, key, ifModifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifModifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifModifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -78,9 +82,10 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
|
||||
}
|
||||
|
||||
@Test(enabled=false )//TODO: fails on linux and windows
|
||||
void testGetIfUnmodifiedSince() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
@Test(enabled = false)
|
||||
// TODO: fails on linux and windows
|
||||
void testGetIfUnmodifiedSince() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
|
@ -88,13 +93,11 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
addObjectAndValidateContent(bucketName, key);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -108,20 +111,18 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testGetIfMatch() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
void testGetIfMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
|
||||
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -134,20 +135,18 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testGetIfNoneMatch() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
void testGetIfNoneMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
|
||||
client.getObject(bucketName, key, ifMd5DoesntMatch(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifMd5DoesntMatch(badMd5)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifMd5DoesntMatch(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
client.getObject(bucketName, key, ifMd5DoesntMatch(goodMd5)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -160,71 +159,65 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testGetRange() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
void testGetRange() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
|
||||
.substring(0, 6));
|
||||
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING.substring(0, 6));
|
||||
|
||||
S3Object object2 = client.getObject(bucketName, key,
|
||||
range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
|
||||
.substring(6, TEST_STRING.length()));
|
||||
S3Object object2 = client.getObject(bucketName, key, range(6, TEST_STRING.length())).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING.substring(6,
|
||||
TEST_STRING.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
void testGetTwoRanges() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object = client.getObject(bucketName, key,
|
||||
range(0, 5).range(6, TEST_STRING.length())).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
range(0, 5).range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetTail() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
void testGetTail() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object = client.getObject(bucketName, key, tail(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||
.substring(TEST_STRING.length() - 5));
|
||||
S3Object object = client.getObject(bucketName, key, tail(5)).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING.substring(TEST_STRING
|
||||
.length() - 5));
|
||||
assertEquals(object.getContentLength(), 5);
|
||||
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStartAt() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
void testGetStartAt() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||
.substring(5, TEST_STRING.length()));
|
||||
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING.substring(5, TEST_STRING
|
||||
.length()));
|
||||
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
||||
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||
}
|
||||
|
||||
private void addObjectAndValidateContent(String sourcebucketName, String sourceKey)
|
||||
throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
addObjectToBucket(sourcebucketName, sourceKey);
|
||||
validateContent(sourcebucketName, sourceKey);
|
||||
}
|
||||
|
|
|
@ -23,32 +23,27 @@
|
|||
*/
|
||||
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.assertNotNull;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
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.
|
||||
* <p/>
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||
* in parallel.
|
||||
* Each test uses a different bucket name, so it should be perfectly fine to run in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -59,38 +54,31 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
|||
|
||||
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
|
||||
|
||||
return new Object[][]{
|
||||
{"file", "text/xml", new File("pom.xml"), realObject},
|
||||
{"string", "text/xml", realObject, realObject},
|
||||
{"bytes", "application/octet-stream", realObject.getBytes(),
|
||||
realObject}};
|
||||
return new Object[][] { { "file", "text/xml", new File("pom.xml"), realObject },
|
||||
{ "string", "text/xml", realObject, realObject },
|
||||
{ "bytes", "application/octet-stream", realObject.getBytes(), realObject } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "putTests", groups = {"integration", "live"})
|
||||
void testPutObject(String key, String type, Object content,
|
||||
Object realObject) throws Exception {
|
||||
@Test(dataProvider = "putTests", groups = { "integration", "live" })
|
||||
void testPutObject(String key, String type, Object content, Object realObject) throws Exception {
|
||||
String bucketName = bucketPrefix + "tpo";
|
||||
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
context.createS3ObjectMap(bucketName).clear();
|
||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
||||
.getContents().size(), 0);
|
||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS).getContents().size(), 0);
|
||||
S3Object object = new S3Object(key);
|
||||
object.getMetadata().setContentType(type);
|
||||
object.setData(content);
|
||||
if (content instanceof InputStream) {
|
||||
object.generateMd5();
|
||||
}
|
||||
assertNotNull(client.putObject(bucketName, object).get(10,
|
||||
TimeUnit.SECONDS));
|
||||
object = client.getObject(bucketName, object.getKey()).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(client.putObject(bucketName, object).get(10, TimeUnit.SECONDS));
|
||||
object = client.getObject(bucketName, object.getKey()).get(10, TimeUnit.SECONDS);
|
||||
String returnedString = S3Utils.getContentAsStringAndClose(object);
|
||||
assertEquals(returnedString, realObject);
|
||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
||||
.getContents().size(), 1);
|
||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS).getContents().size(), 1);
|
||||
}
|
||||
|
||||
@Test(groups = {"integration", "live"})
|
||||
@Test(groups = { "integration", "live" })
|
||||
void testMetadata() throws Exception {
|
||||
String bucketName = bucketPrefix + "tmd";
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
|
@ -101,27 +89,24 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
|||
object.getMetadata().setContentType("text/plain");
|
||||
object.getMetadata().setContentEncoding("x-compress");
|
||||
object.getMetadata().setSize(TEST_STRING.length());
|
||||
object.getMetadata().setContentDisposition(
|
||||
"attachment; filename=hello.txt");
|
||||
object.getMetadata().getUserMetadata().put(
|
||||
S3Headers.USER_METADATA_PREFIX + "adrian", "powderpuff");
|
||||
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||
object.getMetadata().getUserMetadata().put(S3Headers.USER_METADATA_PREFIX + "adrian",
|
||||
"powderpuff");
|
||||
object.getMetadata().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
|
||||
|
||||
addObjectToBucket(bucketName, object);
|
||||
S3Object newObject = validateContent(bucketName, key);
|
||||
|
||||
// TODO.. why does this come back as binary/octetstring
|
||||
assertEquals(newObject.getMetadata().getContentType(),
|
||||
"binary/octet-stream");
|
||||
assertEquals(newObject.getMetadata().getContentType(), "binary/octet-stream");
|
||||
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||
"attachment; filename=hello.txt");
|
||||
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
|
||||
assertEquals(newObject.getMetadata().getUserMetadata().values()
|
||||
.iterator().next(), "powderpuff");
|
||||
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
|
||||
.getBytes()));
|
||||
assertEquals(newObject.getMetadata().getUserMetadata().values().iterator().next(),
|
||||
"powderpuff");
|
||||
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING.getBytes()));
|
||||
}
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ import com.google.inject.Guice;
|
|||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
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.http.HttpResponseHandler;
|
||||
import org.jclouds.http.annotation.ClientErrorHandler;
|
||||
|
@ -46,37 +46,23 @@ import org.testng.annotations.Test;
|
|||
@Test(groups = "unit", testName = "s3.S3ContextModuleTest")
|
||||
public class S3ContextModuleTest {
|
||||
|
||||
Injector injector = null;
|
||||
|
||||
@BeforeMethod
|
||||
void setUpInjector() {
|
||||
injector = Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"localhost");
|
||||
bindConstant().annotatedWith(
|
||||
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("localhost");
|
||||
bindConstant().annotatedWith(
|
||||
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
||||
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to(
|
||||
"localhost");
|
||||
bindConstant().annotatedWith(
|
||||
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
||||
bindConstant().annotatedWith(
|
||||
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
|
||||
"false");
|
||||
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
||||
"localhost");
|
||||
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
||||
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to("false");
|
||||
super.configure();
|
||||
}
|
||||
}, new JavaUrlHttpFutureCommandClientModule());
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
void tearDownInjector() {
|
||||
injector = null;
|
||||
}
|
||||
|
||||
private static class ClientErrorHandlerTest {
|
||||
@Inject
|
||||
@ClientErrorHandler
|
||||
|
@ -85,10 +71,8 @@ public class S3ContextModuleTest {
|
|||
|
||||
@Test
|
||||
void testClientErrorHandler() {
|
||||
ClientErrorHandlerTest error = injector
|
||||
.getInstance(ClientErrorHandlerTest.class);
|
||||
assertEquals(error.errorHandler.getClass(),
|
||||
ParseS3ErrorFromXmlContent.class);
|
||||
ClientErrorHandlerTest error = createInjector().getInstance(ClientErrorHandlerTest.class);
|
||||
assertEquals(error.errorHandler.getClass(), ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
private static class ServerErrorHandlerTest {
|
||||
|
@ -99,10 +83,8 @@ public class S3ContextModuleTest {
|
|||
|
||||
@Test
|
||||
void testServerErrorHandler() {
|
||||
ServerErrorHandlerTest error = injector
|
||||
.getInstance(ServerErrorHandlerTest.class);
|
||||
assertEquals(error.errorHandler.getClass(),
|
||||
ParseS3ErrorFromXmlContent.class);
|
||||
ServerErrorHandlerTest error = createInjector().getInstance(ServerErrorHandlerTest.class);
|
||||
assertEquals(error.errorHandler.getClass(), ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
private static class RedirectHandlerTest {
|
||||
|
@ -113,10 +95,8 @@ public class S3ContextModuleTest {
|
|||
|
||||
@Test
|
||||
void testRedirectHandler() {
|
||||
RedirectHandlerTest error = injector
|
||||
.getInstance(RedirectHandlerTest.class);
|
||||
assertEquals(error.errorHandler.getClass(),
|
||||
CloseContentAndSetExceptionHandler.class);
|
||||
RedirectHandlerTest error = createInjector().getInstance(RedirectHandlerTest.class);
|
||||
assertEquals(error.errorHandler.getClass(), CloseContentAndSetExceptionHandler.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -82,6 +82,7 @@ public class BaseS3MapTest {
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
BaseS3Map<String> map = new MockBaseS3Map();
|
||||
|
@ -101,6 +102,7 @@ public class BaseS3MapTest {
|
|||
assert !objects.contains(S3Object.NOT_FOUND);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
BaseS3Map<String> map = new MockBaseS3Map();
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
package org.jclouds.aws.s3.xml;
|
||||
|
||||
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.commands.callables.xml.ParseSax;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
@ -37,8 +37,8 @@ public class ErrorHandlerTest extends BaseHandlerTest {
|
|||
@Test
|
||||
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader()
|
||||
throws HttpException {
|
||||
ParseSax<S3Error> parser = parserFactory.createErrorParser();
|
||||
S3Error error = parser
|
||||
ParseSax<AWSError> parser = parserFactory.createErrorParser();
|
||||
AWSError error = parser
|
||||
.parse(IOUtils
|
||||
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
|
||||
assertEquals(error.getCode(), "NotImplemented");
|
||||
|
|
|
@ -23,11 +23,12 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -35,20 +36,19 @@ import org.testng.annotations.Test;
|
|||
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 listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
|
||||
ParseSax<S3Bucket> parser;
|
||||
|
||||
@BeforeMethod
|
||||
void setUpParser() {
|
||||
parser = parserFactory.createListBucketParser();
|
||||
ParseSax<S3Bucket> createParser() {
|
||||
ParseSax<S3Bucket> parser = parserFactory.createListBucketParser();
|
||||
((ListBucketHandler) parser.getHandler()).setBucketName("test");
|
||||
return parser;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash()
|
||||
throws HttpException {
|
||||
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash() throws HttpException {
|
||||
|
||||
S3Bucket bucket = parser.parse(IOUtils
|
||||
.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
|
||||
S3Bucket bucket = createParser().parse(
|
||||
IOUtils.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
|
||||
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
|
||||
assertEquals(bucket.getDelimiter(), "/");
|
||||
assert bucket.getMarker() == null;
|
||||
|
@ -57,8 +57,7 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
|
|||
@Test
|
||||
public void testListMyBucketsWithPrefixAppsSlash() throws HttpException {
|
||||
|
||||
S3Bucket bucket = parser.parse(IOUtils
|
||||
.toInputStream(listBucketWithPrefixAppsSlash));
|
||||
S3Bucket bucket = createParser().parse(IOUtils.toInputStream(listBucketWithPrefixAppsSlash));
|
||||
assertEquals(bucket.getPrefix(), "apps/");
|
||||
assertEquals(bucket.getMaxKeys(), 1000);
|
||||
assert bucket.getMarker() == null;
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
<url>http://jclouds.googlecode.com/svn/trunk/s3core/perftest</url>
|
||||
</scm>
|
||||
<build>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
@ -32,8 +34,8 @@ import java.util.TreeMap;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.jets3t.service.S3ServiceException;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Optional;
|
||||
import org.testng.annotations.Parameters;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -49,13 +51,14 @@ import com.amazon.s3.AWSAuthConnection;
|
|||
public class AmazonPerformanceLiveTest extends BasePerformance {
|
||||
private AWSAuthConnection amzClient;
|
||||
|
||||
@Override
|
||||
@BeforeTest
|
||||
@BeforeClass(inheritGroups = false, groups = { "live" })
|
||||
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID, S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
||||
protected void setUpCredentials(@Optional String AWSAccessKeyId,
|
||||
@Optional String AWSSecretAccessKey, ITestContext context) throws Exception {
|
||||
super.setUpCredentials(AWSAccessKeyId, AWSSecretAccessKey, context);
|
||||
amzClient = new AWSAuthConnection(AWSAccessKeyId, AWSSecretAccessKey, false);
|
||||
public void setUpJetS3t(@Optional String AWSAccessKeyId, @Optional String AWSSecretAccessKey)
|
||||
throws S3ServiceException {
|
||||
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId : sysAWSAccessKeyId;
|
||||
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey : sysAWSSecretAccessKey;
|
||||
amzClient = new AWSAuthConnection(checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"),
|
||||
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,6 +23,8 @@ package org.jclouds.aws.s3;
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -32,8 +34,9 @@ import org.jets3t.service.S3Service;
|
|||
import org.jets3t.service.S3ServiceException;
|
||||
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
|
||||
import org.jets3t.service.security.AWSCredentials;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Optional;
|
||||
import org.testng.annotations.Parameters;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
|
@ -45,13 +48,14 @@ import org.testng.annotations.Test;
|
|||
public class Jets3tPerformanceLiveTest extends BasePerformance {
|
||||
private S3Service jetClient;
|
||||
|
||||
@BeforeTest
|
||||
public void setUpJetS3t(ITestContext testContext) throws S3ServiceException {
|
||||
String AWSAccessKeyId = (String) testContext
|
||||
.getAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
||||
String AWSSecretAccessKey = (String) testContext
|
||||
.getAttribute(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||
jetClient = new RestS3Service(new AWSCredentials(AWSAccessKeyId, AWSSecretAccessKey));
|
||||
@BeforeClass(inheritGroups = false, groups = { "live" })
|
||||
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID, S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
||||
public void setUpJetS3t(@Optional String AWSAccessKeyId, @Optional String AWSSecretAccessKey)
|
||||
throws S3ServiceException {
|
||||
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId : sysAWSAccessKeyId;
|
||||
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey : sysAWSSecretAccessKey;
|
||||
jetClient = new RestS3Service(new AWSCredentials(checkNotNull(AWSAccessKeyId,
|
||||
"AWSAccessKeyId"), checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
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>
|
||||
<id>appengine</id>
|
||||
|
@ -31,7 +31,7 @@ Please unzip the above file and modify your maven settings.xml like below before
|
|||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<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>
|
||||
</profile>
|
||||
|
||||
|
|
|
@ -23,22 +23,24 @@
|
|||
*/
|
||||
package org.jclouds.samples.googleappengine;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.S3ResponseException;
|
||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||
import org.jclouds.logging.Logger;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.AWSResponseException;
|
||||
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.
|
||||
|
@ -49,6 +51,17 @@ import java.util.concurrent.TimeUnit;
|
|||
public class JCloudsServlet extends HttpServlet {
|
||||
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
|
||||
S3Context context;
|
||||
|
||||
|
@ -57,22 +70,21 @@ public class JCloudsServlet extends HttpServlet {
|
|||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest httpServletRequest,
|
||||
HttpServletResponse httpServletResponse) throws ServletException,
|
||||
IOException {
|
||||
HttpServletResponse httpServletResponse) throws ServletException, IOException {
|
||||
httpServletResponse.setContentType("text/plain");
|
||||
Writer writer = httpServletResponse.getWriter();
|
||||
writer.write(className + "\n");
|
||||
try {
|
||||
List<S3Bucket.Metadata> myBuckets = context.getConnection()
|
||||
.listOwnedBuckets().get(10, TimeUnit.SECONDS);
|
||||
List<S3Bucket.Metadata> myBuckets = context.getConnection().listOwnedBuckets().get(10,
|
||||
TimeUnit.SECONDS);
|
||||
writer.write("List:\n");
|
||||
for (S3Bucket.Metadata bucket : myBuckets) {
|
||||
writer.write(String.format(" %1$s", bucket));
|
||||
try {
|
||||
writer.write(String.format(": %1$s entries%n", context
|
||||
.createInputStreamMap(bucket.getName()).size()));
|
||||
} catch (S3ResponseException e) {
|
||||
String message = String.format(
|
||||
": unable to list entries due to: %1$s%n", e
|
||||
writer.write(String.format(": %1$s entries%n", context.createInputStreamMap(
|
||||
bucket.getName()).size()));
|
||||
} catch (AWSResponseException e) {
|
||||
String message = String.format(": unable to list entries due to: %1$s%n", e
|
||||
.getError().getCode());
|
||||
writer.write(message);
|
||||
logger.warn(e, "message");
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
*/
|
||||
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.Iterator;
|
||||
import java.util.SortedMap;
|
||||
|
@ -58,6 +62,14 @@ public class BaseHttpRequestOptions implements HttpRequestOptions {
|
|||
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}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue