Issue 76: new annotation for RequestFilters

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1623 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-07-13 22:47:45 +00:00
parent c4d8f5ff96
commit 2573d399ca
16 changed files with 243 additions and 92 deletions

View File

@ -39,6 +39,7 @@ import org.jclouds.aws.s3.binders.S3ObjectBinder;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.functions.ParseETagHeader;
import org.jclouds.aws.s3.functions.ParseMetadataFromHeaders;
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
@ -67,6 +68,7 @@ import org.jclouds.rest.HostPrefixParam;
import org.jclouds.rest.HttpRequestOptionsBinder;
import org.jclouds.rest.PathParamParser;
import org.jclouds.rest.Query;
import org.jclouds.rest.RequestFilters;
import org.jclouds.rest.ResponseParser;
import org.jclouds.rest.SkipEncoding;
import org.jclouds.rest.VirtualHost;
@ -84,6 +86,7 @@ import org.jclouds.rest.XMLResponseParser;
*/
@VirtualHost
@SkipEncoding('/')
@RequestFilters(RequestAuthorizeSignature.class)
public interface S3Connection {
/**

View File

@ -73,8 +73,8 @@ public class S3ContextBuilder extends CloudContextBuilder<S3Connection, S3Contex
Properties properties = new Properties();
properties.setProperty(PROPERTY_HTTP_ADDRESS, "s3.amazonaws.com");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, "5");
properties.setProperty(PROPERTY_HTTP_MAX_REDIRECTS, "5");
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");

View File

@ -25,8 +25,6 @@ package org.jclouds.aws.s3.config;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
@ -38,7 +36,6 @@ import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.cloud.ConfiguresCloudConnection;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
@ -51,6 +48,7 @@ import org.jclouds.rest.config.JaxrsModule;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
@ -78,6 +76,7 @@ public class RestS3ConnectionModule extends AbstractModule {
@Override
protected void configure() {
install(new JaxrsModule());
bind(RequestAuthorizeSignature.class).in(Scopes.SINGLETON);
bindErrorHandlers();
bindRetryHandlers();
requestInjection(this);
@ -86,8 +85,8 @@ public class RestS3ConnectionModule extends AbstractModule {
@Provides
@Singleton
protected S3Connection provideS3Connection(RestClientFactory factory) {
return factory.create(S3Connection.class);
protected S3Connection provideS3Connection(URI uri, RestClientFactory factory) {
return factory.create(uri, S3Connection.class);
}
protected void bindErrorHandlers() {
@ -106,14 +105,6 @@ public class RestS3ConnectionModule extends AbstractModule {
AWSClientErrorRetryHandler.class);
}
@Provides
@Singleton
List<HttpRequestFilter> provideRequestFilters(RequestAuthorizeSignature requestAuthorizeSignature) {
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
filters.add(requestAuthorizeSignature);
return filters;
}
@Singleton
@Provides
protected URI provideAddress(@Named(HttpConstants.PROPERTY_HTTP_ADDRESS) String address,

View File

@ -30,6 +30,7 @@ import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_RETRIES;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_PORT;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_RELAX_HOSTNAME;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
import static org.jclouds.http.HttpConstants.PROPERTY_JSON_DEBUG;
import static org.jclouds.http.HttpConstants.PROPERTY_SAX_DEBUG;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
@ -100,6 +101,11 @@ public abstract class CloudContextBuilder<C, X extends CloudContext<C>> {
return this;
}
public CloudContextBuilder<C, X> withJsonDebug() {
properties.setProperty(PROPERTY_JSON_DEBUG, "true");
return this;
}
/**
* allow mismatches between the certificate and the hostname of ssl requests.
*/

View File

@ -35,6 +35,8 @@ public interface HttpConstants {
public static final String PROPERTY_HTTP_MAX_RETRIES = "jclouds.http.max-retries";
public static final String PROPERTY_HTTP_MAX_REDIRECTS = "jclouds.http.max-redirects";
public static final String PROPERTY_SAX_DEBUG = "jclouds.http.sax.debug";
public static final String PROPERTY_JSON_DEBUG = "jclouds.http.json.debug";
/**
* longest time a single request can take before throwing an exception.
*/

View File

@ -26,10 +26,12 @@ package org.jclouds.http;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.List;
import org.jclouds.command.Request;
import com.google.common.collect.Multimap;
import com.google.inject.internal.Lists;
/**
* Represents a request that can be executed within {@link HttpCommandExecutorService}
@ -38,6 +40,8 @@ import com.google.common.collect.Multimap;
*/
public class HttpRequest extends HttpMessage implements Request<URI> {
private List<HttpRequestFilter> requestFilters = Lists.newArrayList();
private final HttpMethod method;
private final URI endpoint;
private Object entity;
@ -94,4 +98,12 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
return endpoint;
}
public void addFilter(HttpRequestFilter filter) {
requestFilters.add(filter);
}
public List<HttpRequestFilter> getFilters() {
return requestFilters;
}
}

View File

@ -94,7 +94,6 @@ public class ParseSax<T> implements Function<HttpResponse, T> {
}
private void parseAndCloseStream(InputStream xml, ContentHandler handler) throws HttpException {
parser.setContentHandler(handler);
String response = null;
try {
if (suckFirst) {
@ -103,6 +102,7 @@ public class ParseSax<T> implements Function<HttpResponse, T> {
IOUtils.closeQuietly(xml);
xml = IOUtils.toInputStream(response);
}
parser.setContentHandler(handler);
InputSource input = new InputSource(new InputStreamReader(xml, "UTF-8"));
parser.parse(input);
} catch (Exception e) {

View File

@ -24,8 +24,6 @@
package org.jclouds.http.internal;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@ -41,8 +39,6 @@ import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.logging.Logger;
import com.google.inject.Inject;
public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandExecutorService {
private final DelegatingRetryHandler retryHandler;
@ -52,9 +48,6 @@ public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandEx
@Resource
protected Logger logger = Logger.NULL;
@Inject(optional = true)
protected List<HttpRequestFilter> requestFilters = Collections.emptyList();
protected BaseHttpCommandExecutorService(ExecutorService executorService,
DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler) {
this.retryHandler = retryHandler;
@ -81,7 +74,7 @@ public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandEx
Q nativeRequest = null;
try {
logger.trace("%s - converting request %s", request.getEndpoint(), request);
for (HttpRequestFilter filter : requestFilters) {
for (HttpRequestFilter filter : request.getFilters()) {
filter.filter(request);
}
nativeRequest = convert(request);

View File

@ -36,6 +36,7 @@ import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.HttpHeaders;
@ -44,12 +45,14 @@ import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.util.IsHttpMethod;
import org.jclouds.http.HttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnStringIf200;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.http.options.HttpRequestOptions;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -61,10 +64,12 @@ import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.internal.Lists;
import com.google.inject.name.Named;
/**
* Tests behavior of JaxrsUtil
@ -74,6 +79,9 @@ import com.google.inject.internal.Lists;
@Singleton
public class JaxrsAnnotationProcessor {
@Resource
protected Logger logger = Logger.NULL;
private final Class<?> declaring;
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToEntityAnnotation = createMethodToIndexOfParamToAnnotation(EntityParam.class);
@ -170,14 +178,19 @@ public class JaxrsAnnotationProcessor {
private void seedCache(Class<?> declaring) {
Set<Method> methods = Sets.newHashSet(declaring.getMethods());
for (Method method : Sets.difference(methods, Sets.newHashSet(Object.class.getMethods()))) {
getHttpMethodOrThrowException(method);
for (int index = 0; index < method.getParameterTypes().length; index++) {
methodToIndexOfParamToEntityAnnotation.get(method).get(index);
methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
methodToIndexOfParamToHostPrefixParamAnnotations.get(method).get(index);
methodToindexOfParamToPathParamAnnotations.get(method).get(index);
methodToindexOfParamToPathParamParserAnnotations.get(method).get(index);
methodToIndexesOfOptions.get(method);
if (isHttpMethod(method)) {
for (int index = 0; index < method.getParameterTypes().length; index++) {
methodToIndexOfParamToEntityAnnotation.get(method).get(index);
methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
methodToIndexOfParamToHostPrefixParamAnnotations.get(method).get(index);
methodToindexOfParamToPathParamAnnotations.get(method).get(index);
methodToindexOfParamToPathParamParserAnnotations.get(method).get(index);
methodToIndexesOfOptions.get(method);
}
} else if (isConstantDeclaration(method)) {
bindConstant(method);
} else {
throw new RuntimeException("Method is not annotated as either http or constant");
}
}
}
@ -187,9 +200,10 @@ public class JaxrsAnnotationProcessor {
private HttpRequestOptionsBinder optionsBinder;
public HttpRequest createRequest(URI endpoint, Method method, Object[] args) {
HttpMethod httpMethod = getHttpMethodOrThrowException(method);
HttpMethod httpMethod = getHttpMethodOrConstantOrThrowException(method);
UriBuilder builder = addHostPrefixIfPresent(endpoint, method, args);
builder.path(declaring);
builder.path(method);
if (method.isAnnotationPresent(Query.class)) {
@ -227,11 +241,27 @@ public class JaxrsAnnotationProcessor {
}
HttpRequest request = new HttpRequest(httpMethod, endPoint, headers);
addHostHeaderIfAnnotatedWithVirtualHost(headers, request.getEndpoint().getHost(), method);
addFiltersIfAnnotated(method, request);
buildEntityIfPostOrPutRequest(method, args, request);
return request;
}
private void addFiltersIfAnnotated(Method method, HttpRequest request) {
if (declaring.isAnnotationPresent(RequestFilters.class)) {
for (Class<? extends HttpRequestFilter> clazz : declaring.getAnnotation(
RequestFilters.class).value()) {
request.getFilters().add(injector.getInstance(clazz));
}
}
if (method.isAnnotationPresent(RequestFilters.class)) {
for (Class<? extends HttpRequestFilter> clazz : method.getAnnotation(RequestFilters.class)
.value()) {
request.getFilters().add(injector.getInstance(clazz));
}
}
}
private UriBuilder addHostPrefixIfPresent(URI endpoint, Method method, Object[] args) {
Map<Integer, Set<Annotation>> map = getIndexToHostPrefixAnnotation(method);
UriBuilder builder = UriBuilder.fromUri(endpoint);
@ -280,11 +310,27 @@ public class JaxrsAnnotationProcessor {
return null;
}
public static HttpMethod getHttpMethodOrThrowException(Method method) {
private Map<String, String> constants = Maps.newHashMap();
public boolean isHttpMethod(Method method) {
return IsHttpMethod.getHttpMethods(method) != null;
}
public boolean isConstantDeclaration(Method method) {
return method.isAnnotationPresent(PathParam.class) && method.isAnnotationPresent(Named.class);
}
public void bindConstant(Method method) {
String key = method.getAnnotation(PathParam.class).value();
String value = injector.getInstance(Key.get(String.class, method.getAnnotation(Named.class)));
constants.put(key, value);
}
public HttpMethod getHttpMethodOrConstantOrThrowException(Method method) {
Set<String> httpMethods = IsHttpMethod.getHttpMethods(method);
if (httpMethods == null || httpMethods.size() != 1) {
throw new IllegalStateException(
"You must use at least one, but no more than one http method annotation on: "
"You must use at least one, but no more than one http method or pathparam annotation on: "
+ method.toString());
}
return HttpMethod.valueOf(httpMethods.iterator().next());
@ -406,6 +452,7 @@ public class JaxrsAnnotationProcessor {
private Map<String, Object> getEncodedPathParamKeyValues(Method method, Object[] args,
char... skipEncode) throws UnsupportedEncodingException {
Map<String, Object> pathParamValues = Maps.newHashMap();
pathParamValues.putAll(constants);
Map<Integer, Set<Annotation>> indexToPathParam = methodToindexOfParamToPathParamAnnotations
.get(method);
Map<Integer, Set<Annotation>> indexToPathParamExtractor = methodToindexOfParamToPathParamParserAnnotations

View File

@ -0,0 +1,44 @@
/**
*
* 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.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.jclouds.http.HttpRequestFilter;
/**
* Filters that should be applied to the request
*
* @author Adrian Cole
*/
@Target( { TYPE, METHOD })
@Retention(RUNTIME)
public @interface RequestFilters {
Class<? extends HttpRequestFilter>[] value();
}

View File

@ -24,6 +24,7 @@
package org.jclouds.rest;
import java.lang.reflect.Proxy;
import java.net.URI;
import org.jclouds.rest.RestClientProxy.RestClientProxyFactory;
@ -38,9 +39,9 @@ public class RestClientFactory {
}
@SuppressWarnings("unchecked")
public <T> T create(Class<T> clazz) {
public <T> T create(URI endPoint, Class<T> clazz) {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz },
proxyFactory.create(clazz));
proxyFactory.create(endPoint, clazz));
}
}

View File

@ -65,12 +65,13 @@ public class RestClientProxy implements InvocationHandler {
protected Logger logger = Logger.NULL;
public static interface RestClientProxyFactory {
RestClientProxy create(Class<?> clazz);
RestClientProxy create(URI endPoint, Class<?> clazz);
}
@Inject
public RestClientProxy(JaxrsAnnotationProcessor.Factory utilFactory, URI endPoint,
TransformingHttpCommand.Factory factory, @Assisted Class<?> declaring) {
public RestClientProxy(JaxrsAnnotationProcessor.Factory utilFactory,
TransformingHttpCommand.Factory factory, @Assisted URI endPoint,
@Assisted Class<?> declaring) {
this.util = utilFactory.create(declaring);
this.declaring = declaring;
this.endPoint = endPoint;
@ -83,29 +84,35 @@ public class RestClientProxy implements InvocationHandler {
return this.equals(o);
} else if (method.getName().equals("hashCode")) {
return this.hashCode();
}
logger.trace("%s - converting method to request", method);
HttpRequest request = util.createRequest(endPoint, method, args);
logger.trace("%s - converted method to request %s", method, request);
} else if (util.isHttpMethod(method)) {
logger.trace("%s - converting method to request", method);
HttpRequest request = util.createRequest(endPoint, method, args);
logger.trace("%s - converted method to request %s", method, request);
Function<HttpResponse, ?> transformer = util.createResponseParser(method);
Function<Exception, ?> exceptionParser = util.createExceptionParserOrNullIfNotFound(method);
Function<HttpResponse, ?> transformer = util.createResponseParser(method);
Function<Exception, ?> exceptionParser = util
.createExceptionParserOrNullIfNotFound(method);
logger.trace("%s - creating command for request %s, transformer %s, exceptionParser %s",
method, request, transformer, exceptionParser);
Future<?> result = commandFactory.create(request, transformer, exceptionParser).execute();
logger.trace("%s - creating command for request %s, transformer %s, exceptionParser %s",
method, request, transformer, exceptionParser);
Future<?> result = commandFactory.create(request, transformer, exceptionParser).execute();
if (exceptionParser != null) {
logger.trace("%s - wrapping future for request %s in exceptionParser %s", method, request,
exceptionParser);
result = new FutureExceptionParser(result, exceptionParser);
}
if (exceptionParser != null) {
logger.trace("%s - wrapping future for request %s in exceptionParser %s", method,
request, exceptionParser);
result = new FutureExceptionParser(result, exceptionParser);
}
if (method.getReturnType().isAssignableFrom(Future.class)) {
return result;
if (method.getReturnType().isAssignableFrom(Future.class)) {
return result;
} else {
logger
.trace("%s - invoking request synchronously %s", method, request,
exceptionParser);
return result.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
}
} else {
logger.trace("%s - invoking request synchronously %s", method, request, exceptionParser);
return result.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
throw new RuntimeException("method is intended solely to set constants: " + method);
}
}

View File

@ -25,7 +25,6 @@ package org.jclouds.http;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
@ -55,7 +54,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
public abstract class BaseJettyTest {
@ -133,33 +131,18 @@ public abstract class BaseJettyTest {
properties.put(HttpConstants.PROPERTY_HTTP_PORT, testPort + "");
properties.put(HttpConstants.PROPERTY_HTTP_SECURE, "false");
addConnectionProperties(properties);
final List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>(1);
filters.add(new HttpRequestFilter() {
public void filter(HttpRequest request) throws HttpException {
if (request.getHeaders().containsKey("filterme")) {
request.getHeaders().put("test", "test");
}
}
});
List<Module> modules = Lists.newArrayList(new AbstractModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), properties);
bind(URI.class).toInstance(URI.create("http://localhost:" + testPort));
}
}, new JDKLoggingModule(),
new JaxrsModule(), createClientModule(), new AbstractModule() {
@Override
protected void configure() {
bind(new TypeLiteral<List<HttpRequestFilter>>() {
}).toInstance(filters);
}
});
}, new JDKLoggingModule(), new JaxrsModule(), createClientModule());
CloudContextBuilder.addExecutorServiceIfNotPresent(modules);
injector = Guice.createInjector(modules);
RestClientFactory factory = injector.getInstance(RestClientFactory.class);
client = factory.create(IntegrationTestClient.class);
client = factory.create(URI.create("http://localhost:" + testPort),
IntegrationTestClient.class);
closer = injector.getInstance(Closer.class);
assert client != null;
}

View File

@ -36,6 +36,7 @@ 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.RequestFilters;
import org.jclouds.rest.XMLResponseParser;
import com.google.common.base.Function;
@ -83,8 +84,16 @@ public interface IntegrationTestClient {
@GET
@Path("objects/{id}")
@RequestFilters(Filter.class)
Future<String> downloadFilter(@PathParam("id") String id, @HeaderParam("filterme") String header);
static class Filter implements HttpRequestFilter {
public void filter(HttpRequest request) throws HttpException {
if (request.getHeaders().containsKey("filterme")) {
request.getHeaders().put("test", "test");
}
}
}
@GET
@Path("objects/{id}")
Future<String> download(@PathParam("id") String id, @HeaderParam("test") String header);

View File

@ -41,8 +41,10 @@ import javax.ws.rs.PathParam;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ReturnStringIf200;
@ -62,15 +64,52 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
/**
* Tests behavior of Guice.createInjector().getInstance(JaxrsUtil.Factory.class)
* Tests behavior of {@code JaxrsAnnotationProcessor}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "jaxrs.JaxrsUtilTest")
public class JaxrsAnnotationProcessorTest {
static class TestRequestFilter1 implements HttpRequestFilter {
public void filter(HttpRequest request) throws HttpException {
}
}
static class TestRequestFilter2 implements HttpRequestFilter {
public void filter(HttpRequest request) throws HttpException {
}
}
@RequestFilters(TestRequestFilter1.class)
static class TestRequestFilter {
@GET
@RequestFilters(TestRequestFilter2.class)
public void get() {
}
}
@Test
public void testRequestFilter() throws SecurityException, NoSuchMethodException {
Method method = TestRequestFilter.class.getMethod("get");
URI endpoint = URI.create("http://localhost");
HttpRequest httpMethod = factory.create(TestRequestFilter.class).createRequest(endpoint,
method, new Object[] {});
assertEquals(httpMethod.getFilters().size(), 2);
assertEquals(httpMethod.getFilters().get(0).getClass(), TestRequestFilter1.class);
assertEquals(httpMethod.getFilters().get(1).getClass(), TestRequestFilter2.class);
}
@SkipEncoding('/')
public class TestEncoding {
@ -103,6 +142,31 @@ public class JaxrsAnnotationProcessorTest {
assertEquals(httpMethod.getHeaders().size(), 0);
}
@SkipEncoding('/')
@Path("/v1/{account}")
public interface TestConstantPathParam {
@Named("testaccount")
@PathParam("account")
void setUsername();
@GET
@Path("{path1}/{path2}")
public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2);
}
@Test
public void testConstantPathParam() throws SecurityException, NoSuchMethodException {
Method method = TestConstantPathParam.class.getMethod("twoPaths", String.class, String.class);
URI endpoint = URI.create("http://localhost");
HttpRequest httpMethod = factory.create(TestConstantPathParam.class).createRequest(endpoint,
method, new Object[] { "1", "localhost" });
assertEquals(httpMethod.getEndpoint().getPath(), "/v1/ralphie/1/localhost");
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
assertEquals(httpMethod.getHeaders().size(), 0);
}
public class TestPath {
@GET
@ -627,6 +691,7 @@ public class JaxrsAnnotationProcessorTest {
factory = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(Names.named("testaccount")).to("ralphie");
bind(URI.class).toInstance(URI.create("http://localhost:8080"));
}
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),

View File

@ -24,8 +24,6 @@
package org.jclouds.http.httpnio.pool;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import javax.annotation.Resource;
@ -56,16 +54,6 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
private final ConsumingNHttpEntityFactory entityFactory;
private final DelegatingRetryHandler retryHandler;
private final DelegatingErrorHandler errorHandler;
private List<HttpRequestFilter> requestFilters = Collections.emptyList();
public List<HttpRequestFilter> getRequestFilters() {
return requestFilters;
}
@Inject(optional = true)
public void setRequestFilters(List<HttpRequestFilter> requestFilters) {
this.requestFilters = requestFilters;
}
/**
* inputOnly: nothing is taken from this queue.
@ -97,7 +85,7 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
.removeAttribute("command");
if (rendezvous != null) {
HttpRequest request = rendezvous.getCommand().getRequest();
for (HttpRequestFilter filter : getRequestFilters()) {
for (HttpRequestFilter filter : request.getFilters()) {
filter.filter(request);
}
return NioHttpUtils.convertToApacheRequest(request);
@ -119,7 +107,7 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
HttpCommandRendezvous<?> rendezvous = handle.getCommandRendezvous();
HttpCommand command = rendezvous.getCommand();
org.jclouds.http.HttpResponse response = NioHttpUtils.convertToJavaCloudsResponse(
command.getRequest().getEndpoint().toURL(), apacheResponse);
command.getRequest().getEndpoint().toURL(), apacheResponse);
int statusCode = response.getStatusCode();
// TODO determine how to get the original request here so we don't need to build each
// time