mirror of https://github.com/apache/jclouds.git
Issue 76: POST support; Added PostParam PostBinder and renamed PathParamParser to ParamParser so that it can be reused for post.
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1644 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
205a929526
commit
5a548f5a7e
|
@ -66,7 +66,7 @@ import org.jclouds.rest.ExceptionParser;
|
|||
import org.jclouds.rest.Header;
|
||||
import org.jclouds.rest.HostPrefixParam;
|
||||
import org.jclouds.rest.HttpRequestOptionsBinder;
|
||||
import org.jclouds.rest.PathParamParser;
|
||||
import org.jclouds.rest.ParamParser;
|
||||
import org.jclouds.rest.Query;
|
||||
import org.jclouds.rest.RequestFilters;
|
||||
import org.jclouds.rest.ResponseParser;
|
||||
|
@ -212,7 +212,7 @@ public interface S3Connection {
|
|||
@ResponseParser(ParseETagHeader.class)
|
||||
Future<byte[]> putObject(
|
||||
@HostPrefixParam String bucketName,
|
||||
@PathParam("key") @PathParamParser(S3ObjectKey.class) @EntityParam(S3ObjectBinder.class) S3Object object);
|
||||
@PathParam("key") @ParamParser(S3ObjectKey.class) @EntityParam(S3ObjectBinder.class) S3Object object);
|
||||
|
||||
/**
|
||||
* Like {@link #putObject(String, S3Object)} except you can use {@link PutObjectOptions} to
|
||||
|
@ -234,7 +234,7 @@ public interface S3Connection {
|
|||
@ResponseParser(ParseETagHeader.class)
|
||||
Future<byte[]> putObject(
|
||||
@HostPrefixParam String bucketName,
|
||||
@PathParam("key") @PathParamParser(S3ObjectKey.class) @EntityParam(S3ObjectBinder.class) S3Object object,
|
||||
@PathParam("key") @ParamParser(S3ObjectKey.class) @EntityParam(S3ObjectBinder.class) S3Object object,
|
||||
PutObjectOptions options);
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package org.jclouds.http.binders;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.PostEntityBinder;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Binds the object to the request as a json object.
|
||||
*
|
||||
* @author adriancole
|
||||
* @since 4.0
|
||||
*/
|
||||
public class JsonBinder implements PostEntityBinder {
|
||||
protected final Gson gson;
|
||||
|
||||
@Inject
|
||||
public JsonBinder(Gson gson) {
|
||||
this.gson = gson;
|
||||
}
|
||||
|
||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
||||
addEntityToRequest((Object) postParams, request);
|
||||
}
|
||||
|
||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
||||
String json = gson.toJson(toBind);
|
||||
request.setEntity(json);
|
||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
||||
Collections.singletonList(json.getBytes().length + ""));
|
||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
||||
Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
}
|
|
@ -31,5 +31,5 @@ import org.jclouds.http.HttpRequest;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public interface EntityBinder {
|
||||
public void addEntityToRequest(Object args, HttpRequest request);
|
||||
public void addEntityToRequest(Object toBind, HttpRequest request);
|
||||
}
|
||||
|
|
|
@ -88,7 +88,8 @@ public class JaxrsAnnotationProcessor {
|
|||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToHeaderParamAnnotations = createMethodToIndexOfParamToAnnotation(HeaderParam.class);
|
||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToHostPrefixParamAnnotations = createMethodToIndexOfParamToAnnotation(HostPrefixParam.class);
|
||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class);
|
||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPathParamParserAnnotations = createMethodToIndexOfParamToAnnotation(PathParamParser.class);
|
||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(PostParam.class);
|
||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToParamParserAnnotations = createMethodToIndexOfParamToAnnotation(ParamParser.class);
|
||||
|
||||
static Map<Method, Map<Integer, Set<Annotation>>> createMethodToIndexOfParamToAnnotation(
|
||||
final Class<? extends Annotation> annotation) {
|
||||
|
@ -184,7 +185,8 @@ public class JaxrsAnnotationProcessor {
|
|||
methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
|
||||
methodToIndexOfParamToHostPrefixParamAnnotations.get(method).get(index);
|
||||
methodToindexOfParamToPathParamAnnotations.get(method).get(index);
|
||||
methodToindexOfParamToPathParamParserAnnotations.get(method).get(index);
|
||||
methodToindexOfParamToPostParamAnnotations.get(method).get(index);
|
||||
methodToindexOfParamToParamParserAnnotations.get(method).get(index);
|
||||
methodToIndexesOfOptions.get(method);
|
||||
}
|
||||
} else if (isConstantDeclaration(method)) {
|
||||
|
@ -310,6 +312,18 @@ public class JaxrsAnnotationProcessor {
|
|||
return null;
|
||||
}
|
||||
|
||||
public PostEntityBinder getPostEntityBinderOrNull(Method method, Object[] args) {
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof PostEntityBinder)
|
||||
return (PostEntityBinder) arg;
|
||||
}
|
||||
PostBinder annotation = method.getAnnotation(PostBinder.class);
|
||||
if (annotation != null) {
|
||||
return injector.getInstance(annotation.value());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, String> constants = Maps.newHashMap();
|
||||
|
||||
public boolean isHttpMethod(Method method) {
|
||||
|
@ -347,9 +361,18 @@ public class JaxrsAnnotationProcessor {
|
|||
public HttpRequest buildEntityIfPostOrPutRequest(Method method, Object[] args,
|
||||
HttpRequest request) {
|
||||
switch (request.getMethod()) {
|
||||
case PUT:
|
||||
case POST:
|
||||
|
||||
PostEntityBinder postBinder = null;
|
||||
Map<String, String> postParams = buildPostParams(method, args);
|
||||
// post binder is only useful if there are parameters. We guard here in case the
|
||||
// PostEntityBinder is also an EntityBinder. If so, it can be used with or without
|
||||
// parameters.
|
||||
if (postParams.size() > 0
|
||||
&& (postBinder = this.getPostEntityBinderOrNull(method, args)) != null) {
|
||||
postBinder.addEntityToRequest(postParams, request);
|
||||
break;
|
||||
}
|
||||
case PUT:
|
||||
HttpRequestOptions options = findOptionsIn(method, args);
|
||||
if (options != null) {
|
||||
optionsBinder.addEntityToRequest(options, request);
|
||||
|
@ -455,14 +478,14 @@ public class JaxrsAnnotationProcessor {
|
|||
pathParamValues.putAll(constants);
|
||||
Map<Integer, Set<Annotation>> indexToPathParam = methodToindexOfParamToPathParamAnnotations
|
||||
.get(method);
|
||||
Map<Integer, Set<Annotation>> indexToPathParamExtractor = methodToindexOfParamToPathParamParserAnnotations
|
||||
Map<Integer, Set<Annotation>> indexToParamExtractor = methodToindexOfParamToParamParserAnnotations
|
||||
.get(method);
|
||||
for (Entry<Integer, Set<Annotation>> entry : indexToPathParam.entrySet()) {
|
||||
for (Annotation key : entry.getValue()) {
|
||||
Set<Annotation> extractors = indexToPathParamExtractor.get(entry.getKey());
|
||||
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
|
||||
|
||||
if (extractors != null && extractors.size() > 0) {
|
||||
PathParamParser extractor = (PathParamParser) extractors.iterator().next();
|
||||
ParamParser extractor = (ParamParser) extractors.iterator().next();
|
||||
pathParamValues.put(((PathParam) key).value(), injector.getInstance(
|
||||
extractor.value()).apply(args[entry.getKey()]));
|
||||
} else {
|
||||
|
@ -479,4 +502,28 @@ public class JaxrsAnnotationProcessor {
|
|||
}
|
||||
return pathParamValues;
|
||||
}
|
||||
|
||||
private Map<String, String> buildPostParams(Method method, Object[] args) {
|
||||
Map<String, String> postParams = Maps.newHashMap();
|
||||
Map<Integer, Set<Annotation>> indexToPathParam = methodToindexOfParamToPostParamAnnotations
|
||||
.get(method);
|
||||
Map<Integer, Set<Annotation>> indexToParamExtractor = methodToindexOfParamToParamParserAnnotations
|
||||
.get(method);
|
||||
for (Entry<Integer, Set<Annotation>> entry : indexToPathParam.entrySet()) {
|
||||
for (Annotation key : entry.getValue()) {
|
||||
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
|
||||
|
||||
if (extractors != null && extractors.size() > 0) {
|
||||
ParamParser extractor = (ParamParser) extractors.iterator().next();
|
||||
postParams.put(((PathParam) key).value(), injector.getInstance(extractor.value())
|
||||
.apply(args[entry.getKey()]));
|
||||
} else {
|
||||
String paramKey = ((PostParam) key).value();
|
||||
String paramValue = args[entry.getKey()].toString();
|
||||
postParams.put(paramKey, paramValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return postParams;
|
||||
}
|
||||
}
|
||||
|
|
4
core/src/main/java/org/jclouds/rest/PathParamParser.java → core/src/main/java/org/jclouds/rest/ParamParser.java
Normal file → Executable file
4
core/src/main/java/org/jclouds/rest/PathParamParser.java → core/src/main/java/org/jclouds/rest/ParamParser.java
Normal file → Executable file
|
@ -34,13 +34,13 @@ import javax.ws.rs.PathParam;
|
|||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Extracts the value of a path parameter from an object.
|
||||
* Extracts the value of a parameter from an object.
|
||||
*
|
||||
* @see PathParam
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Target(PARAMETER)
|
||||
@Retention(RUNTIME)
|
||||
public @interface PathParamParser {
|
||||
public @interface ParamParser {
|
||||
Class<? extends Function<Object, String>> value();
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.rest;
|
||||
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Designates that this parameter will hold the entity for a PUT or POST command.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Target(METHOD)
|
||||
@Retention(RUNTIME)
|
||||
public @interface PostBinder {
|
||||
|
||||
/**
|
||||
* How to bind {@link PostParam} values, if there is no {@link PostEntityBinder} in the method
|
||||
* definition
|
||||
*/
|
||||
Class<? extends PostEntityBinder> value();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.jclouds.rest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
||||
/**
|
||||
* Builds the entity of a Post request.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface PostEntityBinder extends EntityBinder {
|
||||
|
||||
/**
|
||||
* creates and binds the POST entity to the request using parameters specified.
|
||||
*
|
||||
* @see PostParam
|
||||
*/
|
||||
public void addEntityToRequest(Map<String,String> postParams, HttpRequest request);
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.rest;
|
||||
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Designates that this parameter will hold the entity for a PUT or POST command.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Target(PARAMETER)
|
||||
@Retention(RUNTIME)
|
||||
public @interface PostParam {
|
||||
|
||||
/**
|
||||
* The key used in a map passed to the {@link PostEntityBinder} associated with the request.
|
||||
*/
|
||||
String value();
|
||||
}
|
|
@ -101,18 +101,32 @@ public abstract class BaseHttpCommandExecutorServiceTest extends BaseJettyTest {
|
|||
// TODO assert misses are only one, as permanent redirects paths should be remembered.
|
||||
}
|
||||
|
||||
@Test(invocationCount = 50, timeOut = 5000)
|
||||
public void testPost() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||
TimeoutException {
|
||||
Future<String> put = client.post("", "foo");
|
||||
assertEquals(put.get(10, TimeUnit.SECONDS).trim(), "fooPOST");
|
||||
}
|
||||
|
||||
@Test(invocationCount = 50, timeOut = 5000)
|
||||
public void testPostBinder() throws MalformedURLException, ExecutionException,
|
||||
InterruptedException, TimeoutException {
|
||||
Future<String> put = client.postJson("", "foo");
|
||||
assertEquals(put.get(10, TimeUnit.SECONDS).trim(), "{\"key\":\"foo\"}POST");
|
||||
}
|
||||
|
||||
@Test(invocationCount = 50, timeOut = 5000)
|
||||
public void testPut() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||
TimeoutException {
|
||||
Future<Boolean> put = client.upload("", "foo");
|
||||
assertEquals(put.get(10, TimeUnit.SECONDS), new Boolean(true));
|
||||
Future<String> put = client.upload("", "foo");
|
||||
assertEquals(put.get(10, TimeUnit.SECONDS).trim(), "fooPUT");
|
||||
}
|
||||
|
||||
@Test(invocationCount = 50, timeOut = 5000)
|
||||
public void testPutRedirect() throws MalformedURLException, ExecutionException,
|
||||
InterruptedException, TimeoutException {
|
||||
Future<Boolean> put = client.upload("redirect", "foo");
|
||||
assertEquals(put.get(10, TimeUnit.SECONDS), new Boolean(true));
|
||||
Future<String> put = client.upload("redirect", "foo");
|
||||
assertEquals(put.get(10, TimeUnit.SECONDS).trim(), "fooPUTREDIRECT");
|
||||
}
|
||||
|
||||
@Test(invocationCount = 50, timeOut = 5000)
|
||||
|
|
|
@ -73,11 +73,23 @@ public abstract class BaseJettyTest {
|
|||
Handler server1Handler = new AbstractHandler() {
|
||||
public void handle(String target, HttpServletRequest request,
|
||||
HttpServletResponse response, int dispatch) throws IOException, ServletException {
|
||||
if (failIfNoContentLength(request, response))
|
||||
if (failIfNoContentLength(request, response)) {
|
||||
return;
|
||||
else if (request.getMethod().equals("PUT")) {
|
||||
} else if (target.indexOf("redirect") > 0) {
|
||||
response.sendRedirect("http://localhost:" + (testPort + 1));
|
||||
} else if (request.getMethod().equals("PUT")) {
|
||||
if (request.getContentLength() > 0) {
|
||||
Utils.toStringAndClose(request.getInputStream());
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().println(
|
||||
Utils.toStringAndClose(request.getInputStream()) + "PUT");
|
||||
} else {
|
||||
response.sendError(500, "no content");
|
||||
}
|
||||
} else if (request.getMethod().equals("POST")) {
|
||||
if (request.getContentLength() > 0) {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().println(
|
||||
Utils.toStringAndClose(request.getInputStream()) + "POST");
|
||||
} else {
|
||||
response.sendError(500, "no content");
|
||||
}
|
||||
|
@ -87,8 +99,6 @@ public abstract class BaseJettyTest {
|
|||
response.setContentType("text/plain");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().println("test");
|
||||
} else if (target.indexOf("redirect") > 0) {
|
||||
response.sendRedirect("http://localhost:" + (testPort + 1));
|
||||
} else {
|
||||
if (failOnRequest(request, response))
|
||||
return;
|
||||
|
@ -109,7 +119,9 @@ public abstract class BaseJettyTest {
|
|||
HttpServletResponse response, int dispatch) throws IOException, ServletException {
|
||||
if (request.getMethod().equals("PUT")) {
|
||||
if (request.getContentLength() > 0) {
|
||||
Utils.toStringAndClose(request.getInputStream());
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().println(
|
||||
Utils.toStringAndClose(request.getInputStream()) + "PUTREDIRECT");
|
||||
} else {
|
||||
response.sendError(500, "no content");
|
||||
}
|
||||
|
|
|
@ -28,14 +28,18 @@ import java.util.concurrent.Future;
|
|||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HEAD;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.http.binders.JsonBinder;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.jclouds.rest.EntityParam;
|
||||
import org.jclouds.rest.ExceptionParser;
|
||||
import org.jclouds.rest.PostBinder;
|
||||
import org.jclouds.rest.PostParam;
|
||||
import org.jclouds.rest.RequestFilters;
|
||||
import org.jclouds.rest.XMLResponseParser;
|
||||
|
||||
|
@ -80,7 +84,16 @@ public interface IntegrationTestClient {
|
|||
|
||||
@PUT
|
||||
@Path("objects/{id}")
|
||||
Future<Boolean> upload(@PathParam("id") String id, @EntityParam String toPut);
|
||||
Future<String> upload(@PathParam("id") String id, @EntityParam String toPut);
|
||||
|
||||
@POST
|
||||
@Path("objects/{id}")
|
||||
Future<String> post(@PathParam("id") String id, @EntityParam String toPut);
|
||||
|
||||
@POST
|
||||
@Path("objects/{id}")
|
||||
@PostBinder(JsonBinder.class)
|
||||
Future<String> postJson(@PathParam("id") String id, @PostParam("key") String toPut);
|
||||
|
||||
@GET
|
||||
@Path("objects/{id}")
|
||||
|
@ -94,6 +107,7 @@ public interface IntegrationTestClient {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("objects/{id}")
|
||||
Future<String> download(@PathParam("id") String id, @HeaderParam("test") String header);
|
||||
|
|
|
@ -31,10 +31,12 @@ import java.lang.reflect.Method;
|
|||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
@ -46,6 +48,7 @@ import org.jclouds.http.HttpMethod;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.binders.JsonBinder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.http.functions.ReturnStringIf200;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
|
@ -75,6 +78,101 @@ import com.google.inject.name.Names;
|
|||
@Test(groups = "unit", testName = "jaxrs.JaxrsUtilTest")
|
||||
public class JaxrsAnnotationProcessorTest {
|
||||
|
||||
public class TestPost {
|
||||
@POST
|
||||
public void post(@EntityParam String content) {
|
||||
}
|
||||
|
||||
@POST
|
||||
public void postAsJson(@EntityParam(JsonBinder.class) String content) {
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{foo}")
|
||||
public void postWithPath(@PathParam("foo") @PostParam("fooble") String path,
|
||||
PostEntityBinder content) {
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{foo}")
|
||||
@PostBinder(JsonBinder.class)
|
||||
public void postWithMethodBinder(@PathParam("foo") @PostParam("fooble") String path) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testCreatePostRequest() throws SecurityException, NoSuchMethodException {
|
||||
Method method = TestPost.class.getMethod("post", String.class);
|
||||
URI endpoint = URI.create("http://localhost");
|
||||
HttpRequest httpMethod = factory.create(TestPost.class).createRequest(endpoint, method,
|
||||
new Object[] { "data" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "");
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||
.singletonList("application/unknown"));
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||
.singletonList("data".getBytes().length + ""));
|
||||
assertEquals(httpMethod.getEntity(), "data");
|
||||
}
|
||||
|
||||
public void testCreatePostJsonRequest() throws SecurityException, NoSuchMethodException {
|
||||
Method method = TestPost.class.getMethod("postAsJson", String.class);
|
||||
URI endpoint = URI.create("http://localhost");
|
||||
HttpRequest httpMethod = factory.create(TestPost.class).createRequest(endpoint, method,
|
||||
new Object[] { "data" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "");
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||
.singletonList("application/json"));
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||
.singletonList("\"data\"".getBytes().length + ""));
|
||||
assertEquals(httpMethod.getEntity(), "\"data\"");
|
||||
}
|
||||
|
||||
public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException {
|
||||
Method method = TestPost.class
|
||||
.getMethod("postWithPath", String.class, PostEntityBinder.class);
|
||||
URI endpoint = URI.create("http://localhost");
|
||||
HttpRequest httpMethod = factory.create(TestPost.class).createRequest(endpoint, method,
|
||||
new Object[] { "data", new PostEntityBinder() {
|
||||
|
||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
||||
request.setEntity(postParams.get("fooble"));
|
||||
}
|
||||
|
||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
||||
throw new RuntimeException("this shouldn't be used in POST");
|
||||
}
|
||||
|
||||
} });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/data");
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||
assertEquals(httpMethod.getEntity(), "data");
|
||||
}
|
||||
|
||||
public void testCreatePostWithMethodBinder() throws SecurityException, NoSuchMethodException {
|
||||
Method method = TestPost.class.getMethod("postWithMethodBinder", String.class);
|
||||
URI endpoint = URI.create("http://localhost");
|
||||
HttpRequest httpMethod = factory.create(TestPost.class).createRequest(endpoint, method,
|
||||
new Object[] { "data", });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/data");
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||
.singletonList("application/json"));
|
||||
String expected = "{\"fooble\":\"data\"}";
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||
.singletonList(expected.getBytes().length + ""));
|
||||
assertEquals(httpMethod.getEntity(), expected);
|
||||
}
|
||||
|
||||
static class TestRequestFilter1 implements HttpRequestFilter {
|
||||
|
||||
public void filter(HttpRequest request) throws HttpException {
|
||||
|
@ -188,7 +286,7 @@ public class JaxrsAnnotationProcessorTest {
|
|||
@GET
|
||||
@Path("{path}")
|
||||
public void onePathParamExtractor(
|
||||
@PathParam("path") @PathParamParser(FirstCharacter.class) String path) {
|
||||
@PathParam("path") @ParamParser(FirstCharacter.class) String path) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +414,7 @@ public class JaxrsAnnotationProcessorTest {
|
|||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Future<String> put(@PathParam("id") @PathParamParser(FirstCharacter.class) String id,
|
||||
public Future<String> put(@PathParam("id") @ParamParser(FirstCharacter.class) String id,
|
||||
@EntityParam String payload) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,14 @@ import com.google.inject.Module;
|
|||
public class GaeHttpCommandExecutorServiceIntegrationTest extends
|
||||
BaseHttpCommandExecutorServiceTest {
|
||||
|
||||
@Override
|
||||
@Test(invocationCount = 50, timeOut = 3000)
|
||||
public void testPostBinder() throws MalformedURLException, ExecutionException,
|
||||
InterruptedException, TimeoutException {
|
||||
setupApiProxy();
|
||||
super.testPostBinder();
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
void validateExecutor() {
|
||||
ExecutorService executorService = injector.getInstance(ExecutorService.class);
|
||||
|
@ -124,6 +132,14 @@ public class GaeHttpCommandExecutorServiceIntegrationTest extends
|
|||
super.testGetSynchException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(invocationCount = 50, timeOut = 3000)
|
||||
public void testPost() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||
TimeoutException {
|
||||
setupApiProxy();
|
||||
super.testPost();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(invocationCount = 50, timeOut = 3000)
|
||||
public void testPut() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||
|
@ -207,4 +223,5 @@ public class GaeHttpCommandExecutorServiceIntegrationTest extends
|
|||
@Override
|
||||
protected void addConnectionProperties(Properties props) {
|
||||
}
|
||||
|
||||
}
|
|
@ -55,7 +55,7 @@ import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
|
|||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||
import org.jclouds.rest.EntityParam;
|
||||
import org.jclouds.rest.ExceptionParser;
|
||||
import org.jclouds.rest.PathParamParser;
|
||||
import org.jclouds.rest.ParamParser;
|
||||
import org.jclouds.rest.Query;
|
||||
import org.jclouds.rest.RequestFilters;
|
||||
import org.jclouds.rest.ResponseParser;
|
||||
|
@ -109,7 +109,7 @@ public interface CloudFilesConnection {
|
|||
@ResponseParser(ParseETagHeader.class)
|
||||
Future<byte[]> putObject(
|
||||
@PathParam("container") String container,
|
||||
@PathParam("key") @PathParamParser(CFObjectKey.class) @EntityParam(CFObjectBinder.class)
|
||||
@PathParam("key") @ParamParser(CFObjectKey.class) @EntityParam(CFObjectBinder.class)
|
||||
CFObject object);
|
||||
|
||||
@HEAD
|
||||
|
|
Loading…
Reference in New Issue