mirror of https://github.com/apache/jclouds.git
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:
parent
c4d8f5ff96
commit
2573d399ca
|
@ -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 {
|
||||
|
||||
/**
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,7 +178,7 @@ 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);
|
||||
if (isHttpMethod(method)) {
|
||||
for (int index = 0; index < method.getParameterTypes().length; index++) {
|
||||
methodToIndexOfParamToEntityAnnotation.get(method).get(index);
|
||||
methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
|
||||
|
@ -179,6 +187,11 @@ public class JaxrsAnnotationProcessor {
|
|||
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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,30 +84,36 @@ public class RestClientProxy implements InvocationHandler {
|
|||
return this.equals(o);
|
||||
} else if (method.getName().equals("hashCode")) {
|
||||
return this.hashCode();
|
||||
}
|
||||
} 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<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();
|
||||
|
||||
if (exceptionParser != null) {
|
||||
logger.trace("%s - wrapping future for request %s in exceptionParser %s", method, request,
|
||||
exceptionParser);
|
||||
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;
|
||||
} else {
|
||||
logger.trace("%s - invoking request synchronously %s", method, request, exceptionParser);
|
||||
logger
|
||||
.trace("%s - invoking request synchronously %s", method, request,
|
||||
exceptionParser);
|
||||
return result.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("method is intended solely to set constants: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue