diff --git a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionHandle.java b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionHandle.java index 6a6ba4a649..813f93d75a 100644 --- a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionHandle.java +++ b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionHandle.java @@ -23,17 +23,20 @@ */ package org.jclouds.command.pool; -import com.google.inject.assistedinject.Assisted; -import org.jclouds.Logger; -import org.jclouds.command.FutureCommand; - import java.io.IOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Semaphore; +import javax.annotation.Resource; + +import org.jclouds.command.FutureCommand; +import org.jclouds.logging.Logger; + +import com.google.inject.assistedinject.Assisted; + /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ public abstract class FutureCommandConnectionHandle { @@ -43,62 +46,65 @@ public abstract class FutureCommandConnectionHandle { protected C conn; @SuppressWarnings("unchecked") protected FutureCommand operation; - protected final Logger logger; + @Resource + protected Logger logger = Logger.NULL; @SuppressWarnings("unchecked") - public FutureCommandConnectionHandle(java.util.logging.Logger logger, Semaphore maxConnections, @Assisted FutureCommand operation, @Assisted C conn, BlockingQueue available) throws InterruptedException { - this.maxConnections = maxConnections; - this.operation = operation; - this.conn = conn; - this.available = available; - this.logger = new Logger(logger); - this.completed = new Semaphore(1); - completed.acquire(); + public FutureCommandConnectionHandle(Semaphore maxConnections, + @Assisted FutureCommand operation, @Assisted C conn, + BlockingQueue available) throws InterruptedException { + this.maxConnections = maxConnections; + this.operation = operation; + this.conn = conn; + this.available = available; + this.completed = new Semaphore(1); + completed.acquire(); } @SuppressWarnings("unchecked") public FutureCommand getOperation() { - return operation; + return operation; } public abstract void startConnection(); public boolean isCompleted() { - return (completed.availablePermits() == 1); + return (completed.availablePermits() == 1); } public void release() throws InterruptedException { - if (isCompleted()) { - return; - } - logger.trace("%1s - %2d - releasing to pool", conn, conn.hashCode()); - available.put(conn); - conn = null; - operation = null; - completed.release(); + if (isCompleted()) { + return; + } + logger.trace("%1s - %2d - releasing to pool", conn, conn.hashCode()); + available.put(conn); + conn = null; + operation = null; + completed.release(); } public void cancel() throws IOException { - if (isCompleted()) { - return; - } - if (conn != null) { - logger.trace("%1s - %2d - cancelled; shutting down connection", conn, conn.hashCode()); - try { - shutdownConnection(); - } finally { - conn = null; - operation = null; - maxConnections.release(); - } - } - completed.release(); + if (isCompleted()) { + return; + } + if (conn != null) { + logger.trace("%1s - %2d - cancelled; shutting down connection", + conn, conn.hashCode()); + try { + shutdownConnection(); + } finally { + conn = null; + operation = null; + maxConnections.release(); + } + } + completed.release(); } public abstract void shutdownConnection() throws IOException; public void waitFor() throws InterruptedException { - completed.acquire(); - completed.release(); + completed.acquire(); + completed.release(); } } diff --git a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPool.java b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPool.java index 241863e720..75c662edec 100644 --- a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPool.java +++ b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPool.java @@ -23,14 +23,18 @@ */ package org.jclouds.command.pool; -import com.google.inject.Provides; -import com.google.inject.name.Named; -import org.jclouds.Logger; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + import org.jclouds.command.FutureCommand; import org.jclouds.lifecycle.BaseLifeCycle; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicInteger; +import com.google.inject.Provides; +import com.google.inject.name.Named; /** * // TODO: Adrian: Document this! @@ -47,14 +51,13 @@ public abstract class FutureCommandConnectionPool extends BaseLifeCycle { protected volatile boolean hitBottom = false; public FutureCommandConnectionPool( - Logger logger, ExecutorService executor, FutureCommandConnectionRetry futureCommandConnectionRetry, Semaphore allConnections, FutureCommandConnectionHandleFactory futureCommandConnectionHandleFactory, @Named("maxConnectionReuse") int maxConnectionReuse, BlockingQueue available, BaseLifeCycle... dependencies) { - super(logger, executor, dependencies); + super(executor, dependencies); this.futureCommandConnectionRetry = futureCommandConnectionRetry; this.allConnections = allConnections; this.futureCommandConnectionHandleFactory = futureCommandConnectionHandleFactory; diff --git a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPoolClient.java b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPoolClient.java index 29c538144c..794eccb70a 100644 --- a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPoolClient.java +++ b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionPoolClient.java @@ -28,7 +28,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.jclouds.Logger; import org.jclouds.Utils; import org.jclouds.command.FutureCommand; import org.jclouds.command.FutureCommandClient; @@ -47,11 +46,10 @@ public class FutureCommandConnectionPoolClient extends BaseLifeCycle private final BlockingQueue commandQueue; @Inject - public FutureCommandConnectionPoolClient(java.util.logging.Logger logger, - ExecutorService executor, + public FutureCommandConnectionPoolClient(ExecutorService executor, FutureCommandConnectionPool futureCommandConnectionPool, BlockingQueue commandQueue) { - super(new Logger(logger), executor, futureCommandConnectionPool); + super(executor, futureCommandConnectionPool); this.futureCommandConnectionPool = futureCommandConnectionPool; this.commandQueue = commandQueue; } diff --git a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionRetry.java b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionRetry.java index 4b96f267fd..496c204294 100644 --- a/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionRetry.java +++ b/core/src/main/java/org/jclouds/command/pool/FutureCommandConnectionRetry.java @@ -27,47 +27,53 @@ import java.io.IOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.atomic.AtomicInteger; -import org.jclouds.Logger; +import javax.annotation.Resource; + import org.jclouds.command.FutureCommand; +import org.jclouds.logging.Logger; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ public abstract class FutureCommandConnectionRetry { protected final BlockingQueue commandQueue; protected final AtomicInteger errors; - protected final Logger logger; + @Resource + protected Logger logger = Logger.NULL; - public FutureCommandConnectionRetry(Logger logger, BlockingQueue commandQueue, AtomicInteger errors) { - this.logger = logger; - this.commandQueue = commandQueue; - this.errors = errors; + public FutureCommandConnectionRetry( + BlockingQueue commandQueue, AtomicInteger errors) { + this.commandQueue = commandQueue; + this.errors = errors; } - public abstract void associateHandleWithConnection(FutureCommandConnectionHandle handle, C connection); + public abstract void associateHandleWithConnection( + FutureCommandConnectionHandle handle, C connection); - public abstract FutureCommandConnectionHandle getHandleFromConnection(C connection); + public abstract FutureCommandConnectionHandle getHandleFromConnection( + C connection); public boolean shutdownConnectionAndRetryOperation(C connection) { - FutureCommandConnectionHandle handle = getHandleFromConnection(connection); - if (handle != null) { - try { - logger.info("%1s - shutting down connection", connection); - handle.shutdownConnection(); - incrementErrorCountAndRetry(handle.getOperation()); - return true; - } catch (IOException e) { - logger.error(e, "%1s - error shutting down connection", connection); - } - } - return false; + FutureCommandConnectionHandle handle = getHandleFromConnection(connection); + if (handle != null) { + try { + logger.info("%1s - shutting down connection", connection); + handle.shutdownConnection(); + incrementErrorCountAndRetry(handle.getOperation()); + return true; + } catch (IOException e) { + logger.error(e, "%1s - error shutting down connection", + connection); + } + } + return false; } public void incrementErrorCountAndRetry(FutureCommand command) { - errors.getAndIncrement(); - logger.info("resubmitting command %1s", command); - commandQueue.add(command); + errors.getAndIncrement(); + logger.info("resubmitting command %1s", command); + commandQueue.add(command); } } diff --git a/core/src/main/java/org/jclouds/http/HttpFutureCommand.java b/core/src/main/java/org/jclouds/http/HttpFutureCommand.java index ee5130b424..a7b8a53b5d 100644 --- a/core/src/main/java/org/jclouds/http/HttpFutureCommand.java +++ b/core/src/main/java/org/jclouds/http/HttpFutureCommand.java @@ -25,8 +25,10 @@ package org.jclouds.http; import static com.google.common.base.Preconditions.checkNotNull; +import javax.annotation.Resource; + import org.jclouds.command.FutureCommand; -import org.jclouds.Logger; +import org.jclouds.logging.Logger; /** * // TODO: Adrian: Document this! @@ -58,12 +60,10 @@ public class HttpFutureCommand extends */ public abstract static class ResponseCallable implements FutureCommand.ResponseCallable { - protected final Logger logger; - private HttpResponse response; + @Resource + protected Logger logger = Logger.NULL; - public ResponseCallable(Logger logger) { - this.logger = logger; - } + private HttpResponse response; public HttpResponse getResponse() { return response; diff --git a/core/src/main/java/org/jclouds/http/JavaUrlHttpFutureCommandClient.java b/core/src/main/java/org/jclouds/http/JavaUrlHttpFutureCommandClient.java index b5a5d8bd1d..121e7138e1 100644 --- a/core/src/main/java/org/jclouds/http/JavaUrlHttpFutureCommandClient.java +++ b/core/src/main/java/org/jclouds/http/JavaUrlHttpFutureCommandClient.java @@ -36,10 +36,12 @@ import java.net.URL; import java.util.Collections; import java.util.List; +import javax.annotation.Resource; + import org.apache.commons.io.IOUtils; -import org.jclouds.Logger; import org.jclouds.Utils; import org.jclouds.command.FutureCommand; +import org.jclouds.logging.Logger; import com.google.inject.Inject; @@ -51,7 +53,8 @@ import com.google.inject.Inject; public class JavaUrlHttpFutureCommandClient implements HttpFutureCommandClient { private URL target; private List requestFilters = Collections.emptyList(); - private Logger logger; + @Resource + private Logger logger = Logger.NULL; public List getRequestFilters() { return requestFilters; @@ -63,11 +66,9 @@ public class JavaUrlHttpFutureCommandClient implements HttpFutureCommandClient { } @Inject - public JavaUrlHttpFutureCommandClient(java.util.logging.Logger logger, - URL target) throws MalformedURLException { - this.logger = new Logger(logger); + public JavaUrlHttpFutureCommandClient(URL target) + throws MalformedURLException { this.target = target; - this.logger.info("configured to connect to target: %1s", target); } public void submit(O operation) { diff --git a/core/src/main/java/org/jclouds/http/commands/callables/ReturnStringIf200.java b/core/src/main/java/org/jclouds/http/commands/callables/ReturnStringIf200.java index 5e0df37e84..1cd52021c9 100644 --- a/core/src/main/java/org/jclouds/http/commands/callables/ReturnStringIf200.java +++ b/core/src/main/java/org/jclouds/http/commands/callables/ReturnStringIf200.java @@ -23,45 +23,49 @@ */ package org.jclouds.http.commands.callables; -import com.google.inject.Inject; -import org.jclouds.Logger; +import java.io.IOException; +import java.io.InputStream; + import org.jclouds.Utils; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; -import java.io.IOException; -import java.io.InputStream; +import com.google.inject.Inject; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ -public class ReturnStringIf200 extends HttpFutureCommand.ResponseCallable { +public class ReturnStringIf200 extends + HttpFutureCommand.ResponseCallable { @Inject - public ReturnStringIf200(java.util.logging.Logger logger) { - super(new Logger(logger)); + public ReturnStringIf200() { + super(); } - public String call() throws HttpException { - int code = getResponse().getStatusCode(); - if (code >= 400 && code < 500) { - throw new HttpException(String.format("Content not found - %1s", getResponse())); - } else if (code == 200) { - InputStream entity = getResponse().getContent(); - if (entity == null) - throw new HttpException("no content"); - String toReturn = null; - try { - toReturn = Utils.toStringAndClose(entity); - } catch (IOException e) { - throw new HttpException(String.format("Couldn't receive response %1s, entity: %2s ", getResponse(), toReturn), e); - } - return toReturn; - } else { - throw new HttpException(String.format("Unhandled status code - %1s", getResponse())); - } + int code = getResponse().getStatusCode(); + if (code >= 400 && code < 500) { + throw new HttpException(String.format("Content not found - %1s", + getResponse())); + } else if (code == 200) { + InputStream entity = getResponse().getContent(); + if (entity == null) + throw new HttpException("no content"); + String toReturn = null; + try { + toReturn = Utils.toStringAndClose(entity); + } catch (IOException e) { + throw new HttpException(String.format( + "Couldn't receive response %1s, entity: %2s ", + getResponse(), toReturn), e); + } + return toReturn; + } else { + throw new HttpException(String.format( + "Unhandled status code - %1s", getResponse())); + } } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/http/commands/callables/ReturnTrueIf200.java b/core/src/main/java/org/jclouds/http/commands/callables/ReturnTrueIf200.java index c912d0f3ed..41eec580cc 100644 --- a/core/src/main/java/org/jclouds/http/commands/callables/ReturnTrueIf200.java +++ b/core/src/main/java/org/jclouds/http/commands/callables/ReturnTrueIf200.java @@ -23,30 +23,31 @@ */ package org.jclouds.http.commands.callables; -import com.google.inject.Inject; -import org.jclouds.Logger; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; +import com.google.inject.Inject; + /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ -public class ReturnTrueIf200 extends HttpFutureCommand.ResponseCallable { +public class ReturnTrueIf200 extends + HttpFutureCommand.ResponseCallable { @Inject - public ReturnTrueIf200(java.util.logging.Logger logger) { - super(new Logger(logger)); + public ReturnTrueIf200() { + super(); } public Boolean call() throws HttpException { - if (getResponse().getStatusCode() == 200) { - return true; - } else if (getResponse().getStatusCode() == 404) { - return false; - } else { - throw new HttpException("Error checking bucket " + getResponse()); - } + if (getResponse().getStatusCode() == 200) { + return true; + } else if (getResponse().getStatusCode() == 404) { + return false; + } else { + throw new HttpException("Error checking bucket " + getResponse()); + } } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/http/commands/callables/xml/ParseSax.java b/core/src/main/java/org/jclouds/http/commands/callables/xml/ParseSax.java index cc908c2be6..5236a20915 100644 --- a/core/src/main/java/org/jclouds/http/commands/callables/xml/ParseSax.java +++ b/core/src/main/java/org/jclouds/http/commands/callables/xml/ParseSax.java @@ -23,12 +23,11 @@ */ package org.jclouds.http.commands.callables.xml; -import com.google.inject.Inject; -import com.google.inject.assistedinject.Assisted; -import com.google.inject.name.Named; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.InputStream; import org.apache.commons.io.IOUtils; -import org.jclouds.Logger; import org.jclouds.Utils; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; @@ -36,9 +35,10 @@ import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; -import static com.google.common.base.Preconditions.checkNotNull; -import java.io.InputStream; +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import com.google.inject.name.Named; /** * This object will parse the body of an HttpResponse and return the result of @@ -55,9 +55,8 @@ public class ParseSax extends HttpFutureCommand.ResponseCallable { private boolean suckFirst = false; @Inject - public ParseSax(java.util.logging.Logger logger, XMLReader parser, - @Assisted HandlerWithResult handler) { - super(new Logger(checkNotNull(logger, "logger"))); + public ParseSax(XMLReader parser, @Assisted HandlerWithResult handler) { + super(); this.parser = checkNotNull(parser, "parser"); this.handler = checkNotNull(handler, "handler"); } diff --git a/core/src/main/java/org/jclouds/http/config/HttpFutureCommandClientModule.java b/core/src/main/java/org/jclouds/http/config/HttpFutureCommandClientModule.java new file mode 100644 index 0000000000..81c31a0e3d --- /dev/null +++ b/core/src/main/java/org/jclouds/http/config/HttpFutureCommandClientModule.java @@ -0,0 +1,44 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.config; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import org.jclouds.http.HttpFutureCommandClient; + +/** + * designates the the module configures a {@link HttpFutureCommandClient} + * + * @author Adrian Cole + * + */ +@Retention(RUNTIME) +@Target(TYPE) +public @interface HttpFutureCommandClientModule { + +} diff --git a/core/src/main/java/org/jclouds/http/config/JavaUrlHttpFutureCommandClientModule.java b/core/src/main/java/org/jclouds/http/config/JavaUrlHttpFutureCommandClientModule.java index a833a8050c..3a0a05f392 100644 --- a/core/src/main/java/org/jclouds/http/config/JavaUrlHttpFutureCommandClientModule.java +++ b/core/src/main/java/org/jclouds/http/config/JavaUrlHttpFutureCommandClientModule.java @@ -40,6 +40,7 @@ import com.google.inject.name.Named; * * @author Adrian Cole */ +@HttpFutureCommandClientModule public class JavaUrlHttpFutureCommandClientModule extends AbstractModule { @Override diff --git a/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java b/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java index 5aa65771d3..2f7ea09a6f 100644 --- a/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java +++ b/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java @@ -23,51 +23,54 @@ */ package org.jclouds.lifecycle; -import org.jclouds.Logger; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; + +import org.jclouds.logging.Logger; + /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ public abstract class BaseLifeCycle implements Runnable, LifeCycle { - protected final Logger logger; + @Resource + protected Logger logger = Logger.NULL; protected final ExecutorService executor; protected final BaseLifeCycle[] dependencies; protected final Object statusLock; protected volatile Status status; protected AtomicReference exception = new AtomicReference(); - public BaseLifeCycle(Logger logger, ExecutorService executor, BaseLifeCycle... dependencies) { - this.logger = logger; - this.executor = executor; - this.dependencies = dependencies; - this.statusLock = new Object(); - this.status = Status.INACTIVE; + public BaseLifeCycle(ExecutorService executor, + BaseLifeCycle... dependencies) { + this.executor = executor; + this.dependencies = dependencies; + this.statusLock = new Object(); + this.status = Status.INACTIVE; } public Status getStatus() { - return status; + return status; } public void run() { - try { - while (shouldDoWork()) { - doWork(); - } - } catch (Exception e) { - logger.error(e, "Exception doing work"); - exception.set(e); - } - this.status = Status.SHUTTING_DOWN; - doShutdown(); - this.status = Status.SHUT_DOWN; - logger.info("%1s", this); + try { + while (shouldDoWork()) { + doWork(); + } + } catch (Exception e) { + logger.error(e, "Exception doing work"); + exception.set(e); + } + this.status = Status.SHUTTING_DOWN; + doShutdown(); + this.status = Status.SHUT_DOWN; + logger.info("%1s", this); } protected abstract void doWork() throws Exception; @@ -75,94 +78,97 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle { protected abstract void doShutdown(); protected boolean shouldDoWork() { - try { - exceptionIfDepedenciesNotActive(); - } catch (IllegalStateException e) { - return false; - } - return status.equals(Status.ACTIVE) && exception.get() == null; + try { + exceptionIfDepedenciesNotActive(); + } catch (IllegalStateException e) { + return false; + } + return status.equals(Status.ACTIVE) && exception.get() == null; } @PostConstruct public void start() { - logger.info("starting %1s", this); - synchronized (this.statusLock) { - if (this.status.compareTo(Status.SHUTDOWN_REQUEST) >= 0) { - doShutdown(); - this.status = Status.SHUT_DOWN; - this.statusLock.notifyAll(); - return; - } - if (this.status.compareTo(Status.ACTIVE) == 0) { - this.statusLock.notifyAll(); - return; - } + logger.info("starting %1s", this); + synchronized (this.statusLock) { + if (this.status.compareTo(Status.SHUTDOWN_REQUEST) >= 0) { + doShutdown(); + this.status = Status.SHUT_DOWN; + this.statusLock.notifyAll(); + return; + } + if (this.status.compareTo(Status.ACTIVE) == 0) { + this.statusLock.notifyAll(); + return; + } - if (this.status.compareTo(Status.INACTIVE) != 0) { - throw new IllegalStateException("Illegal state: " + this.status); - } + if (this.status.compareTo(Status.INACTIVE) != 0) { + throw new IllegalStateException("Illegal state: " + this.status); + } - exceptionIfDepedenciesNotActive(); + exceptionIfDepedenciesNotActive(); - this.status = Status.ACTIVE; - } - executor.execute(this); + this.status = Status.ACTIVE; + } + executor.execute(this); } protected void exceptionIfDepedenciesNotActive() { - for (BaseLifeCycle dependency : dependencies) { - if (dependency.status.compareTo(Status.ACTIVE) != 0) { - throw new IllegalStateException(String.format("Illegal state: %1s for component: %2s", dependency.status, dependency)); - } - } + for (BaseLifeCycle dependency : dependencies) { + if (dependency.status.compareTo(Status.ACTIVE) != 0) { + throw new IllegalStateException(String.format( + "Illegal state: %1s for component: %2s", + dependency.status, dependency)); + } + } } public Exception getException() { - return this.exception.get(); + return this.exception.get(); } protected void awaitShutdown(long timeout) throws InterruptedException { - awaitStatus(Status.SHUT_DOWN, timeout); + awaitStatus(Status.SHUT_DOWN, timeout); } - protected void awaitStatus(Status intended, long timeout) throws InterruptedException { - synchronized (this.statusLock) { - long deadline = System.currentTimeMillis() + timeout; - long remaining = timeout; - while (this.status != intended) { - this.statusLock.wait(remaining); - if (timeout > 0) { - remaining = deadline - System.currentTimeMillis(); - if (remaining <= 0) { - break; - } - } - } - } + protected void awaitStatus(Status intended, long timeout) + throws InterruptedException { + synchronized (this.statusLock) { + long deadline = System.currentTimeMillis() + timeout; + long remaining = timeout; + while (this.status != intended) { + this.statusLock.wait(remaining); + if (timeout > 0) { + remaining = deadline - System.currentTimeMillis(); + if (remaining <= 0) { + break; + } + } + } + } } @PreDestroy public void shutdown() { - shutdown(2000); + shutdown(2000); } public void shutdown(long waitMs) { - synchronized (this.statusLock) { - if (this.status.compareTo(Status.ACTIVE) > 0) { - return; - } - this.status = Status.SHUTDOWN_REQUEST; - try { - awaitShutdown(waitMs); - } catch (InterruptedException ignore) { - } - } + synchronized (this.statusLock) { + if (this.status.compareTo(Status.ACTIVE) > 0) { + return; + } + this.status = Status.SHUTDOWN_REQUEST; + try { + awaitShutdown(waitMs); + } catch (InterruptedException ignore) { + } + } } protected void exceptionIfNotActive() { - if (!status.equals(Status.ACTIVE)) - throw new IllegalStateException(String.format("not active: %1s", this)); + if (!status.equals(Status.ACTIVE)) + throw new IllegalStateException(String.format("not active: %1s", + this)); } - } diff --git a/core/src/main/java/org/jclouds/logging/BaseLogger.java b/core/src/main/java/org/jclouds/logging/BaseLogger.java new file mode 100644 index 0000000000..fb5b8a2c8c --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/BaseLogger.java @@ -0,0 +1,83 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging; + +/** + * Base implementation that constructs formatted log strings. + * + * @author Adrian Cole + * + */ +public abstract class BaseLogger implements Logger { + + protected abstract void logError(String message, Throwable e); + + protected abstract void logError(String message); + + protected abstract void logWarn(String message, Throwable e); + + protected abstract void logWarn(String message); + + protected abstract void logInfo(String message); + + protected abstract void logDebug(String message); + + protected abstract void logTrace(String message); + + public void trace(String message, Object... args) { + if (isTraceEnabled()) + logTrace(String.format(message, args)); + } + + public void debug(String message, Object... args) { + if (isDebugEnabled()) + logDebug(String.format(message, args)); + } + + public void info(String message, Object... args) { + if (isInfoEnabled()) + logInfo(String.format(message, args)); + } + + public void warn(String message, Object... args) { + if (isWarnEnabled()) + logWarn(String.format(message, args)); + } + + public void warn(Throwable e, String message, Object... args) { + if (isWarnEnabled()) + logWarn(String.format(message, args), e); + } + + public void error(String message, Object... args) { + if (isErrorEnabled()) + logError(String.format(message, args)); + } + + public void error(Throwable e, String message, Object... args) { + if (isErrorEnabled()) + logError(String.format(message, args), e); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/logging/Logger.java b/core/src/main/java/org/jclouds/logging/Logger.java new file mode 100644 index 0000000000..6423a0c784 --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/Logger.java @@ -0,0 +1,89 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging; + +/** + * JCloud log abstraction layer. + *

+ * Implementations of logging are optional and injected if they are configured. + *

+ * @Resource Logger logger = Logger.NULL; The above will get you a + * null-safe instance of Logger. If configured, this logger will be + * swapped with a real Logger implementation with category set to the current + * class name. This is done post-object construction, so do not attempt to use + * these loggers in your constructor. + *

+ * If you wish to initialize loggers like these yourself, do not use the @Resource + * annotation. + *

+ * This implementation first checks to see if the level is enabled before + * issuing the log command. In other words, don't do the following + * if (logger.isTraceEnabled()) logger.trace("message");. + *

+ * + * @author Adrian Cole + */ +public interface Logger { + + /** + * Assign to member to avoid NPE when no logging module is configured. + */ + public static final Logger NULL = new NullLogger(); + + String getCategory(); + + void trace(String message, Object... args); + + boolean isTraceEnabled(); + + void debug(String message, Object... args); + + boolean isDebugEnabled(); + + void info(String message, Object... args); + + boolean isInfoEnabled(); + + void warn(String message, Object... args); + + void warn(Throwable throwable, String message, Object... args); + + boolean isWarnEnabled(); + + void error(String message, Object... args); + + void error(Throwable throwable, String message, Object... args); + + boolean isErrorEnabled(); + + /** + * Produces instances of {@link Logger} relevant to the specified category + * + * @author Adrian Cole + * + */ + public static interface LoggerFactory { + public Logger getLogger(String category); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/Logger.java b/core/src/main/java/org/jclouds/logging/NullLogger.java similarity index 60% rename from core/src/main/java/org/jclouds/Logger.java rename to core/src/main/java/org/jclouds/logging/NullLogger.java index 3f0dfe6391..ce677075c0 100644 --- a/core/src/main/java/org/jclouds/Logger.java +++ b/core/src/main/java/org/jclouds/logging/NullLogger.java @@ -21,57 +21,73 @@ * under the License. * ==================================================================== */ -package org.jclouds; +package org.jclouds.logging; -import java.util.logging.Level; - -public class Logger { - private final java.util.logging.Logger logger; - - public Logger(java.util.logging.Logger logger) { - this.logger = logger; - } - - public void trace(String message, Object... args) { - if (isTraceEnabled()) - logger.finest(String.format(message, args)); - } - - public boolean isTraceEnabled() { - return logger.isLoggable(Level.FINEST); - } +/** + * Logger that doesn't do anything. + *

+ * Useful to get baseline performance unaffected by logging. + * + * @author Adrian Cole + * + */ +public class NullLogger implements Logger { public void debug(String message, Object... args) { - if (isDebugEnabled()) - logger.fine(String.format(message, args)); - } - public boolean isDebugEnabled() { - return logger.isLoggable(Level.FINE); - } - - public void info(String message, Object... args) { - if (logger.isLoggable(Level.INFO)) - logger.info(String.format(message, args)); - } - - public void warn(String message, Object... args) { - if (logger.isLoggable(Level.WARNING)) - logger.log(Level.WARNING, String.format(message, args)); - } - - public void warn(Throwable throwable, String message, Object... args) { - if (logger.isLoggable(Level.WARNING)) - logger.log(Level.WARNING, String.format(message, args), throwable); } public void error(String message, Object... args) { - if (logger.isLoggable(Level.SEVERE)) - logger.log(Level.SEVERE, String.format(message, args)); + } public void error(Throwable throwable, String message, Object... args) { - if (logger.isLoggable(Level.SEVERE)) - logger.log(Level.SEVERE, String.format(message, args), throwable); + + } + + public String getCategory() { + + return null; + } + + public void info(String message, Object... args) { + + } + + public boolean isDebugEnabled() { + + return false; + } + + 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) { + } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResource.java b/core/src/main/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResource.java new file mode 100644 index 0000000000..bf887aee89 --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResource.java @@ -0,0 +1,147 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.config; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.Resource; + +import org.jclouds.logging.Logger; +import org.jclouds.logging.Logger.LoggerFactory; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.Module; +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 Logger} to members annotated with + * {@link Resource} + * + * This class is a TypeListener so that it can create a logger whose category is + * the same as the name of the injected instance's class. + * + * Note that this occurs post-object construction through + * {@link Module#bindListener}. + * + * Here's an example usage: + *

+ *     class A {
+ *         @Resource private Logger logger = Logger.NULL; 
+ *     }
+ * 
+ *     Injector i = Guice.createInjector(new AbstractModule() {
+ *         @Override protected void configure() { 
+ *             bindListener(any(), new
+ *                 BindLoggersAnnotatedWithResource( new
+ *                     JDKLogger.JDKLoggerFactory()));
+ *         }
+ *     });
+ * 
+ *     A = i.getInstance(A.class); 
+ *     // A will now have a logger associated with it
+ * 
+ * + * @author Adrian Cole + * + */ +public class BindLoggersAnnotatedWithResource implements TypeListener { + + static class AssignLoggerToField implements InjectionListener { + private final Logger logger; + private final Field field; + + AssignLoggerToField(Logger logger, Field field) { + this.logger = logger; + this.field = field; + } + + public void afterInjection(I injectee) { + try { + field.setAccessible(true); + field.set(injectee, logger); + } catch (IllegalAccessException e) { + throw new ProvisionException(e.getMessage(), e); + } + } + } + + static class LoggerFieldsAnnotatedWithResource implements + Function { + public Field apply(Field from) { + Annotation inject = from.getAnnotation(Resource.class); + if (inject != null && from.getType().isAssignableFrom(Logger.class)) { + return from; + } + return null; + } + } + + private final LoggerFactory loggerFactory; + + @Inject + public BindLoggersAnnotatedWithResource(LoggerFactory loggerFactory) { + this.loggerFactory = loggerFactory; + } + + public void hear(TypeLiteral injectableType, + TypeEncounter encounter) { + + Class type = injectableType.getRawType(); + Set loggerFields = getLoggerFieldsAnnotatedWithResource(type); + if (loggerFields.size() == 0) + return; + + Logger logger = loggerFactory.getLogger(type.getName()); + + for (Field field : loggerFields) { + encounter.register(new AssignLoggerToField(logger, field)); + } + } + + @VisibleForTesting + Set getLoggerFieldsAnnotatedWithResource(Class declaredType) { + Set fields = new HashSet(); + Class type = declaredType; + while (type != null) { + fields.addAll(Arrays.asList(type.getDeclaredFields())); + type = type.getSuperclass(); + } + Set loggerFields = Sets.newHashSet(Iterables.transform(fields, + new LoggerFieldsAnnotatedWithResource())); + loggerFields.remove(null); + return loggerFields; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/logging/config/LoggingModule.java b/core/src/main/java/org/jclouds/logging/config/LoggingModule.java new file mode 100644 index 0000000000..e82a355dff --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/config/LoggingModule.java @@ -0,0 +1,49 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.config; + +import static com.google.inject.matcher.Matchers.any; + +import org.jclouds.logging.Logger; + +import com.google.inject.AbstractModule; + +/** + * Creates a post-injection listener that binds Loggers named the same as the + * enclosing class. + * + * @author Adrian Cole + * + */ +public abstract class LoggingModule extends AbstractModule { + + @Override + protected void configure() { + bindListener(any(), new BindLoggersAnnotatedWithResource( + createLoggerFactory())); + } + + public abstract Logger.LoggerFactory createLoggerFactory(); + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/logging/config/NullLoggingModule.java b/core/src/main/java/org/jclouds/logging/config/NullLoggingModule.java new file mode 100644 index 0000000000..7ccc800118 --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/config/NullLoggingModule.java @@ -0,0 +1,43 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.config; + +import org.jclouds.logging.Logger; +import org.jclouds.logging.NullLogger; + +/** + * Configures logging of type {@link NullLogger} + * + * @author Adrian Cole + * + */ +public class NullLoggingModule extends LoggingModule { + public Logger.LoggerFactory createLoggerFactory() { + return new Logger.LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }; + } +} diff --git a/core/src/main/java/org/jclouds/logging/jdk/JDKLogger.java b/core/src/main/java/org/jclouds/logging/jdk/JDKLogger.java new file mode 100644 index 0000000000..5fcd7f0d4c --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/jdk/JDKLogger.java @@ -0,0 +1,108 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.jdk; + +import java.util.logging.Level; + +import org.jclouds.logging.BaseLogger; +import org.jclouds.logging.Logger; + +/** + * {@link java.util.logging.Logger} implementation of {@link Logger}. + * + * @author Adrian Cole + * + */ +public class JDKLogger extends BaseLogger { + private final java.util.logging.Logger logger; + + public static class JDKLoggerFactory implements LoggerFactory { + public Logger getLogger(String category) { + return new JDKLogger(java.util.logging.Logger.getLogger(category)); + } + } + + public JDKLogger(java.util.logging.Logger logger) { + this.logger = logger; + } + + @Override + protected void logTrace(String message) { + logger.finest(message); + } + + public boolean isTraceEnabled() { + return logger.isLoggable(Level.FINEST); + } + + @Override + protected void logDebug(String message) { + logger.fine(message); + } + + public boolean isDebugEnabled() { + return logger.isLoggable(Level.FINE); + } + + @Override + protected void logInfo(String message) { + logger.info(message); + } + + public boolean isInfoEnabled() { + return logger.isLoggable(Level.INFO); + } + + @Override + protected void logWarn(String message) { + logger.warning(message); + } + + @Override + protected void logWarn(String message, Throwable e) { + logger.log(Level.WARNING, message, e); + } + + public boolean isWarnEnabled() { + return logger.isLoggable(Level.WARNING); + } + + @Override + protected void logError(String message) { + logger.severe(message); + } + + @Override + protected void logError(String message, Throwable e) { + logger.log(Level.SEVERE, message, e); + } + + public boolean isErrorEnabled() { + return logger.isLoggable(Level.SEVERE); + } + + public String getCategory() { + return logger.getName(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/logging/jdk/config/JDKLoggingModule.java b/core/src/main/java/org/jclouds/logging/jdk/config/JDKLoggingModule.java new file mode 100644 index 0000000000..cff19aceb3 --- /dev/null +++ b/core/src/main/java/org/jclouds/logging/jdk/config/JDKLoggingModule.java @@ -0,0 +1,40 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.jdk.config; + +import org.jclouds.logging.Logger; +import org.jclouds.logging.config.LoggingModule; +import org.jclouds.logging.jdk.JDKLogger; + +/** + * Configures logging of type {@link JDKLogger} + * + * @author Adrian Cole + * + */ +public class JDKLoggingModule extends LoggingModule { + public Logger.LoggerFactory createLoggerFactory() { + return new JDKLogger.JDKLoggerFactory(); + } +} diff --git a/core/src/test/java/org/jclouds/http/BaseHttpFutureCommandClientTest.java b/core/src/test/java/org/jclouds/http/BaseHttpFutureCommandClientTest.java index 861c1db025..2092fccf65 100644 --- a/core/src/test/java/org/jclouds/http/BaseHttpFutureCommandClientTest.java +++ b/core/src/test/java/org/jclouds/http/BaseHttpFutureCommandClientTest.java @@ -43,6 +43,7 @@ import org.jclouds.http.commands.Head; import org.jclouds.http.commands.callables.xml.ParseSax; import org.jclouds.http.commands.config.HttpCommandsModule; import org.jclouds.lifecycle.Closer; +import org.jclouds.logging.jdk.config.JDKLoggingModule; import org.mortbay.jetty.Handler; import org.mortbay.jetty.Request; import org.mortbay.jetty.Server; @@ -117,8 +118,8 @@ public abstract class BaseHttpFutureCommandClientTest { protected void configure() { Names.bindProperties(binder(), properties); } - }, new HttpCommandsModule(), createClientModule(), - new AbstractModule() { + }, new JDKLoggingModule(), new HttpCommandsModule(), + createClientModule(), new AbstractModule() { @Override protected void configure() { bind(new TypeLiteral>() { diff --git a/core/src/test/java/org/jclouds/http/commands/GetStringTest.java b/core/src/test/java/org/jclouds/http/commands/GetStringTest.java index ed62df9c71..7967e7a4ef 100644 --- a/core/src/test/java/org/jclouds/http/commands/GetStringTest.java +++ b/core/src/test/java/org/jclouds/http/commands/GetStringTest.java @@ -23,44 +23,40 @@ */ package org.jclouds.http.commands; -import static org.easymock.classextension.EasyMock.createMock; import org.jclouds.http.commands.callables.ReturnStringIf200; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import java.util.logging.Logger; - /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ @Test public class GetStringTest { private static final String GOOD_PATH = "/index.html"; - private GetString get = null; private ReturnStringIf200 callable = null; @BeforeMethod void setUp() { - callable = new ReturnStringIf200(createMock(Logger.class)); - get = new GetString(callable, GOOD_PATH); - + callable = new ReturnStringIf200(); + get = new GetString(callable, GOOD_PATH); + } @AfterMethod void tearDown() { - get = null; - callable = null; + get = null; + callable = null; } @Test public void testConstructor() { - assert get.getResponseFuture() != null; - assert get.getRequest().getUri().equals(GOOD_PATH); - assert get.getRequest().getMethod().equals("GET"); + assert get.getResponseFuture() != null; + assert get.getRequest().getUri().equals(GOOD_PATH); + assert get.getRequest().getMethod().equals("GET"); } } \ No newline at end of file diff --git a/core/src/test/java/org/jclouds/http/commands/callables/ReturnStringIf200Test.java b/core/src/test/java/org/jclouds/http/commands/callables/ReturnStringIf200Test.java index 38112296dc..60dd6db36f 100644 --- a/core/src/test/java/org/jclouds/http/commands/callables/ReturnStringIf200Test.java +++ b/core/src/test/java/org/jclouds/http/commands/callables/ReturnStringIf200Test.java @@ -23,19 +23,22 @@ */ package org.jclouds.http.commands.callables; +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + import org.apache.commons.io.IOUtils; -import static org.easymock.classextension.EasyMock.*; import org.jclouds.http.HttpFutureCommand; import org.jclouds.http.HttpResponse; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; -import java.util.logging.Logger; - @Test public class ReturnStringIf200Test { @@ -43,53 +46,55 @@ public class ReturnStringIf200Test { @BeforeMethod void setUp() { - callable = new ReturnStringIf200(createMock(Logger.class)); + callable = new ReturnStringIf200(); } @AfterMethod void tearDown() { - callable = null; + callable = null; } @Test - public void testExceptionWhenNoContentOn200() throws ExecutionException, InterruptedException, TimeoutException, IOException { - HttpResponse response = createMock(HttpResponse.class); - expect(response.getStatusCode()).andReturn(200); - expect(response.getContent()).andReturn(null); - replay(response); - callable.setResponse(response); - try { - callable.call(); - } catch (Exception e) { - assert e.getMessage().equals("no content"); - } - verify(response); + public void testExceptionWhenNoContentOn200() throws ExecutionException, + InterruptedException, TimeoutException, IOException { + HttpResponse response = createMock(HttpResponse.class); + expect(response.getStatusCode()).andReturn(200); + expect(response.getContent()).andReturn(null); + replay(response); + callable.setResponse(response); + try { + callable.call(); + } catch (Exception e) { + assert e.getMessage().equals("no content"); + } + verify(response); } @Test - public void testExceptionWhenIOExceptionOn200() throws ExecutionException, InterruptedException, TimeoutException, IOException { - HttpResponse response = createMock(HttpResponse.class); - expect(response.getStatusCode()).andReturn(200); - RuntimeException exception = new RuntimeException("bad"); - expect(response.getContent()).andThrow(exception); - replay(response); - callable.setResponse(response); - try { - callable.call(); - } catch (Exception e) { - assert e.equals(exception); - } - verify(response); + public void testExceptionWhenIOExceptionOn200() throws ExecutionException, + InterruptedException, TimeoutException, IOException { + HttpResponse response = createMock(HttpResponse.class); + expect(response.getStatusCode()).andReturn(200); + RuntimeException exception = new RuntimeException("bad"); + expect(response.getContent()).andThrow(exception); + replay(response); + callable.setResponse(response); + try { + callable.call(); + } catch (Exception e) { + assert e.equals(exception); + } + verify(response); } @Test public void testResponseOk() throws Exception { - HttpResponse response = createMock(HttpResponse.class); - expect(response.getStatusCode()).andReturn(200); - expect(response.getContent()).andReturn(IOUtils.toInputStream("hello")); - replay(response); - callable.setResponse(response); - assert "hello".equals(callable.call()); - verify(response); + HttpResponse response = createMock(HttpResponse.class); + expect(response.getStatusCode()).andReturn(200); + expect(response.getContent()).andReturn(IOUtils.toInputStream("hello")); + replay(response); + callable.setResponse(response); + assert "hello".equals(callable.call()); + verify(response); } } \ No newline at end of file diff --git a/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java b/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java index 59d45ab147..62a8cb1ec4 100644 --- a/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java +++ b/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java @@ -23,21 +23,30 @@ */ package org.jclouds.lifecycle.config; +import static com.google.inject.matcher.Matchers.*; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.concurrent.ExecutorService; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; + +import org.jclouds.lifecycle.Closer; +import org.jclouds.logging.Logger; +import org.jclouds.logging.config.BindLoggersAnnotatedWithResource; +import org.jclouds.logging.jdk.JDKLogger; +import org.testng.annotations.Test; + import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; -import org.jclouds.lifecycle.Closer; -import org.testng.annotations.Test; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.io.IOException; -import java.util.concurrent.ExecutorService; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ @Test @@ -45,78 +54,81 @@ public class LifeCycleModuleTest { @Test void testBindsExecutor() { - Injector i = Guice.createInjector(new LifeCycleModule()); - assert i.getInstance(ExecutorService.class) != null; + Injector i = Guice.createInjector(new LifeCycleModule()); + assert i.getInstance(ExecutorService.class) != null; } @Test void testBindsCloser() { - Injector i = Guice.createInjector(new LifeCycleModule()); - assert i.getInstance(Closer.class) != null; + Injector i = Guice.createInjector(new LifeCycleModule()); + assert i.getInstance(Closer.class) != null; } @Test void testCloserClosesExecutor() throws IOException { - Injector i = Guice.createInjector(new LifeCycleModule()); - ExecutorService executor = i.getInstance(ExecutorService.class); - assert !executor.isShutdown(); - Closer closer = i.getInstance(Closer.class); - closer.close(); - assert executor.isShutdown(); + Injector i = Guice.createInjector(new LifeCycleModule()); + ExecutorService executor = i.getInstance(ExecutorService.class); + assert !executor.isShutdown(); + Closer closer = i.getInstance(Closer.class); + closer.close(); + assert executor.isShutdown(); } static class PreDestroyable { - boolean isClosed = false; + boolean isClosed = false; - @Inject - PreDestroyable(ExecutorService executor) { - this.executor = executor; - } + @Inject + PreDestroyable(ExecutorService executor) { + this.executor = executor; + } - ExecutorService executor; + ExecutorService executor; - @PreDestroy - public void close() { - assert !executor.isShutdown(); - isClosed = true; - } + @PreDestroy + public void close() { + assert !executor.isShutdown(); + isClosed = true; + } } @Test void testCloserPreDestroyOrder() throws IOException { - Injector i = Guice.createInjector(new LifeCycleModule(), new AbstractModule() { - protected void configure() { - bind(PreDestroyable.class); - } - }); - ExecutorService executor = i.getInstance(ExecutorService.class); - assert !executor.isShutdown(); - PreDestroyable preDestroyable = i.getInstance(PreDestroyable.class); - assert !preDestroyable.isClosed; - Closer closer = i.getInstance(Closer.class); - closer.close(); - assert preDestroyable.isClosed; - assert executor.isShutdown(); + Injector i = Guice.createInjector(new LifeCycleModule(), + new AbstractModule() { + protected void configure() { + bind(PreDestroyable.class); + } + }); + ExecutorService executor = i.getInstance(ExecutorService.class); + assert !executor.isShutdown(); + PreDestroyable preDestroyable = i.getInstance(PreDestroyable.class); + assert !preDestroyable.isClosed; + Closer closer = i.getInstance(Closer.class); + closer.close(); + assert preDestroyable.isClosed; + assert executor.isShutdown(); } static class PostConstructable { - boolean isStarted; + boolean isStarted; - @PostConstruct - void start() { - isStarted = true; - } + @PostConstruct + void start() { + isStarted = true; + } } @Test void testPostConstruct() { - Injector i = Guice.createInjector(new LifeCycleModule(), new AbstractModule() { - protected void configure() { - bind(PostConstructable.class); - } - }); - PostConstructable postConstructable = i.getInstance(PostConstructable.class); - assert postConstructable.isStarted; + Injector i = Guice.createInjector(new LifeCycleModule(), + new AbstractModule() { + protected void configure() { + bind(PostConstructable.class); + } + }); + PostConstructable postConstructable = i + .getInstance(PostConstructable.class); + assert postConstructable.isStarted; } diff --git a/core/src/test/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResourceTest.java b/core/src/test/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResourceTest.java new file mode 100644 index 0000000000..e046061d05 --- /dev/null +++ b/core/src/test/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResourceTest.java @@ -0,0 +1,148 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.config; + +import static com.google.inject.matcher.Matchers.any; +import static org.easymock.classextension.EasyMock.createMock; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.lang.reflect.Field; +import java.util.Set; + +import javax.annotation.Resource; + +import org.jclouds.logging.Logger; +import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.AssignLoggerToField; +import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.LoggerFieldsAnnotatedWithResource; +import org.jclouds.logging.jdk.JDKLogger; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; + +public class BindLoggersAnnotatedWithResourceTest { + + private BindLoggersAnnotatedWithResource blawr; + + public static class A { + @Resource + private Logger logger = Logger.NULL; + } + + public static class B { + @Resource + private Logger logger = Logger.NULL; + } + + @BeforeMethod + void createBlawr() { + blawr = new BindLoggersAnnotatedWithResource( + new JDKLogger.JDKLoggerFactory()); + } + + @Test + void testHear() { + Injector i = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + bindListener(any(), blawr); + } + + }); + assertEquals(i.getInstance(A.class).logger.getCategory(), getClass() + .getName() + + "$A"); + assertEquals(i.getInstance(B.class).logger.getCategory(), getClass() + .getName() + + "$B"); + + } + + @Test + public void testAssignLoggerToField() throws SecurityException, + NoSuchFieldException, IllegalArgumentException, + IllegalAccessException { + Logger logger = createMock(Logger.class); + A a = new A(); + Field field = A.class.getDeclaredField("logger"); + AssignLoggerToField assigner = new AssignLoggerToField(logger, + field); + assigner.afterInjection(a); + assert field.get(a).equals(logger); + } + + @Test + public void testLoggerFieldsAnnotatedWithResource() + throws SecurityException, NoSuchFieldException { + LoggerFieldsAnnotatedWithResource function = new LoggerFieldsAnnotatedWithResource(); + assertEquals(function.apply(A.class.getDeclaredField("logger")), + A.class.getDeclaredField("logger")); + } + + public static class C { + @Inject + private Logger logger = Logger.NULL; + } + + @Test + public void testLoggerFieldsAnnotatedWithInjectReturnsNull() + throws SecurityException, NoSuchFieldException { + LoggerFieldsAnnotatedWithResource function = new LoggerFieldsAnnotatedWithResource(); + assertNull(function.apply(C.class.getDeclaredField("logger"))); + } + + public static class D { + @Resource + private Logger logger = Logger.NULL; + + @Resource + private Logger blogger; + + } + + @Test + public void testGetLoggerFieldsAnnotatedWithResourceNoLogger() { + Set fields = blawr.getLoggerFieldsAnnotatedWithResource(this + .getClass()); + assertEquals(fields.size(), 0); + } + + @Test + public void testGetLoggerFieldsAnnotatedWithResourceOneLogger() { + Set fields = blawr.getLoggerFieldsAnnotatedWithResource(A.class); + assertEquals(fields.size(), 1); + } + + @Test + public void testGetLoggerFieldsAnnotatedWithResourceTwoLoggers() { + Set fields = blawr.getLoggerFieldsAnnotatedWithResource(D.class); + assertEquals(fields.size(), 2); + } + +} diff --git a/extensions/httpnio/pom.xml b/extensions/httpnio/pom.xml index ca8d0356fb..86e7791c8c 100644 --- a/extensions/httpnio/pom.xml +++ b/extensions/httpnio/pom.xml @@ -64,6 +64,7 @@ ${project.groupId} jclouds-core ${project.version} + provided org.apache.httpcomponents diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/config/HttpNioConnectionPoolClientModule.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/config/HttpNioConnectionPoolClientModule.java index 769add32e2..dee1439e55 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/config/HttpNioConnectionPoolClientModule.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/config/HttpNioConnectionPoolClientModule.java @@ -29,6 +29,7 @@ import org.apache.http.nio.NHttpConnection; import org.jclouds.command.pool.FutureCommandConnectionRetry; import org.jclouds.http.HttpConstants; import org.jclouds.http.HttpFutureCommandClient; +import org.jclouds.http.config.HttpFutureCommandClientModule; import org.jclouds.http.httpnio.config.internal.NonSSLHttpNioConnectionPoolClientModule; import org.jclouds.http.httpnio.config.internal.SSLHttpNioConnectionPoolClientModule; import org.jclouds.http.httpnio.pool.HttpNioConnectionPoolClient; @@ -45,6 +46,7 @@ import com.google.inject.name.Named; * * @author Adrian Cole */ +@HttpFutureCommandClientModule public class HttpNioConnectionPoolClientModule extends AbstractModule { @Named(HttpConstants.PROPERTY_HTTP_SECURE) diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioConnectionPoolClient.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioConnectionPoolClient.java index 34a6afb330..22eaa3b53e 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioConnectionPoolClient.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioConnectionPoolClient.java @@ -23,8 +23,11 @@ */ package org.jclouds.http.httpnio.pool; -import com.google.inject.Inject; -import com.google.inject.Singleton; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; + import org.apache.http.nio.NHttpConnection; import org.jclouds.command.FutureCommand; import org.jclouds.command.pool.FutureCommandConnectionPoolClient; @@ -33,46 +36,50 @@ import org.jclouds.http.HttpFutureCommandClient; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ExecutorService; -import java.util.logging.Logger; +import com.google.inject.Inject; +import com.google.inject.Singleton; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ @Singleton -public class HttpNioConnectionPoolClient extends FutureCommandConnectionPoolClient implements HttpFutureCommandClient { +public class HttpNioConnectionPoolClient extends + FutureCommandConnectionPoolClient implements + HttpFutureCommandClient { private List requestFilters = Collections.emptyList(); public List getRequestFilters() { - return requestFilters; + return requestFilters; } @Inject(optional = true) public void setRequestFilters(List requestFilters) { - this.requestFilters = requestFilters; + this.requestFilters = requestFilters; } @Override protected void invoke(O operation) { - HttpRequest request = (HttpRequest) operation.getRequest(); - try { - for (HttpRequestFilter filter : getRequestFilters()) { - filter.filter(request); - } - super.invoke(operation); - } catch (HttpException e) { - operation.setException(e); - } + HttpRequest request = (HttpRequest) operation.getRequest(); + try { + for (HttpRequestFilter filter : getRequestFilters()) { + filter.filter(request); + } + super.invoke(operation); + } catch (HttpException e) { + operation.setException(e); + } } @Inject - public HttpNioConnectionPoolClient(Logger logger, ExecutorService executor, HttpNioFutureCommandConnectionPool httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool, BlockingQueue commandQueue) { - super(logger, executor, httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool, commandQueue); // TODO: Adrian: Customise this generated block + public HttpNioConnectionPoolClient( + ExecutorService executor, + HttpNioFutureCommandConnectionPool httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool, + BlockingQueue commandQueue) { + super( + executor, + httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool, + commandQueue); } } - diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionHandle.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionHandle.java index 225273ad8b..7186b5a8ae 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionHandle.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionHandle.java @@ -23,38 +23,42 @@ */ package org.jclouds.http.httpnio.pool; -import com.google.inject.Inject; -import com.google.inject.assistedinject.Assisted; -import org.apache.http.nio.NHttpConnection; -import org.jclouds.command.FutureCommand; -import org.jclouds.command.pool.FutureCommandConnectionHandle; - import java.io.IOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Semaphore; +import org.apache.http.nio.NHttpConnection; +import org.jclouds.command.FutureCommand; +import org.jclouds.command.pool.FutureCommandConnectionHandle; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ -public class HttpNioFutureCommandConnectionHandle extends FutureCommandConnectionHandle { +public class HttpNioFutureCommandConnectionHandle extends + FutureCommandConnectionHandle { @Inject - public HttpNioFutureCommandConnectionHandle(java.util.logging.Logger logger, BlockingQueue available, Semaphore maxConnections, @Assisted NHttpConnection conn, @Assisted FutureCommand operation) throws InterruptedException { - super(logger, maxConnections, operation, conn, available); + public HttpNioFutureCommandConnectionHandle( + BlockingQueue available, Semaphore maxConnections, + @Assisted NHttpConnection conn, @Assisted FutureCommand operation) + throws InterruptedException { + super(maxConnections, operation, conn, available); } public void startConnection() { - conn.getContext().setAttribute("operation", operation); - logger.trace("invoking %1s on connection %2s", operation, conn); - conn.requestOutput(); + conn.getContext().setAttribute("operation", operation); + logger.trace("invoking %1s on connection %2s", operation, conn); + conn.requestOutput(); } public void shutdownConnection() throws IOException { - conn.shutdown(); + conn.shutdown(); } } - diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionPool.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionPool.java index de61d13911..2e8eef2b84 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionPool.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionPool.java @@ -39,7 +39,6 @@ import org.apache.http.nio.reactor.IOEventDispatch; import org.apache.http.nio.reactor.IOReactorStatus; import org.apache.http.nio.reactor.SessionRequest; import org.apache.http.nio.reactor.SessionRequestCallback; -import org.jclouds.Logger; import org.jclouds.command.FutureCommand; import org.jclouds.command.pool.FutureCommandConnectionPool; import org.jclouds.command.pool.FutureCommandConnectionRetry; @@ -64,7 +63,6 @@ public class HttpNioFutureCommandConnectionPool extends @Inject public HttpNioFutureCommandConnectionPool( - java.util.logging.Logger logger, ExecutorService executor, Semaphore allConnections, BlockingQueue available, @@ -76,9 +74,8 @@ public class HttpNioFutureCommandConnectionPool extends FutureCommandConnectionRetry futureCommandConnectionRetry, @Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE) int maxConnectionReuse, @Named(PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES) int maxSessionFailures) { - super(new Logger(logger), executor, futureCommandConnectionRetry, - allConnections, requestHandleFactory, maxConnectionReuse, - available); + super(executor, futureCommandConnectionRetry, allConnections, + requestHandleFactory, maxConnectionReuse, available); this.ioReactor = ioReactor; this.dispatch = dispatch; this.target = target; diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionRetry.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionRetry.java index e3ff8b8fd4..bb28d3ac30 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionRetry.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandConnectionRetry.java @@ -23,38 +23,45 @@ */ package org.jclouds.http.httpnio.pool; -import com.google.inject.Inject; -import org.apache.http.nio.NHttpConnection; -import org.jclouds.command.FutureCommand; -import org.jclouds.Logger; -import org.jclouds.command.pool.FutureCommandConnectionRetry; -import org.jclouds.command.pool.FutureCommandConnectionHandle; -import org.jclouds.http.httpnio.pool.HttpNioFutureCommandConnectionHandle; - import java.util.concurrent.BlockingQueue; import java.util.concurrent.atomic.AtomicInteger; -public class HttpNioFutureCommandConnectionRetry extends FutureCommandConnectionRetry { +import org.apache.http.nio.NHttpConnection; +import org.jclouds.command.FutureCommand; +import org.jclouds.command.pool.FutureCommandConnectionHandle; +import org.jclouds.command.pool.FutureCommandConnectionRetry; + +import com.google.inject.Inject; + +public class HttpNioFutureCommandConnectionRetry extends + FutureCommandConnectionRetry { @Inject - public HttpNioFutureCommandConnectionRetry(java.util.logging.Logger logger, BlockingQueue commandQueue, AtomicInteger errors) { - super(new Logger(logger), commandQueue, errors); + public HttpNioFutureCommandConnectionRetry( + BlockingQueue commandQueue, AtomicInteger errors) { + super(commandQueue, errors); } @Override - public void associateHandleWithConnection(FutureCommandConnectionHandle handle, NHttpConnection connection) { - connection.getContext().setAttribute("operation-handle", handle); - } - - @Override - public HttpNioFutureCommandConnectionHandle getHandleFromConnection(NHttpConnection connection) { - return (HttpNioFutureCommandConnectionHandle) connection.getContext().getAttribute("operation-handle"); + public void associateHandleWithConnection( + FutureCommandConnectionHandle handle, + NHttpConnection connection) { + connection.getContext().setAttribute("operation-handle", handle); } -// @Override -// public void incrementErrorCountAndRetry(FutureCommand operation) { -// ((HttpEntityEnclosingRequest) operation.getRequest()).removeHeaders(HTTP.CONTENT_LEN); -// ((HttpEntityEnclosingRequest) operation.getRequest()).removeHeaders(HTTP.DATE_HEADER); -// super.incrementErrorCountAndRetry(operation); -// } + @Override + public HttpNioFutureCommandConnectionHandle getHandleFromConnection( + NHttpConnection connection) { + return (HttpNioFutureCommandConnectionHandle) connection.getContext() + .getAttribute("operation-handle"); + } + + // @Override + // public void incrementErrorCountAndRetry(FutureCommand operation) { + // ((HttpEntityEnclosingRequest) + // operation.getRequest()).removeHeaders(HTTP.CONTENT_LEN); + // ((HttpEntityEnclosingRequest) + // operation.getRequest()).removeHeaders(HTTP.DATE_HEADER); + // super.incrementErrorCountAndRetry(operation); + // } } \ No newline at end of file diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandExecutionHandler.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandExecutionHandler.java index 587930812d..56de0c5e72 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandExecutionHandler.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/HttpNioFutureCommandExecutionHandler.java @@ -23,7 +23,11 @@ */ package org.jclouds.http.httpnio.pool; -import com.google.inject.Inject; +import java.io.IOException; +import java.util.concurrent.ExecutorService; + +import javax.annotation.Resource; + import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpResponse; @@ -32,117 +36,130 @@ import org.apache.http.nio.entity.ConsumingNHttpEntity; import org.apache.http.nio.protocol.NHttpRequestExecutionHandler; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; -import org.jclouds.Logger; import org.jclouds.command.FutureCommand; import org.jclouds.http.HttpFutureCommand; import org.jclouds.http.HttpRequest; import org.jclouds.http.httpnio.HttpNioUtils; +import org.jclouds.logging.Logger; -import java.io.IOException; -import java.util.concurrent.ExecutorService; - +import com.google.inject.Inject; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ -public class HttpNioFutureCommandExecutionHandler implements NHttpRequestExecutionHandler { +public class HttpNioFutureCommandExecutionHandler implements + NHttpRequestExecutionHandler { private final ExecutorService executor; - protected final Logger logger; + @Resource + protected Logger logger = Logger.NULL; private final ConsumingNHttpEntityFactory entityFactory; private final HttpNioFutureCommandConnectionRetry futureOperationRetry; public interface ConsumingNHttpEntityFactory { - public ConsumingNHttpEntity create(HttpEntity httpEntity); + public ConsumingNHttpEntity create(HttpEntity httpEntity); } @Inject - public HttpNioFutureCommandExecutionHandler(java.util.logging.Logger logger, ConsumingNHttpEntityFactory entityFactory, ExecutorService executor, HttpNioFutureCommandConnectionRetry futureOperationRetry) { - this.logger = new Logger(logger); - this.executor = executor; - this.entityFactory = entityFactory; - this.futureOperationRetry = futureOperationRetry; + public HttpNioFutureCommandExecutionHandler( + ConsumingNHttpEntityFactory entityFactory, + ExecutorService executor, + HttpNioFutureCommandConnectionRetry futureOperationRetry) { + this.executor = executor; + this.entityFactory = entityFactory; + this.futureOperationRetry = futureOperationRetry; } - public void initalizeContext(HttpContext context, Object attachment) { } public HttpEntityEnclosingRequest submitRequest(HttpContext context) { - HttpFutureCommand operation = (HttpFutureCommand) context.removeAttribute("operation"); - if (operation != null) { - //TODO determine why type is lost - HttpRequest object = (HttpRequest) operation.getRequest(); - return HttpNioUtils.convertToApacheRequest(object); - } - return null; + HttpFutureCommand operation = (HttpFutureCommand) context + .removeAttribute("operation"); + if (operation != null) { + // TODO determine why type is lost + HttpRequest object = (HttpRequest) operation.getRequest(); + return HttpNioUtils.convertToApacheRequest(object); + } + return null; } - public ConsumingNHttpEntity responseEntity(HttpResponse response, HttpContext context) throws IOException { - return entityFactory.create(response.getEntity()); + public ConsumingNHttpEntity responseEntity(HttpResponse response, + HttpContext context) throws IOException { + return entityFactory.create(response.getEntity()); } - - public void handleResponse(HttpResponse response, HttpContext context) throws IOException { - HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context.removeAttribute("operation-handle"); - if (handle != null) { - try { - FutureCommand command = handle.getOperation(); - int code = response.getStatusLine().getStatusCode(); - //normal codes for rest commands - if ((code >= 200 && code < 300) || code == 404) { - processResponse(response, command); - } else { - if (isRetryable(response)) { - futureOperationRetry.shutdownConnectionAndRetryOperation((NHttpClientConnection) context.getAttribute(ExecutionContext.HTTP_CONNECTION)); - } else { - operationFailed(command); - } - } - } finally { - releaseConnectionToPool(handle); - } - } else { - throw new IllegalStateException(String.format("No operation-handle associated with operation %1s", context)); - } + public void handleResponse(HttpResponse response, HttpContext context) + throws IOException { + HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context + .removeAttribute("operation-handle"); + if (handle != null) { + try { + FutureCommand command = handle.getOperation(); + int code = response.getStatusLine().getStatusCode(); + // normal codes for rest commands + if ((code >= 200 && code < 300) || code == 404) { + processResponse(response, command); + } else { + if (isRetryable(response)) { + futureOperationRetry + .shutdownConnectionAndRetryOperation((NHttpClientConnection) context + .getAttribute(ExecutionContext.HTTP_CONNECTION)); + } else { + operationFailed(command); + } + } + } finally { + releaseConnectionToPool(handle); + } + } else { + throw new IllegalStateException(String.format( + "No operation-handle associated with operation %1s", + context)); + } } protected boolean isRetryable(HttpResponse response) throws IOException { - int code = response.getStatusLine().getStatusCode(); - return code == 500 || code == 503; + int code = response.getStatusLine().getStatusCode(); + return code == 500 || code == 503; } - protected void releaseConnectionToPool(HttpNioFutureCommandConnectionHandle handle) { - try { - handle.release(); - } catch (InterruptedException e) { - logger.error(e, "Interrupted releasing handle %1s", handle); - } + protected void releaseConnectionToPool( + HttpNioFutureCommandConnectionHandle handle) { + try { + handle.release(); + } catch (InterruptedException e) { + logger.error(e, "Interrupted releasing handle %1s", handle); + } } protected void operationFailed(FutureCommand command) throws IOException { - String message = String.format("command failed: %1s", command); - logger.error(message); - command.getResponseFuture().setException(new IOException(message)); + String message = String.format("command failed: %1s", command); + logger.error(message); + command.getResponseFuture().setException(new IOException(message)); } - protected void processResponse(HttpResponse apacheResponse, FutureCommand command) throws IOException { - org.jclouds.http.HttpResponse response = HttpNioUtils.convertToJavaCloudsResponse(apacheResponse); - command.getResponseFuture().setResponse(response); - logger.trace("submitting response task %1s", command.getResponseFuture()); - executor.submit(command.getResponseFuture()); + protected void processResponse(HttpResponse apacheResponse, + FutureCommand command) throws IOException { + org.jclouds.http.HttpResponse response = HttpNioUtils + .convertToJavaCloudsResponse(apacheResponse); + command.getResponseFuture().setResponse(response); + logger.trace("submitting response task %1s", command + .getResponseFuture()); + executor.submit(command.getResponseFuture()); } public void finalizeContext(HttpContext context) { - HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context.removeAttribute("operation-handle"); - if (handle != null) { - try { - handle.cancel(); - } catch (Exception e) { - logger.error(e, "Error cancelling handle %1s", handle); - } - } + HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context + .removeAttribute("operation-handle"); + if (handle != null) { + try { + handle.cancel(); + } catch (Exception e) { + logger.error(e, "Error cancelling handle %1s", handle); + } + } } } \ No newline at end of file diff --git a/extensions/log4j/pom.xml b/extensions/log4j/pom.xml new file mode 100644 index 0000000000..6805e97f16 --- /dev/null +++ b/extensions/log4j/pom.xml @@ -0,0 +1,69 @@ + + + + + jclouds-project + org.jclouds + 1.0-SNAPSHOT + ../../project/pom.xml + + 4.0.0 + jclouds-log4j + jclouds log4j logging module + jar + Log4J logging module + + + scm:svn:http://jclouds.googlecode.com/svn/trunk/extensions/log4j + scm:svn:https://jclouds.googlecode.com/svn/trunk/extensions/log4j + http://jclouds.googlecode.com/svn/trunk/extensions/log4j + + + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + + + ${project.groupId} + jclouds-core + ${project.version} + provided + + + log4j + log4j + 1.2.14 + provided + + + diff --git a/extensions/log4j/src/main/java/org/jclouds/logging/log4j/Log4JLogger.java b/extensions/log4j/src/main/java/org/jclouds/logging/log4j/Log4JLogger.java new file mode 100644 index 0000000000..320bcd4fa9 --- /dev/null +++ b/extensions/log4j/src/main/java/org/jclouds/logging/log4j/Log4JLogger.java @@ -0,0 +1,112 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.log4j; + +import static org.apache.log4j.Level.ERROR; +import static org.apache.log4j.Level.WARN; + +import org.jclouds.logging.BaseLogger; +import org.jclouds.logging.Logger; + +/** + * {@link org.apache.log4j.Logger} implementation of {@link Logger}. + * + * @author Adrian Cole + * + */ +public class Log4JLogger extends BaseLogger { + private final org.apache.log4j.Logger logger; + private final String category; + + public static class Log4JLoggerFactory implements LoggerFactory { + public Logger getLogger(String category) { + return new Log4JLogger(category, org.apache.log4j.Logger + .getLogger(category)); + } + } + + public Log4JLogger(String category, org.apache.log4j.Logger logger) { + this.category = category; + this.logger = logger; + } + + @Override + protected void logTrace(String message) { + logger.trace(message); + } + + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + @Override + protected void logDebug(String message) { + logger.debug(message); + } + + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + protected void logInfo(String message) { + logger.info(message); + } + + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + protected void logWarn(String message) { + logger.warn(message); + } + + @Override + protected void logWarn(String message, Throwable e) { + logger.warn(message, e); + } + + public boolean isWarnEnabled() { + return logger.isEnabledFor(WARN); + } + + @Override + protected void logError(String message) { + logger.error(message); + } + + @Override + protected void logError(String message, Throwable e) { + logger.error(message, e); + } + + public boolean isErrorEnabled() { + return logger.isEnabledFor(ERROR); + } + + public String getCategory() { + return category; + } +} \ No newline at end of file diff --git a/extensions/log4j/src/main/java/org/jclouds/logging/log4j/config/Log4JLoggingModule.java b/extensions/log4j/src/main/java/org/jclouds/logging/log4j/config/Log4JLoggingModule.java new file mode 100644 index 0000000000..be5dbe4321 --- /dev/null +++ b/extensions/log4j/src/main/java/org/jclouds/logging/log4j/config/Log4JLoggingModule.java @@ -0,0 +1,42 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.log4j.config; + +import org.jclouds.logging.Logger.LoggerFactory; +import org.jclouds.logging.config.LoggingModule; +import org.jclouds.logging.log4j.Log4JLogger; + +/** + * Configures logging of type {@link Log4JLogger} + * + * @author Adrian Cole + * + */ +public class Log4JLoggingModule extends LoggingModule { + + @Override + public LoggerFactory createLoggerFactory() { + return new Log4JLogger.Log4JLoggerFactory(); + } +} diff --git a/extensions/log4j/src/test/java/org/jclouds/logging/log4j/config/Log4JLoggingModuleTest.java b/extensions/log4j/src/test/java/org/jclouds/logging/log4j/config/Log4JLoggingModuleTest.java new file mode 100644 index 0000000000..2da43672b1 --- /dev/null +++ b/extensions/log4j/src/test/java/org/jclouds/logging/log4j/config/Log4JLoggingModuleTest.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.logging.log4j.config; + +import static org.testng.Assert.*; + +import javax.annotation.Resource; + +import org.jclouds.logging.Logger; +import org.jclouds.logging.log4j.Log4JLogger; +import org.testng.annotations.Test; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +@Test +public class Log4JLoggingModuleTest { + + static class A { + @Resource + Logger logger = Logger.NULL; + } + + @Test + public void testConfigure() { + Injector i = Guice.createInjector(new Log4JLoggingModule()); + A a = i.getInstance(A.class); + assertEquals(a.logger.getClass(), Log4JLogger.class); + assertEquals(a.logger.getCategory(), getClass().getName() + "$A"); + } + +} diff --git a/extensions/s3nio/pom.xml b/extensions/s3nio/pom.xml index 82042a4a2e..f1e438365c 100644 --- a/extensions/s3nio/pom.xml +++ b/extensions/s3nio/pom.xml @@ -61,6 +61,7 @@ ${project.groupId} jclouds-s3 ${project.version} + provided ${project.groupId} diff --git a/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandler.java b/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandler.java index 862b88f1c0..34f9090ce3 100644 --- a/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandler.java +++ b/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandler.java @@ -23,64 +23,68 @@ */ package org.jclouds.aws.s3.nio; -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; -import org.apache.http.HttpEntity; -import org.apache.http.nio.entity.NStringEntity; -import org.apache.http.entity.InputStreamEntity; -import org.jclouds.http.httpnio.pool.HttpNioFutureCommandConnectionRetry; -import org.jclouds.http.httpnio.pool.HttpNioFutureCommandExecutionHandler; - import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ExecutorService; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.nio.entity.NStringEntity; +import org.jclouds.http.httpnio.pool.HttpNioFutureCommandConnectionRetry; +import org.jclouds.http.httpnio.pool.HttpNioFutureCommandExecutionHandler; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ @Singleton -public class S3HttpNioFutureCommandExecutionHandler extends HttpNioFutureCommandExecutionHandler { +public class S3HttpNioFutureCommandExecutionHandler extends + HttpNioFutureCommandExecutionHandler { @Inject - public S3HttpNioFutureCommandExecutionHandler(java.util.logging.Logger logger, ConsumingNHttpEntityFactory entityFactory, ExecutorService executor, HttpNioFutureCommandConnectionRetry futureOperationRetry) { - super(logger, entityFactory, executor, futureOperationRetry); + public S3HttpNioFutureCommandExecutionHandler( + ConsumingNHttpEntityFactory entityFactory, + ExecutorService executor, + HttpNioFutureCommandConnectionRetry futureOperationRetry) { + super(entityFactory, executor, futureOperationRetry); } @Override protected boolean isRetryable(HttpResponse response) throws IOException { - if (super.isRetryable(response)) - return true; - int code = response.getStatusLine().getStatusCode(); - if (code == 409) { - return true; - } else if (code == 400) { - if (response.getEntity() != null) { - InputStream input = response.getEntity().getContent(); - if (input != null) { - String reason = null; - try { - reason = IOUtils.toString(input); - } finally { - IOUtils.closeQuietly(input); - } - if (reason != null) { - try { - if (reason.indexOf("RequestTime") >= 0) return true; - } finally { - IOUtils.closeQuietly(input); - response.setEntity(new NStringEntity(reason)); - } - } + if (super.isRetryable(response)) + return true; + int code = response.getStatusLine().getStatusCode(); + if (code == 409) { + return true; + } else if (code == 400) { + if (response.getEntity() != null) { + InputStream input = response.getEntity().getContent(); + if (input != null) { + String reason = null; + try { + reason = IOUtils.toString(input); + } finally { + IOUtils.closeQuietly(input); + } + if (reason != null) { + try { + if (reason.indexOf("RequestTime") >= 0) + return true; + } finally { + IOUtils.closeQuietly(input); + response.setEntity(new NStringEntity(reason)); + } + } - } + } - } - } - return false; + } + } + return false; } } diff --git a/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/config/S3HttpNioConnectionPoolClientModule.java b/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/config/S3HttpNioConnectionPoolClientModule.java index 91b8da7802..557bf16321 100644 --- a/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/config/S3HttpNioConnectionPoolClientModule.java +++ b/extensions/s3nio/src/main/java/org/jclouds/aws/s3/nio/config/S3HttpNioConnectionPoolClientModule.java @@ -23,25 +23,29 @@ */ package org.jclouds.aws.s3.nio.config; -import com.google.inject.AbstractModule; -import com.google.inject.Scopes; -import com.google.inject.util.Modules; import org.apache.http.nio.protocol.NHttpRequestExecutionHandler; import org.jclouds.aws.s3.nio.S3HttpNioFutureCommandExecutionHandler; +import org.jclouds.http.config.HttpFutureCommandClientModule; import org.jclouds.http.httpnio.config.HttpNioConnectionPoolClientModule; +import com.google.inject.AbstractModule; +import com.google.inject.util.Modules; + /** - * This installs a {@link HttpNioConnectionPoolClientModule}, but overrides it binding {@link S3HttpNioFutureCommandExecutionHandler}. - * + * This installs a {@link HttpNioConnectionPoolClientModule}, but overrides it + * binding {@link S3HttpNioFutureCommandExecutionHandler}. + * * @author Adrian Cole */ +@HttpFutureCommandClientModule public class S3HttpNioConnectionPoolClientModule extends AbstractModule { protected void configure() { - install(Modules.override(new HttpNioConnectionPoolClientModule()).with(new AbstractModule() { - protected void configure() { - bind(NHttpRequestExecutionHandler.class).to(S3HttpNioFutureCommandExecutionHandler.class); - } - })); + install(Modules.override(new HttpNioConnectionPoolClientModule()).with( + new AbstractModule() { + protected void configure() { + bind(NHttpRequestExecutionHandler.class).to( + S3HttpNioFutureCommandExecutionHandler.class); + } + })); } } - diff --git a/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandlerTest.java b/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandlerTest.java index 9547736390..6fb09a93ef 100644 --- a/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandlerTest.java +++ b/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/S3HttpNioFutureCommandExecutionHandlerTest.java @@ -23,24 +23,28 @@ */ package org.jclouds.aws.s3.nio; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import java.io.IOException; +import java.util.concurrent.ExecutorService; + import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.nio.entity.NStringEntity; -import static org.easymock.EasyMock.expect; -import static org.easymock.classextension.EasyMock.*; import org.jclouds.http.httpnio.pool.HttpNioFutureCommandConnectionRetry; import org.jclouds.http.httpnio.pool.HttpNioFutureCommandExecutionHandler; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import java.io.IOException; -import java.util.concurrent.ExecutorService; - /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ @Test @@ -51,91 +55,93 @@ public class S3HttpNioFutureCommandExecutionHandlerTest { @BeforeMethod public void createHandler() { - handler = new S3HttpNioFutureCommandExecutionHandler(createMock( - java.util.logging.Logger.class), createMock(HttpNioFutureCommandExecutionHandler.ConsumingNHttpEntityFactory.class), - createMock(ExecutorService.class), - createMock(HttpNioFutureCommandConnectionRetry.class)); - response = createMock(HttpResponse.class); - statusline = createMock(StatusLine.class); - expect(response.getStatusLine()).andReturn(statusline).atLeastOnce(); + handler = new S3HttpNioFutureCommandExecutionHandler( + createMock(HttpNioFutureCommandExecutionHandler.ConsumingNHttpEntityFactory.class), + createMock(ExecutorService.class), + createMock(HttpNioFutureCommandConnectionRetry.class)); + response = createMock(HttpResponse.class); + statusline = createMock(StatusLine.class); + expect(response.getStatusLine()).andReturn(statusline).atLeastOnce(); } @Test void test500isRetryable() throws IOException { - isRetryable(500); + isRetryable(500); } @Test void test503isRetryable() throws IOException { - isRetryable(503); + isRetryable(503); } @Test void test409isRetryable() throws IOException { - isRetryable(409); + isRetryable(409); } @Test void test404NotRetryable() throws IOException { - expect(statusline.getStatusCode()).andReturn(404).atLeastOnce(); + expect(statusline.getStatusCode()).andReturn(404).atLeastOnce(); - replay(statusline); - replay(response); - assert !handler.isRetryable(response); - verify(statusline); - verify(response); + replay(statusline); + replay(response); + assert !handler.isRetryable(response); + verify(statusline); + verify(response); } @Test void test400WithNoEnitityNotRetryable() throws IOException { - expect(statusline.getStatusCode()).andReturn(400).atLeastOnce(); - expect(response.getEntity()).andReturn(null); - replay(statusline); - replay(response); - assert !handler.isRetryable(response); - verify(statusline); - verify(response); + expect(statusline.getStatusCode()).andReturn(400).atLeastOnce(); + expect(response.getEntity()).andReturn(null); + replay(statusline); + replay(response); + assert !handler.isRetryable(response); + verify(statusline); + verify(response); } @Test void test400WithIrrelevantEnitityNotRetryable() throws IOException { - expect(statusline.getStatusCode()).andReturn(400).atLeastOnce(); - HttpEntity entity = createMock(HttpEntity.class); - expect(response.getEntity()).andReturn(entity).atLeastOnce(); - expect(entity.getContent()).andReturn(IOUtils.toInputStream("hello")); - response.setEntity(isA(NStringEntity.class)); - replay(entity); - replay(statusline); - replay(response); - assert !handler.isRetryable(response); - verify(statusline); - verify(response); - verify(entity); + expect(statusline.getStatusCode()).andReturn(400).atLeastOnce(); + HttpEntity entity = createMock(HttpEntity.class); + expect(response.getEntity()).andReturn(entity).atLeastOnce(); + expect(entity.getContent()).andReturn(IOUtils.toInputStream("hello")); + response.setEntity(isA(NStringEntity.class)); + replay(entity); + replay(statusline); + replay(response); + assert !handler.isRetryable(response); + verify(statusline); + verify(response); + verify(entity); } @Test - void test400WithRequestTimeTooSkewedTimeEnitityRetryable() throws IOException { - expect(statusline.getStatusCode()).andReturn(400).atLeastOnce(); - HttpEntity entity = createMock(HttpEntity.class); - expect(response.getEntity()).andReturn(entity).atLeastOnce(); - expect(entity.getContent()).andReturn(IOUtils.toInputStream("RequestTimeTooSkewed")); - response.setEntity(isA(NStringEntity.class)); - replay(entity); - replay(statusline); - replay(response); - assert handler.isRetryable(response); - verify(statusline); - verify(response); - verify(entity); + void test400WithRequestTimeTooSkewedTimeEnitityRetryable() + throws IOException { + expect(statusline.getStatusCode()).andReturn(400).atLeastOnce(); + HttpEntity entity = createMock(HttpEntity.class); + expect(response.getEntity()).andReturn(entity).atLeastOnce(); + expect(entity.getContent()).andReturn( + IOUtils.toInputStream("RequestTimeTooSkewed")); + response.setEntity(isA(NStringEntity.class)); + replay(entity); + replay(statusline); + replay(response); + assert handler.isRetryable(response); + verify(statusline); + verify(response); + verify(entity); } private void isRetryable(int code) throws IOException { - expect(statusline.getStatusCode()).andReturn(code).atLeastOnce(); - replay(statusline); - replay(response); - assert handler.isRetryable(response); - verify(statusline); - verify(response); + expect(statusline.getStatusCode()).andReturn(code).atLeastOnce(); + replay(statusline); + replay(response); + assert handler.isRetryable(response); + verify(statusline); + verify(response); } } \ No newline at end of file diff --git a/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java b/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java index dac5f64e6e..a4f3d8ca4b 100644 --- a/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java +++ b/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java @@ -35,14 +35,16 @@ import java.net.URL; import java.util.Collections; import java.util.List; +import javax.annotation.Resource; + import org.apache.commons.io.IOUtils; -import org.jclouds.Logger; import org.jclouds.command.FutureCommand; import org.jclouds.http.HttpConstants; import org.jclouds.http.HttpFutureCommandClient; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpResponse; +import org.jclouds.logging.Logger; import com.google.appengine.api.urlfetch.HTTPHeader; import com.google.appengine.api.urlfetch.HTTPMethod; @@ -60,7 +62,8 @@ import com.google.inject.Inject; public class URLFetchServiceClient implements HttpFutureCommandClient { private final URL target; private List requestFilters = Collections.emptyList(); - private final Logger logger; + @Resource + private Logger logger = Logger.NULL; private final URLFetchService urlFetchService; public List getRequestFilters() { @@ -73,10 +76,9 @@ public class URLFetchServiceClient implements HttpFutureCommandClient { } @Inject - public URLFetchServiceClient(java.util.logging.Logger logger, URL target, - URLFetchService urlFetchService) throws MalformedURLException { + public URLFetchServiceClient(URL target, URLFetchService urlFetchService) + throws MalformedURLException { this.urlFetchService = urlFetchService; - this.logger = new Logger(logger); this.target = target; this.logger.info("configured to connect to target: %1s", target); } diff --git a/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java b/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java index 5545bc5933..220780dc7a 100644 --- a/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java +++ b/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java @@ -29,6 +29,7 @@ import java.net.URL; import org.jclouds.gae.URLFetchServiceClient; import org.jclouds.http.HttpConstants; import org.jclouds.http.HttpFutureCommandClient; +import org.jclouds.http.config.HttpFutureCommandClientModule; import com.google.appengine.api.urlfetch.URLFetchService; import com.google.appengine.api.urlfetch.URLFetchServiceFactory; @@ -42,6 +43,7 @@ import com.google.inject.name.Named; * * @author Adrian Cole */ +@HttpFutureCommandClientModule public class URLFetchServiceClientModule extends AbstractModule { @Override diff --git a/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java b/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java index 7ba3bbbbf7..f3fc1ce46c 100644 --- a/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java +++ b/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java @@ -23,11 +23,11 @@ */ package org.jclouds.gae; -import static org.testng.Assert.*; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.createNiceMock; import static org.easymock.classextension.EasyMock.replay; +import static org.testng.Assert.assertEquals; import java.io.File; import java.io.FileOutputStream; @@ -64,8 +64,7 @@ public class URLFetchServiceClientTest { @BeforeTest void setupClient() throws MalformedURLException { url = new URL("http://localhost:80"); - client = new URLFetchServiceClient( - createNiceMock(java.util.logging.Logger.class), url, + client = new URLFetchServiceClient(url, createNiceMock(URLFetchService.class)); } diff --git a/pom.xml b/pom.xml index 5925545954..b79d9b5aee 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ core extensions/httpnio extensions/s3nio + extensions/log4j gae s3 diff --git a/s3/src/main/java/org/jclouds/aws/s3/S3ContextFactory.java b/s3/src/main/java/org/jclouds/aws/s3/S3ContextFactory.java index 6c4ee48d78..eeba337f43 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/S3ContextFactory.java +++ b/s3/src/main/java/org/jclouds/aws/s3/S3ContextFactory.java @@ -35,22 +35,26 @@ import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS; import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_PORT; import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Properties; import org.jclouds.aws.s3.config.S3ContextModule; -import org.jclouds.http.HttpFutureCommandClient; +import org.jclouds.http.config.HttpFutureCommandClientModule; import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule; +import org.jclouds.logging.config.LoggingModule; +import org.jclouds.logging.jdk.config.JDKLoggingModule; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.name.Names; - /** * Creates {@link S3Context} or {@link Injector} instances based on the most * commonly requested arguments. @@ -160,28 +164,49 @@ public class S3ContextFactory { /** * Bind the given properties and install the list of modules. If no modules - * are specified, install the default + * are specified, install the default {@link JDKLoggingModule} * {@link JavaUrlHttpFutureCommandClientModule} * * @param properties * - contains constants used by jclouds * {@link #DEFAULT_PROPERTIES} - * @param httpModules - * - modules that must bind {@link HttpFutureCommandClient} if - * specified - * */ + * @param configModules + * - alternative configuration modules + */ public static Injector createInjector(final Properties properties, - Module... httpModules) { - final List modules = httpModules.length != 0 ? Arrays - .asList(httpModules) : Collections - .singletonList(new JavaUrlHttpFutureCommandClientModule()); + Module... configModules) { + final List modules = Lists.newArrayList(configModules); + + addLoggingModuleIfNotPresent(modules); + + addHttpModuleIfNotPresent(modules); + return Guice.createInjector(new AbstractModule() { @Override protected void configure() { - Names.bindProperties(binder(), checkNotNull(properties,"properties")); + Names.bindProperties(binder(), checkNotNull(properties, + "properties")); for (Module module : modules) install(module); } }, new S3ContextModule()); } + + @VisibleForTesting + static void addHttpModuleIfNotPresent(final List modules) { + if (!Iterables.any(modules, new Predicate() { + public boolean apply(Module input) { + return input.getClass().isAnnotationPresent( + HttpFutureCommandClientModule.class); + } + + })) + modules.add(new JavaUrlHttpFutureCommandClientModule()); + } + + @VisibleForTesting + static void addLoggingModuleIfNotPresent(final List modules) { + if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class))) + modules.add(new JDKLoggingModule()); + } } diff --git a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallable.java b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallable.java index 90459c12ca..d9434cae28 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallable.java +++ b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallable.java @@ -26,7 +26,6 @@ package org.jclouds.aws.s3.commands.callables; import java.io.IOException; import java.io.InputStream; -import org.jclouds.Logger; import org.jclouds.Utils; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; @@ -42,8 +41,8 @@ public class CopyObjectCallable extends HttpFutureCommand.ResponseCallable { @Inject - public CopyObjectCallable(java.util.logging.Logger logger) { - super(new Logger(logger)); + public CopyObjectCallable() { + super(); } public Boolean call() throws HttpException { @@ -57,7 +56,7 @@ public class CopyObjectCallable extends } throw new HttpException("Error copying source " + reason); } else if (getResponse().getStatusCode() == 200) { - String response = null; + String response; InputStream content = getResponse().getContent(); if (content != null) { try { diff --git a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteBucketCallable.java b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteBucketCallable.java index 699727f8cc..8f7bd548c1 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteBucketCallable.java +++ b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteBucketCallable.java @@ -23,42 +23,34 @@ */ package org.jclouds.aws.s3.commands.callables; -import com.google.inject.Inject; +import java.io.IOException; + import org.jclouds.aws.s3.S3Utils; import org.jclouds.http.HttpException; -import java.io.IOException; - /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ public class DeleteBucketCallable extends DeleteCallable { - private final S3Utils s3Utils; - - @Inject - public DeleteBucketCallable(java.util.logging.Logger logger, S3Utils s3Utils) { - super(logger); - this.s3Utils = s3Utils; - } - public Boolean call() throws HttpException { - if (getResponse().getStatusCode() == 404) { - return true; - } else if (getResponse().getStatusCode() == 409) { - try { - String reason = s3Utils.toStringAndClose(getResponse().getContent()); - if (reason.indexOf("BucketNotEmpty") >= 0) - return false; - else - throw new HttpException("Error deleting bucket.\n" + reason); - } catch (IOException e) { - throw new HttpException("Error deleting bucket", e); - } - } else { - return super.call(); - } + if (getResponse().getStatusCode() == 404) { + return true; + } else if (getResponse().getStatusCode() == 409) { + try { + String reason = S3Utils.toStringAndClose(getResponse() + .getContent()); + if (reason.indexOf("BucketNotEmpty") >= 0) + return false; + else + throw new HttpException("Error deleting bucket.\n" + reason); + } catch (IOException e) { + throw new HttpException("Error deleting bucket", e); + } + } else { + return super.call(); + } } } \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteCallable.java b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteCallable.java index b1c36a54ac..2f380b8c12 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteCallable.java +++ b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/DeleteCallable.java @@ -23,28 +23,21 @@ */ package org.jclouds.aws.s3.commands.callables; -import com.google.inject.Inject; -import org.jclouds.Logger; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ public class DeleteCallable extends HttpFutureCommand.ResponseCallable { - @Inject - public DeleteCallable(java.util.logging.Logger logger) { - super(new Logger(logger)); - } - public Boolean call() throws HttpException { - if (getResponse().getStatusCode() == 204) { - return true; - } else { - throw new HttpException("Error deleting bucket " + getResponse()); - } + if (getResponse().getStatusCode() == 204) { + return true; + } else { + throw new HttpException("Error deleting bucket " + getResponse()); + } } } \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutBucketCallable.java b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutBucketCallable.java index 45f4b17486..3b70869be3 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutBucketCallable.java +++ b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutBucketCallable.java @@ -23,30 +23,24 @@ */ package org.jclouds.aws.s3.commands.callables; -import com.google.inject.Inject; -import org.jclouds.Logger; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ -public class PutBucketCallable extends HttpFutureCommand.ResponseCallable { - - @Inject - public PutBucketCallable(java.util.logging.Logger logger) { - super(new Logger(logger)); - } +public class PutBucketCallable extends + HttpFutureCommand.ResponseCallable { public Boolean call() throws HttpException { - if (getResponse().getStatusCode() == 200) { - return true; - } else if (getResponse().getStatusCode() == 404) { - return false; - } else { - throw new HttpException("Error checking bucket " + getResponse()); - } + if (getResponse().getStatusCode() == 200) { + return true; + } else if (getResponse().getStatusCode() == 404) { + return false; + } else { + throw new HttpException("Error checking bucket " + getResponse()); + } } } \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutObjectCallable.java b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutObjectCallable.java index 3c67609f03..378dc6d1d9 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutObjectCallable.java +++ b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/PutObjectCallable.java @@ -25,43 +25,36 @@ package org.jclouds.aws.s3.commands.callables; import java.io.IOException; -import org.jclouds.Logger; import org.jclouds.aws.s3.S3Utils; import org.jclouds.http.HttpException; import org.jclouds.http.HttpFutureCommand; -import com.google.inject.Inject; - /** * // TODO: Adrian: Document this! - * + * * @author Adrian Cole */ -public class PutObjectCallable extends HttpFutureCommand.ResponseCallable { - - private final S3Utils s3Utils; - - @Inject - public PutObjectCallable(java.util.logging.Logger logger, S3Utils s3Utils) { - super(new Logger(logger)); - this.s3Utils = s3Utils; - } +public class PutObjectCallable extends + HttpFutureCommand.ResponseCallable { public String call() throws HttpException { - if (getResponse().getStatusCode() == 200) { - try { - getResponse().getContent().close(); - } catch (IOException e) { - logger.error(e, "error consuming content"); - } - return getResponse().getHeaders().get("ETag").iterator().next(); - } else { - try { - String reason = s3Utils.toStringAndClose(getResponse().getContent()); - throw new HttpException(getResponse().getStatusCode() + ": Problem uploading content.\n" + reason); - } catch (IOException e) { - throw new HttpException(getResponse().getStatusCode() + ": Problem uploading content", e); - } - } + if (getResponse().getStatusCode() == 200) { + try { + getResponse().getContent().close(); + } catch (IOException e) { + logger.error(e, "error consuming content"); + } + return getResponse().getHeaders().get("ETag").iterator().next(); + } else { + try { + String reason = S3Utils.toStringAndClose(getResponse() + .getContent()); + throw new HttpException(getResponse().getStatusCode() + + ": Problem uploading content.\n" + reason); + } catch (IOException e) { + throw new HttpException(getResponse().getStatusCode() + + ": Problem uploading content", e); + } + } } } \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/RetrieveObjectCallable.java b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/RetrieveObjectCallable.java index 7f4db4cce5..da8a54416b 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/commands/callables/RetrieveObjectCallable.java +++ b/s3/src/main/java/org/jclouds/aws/s3/commands/callables/RetrieveObjectCallable.java @@ -25,7 +25,6 @@ package org.jclouds.aws.s3.commands.callables; import java.io.IOException; -import org.jclouds.Logger; import org.jclouds.Utils; import org.jclouds.aws.s3.DateService; import org.jclouds.aws.s3.domain.S3Object; @@ -45,9 +44,7 @@ public class RetrieveObjectCallable extends private String key; @Inject - public RetrieveObjectCallable(java.util.logging.Logger logger, - DateService dateParser) { - super(new Logger(logger)); + public RetrieveObjectCallable(DateService dateParser) { this.dateParser = dateParser; } diff --git a/s3/src/main/java/org/jclouds/aws/s3/internal/GuiceS3Context.java b/s3/src/main/java/org/jclouds/aws/s3/internal/GuiceS3Context.java index c7306c17a6..2c3603b464 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/internal/GuiceS3Context.java +++ b/s3/src/main/java/org/jclouds/aws/s3/internal/GuiceS3Context.java @@ -25,13 +25,15 @@ package org.jclouds.aws.s3.internal; import java.io.IOException; -import org.jclouds.Logger; +import javax.annotation.Resource; + import org.jclouds.aws.s3.S3Connection; import org.jclouds.aws.s3.S3Context; import org.jclouds.aws.s3.S3InputStreamMap; import org.jclouds.aws.s3.S3ObjectMap; import org.jclouds.aws.s3.domain.S3Bucket; import org.jclouds.lifecycle.Closer; +import org.jclouds.logging.Logger; import com.google.inject.Inject; import com.google.inject.Injector; @@ -50,17 +52,17 @@ public class GuiceS3Context implements S3Context { S3InputStreamMap createMapView(S3Bucket bucket); } - private final Logger logger; + @Resource + private Logger logger = Logger.NULL; private final Injector injector; private final S3InputStreamMapFactory s3InputStreamMapFactory; private final S3ObjectMapFactory s3ObjectMapFactory; private final Closer closer; @Inject - private GuiceS3Context(java.util.logging.Logger logger, Injector injector, - Closer closer, S3ObjectMapFactory s3ObjectMapFactory, + private GuiceS3Context(Injector injector, Closer closer, + S3ObjectMapFactory s3ObjectMapFactory, S3InputStreamMapFactory s3InputStreamMapFactory) { - this.logger = new Logger(logger); this.injector = injector; this.s3InputStreamMapFactory = s3InputStreamMapFactory; this.s3ObjectMapFactory = s3ObjectMapFactory; diff --git a/s3/src/test/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallableTest.java b/s3/src/test/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallableTest.java index 2b052c721b..6621fc79d9 100644 --- a/s3/src/test/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallableTest.java +++ b/s3/src/test/java/org/jclouds/aws/s3/commands/callables/CopyObjectCallableTest.java @@ -32,7 +32,6 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import java.util.logging.Logger; import org.apache.commons.io.IOUtils; import org.jclouds.http.HttpFutureCommand; @@ -48,7 +47,7 @@ public class CopyObjectCallableTest { @BeforeMethod void setUp() { - callable = new CopyObjectCallable(createMock(Logger.class)); + callable = new CopyObjectCallable(); } @AfterMethod