Issue 74: refactored logging including addition of new trace and header logs. These remove the need for separate json and xml debugging, as it is seen in wire logs

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1968 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-10-10 21:55:18 +00:00
parent b0cc1304bd
commit 50fc3cb913
65 changed files with 1195 additions and 561 deletions

View File

@ -33,6 +33,28 @@
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" /> <param name="File" value="target/test-data/jclouds.log" />
@ -59,12 +81,27 @@
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
<category name="org.jclouds"> <category name="org.jclouds">
<priority value="TRACE" /> <priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.http.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category> </category>
<!-- ======================= --> <!-- ======================= -->
@ -73,7 +110,6 @@
<root> <root>
<priority value="WARN" /> <priority value="WARN" />
<appender-ref ref="ASYNC" />
</root> </root>
</log4j:configuration> </log4j:configuration>

View File

@ -110,11 +110,6 @@ public class S3ContextBuilder extends
return (S3ContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (S3ContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public S3ContextBuilder withJsonDebug() {
return (S3ContextBuilder) super.withJsonDebug();
}
@Override @Override
public S3ContextBuilder withModule(Module module) { public S3ContextBuilder withModule(Module module) {
return (S3ContextBuilder) super.withModule(module); return (S3ContextBuilder) super.withModule(module);
@ -150,11 +145,6 @@ public class S3ContextBuilder extends
return (S3ContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads); return (S3ContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public S3ContextBuilder withSaxDebug() {
return (S3ContextBuilder) (S3ContextBuilder) super.withSaxDebug();
}
@Override @Override
public S3ContextBuilder withEndpoint(URI endpoint) { public S3ContextBuilder withEndpoint(URI endpoint) {
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint") properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint")

View File

@ -48,8 +48,8 @@ public class S3TestInitializer extends
protected BlobStoreContext<S3Connection, BucketMetadata, ObjectMetadata, S3Object> createLiveContext( protected BlobStoreContext<S3Connection, BucketMetadata, ObjectMetadata, S3Object> createLiveContext(
Module configurationModule, String url, String app, String account, String key) { Module configurationModule, String url, String app, String account, String key) {
BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true; BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true;
return new S3ContextBuilder(account, key).withSaxDebug().relaxSSLHostname().withModules( return new S3ContextBuilder(account, key).relaxSSLHostname().withModules(configurationModule,
configurationModule, new Log4JLoggingModule()).buildContext(); new Log4JLoggingModule()).buildContext();
} }
@Override @Override

View File

@ -78,11 +78,11 @@ public class AzureBlobContextBuilder extends
"https://{account}.blob.core.windows.net"); "https://{account}.blob.core.windows.net");
} }
// @Override // @Override
// protected void addBlobStoreModule(List<Module> modules) { // protected void addBlobStoreModule(List<Module> modules) {
// modules.add(BlobStoreMapsModule.Builder.newBuilder(containerMetadataType, blobMetadataType, // modules.add(BlobStoreMapsModule.Builder.newBuilder(containerMetadataType, blobMetadataType,
// blobType).withClearContainerStrategy(RecreateClearContainerStrategy.class).build()); // blobType).withClearContainerStrategy(RecreateClearContainerStrategy.class).build());
// } // }
public AzureBlobContextBuilder(String id, String secret) { public AzureBlobContextBuilder(String id, String secret) {
this(new Properties()); this(new Properties());
@ -115,11 +115,6 @@ public class AzureBlobContextBuilder extends
return (AzureBlobContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (AzureBlobContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public AzureBlobContextBuilder withJsonDebug() {
return (AzureBlobContextBuilder) super.withJsonDebug();
}
@Override @Override
public AzureBlobContextBuilder withModule(Module module) { public AzureBlobContextBuilder withModule(Module module) {
return (AzureBlobContextBuilder) super.withModule(module); return (AzureBlobContextBuilder) super.withModule(module);
@ -161,11 +156,6 @@ public class AzureBlobContextBuilder extends
.withPoolRequestInvokerThreads(poolRequestInvokerThreads); .withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public AzureBlobContextBuilder withSaxDebug() {
return (AzureBlobContextBuilder) super.withSaxDebug();
}
@Override @Override
public AzureBlobContextBuilder withEndpoint(URI endpoint) { public AzureBlobContextBuilder withEndpoint(URI endpoint) {
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, checkNotNull(endpoint, properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, checkNotNull(endpoint,

View File

@ -53,6 +53,8 @@ import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.ReturnTrueOn404; import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
@ -350,6 +352,11 @@ public class AzureBlobConnectionTest {
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to( Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to(
"x-ms-meta-"); "x-ms-meta-");
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());

View File

@ -49,6 +49,8 @@ import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
@ -181,6 +183,11 @@ public class AzureBlobStoreTest {
HttpUtils.toBase64String("key".getBytes())); HttpUtils.toBase64String("key".getBytes()));
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to("prefix"); Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to("prefix");
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -46,8 +46,8 @@ public class AzureBlobTestInitializer extends
@Override @Override
protected BlobStoreContext<AzureBlobConnection, ContainerMetadata, BlobMetadata, Blob> createLiveContext( protected BlobStoreContext<AzureBlobConnection, ContainerMetadata, BlobMetadata, Blob> createLiveContext(
Module configurationModule, String url, String app, String account, String key) { Module configurationModule, String url, String app, String account, String key) {
return new AzureBlobContextBuilder(account, key).withSaxDebug().relaxSSLHostname() return new AzureBlobContextBuilder(account, key).relaxSSLHostname().withModules(
.withModules(configurationModule, new Log4JLoggingModule()).buildContext(); configurationModule, new Log4JLoggingModule()).buildContext();
} }
@Override @Override

View File

@ -33,6 +33,28 @@
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" /> <param name="File" value="target/test-data/jclouds.log" />
@ -59,12 +81,27 @@
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
<category name="org.jclouds"> <category name="org.jclouds">
<priority value="TRACE" /> <priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.http.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category> </category>
<!-- ======================= --> <!-- ======================= -->
@ -73,7 +110,6 @@
<root> <root>
<priority value="WARN" /> <priority value="WARN" />
<appender-ref ref="ASYNC" />
</root> </root>
</log4j:configuration> </log4j:configuration>

View File

@ -126,11 +126,6 @@ public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueConn
return (AzureQueueContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (AzureQueueContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public AzureQueueContextBuilder withJsonDebug() {
return (AzureQueueContextBuilder) super.withJsonDebug();
}
@Override @Override
public AzureQueueContextBuilder withModule(Module module) { public AzureQueueContextBuilder withModule(Module module) {
return (AzureQueueContextBuilder) super.withModule(module); return (AzureQueueContextBuilder) super.withModule(module);
@ -166,10 +161,4 @@ public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueConn
return (AzureQueueContextBuilder) super return (AzureQueueContextBuilder) super
.withPoolRequestInvokerThreads(poolRequestInvokerThreads); .withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public AzureQueueContextBuilder withSaxDebug() {
return (AzureQueueContextBuilder) super.withSaxDebug();
}
} }

View File

@ -59,7 +59,7 @@ public class AzureQueueConnectionLiveTest {
account = System.getProperty("jclouds.test.user"); account = System.getProperty("jclouds.test.user");
String key = System.getProperty("jclouds.test.key"); String key = System.getProperty("jclouds.test.key");
Injector injector = new AzureQueueContextBuilder(account, key).withModules( Injector injector = new AzureQueueContextBuilder(account, key).withModules(
new Log4JLoggingModule()).withSaxDebug().buildInjector(); new Log4JLoggingModule()).buildInjector();
connection = injector.getInstance(AzureQueueConnection.class); connection = injector.getInstance(AzureQueueConnection.class);
} }

View File

@ -44,6 +44,8 @@ import org.jclouds.http.HttpUtils;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
@ -176,6 +178,11 @@ public class AzureQueueConnectionTest {
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to( Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
HttpUtils.toBase64String("key".getBytes())); HttpUtils.toBase64String("key".getBytes()));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());

View File

@ -59,7 +59,8 @@ public abstract class BlobStoreContextBuilder<S, C extends ContainerMetadata, M
* longest time a single synchronous operation can take before throwing an exception. * longest time a single synchronous operation can take before throwing an exception.
*/ */
public BlobStoreContextBuilder<S, C, M, B> withRequestTimeout(long milliseconds) { public BlobStoreContextBuilder<S, C, M, B> withRequestTimeout(long milliseconds) {
properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long.toString(milliseconds)); properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long
.toString(milliseconds));
return this; return this;
} }
@ -69,12 +70,6 @@ public abstract class BlobStoreContextBuilder<S, C extends ContainerMetadata, M
return (BlobStoreContextBuilder<S, C, M, B>) super.withHttpMaxRetries(httpMaxRetries); return (BlobStoreContextBuilder<S, C, M, B>) super.withHttpMaxRetries(httpMaxRetries);
} }
@SuppressWarnings("unchecked")
@Override
public BlobStoreContextBuilder<S, C, M, B> withJsonDebug() {
return (BlobStoreContextBuilder<S, C, M, B>) super.withJsonDebug();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public BlobStoreContextBuilder<S, C, M, B> withModule(Module module) { public BlobStoreContextBuilder<S, C, M, B> withModule(Module module) {
@ -122,12 +117,6 @@ public abstract class BlobStoreContextBuilder<S, C extends ContainerMetadata, M
.withPoolRequestInvokerThreads(poolRequestInvokerThreads); .withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@SuppressWarnings("unchecked")
@Override
public BlobStoreContextBuilder<S, C, M, B> withSaxDebug() {
return (BlobStoreContextBuilder<S, C, M, B>) super.withSaxDebug();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public BlobStoreContextBuilder<S, C, M, B> relaxSSLHostname() { public BlobStoreContextBuilder<S, C, M, B> relaxSSLHostname() {

View File

@ -27,8 +27,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_REDIRECTS; import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_REDIRECTS;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_RETRIES; import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_RETRIES;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_RELAX_HOSTNAME; import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_RELAX_HOSTNAME;
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_IO_WORKER_THREADS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS; import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE; import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
@ -91,16 +89,6 @@ public abstract class CloudContextBuilder<C> {
this.properties = properties; this.properties = properties;
} }
public CloudContextBuilder<C> withSaxDebug() {
properties.setProperty(PROPERTY_SAX_DEBUG, "true");
return this;
}
public CloudContextBuilder<C> withJsonDebug() {
properties.setProperty(PROPERTY_JSON_DEBUG, "true");
return this;
}
/** /**
* allow mismatches between the certificate and the hostname of ssl requests. * allow mismatches between the certificate and the hostname of ssl requests.
*/ */
@ -267,8 +255,5 @@ public abstract class CloudContextBuilder<C> {
Injector injector = buildInjector(); Injector injector = buildInjector();
return (CloudContext<C>) injector.getInstance(Key.get(Types.newParameterizedType( return (CloudContext<C>) injector.getInstance(Key.get(Types.newParameterizedType(
CloudContext.class, connectionType.getType()))); CloudContext.class, connectionType.getType())));
// return (CloudContext<C>) this.buildInjector().getInstance(
// Key.get(new TypeLiteral<CloudContext<?>>() {
// }));
} }
} }

View File

@ -31,8 +31,8 @@ package org.jclouds.http;
public interface HttpConstants { public interface HttpConstants {
public static final String PROPERTY_HTTP_MAX_RETRIES = "jclouds.http.max-retries"; 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_HTTP_MAX_REDIRECTS = "jclouds.http.max-redirects";
public static final String PROPERTY_SAX_DEBUG = "jclouds.http.sax.debug"; public static final String HTTP_HEADERS_LOGGER = "jclouds.http.headers";
public static final String PROPERTY_JSON_DEBUG = "jclouds.http.json.debug"; public static final String HTTP_WIRE_LOGGER = "jclouds.http.wire";
/** /**
* longest time a single request can take before throwing an exception. * longest time a single request can take before throwing an exception.

View File

@ -88,21 +88,8 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
setEntity(entity); setEntity(entity);
} }
@Override public String getRequestLine() {
public String toString() { return String.format("%s %s HTTP/1.1", getMethod(), endpoint.toASCIIString());
final StringBuilder sb = new StringBuilder();
sb.append("HttpRequest");
sb.append("{endPoint='").append(endpoint).append('\'');
sb.append(", method='").append(method).append('\'');
sb.append(", headers=").append(headers);
sb.append(", filters=").append(requestFilters);
if (entity != null && entity instanceof String) {
sb.append(", entity=").append(entity);
} else {
sb.append(", entity set=").append(entity != null);
}
sb.append('}');
return sb.toString();
} }
/** /**

View File

@ -35,18 +35,6 @@ public class HttpResponse extends HttpMessage {
private String message; private String message;
private InputStream content; private InputStream content;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("HttpResponse");
sb.append("{statusCode=").append(statusCode);
sb.append(", headers=").append(headers);
sb.append(", message='").append(message).append('\'');
sb.append(", content set=").append(content != null);
sb.append('}');
return sb.toString();
}
public int getStatusCode() { public int getStatusCode() {
return statusCode; return statusCode;
} }
@ -71,4 +59,8 @@ public class HttpResponse extends HttpMessage {
this.content = content; this.content = content;
} }
public String getStatusLine() {
return String.format("HTTP/1.1 %d %s", getStatusCode(), getMessage());
}
} }

View File

@ -30,6 +30,7 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -177,6 +178,26 @@ public class HttpUtils {
} }
public static void copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024];
long length = 0;
int numRead = -1;
try {
do {
numRead = input.read(buffer);
if (numRead > 0) {
length += numRead;
output.write(buffer, 0, numRead);
}
} while (numRead != -1);
} finally {
output.close();
IOUtils.closeQuietly(input);
}
}
public static MD5InputStreamResult generateMD5Result(InputStream toEncode) throws IOException { public static MD5InputStreamResult generateMD5Result(InputStream toEncode) throws IOException {
MD5Digest eTag = new MD5Digest(); MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()]; byte[] resBuf = new byte[eTag.getDigestSize()];

View File

@ -28,6 +28,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import org.jclouds.concurrent.FutureFunctionCallable; import org.jclouds.concurrent.FutureFunctionCallable;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function; import com.google.common.base.Function;
import javax.inject.Inject; import javax.inject.Inject;
@ -42,12 +43,14 @@ public class TransformingHttpCommandExecutorServiceImpl implements
TransformingHttpCommandExecutorService { TransformingHttpCommandExecutorService {
private final HttpCommandExecutorService client; private final HttpCommandExecutorService client;
private final ExecutorService executorService; private final ExecutorService executorService;
private final LoggerFactory logFactory;
@Inject @Inject
public TransformingHttpCommandExecutorServiceImpl(HttpCommandExecutorService client, public TransformingHttpCommandExecutorServiceImpl(HttpCommandExecutorService client,
ExecutorService executorService) { ExecutorService executorService, LoggerFactory logFactory) {
this.client = client; this.client = client;
this.executorService = executorService; this.executorService = executorService;
this.logFactory = logFactory;
} }
/** /**
@ -57,7 +60,7 @@ public class TransformingHttpCommandExecutorServiceImpl implements
Function<Exception, T> exceptionTransformer) { Function<Exception, T> exceptionTransformer) {
Future<HttpResponse> responseFuture = client.submit(command); Future<HttpResponse> responseFuture = client.submit(command);
Callable<T> valueCallable = new FutureFunctionCallable<HttpResponse, T>(responseFuture, Callable<T> valueCallable = new FutureFunctionCallable<HttpResponse, T>(responseFuture,
responseTransformer); responseTransformer, logFactory.getLogger(responseTransformer.getClass().getName()));
return executorService.submit(valueCallable); return executorService.submit(valueCallable);
} }

View File

@ -30,13 +30,13 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import javax.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.google.inject.internal.Nullable; import com.google.inject.internal.Nullable;
@ -66,7 +66,7 @@ public class TransformingHttpCommandImpl<T> implements TransformingHttpCommand<T
@Override @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("TransformingHttpCommandImpl"); sb.append("HttpCommand");
sb.append("{request='").append(request).append('\''); sb.append("{request='").append(request).append('\'');
sb.append(", transformer='").append(transformer).append('\''); sb.append(", transformer='").append(transformer).append('\'');
sb.append(", exceptionTransformer='").append(exceptionTransformer).append('\''); sb.append(", exceptionTransformer='").append(exceptionTransformer).append('\'');

View File

@ -1,53 +0,0 @@
/**
*
* 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.http;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import com.google.common.base.Function;
public class TransformingHttpUtils {
public static <T> HttpCommandRendezvous<T> submitHttpCommand(HttpCommand command,
final Function<HttpResponse, T> responseTransformer, ExecutorService executorService) {
final SynchronousQueue<?> channel = new SynchronousQueue<Object>();
// should block and immediately parse the response on exit.
Future<T> future = executorService.submit(new Callable<T>() {
public T call() throws Exception {
Object o = channel.take();
if (o instanceof Exception)
throw (Exception) o;
return responseTransformer.apply((HttpResponse) o);
}
});
HttpCommandRendezvous<T> rendezvous = new HttpCommandRendezvous<T>(command, channel, future);
return rendezvous;
}
}

View File

@ -23,8 +23,6 @@
*/ */
package org.jclouds.http.functions; package org.jclouds.http.functions;
import static org.jclouds.http.HttpConstants.PROPERTY_JSON_DEBUG;
import java.io.InputStream; import java.io.InputStream;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -36,8 +34,6 @@ import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.gson.Gson; import com.google.gson.Gson;
import javax.inject.Inject;
import javax.inject.Named;
/** /**
* This object will parse the body of an HttpResponse and return the result of type <T> back to the * This object will parse the body of an HttpResponse and return the result of type <T> back to the
@ -47,9 +43,6 @@ import javax.inject.Named;
*/ */
public abstract class ParseJson<T> implements Function<HttpResponse, T> { public abstract class ParseJson<T> implements Function<HttpResponse, T> {
@Inject(optional = true)
@Named(PROPERTY_JSON_DEBUG)
private boolean suckFirst = false;
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final Gson gson; protected final Gson gson;
@ -63,23 +56,13 @@ public abstract class ParseJson<T> implements Function<HttpResponse, T> {
*/ */
public T apply(HttpResponse from) { public T apply(HttpResponse from) {
InputStream gson = from.getContent(); InputStream gson = from.getContent();
String response = null;
try { try {
if (suckFirst) {
response = IOUtils.toString(gson);
logger.trace("received content %n%s", response);
IOUtils.closeQuietly(gson);
gson = IOUtils.toInputStream(response);
}
return apply(gson); return apply(gson);
} catch (Exception e) { } catch (Exception e) {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
message.append("Error parsing input"); message.append("Error parsing input");
if (response != null) {
message.append("\n").append(response);
}
logger.error(e, message.toString()); logger.error(e, message.toString());
throw new HttpResponseException(message.toString()+"\n"+from, null, from, e); throw new HttpResponseException(message.toString() + "\n" + from, null, from, e);
} finally { } finally {
IOUtils.closeQuietly(gson); IOUtils.closeQuietly(gson);
} }

View File

@ -24,11 +24,11 @@
package org.jclouds.http.functions; package org.jclouds.http.functions;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.HttpConstants.PROPERTY_SAX_DEBUG;
import java.io.InputStream; import java.io.InputStream;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
@ -41,9 +41,7 @@ import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import com.google.common.base.Function; import com.google.common.base.Function;
import javax.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import javax.inject.Named;
/** /**
* This object will parse the body of an HttpResponse and return the result of type <T> back to the * This object will parse the body of an HttpResponse and return the result of type <T> back to the
@ -55,9 +53,6 @@ public class ParseSax<T> implements Function<HttpResponse, T> {
private final XMLReader parser; private final XMLReader parser;
private final HandlerWithResult<T> handler; private final HandlerWithResult<T> handler;
@Inject(optional = true)
@Named(PROPERTY_SAX_DEBUG)
private boolean suckFirst = false;
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@ -93,14 +88,7 @@ public class ParseSax<T> implements Function<HttpResponse, T> {
} }
private void parseAndCloseStream(InputStream xml, ContentHandler handler) throws HttpException { private void parseAndCloseStream(InputStream xml, ContentHandler handler) throws HttpException {
String response = null;
try { try {
if (suckFirst) {
response = IOUtils.toString(xml);
logger.trace("received content %n%s", response);
IOUtils.closeQuietly(xml);
xml = IOUtils.toInputStream(response);
}
parser.setContentHandler(handler); parser.setContentHandler(handler);
// This method should accept documents with a BOM (Byte-order mark) // This method should accept documents with a BOM (Byte-order mark)
InputSource input = new InputSource(xml); InputSource input = new InputSource(xml);
@ -108,9 +96,6 @@ public class ParseSax<T> implements Function<HttpResponse, T> {
} catch (Exception e) { } catch (Exception e) {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
message.append("Error parsing input for ").append(handler); message.append("Error parsing input for ").append(handler);
if (response != null) {
message.append("\n").append(response);
}
logger.error(e, message.toString()); logger.error(e, message.toString());
if (!(e instanceof NullPointerException)) if (!(e instanceof NullPointerException))
Utils.<HttpException> rethrowIfRuntimeOrSameType(e); Utils.<HttpException> rethrowIfRuntimeOrSameType(e);

View File

@ -24,14 +24,17 @@
package org.jclouds.http.internal; package org.jclouds.http.internal;
import java.io.IOException; import java.io.IOException;
import java.util.Map.Entry;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Named;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
@ -47,12 +50,18 @@ public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandEx
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@Resource
@Named(HttpConstants.HTTP_HEADERS_LOGGER)
protected Logger headerLog = Logger.NULL;
private final Wire wire;
protected BaseHttpCommandExecutorService(ExecutorService executorService, protected BaseHttpCommandExecutorService(ExecutorService executorService,
DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler) { DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler, Wire wire) {
this.retryHandler = retryHandler; this.retryHandler = retryHandler;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
this.executorService = executorService; this.executorService = executorService;
this.wire = wire;
} }
public Future<HttpResponse> submit(HttpCommand command) { public Future<HttpResponse> submit(HttpCommand command) {
@ -73,13 +82,31 @@ public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandEx
HttpRequest request = command.getRequest(); HttpRequest request = command.getRequest();
Q nativeRequest = null; Q nativeRequest = null;
try { try {
logger.trace("%s - filtering request %s", request.getEndpoint(), request);
for (HttpRequestFilter filter : request.getFilters()) { for (HttpRequestFilter filter : request.getFilters()) {
request = filter.filter(request); request = filter.filter(request);
} }
logger.trace("%s - request now %s", request.getEndpoint(), request); logger.debug("Sending request: %s", request.getRequestLine());
if (request.getEntity() != null && wire.enabled())
request.setEntity(wire.output(request.getEntity()));
nativeRequest = convert(request); nativeRequest = convert(request);
if (headerLog.isDebugEnabled()) {
headerLog.debug(">> %s", request.getRequestLine().toString());
for (Entry<String, String> header : request.getHeaders().entries()) {
if (header.getKey() != null)
headerLog.debug(">> %s: %s", header.getKey(), header.getValue());
}
}
response = invoke(nativeRequest); response = invoke(nativeRequest);
logger.debug("Receiving response: " + response.getStatusLine());
if (headerLog.isDebugEnabled()) {
headerLog.debug("<< " + response.getStatusLine().toString());
for (Entry<String, String> header : response.getHeaders().entries()) {
if (header.getKey() != null)
headerLog.debug("<< %s: %s", header.getKey(), header.getValue());
}
}
if (response.getContent() != null && wire.enabled())
response.setContent(wire.input(response.getContent()));
int statusCode = response.getStatusCode(); int statusCode = response.getStatusCode();
if (statusCode >= 300) { if (statusCode >= 300) {
if (retryHandler.shouldRetryRequest(command, response)) { if (retryHandler.shouldRetryRequest(command, response)) {

View File

@ -66,8 +66,8 @@ public class JavaUrlHttpCommandExecutorService extends
@Inject @Inject
public JavaUrlHttpCommandExecutorService(ExecutorService executorService, public JavaUrlHttpCommandExecutorService(ExecutorService executorService,
DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler) { DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler, Wire wire) {
super(executorService, retryHandler, errorHandler); super(executorService, retryHandler, errorHandler, wire);
sslMap = Maps.newHashMap(); sslMap = Maps.newHashMap();
} }
@ -88,8 +88,6 @@ public class JavaUrlHttpCommandExecutorService extends
@Override @Override
protected HttpResponse invoke(HttpURLConnection connection) throws IOException { protected HttpResponse invoke(HttpURLConnection connection) throws IOException {
logger.trace("%s - submitting request %s; %s", connection.getURL().getHost(), connection
.getURL(), connection.getHeaderFields().toString());
HttpResponse response = new HttpResponse(); HttpResponse response = new HttpResponse();
InputStream in; InputStream in;
try { try {
@ -97,8 +95,6 @@ public class JavaUrlHttpCommandExecutorService extends
} catch (IOException e) { } catch (IOException e) {
in = connection.getErrorStream(); in = connection.getErrorStream();
} }
logger.trace("%s - received response code %s, headers: %s", connection.getURL().getHost(),
connection.getResponseCode(), connection.getHeaderFields());
if (in != null) { if (in != null) {
response.setContent(in); response.setContent(in);
} }

View File

@ -0,0 +1,166 @@
package org.jclouds.http.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.ExecutorService;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.TeeInputStream;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.http.HttpConstants;
import org.jclouds.logging.Logger;
/**
* Logs data to the wire LOG.
*
* @author Adrian Cole
* @see org.apache.http.impl.conn.Wire
*/
public class Wire {
@Resource
@Named(HttpConstants.HTTP_WIRE_LOGGER)
protected Logger wireLog = Logger.NULL;
@Resource
protected Logger logger = Logger.NULL;
private final ExecutorService exec;
@Inject
public Wire(ExecutorService exec) {
this.exec = checkNotNull(exec, "executor");
}
private void wire(String header, InputStream instream) {
StringBuilder buffer = new StringBuilder();
int ch;
try {
while ((ch = instream.read()) != -1) {
if (ch == 13) {
buffer.append("[\\r]");
} else if (ch == 10) {
buffer.append("[\\n]\"");
buffer.insert(0, "\"");
buffer.insert(0, header);
wireLog.debug(buffer.toString());
buffer.setLength(0);
} else if ((ch < 32) || (ch > 127)) {
buffer.append("[0x");
buffer.append(Integer.toHexString(ch));
buffer.append("]");
} else {
buffer.append((char) ch);
}
}
if (buffer.length() > 0) {
buffer.append('\"');
buffer.insert(0, '\"');
buffer.insert(0, header);
wireLog.debug(buffer.toString());
}
} catch (IOException e) {
logger.error(e, "Error tapping line");
}
}
public boolean enabled() {
return wireLog.isDebugEnabled();
}
public InputStream copy(final String header, InputStream instream) {
try {
byte[] data = IOUtils.toByteArray(instream);
wire(header, new ByteArrayInputStream(data));
return new ByteArrayInputStream(data);
} catch (IOException e) {
throw new RuntimeException("Error tapping line", e);
} finally {
IOUtils.closeQuietly(instream);
}
}
public InputStream tapAsynch(final String header, InputStream instream) {
PipedOutputStream out = new PipedOutputStream();
InputStream toReturn = new TeeInputStream(instream, out, true);
final InputStream line;
try {
line = new PipedInputStream(out);
exec.submit(new Runnable() {
public void run() {
try {
wire(header, line);
} finally {
IOUtils.closeQuietly(line);
}
}
});
} catch (IOException e) {
logger.error(e, "Error tapping line");
}
return toReturn;
}
public InputStream input(InputStream instream) {
return copy("<< ", checkNotNull(instream, "input"));
}
@SuppressWarnings("unchecked")
public <T> T output(T data) {
checkNotNull(data, "data must be set before calling generateETag()");
if (data instanceof InputStream) {
if (exec.getClass().isAnnotationPresent(SingleThreaded.class))
return (T) copy(">> ", (InputStream) data);
else
return (T) tapAsynch(">> ", (InputStream) data);
} else if (data instanceof byte[]) {
output((byte[]) data);
return data;
} else if (data instanceof String) {
output((String) data);
return data;
} else if (data instanceof File) {
output(((File) data));
return data;
} else {
throw new UnsupportedOperationException("Content not supported " + data.getClass());
}
}
private void output(final File out) {
checkNotNull(out, "output");
exec.submit(new Runnable() {
public void run() {
InputStream in = null;
try {
in = new FileInputStream(out);
wire(">> ", in);
} catch (FileNotFoundException e) {
logger.error(e, "Error tapping file: %s", out);
} finally {
IOUtils.closeQuietly(in);
}
}
});
}
private void output(byte[] b) {
wire(">> ", new ByteArrayInputStream(checkNotNull(b, "output")));
}
private void output(final String s) {
output(checkNotNull(s, "output").getBytes());
}
}

View File

@ -36,17 +36,20 @@ import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import javax.inject.Inject;
import org.jclouds.concurrent.FutureExceptionParser; import org.jclouds.concurrent.FutureExceptionParser;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpCommandRendezvous; import org.jclouds.http.HttpCommandRendezvous;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.TransformingHttpCommandExecutorService; import org.jclouds.http.TransformingHttpCommandExecutorService;
import org.jclouds.lifecycle.BaseLifeCycle; import org.jclouds.lifecycle.BaseLifeCycle;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import javax.inject.Inject;
/** /**
* // TODO: Adrian: Document this! * // TODO: Adrian: Document this!
@ -59,11 +62,12 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
private final ConcurrentMap<URI, HttpCommandConnectionPool<C>> poolMap; private final ConcurrentMap<URI, HttpCommandConnectionPool<C>> poolMap;
private final BlockingQueue<HttpCommandRendezvous<?>> commandQueue; private final BlockingQueue<HttpCommandRendezvous<?>> commandQueue;
private final HttpCommandConnectionPool.Factory<C> poolFactory; private final HttpCommandConnectionPool.Factory<C> poolFactory;
private final LoggerFactory logFactory;
@Inject @Inject
public ConnectionPoolTransformingHttpCommandExecutorService(ExecutorService executor, public ConnectionPoolTransformingHttpCommandExecutorService(ExecutorService executor,
HttpCommandConnectionPool.Factory<C> pf, HttpCommandConnectionPool.Factory<C> pf,
BlockingQueue<HttpCommandRendezvous<?>> commandQueue) { BlockingQueue<HttpCommandRendezvous<?>> commandQueue, LoggerFactory logFactory) {
super(executor); super(executor);
this.poolFactory = pf; this.poolFactory = pf;
// TODO inject this. // TODO inject this.
@ -82,6 +86,7 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
} }
}); });
this.commandQueue = commandQueue; this.commandQueue = commandQueue;
this.logFactory = logFactory;
} }
/** /**
@ -120,7 +125,7 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
invoke(rendezvous); invoke(rendezvous);
} catch (Exception e) { } catch (Exception e) {
Utils.<InterruptedException> rethrowIfRuntimeOrSameType(e); Utils.<InterruptedException> rethrowIfRuntimeOrSameType(e);
logger.error(e, "Error processing command %s", rendezvous); logger.error(e, "Error processing command %s", rendezvous.getCommand());
} }
} }
} }
@ -135,14 +140,18 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
Function<Exception, T> exceptionTransformer) { Function<Exception, T> exceptionTransformer) {
exceptionIfNotActive(); exceptionIfNotActive();
final SynchronousQueue<?> channel = new SynchronousQueue<Object>(); final SynchronousQueue<?> channel = new SynchronousQueue<Object>();
// should block and immediately parse the response on exit. // should block and immediately parse the response on exit.
Future<T> future = executorService.submit(new Callable<T>() { Future<T> future = executorService.submit(new Callable<T>() {
Logger transformerLogger = logFactory.getLogger(responseTransformer.getClass().getName());
public T call() throws Exception { public T call() throws Exception {
Object o = channel.take(); Object o = channel.take();
if (o instanceof Exception) if (o instanceof Exception) {
throw (Exception) o; throw (Exception) o;
return responseTransformer.apply((HttpResponse) o); }
transformerLogger.debug("Processing intermediate result for: %s", o);
T result = responseTransformer.apply((HttpResponse) o);
transformerLogger.debug("Processed intermediate result for: %s", o);
return result;
} }
}); });
@ -169,7 +178,7 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
HttpCommandConnectionPool<C> pool = poolMap.get(endpoint); HttpCommandConnectionPool<C> pool = poolMap.get(endpoint);
if (pool == null) { if (pool == null) {
// TODO limit; // TODO limit;
logger.warn("pool not available for command %s; retrying", command); logger.warn("pool not available for command %s; retrying", command.getCommand());
commandQueue.add(command); commandQueue.add(command);
return; return;
} }
@ -178,24 +187,25 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
try { try {
connectionHandle = pool.getHandle(command); connectionHandle = pool.getHandle(command);
} catch (InterruptedException e) { } catch (InterruptedException e) {
logger.warn(e, "Interrupted getting a connection for command %s; retrying", command); logger.warn(e, "Interrupted getting a connection for command %s; retrying", command
.getCommand());
commandQueue.add(command); commandQueue.add(command);
return; return;
} catch (TimeoutException e) { } catch (TimeoutException e) {
logger.warn(e, "Timeout getting a connection for command %s on pool %s; retrying", logger.warn(e, "Timeout getting a connection for command %s on pool %s; retrying", command
command, pool); .getCommand(), pool);
commandQueue.add(command); commandQueue.add(command);
return; return;
} catch (RuntimeException e) { } catch (RuntimeException e) {
logger.warn(e, "Error getting a connection for command %s on pool %s; retrying", command, logger.warn(e, "Error getting a connection for command %s on pool %s; retrying", command
pool); .getCommand(), pool);
discardPool(endpoint, pool); discardPool(endpoint, pool);
commandQueue.add(command); commandQueue.add(command);
return; return;
} }
if (connectionHandle == null) { if (connectionHandle == null) {
logger.error("Failed to obtain connection for command %s; retrying", command); logger.error("Failed to obtain connection for command %s; retrying", command.getCommand());
commandQueue.add(command); commandQueue.add(command);
return; return;
} }
@ -221,16 +231,4 @@ public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends Bas
endpoint.getPort())); endpoint.getPort()));
} }
} }
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("ConnectionPoolTransformingHttpCommandExecutorService");
sb.append("{status=").append(status);
sb.append(", commandQueue=").append((commandQueue != null) ? commandQueue.size() : 0);
sb.append(", poolMap=").append(poolMap);
sb.append('}');
return sb.toString();
}
} }

View File

@ -46,18 +46,6 @@ import com.google.inject.assistedinject.Assisted;
*/ */
public abstract class HttpCommandConnectionPool<C> extends BaseLifeCycle { public abstract class HttpCommandConnectionPool<C> extends BaseLifeCycle {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("HttpCommandConnectionPool");
sb.append("{endPoint=").append(endPoint);
sb.append(", available=").append(available);
sb.append(", currentSessionFailures=").append(currentSessionFailures);
sb.append(", hitBottom=").append(hitBottom);
sb.append('}');
return sb.toString();
}
protected final Semaphore allConnections; protected final Semaphore allConnections;
protected final BlockingQueue<C> available; protected final BlockingQueue<C> available;
@ -110,20 +98,18 @@ public abstract class HttpCommandConnectionPool<C> extends BaseLifeCycle {
if (!hitBottom) { if (!hitBottom) {
hitBottom = available.size() == 0 && allConnections.availablePermits() == 0; hitBottom = available.size() == 0 && allConnections.availablePermits() == 0;
if (hitBottom) if (hitBottom)
logger.warn("%1$s - saturated connection pool", this); logger.warn("saturated connection pool");
} }
logger.debug("%s - attempting to acquire connection; %s currently available", this, available logger.trace("Blocking up to %ds for a connection to %s", 5, getEndPoint());
.size());
C conn = available.poll(5, TimeUnit.SECONDS); C conn = available.poll(5, TimeUnit.SECONDS);
if (conn == null) if (conn == null)
throw new TimeoutException("could not obtain a pooled connection within 5 seconds"); throw new TimeoutException(String.format("Timeout after %ds for a connection to %s", 5,
getEndPoint()));
logger.trace("%1$s - %2$d - aquired", conn, conn.hashCode());
if (connectionValid(conn)) { if (connectionValid(conn)) {
logger.debug("%1$s - %2$d - reusing", conn, conn.hashCode());
return conn; return conn;
} else { } else {
logger.debug("%1$s - %2$d - unusable", conn, conn.hashCode()); logger.debug("Connection %s unusable for endpoint %s", conn.hashCode(), getEndPoint());
shutdownConnection(conn); shutdownConnection(conn);
allConnections.release(); allConnections.release();
return getConnection(); return getConnection();
@ -156,7 +142,8 @@ public abstract class HttpCommandConnectionPool<C> extends BaseLifeCycle {
HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(connection); HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(connection);
if (rendezvous != null) { if (rendezvous != null) {
if (isReplayable(rendezvous)) { if (isReplayable(rendezvous)) {
logger.info("resubmitting rendezvous: %1$s", rendezvous); logger.info("resubmitting request: %s", rendezvous.getCommand().getRequest()
.getRequestLine());
resubmitQueue.add(rendezvous); resubmitQueue.add(rendezvous);
} else { } else {
setExceptionOnCommand(e, rendezvous); setExceptionOnCommand(e, rendezvous);
@ -182,11 +169,11 @@ public abstract class HttpCommandConnectionPool<C> extends BaseLifeCycle {
} }
protected void setExceptionOnCommand(Exception e, HttpCommandRendezvous<?> rendezvous) { protected void setExceptionOnCommand(Exception e, HttpCommandRendezvous<?> rendezvous) {
logger.warn(e, "exception in rendezvous: %s", rendezvous); logger.warn(e, "Exception processing command: %s", rendezvous.getCommand());
try { try {
rendezvous.setException(e); rendezvous.setException(e);
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
logger.error(e, "interrupted setting exception on command", rendezvous); logger.error(e, "interrupted setting exception on command", rendezvous.getCommand());
} }
} }

View File

@ -100,7 +100,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
@PostConstruct @PostConstruct
public void start() { public void start() {
logger.info("starting %1$s", this); logger.info("Starting %s", this);
synchronized (this.statusLock) { synchronized (this.statusLock) {
if (this.status.compareTo(Status.SHUTDOWN_REQUEST) >= 0) { if (this.status.compareTo(Status.SHUTDOWN_REQUEST) >= 0) {
doShutdown(); doShutdown();

View File

@ -47,37 +47,41 @@ public abstract class BaseLogger implements Logger {
public void trace(String message, Object... args) { public void trace(String message, Object... args) {
if (isTraceEnabled()) if (isTraceEnabled())
logTrace(String.format(message, args)); logTrace(formatIfArgs(message, args));
}
private String formatIfArgs(String message, Object... args) {
return args.length == 0 ? message : String.format(message, args);
} }
public void debug(String message, Object... args) { public void debug(String message, Object... args) {
if (isDebugEnabled()) if (isDebugEnabled())
logDebug(String.format(message, args)); logDebug(formatIfArgs(message, args));
} }
public void info(String message, Object... args) { public void info(String message, Object... args) {
if (isInfoEnabled()) if (isInfoEnabled())
logInfo(String.format(message, args)); logInfo(formatIfArgs(message, args));
} }
public void warn(String message, Object... args) { public void warn(String message, Object... args) {
if (isWarnEnabled()) if (isWarnEnabled())
logWarn(String.format(message, args)); logWarn(formatIfArgs(message, args));
} }
public void warn(Throwable e, String message, Object... args) { public void warn(Throwable e, String message, Object... args) {
if (isWarnEnabled()) if (isWarnEnabled())
logWarn(String.format(message, args), e); logWarn(formatIfArgs(message, args), e);
} }
public void error(String message, Object... args) { public void error(String message, Object... args) {
if (isErrorEnabled()) if (isErrorEnabled())
logError(String.format(message, args)); logError(formatIfArgs(message, args));
} }
public void error(Throwable e, String message, Object... args) { public void error(Throwable e, String message, Object... args) {
if (isErrorEnabled()) if (isErrorEnabled())
logError(String.format(message, args), e); logError(formatIfArgs(message, args), e);
} }
} }

View File

@ -23,25 +23,29 @@
*/ */
package org.jclouds.logging.config; package org.jclouds.logging.config;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import static com.google.common.collect.Sets.filter; import static com.google.common.collect.Sets.filter;
import javax.inject.Inject;
import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import javax.annotation.Resource;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
/** /**
* TypeListener that will bind {@link org.jclouds.logging.Logger} to members annotated with * TypeListener that will bind {@link org.jclouds.logging.Logger} to members annotated with
* {@link javax.annotation.Resource} * {@link javax.annotation.Resource}
@ -119,9 +123,14 @@ public class BindLoggersAnnotatedWithResource implements TypeListener {
Logger logger = loggerFactory.getLogger(type.getName()); Logger logger = loggerFactory.getLogger(type.getName());
for (Field field : loggerFields) { for (Field field : loggerFields) {
if (field.isAnnotationPresent(Named.class)){
Named name = field.getAnnotation(Named.class);
encounter.register(new AssignLoggerToField<I>(loggerFactory.getLogger(name.value()), field));
} else {
encounter.register(new AssignLoggerToField<I>(logger, field)); encounter.register(new AssignLoggerToField<I>(logger, field));
} }
} }
}
@VisibleForTesting @VisibleForTesting
Set<Field> getLoggerFieldsAnnotatedWithResource(Class<?> declaredType) { Set<Field> getLoggerFieldsAnnotatedWithResource(Class<?> declaredType) {

View File

@ -25,13 +25,15 @@ package org.jclouds.logging.config;
import static com.google.inject.matcher.Matchers.any; import static com.google.inject.matcher.Matchers.any;
import javax.inject.Singleton;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/** /**
* Creates a post-injection listener that binds Loggers named the same as the * Creates a post-injection listener that binds Loggers named the same as the enclosing class.
* enclosing class.
* *
* @author Adrian Cole * @author Adrian Cole
* *
@ -40,10 +42,11 @@ public abstract class LoggingModule extends AbstractModule {
@Override @Override
protected void configure() { protected void configure() {
bindListener(any(), new BindLoggersAnnotatedWithResource( bindListener(any(), new BindLoggersAnnotatedWithResource(createLoggerFactory()));
createLoggerFactory()));
} }
@Provides
@Singleton
public abstract Logger.LoggerFactory createLoggerFactory(); public abstract Logger.LoggerFactory createLoggerFactory();
} }

View File

@ -243,7 +243,7 @@ public class RestAnnotationProcessor<T> {
} else if (isConstantDeclaration(method)) { } else if (isConstantDeclaration(method)) {
bindConstant(method); bindConstant(method);
} else if (!method.getDeclaringClass().equals(declaring)) { } else if (!method.getDeclaringClass().equals(declaring)) {
logger.debug("skipping potentially overridden method", method); logger.debug("skipping potentially overridden method %s", method);
} else { } else {
throw new RuntimeException("Method is not annotated as either http or constant: " throw new RuntimeException("Method is not annotated as either http or constant: "
+ method); + method);
@ -422,7 +422,7 @@ public class RestAnnotationProcessor<T> {
RequestFilters.class).value()) { RequestFilters.class).value()) {
HttpRequestFilter instance = injector.getInstance(clazz); HttpRequestFilter instance = injector.getInstance(clazz);
request.getFilters().add(instance); request.getFilters().add(instance);
logger.debug("%s - adding filter %s from annotation on %s", request, instance, logger.trace("%s - adding filter %s from annotation on %s", request, instance,
declaring.getName()); declaring.getName());
} }
} }
@ -431,7 +431,7 @@ public class RestAnnotationProcessor<T> {
.value()) { .value()) {
HttpRequestFilter instance = injector.getInstance(clazz); HttpRequestFilter instance = injector.getInstance(clazz);
request.getFilters().add(instance); request.getFilters().add(instance);
logger.debug("%s - adding filter %s from annotation on %s", request, instance, method logger.trace("%s - adding filter %s from annotation on %s", request, instance, method
.getName()); .getName());
} }
} }

View File

@ -69,8 +69,8 @@ public class RestClientProxy<T> implements InvocationHandler {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Inject @Inject
public RestClientProxy(TransformingHttpCommand.Factory factory, public RestClientProxy(TransformingHttpCommand.Factory factory, RestAnnotationProcessor<T> util,
RestAnnotationProcessor<T> util, TypeLiteral<T> typeLiteral) { TypeLiteral<T> typeLiteral) {
this.util = util; this.util = util;
this.declaring = (Class<T>) typeLiteral.getRawType(); this.declaring = (Class<T>) typeLiteral.getRawType();
this.commandFactory = factory; this.commandFactory = factory;
@ -84,7 +84,7 @@ public class RestClientProxy<T> implements InvocationHandler {
return this.hashCode(); return this.hashCode();
} else if (util.getDelegateOrNull(method) != null) { } else if (util.getDelegateOrNull(method) != null) {
method = util.getDelegateOrNull(method); method = util.getDelegateOrNull(method);
logger.trace("%s - converting method to request", method); logger.trace("Converting %s.%s", declaring.getSimpleName(), method.getName());
Function<Exception, ?> exceptionParser = util Function<Exception, ?> exceptionParser = util
.createExceptionParserOrNullIfNotFound(method); .createExceptionParserOrNullIfNotFound(method);
// in case there is an exception creating the request, we should at least pass in args // in case there is an exception creating the request, we should at least pass in args
@ -133,27 +133,27 @@ public class RestClientProxy<T> implements InvocationHandler {
} }
throw e; throw e;
} }
logger.debug("Converted %s.%s to %s", declaring.getSimpleName(), method.getName(), request
logger.trace("%s - converted method to request %s", method, request); .getRequestLine());
Function<HttpResponse, ?> transformer = util.createResponseParser(method, request, args); Function<HttpResponse, ?> transformer = util.createResponseParser(method, request, args);
logger.trace("Response from %s.%s is parsed by %s", declaring.getSimpleName(), method
.getName(), transformer.getClass().getSimpleName());
logger.trace("%s - creating command for request %s, transformer %s, exceptionParser %s", logger.debug("Invoking %s.%s", declaring.getSimpleName(), method.getName());
method, request, transformer, exceptionParser);
Future<?> result = commandFactory.create(request, transformer, exceptionParser).execute(); Future<?> result = commandFactory.create(request, transformer, exceptionParser).execute();
if (exceptionParser != null) { if (exceptionParser != null) {
logger.trace("%s - wrapping future for request %s in exceptionParser %s", method, logger.trace("Exceptions from %s.%s are parsed by %s", declaring.getSimpleName(),
request, exceptionParser); method.getName(), exceptionParser.getClass().getSimpleName());
result = new FutureExceptionParser(result, exceptionParser); result = new FutureExceptionParser(result, exceptionParser);
} }
if (method.getReturnType().isAssignableFrom(Future.class)) { if (method.getReturnType().isAssignableFrom(Future.class)) {
return result; return result;
} else { } else {
logger logger.debug("Blocking up to %dms for %s.%s to complete", requestTimeoutMilliseconds,
.trace("%s - invoking request synchronously %s", method, request, declaring.getSimpleName(), method.getName());
exceptionParser);
return result.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS); return result.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
} }
} else { } else {

View File

@ -39,6 +39,9 @@ import org.jclouds.http.TransformingHttpCommandExecutorServiceImpl;
import org.jclouds.http.TransformingHttpCommandImpl; import org.jclouds.http.TransformingHttpCommandImpl;
import org.jclouds.http.functions.ReturnStringIf200; import org.jclouds.http.functions.ReturnStringIf200;
import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService; import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService;
import org.jclouds.http.internal.Wire;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -91,8 +94,16 @@ public class BackoffLimitedRetryHandlerTest {
void setupExecutorService() throws Exception { void setupExecutorService() throws Exception {
ExecutorService execService = Executors.newCachedThreadPool(); ExecutorService execService = Executors.newCachedThreadPool();
JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService( JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService(
execService, new DelegatingRetryHandler(), new DelegatingErrorHandler()); execService, new DelegatingRetryHandler(), new DelegatingErrorHandler(), new Wire(
executorService = new TransformingHttpCommandExecutorServiceImpl(httpService, execService); Executors.newCachedThreadPool()));
executorService = new TransformingHttpCommandExecutorServiceImpl(httpService, execService,
new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
@Test @Test

View File

@ -0,0 +1,181 @@
/**
*
* 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.http.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.HttpUtils.MD5InputStreamResult;
import org.jclouds.logging.Logger;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "core.WireLiveTest")
public class WireLiveTest {
private static final String sysHttpStreamUrl = System.getProperty("jclouds.wire.httpstream.url");
private static final String sysHttpStreamMd5 = System.getProperty("jclouds.wire.httpstream.md5");
private static class ConnectionTester implements Callable<Void> {
private final InputStream fromServer;
private ConnectionTester(InputStream fromServer) {
this.fromServer = fromServer;
}
public Void call() throws Exception {
Wire wire = setUp();
InputStream in = wire.input(fromServer);
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
MD5InputStreamResult compare = HttpUtils.generateMD5Result(new ByteArrayInputStream(out
.toByteArray()));
Thread.sleep(100);
assertEquals(HttpUtils.toHexString(compare.eTag), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.wireLog).buff.toString().getBytes().length, 3331484);
return null;
}
}
static class BufferLogger implements Logger {
StringBuffer buff = new StringBuffer();
public void debug(String message, Object... args) {
buff.append(message);
}
public void error(String message, Object... args) {
}
public void error(Throwable throwable, String message, Object... args) {
}
public String getCategory() {
return null;
}
public void info(String message, Object... args) {
}
public boolean isDebugEnabled() {
return true;
}
public boolean isErrorEnabled() {
return false;
}
public boolean isInfoEnabled() {
return false;
}
public boolean isTraceEnabled() {
return false;
}
public boolean isWarnEnabled() {
return false;
}
public void trace(String message, Object... args) {
}
public void warn(String message, Object... args) {
}
public void warn(Throwable throwable, String message, Object... args) {
}
}
public static Wire setUp() throws Exception {
ExecutorService service = Executors.newCachedThreadPool();
BufferLogger bufferLogger = new BufferLogger();
Wire wire = new Wire(service);
wire.wireLog = bufferLogger;
return wire;
}
public Wire setUpSynch() throws Exception {
ExecutorService service = new WithinThreadExecutorService();
BufferLogger bufferLogger = new BufferLogger();
Wire wire = new Wire(service);
wire.wireLog = bufferLogger;
return wire;
}
@Test(groups = "live")
public void testRemoteInputInputStream() throws Exception {
URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl"));
URLConnection connection = url.openConnection();
Wire wire = setUp();
InputStream in = wire.input(connection.getInputStream());
MD5InputStreamResult compare = HttpUtils.generateMD5Result(in);
Thread.sleep(100);
assertEquals(HttpUtils.toHexString(compare.eTag), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.wireLog).buff.toString().getBytes().length, 3331484);
}
@Test(groups = "live")
public void testCopyRemoteInputInputStream() throws Exception {
URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl"));
URLConnection connection = url.openConnection();
Callable<Void> callable = new ConnectionTester(connection.getInputStream());
Future<Void> result = Executors.newCachedThreadPool().submit(callable);
result.get(30, TimeUnit.SECONDS);
}
@Test(groups = "live")
public void testRemoteInputInputStreamSynch() throws Exception {
URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl"));
URLConnection connection = url.openConnection();
Wire wire = setUpSynch();
InputStream in = wire.input(connection.getInputStream());
MD5InputStreamResult compare = HttpUtils.generateMD5Result(in);
Thread.sleep(100);
assertEquals(HttpUtils.toHexString(compare.eTag), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.wireLog).buff.toString().getBytes().length, 3331484);
}
}

View File

@ -0,0 +1,149 @@
/**
*
* 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.http.internal;
import static org.testng.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.logging.Logger;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "core.WireTest")
public class WireTest {
class BufferLogger implements Logger {
StringBuffer buff = new StringBuffer();
public void debug(String message, Object... args) {
buff.append(message);
}
public void error(String message, Object... args) {
}
public void error(Throwable throwable, String message, Object... args) {
}
public String getCategory() {
return null;
}
public void info(String message, Object... args) {
}
public boolean isDebugEnabled() {
return true;
}
public boolean isErrorEnabled() {
return false;
}
public boolean isInfoEnabled() {
return false;
}
public boolean isTraceEnabled() {
return false;
}
public boolean isWarnEnabled() {
return false;
}
public void trace(String message, Object... args) {
}
public void warn(String message, Object... args) {
}
public void warn(Throwable throwable, String message, Object... args) {
}
}
public Wire setUp() throws Exception {
ExecutorService service = Executors.newCachedThreadPool();
BufferLogger bufferLogger = new BufferLogger();
Wire wire = new Wire(service);
wire.wireLog = bufferLogger;
return wire;
}
public Wire setUpSynch() throws Exception {
ExecutorService service = new WithinThreadExecutorService();
BufferLogger bufferLogger = new BufferLogger();
Wire wire = new Wire(service);
wire.wireLog = bufferLogger;
return wire;
}
public void testInputInputStream() throws Exception {
Wire wire = setUp();
InputStream in = wire.input(new ByteArrayInputStream("foo".getBytes()));
String compare = Utils.toStringAndClose(in);
Thread.sleep(100);
assertEquals(compare, "foo");
assertEquals(((BufferLogger) wire.wireLog).buff.toString(), "<< \"foo\"");
}
public void testInputInputStreamSynch() throws Exception {
Wire wire = setUpSynch();
InputStream in = wire.input(new ByteArrayInputStream("foo".getBytes()));
String compare = Utils.toStringAndClose(in);
assertEquals(compare, "foo");
assertEquals(((BufferLogger) wire.wireLog).buff.toString(), "<< \"foo\"");
}
public void testOutputInputStream() throws Exception {
Wire wire = setUp();
InputStream in = wire.output(new ByteArrayInputStream("foo".getBytes()));
String compare = Utils.toStringAndClose(in);
Thread.sleep(100);
assertEquals(compare, "foo");
assertEquals(((BufferLogger) wire.wireLog).buff.toString(), ">> \"foo\"");
}
public void testOutputBytes() throws Exception {
Wire wire = setUp();
wire.output("foo".getBytes());
assertEquals(((BufferLogger) wire.wireLog).buff.toString(), ">> \"foo\"");
}
public void testOutputString() throws Exception {
Wire wire = setUp();
wire.output("foo");
assertEquals(((BufferLogger) wire.wireLog).buff.toString(), ">> \"foo\"");
}
}

View File

@ -31,6 +31,8 @@ import java.lang.reflect.Field;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.AssignLoggerToField; import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.AssignLoggerToField;
@ -41,7 +43,6 @@ import org.testng.annotations.Test;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import javax.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
@Test @Test
@ -57,12 +58,15 @@ public class BindLoggersAnnotatedWithResourceTest {
private static class B { private static class B {
@Resource @Resource
private Logger logger = Logger.NULL; private Logger logger = Logger.NULL;
@Resource
@Named("blogger")
private Logger blogger = Logger.NULL;
} }
@BeforeMethod @BeforeMethod
void createBlawr() { void createBlawr() {
blawr = new BindLoggersAnnotatedWithResource( blawr = new BindLoggersAnnotatedWithResource(new JDKLogger.JDKLoggerFactory());
new JDKLogger.JDKLoggerFactory());
} }
@Test @Test
@ -75,31 +79,25 @@ public class BindLoggersAnnotatedWithResourceTest {
} }
}); });
assertEquals(i.getInstance(A.class).logger.getCategory(), getClass() assertEquals(i.getInstance(A.class).logger.getCategory(), getClass().getName() + "$A");
.getName() assertEquals(i.getInstance(B.class).logger.getCategory(), getClass().getName() + "$B");
+ "$A"); assertEquals(i.getInstance(B.class).blogger.getCategory(), "blogger");
assertEquals(i.getInstance(B.class).logger.getCategory(), getClass()
.getName()
+ "$B");
} }
@Test @Test
public void testAssignLoggerToField() throws SecurityException, public void testAssignLoggerToField() throws SecurityException, NoSuchFieldException,
NoSuchFieldException, IllegalArgumentException, IllegalArgumentException, IllegalAccessException {
IllegalAccessException {
Logger logger = createMock(Logger.class); Logger logger = createMock(Logger.class);
A a = new A(); A a = new A();
Field field = A.class.getDeclaredField("logger"); Field field = A.class.getDeclaredField("logger");
AssignLoggerToField<A> assigner = new AssignLoggerToField<A>(logger, AssignLoggerToField<A> assigner = new AssignLoggerToField<A>(logger, field);
field);
assigner.afterInjection(a); assigner.afterInjection(a);
assert field.get(a).equals(logger); assert field.get(a).equals(logger);
} }
@Test @Test
public void testLoggerFieldsAnnotatedWithResource() public void testLoggerFieldsAnnotatedWithResource() throws SecurityException,
throws SecurityException, NoSuchFieldException { NoSuchFieldException {
LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource(); LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource();
assert predicate.apply(A.class.getDeclaredField("logger")); assert predicate.apply(A.class.getDeclaredField("logger"));
} }
@ -111,10 +109,10 @@ public class BindLoggersAnnotatedWithResourceTest {
} }
@Test @Test
public void testLoggerFieldsAnnotatedWithInjectReturnsNull() public void testLoggerFieldsAnnotatedWithInjectReturnsNull() throws SecurityException,
throws SecurityException, NoSuchFieldException { NoSuchFieldException {
LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource(); LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource();
assert ! predicate.apply(C.class.getDeclaredField("logger")); assert !predicate.apply(C.class.getDeclaredField("logger"));
} }
public static class D { public static class D {
@ -130,8 +128,7 @@ public class BindLoggersAnnotatedWithResourceTest {
@Test @Test
public void testGetLoggerFieldsAnnotatedWithResourceNoLogger() { public void testGetLoggerFieldsAnnotatedWithResourceNoLogger() {
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(this Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(this.getClass());
.getClass());
assertEquals(fields.size(), 0); assertEquals(fields.size(), 0);
} }

View File

@ -70,7 +70,8 @@ import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.http.options.HttpRequestOptions;
import org.jclouds.rest.InvocationContext; import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.annotations.DecoratorParam; import org.jclouds.rest.annotations.DecoratorParam;
import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.Headers;
@ -472,7 +473,6 @@ public class RestAnnotationProcessorTest {
assertEquals(httpMethod.getEntity(), expected); assertEquals(httpMethod.getEntity(), expected);
} }
static class TestRequestFilter1 implements HttpRequestFilter { static class TestRequestFilter1 implements HttpRequestFilter {
public HttpRequest filter(HttpRequest request) throws HttpException { public HttpRequest filter(HttpRequest request) throws HttpException {
return null; return null;
@ -963,7 +963,8 @@ public class RestAnnotationProcessorTest {
assertEquals(transformer, ParseURIList.class); assertEquals(transformer, ParseURIList.class);
} }
public static class ReturnStringIf200Context extends ReturnStringIf200 implements InvocationContext { public static class ReturnStringIf200Context extends ReturnStringIf200 implements
InvocationContext {
private Object[] args; private Object[] args;
private HttpRequest request; private HttpRequest request;
@ -1452,6 +1453,11 @@ public class RestAnnotationProcessorTest {
URI.create("http://localhost:8080")); URI.create("http://localhost:8080"));
bind(URI.class).annotatedWith(Localhost2.class).toInstance( bind(URI.class).annotatedWith(Localhost2.class).toInstance(
URI.create("http://localhost:8081")); URI.create("http://localhost:8081"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());

View File

@ -31,7 +31,6 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -47,6 +46,7 @@ import org.jclouds.http.HttpResponse;
import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.internal.BaseHttpCommandExecutorService; import org.jclouds.http.internal.BaseHttpCommandExecutorService;
import org.jclouds.http.internal.Wire;
import com.google.appengine.api.urlfetch.FetchOptions; import com.google.appengine.api.urlfetch.FetchOptions;
import com.google.appengine.api.urlfetch.HTTPHeader; import com.google.appengine.api.urlfetch.HTTPHeader;
@ -68,8 +68,8 @@ public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorServic
@Inject @Inject
public GaeHttpCommandExecutorService(URLFetchService urlFetchService, public GaeHttpCommandExecutorService(URLFetchService urlFetchService,
ExecutorService executorService, DelegatingRetryHandler retryHandler, ExecutorService executorService, DelegatingRetryHandler retryHandler,
DelegatingErrorHandler errorHandler) { DelegatingErrorHandler errorHandler, Wire wire) {
super(executorService, retryHandler, errorHandler); super(executorService, retryHandler, errorHandler, wire);
this.urlFetchService = urlFetchService; this.urlFetchService = urlFetchService;
} }
@ -169,20 +169,6 @@ public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorServic
@Override @Override
protected HttpResponse invoke(HTTPRequest request) throws IOException { protected HttpResponse invoke(HTTPRequest request) throws IOException {
logger.trace("%s - submitting request %s, headers: %s", request.getURL().getHost(), request return convert(urlFetchService.fetch(request));
.getURL(), headersAsString(request.getHeaders()));
HTTPResponse response = urlFetchService.fetch(request);
logger.trace("%s - received response code %s, headers: %s", request.getURL().getHost(),
response.getResponseCode(), headersAsString(response.getHeaders()));
return convert(response);
} }
String headersAsString(List<HTTPHeader> headers) {
StringBuilder builder = new StringBuilder("");
for (HTTPHeader header : headers)
builder.append("[").append(header.getName()).append("=").append(header.getValue()).append(
"],");
return builder.toString();
}
} }

View File

@ -47,6 +47,7 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.internal.Wire;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters; import org.testng.annotations.Parameters;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -70,7 +71,7 @@ public class GaeHttpCommandExecutorServiceTest {
endPoint = URI.create("http://localhost:80/foo"); endPoint = URI.create("http://localhost:80/foo");
client = new GaeHttpCommandExecutorService(createNiceMock(URLFetchService.class), client = new GaeHttpCommandExecutorService(createNiceMock(URLFetchService.class),
createNiceMock(ExecutorService.class), createNiceMock(DelegatingRetryHandler.class), createNiceMock(ExecutorService.class), createNiceMock(DelegatingRetryHandler.class),
createNiceMock(DelegatingErrorHandler.class)); createNiceMock(DelegatingErrorHandler.class), createNiceMock(Wire.class));
} }
@Test @Test

View File

@ -32,6 +32,8 @@ import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.gae.GaeHttpCommandExecutorService; import org.jclouds.gae.GaeHttpCommandExecutorService;
import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -55,6 +57,11 @@ public class GaeHttpCommandExecutorServiceModuleTest {
@Override @Override
protected void configure() { protected void configure() {
Jsr330.bindProperties(binder(), properties); Jsr330.bindProperties(binder(), properties);
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
super.configure(); super.configure();
} }
}); });

View File

@ -31,6 +31,7 @@ import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.nio.charset.UnmappableCharacterException; import java.nio.charset.UnmappableCharacterException;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -53,7 +54,6 @@ import org.apache.http.nio.reactor.SessionRequestCallback;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
import org.jclouds.http.HttpCommandRendezvous; import org.jclouds.http.HttpCommandRendezvous;
import org.jclouds.http.TransformingHttpCommand; import org.jclouds.http.TransformingHttpCommand;
import org.jclouds.http.TransformingHttpCommandExecutorService;
import org.jclouds.http.pool.HttpCommandConnectionHandle; import org.jclouds.http.pool.HttpCommandConnectionHandle;
import org.jclouds.http.pool.HttpCommandConnectionPool; import org.jclouds.http.pool.HttpCommandConnectionPool;
@ -68,6 +68,12 @@ import com.google.inject.assistedinject.Assisted;
public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHttpConnection> public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHttpConnection>
implements EventListener { implements EventListener {
@Override
public String toString() {
return "NioHttpCommandConnectionPool [ target=" + target + ", endPoint=" + getEndPoint()
+ ", hashCode=" + hashCode() + " ]";
}
private final NHttpClientConnectionPoolSessionRequestCallback sessionCallback; private final NHttpClientConnectionPoolSessionRequestCallback sessionCallback;
private final DefaultConnectingIOReactor ioReactor; private final DefaultConnectingIOReactor ioReactor;
private final IOEventDispatch dispatch; private final IOEventDispatch dispatch;
@ -152,9 +158,6 @@ public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHtt
@Override @Override
public void shutdownConnection(NHttpConnection conn) { public void shutdownConnection(NHttpConnection conn) {
if (conn.getMetrics().getRequestCount() >= maxConnectionReuse)
logger.debug("%1$s - %2$d - closing connection due to overuse %1$s/%2$s", conn, conn
.hashCode(), conn.getMetrics().getRequestCount(), maxConnectionReuse);
if (conn.getStatus() == NHttpConnection.ACTIVE) { if (conn.getStatus() == NHttpConnection.ACTIVE) {
try { try {
conn.shutdown(); conn.shutdown();
@ -182,7 +185,7 @@ public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHtt
boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS); boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS);
if (acquired) { if (acquired) {
if (shouldDoWork()) { if (shouldDoWork()) {
logger.debug("%1$s - opening new connection", getTarget()); logger.trace("Opening: %s", getTarget());
ioReactor.connect(getTarget(), null, null, sessionCallback); ioReactor.connect(getTarget(), null, null, sessionCallback);
} else { } else {
allConnections.release(); allConnections.release();
@ -205,56 +208,37 @@ public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHtt
class NHttpClientConnectionPoolSessionRequestCallback implements SessionRequestCallback { class NHttpClientConnectionPoolSessionRequestCallback implements SessionRequestCallback {
public void completed(SessionRequest request) { public void completed(SessionRequest request) {
logger.trace("%1$s->%2$s[%3$s] - SessionRequest complete", request.getLocalAddress(),
request.getRemoteAddress(), request.getAttachment());
} }
public void cancelled(SessionRequest request) { public void cancelled(SessionRequest request) {
logger.trace("%1$s->%2$s[%3$s] - SessionRequest cancelled", request.getLocalAddress(), releaseConnectionAndSetResponseException(request, new CancellationException(
request.getRemoteAddress(), request.getAttachment()); "Cancelled request: " + request.getRemoteAddress()));
releaseConnectionAndCancelResponse(request);
}
private void releaseConnectionAndCancelResponse(SessionRequest request) {
allConnections.release();
TransformingHttpCommandExecutorService frequest = (TransformingHttpCommandExecutorService) request
.getAttachment();
if (frequest != null) {
logger.error("%1$s->%2$s[%3$s] - Cancelling FutureCommand", request.getLocalAddress(),
request.getRemoteAddress(), frequest);
// TODO frequest.cancel(true);
}
} }
private void releaseConnectionAndSetResponseException(SessionRequest request, Exception e) { private void releaseConnectionAndSetResponseException(SessionRequest request, Exception e) {
allConnections.release(); allConnections.release();
TransformingHttpCommand<?> frequest = (TransformingHttpCommand<?>) request.getAttachment(); TransformingHttpCommand<?> frequest = (TransformingHttpCommand<?>) request.getAttachment();
if (frequest != null) { if (frequest != null) {
logger.error(e, "%1$s->%2$s[%3$s] - Setting Exception on FutureCommand", request
.getLocalAddress(), request.getRemoteAddress(), frequest);
frequest.setException(e); frequest.setException(e);
} }
} }
public void failed(SessionRequest request) { public void failed(SessionRequest request) {
int count = currentSessionFailures.getAndIncrement(); int count = currentSessionFailures.getAndIncrement();
logger.warn("%1$s->%2$s[%3$s] - SessionRequest failed", request.getLocalAddress(), request
.getRemoteAddress(), request.getAttachment());
releaseConnectionAndSetResponseException(request, request.getException()); releaseConnectionAndSetResponseException(request, request.getException());
if (count >= maxSessionFailures) { if (count >= maxSessionFailures) {
logger.error(request.getException(), logger.error(request.getException(),
"%1$s->%2$s[%3$s] - SessionRequest failures: %4$s, Disabling pool for %5$s", "Exceeded maximum Session failures: %d, Disabling pool for %s",
request.getLocalAddress(), request.getRemoteAddress(), maxSessionFailures, maxSessionFailures, getTarget());
getTarget());
exception.set(request.getException()); exception.set(request.getException());
} }
} }
public void timeout(SessionRequest request) { public void timeout(SessionRequest request) {
logger.warn("%1$s->%2$s[%3$s] - SessionRequest timeout", request.getLocalAddress(), releaseConnectionAndSetResponseException(request, new TimeoutException("Timeout on: "
request.getRemoteAddress(), request.getAttachment()); + request.getRemoteAddress()));
releaseConnectionAndCancelResponse(request);
} }
} }
@ -262,22 +246,22 @@ public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHtt
public void connectionOpen(NHttpConnection conn) { public void connectionOpen(NHttpConnection conn) {
conn.setSocketTimeout(0); conn.setSocketTimeout(0);
available.offer(conn); available.offer(conn);
logger.trace("%1$s - %2$d - open", conn, conn.hashCode()); logger.info("Opened: %s", getTarget());
} }
public void connectionTimeout(NHttpConnection conn) { public void connectionTimeout(NHttpConnection conn) {
String message = String.format("%1$s - %2$d - timeout %2$d", conn, conn.hashCode(), conn String message = String.format("Timeout on : %s - timeout %d", getTarget(), conn
.getSocketTimeout()); .getSocketTimeout());
logger.warn(message); logger.warn(message);
resubmitIfRequestIsReplayable(conn, new TimeoutException(message)); resubmitIfRequestIsReplayable(conn, new TimeoutException(message));
} }
public void connectionClosed(NHttpConnection conn) { public void connectionClosed(NHttpConnection conn) {
logger.trace("%1$s - %2$d - closed", conn, conn.hashCode()); logger.info("Closed: %s", getTarget());
} }
public void fatalIOException(IOException ex, NHttpConnection conn) { public void fatalIOException(IOException ex, NHttpConnection conn) {
logger.error(ex, "%3$s-%1$s{%2$d} - io error", conn, conn.hashCode(), getTarget()); logger.error(ex, "IO Exception: %s", getTarget());
HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(conn); HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(conn);
if (rendezvous != null) { if (rendezvous != null) {
/** /**
@ -293,7 +277,7 @@ public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHtt
} }
public void fatalProtocolException(HttpException ex, NHttpConnection conn) { public void fatalProtocolException(HttpException ex, NHttpConnection conn) {
logger.error(ex, "%3$s-%1$s{%2$d} - http error", conn, conn.hashCode(), getTarget()); logger.error(ex, "Protocol Exception: %s", getTarget());
setExceptionOnCommand(conn, ex); setExceptionOnCommand(conn, ex);
} }

View File

@ -24,10 +24,12 @@
package org.jclouds.http.httpnio.pool; package org.jclouds.http.httpnio.pool;
import java.io.IOException; import java.io.IOException;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpEntityEnclosingRequest;
@ -37,11 +39,13 @@ import org.apache.http.nio.protocol.NHttpRequestExecutionHandler;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpCommandRendezvous; import org.jclouds.http.HttpCommandRendezvous;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.httpnio.util.NioHttpUtils; import org.jclouds.http.httpnio.util.NioHttpUtils;
import org.jclouds.http.internal.Wire;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
/** /**
@ -53,6 +57,7 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
private final ConsumingNHttpEntityFactory entityFactory; private final ConsumingNHttpEntityFactory entityFactory;
private final DelegatingRetryHandler retryHandler; private final DelegatingRetryHandler retryHandler;
private final DelegatingErrorHandler errorHandler; private final DelegatingErrorHandler errorHandler;
private final Wire wire;
/** /**
* inputOnly: nothing is taken from this queue. * inputOnly: nothing is taken from this queue.
@ -61,15 +66,19 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@Resource
@Named(HttpConstants.HTTP_HEADERS_LOGGER)
protected Logger headerLog = Logger.NULL;
@Inject @Inject
public NioHttpCommandExecutionHandler(ConsumingNHttpEntityFactory entityFactory, public NioHttpCommandExecutionHandler(ConsumingNHttpEntityFactory entityFactory,
BlockingQueue<HttpCommandRendezvous<?>> resubmitQueue, BlockingQueue<HttpCommandRendezvous<?>> resubmitQueue,
DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler) { DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler, Wire wire) {
this.entityFactory = entityFactory; this.entityFactory = entityFactory;
this.resubmitQueue = resubmitQueue; this.resubmitQueue = resubmitQueue;
this.retryHandler = retryHandler; this.retryHandler = retryHandler;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
this.wire = wire;
} }
public interface ConsumingNHttpEntityFactory { public interface ConsumingNHttpEntityFactory {
@ -87,10 +96,19 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
for (HttpRequestFilter filter : request.getFilters()) { for (HttpRequestFilter filter : request.getFilters()) {
request = filter.filter(request); request = filter.filter(request);
} }
return NioHttpUtils.convertToApacheRequest(request); logger.debug("Sending request: %s", request.getRequestLine());
if (request.getEntity() != null && wire.enabled())
request.setEntity(wire.output(request.getEntity()));
HttpEntityEnclosingRequest nativeRequest = NioHttpUtils.convertToApacheRequest(request);
if (headerLog.isDebugEnabled()) {
headerLog.debug(">> %s", request.getRequestLine().toString());
for (Entry<String, String> header : request.getHeaders().entries()) {
headerLog.debug(">> %s: %s", header.getKey(), header.getValue());
}
}
return nativeRequest;
} }
return null; return null;
} }
public ConsumingNHttpEntity responseEntity(HttpResponse response, HttpContext context) public ConsumingNHttpEntity responseEntity(HttpResponse response, HttpContext context)
@ -107,9 +125,16 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
HttpCommand command = rendezvous.getCommand(); HttpCommand command = rendezvous.getCommand();
org.jclouds.http.HttpResponse response = NioHttpUtils org.jclouds.http.HttpResponse response = NioHttpUtils
.convertToJavaCloudsResponse(apacheResponse); .convertToJavaCloudsResponse(apacheResponse);
logger.debug("Receiving response: %s", response.getStatusLine());
if (headerLog.isDebugEnabled()) {
headerLog.debug("<< %s", response.getStatusLine().toString());
for (Entry<String, String> header : response.getHeaders().entries()) {
headerLog.debug("<< %s: %s", header.getKey(), header.getValue());
}
}
if (response.getContent() != null && wire.enabled())
response.setContent(wire.input(response.getContent()));
int statusCode = response.getStatusCode(); int statusCode = response.getStatusCode();
// TODO determine how to get the original request here so we don't need to build each
// time
if (statusCode >= 300) { if (statusCode >= 300) {
if (retryHandler.shouldRetryRequest(command, response)) { if (retryHandler.shouldRetryRequest(command, response)) {
resubmitQueue.add(rendezvous); resubmitQueue.add(rendezvous);
@ -119,7 +144,6 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
rendezvous.setException(command.getException()); rendezvous.setException(command.getException());
} }
} else { } else {
logger.trace("submitting response task %s", command);
rendezvous.setResponse(response); rendezvous.setResponse(response);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@ -26,12 +26,13 @@ package org.jclouds.http.httpnio.pool;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.http.nio.NHttpConnection; import org.apache.http.nio.NHttpConnection;
import org.jclouds.http.HttpCommandRendezvous; import org.jclouds.http.HttpCommandRendezvous;
import org.jclouds.http.pool.ConnectionPoolTransformingHttpCommandExecutorService; import org.jclouds.http.pool.ConnectionPoolTransformingHttpCommandExecutorService;
import org.jclouds.logging.Logger.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
/** /**
* // TODO: Adrian: Document this! * // TODO: Adrian: Document this!
@ -42,11 +43,16 @@ import javax.inject.Singleton;
public class NioTransformingHttpCommandExecutorService extends public class NioTransformingHttpCommandExecutorService extends
ConnectionPoolTransformingHttpCommandExecutorService<NHttpConnection> { ConnectionPoolTransformingHttpCommandExecutorService<NHttpConnection> {
@Override
public String toString() {
return String.format("NioTransformingHttpCommandExecutorService [ hashCode=%d ]", hashCode());
}
@Inject @Inject
public NioTransformingHttpCommandExecutorService(ExecutorService executor, public NioTransformingHttpCommandExecutorService(ExecutorService executor,
NioHttpCommandConnectionPool.Factory poolFactory, NioHttpCommandConnectionPool.Factory poolFactory,
BlockingQueue<HttpCommandRendezvous<?>> commandQueue) { BlockingQueue<HttpCommandRendezvous<?>> commandQueue, LoggerFactory logFactory) {
super(executor, poolFactory, commandQueue); super(executor, poolFactory, commandQueue, logFactory);
} }
} }

View File

@ -114,6 +114,7 @@ public class NioHttpUtils {
response.getHeaders().put(header.getName(), header.getValue()); response.getHeaders().put(header.getName(), header.getValue());
} }
response.setStatusCode(apacheResponse.getStatusLine().getStatusCode()); response.setStatusCode(apacheResponse.getStatusLine().getStatusCode());
response.setMessage(apacheResponse.getStatusLine().getReasonPhrase());
return response; return response;
} }
} }

View File

@ -113,11 +113,6 @@ public class PCSContextBuilder extends
return (PCSContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (PCSContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public PCSContextBuilder withJsonDebug() {
return (PCSContextBuilder) super.withJsonDebug();
}
@Override @Override
public PCSContextBuilder withModule(Module module) { public PCSContextBuilder withModule(Module module) {
return (PCSContextBuilder) super.withModule(module); return (PCSContextBuilder) super.withModule(module);
@ -157,9 +152,4 @@ public class PCSContextBuilder extends
public PCSContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) { public PCSContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
return (PCSContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads); return (PCSContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public PCSContextBuilder withSaxDebug() {
return (PCSContextBuilder) super.withSaxDebug();
}
} }

View File

@ -54,6 +54,8 @@ import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata;
import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.mezeo.pcs2.domain.PCSFile;
@ -434,6 +436,11 @@ public class PCSBlobStoreTest {
bind(URI.class).annotatedWith(WebDAV.class).toInstance( bind(URI.class).annotatedWith(WebDAV.class).toInstance(
URI.create("http://localhost:8080/webdav")); URI.create("http://localhost:8080/webdav"));
bind(PCSConnection.class).to(StubPCSConnection.class).asEagerSingleton(); bind(PCSConnection.class).to(StubPCSConnection.class).asEagerSingleton();
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -50,6 +50,8 @@ import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseURIList; import org.jclouds.http.functions.ParseURIList;
import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnInputStream;
import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata;
import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.mezeo.pcs2.domain.PCSFile;
import org.jclouds.mezeo.pcs2.endpoints.RootContainer; import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
@ -225,6 +227,11 @@ public class PCSConnectionTest {
URI.create("http://localhost:8080")); URI.create("http://localhost:8080"));
bind(URI.class).annotatedWith(RootContainer.class).toInstance( bind(URI.class).annotatedWith(RootContainer.class).toInstance(
URI.create("http://localhost:8080/root")); URI.create("http://localhost:8080/root"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -26,6 +26,8 @@ package org.jclouds.mezeo.pcs2;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.jclouds.blobstore.BlobStoreMapsModule; import org.jclouds.blobstore.BlobStoreMapsModule;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.mezeo.pcs2.config.PCSContextModule; import org.jclouds.mezeo.pcs2.config.PCSContextModule;
import org.jclouds.mezeo.pcs2.config.StubPCSBlobStoreModule; import org.jclouds.mezeo.pcs2.config.StubPCSBlobStoreModule;
import org.jclouds.mezeo.pcs2.config.PCSContextModule.PCSContextImpl; import org.jclouds.mezeo.pcs2.config.PCSContextModule.PCSContextImpl;
@ -58,6 +60,11 @@ public class PCSContextModuleTest {
"key"); "key");
bindConstant().annotatedWith(Jsr330.named(PCSConstants.PROPERTY_PCS2_ENDPOINT)).to( bindConstant().annotatedWith(Jsr330.named(PCSConstants.PROPERTY_PCS2_ENDPOINT)).to(
"http://localhost"); "http://localhost");
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
super.configure(); super.configure();
} }
}); });

View File

@ -34,6 +34,8 @@ import org.jclouds.http.handlers.CloseContentAndSetExceptionErrorHandler;
import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.handlers.RedirectionRetryHandler; import org.jclouds.http.handlers.RedirectionRetryHandler;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata;
import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.mezeo.pcs2.domain.PCSFile;
@ -65,6 +67,11 @@ public class PCSContextModuleTest {
"key"); "key");
bindConstant().annotatedWith(Jsr330.named(PCSConstants.PROPERTY_PCS2_ENDPOINT)).to( bindConstant().annotatedWith(Jsr330.named(PCSConstants.PROPERTY_PCS2_ENDPOINT)).to(
"http://localhost"); "http://localhost");
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
super.configure(); super.configure();
} }
}, new ParserModule(), new JavaUrlHttpCommandExecutorServiceModule(), }, new ParserModule(), new JavaUrlHttpCommandExecutorServiceModule(),

View File

@ -49,8 +49,8 @@ public class PCSTestInitializer extends
protected PCSContext createLiveContext(Module configurationModule, String url, String app, protected PCSContext createLiveContext(Module configurationModule, String url, String app,
String account, String key) { String account, String key) {
return new PCSContextBuilder(URI.create(url), account, key).withRequestTimeout(60000) return new PCSContextBuilder(URI.create(url), account, key).withRequestTimeout(60000)
.relaxSSLHostname().withSaxDebug().withModules(configurationModule, .relaxSSLHostname().withModules(configurationModule, new Log4JLoggingModule())
new Log4JLoggingModule()).buildContext(); .buildContext();
} }
@Override @Override

View File

@ -33,6 +33,28 @@
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" /> <param name="File" value="target/test-data/jclouds.log" />
@ -59,12 +81,27 @@
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
<category name="org.jclouds"> <category name="org.jclouds">
<priority value="TRACE" /> <priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.http.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category> </category>
<!-- ======================= --> <!-- ======================= -->
@ -73,7 +110,6 @@
<root> <root>
<priority value="WARN" /> <priority value="WARN" />
<appender-ref ref="ASYNC" />
</root> </root>
</log4j:configuration> </log4j:configuration>

View File

@ -106,11 +106,6 @@ public class SDNContextBuilder extends CloudContextBuilder<SDNConnection> {
return (SDNContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (SDNContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public SDNContextBuilder withJsonDebug() {
return (SDNContextBuilder) super.withJsonDebug();
}
@Override @Override
public SDNContextBuilder withModule(Module module) { public SDNContextBuilder withModule(Module module) {
return (SDNContextBuilder) super.withModule(module); return (SDNContextBuilder) super.withModule(module);
@ -146,11 +141,6 @@ public class SDNContextBuilder extends CloudContextBuilder<SDNConnection> {
return (SDNContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads); return (SDNContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public SDNContextBuilder withSaxDebug() {
return (SDNContextBuilder) super.withSaxDebug();
}
@Override @Override
public SDNContextBuilder withEndpoint(URI endpoint) { public SDNContextBuilder withEndpoint(URI endpoint) {
return (SDNContextBuilder) (SDNContextBuilder) withEndpoint(this, endpoint); return (SDNContextBuilder) (SDNContextBuilder) withEndpoint(this, endpoint);

View File

@ -24,7 +24,6 @@
package org.jclouds.nirvanix.sdn; package org.jclouds.nirvanix.sdn;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.HttpConstants.PROPERTY_JSON_DEBUG;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.net.URI; import java.net.URI;
@ -37,7 +36,6 @@ import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestClientFactory; import org.jclouds.rest.RestClientFactory;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.util.Jsr330;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -73,7 +71,6 @@ public class SDNAuthenticationLiveTest {
protected void configure() { protected void configure() {
bind(URI.class).annotatedWith(SDN.class).toInstance( bind(URI.class).annotatedWith(SDN.class).toInstance(
URI.create("http://services.nirvanix.com/ws")); URI.create("http://services.nirvanix.com/ws"));
bindConstant().annotatedWith(Jsr330.named(PROPERTY_JSON_DEBUG)).to(true);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -34,6 +34,8 @@ import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.nirvanix.sdn.functions.ParseSessionTokenFromJsonResponse; import org.jclouds.nirvanix.sdn.functions.ParseSessionTokenFromJsonResponse;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
@ -78,6 +80,11 @@ public class SDNAuthenticationTest {
protected void configure() { protected void configure() {
bind(URI.class).annotatedWith(SDN.class) bind(URI.class).annotatedWith(SDN.class)
.toInstance(URI.create("http://localhost:8080")); .toInstance(URI.create("http://localhost:8080"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());

View File

@ -16,9 +16,6 @@ import org.jclouds.nirvanix.sdn.domain.UploadInfo;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
/** /**
* Tests behavior of {@code SDNConnection} * Tests behavior of {@code SDNConnection}
* *
@ -40,7 +37,7 @@ public class SDNConnectionLiveTest {
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
connection = new SDNContextBuilder(app, user, password).withModules(new Log4JLoggingModule()) connection = new SDNContextBuilder(app, user, password).withModules(new Log4JLoggingModule())
.withJsonDebug().buildContext().getApi(); .buildContext().getApi();
} }
public void testUploadToken() throws InterruptedException, ExecutionException, TimeoutException { public void testUploadToken() throws InterruptedException, ExecutionException, TimeoutException {
@ -54,6 +51,7 @@ public class SDNConnectionLiveTest {
new Blob<BlobMetadata>("key", "value")).get(30, TimeUnit.SECONDS); new Blob<BlobMetadata>("key", "value")).get(30, TimeUnit.SECONDS);
// Multimap<String, String> metadata = ImmutableMultimap.of("chef", "sushi"); // Multimap<String, String> metadata = ImmutableMultimap.of("chef", "sushi");
// who knows... 403 error; connection.setMetadata("container", "key", metadata).get(30, TimeUnit.SECONDS); // who knows... 403 error; connection.setMetadata("container", "key", metadata).get(30,
// TimeUnit.SECONDS);
} }
} }

View File

@ -42,6 +42,8 @@ import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.nirvanix.sdn.functions.ParseUploadInfoFromJsonResponse; import org.jclouds.nirvanix.sdn.functions.ParseUploadInfoFromJsonResponse;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
@ -130,6 +132,11 @@ public class SDNConnectionTest {
protected void configure() { protected void configure() {
bind(URI.class).annotatedWith(SDN.class) bind(URI.class).annotatedWith(SDN.class)
.toInstance(URI.create("http://localhost:8080")); .toInstance(URI.create("http://localhost:8080"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -33,6 +33,28 @@
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" /> <param name="File" value="target/test-data/jclouds.log" />
@ -59,12 +81,27 @@
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
<category name="org.jclouds"> <category name="org.jclouds">
<priority value="TRACE" /> <priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.http.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category> </category>
<!-- ======================= --> <!-- ======================= -->
@ -73,7 +110,6 @@
<root> <root>
<priority value="WARN" /> <priority value="WARN" />
<appender-ref ref="ASYNC" />
</root> </root>
</log4j:configuration> </log4j:configuration>

View File

@ -146,6 +146,8 @@
<maven.compile.deprecation>true</maven.compile.deprecation> <maven.compile.deprecation>true</maven.compile.deprecation>
<jclouds.blobstore.httpstream.url>http://mirror.cloudera.com/apache/maven/binaries/apache-maven-2.2.1-bin.tar.bz2</jclouds.blobstore.httpstream.url> <jclouds.blobstore.httpstream.url>http://mirror.cloudera.com/apache/maven/binaries/apache-maven-2.2.1-bin.tar.bz2</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>c581a15cb0001d9b771ad6df7c8156f8</jclouds.blobstore.httpstream.md5> <jclouds.blobstore.httpstream.md5>c581a15cb0001d9b771ad6df7c8156f8</jclouds.blobstore.httpstream.md5>
<jclouds.wire.httpstream.url>http://apache.opensourceresources.org/commons/logging/binaries/commons-logging-1.1.1-bin.tar.gz</jclouds.wire.httpstream.url>
<jclouds.wire.httpstream.md5>e5de09672af9b386c30a311654d8541a</jclouds.wire.httpstream.md5>
<jclouds.test.listener>org.jclouds.test.testng.UnitTestStatusListener</jclouds.test.listener> <jclouds.test.listener>org.jclouds.test.testng.UnitTestStatusListener</jclouds.test.listener>
</properties> </properties>
@ -217,6 +219,14 @@
<name>jclouds.test.initializer</name> <name>jclouds.test.initializer</name>
<value>${jclouds.test.initializer}</value> <value>${jclouds.test.initializer}</value>
</property> </property>
<property>
<name>jclouds.wire.httpstream.url</name>
<value>${jclouds.wire.httpstream.url}</value>
</property>
<property>
<name>jclouds.wire.httpstream.md5</name>
<value>${jclouds.wire.httpstream.md5}</value>
</property>
<property> <property>
<name>jclouds.blobstore.httpstream.url</name> <name>jclouds.blobstore.httpstream.url</name>
<value>${jclouds.blobstore.httpstream.url}</value> <value>${jclouds.blobstore.httpstream.url}</value>
@ -422,6 +432,14 @@ pageTracker._trackPageview();
<name>jclouds.blobstore.httpstream.md5</name> <name>jclouds.blobstore.httpstream.md5</name>
<value>${jclouds.blobstore.httpstream.md5}</value> <value>${jclouds.blobstore.httpstream.md5}</value>
</property> </property>
<property>
<name>jclouds.wire.httpstream.url</name>
<value>${jclouds.wire.httpstream.url}</value>
</property>
<property>
<name>jclouds.wire.httpstream.md5</name>
<value>${jclouds.wire.httpstream.md5}</value>
</property>
</systemProperties> </systemProperties>
</configuration> </configuration>
</execution> </execution>

View File

@ -91,11 +91,6 @@ public class CloudFilesContextBuilder
return (CloudFilesContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (CloudFilesContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public CloudFilesContextBuilder withJsonDebug() {
return (CloudFilesContextBuilder) super.withJsonDebug();
}
@Override @Override
public CloudFilesContextBuilder withModule(Module module) { public CloudFilesContextBuilder withModule(Module module) {
return (CloudFilesContextBuilder) super.withModule(module); return (CloudFilesContextBuilder) super.withModule(module);
@ -132,11 +127,6 @@ public class CloudFilesContextBuilder
.withPoolRequestInvokerThreads(poolRequestInvokerThreads); .withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public CloudFilesContextBuilder withSaxDebug() {
return (CloudFilesContextBuilder) super.withSaxDebug();
}
public CloudFilesContextBuilder(Properties props) { public CloudFilesContextBuilder(Properties props) {
super(new TypeLiteral<CloudFilesConnection>() { super(new TypeLiteral<CloudFilesConnection>() {
}, new TypeLiteral<ContainerMetadata>() { }, new TypeLiteral<ContainerMetadata>() {
@ -165,8 +155,7 @@ public class CloudFilesContextBuilder
@Override @Override
public CloudFilesContextBuilder withEndpoint(URI endpoint) { public CloudFilesContextBuilder withEndpoint(URI endpoint) {
return (CloudFilesContextBuilder) RackspaceContextBuilder return (CloudFilesContextBuilder) RackspaceContextBuilder.withEndpoint(this, endpoint);
.withEndpoint(this, endpoint);
} }
} }

View File

@ -107,11 +107,6 @@ public class CloudServersContextBuilder extends RackspaceContextBuilder<CloudSer
return (CloudServersContextBuilder) super.withHttpMaxRetries(httpMaxRetries); return (CloudServersContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
} }
@Override
public CloudServersContextBuilder withJsonDebug() {
return (CloudServersContextBuilder) super.withJsonDebug();
}
@Override @Override
public CloudServersContextBuilder withModule(Module module) { public CloudServersContextBuilder withModule(Module module) {
return (CloudServersContextBuilder) super.withModule(module); return (CloudServersContextBuilder) super.withModule(module);
@ -148,8 +143,4 @@ public class CloudServersContextBuilder extends RackspaceContextBuilder<CloudSer
.withPoolRequestInvokerThreads(poolRequestInvokerThreads); .withPoolRequestInvokerThreads(poolRequestInvokerThreads);
} }
@Override
public CloudServersContextBuilder withSaxDebug() {
return (CloudServersContextBuilder) (CloudServersContextBuilder) super.withSaxDebug();
}
} }

View File

@ -83,7 +83,7 @@ public class CloudServersConnectionLiveTest {
String key = System.getProperty("jclouds.test.key"); String key = System.getProperty("jclouds.test.key");
connection = new CloudServersContextBuilder(account, key).withModules( connection = new CloudServersContextBuilder(account, key).withModules(
new Log4JLoggingModule()).withJsonDebug().buildContext().getApi(); new Log4JLoggingModule()).buildContext().getApi();
Injector injector = Guice.createInjector(new Log4JLoggingModule(), Injector injector = Guice.createInjector(new Log4JLoggingModule(),
new JschSshConnectionModule(), new ExecutorServiceModule( new JschSshConnectionModule(), new ExecutorServiceModule(

View File

@ -49,6 +49,8 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rackspace.Authentication; import org.jclouds.rackspace.Authentication;
import org.jclouds.rackspace.CloudServers; import org.jclouds.rackspace.CloudServers;
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule; import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
@ -880,6 +882,11 @@ public class CloudServersConnectionTest {
protected void configure() { protected void configure() {
bind(URI.class).annotatedWith(CloudServers.class).toInstance( bind(URI.class).annotatedWith(CloudServers.class).toInstance(
URI.create("http://localhost:8080")); URI.create("http://localhost:8080"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -35,6 +35,8 @@ import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rackspace.functions.ParseAuthenticationResponseFromHeaders; import org.jclouds.rackspace.functions.ParseAuthenticationResponseFromHeaders;
import org.jclouds.rackspace.reference.RackspaceHeaders; import org.jclouds.rackspace.reference.RackspaceHeaders;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
@ -82,6 +84,11 @@ public class RackspaceAuthenticationTest {
protected void configure() { protected void configure() {
bind(URI.class).annotatedWith(Authentication.class).toInstance( bind(URI.class).annotatedWith(Authentication.class).toInstance(
URI.create("http://localhost:8080")); URI.create("http://localhost:8080"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
} }
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());

View File

@ -33,6 +33,28 @@
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" /> <param name="File" value="target/test-data/jclouds.log" />
@ -59,12 +81,27 @@
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
<category name="org.jclouds"> <category name="org.jclouds">
<priority value="TRACE" /> <priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.http.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category> </category>
<!-- ======================= --> <!-- ======================= -->
@ -73,7 +110,6 @@
<root> <root>
<priority value="WARN" /> <priority value="WARN" />
<appender-ref ref="ASYNC" />
</root> </root>
</log4j:configuration> </log4j:configuration>