Issue 8: Removed direct dependencies on java.util.logging, LoggingModules are now used to select logging

git-svn-id: http://jclouds.googlecode.com/svn/trunk@251 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-05-04 20:19:42 +00:00
parent 3b70fd807d
commit c5486f6c5e
53 changed files with 1872 additions and 742 deletions

View File

@ -23,14 +23,17 @@
*/
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!
*
@ -43,62 +46,65 @@ public abstract class FutureCommandConnectionHandle<C> {
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<C> 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<C> 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();
}
}

View File

@ -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<C> extends BaseLifeCycle {
protected volatile boolean hitBottom = false;
public FutureCommandConnectionPool(
Logger logger,
ExecutorService executor,
FutureCommandConnectionRetry<C> futureCommandConnectionRetry,
Semaphore allConnections,
FutureCommandConnectionHandleFactory<C> futureCommandConnectionHandleFactory,
@Named("maxConnectionReuse") int maxConnectionReuse,
BlockingQueue<C> available, BaseLifeCycle... dependencies) {
super(logger, executor, dependencies);
super(executor, dependencies);
this.futureCommandConnectionRetry = futureCommandConnectionRetry;
this.allConnections = allConnections;
this.futureCommandConnectionHandleFactory = futureCommandConnectionHandleFactory;

View File

@ -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<C> extends BaseLifeCycle
private final BlockingQueue<FutureCommand> commandQueue;
@Inject
public FutureCommandConnectionPoolClient(java.util.logging.Logger logger,
ExecutorService executor,
public FutureCommandConnectionPoolClient(ExecutorService executor,
FutureCommandConnectionPool<C> futureCommandConnectionPool,
BlockingQueue<FutureCommand> commandQueue) {
super(new Logger(logger), executor, futureCommandConnectionPool);
super(executor, futureCommandConnectionPool);
this.futureCommandConnectionPool = futureCommandConnectionPool;
this.commandQueue = commandQueue;
}

View File

@ -27,8 +27,10 @@ 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!
@ -38,36 +40,40 @@ import org.jclouds.command.FutureCommand;
public abstract class FutureCommandConnectionRetry<C> {
protected final BlockingQueue<FutureCommand> commandQueue;
protected final AtomicInteger errors;
protected final Logger logger;
@Resource
protected Logger logger = Logger.NULL;
public FutureCommandConnectionRetry(Logger logger, BlockingQueue<FutureCommand> commandQueue, AtomicInteger errors) {
this.logger = logger;
this.commandQueue = commandQueue;
this.errors = errors;
public FutureCommandConnectionRetry(
BlockingQueue<FutureCommand> commandQueue, AtomicInteger errors) {
this.commandQueue = commandQueue;
this.errors = errors;
}
public abstract void associateHandleWithConnection(FutureCommandConnectionHandle<C> handle, C connection);
public abstract void associateHandleWithConnection(
FutureCommandConnectionHandle<C> handle, C connection);
public abstract FutureCommandConnectionHandle<C> getHandleFromConnection(C connection);
public abstract FutureCommandConnectionHandle<C> getHandleFromConnection(
C connection);
public boolean shutdownConnectionAndRetryOperation(C connection) {
FutureCommandConnectionHandle<C> 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<C> 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);
}
}

View File

@ -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<T> extends
*/
public abstract static class ResponseCallable<T> implements
FutureCommand.ResponseCallable<HttpResponse, T> {
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;

View File

@ -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<HttpRequestFilter> requestFilters = Collections.emptyList();
private Logger logger;
@Resource
private Logger logger = Logger.NULL;
public List<HttpRequestFilter> 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 <O extends FutureCommand> void submit(O operation) {

View File

@ -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<String> {
public class ReturnStringIf200 extends
HttpFutureCommand.ResponseCallable<String> {
@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()));
}
}
}

View File

@ -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<Boolean> {
public class ReturnTrueIf200 extends
HttpFutureCommand.ResponseCallable<Boolean> {
@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());
}
}
}

View File

@ -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<T> extends HttpFutureCommand.ResponseCallable<T> {
private boolean suckFirst = false;
@Inject
public ParseSax(java.util.logging.Logger logger, XMLReader parser,
@Assisted HandlerWithResult<T> handler) {
super(new Logger(checkNotNull(logger, "logger")));
public ParseSax(XMLReader parser, @Assisted HandlerWithResult<T> handler) {
super();
this.parser = checkNotNull(parser, "parser");
this.handler = checkNotNull(handler, "handler");
}

View File

@ -0,0 +1,44 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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 {
}

View File

@ -40,6 +40,7 @@ import com.google.inject.name.Named;
*
* @author Adrian Cole
*/
@HttpFutureCommandClientModule
public class JavaUrlHttpFutureCommandClientModule extends AbstractModule {
@Override

View File

@ -23,12 +23,14 @@
*/
package org.jclouds.lifecycle;
import org.jclouds.Logger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Resource;
import org.jclouds.logging.Logger;
/**
* // TODO: Adrian: Document this!
@ -36,38 +38,39 @@ import java.util.concurrent.atomic.AtomicReference;
* @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> exception = new AtomicReference<Exception>();
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));
}
}

View File

@ -0,0 +1,83 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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);
}
}

View File

@ -0,0 +1,89 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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.
* <p/>
* Implementations of logging are optional and injected if they are configured.
* <p/>
* <code> @Resource Logger logger = Logger.NULL;</code> The above will get you a
* null-safe instance of <tt>Logger</tt>. 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.
* <p/>
* If you wish to initialize loggers like these yourself, do not use the @Resource
* annotation.
* <p/>
* This implementation first checks to see if the level is enabled before
* issuing the log command. In other words, don't do the following
* <code>if (logger.isTraceEnabled()) logger.trace("message");.
* <p/>
*
* @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);
}
}

View File

@ -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);
}
/**
* <tt>Logger</tt> that doesn't do anything.
* <p />
* 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) {
}
}

View File

@ -0,0 +1,147 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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:
* <pre>
* 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
* </pre>
*
* @author Adrian Cole
*
*/
public class BindLoggersAnnotatedWithResource implements TypeListener {
static class AssignLoggerToField<I> implements InjectionListener<I> {
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<Field, Field> {
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 <I> void hear(TypeLiteral<I> injectableType,
TypeEncounter<I> encounter) {
Class<? super I> type = injectableType.getRawType();
Set<Field> loggerFields = getLoggerFieldsAnnotatedWithResource(type);
if (loggerFields.size() == 0)
return;
Logger logger = loggerFactory.getLogger(type.getName());
for (Field field : loggerFields) {
encounter.register(new AssignLoggerToField<I>(logger, field));
}
}
@VisibleForTesting
Set<Field> getLoggerFieldsAnnotatedWithResource(Class<?> declaredType) {
Set<Field> fields = new HashSet<Field>();
Class<?> type = declaredType;
while (type != null) {
fields.addAll(Arrays.asList(type.getDeclaredFields()));
type = type.getSuperclass();
}
Set<Field> loggerFields = Sets.newHashSet(Iterables.transform(fields,
new LoggerFieldsAnnotatedWithResource()));
loggerFields.remove(null);
return loggerFields;
}
}

View File

@ -0,0 +1,49 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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();
}

View File

@ -0,0 +1,43 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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;
}
};
}
}

View File

@ -0,0 +1,108 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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();
}
}

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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();
}
}

View File

@ -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<List<HttpRequestFilter>>() {

View File

@ -23,14 +23,11 @@
*/
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!
*
@ -40,27 +37,26 @@ import java.util.logging.Logger;
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");
}
}

View File

@ -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);
}
}

View File

@ -23,17 +23,26 @@
*/
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!
@ -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;
}

View File

@ -0,0 +1,148 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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<A> assigner = new AssignLoggerToField<A>(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<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(this
.getClass());
assertEquals(fields.size(), 0);
}
@Test
public void testGetLoggerFieldsAnnotatedWithResourceOneLogger() {
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(A.class);
assertEquals(fields.size(), 1);
}
@Test
public void testGetLoggerFieldsAnnotatedWithResourceTwoLoggers() {
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(D.class);
assertEquals(fields.size(), 2);
}
}

View File

@ -64,6 +64,7 @@
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View File

@ -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)

View File

@ -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,11 +36,8 @@ 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!
@ -45,34 +45,41 @@ import java.util.logging.Logger;
* @author Adrian Cole
*/
@Singleton
public class HttpNioConnectionPoolClient extends FutureCommandConnectionPoolClient<NHttpConnection> implements HttpFutureCommandClient {
public class HttpNioConnectionPoolClient extends
FutureCommandConnectionPoolClient<NHttpConnection> implements
HttpFutureCommandClient {
private List<HttpRequestFilter> requestFilters = Collections.emptyList();
public List<HttpRequestFilter> getRequestFilters() {
return requestFilters;
return requestFilters;
}
@Inject(optional = true)
public void setRequestFilters(List<HttpRequestFilter> requestFilters) {
this.requestFilters = requestFilters;
this.requestFilters = requestFilters;
}
@Override
protected <O extends FutureCommand> 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<FutureCommand> commandQueue) {
super(logger, executor, httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool, commandQueue); // TODO: Adrian: Customise this generated block
public HttpNioConnectionPoolClient(
ExecutorService executor,
HttpNioFutureCommandConnectionPool httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool,
BlockingQueue<FutureCommand> commandQueue) {
super(
executor,
httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool,
commandQueue);
}
}

View File

@ -23,38 +23,42 @@
*/
package org.jclouds.http.httpnio.pool;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
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 java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Semaphore;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
/**
* // TODO: Adrian: Document this!
*
* @author Adrian Cole
*/
public class HttpNioFutureCommandConnectionHandle extends FutureCommandConnectionHandle<NHttpConnection> {
public class HttpNioFutureCommandConnectionHandle extends
FutureCommandConnectionHandle<NHttpConnection> {
@Inject
public HttpNioFutureCommandConnectionHandle(java.util.logging.Logger logger, BlockingQueue<NHttpConnection> available, Semaphore maxConnections, @Assisted NHttpConnection conn, @Assisted FutureCommand operation) throws InterruptedException {
super(logger, maxConnections, operation, conn, available);
public HttpNioFutureCommandConnectionHandle(
BlockingQueue<NHttpConnection> 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();
}
}

View File

@ -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<NHttpConnection> available,
@ -76,9 +74,8 @@ public class HttpNioFutureCommandConnectionPool extends
FutureCommandConnectionRetry<NHttpConnection> 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;

View File

@ -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<NHttpConnection> {
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<NHttpConnection> {
@Inject
public HttpNioFutureCommandConnectionRetry(java.util.logging.Logger logger, BlockingQueue<FutureCommand> commandQueue, AtomicInteger errors) {
super(new Logger(logger), commandQueue, errors);
public HttpNioFutureCommandConnectionRetry(
BlockingQueue<FutureCommand> commandQueue, AtomicInteger errors) {
super(commandQueue, errors);
}
@Override
public void associateHandleWithConnection(FutureCommandConnectionHandle<NHttpConnection> handle, NHttpConnection connection) {
connection.getContext().setAttribute("operation-handle", handle);
public void associateHandleWithConnection(
FutureCommandConnectionHandle<NHttpConnection> handle,
NHttpConnection connection) {
connection.getContext().setAttribute("operation-handle", handle);
}
@Override
public HttpNioFutureCommandConnectionHandle getHandleFromConnection(NHttpConnection connection) {
return (HttpNioFutureCommandConnectionHandle) connection.getContext().getAttribute("operation-handle");
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);
// }
// @Override
// public void incrementErrorCountAndRetry(FutureCommand operation) {
// ((HttpEntityEnclosingRequest)
// operation.getRequest()).removeHeaders(HTTP.CONTENT_LEN);
// ((HttpEntityEnclosingRequest)
// operation.getRequest()).removeHeaders(HTTP.DATE_HEADER);
// super.incrementErrorCountAndRetry(operation);
// }
}

View File

@ -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);
}
}
}
}

69
extensions/log4j/pom.xml Normal file
View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$HeadURL$
$Revision$
$Date$
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
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.html
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>jclouds-project</artifactId>
<groupId>org.jclouds</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jclouds-log4j</artifactId>
<name>jclouds log4j logging module</name>
<packaging>jar</packaging>
<description>Log4J logging module</description>
<scm>
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/extensions/log4j</connection>
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/extensions/log4j</developerConnection>
<url>http://jclouds.googlecode.com/svn/trunk/extensions/log4j</url>
</scm>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,112 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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;
}
}

View File

@ -0,0 +1,42 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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();
}
}

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* 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");
}
}

View File

@ -61,6 +61,7 @@
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-s3</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>

View File

@ -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;
}
}

View File

@ -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);
}
}));
}
}

View File

@ -23,21 +23,25 @@
*/
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!
*
@ -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);
}
}

View File

@ -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<HttpRequestFilter> requestFilters = Collections.emptyList();
private final Logger logger;
@Resource
private Logger logger = Logger.NULL;
private final URLFetchService urlFetchService;
public List<HttpRequestFilter> 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);
}

View File

@ -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

View File

@ -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));
}

View File

@ -42,6 +42,7 @@
<module>core</module>
<module>extensions/httpnio</module>
<module>extensions/s3nio</module>
<module>extensions/log4j</module>
<module>gae</module>
<module>s3</module>
</modules>

View File

@ -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<? extends Module> modules = httpModules.length != 0 ? Arrays
.asList(httpModules) : Collections
.singletonList(new JavaUrlHttpFutureCommandClientModule());
Module... configModules) {
final List<Module> 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<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(
HttpFutureCommandClientModule.class);
}
}))
modules.add(new JavaUrlHttpFutureCommandClientModule());
}
@VisibleForTesting
static void addLoggingModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
modules.add(new JDKLoggingModule());
}
}

View File

@ -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<Boolean> {
@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 {

View File

@ -23,12 +23,11 @@
*/
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!
*
@ -36,29 +35,22 @@ import java.io.IOException;
*/
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();
}
}
}

View File

@ -23,8 +23,6 @@
*/
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;
@ -35,16 +33,11 @@ import org.jclouds.http.HttpFutureCommand;
*/
public class DeleteCallable extends HttpFutureCommand.ResponseCallable<Boolean> {
@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());
}
}
}

View File

@ -23,8 +23,6 @@
*/
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;
@ -33,20 +31,16 @@ import org.jclouds.http.HttpFutureCommand;
*
* @author Adrian Cole
*/
public class PutBucketCallable extends HttpFutureCommand.ResponseCallable<Boolean> {
@Inject
public PutBucketCallable(java.util.logging.Logger logger) {
super(new Logger(logger));
}
public class PutBucketCallable extends
HttpFutureCommand.ResponseCallable<Boolean> {
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());
}
}
}

View File

@ -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<String> {
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<String> {
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);
}
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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