mirror of https://github.com/apache/jclouds.git
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:
parent
3b70fd807d
commit
c5486f6c5e
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -40,6 +40,7 @@ import com.google.inject.name.Named;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@HttpFutureCommandClientModule
|
||||
public class JavaUrlHttpFutureCommandClientModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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>>() {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
1
pom.xml
1
pom.xml
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue