Issue 134: switch to typed payloads for http requests and blob types

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2410 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-12-13 20:46:48 +00:00
parent 74be2180d3
commit 4a22f808d1
183 changed files with 1588 additions and 1527 deletions

View File

@ -64,7 +64,7 @@ public class ${clientName}AsyncClientTest extends RestClientTest<${clientName}As
assertRequestLineEquals(httpMethod, "TODO: insert expected request");
assertHeadersEqual(httpMethod, "");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseStatusesFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null);

View File

@ -36,7 +36,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.atmosonline.saas.binders.BindAtmosObjectToEntityAndMetadataToHeaders;
import org.jclouds.atmosonline.saas.binders.BindAtmosObjectToPayloadAndMetadataToHeaders;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
@ -117,7 +117,7 @@ public interface AtmosStorageAsyncClient {
@Consumes(MediaType.WILDCARD)
Future<URI> createFile(
@PathParam("parent") String parent,
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToEntityAndMetadataToHeaders.class) AtmosObject object);
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToPayloadAndMetadataToHeaders.class) AtmosObject object);
/**
* @see AtmosStorageClient#updateFile
@ -128,7 +128,7 @@ public interface AtmosStorageAsyncClient {
@Consumes(MediaType.WILDCARD)
Future<Void> updateFile(
@PathParam("parent") String parent,
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToEntityAndMetadataToHeaders.class) AtmosObject object);
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToPayloadAndMetadataToHeaders.class) AtmosObject object);
/**
* @see AtmosStorageClient#readFile

View File

@ -33,21 +33,21 @@ import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
public class BindAtmosObjectToEntityAndMetadataToHeaders implements Binder {
public class BindAtmosObjectToPayloadAndMetadataToHeaders implements Binder {
private final BindUserMetadataToHeaders metaBinder;
private final EncryptionService encryptionService;
@Inject
protected BindAtmosObjectToEntityAndMetadataToHeaders(BindUserMetadataToHeaders metaBinder,
protected BindAtmosObjectToPayloadAndMetadataToHeaders(BindUserMetadataToHeaders metaBinder,
EncryptionService encryptionService) {
this.metaBinder = metaBinder;
this.encryptionService = encryptionService;
}
public void bindToRequest(HttpRequest request, Object entity) {
AtmosObject object = (AtmosObject) entity;
public void bindToRequest(HttpRequest request, Object payload) {
AtmosObject object = (AtmosObject) payload;
request.setEntity(checkNotNull(object.getData(), "object.getContent()"));
request.setPayload(checkNotNull(object.getPayload(), "object.getPayload()"));
request.getHeaders().put(
HttpHeaders.CONTENT_TYPE,
checkNotNull(object.getContentMetadata().getContentType(),

View File

@ -35,8 +35,8 @@ import org.jclouds.rest.Binder;
public class BindUserMetadataToHeaders implements Binder {
public void bindToRequest(HttpRequest request, Object entity) {
UserMetadata md = (UserMetadata) checkNotNull(entity, "entity");
public void bindToRequest(HttpRequest request, Object payload) {
UserMetadata md = (UserMetadata) checkNotNull(payload, "payload");
if (md.getMetadata().size() > 0) {
String header = join(md.getMetadata());
request.getHeaders().put("x-emc-meta", header);

View File

@ -45,7 +45,7 @@ public class BlobToObject implements Function<Blob, AtmosObject> {
public AtmosObject apply(Blob from) {
AtmosObject object = blobMd2Object.apply(from.getMetadata());
object.setData(from.getData());
object.setPayload(from.getPayload());
object.setAllHeaders(from.getAllHeaders());
return object;
}

View File

@ -50,7 +50,7 @@ public class ObjectToBlob implements Function<AtmosObject, Blob> {
Blob blob = blobFactory.create(object2BlobMd.apply(from));
if (from.getContentMetadata().getContentLength() != null)
blob.setContentLength(from.getContentMetadata().getContentLength());
blob.setData(from.getData());
blob.setPayload(from.getPayload());
blob.setAllHeaders(from.getAllHeaders());
return blob;
}

View File

@ -31,9 +31,7 @@ import org.jclouds.atmosonline.saas.domain.MutableContentMetadata;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
import org.jclouds.atmosonline.saas.domain.internal.AtmosObjectImpl;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -57,28 +55,24 @@ public class AtmosObjectModule extends AbstractModule {
private static class AtmosObjectFactory implements AtmosObject.Factory {
@Inject
GenerateMD5Result generateMD5Result;
@Inject
GenerateMD5 generateMD5;
@Inject
CalculateSize calculateSize;
EncryptionService encryptionService;
@Inject
Provider<MutableContentMetadata> metadataProvider;
public AtmosObject create(MutableContentMetadata contentMetadata) {
return new AtmosObjectImpl(generateMD5Result, generateMD5, calculateSize,
contentMetadata != null ? contentMetadata : metadataProvider.get());
return new AtmosObjectImpl(encryptionService, contentMetadata != null ? contentMetadata
: metadataProvider.get());
}
public AtmosObject create(SystemMetadata systemMetadata, UserMetadata userMetadata) {
return new AtmosObjectImpl(generateMD5Result, generateMD5, calculateSize, metadataProvider
.get(), systemMetadata, userMetadata);
return new AtmosObjectImpl(encryptionService, metadataProvider.get(), systemMetadata,
userMetadata);
}
public AtmosObject create(MutableContentMetadata contentMetadata,
SystemMetadata systemMetadata, UserMetadata userMetadata) {
return new AtmosObjectImpl(generateMD5Result, generateMD5, calculateSize, contentMetadata,
systemMetadata, userMetadata);
return new AtmosObjectImpl(encryptionService, contentMetadata, systemMetadata,
userMetadata);
}
}

View File

@ -23,14 +23,14 @@
*/
package org.jclouds.atmosonline.saas.domain;
import java.io.IOException;
import org.jclouds.http.PayloadEnclosing;
import com.google.common.collect.Multimap;
import com.google.inject.internal.Nullable;
/**
* Amazon Atmos is designed to store objects. Objects are stored in buckets and consist of a
* {@link ObjectMetadataAtmosObject#getData() value}, a {@link ObjectMetadata#getKey key},
* {@link ObjectMetadataAtmosObject#getContent() value}, a {@link ObjectMetadata#getKey key},
* {@link ObjectMetadata#getUserMetadata() metadata}, and an access control policy.
*
* @author Adrian Cole
@ -38,7 +38,7 @@ import com.google.inject.internal.Nullable;
* href="http://docs.amazonwebservices.com/AmazonAtmos/2006-03-01/index.html?UsingObjects.html"
* />
*/
public interface AtmosObject extends Comparable<AtmosObject> {
public interface AtmosObject extends PayloadEnclosing, Comparable<AtmosObject> {
public interface Factory {
AtmosObject create(@Nullable MutableContentMetadata contentMetadata);
@ -49,33 +49,6 @@ public interface AtmosObject extends Comparable<AtmosObject> {
}
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException
* if there is a problem generating the hash.
*/
void generateMD5() throws IOException;
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
void setData(Object data);
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
Object getData();
MutableContentMetadata getContentMetadata();
/**

View File

@ -51,7 +51,7 @@ public class MutableContentMetadata {
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getData()}
* @return the length in bytes that can be be obtained from {@link #getContent()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/

View File

@ -24,18 +24,13 @@
package org.jclouds.atmosonline.saas.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.InputStream;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.MutableContentMetadata;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.internal.BasePayloadEnclosingImpl;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
@ -45,67 +40,28 @@ import com.google.common.collect.Multimap;
*
* @author Adrian Cole
*/
public class AtmosObjectImpl implements AtmosObject, Comparable<AtmosObject> {
public class AtmosObjectImpl extends BasePayloadEnclosingImpl implements AtmosObject,
Comparable<AtmosObject> {
private final UserMetadata userMetadata;
private final GenerateMD5Result generateMD5Result;
private final GenerateMD5 generateMD5;
private final CalculateSize calculateSize;
private final MutableContentMetadata contentMetadata;
private final SystemMetadata systemMetadata;
private Object data;
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
public AtmosObjectImpl(GenerateMD5Result generateMD5Result, GenerateMD5 generateMD5,
CalculateSize calculateSize, MutableContentMetadata contentMetadata) {
this(generateMD5Result, generateMD5, calculateSize, contentMetadata, null, new UserMetadata());
public AtmosObjectImpl(EncryptionService encryptionService,
MutableContentMetadata contentMetadata) {
this(encryptionService, contentMetadata, null, new UserMetadata());
}
public AtmosObjectImpl(GenerateMD5Result generateMD5Result, GenerateMD5 generateMD5,
CalculateSize calculateSize, MutableContentMetadata contentMetadata,
SystemMetadata systemMetadata, UserMetadata userMetadata) {
this.generateMD5Result = generateMD5Result;
this.generateMD5 = generateMD5;
this.calculateSize = calculateSize;
public AtmosObjectImpl(EncryptionService encryptionService,
MutableContentMetadata contentMetadata, SystemMetadata systemMetadata,
UserMetadata userMetadata) {
super(encryptionService);
this.contentMetadata = contentMetadata;
this.systemMetadata = systemMetadata;
this.userMetadata = userMetadata;
}
/**
* {@inheritDoc}
*/
public void generateMD5() {
checkState(data != null, "data");
if (data instanceof InputStream) {
MD5InputStreamResult result = generateMD5Result.apply((InputStream) data);
getContentMetadata().setContentMD5(result.md5);
getContentMetadata().setContentLength(result.length);
setData(result.data);
} else {
getContentMetadata().setContentMD5(generateMD5.apply(data));
}
}
/**
* {@inheritDoc}
*/
public Object getData() {
return data;
}
/**
* {@inheritDoc}
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getContentMetadata().getContentLength() == null) {
Long size = calculateSize.apply(data);
if (size != null)
getContentMetadata().setContentLength(size);
}
}
/**
* {@inheritDoc}
*/
@ -148,4 +104,19 @@ public class AtmosObjectImpl implements AtmosObject, Comparable<AtmosObject> {
return userMetadata;
}
@Override
public Long getContentLength() {
return getContentMetadata().getContentLength();
}
@Override
public void setContentLength(long contentLength) {
getContentMetadata().setContentLength(contentLength);
}
@Override
protected void setContentMD5(byte[] md5) {
getContentMetadata().setContentMD5(md5);
}
}

View File

@ -67,7 +67,7 @@ public class ParseObjectFromHeadersAndHttpContent implements Function<HttpRespon
AtmosObject object = objectProvider.create(systemMetadataParser.apply(from),
userMetadataParser.apply(from));
addAllHeadersTo(from, object);
object.setData(from.getContent());
object.setPayload(from.getContent());
String contentLength = from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH);
if (contentLength != null) {
object.getContentMetadata().setContentLength(Long.parseLong(contentLength));

View File

@ -27,7 +27,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.security.SecureRandom;
@ -47,6 +46,8 @@ import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.blobstore.strategy.ClearContainerStrategy;
import org.jclouds.http.HttpResponseException;
import org.jclouds.http.Payloads;
import org.jclouds.http.payloads.InputStreamPayload;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.util.Utils;
@ -225,7 +226,7 @@ public class AtmosStorageClientLiveTest {
// Test PUT with string data, ETag hash, and a piece of metadata
AtmosObject object = connection.newObject();
object.getContentMetadata().setName(name);
object.setData(data);
object.setPayload(Payloads.newPayload(data));
object.getContentMetadata().setContentLength(16);
object.generateMD5();
object.getContentMetadata().setContentType("text/plain");
@ -273,7 +274,7 @@ public class AtmosStorageClientLiveTest {
String metadataValue) throws InterruptedException, ExecutionException,
TimeoutException, IOException {
AtmosObject getBlob = connection.headFile(path);
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), "");
assertEquals(IOUtils.toString(getBlob.getContent()), "");
verifyMetadata(metadataValue, getBlob);
}
@ -281,8 +282,7 @@ public class AtmosStorageClientLiveTest {
String metadataValue) throws InterruptedException, ExecutionException,
TimeoutException, IOException {
AtmosObject getBlob = connection.readFile(path);
assertEquals(getBlob.getData() instanceof String ? getBlob.getData() : IOUtils
.toString((InputStream) getBlob.getData()), compare);
assertEquals(IOUtils.toString(getBlob.getContent()), compare);
verifyMetadata(metadataValue, getBlob);
}
@ -326,14 +326,14 @@ public class AtmosStorageClientLiveTest {
try {
connection.createFile(privateDirectory, object);
System.err.printf("%s %s; %dms%n", "created",
object.getData() instanceof InputStream ? "stream" : "string", System
object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System
.currentTimeMillis()
- time);
} catch (Exception e) {
String message = (e.getCause().getCause() != null) ? e.getCause().getCause().getMessage()
: e.getCause().getMessage();
System.err.printf("failure %s %s; %dms: [%s]%n", "creating",
object.getData() instanceof InputStream ? "stream" : "string", System
object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System
.currentTimeMillis()
- time, message);
throw e;
@ -386,7 +386,7 @@ public class AtmosStorageClientLiveTest {
}
if (failures > 0)
System.err.printf("%d failures create/replacing %s%n", failures,
object.getData() instanceof InputStream ? "stream" : "string");
object.getPayload() instanceof InputStreamPayload ? "stream" : "string");
}
private void checkSystemMetadataAndPutIfPresentReplaceStrategy(AtmosObject object)
@ -404,14 +404,14 @@ public class AtmosStorageClientLiveTest {
else
connection.createFile(privateDirectory, object);
System.err.printf("%s %s; %dms%n", update ? "updated" : "created",
object.getData() instanceof InputStream ? "stream" : "string", System
object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System
.currentTimeMillis()
- time);
} catch (Exception e) {
String message = (e.getCause().getCause() != null) ? e.getCause().getCause().getMessage()
: e.getCause().getMessage();
System.err.printf("failure %s %s; %dms: [%s]%n", update ? "updating" : "creating", object
.getData() instanceof InputStream ? "stream" : "string", System
.getPayload() instanceof InputStreamPayload ? "stream" : "string", System
.currentTimeMillis()
- time, message);
throw e;

View File

@ -82,7 +82,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
assertRequestLineEquals(httpMethod,
"GET http://accesspoint.emccis.com/rest/namespace HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": text/xml\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseDirectoryListFromContentAndHeaders.class);
@ -101,7 +101,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
assertRequestLineEquals(httpMethod,
"GET http://accesspoint.emccis.com/rest/namespace/directory/ HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": text/xml\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseDirectoryListFromContentAndHeaders.class);
@ -122,7 +122,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
"GET http://accesspoint.emccis.com/rest/namespace HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT
+ ": text/xml\nx-emc-limit: 1\nx-emc-token: asda\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseDirectoryListFromContentAndHeaders.class);
@ -143,7 +143,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
"GET http://accesspoint.emccis.com/rest/namespace/directory/ HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT
+ ": text/xml\nx-emc-limit: 1\nx-emc-token: asda\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseDirectoryListFromContentAndHeaders.class);
@ -161,7 +161,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
assertRequestLineEquals(httpMethod,
"POST http://accesspoint.emccis.com/rest/namespace/dir/ HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": */*\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseURIFromListOrLocationHeaderIf20x.class);
@ -181,7 +181,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
"POST http://accesspoint.emccis.com/rest/namespace/dir/hello HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT
+ ": */*\nContent-Length: 5\nContent-Type: text/plain\n");
assertEntityEquals(httpMethod, "hello");
assertPayloadEquals(httpMethod, "hello");
assertResponseParserClassEquals(method, httpMethod,
ParseURIFromListOrLocationHeaderIf20x.class);
@ -201,7 +201,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
"PUT http://accesspoint.emccis.com/rest/namespace/dir/hello HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT
+ ": */*\nContent-Length: 5\nContent-Type: text/plain\n");
assertEntityEquals(httpMethod, "hello");
assertPayloadEquals(httpMethod, "hello");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -219,7 +219,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
assertRequestLineEquals(httpMethod,
"GET http://accesspoint.emccis.com/rest/namespace/dir/file HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": */*\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseObjectFromHeadersAndHttpContent.class);
@ -237,7 +237,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
assertRequestLineEquals(httpMethod,
"HEAD http://accesspoint.emccis.com/rest/namespace/dir/file HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": */*\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSystemMetadataFromHeaders.class);
assertSaxResponseParserClassEquals(method, null);
@ -254,7 +254,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
assertRequestLineEquals(httpMethod,
"DELETE http://accesspoint.emccis.com/rest/namespace/dir/file HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": */*\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);

View File

@ -103,13 +103,13 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
checkNotNull(request.getFirstHeaderOrNull(HttpHeaders.HOST),
"request is not ready to sign; host not present");
Multimap<String, String> decodedParams = RestAnnotationProcessor.parseQueryToMap(request
.getEntity().toString());
.getPayload().getRawContent().toString());
addSigningParams(decodedParams);
validateParams(decodedParams);
String stringToSign = createStringToSign(request, decodedParams);
String signature = signString(stringToSign);
addSignature(decodedParams, signature);
setEntity(request, decodedParams);
setPayload(request, decodedParams);
HttpUtils.logRequest(signatureLog, request, "<<");
}
@ -128,8 +128,8 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
return parts;
}
void setEntity(GeneratedHttpRequest<?> request, Multimap<String, String> decodedParams) {
request.setEntity(RestAnnotationProcessor.makeQueryLine(decodedParams,
void setPayload(GeneratedHttpRequest<?> request, Multimap<String, String> decodedParams) {
request.setPayload(RestAnnotationProcessor.makeQueryLine(decodedParams,
new Comparator<Map.Entry<String, String>>() {
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
if (o1.getKey().startsWith("Action")
@ -209,8 +209,8 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
}
public String createStringToSign(HttpRequest input) {
return createStringToSign(input, RestAnnotationProcessor.parseQueryToMap(input.getEntity()
.toString()));
return createStringToSign(input, RestAnnotationProcessor.parseQueryToMap(input.getPayload()
.getRawContent().toString()));
}
}

View File

@ -36,8 +36,8 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.aws.s3.binders.BindACLToXMLEntity;
import org.jclouds.aws.s3.binders.BindS3ObjectToEntity;
import org.jclouds.aws.s3.binders.BindACLToXMLPayload;
import org.jclouds.aws.s3.binders.BindS3ObjectToPayload;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
@ -139,7 +139,7 @@ public interface S3AsyncClient {
@ResponseParser(ParseETagHeader.class)
Future<String> putObject(
@HostPrefixParam String bucketName,
@PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
@PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectToPayload.class) S3Object object,
PutObjectOptions... options);
/**
@ -214,7 +214,7 @@ public interface S3AsyncClient {
@Path("/")
@QueryParams(keys = "acl")
Future<Boolean> putBucketACL(@HostPrefixParam String bucketName,
@BinderParam(BindACLToXMLEntity.class) AccessControlList acl);
@BinderParam(BindACLToXMLPayload.class) AccessControlList acl);
/**
* @see S3Client#getObjectACL
@ -234,6 +234,6 @@ public interface S3AsyncClient {
@QueryParams(keys = "acl")
@Path("{key}")
Future<Boolean> putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key,
@BinderParam(BindACLToXMLEntity.class) AccessControlList acl);
@BinderParam(BindACLToXMLPayload.class) AccessControlList acl);
}

View File

@ -42,17 +42,17 @@ import org.jclouds.util.Utils;
import com.jamesmurty.utils.XMLBuilder;
public class BindACLToXMLEntity implements Binder {
public class BindACLToXMLPayload implements Binder {
public void bindToRequest(HttpRequest request, Object entity) {
AccessControlList from = (AccessControlList) entity;
public void bindToRequest(HttpRequest request, Object payload) {
AccessControlList from = (AccessControlList) payload;
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
try {
String stringEntity = generateBuilder(from).asString(outputProperties);
String stringPayload = generateBuilder(from).asString(outputProperties);
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML);
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
request.setEntity(stringEntity);
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringPayload.getBytes().length + "");
request.setPayload(stringPayload);
} catch (Exception e) {
Utils.rethrowIfRuntime(e);
throw new RuntimeException("error transforming acl: " + from, e);

View File

@ -31,23 +31,23 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.binders.BindBlobToPayloadAndUserMetadataToHeadersWithPrefix;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
public class BindS3ObjectToEntity implements Binder {
private final BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder;
public class BindS3ObjectToPayload implements Binder {
private final BindBlobToPayloadAndUserMetadataToHeadersWithPrefix blobBinder;
private final ObjectToBlob object2Blob;
@Inject
public BindS3ObjectToEntity(ObjectToBlob object2Blob,
BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder) {
public BindS3ObjectToPayload(ObjectToBlob object2Blob,
BindBlobToPayloadAndUserMetadataToHeadersWithPrefix blobBinder) {
this.blobBinder = blobBinder;
this.object2Blob = object2Blob;
}
public void bindToRequest(HttpRequest request, Object entity) {
S3Object s3Object = (S3Object) entity;
public void bindToRequest(HttpRequest request, Object payload) {
S3Object s3Object = (S3Object) payload;
checkNotNull(s3Object.getContentLength(), "contentLength");
checkArgument(s3Object.getContentLength() <= 5 * 1024 * 1024 * 1024,
"maximum size for put object is 5GB");

View File

@ -49,7 +49,7 @@ public class BlobToObject implements Function<Blob, S3Object> {
S3Object object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
if (from.getContentLength() != null)
object.setContentLength(from.getContentLength());
object.setData(from.getData());
object.setPayload(from.getPayload());
object.setAllHeaders(from.getAllHeaders());
return object;
}

View File

@ -50,7 +50,7 @@ public class ObjectToBlob implements Function<S3Object, Blob> {
Blob blob = blobFactory.create(object2BlobMd.apply(from.getMetadata()));
if (from.getContentLength() != null)
blob.setContentLength(from.getContentLength());
blob.setData(from.getData());
blob.setPayload(from.getPayload());
blob.setAllHeaders(from.getAllHeaders());
return blob;
}

View File

@ -29,9 +29,7 @@ import javax.inject.Provider;
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -44,7 +42,6 @@ import com.google.inject.Scopes;
*/
public class S3ObjectModule extends AbstractModule {
/**
* explicit factories are created here as it has been shown that Assisted Inject is extremely
* inefficient. http://code.google.com/p/google-guice/issues/detail?id=435
@ -56,17 +53,13 @@ public class S3ObjectModule extends AbstractModule {
private static class S3ObjectFactory implements S3Object.Factory {
@Inject
GenerateMD5Result generateMD5Result;
@Inject
GenerateMD5 generateMD5;
@Inject
CalculateSize calculateSize;
EncryptionService encryptionService;
@Inject
Provider<MutableObjectMetadata> metadataProvider;
public S3Object create(MutableObjectMetadata metadata) {
return new S3ObjectImpl(generateMD5Result, generateMD5, calculateSize,
metadata != null ? metadata : metadataProvider.get());
return new S3ObjectImpl(encryptionService, metadata != null ? metadata : metadataProvider
.get());
}
}

View File

@ -40,9 +40,9 @@ import com.google.common.collect.Collections2;
* An Access Control List (ACL) describes the access control settings for a bucket or object in S3.
*
* ACL settings comprise a set of {@link Grant}s, each of which specifies a {@link Permission} that
* has been granted to a specific {@link Grantee}. If an entity tries to access or modify an item in
* has been granted to a specific {@link Grantee}. If an payload tries to access or modify an item in
* S3, the operation will be denied unless the item has ACL settings that explicitly permit that
* entity to perform that action.
* payload to perform that action.
*
*
* @author James Murty

View File

@ -23,66 +23,25 @@
*/
package org.jclouds.aws.s3.domain;
import java.io.IOException;
import org.jclouds.http.PayloadEnclosing;
import com.google.common.collect.Multimap;
import com.google.inject.internal.Nullable;
/**
* Amazon S3 is designed to store objects. Objects are stored in buckets and consist of a
* {@link ObjectMetadataS3Object#getData() value}, a {@link ObjectMetadata#getKey key},
* {@link ObjectMetadataS3Object#getContent() value}, a {@link ObjectMetadata#getKey key},
* {@link ObjectMetadata#getUserMetadata() metadata}, and an access control policy.
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
* />
*/
public interface S3Object extends Comparable<S3Object> {
public interface S3Object extends PayloadEnclosing, Comparable<S3Object> {
public interface Factory {
S3Object create(@Nullable MutableObjectMetadata metadata);
}
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
void setData(Object data);
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
Object getData();
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException
* if there is a problem generating the hash.
*/
void generateMD5() throws IOException;
void setContentLength(long contentLength);
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getData()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
Long getContentLength();
/**
* @return System and User metadata relevant to this object.
*/

View File

@ -24,19 +24,14 @@
package org.jclouds.aws.s3.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.InputStream;
import javax.inject.Inject;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.internal.BasePayloadEnclosingImpl;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
@ -46,25 +41,22 @@ import com.google.common.collect.Multimap;
*
* @author Adrian Cole
*/
public class S3ObjectImpl implements S3Object, Comparable<S3Object> {
private final GenerateMD5Result generateMD5Result;
private final GenerateMD5 generateMD5;
private final CalculateSize calculateSize;
public class S3ObjectImpl extends BasePayloadEnclosingImpl implements S3Object,
Comparable<S3Object> {
private final MutableObjectMetadata metadata;
private Object data;
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
private Long contentLength;
private AccessControlList accessControlList;
@Inject
public S3ObjectImpl(GenerateMD5Result generateMD5Result, GenerateMD5 generateMD5,
CalculateSize calculateSize, MutableObjectMetadata metadata) {
this.generateMD5Result = generateMD5Result;
this.generateMD5 = generateMD5;
this.calculateSize = calculateSize;
public S3ObjectImpl(EncryptionService encryptionService, MutableObjectMetadata metadata) {
super(encryptionService);
this.metadata = metadata;
}
private AccessControlList accessControlList;
@Override
protected void setContentMD5(byte[] md5) {
getMetadata().setContentMD5(md5);
}
/**
* {@inheritDoc}
@ -80,54 +72,6 @@ public class S3ObjectImpl implements S3Object, Comparable<S3Object> {
return this.accessControlList;
}
/**
* {@inheritDoc}
*/
public void generateMD5() {
checkState(data != null, "data");
if (data instanceof InputStream) {
MD5InputStreamResult result = generateMD5Result.apply((InputStream) data);
getMetadata().setContentMD5(result.md5);
setContentLength(result.length);
setData(result.data);
} else {
getMetadata().setContentMD5(generateMD5.apply(data));
}
}
/**
* {@inheritDoc}
*/
public Object getData() {
return data;
}
/**
* {@inheritDoc}
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getContentLength() == null) {
Long size = calculateSize.apply(data);
if (size != null)
this.setContentLength(size);
}
}
/**
* {@inheritDoc}
*/
public Long getContentLength() {
return contentLength;
}
/**
* {@inheritDoc}
*/
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
/**
* {@inheritDoc}
*/
@ -165,7 +109,7 @@ public class S3ObjectImpl implements S3Object, Comparable<S3Object> {
result = prime * result + ((accessControlList == null) ? 0 : accessControlList.hashCode());
result = prime * result + ((allHeaders == null) ? 0 : allHeaders.hashCode());
result = prime * result + ((contentLength == null) ? 0 : contentLength.hashCode());
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((payload == null) ? 0 : payload.hashCode());
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
return result;
}
@ -194,10 +138,10 @@ public class S3ObjectImpl implements S3Object, Comparable<S3Object> {
return false;
} else if (!contentLength.equals(other.contentLength))
return false;
if (data == null) {
if (other.data != null)
if (payload == null) {
if (other.payload != null)
return false;
} else if (!data.equals(other.data))
} else if (!payload.equals(other.payload))
return false;
if (metadata == null) {
if (other.metadata != null)

View File

@ -66,7 +66,7 @@ public class ParseObjectFromHeadersAndHttpContent implements Function<HttpRespon
public S3Object apply(HttpResponse from) {
S3Object object = objectProvider.create(metadataParser.apply(from));
addAllHeadersTo(from, object);
object.setData(from.getContent());
object.setPayload(from.getContent());
attemptToParseSizeAndRangeFromHeaders(from, object);
return object;
}

View File

@ -145,7 +145,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
/**
* For use in the request header: x-amz-copy-source-if-match
* <p/>
* Copies the object if its entity tag (ETag) matches the specified tag; otherwise return a 412
* Copies the object if its payload tag (ETag) matches the specified tag; otherwise return a 412
* (precondition failed).
* <p/>
* This header can be used with x-amz-copy-source-if-unmodified-since, but cannot be used with
@ -160,7 +160,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
/**
* For use in the request header: x-amz-copy-source-if-none-match
* <p/>
* Copies the object if its entity tag (ETag) is different than the specified Etag; otherwise
* Copies the object if its payload tag (ETag) is different than the specified Etag; otherwise
* returns a 412 (failed condition).
* <p/>
* This header can be used with x-amz-copy-source-if-modified-since, but cannot be used with
@ -221,7 +221,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
* {@link #ifSourceModifiedSince(Date)}
*
* @param eTag
* hash representing the entity
* hash representing the payload
*/
public CopyObjectOptions ifSourceETagMatches(String eTag) throws UnsupportedEncodingException {
checkState(getIfNoneMatch() == null,
@ -240,7 +240,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
* {@link #ifSourceUnmodifiedSince(Date)}
*
* @param eTag
* hash representing the entity
* hash representing the payload
* @throws UnsupportedEncodingException
* if there was a problem converting this into an S3 eTag string
*/

View File

@ -61,7 +61,7 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
*/
public PutBucketOptions createIn(LocationConstraint constraint) {
this.constraint = checkNotNull(constraint, "constraint");
this.entity = String
this.payload = String
.format(
"<CreateBucketConfiguration><LocationConstraint>%1$s</LocationConstraint></CreateBucketConfiguration>",
constraint.toString());

View File

@ -83,9 +83,9 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 40\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DescribeImages");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeImages");
filter.filter(httpMethod);
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Action=DescribeImages&Signature=wJmKTnrx5v3PSECZJjm%2BE1s8I%2FqHkVs2K1hJ6yxbpC0%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-08-15&AWSAccessKeyId=user");
@ -106,7 +106,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 107\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Version=2009-08-15&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2");
@ -127,10 +127,10 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 93\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=DescribeImageAttribute&ImageId=imageId&Attribute=blockDeviceMapping");
filter.filter(httpMethod);
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId&Signature=IiyxXwoOmpLiPC%2BbfBdqJwE758bvbs8kXCL71FefStY%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-08-15&AWSAccessKeyId=user");
@ -149,7 +149,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 43\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DescribeInstances");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeInstances");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeInstancesResponseHandler.class);
@ -167,7 +167,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 43\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=DescribeInstances&InstanceId.1=1&InstanceId.2=2");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
@ -186,7 +186,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=TerminateInstances&InstanceId.0=1&InstanceId.1=2");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
@ -204,7 +204,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 76\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
@ -224,7 +224,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 118\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Version=2009-08-15&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true");
@ -242,7 +242,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 53\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=CreateKeyPair&KeyName=mykey");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=CreateKeyPair&KeyName=mykey");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, KeyPairResponseHandler.class);
@ -260,7 +260,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 64\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=DisassociateAddress&PublicIp=127.0.0.1");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
@ -279,7 +279,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 75\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=AssociateAddress&PublicIp=127.0.0.1&InstanceId=me");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
@ -297,7 +297,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=ReleaseAddress&PublicIp=127.0.0.1");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=ReleaseAddress&PublicIp=127.0.0.1");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -315,7 +315,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 43\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=DescribeAddresses&PublicIp.1=127.0.0.1");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
@ -332,7 +332,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 41\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=AllocateAddress");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=AllocateAddress");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, AllocateAddressResponseHandler.class);
@ -348,7 +348,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 53\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DeleteKeyPair&KeyName=mykey");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DeleteKeyPair&KeyName=mykey");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -365,7 +365,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 42\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DescribeKeyPairs");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeKeyPairs");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class);
@ -383,7 +383,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 42\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=DescribeKeyPairs&KeyName.1=1&KeyName.2=2");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
@ -401,7 +401,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 60\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DeleteSecurityGroup&GroupName=name");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DeleteSecurityGroup&GroupName=name");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -419,7 +419,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 89\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=CreateSecurityGroup&GroupName=name&GroupDescription=description");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
@ -438,7 +438,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 48\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DescribeSecurityGroups");
assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeSecurityGroups");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSecurityGroupsResponseHandler.class);
@ -456,7 +456,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 48\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
assertPayloadEquals(httpMethod,
"Version=2009-08-15&Action=DescribeSecurityGroups&GroupName.1=1&GroupName.2=2");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
@ -476,7 +476,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 71\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Version=2009-08-15&Action=AuthorizeSecurityGroupIngress&GroupName=group&SourceSecurityGroupOwnerId=sourceUser&SourceSecurityGroupName=sourceGroup");
@ -497,7 +497,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 131\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Version=2009-08-15&Action=AuthorizeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0");
@ -518,7 +518,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 68\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Version=2009-08-15&Action=RevokeSecurityGroupIngress&GroupName=group&SourceSecurityGroupOwnerId=sourceUser&SourceSecurityGroupName=sourceGroup");
@ -539,7 +539,7 @@ public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 128\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"Version=2009-08-15&Action=RevokeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0");

View File

@ -43,7 +43,6 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Date;
@ -104,7 +103,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
String key = "hello";
S3Object object = context.getApi().newS3Object();
object.getMetadata().setKey(key);
object.setData(TEST_STRING);
object.setPayload(TEST_STRING);
context.getApi().putObject(containerName, object,
withAcl(CannedAccessPolicy.PUBLIC_READ));
@ -149,7 +148,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
try {
S3Object object = context.getApi().newS3Object();
object.getMetadata().setKey(publicReadWriteObjectKey);
object.setData("");
object.setPayload("");
// Public Read-Write object
context.getApi().putObject(containerName, object,
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE));
@ -252,7 +251,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
try {
S3Object object = context.getApi().newS3Object();
object.getMetadata().setKey(publicReadObjectKey);
object.setData("");
object.setPayload("");
context.getApi().putObject(containerName, object,
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ));
@ -284,7 +283,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
S3Object sourceObject = context.getApi().newS3Object();
sourceObject.getMetadata().setKey(key);
sourceObject.getMetadata().setContentType("text/xml");
sourceObject.setData(TEST_STRING);
sourceObject.setPayload(TEST_STRING);
return context.getApi().putObject(sourceContainer, sourceObject);
}
@ -293,7 +292,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
assertConsistencyAwareContainerSize(sourceContainer, 1);
S3Object newObject = context.getApi().getObject(sourceContainer, key);
assert newObject != null;
assertEquals(Utils.toStringAndClose((InputStream) newObject.getData()), TEST_STRING);
assertEquals(Utils.toStringAndClose(newObject.getContent()), TEST_STRING);
return newObject;
}
@ -302,7 +301,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
S3Object object = context.getApi().newS3Object();
object.getMetadata().setKey(key);
object.setData(TEST_STRING);
object.setPayload(TEST_STRING);
object.getMetadata().setCacheControl("no-cache");
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
String containerName = getContainerName();
@ -325,7 +324,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
S3Object object = context.getApi().newS3Object();
object.getMetadata().setKey(key);
object.setData(TEST_STRING);
object.setPayload(TEST_STRING);
object.getMetadata().setContentEncoding("x-compress");
String containerName = getContainerName();
try {
@ -619,7 +618,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
for (char letter = 'a'; letter <= 'z'; letter++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(letter + "");
blob.setData(letter + "content");
blob.setPayload(letter + "content");
context.getApi().putObject(containerName, blob);
}
}
@ -694,7 +693,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
for (int i = 0; i < 15; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(i + "");
blob.setData(i + "content");
blob.setPayload(i + "content");
context.getApi().putObject(containerName, blob);
}
}
@ -703,7 +702,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
for (int i = 0; i < 10; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(prefix + "/" + i);
blob.setData(i + "content");
blob.setPayload(i + "content");
context.getApi().putObject(containerName, blob);
}
}

View File

@ -91,7 +91,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, ListBucketHandler.class);
@ -106,7 +106,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "HEAD http://bucket.stub:8080/?max-keys=0 HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -127,7 +127,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
"PUT http://destinationBucket.stub:8080/destinationObject HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 0\nHost: destinationBucket.stub\nx-amz-copy-source: /sourceBucket/sourceObject\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, CopyObjectHandler.class);
@ -143,7 +143,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "DELETE http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -159,7 +159,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "DELETE http://bucket.stub:8080/object HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -175,7 +175,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/?acl HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, AccessControlListHandler.class);
@ -193,7 +193,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/object HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod,
ParseObjectFromHeadersAndHttpContent.class);
@ -211,7 +211,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/object?acl HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, AccessControlListHandler.class);
@ -228,7 +228,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "HEAD http://bucket.stub:8080/object HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseObjectMetadataFromHeaders.class);
assertSaxResponseParserClassEquals(method, null);
@ -243,7 +243,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "GET http://stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, ListAllMyBucketsHandler.class);
@ -266,7 +266,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/?acl HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 321\nContent-Type: text/xml\nHost: bucket.stub\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"<AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>1234</ID></Owner><AccessControlList><Grant><Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>1234</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>");
@ -285,7 +285,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Content-Length: 0\nHost: bucket.stub\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
@ -305,7 +305,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/hello HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 5\nContent-Type: text/plain\nHost: bucket.stub\n");
assertEntityEquals(httpMethod, "hello");
assertPayloadEquals(httpMethod, "hello");
assertResponseParserClassEquals(method, httpMethod, ParseETagHeader.class);
assertSaxResponseParserClassEquals(method, null);
@ -323,7 +323,7 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/key?acl HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 321\nContent-Type: text/xml\nHost: bucket.stub\n");
assertEntityEquals(
assertPayloadEquals(
httpMethod,
"<AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>1234</ID></Owner><AccessControlList><Grant><Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>1234</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>");

View File

@ -187,7 +187,7 @@ public class StubS3AsyncClient implements S3AsyncClient {
newMd.setLastModified(new Date());
Blob newBlob = blobProvider.create(newMd);
newBlob.setData(sourceS3.getData());
newBlob.setPayload(sourceS3.getContent());
dest.put(destinationObject, newBlob);
return blob2ObjectMetadata.apply(blobStore.copy(newMd));
}

View File

@ -54,11 +54,11 @@ public class PutBucketOptionsTest {
}
@Test
public void testEntity() {
public void testPayload() {
PutBucketOptions options = new PutBucketOptions();
options.createIn(LocationConstraint.EU);
assertEquals(
options.buildStringEntity(),
options.buildStringPayload(),
"<CreateBucketConfiguration><LocationConstraint>EU</LocationConstraint></CreateBucketConfiguration>");
}

View File

@ -65,7 +65,7 @@ public class MainApp {
Blob blob = blobStore.newBlob();
blob.getMetadata().setName("test");
blob.setData("testdata");
blob.setPayload("testdata");
blobStore.putBlob(containerName, blob);
// List Container

View File

@ -23,7 +23,6 @@
*/
package org.jclouds.aws.s3.jets3t;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Calendar;
@ -114,8 +113,8 @@ public class Util {
public static S3Object convertObject(org.jclouds.aws.s3.domain.S3Object jcObject) {
S3Object jsObject = convertObjectHead(jcObject.getMetadata());
if (jcObject.getData() != null) {
jsObject.setDataInputStream((InputStream) jcObject.getData());
if (jcObject.getContent() != null) {
jsObject.setDataInputStream(jcObject.getContent());
}
return jsObject;
}
@ -149,9 +148,9 @@ public class Util {
}
if (jsObject.getDataInputStream() != null) {
jcObject.setData(jsObject.getDataInputStream());
jcObject.setPayload(jsObject.getDataInputStream());
} else {
jcObject.setData(""); // Must explicitly set data for empty jClouds objects.
jcObject.setPayload(""); // Must explicitly set data for empty jClouds objects.
}
if (jsObject.getContentType() != null) {

View File

@ -134,7 +134,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Asy
String objectValue = "test";
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(objectKey);
blob.setData(objectValue);
blob.setPayload(objectValue);
addBlobToContainer(bucketName, blob);
service.deleteObject(bucketName, objectKey);
@ -155,7 +155,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Asy
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(objectKey);
blob.setData(objectValue);
blob.setPayload(objectValue);
blob.getMetadata().getUserMetadata().put(metadataName, metadataValue);
addBlobToContainer(bucketName, blob);
@ -182,7 +182,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Asy
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(objectKey);
blob.setData(objectValue);
blob.setPayload(objectValue);
blob.getMetadata().getUserMetadata().put(metadataName, metadataValue);
addBlobToContainer(bucketName, blob);
@ -441,7 +441,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Asy
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(sourceObjectKey);
blob.setData(data);
blob.setPayload(data);
blob.getMetadata().getUserMetadata().put(metadataName, sourceMetadataValue);
addBlobToContainer(bucketName, blob);

View File

@ -44,8 +44,8 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
// object.setKey(id + "");
// //object.setContentType("text/plain");
// object.setContentType("application/octetstream");
// //object.setData("this is a test");
// object.setData(test);
// //object.setPayload("this is a test");
// object.setPayload(test);
// return context.getApi()Provider.getObject(s3Bucket,
// object.getKey()).get(120,TimeUnit.SECONDS) !=
// S3Object.NOT_FOUND;
@ -57,7 +57,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
throws Exception {
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
object.setPayload(data);
return context.getApi().putObject(bucket, object) != null;
}
@ -66,7 +66,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
throws Exception {
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
object.setPayload(data);
return context.getApi().putObject(bucket, object) != null;
}
@ -81,7 +81,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
throws Exception {
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
object.setPayload(data);
object.setContentLength(new Long(data.available()));
return context.getApi().putObject(bucket, object) != null;
}
@ -91,7 +91,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
throws Exception {
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
object.setPayload(data);
return context.getApi().putObject(bucket, object) != null;
}
}

View File

@ -35,7 +35,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.azure.storage.AzureBlob;
import org.jclouds.azure.storage.blob.binders.BindAzureBlobToEntity;
import org.jclouds.azure.storage.blob.binders.BindAzureBlobToPayload;
import org.jclouds.azure.storage.blob.domain.BlobProperties;
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
@ -193,7 +193,7 @@ public interface AzureBlobAsyncClient {
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(
@PathParam("container") String container,
@PathParam("name") @ParamParser(BlobName.class) @BinderParam(BindAzureBlobToEntity.class) org.jclouds.azure.storage.blob.domain.AzureBlob object);
@PathParam("name") @ParamParser(BlobName.class) @BinderParam(BindAzureBlobToPayload.class) org.jclouds.azure.storage.blob.domain.AzureBlob object);
/**
* @see AzureBlobClient#getBlob

View File

@ -194,7 +194,7 @@ public interface AzureBlobClient {
* it as a set of blocks. For more information, see the Put Block and Put Block List operations.
* <p/>
* If you attempt to upload a blob that is larger than 64 MB, the service returns status code 413
* (Request Entity Too Large). The Blob service also returns additional information about the
* (Request Payload Too Large). The Blob service also returns additional information about the
* error in the response, including the maximum blob size permitted in bytes.
* <p/>
* A Put Blob operation is permitted 10 minutes per MB to complete. If the operation is taking

View File

@ -33,24 +33,24 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.binders.BindBlobToPayloadAndUserMetadataToHeadersWithPrefix;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.HttpRequest;
public class BindAzureBlobToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
public class BindAzureBlobToPayload extends BindBlobToPayloadAndUserMetadataToHeadersWithPrefix {
private final AzureBlobToBlob azureBlob2Blob;
@Inject
public BindAzureBlobToEntity(AzureBlobToBlob azureBlob2Blob,
public BindAzureBlobToPayload(AzureBlobToBlob azureBlob2Blob,
@Named(AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX) String prefix,
EncryptionService encryptionService) {
super(prefix, encryptionService);
this.azureBlob2Blob = azureBlob2Blob;
}
public void bindToRequest(HttpRequest request, Object entity) {
AzureBlob object = (AzureBlob) entity;
public void bindToRequest(HttpRequest request, Object payload) {
AzureBlob object = (AzureBlob) payload;
checkArgument(object.getProperties().getSize() >= 0, "size must be set");
checkArgument(
checkNotNull(object.getContentLength(), "object.getContentLength()") <= 64 * 1024 * 1024,

View File

@ -50,7 +50,7 @@ public class AzureBlobToBlob implements Function<AzureBlob, Blob> {
Blob blob = blobFactory.create(blobPr2BlobMd.apply(from.getProperties()));
if (from.getContentLength() != null)
blob.setContentLength(from.getContentLength());
blob.setData(from.getData());
blob.setPayload(from.getPayload());
blob.setAllHeaders(from.getAllHeaders());
return blob;
}

View File

@ -49,7 +49,7 @@ public class BlobToAzureBlob implements Function<Blob, AzureBlob> {
AzureBlob object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
if (from.getContentLength() != null)
object.setContentLength(from.getContentLength());
object.setData(from.getData());
object.setPayload(from.getPayload());
object.setAllHeaders(from.getAllHeaders());
return object;
}

View File

@ -29,9 +29,7 @@ import javax.inject.Provider;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
import org.jclouds.azure.storage.blob.domain.internal.AzureBlobImpl;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -44,7 +42,6 @@ import com.google.inject.Scopes;
*/
public class AzureBlobModule extends AbstractModule {
/**
* explicit factories are created here as it has been shown that Assisted Inject is extremely
* inefficient. http://code.google.com/p/google-guice/issues/detail?id=435
@ -56,17 +53,13 @@ public class AzureBlobModule extends AbstractModule {
private static class AzureBlobFactory implements AzureBlob.Factory {
@Inject
GenerateMD5Result generateMD5Result;
@Inject
GenerateMD5 generateMD5;
@Inject
CalculateSize calculateSize;
EncryptionService encryptionService;
@Inject
Provider<MutableBlobProperties> metadataProvider;
public AzureBlob create(MutableBlobProperties metadata) {
return new AzureBlobImpl(generateMD5Result, generateMD5, calculateSize,
metadata != null ? metadata : metadataProvider.get());
return new AzureBlobImpl(encryptionService, metadata != null ? metadata : metadataProvider
.get());
}
}

View File

@ -23,66 +23,25 @@
*/
package org.jclouds.azure.storage.blob.domain;
import java.io.IOException;
import org.jclouds.http.PayloadEnclosing;
import com.google.common.collect.Multimap;
import com.google.inject.internal.Nullable;
/**
* Amazon S3 is designed to store objects. Objects are stored in buckets and consist of a
* {@link ObjectPropertiesBlob#getData() value}, a {@link ObjectProperties#getKey key},
* {@link ObjectPropertiesBlob#getContent() value}, a {@link ObjectProperties#getKey key},
* {@link ObjectProperties#getUserProperties() metadata}, and an access control policy.
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
* />
*/
public interface AzureBlob extends Comparable<AzureBlob> {
public interface AzureBlob extends PayloadEnclosing, Comparable<AzureBlob> {
public interface Factory {
AzureBlob create(@Nullable MutableBlobProperties properties);
}
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
void setData(Object data);
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
Object getData();
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException
* if there is a problem generating the hash.
*/
void generateMD5() throws IOException;
void setContentLength(long contentLength);
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getData()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
Long getContentLength();
/**
* @return System and User metadata relevant to this object.
*/

View File

@ -24,18 +24,13 @@
package org.jclouds.azure.storage.blob.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.InputStream;
import javax.inject.Inject;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.internal.BasePayloadEnclosingImpl;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
@ -45,70 +40,20 @@ import com.google.common.collect.Multimap;
*
* @author Adrian Cole
*/
public class AzureBlobImpl implements AzureBlob, Comparable<AzureBlob> {
private final GenerateMD5Result generateMD5Result;
private final GenerateMD5 generateMD5;
private final CalculateSize calculateSize;
public class AzureBlobImpl extends BasePayloadEnclosingImpl implements AzureBlob,
Comparable<AzureBlob> {
private final MutableBlobProperties properties;
private Object data;
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
private Long contentLength;
@Inject
public AzureBlobImpl(GenerateMD5Result generateMD5Result, GenerateMD5 generateMD5,
CalculateSize calculateSize, MutableBlobProperties properties) {
this.generateMD5Result = generateMD5Result;
this.generateMD5 = generateMD5;
this.calculateSize = calculateSize;
public AzureBlobImpl(EncryptionService encryptionService, MutableBlobProperties properties) {
super(encryptionService);
this.properties = properties;
}
/**
* {@inheritDoc}
*/
public void generateMD5() {
checkState(data != null, "data");
if (data instanceof InputStream) {
MD5InputStreamResult result = generateMD5Result.apply((InputStream) data);
getProperties().setContentMD5(result.md5);
setContentLength(result.length);
setData(result.data);
} else {
getProperties().setContentMD5(generateMD5.apply(data));
}
}
/**
* {@inheritDoc}
*/
public Object getData() {
return data;
}
/**
* {@inheritDoc}
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getContentLength() == null) {
Long size = calculateSize.apply(data);
if (size != null)
this.setContentLength(size);
}
}
/**
* {@inheritDoc}
*/
public Long getContentLength() {
return contentLength;
}
/**
* {@inheritDoc}
*/
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
@Override
protected void setContentMD5(byte[] md5) {
getProperties().setContentMD5(md5);
}
/**
@ -147,7 +92,7 @@ public class AzureBlobImpl implements AzureBlob, Comparable<AzureBlob> {
int result = 1;
result = prime * result + ((allHeaders == null) ? 0 : allHeaders.hashCode());
result = prime * result + ((contentLength == null) ? 0 : contentLength.hashCode());
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((payload == null) ? 0 : payload.hashCode());
result = prime * result + ((properties == null) ? 0 : properties.hashCode());
return result;
}
@ -171,10 +116,10 @@ public class AzureBlobImpl implements AzureBlob, Comparable<AzureBlob> {
return false;
} else if (!contentLength.equals(other.contentLength))
return false;
if (data == null) {
if (other.data != null)
if (payload == null) {
if (other.payload != null)
return false;
} else if (!data.equals(other.data))
} else if (!payload.equals(other.payload))
return false;
if (properties == null) {
if (other.properties != null)

View File

@ -66,7 +66,7 @@ public class ParseBlobFromHeadersAndHttpContent implements Function<HttpResponse
public AzureBlob apply(HttpResponse from) {
AzureBlob object = objectProvider.create(metadataParser.apply(from));
addAllHeadersTo(from, object);
object.setData(from.getContent());
object.setPayload(from.getContent());
attemptToParseSizeAndRangeFromHeaders(from, object);
return object;
}

View File

@ -27,7 +27,6 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.net.URL;
@ -229,7 +228,7 @@ public class AzureBlobClientLiveTest {
// Test PUT with string data, ETag hash, and a piece of metadata
AzureBlob object = connection.newBlob();
object.getProperties().setName("object");
object.setData(data);
object.setPayload(data);
object.setContentLength(data.length());
object.generateMD5();
object.getProperties().setContentType("text/plain");
@ -281,7 +280,7 @@ public class AzureBlobClientLiveTest {
}
// Test GET of object (including updated metadata)
AzureBlob getBlob = connection.getBlob(privateContainer, object.getProperties().getName());
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data);
assertEquals(IOUtils.toString(getBlob.getContent()), data);
// TODO assertEquals(getBlob.getName(), object.getProperties().getName());
assertEquals(getBlob.getContentLength(), new Long(data.length()));
assertEquals(getBlob.getProperties().getContentType(), "text/plain");
@ -313,7 +312,7 @@ public class AzureBlobClientLiveTest {
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes("UTF-8"));
object = connection.newBlob();
object.getProperties().setName("chunked-object");
object.setData(bais);
object.setPayload(bais);
object.setContentLength(new Long(data.getBytes().length));
newEtag = connection.putBlob(privateContainer, object);
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob

View File

@ -48,18 +48,17 @@ public class BindBlobToMultipartForm implements Binder {
public static final String BOUNDARY = "--JCLOUDS--";
public void bindToRequest(HttpRequest request, Object entity) {
Blob object = (Blob) entity;
public void bindToRequest(HttpRequest request, Object payload) {
Blob object = (Blob) payload;
File file = new File(object.getMetadata().getName());
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition", String
.format("form-data; name=\"%s\"; filename=\"%s\"", file.getName(), file.getName()),
HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(),
"object.metadata.contentType()"));
Object data = checkNotNull(object.getData(), "object.getData()");
Object data = checkNotNull(object.getPayload(), "object.getPayload()").getRawContent();
Part part;
try {
if (data instanceof byte[]) {
part = new Part(partHeaders, (byte[]) data);
} else if (data instanceof String) {
@ -77,7 +76,7 @@ public class BindBlobToMultipartForm implements Binder {
}
MultipartForm form = new MultipartForm(BOUNDARY, part);
request.setEntity(form.getData());
request.setPayload(form.getData());
request.getHeaders().put(HttpHeaders.CONTENT_TYPE,
"multipart/form-data; boundary=" + BOUNDARY);

View File

@ -37,18 +37,18 @@ import org.jclouds.rest.Binder;
*
* @author Adrian Cole
*/
public class BindBlobToEntity implements Binder {
public class BindBlobToPayload implements Binder {
private final EncryptionService encryptionService;
@Inject
public BindBlobToEntity(EncryptionService encryptionService) {
public BindBlobToPayload(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
public void bindToRequest(HttpRequest request, Object entity) {
Blob object = (Blob) entity;
public void bindToRequest(HttpRequest request, Object payload) {
Blob object = (Blob) payload;
request.setEntity(checkNotNull(object.getData(), "object.getContent()"));
request.setPayload(checkNotNull(object.getContent(), "object.getContent()"));
request.getHeaders()
.put(
HttpHeaders.CONTENT_TYPE,

View File

@ -36,24 +36,24 @@ import org.jclouds.http.HttpRequest;
*
* @author Adrian Cole
*/
public class BindBlobToEntityAndUserMetadataToHeadersWithPrefix extends BindBlobToEntity {
public class BindBlobToPayloadAndUserMetadataToHeadersWithPrefix extends BindBlobToPayload {
private final String metadataPrefix;
@Inject
public BindBlobToEntityAndUserMetadataToHeadersWithPrefix(
public BindBlobToPayloadAndUserMetadataToHeadersWithPrefix(
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
EncryptionService encryptionService) {
super(encryptionService);
this.metadataPrefix = metadataPrefix;
}
public void bindToRequest(HttpRequest request, Object entity) {
Blob object = (Blob) entity;
public void bindToRequest(HttpRequest request, Object payload) {
Blob object = (Blob) payload;
for (String key : object.getMetadata().getUserMetadata().keySet()) {
request.getHeaders().put(key.startsWith(metadataPrefix) ? key : metadataPrefix + key,
object.getMetadata().getUserMetadata().get(key));
}
super.bindToRequest(request, entity);
super.bindToRequest(request, payload);
}
}

View File

@ -43,8 +43,8 @@ public class BindMapToHeadersWithPrefix implements Binder {
}
@SuppressWarnings("unchecked")
public void bindToRequest(HttpRequest request, Object entity) {
Map<String, String> userMetadata = (Map<String, String>) entity;
public void bindToRequest(HttpRequest request, Object payload) {
Map<String, String> userMetadata = (Map<String, String>) payload;
for (Entry<String, String> entry : userMetadata.entrySet()) {
if (entry.getKey().startsWith(metadataPrefix)) {
request.getHeaders().put(entry.getKey().toLowerCase(), entry.getValue());

View File

@ -29,9 +29,7 @@ import javax.inject.Provider;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.internal.BlobImpl;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -55,17 +53,13 @@ public class BlobStoreObjectModule extends AbstractModule {
private static class BlobFactory implements Blob.Factory {
@Inject
GenerateMD5Result generateMD5Result;
@Inject
GenerateMD5 generateMD5;
@Inject
CalculateSize calculateSize;
EncryptionService encryptionService;
@Inject
Provider<MutableBlobMetadata> metadataProvider;
public Blob create(MutableBlobMetadata metadata) {
return new BlobImpl(generateMD5Result, generateMD5, calculateSize,
metadata != null ? metadata : metadataProvider.get());
return new BlobImpl(encryptionService, metadata != null ? metadata : metadataProvider
.get());
}
}

View File

@ -23,60 +23,24 @@
*/
package org.jclouds.blobstore.domain;
import org.jclouds.http.PayloadEnclosing;
import com.google.common.collect.Multimap;
import com.google.inject.internal.Nullable;
/**
* Value type for an HTTP Blob service. Blobs are stored in containers and consist
* of a {@link org.jclouds.blobstore.domain.Value#getData() value}, a {@link Blob#getKey key and
* of a {@link org.jclouds.blobstore.domain.Value#getContent() value}, a {@link Blob#getKey key and
*
* @link Blob.Metadata#getUserMetadata() metadata}
*
* @author Adrian Cole
*/
public interface Blob extends Comparable<Blob> {
public interface Blob extends PayloadEnclosing, Comparable<Blob> {
public interface Factory {
Blob create(@Nullable MutableBlobMetadata metadata);
}
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
void setData(Object data);
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
Object getData();
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*/
void generateMD5();
void setContentLength(long contentLength);
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getData()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
Long getContentLength();
/**
* @return System and User metadata relevant to this object.
*/

View File

@ -24,109 +24,39 @@
package org.jclouds.blobstore.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.InputStream;
import javax.inject.Inject;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.internal.BasePayloadEnclosingImpl;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
* Value type for an HTTP Blob service. Blobs are stored in {@link ResourceMetadata containers} and consist
* of a {@link org.jclouds.blobstore.domain.Value#getData() value}, a {@link Blob#getKey key and
* of a {@link org.jclouds.blobstore.domain.Value#getContent() value}, a {@link Blob#getKey key and
*
* @link Blob.Metadata#getUserMetadata() metadata}
*
* @author Adrian Cole
*/
public class BlobImpl implements Blob, Comparable<Blob> {
private final GenerateMD5Result generateMD5Result;
private final GenerateMD5 generateMD5;
private final CalculateSize calculateSize;
public class BlobImpl extends BasePayloadEnclosingImpl implements Blob, Comparable<Blob> {
private final MutableBlobMetadata metadata;
private Object data;
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
private Long contentLength;
@Inject
public BlobImpl(GenerateMD5Result generateMD5Result, GenerateMD5 generateMD5,
CalculateSize calculateSize, MutableBlobMetadata metadata) {
this.generateMD5Result = generateMD5Result;
this.generateMD5 = generateMD5;
this.calculateSize = calculateSize;
public BlobImpl(EncryptionService encryptionService, MutableBlobMetadata metadata) {
super(encryptionService);
this.metadata = metadata;
}
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
*/
public void generateMD5() {
checkState(data != null, "data");
if (data instanceof InputStream) {
MD5InputStreamResult result = generateMD5Result.apply((InputStream) data);
getMetadata().setContentMD5(result.md5);
setContentLength(result.length);
setData(result.data);
} else {
getMetadata().setContentMD5(generateMD5.apply(data));
}
}
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
public Object getData() {
return data;
}
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getContentLength() == null) {
Long size = calculateSize.apply(data);
if (size != null)
this.setContentLength(size);
}
}
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getData()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
public Long getContentLength() {
return contentLength;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
@Override
protected void setContentMD5(byte[] md5) {
getMetadata().setContentMD5(checkNotNull(md5, "md5"));
}
/**
@ -159,7 +89,7 @@ public class BlobImpl implements Blob, Comparable<Blob> {
int result = 1;
result = prime * result + ((allHeaders == null) ? 0 : allHeaders.hashCode());
result = prime * result + ((contentLength == null) ? 0 : contentLength.hashCode());
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((payload == null) ? 0 : payload.hashCode());
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
return result;
}
@ -183,10 +113,10 @@ public class BlobImpl implements Blob, Comparable<Blob> {
return false;
} else if (!contentLength.equals(other.contentLength))
return false;
if (data == null) {
if (other.data != null)
if (payload == null) {
if (other.payload != null)
return false;
} else if (!data.equals(other.data))
} else if (!payload.equals(other.payload))
return false;
if (metadata == null) {
if (other.metadata != null)

View File

@ -35,7 +35,7 @@ import org.jclouds.blobstore.domain.ResourceType;
import com.google.common.collect.Maps;
/**
* Identity of the object
* Idpayload of the object
*
* @author Adrian Cole
*/

View File

@ -36,7 +36,7 @@ import org.jclouds.blobstore.domain.ResourceType;
import com.google.inject.internal.Nullable;
/**
* Identity of the object
* Idpayload of the object
*
* @author Adrian Cole
*/

View File

@ -1,38 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.blobstore.functions;
import org.jclouds.blobstore.functions.impl.CalculateSizeByLength;
import com.google.common.base.Function;
import com.google.inject.ImplementedBy;
/**
*
* @author Adrian Cole
*/
@ImplementedBy(CalculateSizeByLength.class)
public interface CalculateSize extends Function<Object, Long> {
}

View File

@ -26,6 +26,7 @@ package org.jclouds.blobstore.functions;
import javax.inject.Inject;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.Payloads;
import com.google.common.base.Function;
@ -44,7 +45,7 @@ public class ObjectMD5 implements Function<Object, byte[]> {
object = (Blob) from;
} else {
object = blobFactory.create(null);
object.setData(from);
object.setPayload(Payloads.newPayload(from));
}
if (object.getMetadata().getContentMD5() == null)
object.generateMD5();

View File

@ -66,7 +66,7 @@ public class ParseBlobFromHeadersAndHttpContent implements Function<HttpResponse
MutableBlobMetadata metadata = metadataParser.apply(from);
Blob object = blobFactory.create(metadata);
addAllHeadersTo(from, object);
object.setData(from.getContent());
object.setPayload(from.getContent());
assert object.getMetadata() == metadata;
attemptToParseSizeAndRangeFromHeaders(from, object);
return object;

View File

@ -44,6 +44,12 @@ import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
import org.jclouds.blobstore.strategy.CountListStrategy;
import org.jclouds.blobstore.strategy.GetBlobsInListStrategy;
import org.jclouds.blobstore.strategy.ListBlobMetadataStrategy;
import org.jclouds.http.Payload;
import org.jclouds.http.Payloads;
import org.jclouds.http.payloads.ByteArrayPayload;
import org.jclouds.http.payloads.FilePayload;
import org.jclouds.http.payloads.InputStreamPayload;
import org.jclouds.http.payloads.StringPayload;
import org.jclouds.util.Utils;
import com.google.common.annotations.VisibleForTesting;
@ -81,7 +87,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
String realKey = prefixer.apply(o.toString());
try {
return (InputStream) (connection.getBlob(containerName, realKey).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).getData();
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).getContent();
} catch (KeyNotFoundException e) {
return null;
} catch (Exception e) {
@ -129,7 +135,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
return Collections2.transform(getAllBlobs.execute(containerName, options),
new Function<Blob, InputStream>() {
public InputStream apply(Blob from) {
return (InputStream) from.getData();
return (InputStream) from.getContent();
}
});
}
@ -143,7 +149,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
for (Blob object : this.getAllBlobs.execute(containerName, options)) {
entrySet.add(new Entry(pathStripper.apply(object.getMetadata().getName()),
(InputStream) object.getData()));
(InputStream) object.getContent()));
}
return entrySet;
}
@ -226,7 +232,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
Blob object = connection.newBlob();
object.getMetadata().setName(prefixer.apply(entry.getKey()));
object.setData(entry.getValue());
object.setPayload(Payloads.newPayload(entry.getValue()));
object.generateMD5();
puts.add(connection.putBlob(containerName, object));
// / ParamExtractor Funcion<?,String>
@ -248,7 +254,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
* @see #putInternal(String, Object)
*/
public InputStream putString(String key, String value) {
return putInternal(key, value);
return putInternal(key, new StringPayload(value));
}
/**
@ -257,7 +263,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
* @see #putInternal(String, Object)
*/
public InputStream putFile(String key, File value) {
return putInternal(key, value);
return putInternal(key, new FilePayload(value));
}
/**
@ -266,7 +272,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
* @see #putInternal(String, Object)
*/
public InputStream putBytes(String key, byte[] value) {
return putInternal(key, value);
return putInternal(key, new ByteArrayPayload(value));
}
/**
@ -275,7 +281,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
* @see #putInternal(String, Object)
*/
public InputStream put(String key, InputStream value) {
return putInternal(key, value);
return putInternal(key, new InputStreamPayload(value));
}
/**
@ -285,12 +291,12 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
* @see S3Client#put(String, Blob)
*/
@VisibleForTesting
InputStream putInternal(String s, Object o) {
InputStream putInternal(String s, Payload payload) {
Blob object = connection.newBlob();
object.getMetadata().setName(prefixer.apply(s));
try {
InputStream returnVal = containsKey(s) ? get(s) : null;
object.setData(o);
object.setPayload(payload);
object.generateMD5();
connection.putBlob(containerName, object).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);

View File

@ -133,7 +133,7 @@ public class GetOptions {
* Not compatible with {@link #ifETagDoesntMatch(String)} or {@link #ifModifiedSince(Date)}
*
* @param eTag
* hash representing the entity
* hash representing the payload
*/
public GetOptions ifETagMatches(String eTag) {
checkArgument(getIfNoneMatch() == null,
@ -147,7 +147,7 @@ public class GetOptions {
/**
* For use in the request header: If-Match
* <p />
* Return the object only if its entity tag (ETag) is the same as the eTag specified, otherwise
* Return the object only if its payload tag (ETag) is the same as the eTag specified, otherwise
* return a 412 (precondition failed).
*
* @see GetOptions#ifETagMatches(String)
@ -162,7 +162,7 @@ public class GetOptions {
* Not compatible with {@link #ifETagMatches(String)} or {@link #ifUnmodifiedSince(Date)}
*
* @param eTag
* hash representing the entity
* hash representing the payload
*/
public GetOptions ifETagDoesntMatch(String eTag) {
checkArgument(getIfMatch() == null,
@ -176,7 +176,7 @@ public class GetOptions {
/**
* For use in the request header: If-None-Match
* <p />
* Return the object only if its entity tag (ETag) is different from the one specified, otherwise
* Return the object only if its payload tag (ETag) is different from the one specified, otherwise
* return a 304 (not modified).
*
* @see GetOptions#ifETagDoesntMatch(String)

View File

@ -65,7 +65,7 @@ public class MarkerFileMkdirStrategy implements MkdirStrategy {
TimeUnit.MILLISECONDS)) {
Blob blob = connection.newBlob();
blob.getMetadata().setName(directory + directorySuffix);
blob.setData("");
blob.setPayload("");
blob.getMetadata().setContentType("application/directory");
connection.putBlob(containerName, blob).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);

View File

@ -40,6 +40,7 @@ import org.jclouds.util.Utils;
* @author Adrian Cole
*/
public class BlobStoreUtils {
public static Blob newBlob(BlobStore blobStore, ResourceMetadata blobMeta) {
Blob blob = blobStore.newBlob();
if (blobMeta instanceof BlobMetadata) {
@ -77,8 +78,8 @@ public class BlobStoreUtils {
public static String getContentAsStringAndClose(Blob blob) throws IOException {
checkNotNull(blob, "blob");
checkNotNull(blob.getData(), "blob.data");
Object o = blob.getData();
checkNotNull(blob.getContent(), "blob.data");
Object o = blob.getContent();
if (o instanceof InputStream) {
return Utils.toStringAndClose((InputStream) o);
} else {

View File

@ -63,7 +63,7 @@ public class BindBlobToMultipartFormTest {
EXPECTS = builder.toString();
TEST_BLOB = blobProvider.create(null);
TEST_BLOB.getMetadata().setName("hello");
TEST_BLOB.setData("hello");
TEST_BLOB.setPayload("hello");
TEST_BLOB.getMetadata().setContentType(MediaType.TEXT_PLAIN);
}
@ -76,7 +76,7 @@ public class BindBlobToMultipartFormTest {
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost:8001"));
binder.bindToRequest(request, TEST_BLOB);
assertEquals(Utils.toStringAndClose((InputStream) request.getEntity()), EXPECTS);
assertEquals(Utils.toStringAndClose((InputStream) request.getPayload().getRawContent()), EXPECTS);
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 131 + "");
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE),

View File

@ -47,6 +47,7 @@ import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.util.BlobStoreUtils;
import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.HttpResponseException;
import org.jclouds.http.Payloads;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -302,7 +303,7 @@ public class BaseBlobIntegrationTest<A, S> extends BaseBlobStoreIntegrationTest<
throws InterruptedException, IOException {
Blob object = newBlob(key);
object.getMetadata().setContentType(type);
object.setData(content);
object.setPayload(Payloads.newPayload(content));
if (content instanceof InputStream) {
object.generateMD5();
}
@ -323,7 +324,7 @@ public class BaseBlobIntegrationTest<A, S> extends BaseBlobStoreIntegrationTest<
String key = "hello";
Blob object = newBlob(key);
object.setData(TEST_STRING);
object.setPayload(TEST_STRING);
object.getMetadata().setContentType("text/plain");
object.getMetadata().setSize(new Long(TEST_STRING.length()));
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the

View File

@ -71,7 +71,7 @@ public class BaseBlobLiveTest<A, S> extends BaseBlobStoreIntegrationTest<A, S> {
InputStream input = connection.getInputStream();
Blob object = newBlob(key);
object.setData(input);
object.setPayload(input);
object.setContentLength(length);
object.getMetadata().setContentMD5(md5);
object.getMetadata().setSize(new Long(length));

View File

@ -115,7 +115,7 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
assertEquals(fiveStrings.get(entry.getKey()), BlobStoreUtils
.getContentAsStringAndClose(entry.getValue()));
Blob value = entry.getValue();
value.setData("");
value.setPayload("");
value.generateMD5();
entry.setValue(value);
}
@ -135,7 +135,7 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
Map<String, Blob> map = createMap(context, bucketName);
putStringWithMD5(map, "one", "apple");
Blob object = newBlob("one");
object.setData("apple");
object.setPayload("apple");
object.generateMD5();
assertConsistencyAwareContainsValue(map, object);
} finally {
@ -163,11 +163,11 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
try {
Map<String, Blob> map = createMap(context, bucketName);
Blob object = newBlob("one");
object.setData(IOUtils.toInputStream("apple"));
object.setPayload(IOUtils.toInputStream("apple"));
object.generateMD5();
Blob old = map.put(object.getMetadata().getName(), object);
getOneReturnsAppleAndOldValueIsNull(map, old);
object.setData(IOUtils.toInputStream("bear"));
object.setPayload(IOUtils.toInputStream("bear"));
object.generateMD5();
Blob apple = map.put(object.getMetadata().getName(), object);
getOneReturnsBearAndOldValueIsApple(map, apple);
@ -184,7 +184,7 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
Map<String, Blob> newMap = new HashMap<String, Blob>();
for (String key : fiveInputs.keySet()) {
Blob object = newBlob(key);
object.setData(fiveInputs.get(key));
object.setPayload(fiveInputs.get(key));
object.setContentLength(new Long(fiveBytes.get(key).length));
newMap.put(key, object);
}
@ -200,7 +200,7 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
@Override
protected void putStringWithMD5(Map<String, Blob> map, String key, String value) {
Blob object = newBlob(key);
object.setData(value);
object.setPayload(value);
object.generateMD5();
map.put(key, object);
}
@ -209,7 +209,7 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
Map<String, Blob> newMap = new HashMap<String, Blob>();
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
Blob object = newBlob(entry.getKey());
object.setData(entry.getValue());
object.setPayload(entry.getValue());
newMap.put(entry.getKey(), object);
}
map.putAll(newMap);
@ -219,7 +219,7 @@ public class BaseBlobMapIntegrationTest<A, S> extends BaseMapIntegrationTest<A,
Map<String, Blob> newMap = new HashMap<String, Blob>();
for (Map.Entry<String, String> entry : fiveStringsUnderPath.entrySet()) {
Blob object = newBlob(entry.getKey());
object.setData(entry.getValue());
object.setPayload(entry.getValue());
newMap.put(entry.getKey(), object);
}
map.putAll(newMap);

View File

@ -263,7 +263,7 @@ public class BaseBlobStoreIntegrationTest<A, S> {
protected String addBlobToContainer(String sourceContainer, String key) {
Blob sourceObject = newBlob(key);
sourceObject.getMetadata().setContentType("text/xml");
sourceObject.setData(TEST_STRING);
sourceObject.setPayload(TEST_STRING);
return addBlobToContainer(sourceContainer, sourceObject);
}
@ -272,7 +272,7 @@ public class BaseBlobStoreIntegrationTest<A, S> {
fiveStringsUnderPath.entrySet())) {
Blob sourceObject = newBlob(entry.getKey());
sourceObject.getMetadata().setContentType("text/xml");
sourceObject.setData(entry.getValue());
sourceObject.setPayload(entry.getValue());
addBlobToContainer(sourceContainer, sourceObject);
}
}

View File

@ -202,7 +202,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
protected void addAlphabetUnderRoot(String containerName) throws InterruptedException {
for (char letter = 'a'; letter <= 'z'; letter++) {
Blob blob = newBlob(letter + "");
blob.setData(letter + "content");
blob.setPayload(letter + "content");
context.getBlobStore().putBlob(containerName, blob);
}
}
@ -210,7 +210,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
protected void add15UnderRoot(String containerName) throws InterruptedException {
for (int i = 0; i < 15; i++) {
Blob blob = newBlob(i + "");
blob.setData(i + "content");
blob.setPayload(i + "content");
context.getBlobStore().putBlob(containerName, blob);
}
}
@ -219,7 +219,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
throws InterruptedException {
for (int i = 0; i < 10; i++) {
Blob blob = newBlob(prefix + "/" + i);
blob.setData(i + "content");
blob.setPayload(i + "content");
context.getBlobStore().putBlob(containerName, blob);
}
}

View File

@ -168,7 +168,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
Blob object = realContents.get(key);
Blob returnVal = blobProvider.create(copy(object.getMetadata()));
returnVal.setData(new ByteArrayInputStream((byte[]) object.getData()));
returnVal.setPayload(object.getContent());
return returnVal;
}
};
@ -512,7 +512,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
new RuntimeException("bucketName not found: " + bucketName);
}
try {
byte[] data = toByteArray(object.getData());
byte[] data = toByteArray(object.getPayload().getRawContent());
object.getMetadata().setSize(data.length);
MutableBlobMetadata newMd = copy(object.getMetadata());
newMd.setLastModified(new Date());
@ -523,7 +523,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
newMd.setContentType(object.getMetadata().getContentType());
Blob blob = blobProvider.create(newMd);
blob.setData(data);
blob.setPayload(data);
container.put(blob.getMetadata().getName(), blob);
// Set HTTP headers to match metadata
@ -592,7 +592,12 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
Blob returnVal = copyBlob(object);
if (options.getRanges() != null && options.getRanges().size() > 0) {
byte[] data = (byte[]) returnVal.getData();
byte[] data;
try {
data = IOUtils.toByteArray(returnVal.getPayload().getContent());
} catch (IOException e) {
throw new RuntimeException(e);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (String s : options.getRanges()) {
if (s.startsWith("-")) {
@ -612,11 +617,11 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
}
}
returnVal.setData(out.toByteArray());
returnVal.setPayload(out.toByteArray());
returnVal.setContentLength(out.size());
returnVal.getMetadata().setSize(new Long(data.length));
}
returnVal.setData(new ByteArrayInputStream((byte[]) returnVal.getData()));
returnVal.setPayload(returnVal.getPayload());
return returnVal;
}
};
@ -638,7 +643,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
private Blob copyBlob(Blob object) {
Blob returnVal = blobProvider.create(copy(object.getMetadata()));
returnVal.setData(object.getData());
returnVal.setPayload(object.getPayload());
return returnVal;
}

View File

@ -76,7 +76,7 @@ public class RetryOnNotFoundGetAllBlobsStrategyTest {
Future<Blob> futureObject = createMock(Future.class);
Blob object = blobProvider.create(null);
object.getMetadata().setName("key");
object.setData("goo");
object.setPayload("goo");
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
new KeyNotFoundException());
context.getInstance(AsyncBlobStore.class).putBlob("container", object).get();
@ -86,7 +86,7 @@ public class RetryOnNotFoundGetAllBlobsStrategyTest {
map.ifNotFoundRetryOtherwiseAddToSet("container", "key", futureObject, objects);
// should have retried once
assert System.currentTimeMillis() >= time + map.requestRetryMilliseconds;
assertEquals(IOUtils.toString((InputStream) objects.iterator().next().getData()), "goo");
assertEquals(IOUtils.toString((InputStream) objects.iterator().next().getContent()), "goo");
assert !objects.contains(null);
}

View File

@ -26,6 +26,8 @@ package org.jclouds.http;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
@ -48,7 +50,7 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
private String method;
private URI endpoint;
private Object entity;
private Payload payload;
/**
*
@ -84,10 +86,10 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
* If the request is HEAD, this may change to GET due to redirects
*/
protected HttpRequest(String method, URI endPoint, Multimap<String, String> headers,
@Nullable Object entity) {
@Nullable Payload payload) {
this(method, endPoint);
getHeaders().putAll(checkNotNull(headers, "headers"));
setEntity(entity);
setPayload(payload);
}
public String getRequestLine() {
@ -104,16 +106,51 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
return method;
}
public Object getEntity() {
return entity;
public Payload getPayload() {
return payload;
}
public void setEntity(Object content) {
if (content instanceof String
&& this.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH) == null) {
getHeaders().put(HttpHeaders.CONTENT_LENGTH, content.toString().getBytes().length + "");
/**
* {@inheritDoc}
*/
public void setPayload(Payload data) {
this.payload = checkNotNull(data, "data");
setLength();
}
/**
* {@inheritDoc}
*/
public void setPayload(InputStream data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
/**
* {@inheritDoc}
*/
public void setPayload(byte[] data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
/**
* {@inheritDoc}
*/
public void setPayload(String data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
/**
* {@inheritDoc}
*/
public void setPayload(File data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
private void setLength() {
Long size = getPayload().calculateSize();
if (size != null && this.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH) == null) {
getHeaders().put(HttpHeaders.CONTENT_LENGTH, size.toString());
}
this.entity = content;
}
public URI getEndpoint() {

View File

@ -26,7 +26,6 @@ package org.jclouds.http;
import static com.google.common.base.Preconditions.checkState;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -58,18 +57,6 @@ public class HttpUtils {
public static final Pattern URI_PATTERN = Pattern.compile("([a-z0-9]+)://([^:]*):(.*)@(.*)");
public static final Pattern PATTERN_THAT_BREAKS_URI = Pattern.compile("[a-z0-9]+://.*/.*@.*"); // slash
public static Long calculateSize(Object data) {
Long size = null;
if (data instanceof byte[]) {
size = new Long(((byte[]) data).length);
} else if (data instanceof String) {
size = new Long(((String) data).length());
} else if (data instanceof File) {
size = ((File) data).length();
}
return size;
}
@Resource
protected static Logger logger = Logger.NULL;

View File

@ -21,22 +21,42 @@
* under the License.
* ====================================================================
*/
package org.jclouds.blobstore.functions.impl;
package org.jclouds.http;
import javax.inject.Singleton;
import org.jclouds.blobstore.functions.CalculateSize;
import org.jclouds.http.HttpUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
*
* @author Adrian Cole
*/
@Singleton
public class CalculateSizeByLength implements CalculateSize {
public interface Payload {
public Long apply(Object from) {
return HttpUtils.calculateSize(from);
}
/**
*  Creates a new InputStream object of the payload.
*/
InputStream getContent();
/**
* Payload in its original form.
*/
Object getRawContent();
/**
* Tells if the payload is capable of producing its data more than once.
*/
boolean isRepeatable();
}
/**
*  Writes the payload content to the output stream.
*
* @throws IOException
*/
void writeTo(OutputStream outstream) throws IOException;
/**
* Attempts to determine the size of the payload
*/
Long calculateSize();
}

View File

@ -0,0 +1,61 @@
package org.jclouds.http;
import java.io.File;
import java.io.InputStream;
/**
*
* @author Adrian Cole
*/
public interface PayloadEnclosing {
/**
* Sets payload for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
void setPayload(Payload data);
void setPayload(File data);
void setPayload(byte[] data);
void setPayload(InputStream data);
void setPayload(String data);
Payload getPayload();
/**
* @return InputStream, if downloading, or whatever was set during {@link #setPayload(Object)}
*/
InputStream getContent();
void setContentLength(long contentLength);
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getContent()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
Long getContentLength();
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*/
void generateMD5();
}

View File

@ -0,0 +1,52 @@
package org.jclouds.http;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.InputStream;
import org.jclouds.http.payloads.ByteArrayPayload;
import org.jclouds.http.payloads.FilePayload;
import org.jclouds.http.payloads.InputStreamPayload;
import org.jclouds.http.payloads.StringPayload;
/**
*
* @author Adrian Cole
*/
public class Payloads {
public static Payload newPayload(Object data) {
checkNotNull(data, "data");
if (data instanceof Payload) {
return (Payload) data;
} else if (data instanceof InputStream) {
return newInputStreamPayload((InputStream) data);
} else if (data instanceof byte[]) {
return newByteArrayPayload((byte[]) data);
} else if (data instanceof String) {
return newStringPayload((String) data);
} else if (data instanceof File) {
return newFilePayload((File) data);
} else {
throw new UnsupportedOperationException("unsupported payload type: " + data.getClass());
}
}
public static InputStreamPayload newInputStreamPayload(InputStream data) {
return new InputStreamPayload(checkNotNull(data, "data"));
}
public static ByteArrayPayload newByteArrayPayload(byte[] data) {
return new ByteArrayPayload(checkNotNull(data, "data"));
}
public static StringPayload newStringPayload(String data) {
return new StringPayload(checkNotNull(data, "data"));
}
public static FilePayload newFilePayload(File data) {
return new FilePayload(checkNotNull(data, "data"));
}
}

View File

@ -23,7 +23,6 @@
*/
package org.jclouds.http;
import java.io.InputStream;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -127,12 +126,7 @@ public class TransformingHttpCommandImpl<T> implements TransformingHttpCommand<T
}
public boolean isReplayable() {
Object content = request.getEntity();
if (content != null && content instanceof InputStream) {
logger.warn("%1$s: InputStreams are not replayable", toString());
return false;
}
return true;
return (request.getPayload() == null) ? true : request.getPayload().isRepeatable();
}
/**
@ -140,7 +134,6 @@ public class TransformingHttpCommandImpl<T> implements TransformingHttpCommand<T
* IOUtils.closeQuietly(getResponse().getContent()); throw new
* IllegalStateException("incorrect code for this operation: " + getResponse()); } }
**/
public HttpRequest getRequest() {
return request;
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.http.config;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.TransformingHttpCommandExecutorService;
import org.jclouds.http.TransformingHttpCommandExecutorServiceImpl;
@ -39,6 +40,7 @@ import com.google.inject.Scopes;
* @author Adrian Cole
*/
@ConfiguresHttpCommandExecutorService
@SingleThreaded
public class JavaUrlHttpCommandExecutorServiceModule extends AbstractModule {
@Override

View File

@ -43,14 +43,14 @@ public class ReturnStringIf200 implements Function<HttpResponse,String> {
public String apply(HttpResponse from) {
if (from.getStatusCode() == 200) {
InputStream entity = from.getContent();
if (entity == null)
InputStream payload = from.getContent();
if (payload == null)
throw new HttpException("no content");
String toReturn = null;
try {
toReturn = Utils.toStringAndClose(entity);
toReturn = Utils.toStringAndClose(payload);
} catch (IOException e) {
throw new HttpException(String.format("Couldn't receive response %1$s, entity: %2$s ",
throw new HttpException(String.format("Couldn't receive response %1$s, payload: %2$s ",
from, toReturn), e);
}
return toReturn;

View File

@ -38,6 +38,7 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.Payloads;
import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.logging.Logger;
@ -86,8 +87,9 @@ public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandEx
filter.filter(request);
}
logger.debug("Sending request %s: %s", request.hashCode(), request.getRequestLine());
if (request.getEntity() != null && wire.enabled())
request.setEntity(wire.output(request.getEntity()));
if (request.getPayload() != null && wire.enabled())
request.setPayload(Payloads.newPayload(wire.output(request.getPayload()
.getRawContent())));
nativeRequest = convert(request);
HttpUtils.logRequest(headerLog, request, ">>");
response = invoke(nativeRequest);

View File

@ -0,0 +1,130 @@
package org.jclouds.http.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.File;
import java.io.InputStream;
import javax.inject.Inject;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.EncryptionService.MD5InputStreamResult;
import org.jclouds.http.Payload;
import org.jclouds.http.PayloadEnclosing;
import org.jclouds.http.Payloads;
import org.jclouds.http.payloads.InputStreamPayload;
/**
*
* @author Adrian Cole
*/
public abstract class BasePayloadEnclosingImpl implements PayloadEnclosing {
private final EncryptionService encryptionService;
protected Payload payload;
protected Long contentLength;
@Inject
public BasePayloadEnclosingImpl(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
*/
public void generateMD5() {
checkState(payload != null, "payload");
if (payload instanceof InputStreamPayload) {
MD5InputStreamResult result = encryptionService
.generateMD5Result(((InputStreamPayload) payload).getContent());
setContentMD5(result.md5);
setContentLength(result.length);
setPayload(result.data);
} else {
setContentMD5(encryptionService.md5(payload.getRawContent()));
}
}
protected abstract void setContentMD5(byte[] md5);
/**
* @return InputStream, if downloading, or whatever was set during {@link #setPayload(Object)}
*/
public InputStream getContent() {
checkState(payload != null, "payload");
return payload.getContent();
}
@Override
public Payload getPayload() {
return payload;
}
/**
* {@inheritDoc}
*/
public void setPayload(Payload data) {
this.payload = checkNotNull(data, "data");
setLength();
}
/**
* {@inheritDoc}
*/
public void setPayload(InputStream data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
/**
* {@inheritDoc}
*/
public void setPayload(byte[] data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
/**
* {@inheritDoc}
*/
public void setPayload(String data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
/**
* {@inheritDoc}
*/
public void setPayload(File data) {
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
}
private void setLength() {
if (getContentLength() == null) {
Long size = payload.calculateSize();
if (size != null)
this.setContentLength(size);
}
}
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getContent()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
public Long getContentLength() {
return contentLength;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
}

View File

@ -23,12 +23,9 @@
*/
package org.jclouds.http.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
@ -133,23 +130,10 @@ public class JavaUrlHttpCommandExecutorService extends
}
}
connection.setRequestProperty(HttpHeaders.HOST, request.getEndpoint().getHost());
if (request.getEntity() != null) {
if (request.getPayload() != null) {
OutputStream out = connection.getOutputStream();
try {
if (request.getEntity() instanceof String) {
OutputStreamWriter writer = new OutputStreamWriter(out);
writer.write((String) request.getEntity());
writer.close();
} else if (request.getEntity() instanceof InputStream) {
IOUtils.copy((InputStream) request.getEntity(), out);
} else if (request.getEntity() instanceof File) {
IOUtils.copy(new FileInputStream((File) request.getEntity()), out);
} else if (request.getEntity() instanceof byte[]) {
IOUtils.write((byte[]) request.getEntity(), out);
} else {
throw new UnsupportedOperationException("Content not supported "
+ request.getEntity().getClass());
}
request.getPayload().writeTo(out);
} finally {
IOUtils.closeQuietly(out);
}

View File

@ -40,11 +40,11 @@ public class BaseHttpRequestOptions implements HttpRequestOptions {
protected Multimap<String, String> formParameters = LinkedHashMultimap.create();
protected Multimap<String, String> queryParameters = LinkedHashMultimap.create();
protected Multimap<String, String> headers = LinkedHashMultimap.create();
protected String entity;
protected String payload;
protected String pathSuffix;
public String buildStringEntity() {
return entity;
public String buildStringPayload() {
return payload;
}
protected String getFirstMatrixOrNull(String string) {

View File

@ -169,7 +169,7 @@ public class GetOptions extends BaseHttpRequestOptions {
* Not compatible with {@link #ifETagDoesntMatch(byte[])} or {@link #ifModifiedSince(Date)}
*
* @param eTag
* hash representing the entity
* hash representing the payload
* @throws UnsupportedEncodingException
* if there was a problem converting this into an S3 eTag string
*/
@ -185,7 +185,7 @@ public class GetOptions extends BaseHttpRequestOptions {
/**
* For use in the request header: If-Match
* <p />
* Return the object only if its entity tag (ETag) is the same as the eTag specified, otherwise
* Return the object only if its payload tag (ETag) is the same as the eTag specified, otherwise
* return a 412 (precondition failed).
*
* @see GetOptions#ifETagMatches(byte[])
@ -200,7 +200,7 @@ public class GetOptions extends BaseHttpRequestOptions {
* Not compatible with {@link #ifETagMatches(String)} or {@link #ifUnmodifiedSince(Date)}
*
* @param eTag
* hash representing the entity
* hash representing the payload
* @throws UnsupportedEncodingException
* if there was a problem converting this into an S3 eTag string
*/
@ -217,7 +217,7 @@ public class GetOptions extends BaseHttpRequestOptions {
/**
* For use in the request header: If-None-Match
* <p />
* Return the object only if its entity tag (ETag) is different from the one specified, otherwise
* Return the object only if its payload tag (ETag) is different from the one specified, otherwise
* return a 304 (not modified).
*
* @see GetOptions#ifETagDoesntMatch(byte[])

View File

@ -61,7 +61,7 @@ public interface HttpRequestOptions {
*/
Multimap<String, String> buildMatrixParameters();
String buildStringEntity();
String buildStringPayload();
String buildPathSuffix();

View File

@ -0,0 +1,78 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.http.payloads;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.jclouds.http.Payload;
/**
* @author Adrian Cole
*/
public class ByteArrayPayload implements Payload {
private final byte[] content;
public ByteArrayPayload(byte[] content) {
this.content = checkNotNull(content, "content");
}
public byte[] getRawContent() {
return content;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getContent() {
return new ByteArrayInputStream(content);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRepeatable() {
return true;
}
/**
* {@inheritDoc}
*/
@Override
public void writeTo(OutputStream outstream) throws IOException {
IOUtils.write(content, outstream);
}
@Override
public Long calculateSize() {
return new Long(content.length);
}
}

View File

@ -0,0 +1,94 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.http.payloads;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.jclouds.http.Payload;
/**
* @author Adrian Cole
*/
public class FilePayload implements Payload {
private final File content;
public FilePayload(File content) {
checkArgument(checkNotNull(content, "content").exists(), "file must exist: " + content);
this.content = content;
}
public File getRawContent() {
return content;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getContent() {
try {
return new FileInputStream(content);
} catch (FileNotFoundException e) {
throw new IllegalStateException("file " + content + " does not exist", e);
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRepeatable() {
return true;
}
/**
* {@inheritDoc}
*/
@Override
public void writeTo(OutputStream outstream) throws IOException {
InputStream in = getContent();
try {
IOUtils.copy(getContent(), outstream);
} finally {
IOUtils.closeQuietly(in);
}
}
/**
* {@inheritDoc}
*/
@Override
public Long calculateSize() {
return content.length();
}
}

View File

@ -0,0 +1,85 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.http.payloads;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.jclouds.http.Payload;
/**
* @author Adrian Cole
*/
public class InputStreamPayload implements Payload {
private final InputStream content;
public InputStreamPayload(InputStream content) {
this.content = checkNotNull(content, "content");
}
public InputStream getRawContent() {
return content;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getContent() {
return content;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRepeatable() {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void writeTo(OutputStream outstream) throws IOException {
InputStream in = getContent();
try {
IOUtils.copy(getContent(), outstream);
} finally {
IOUtils.closeQuietly(in);
}
}
/**
* {@inheritDoc}
*/
@Override
public Long calculateSize() {
return null;
}
}

View File

@ -0,0 +1,85 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.http.payloads;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.jclouds.http.Payload;
/**
* @author Adrian Cole
*/
public class StringPayload implements Payload {
private final String content;
public StringPayload(String content) {
this.content = checkNotNull(content, "content");
}
public String getRawContent() {
return content;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getContent() {
return IOUtils.toInputStream(content);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRepeatable() {
return true;
}
/**
* {@inheritDoc}
*/
@Override
public void writeTo(OutputStream outstream) throws IOException {
IOUtils.write(content.getBytes(), outstream);
}
/**
* {@inheritDoc}
*/
@Override
public Long calculateSize() {
return new Long(content.length());
}
@Override
public String toString() {
return content;
}
}

View File

@ -26,7 +26,7 @@ package org.jclouds.rest;
import org.jclouds.http.HttpRequest;
/**
* Adds an entity to a request.
* Adds an payload to a request.
*
* @author Adrian Cole
*/

View File

@ -28,7 +28,7 @@ import java.util.Map;
import org.jclouds.http.HttpRequest;
/**
* Builds the entity of a Post request.
* Builds the payload of a Post request.
*
* @author Adrian Cole
*
@ -36,9 +36,9 @@ import org.jclouds.http.HttpRequest;
public interface MapBinder extends Binder {
/**
* creates and binds the POST entity to the request using parameters specified.
* creates and binds the POST payload to the request using parameters specified.
*
* @see MapEntityParam
* @see MapPayloadParam
*/
public void bindToRequest(HttpRequest request, Map<String, String> postParams);

View File

@ -32,7 +32,7 @@ import java.lang.annotation.Target;
import org.jclouds.rest.Binder;
/**
* Designates that this parameter will modify the request, possibly including adding an entity to
* Designates that this parameter will modify the request, possibly including adding an payload to
* it.
*
* @author Adrian Cole
@ -42,7 +42,7 @@ import org.jclouds.rest.Binder;
public @interface BinderParam {
/**
* how to persist this entity.
* how to persist this payload.
*/
Class<? extends Binder> value();
}

View File

@ -30,7 +30,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Designates that this parameter will hold the entity for a PUT or POST command.
* Designates that this parameter will hold the payload for a PUT or POST command.
*
* @author Adrian Cole
*/
@ -39,7 +39,7 @@ import java.lang.annotation.Target;
public @interface MapBinder {
/**
* How to bind {@link MapEntityParam} values, if there is no {@link MapBinder} in the method
* How to bind {@link MapPayloadParam} values, if there is no {@link MapBinder} in the method
* definition
*/
Class<? extends org.jclouds.rest.MapBinder> value();

View File

@ -30,13 +30,13 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Designates that this parameter will hold the entity for a PUT or POST command.
* Designates that this parameter will hold the payload for a PUT or POST command.
*
* @author Adrian Cole
*/
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface MapEntityParam {
public @interface MapPayloadParam {
/**
* The key used in a map passed to the {@link MapBinder} associated with the request.

View File

@ -43,7 +43,7 @@ import com.google.gson.Gson;
* @author Adrian Cole
* @since 4.0
*/
public class BindToJsonEntity implements MapBinder {
public class BindToJsonPayload implements MapBinder {
@Inject
protected Gson gson;
@ -55,7 +55,7 @@ public class BindToJsonEntity implements MapBinder {
public void bindToRequest(HttpRequest request, Object toBind) {
checkState(gson != null, "Program error: gson should have been injected at this point");
String json = gson.toJson(toBind);
request.setEntity(json);
request.setPayload(json);
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
Collections.singletonList(json.getBytes().length + ""));
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,

View File

@ -32,17 +32,17 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Adds an entity to a request.
* Adds an payload to a request.
*
* @author Adrian Cole
*/
@Singleton
public class BindToStringEntity implements Binder {
public void bindToRequest(HttpRequest request, Object entity) {
String stringEntity = entity.toString();
public class BindToStringPayload implements Binder {
public void bindToRequest(HttpRequest request, Object payload) {
String stringPayload = payload.toString();
if (request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE) == null)
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown");
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,Collections.singletonList(stringEntity.getBytes().length + ""));
request.setEntity(stringEntity);
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,Collections.singletonList(stringPayload.getBytes().length + ""));
request.setPayload(stringPayload);
}
}

View File

@ -91,6 +91,8 @@ public class GeneratedHttpRequest<T> extends HttpRequest {
}
public void addFormParam(String name, String... values) {
this.setEntity(processor.addFormParam(getEntity().toString(), name, values));
this
.setPayload(processor.addFormParam(getPayload().getRawContent().toString(), name,
values));
}
}

View File

@ -84,7 +84,7 @@ import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.HostPrefixParam;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapEntityParam;
import org.jclouds.rest.annotations.MapPayloadParam;
import org.jclouds.rest.annotations.MatrixParams;
import org.jclouds.rest.annotations.OverrideRequestFilters;
import org.jclouds.rest.annotations.ParamParser;
@ -132,7 +132,7 @@ public class RestAnnotationProcessor<T> {
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToFormParamAnnotations = createMethodToIndexOfParamToAnnotation(FormParam.class);
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToQueryParamAnnotations = createMethodToIndexOfParamToAnnotation(QueryParam.class);
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class);
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapEntityParam.class);
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapPayloadParam.class);
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToParamParserAnnotations = createMethodToIndexOfParamToAnnotation(ParamParser.class);
private final Map<MethodKey, Method> delegationMap = Maps.newHashMap();
@ -329,7 +329,7 @@ public class RestAnnotationProcessor<T> {
Multimap<String, String> headers = buildHeaders(tokenValues.entries(), method, args);
String stringEntity = null;
String stringPayload = null;
HttpRequestOptions options = findOptionsIn(method, args);
if (options != null) {
injector.injectMembers(options);// TODO test case
@ -351,7 +351,7 @@ public class RestAnnotationProcessor<T> {
if (pathSuffix != null) {
builder.path(pathSuffix);
}
stringEntity = options.buildStringEntity();
stringPayload = options.buildStringPayload();
}
if (queryParams.size() > 0) {
@ -375,13 +375,13 @@ public class RestAnnotationProcessor<T> {
if (formParams.size() > 0) {
if (headers.get(HttpHeaders.CONTENT_TYPE) != null)
headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED);
request.setEntity(makeQueryLine(formParams, null, skips));
request.setPayload(makeQueryLine(formParams, null, skips));
}
if (stringEntity != null) {
request.setEntity(stringEntity);
if (stringPayload != null) {
request.setPayload(stringPayload);
if (headers.get(HttpHeaders.CONTENT_LENGTH) != null)
headers.put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
headers.put(HttpHeaders.CONTENT_LENGTH, stringPayload.getBytes().length + "");
if (headers.get(HttpHeaders.CONTENT_TYPE) != null)
headers.put(HttpHeaders.CONTENT_TYPE, "application/unknown");
}
@ -669,7 +669,7 @@ public class RestAnnotationProcessor<T> {
return null;
}
public org.jclouds.rest.MapBinder getMapEntityBinderOrNull(Method method, Object... args) {
public org.jclouds.rest.MapBinder getMapPayloadBinderOrNull(Method method, Object... args) {
if (args != null) {
for (Object arg : args) {
if (arg instanceof Object[]) {
@ -737,11 +737,11 @@ public class RestAnnotationProcessor<T> {
}
public void decorateRequest(GeneratedHttpRequest<T> request) {
org.jclouds.rest.MapBinder mapBinder = getMapEntityBinderOrNull(request.getJavaMethod(),
org.jclouds.rest.MapBinder mapBinder = getMapPayloadBinderOrNull(request.getJavaMethod(),
request.getArgs());
Map<String, String> mapParams = buildPostParams(request.getJavaMethod(), request.getArgs());
// MapEntityBinder is only useful if there are parameters. We guard here in case the
// MapEntityBinder is also an EntityBinder. If so, it can be used with or without
// MapPayloadBinder is only useful if there are parameters. We guard here in case the
// MapPayloadBinder is also an PayloadBinder. If so, it can be used with or without
// parameters.
if (mapBinder != null) {
mapBinder.bindToRequest(request, mapParams);
@ -756,8 +756,8 @@ public class RestAnnotationProcessor<T> {
}
}).entrySet()) {
boolean shouldBreak = false;
BinderParam entityAnnotation = (BinderParam) entry.getValue().iterator().next();
Binder binder = injector.getInstance(entityAnnotation.value());
BinderParam payloadAnnotation = (BinderParam) entry.getValue().iterator().next();
Binder binder = injector.getInstance(payloadAnnotation.value());
if (request.getArgs().length != 0) {
Object input;
Class<?> parameterType = request.getJavaMethod().getParameterTypes()[entry.getKey()];
@ -778,8 +778,8 @@ public class RestAnnotationProcessor<T> {
} else {
input = request.getArgs()[entry.getKey()];
if (input.getClass().isArray()) {
Object[] entityArray = (Object[]) input;
input = entityArray.length > 0 ? entityArray[0] : null;
Object[] payloadArray = (Object[]) input;
input = payloadArray.length > 0 ? payloadArray[0] : null;
}
}
if (input != null) {
@ -789,27 +789,29 @@ public class RestAnnotationProcessor<T> {
break OUTER;
}
}
if (request.getMethod().equals("PUT") && request.getEntity() == null) {
if (request.getMethod().equals("PUT") && request.getPayload() == null) {
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
Collections.singletonList(0 + ""));
}
if (request.getPayload() != null)
assert request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH) != null : "no content length";
}
protected Map<Integer, Set<Annotation>> indexWithOnlyOneAnnotation(Method method,
String description, Map<Method, Map<Integer, Set<Annotation>>> toRefine) {
Map<Integer, Set<Annotation>> indexToEntityAnnotation = Maps.filterValues(toRefine
Map<Integer, Set<Annotation>> indexToPayloadAnnotation = Maps.filterValues(toRefine
.get(method), new Predicate<Set<Annotation>>() {
public boolean apply(Set<Annotation> input) {
return input.size() == 1;
}
});
if (indexToEntityAnnotation.size() > 1) {
if (indexToPayloadAnnotation.size() > 1) {
throw new IllegalStateException(String.format(
"You must not specify more than one %s annotation on: %s; found %s", description,
method.toString(), indexToEntityAnnotation));
method.toString(), indexToPayloadAnnotation));
}
return indexToEntityAnnotation;
return indexToPayloadAnnotation;
}
private HttpRequestOptions findOptionsIn(Method method, Object... args) {
@ -1069,7 +1071,7 @@ public class RestAnnotationProcessor<T> {
for (Entry<Integer, Set<Annotation>> entry : indexToPathParam.entrySet()) {
for (Annotation key : entry.getValue()) {
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
String paramKey = ((MapEntityParam) key).value();
String paramKey = ((MapPayloadParam) key).value();
String paramValue;
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();

View File

@ -41,12 +41,12 @@ import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapEntityParam;
import org.jclouds.rest.annotations.MapPayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.binders.BindMapToMatrixParams;
import org.jclouds.rest.binders.BindToJsonEntity;
import org.jclouds.rest.binders.BindToStringEntity;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.internal.RestAnnotationProcessorTest.Localhost;
import com.google.common.base.Function;
@ -92,30 +92,30 @@ public interface IntegrationTestAsyncClient {
@PUT
@Path("objects/{id}")
Future<String> upload(@PathParam("id") String id,
@BinderParam(BindToStringEntity.class) String toPut);
@BinderParam(BindToStringPayload.class) String toPut);
@POST
@Path("objects/{id}")
Future<String> post(@PathParam("id") String id,
@BinderParam(BindToStringEntity.class) String toPut);
@BinderParam(BindToStringPayload.class) String toPut);
@POST
@Path("objects/{id}")
Future<String> postAsInputStream(@PathParam("id") String id,
@BinderParam(BindToInputStreamEntity.class) String toPut);
@BinderParam(BindToInputStreamPayload.class) String toPut);
static class BindToInputStreamEntity extends BindToStringEntity {
static class BindToInputStreamPayload extends BindToStringPayload {
@Override
public void bindToRequest(HttpRequest request, Object entity) {
super.bindToRequest(request, entity);
request.setEntity(IOUtils.toInputStream(entity.toString()));
public void bindToRequest(HttpRequest request, Object payload) {
super.bindToRequest(request, payload);
request.setPayload(IOUtils.toInputStream(payload.toString()));
}
}
@POST
@Path("objects/{id}")
@MapBinder(BindToJsonEntity.class)
Future<String> postJson(@PathParam("id") String id, @MapEntityParam("key") String toPut);
@MapBinder(BindToJsonPayload.class)
Future<String> postJson(@PathParam("id") String id, @MapPayloadParam("key") String toPut);
@POST
@Path("objects/{id}/action/{action}")

View File

@ -27,7 +27,6 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.apache.commons.io.IOUtils;
@ -55,6 +54,7 @@ public abstract class RestClientTest<T> {
protected abstract Module createModule();
protected abstract void checkFilters(GeneratedHttpRequest<T> httpMethod);
protected abstract TypeLiteral<RestAnnotationProcessor<T>> createTypeLiteral();
@BeforeClass
@ -63,18 +63,16 @@ public abstract class RestClientTest<T> {
injector = Guice.createInjector(createModule(), new RestModule(), new ExecutorServiceModule(
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
processor = injector.getInstance(Key
.get(createTypeLiteral()));
processor = injector.getInstance(Key.get(createTypeLiteral()));
}
protected void assertEntityEquals(GeneratedHttpRequest<T> httpMethod, String toMatch)
protected void assertPayloadEquals(GeneratedHttpRequest<T> httpMethod, String toMatch)
throws IOException {
if (httpMethod.getEntity() == null) {
if (httpMethod.getPayload() == null) {
assertNull(toMatch);
} else {
String entity = (httpMethod.getEntity() instanceof String) ? httpMethod.getEntity()
.toString() : IOUtils.toString((InputStream) httpMethod.getEntity());
assertEquals(entity, toMatch);
String payload = IOUtils.toString(httpMethod.getPayload().getContent());
assertEquals(payload, toMatch);
}
}
@ -82,8 +80,7 @@ public abstract class RestClientTest<T> {
assertEquals(HttpUtils.sortAndConcatHeadersIntoString(httpMethod.getHeaders()), toMatch);
}
protected void assertRequestLineEquals(GeneratedHttpRequest<T> httpMethod,
String toMatch) {
protected void assertRequestLineEquals(GeneratedHttpRequest<T> httpMethod, String toMatch) {
assertEquals(httpMethod.getRequestLine(), toMatch);
}

View File

@ -88,7 +88,7 @@ import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.HostPrefixParam;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapEntityParam;
import org.jclouds.rest.annotations.MapPayloadParam;
import org.jclouds.rest.annotations.MatrixParams;
import org.jclouds.rest.annotations.OverrideRequestFilters;
import org.jclouds.rest.annotations.ParamParser;
@ -98,8 +98,8 @@ import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.binders.BindMapToMatrixParams;
import org.jclouds.rest.binders.BindToJsonEntity;
import org.jclouds.rest.binders.BindToStringEntity;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.config.RestModule;
import org.jclouds.util.Jsr330;
import org.mortbay.jetty.HttpHeaders;
@ -206,7 +206,7 @@ public class RestAnnotationProcessorTest {
}
@Endpoint(Localhost.class)
public interface TestEntityParamVarargs {
public interface TestPayloadParamVarargs {
@POST
public void varargs(HttpRequestOptions... options);
@ -215,19 +215,19 @@ public class RestAnnotationProcessorTest {
}
public void testHttpRequestOptionsEntityParam() throws SecurityException, NoSuchMethodException {
Method method = TestEntityParamVarargs.class.getMethod("post", HttpRequestOptions.class);
public void testHttpRequestOptionsPayloadParam() throws SecurityException, NoSuchMethodException {
Method method = TestPayloadParamVarargs.class.getMethod("post", HttpRequestOptions.class);
verifyTestPostOptions(method);
}
public void testEntityParamVarargs() throws SecurityException, NoSuchMethodException {
Method method = TestEntityParamVarargs.class.getMethod("varargs", Array.newInstance(
public void testPayloadParamVarargs() throws SecurityException, NoSuchMethodException {
Method method = TestPayloadParamVarargs.class.getMethod("varargs", Array.newInstance(
HttpRequestOptions.class, 0).getClass());
verifyTestPostOptions(method);
}
private void verifyTestPostOptions(Method method) {
GeneratedHttpRequest<?> httpMethod = factory(TestEntityParamVarargs.class).createRequest(
GeneratedHttpRequest<?> httpMethod = factory(TestPayloadParamVarargs.class).createRequest(
method, new Object[] { new HttpRequestOptions() {
public Multimap<String, String> buildMatrixParameters() {
@ -250,7 +250,7 @@ public class RestAnnotationProcessorTest {
return LinkedHashMultimap.create();
}
public String buildStringEntity() {
public String buildStringPayload() {
return "fooya";
}
@ -263,7 +263,7 @@ public class RestAnnotationProcessorTest {
.singletonList("application/unknown"));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList("fooya".getBytes().length + ""));
assertEquals(httpMethod.getEntity(), "fooya");
assertEquals(httpMethod.getPayload().toString(), "fooya");
}
@Endpoint(Localhost.class)
@ -338,23 +338,23 @@ public class RestAnnotationProcessorTest {
@Endpoint(Localhost.class)
public class TestPost {
@POST
public void post(@BinderParam(BindToStringEntity.class) String content) {
public void post(@BinderParam(BindToStringPayload.class) String content) {
}
@POST
public void postAsJson(@BinderParam(BindToJsonEntity.class) String content) {
public void postAsJson(@BinderParam(BindToJsonPayload.class) String content) {
}
@POST
@Path("{foo}")
public void postWithPath(@PathParam("foo") @MapEntityParam("fooble") String path,
public void postWithPath(@PathParam("foo") @MapPayloadParam("fooble") String path,
MapBinder content) {
}
@POST
@Path("{foo}")
@MapBinder(BindToJsonEntity.class)
public void postWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) {
@MapBinder(BindToJsonPayload.class)
public void postWithMethodBinder(@PathParam("foo") @MapPayloadParam("fooble") String path) {
}
}
@ -370,7 +370,7 @@ public class RestAnnotationProcessorTest {
.singletonList("application/unknown"));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList("data".getBytes().length + ""));
assertEquals(httpMethod.getEntity(), "data");
assertEquals(httpMethod.getPayload().toString(), "data");
}
public void testCreatePostJsonRequest() throws SecurityException, NoSuchMethodException {
@ -385,7 +385,7 @@ public class RestAnnotationProcessorTest {
.singletonList("application/json"));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList("\"data\"".getBytes().length + ""));
assertEquals(httpMethod.getEntity(), "\"data\"");
assertEquals(httpMethod.getPayload().toString(), "\"data\"");
}
public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException {
@ -393,7 +393,7 @@ public class RestAnnotationProcessorTest {
GeneratedHttpRequest<?> httpMethod = factory(TestPost.class).createRequest(method,
new Object[] { "data", new org.jclouds.rest.MapBinder() {
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
request.setEntity(postParams.get("fooble"));
request.setPayload(postParams.get("fooble"));
}
public void bindToRequest(HttpRequest request, Object toBind) {
@ -404,7 +404,7 @@ public class RestAnnotationProcessorTest {
assertEquals(httpMethod.getEndpoint().getPath(), "/data");
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
assertEquals(httpMethod.getHeaders().size(), 1);
assertEquals(httpMethod.getEntity(), "data");
assertEquals(httpMethod.getPayload().toString(), "data");
}
public void testCreatePostWithMethodBinder() throws SecurityException, NoSuchMethodException {
@ -420,30 +420,30 @@ public class RestAnnotationProcessorTest {
String expected = "{\"fooble\":\"data\"}";
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList(expected.getBytes().length + ""));
assertEquals(httpMethod.getEntity(), expected);
assertEquals(httpMethod.getPayload().toString(), expected);
}
@Endpoint(Localhost.class)
public class TestPut {
@PUT
@Path("{foo}")
@MapBinder(BindToJsonEntity.class)
public void putWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) {
@MapBinder(BindToJsonPayload.class)
public void putWithMethodBinder(@PathParam("foo") @MapPayloadParam("fooble") String path) {
}
@PUT
@Path("{foo}")
@Produces(MediaType.TEXT_PLAIN)
public void putWithMethodBinderProduces(
@PathParam("foo") @BinderParam(BindToStringEntity.class) String path) {
@PathParam("foo") @BinderParam(BindToStringPayload.class) String path) {
}
@PUT
@Path("{foo}")
@MapBinder(BindToJsonEntity.class)
@MapBinder(BindToJsonPayload.class)
@Consumes(MediaType.APPLICATION_JSON)
public void putWithMethodBinderConsumes(
@PathParam("foo") @MapEntityParam("fooble") String path) {
@PathParam("foo") @MapPayloadParam("fooble") String path) {
}
}
@ -460,7 +460,7 @@ public class RestAnnotationProcessorTest {
String expected = "{\"fooble\":\"data\"}";
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList(expected.getBytes().length + ""));
assertEquals(httpMethod.getEntity(), expected);
assertEquals(httpMethod.getPayload().toString(), expected);
}
public void testCreatePutWithMethodProduces() throws SecurityException, NoSuchMethodException {
@ -475,7 +475,7 @@ public class RestAnnotationProcessorTest {
.singletonList("text/plain"));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList("data".getBytes().length + ""));
assertEquals(httpMethod.getEntity(), "data");
assertEquals(httpMethod.getPayload().toString(), "data");
}
public void testCreatePutWithMethodConsumes() throws SecurityException, NoSuchMethodException {
@ -493,7 +493,7 @@ public class RestAnnotationProcessorTest {
String expected = "{\"fooble\":\"data\"}";
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList(expected.getBytes().length + ""));
assertEquals(httpMethod.getEntity(), expected);
assertEquals(httpMethod.getPayload().toString(), expected);
}
static class TestRequestFilter1 implements HttpRequestFilter {
@ -589,7 +589,7 @@ public class RestAnnotationProcessorTest {
assertRequestLineEquals(httpMethod,
"GET http://localhost:8080/v1/ralphie/1/localhost HTTP/1.1");
assertHeadersEqual(httpMethod, "");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
}
@Endpoint(Localhost.class)
@ -650,7 +650,7 @@ public class RestAnnotationProcessorTest {
new Object[] { "localhost" });
assertRequestLineEquals(httpMethod, "GET http://localhost:8080/l HTTP/1.1");
assertHeadersEqual(httpMethod, "");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
}
@Test
@ -661,7 +661,7 @@ public class RestAnnotationProcessorTest {
"localhost");
assertRequestLineEquals(httpMethod, "GET http://localhost:8080/?one=l HTTP/1.1");
assertHeadersEqual(httpMethod, "");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
}
@Test
@ -672,7 +672,7 @@ public class RestAnnotationProcessorTest {
new Object[] { "localhost" });
assertRequestLineEquals(httpMethod, "GET http://localhost:8080/;one=l HTTP/1.1");
assertHeadersEqual(httpMethod, "");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
}
@Test
@ -684,7 +684,7 @@ public class RestAnnotationProcessorTest {
assertRequestLineEquals(httpMethod, "POST http://localhost:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 5\nContent-Type: application/x-www-form-urlencoded\n");
assertEntityEquals(httpMethod, "one=l");
assertPayloadEquals(httpMethod, "one=l");
}
@Test
@ -1149,7 +1149,7 @@ public class RestAnnotationProcessorTest {
@PUT
@Path("/{id}")
public Future<String> put(@PathParam("id") @ParamParser(FirstCharacter.class) String id,
@BinderParam(BindToStringEntity.class) String payload) {
@BinderParam(BindToStringPayload.class) String payload) {
return null;
}
@ -1165,7 +1165,7 @@ public class RestAnnotationProcessorTest {
@Headers(keys = "foo", values = "--{id}--")
@ResponseParser(ReturnTrueIf2xx.class)
public Future<String> putHeader(@PathParam("id") String id,
@BinderParam(BindToStringEntity.class) String payload) {
@BinderParam(BindToStringPayload.class) String payload) {
return null;
}
}
@ -1221,7 +1221,7 @@ public class RestAnnotationProcessorTest {
new Object[] { "1", options });
assertRequestLineEquals(httpMethod, "GET http://localhost:8080/1?prefix=1 HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: localhost\n");
assertEntityEquals(httpMethod, null);
assertPayloadEquals(httpMethod, null);
}
public void testCreateGetQuery() throws SecurityException, NoSuchMethodException {
@ -1247,16 +1247,16 @@ public class RestAnnotationProcessorTest {
}
@Endpoint(Localhost.class)
public class EntityOptions extends BaseHttpRequestOptions {
public class PayloadOptions extends BaseHttpRequestOptions {
@Override
public String buildStringEntity() {
public String buildStringPayload() {
return "foo";
}
}
public void testCreateGetOptionsThatProducesEntity() throws SecurityException,
public void testCreateGetOptionsThatProducesPayload() throws SecurityException,
NoSuchMethodException {
EntityOptions options = new EntityOptions();
PayloadOptions options = new PayloadOptions();
Method method = TestRequest.class.getMethod("putOptions", String.class,
HttpRequestOptions.class);
GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method,
@ -1267,7 +1267,7 @@ public class RestAnnotationProcessorTest {
assertEquals(httpMethod.getHeaders().size(), 3);
assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections
.singletonList("localhost"));
assertEquals(httpMethod.getEntity(), "foo");
assertEquals(httpMethod.getPayload().toString(), "foo");
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
.singletonList("application/unknown"));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
@ -1307,7 +1307,7 @@ public class RestAnnotationProcessorTest {
.singletonList("application/unknown"));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList("data".getBytes().length + ""));
assertEquals(httpMethod.getEntity(), "data");
assertEquals(httpMethod.getPayload().toString(), "data");
}
public void testCreatePutHeader() throws SecurityException, NoSuchMethodException {
@ -1323,7 +1323,7 @@ public class RestAnnotationProcessorTest {
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
.singletonList("data".getBytes().length + ""));
assertEquals(httpMethod.getHeaders().get("foo"), Collections.singletonList("--1--"));
assertEquals(httpMethod.getEntity(), "data");
assertEquals(httpMethod.getPayload().toString(), "data");
}
@Endpoint(Localhost.class)
@ -1480,28 +1480,28 @@ public class RestAnnotationProcessorTest {
}
@Endpoint(Localhost.class)
public interface TestEntity {
public interface TestPayload {
@PUT
public void put(@BinderParam(BindToStringEntity.class) String content);
public void put(@BinderParam(BindToStringPayload.class) String content);
@PUT
@Path("{foo}")
public Future<Void> putWithPath(@PathParam("foo") String path,
@BinderParam(BindToStringEntity.class) String content);
@BinderParam(BindToStringPayload.class) String content);
@PUT
public void twoEntities(@BinderParam(BindToStringEntity.class) String entity1,
@BinderParam(BindToStringEntity.class) String entity2);
public void twoEntities(@BinderParam(BindToStringPayload.class) String payload1,
@BinderParam(BindToStringPayload.class) String payload2);
}
@Test
public void testPut() throws SecurityException, NoSuchMethodException {
RestAnnotationProcessor<TestEntity> processor = factory(TestEntity.class);
Method method = TestEntity.class.getMethod("put", String.class);
GeneratedHttpRequest<TestEntity> request = new GeneratedHttpRequest<TestEntity>("GET", URI
.create("http://localhost"), processor, TestEntity.class, method, "test");
RestAnnotationProcessor<TestPayload> processor = factory(TestPayload.class);
Method method = TestPayload.class.getMethod("put", String.class);
GeneratedHttpRequest<TestPayload> request = new GeneratedHttpRequest<TestPayload>("GET", URI
.create("http://localhost"), processor, TestPayload.class, method, "test");
processor.decorateRequest(request);
assertEquals(request.getEntity(), "test");
assertEquals(request.getPayload().toString(), "test");
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
.singletonList("application/unknown"));
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
@ -1513,12 +1513,12 @@ public class RestAnnotationProcessorTest {
@Test
public void putWithPath() throws SecurityException, NoSuchMethodException {
RestAnnotationProcessor<TestEntity> processor = factory(TestEntity.class);
Method method = TestEntity.class.getMethod("putWithPath", String.class, String.class);
GeneratedHttpRequest<TestEntity> request = new GeneratedHttpRequest<TestEntity>("GET", URI
.create("http://localhost"), processor, TestEntity.class, method, "rabble", "test");
RestAnnotationProcessor<TestPayload> processor = factory(TestPayload.class);
Method method = TestPayload.class.getMethod("putWithPath", String.class, String.class);
GeneratedHttpRequest<TestPayload> request = new GeneratedHttpRequest<TestPayload>("GET", URI
.create("http://localhost"), processor, TestPayload.class, method, "rabble", "test");
processor.decorateRequest(request);
assertEquals(request.getEntity(), "test");
assertEquals(request.getPayload().toString(), "test");
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
.singletonList("application/unknown"));
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
@ -1566,7 +1566,7 @@ public class RestAnnotationProcessorTest {
UnsupportedEncodingException {
Method oneForm = TestFormReplace.class.getMethod("twoForm", String.class);
String form = factory(TestFormReplace.class).createRequest(oneForm, new Object[] { "robot" })
.getEntity().toString();
.getPayload().toString().toString();
assertEquals(form, "slash=/robot&hyphen=-robot");
}
@ -1584,7 +1584,7 @@ public class RestAnnotationProcessorTest {
UnsupportedEncodingException {
Method oneForm = TestClassForm.class.getMethod("oneForm", String.class);
String form = factory(TestClassForm.class).createRequest(oneForm, new Object[] { "robot" })
.getEntity().toString();
.getPayload().toString().toString();
assertEquals(form, "x-amz-copy-source=/robot");
}
@ -1593,7 +1593,7 @@ public class RestAnnotationProcessorTest {
UnsupportedEncodingException {
Method oneForm = TestFormReplace.class.getMethod("oneForm", String.class);
String form = factory(TestFormReplace.class).createRequest(oneForm, new Object[] { "robot" })
.getEntity().toString();
.getPayload().toString().toString();
assertEquals(form, "x-amz-copy-source=/robot");
}
@ -1602,7 +1602,7 @@ public class RestAnnotationProcessorTest {
UnsupportedEncodingException {
Method twoForms = TestFormReplace.class.getMethod("twoForms", String.class, String.class);
String form = factory(TestFormReplace.class).createRequest(twoForms,
new Object[] { "robot", "eggs" }).getEntity().toString();
new Object[] { "robot", "eggs" }).getPayload().toString().toString();
assertEquals(form, "x-amz-copy-source=/robot/eggs");
}
@ -1612,7 +1612,7 @@ public class RestAnnotationProcessorTest {
Method twoFormsOutOfOrder = TestFormReplace.class.getMethod("twoFormsOutOfOrder",
String.class, String.class);
String form = factory(TestFormReplace.class).createRequest(twoFormsOutOfOrder,
new Object[] { "robot", "eggs" }).getEntity().toString();
new Object[] { "robot", "eggs" }).getPayload().toString().toString();
assertEquals(form, "x-amz-copy-source=/eggs/robot");
}
@ -1646,14 +1646,13 @@ public class RestAnnotationProcessorTest {
}
protected void assertEntityEquals(GeneratedHttpRequest<?> httpMethod, String toMatch)
protected void assertPayloadEquals(GeneratedHttpRequest<?> httpMethod, String toMatch)
throws IOException {
if (httpMethod.getEntity() == null) {
if (httpMethod.getPayload() == null) {
assertNull(toMatch);
} else {
String entity = (httpMethod.getEntity() instanceof String) ? httpMethod.getEntity()
.toString() : IOUtils.toString((InputStream) httpMethod.getEntity());
assertEquals(entity, toMatch);
String payload = IOUtils.toString(httpMethod.getPayload().getContent());
assertEquals(payload, toMatch);
}
}

View File

@ -69,7 +69,7 @@ public class StoreTweetsController extends HttpServlet {
Blob to = map.newBlob();
to.getMetadata().setContentType(MediaType.TEXT_PLAIN);
to.getMetadata().setName(from.getId() + "");
to.setData(from.getText());
to.setPayload(from.getText());
to.getMetadata().getUserMetadata().put(TweetStoreConstants.SENDER_NAME,
from.getUser().getScreenName());
return to;

Some files were not shown because too many files have changed in this diff Show More