mirror of https://github.com/apache/jclouds.git
finished creating integration tests for all functionality needed for beta. fixed bad logging formats, added javadoc
git-svn-id: http://jclouds.googlecode.com/svn/trunk@643 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
589c37ec04
commit
67683084ff
|
@ -73,7 +73,7 @@ public abstract class FutureCommandConnectionHandle<C, O extends FutureCommand<?
|
||||||
if (isCompleted()) {
|
if (isCompleted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.trace("%1s - %2d - releasing to pool", conn, conn.hashCode());
|
logger.trace("%1$s - %2$d - releasing to pool", conn, conn.hashCode());
|
||||||
available.put(conn);
|
available.put(conn);
|
||||||
conn = null;
|
conn = null;
|
||||||
command = null;
|
command = null;
|
||||||
|
@ -85,7 +85,7 @@ public abstract class FutureCommandConnectionHandle<C, O extends FutureCommand<?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
logger.trace("%1s - %2d - cancelled; shutting down connection",
|
logger.trace("%1$s - %2$d - cancelled; shutting down connection",
|
||||||
conn, conn.hashCode());
|
conn, conn.hashCode());
|
||||||
try {
|
try {
|
||||||
shutdownConnection();
|
shutdownConnection();
|
||||||
|
|
|
@ -83,23 +83,23 @@ public abstract class FutureCommandConnectionPool<C, O extends FutureCommand<?,
|
||||||
hitBottom = available.size() == 0
|
hitBottom = available.size() == 0
|
||||||
&& allConnections.availablePermits() == 0;
|
&& allConnections.availablePermits() == 0;
|
||||||
if (hitBottom)
|
if (hitBottom)
|
||||||
logger.warn("%1s - saturated connection pool", this);
|
logger.warn("%1$s - saturated connection pool", this);
|
||||||
}
|
}
|
||||||
logger
|
logger
|
||||||
.debug(
|
.debug(
|
||||||
"%1s - attempting to acquire connection; %d currently available",
|
"%1$s - attempting to acquire connection; %d currently available",
|
||||||
this, available.size());
|
this, available.size());
|
||||||
C conn = available.poll(5, TimeUnit.SECONDS);
|
C conn = available.poll(5, TimeUnit.SECONDS);
|
||||||
if (conn == null)
|
if (conn == null)
|
||||||
throw new TimeoutException(
|
throw new TimeoutException(
|
||||||
"could not obtain a pooled connection within 5 seconds");
|
"could not obtain a pooled connection within 5 seconds");
|
||||||
|
|
||||||
logger.trace("%1s - %2d - aquired", conn, conn.hashCode());
|
logger.trace("%1$s - %2$d - aquired", conn, conn.hashCode());
|
||||||
if (connectionValid(conn)) {
|
if (connectionValid(conn)) {
|
||||||
logger.debug("%1s - %2d - reusing", conn, conn.hashCode());
|
logger.debug("%1$s - %2$d - reusing", conn, conn.hashCode());
|
||||||
return conn;
|
return conn;
|
||||||
} else {
|
} else {
|
||||||
logger.debug("%1s - %2d - unusable", conn, conn.hashCode());
|
logger.debug("%1$s - %2$d - unusable", conn, conn.hashCode());
|
||||||
shutdownConnection(conn);
|
shutdownConnection(conn);
|
||||||
allConnections.release();
|
allConnections.release();
|
||||||
return getConnection();
|
return getConnection();
|
||||||
|
@ -130,7 +130,7 @@ public abstract class FutureCommandConnectionPool<C, O extends FutureCommand<?,
|
||||||
O command = getCommandFromConnection(connection);
|
O command = getCommandFromConnection(connection);
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
if (isReplayable(command)) {
|
if (isReplayable(command)) {
|
||||||
logger.info("resubmitting command: %1s", command);
|
logger.info("resubmitting command: %1$s", command);
|
||||||
commandQueue.add(command);
|
commandQueue.add(command);
|
||||||
} else {
|
} else {
|
||||||
command.setException(e);
|
command.setException(e);
|
||||||
|
@ -151,7 +151,7 @@ public abstract class FutureCommandConnectionPool<C, O extends FutureCommand<?,
|
||||||
protected void setExceptionOnCommand(C connection, Exception e) {
|
protected void setExceptionOnCommand(C connection, Exception e) {
|
||||||
FutureCommand<?, ?, ?> command = getCommandFromConnection(connection);
|
FutureCommand<?, ?, ?> command = getCommandFromConnection(connection);
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
logger.warn(e, "exception in command: %1s", command);
|
logger.warn(e, "exception in command: %1$s", command);
|
||||||
command.setException(e);
|
command.setException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,13 +104,13 @@ public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?,
|
||||||
logger
|
logger
|
||||||
.warn(
|
.warn(
|
||||||
e,
|
e,
|
||||||
"Interrupted getting a connection for command %1s; retrying",
|
"Interrupted getting a connection for command %1$s; retrying",
|
||||||
command);
|
command);
|
||||||
commandQueue.add(command);
|
commandQueue.add(command);
|
||||||
return;
|
return;
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
logger.warn(e,
|
logger.warn(e,
|
||||||
"Timeout getting a connection for command %1s; retrying",
|
"Timeout getting a connection for command %1$s; retrying",
|
||||||
command);
|
command);
|
||||||
commandQueue.add(command);
|
commandQueue.add(command);
|
||||||
return;
|
return;
|
||||||
|
@ -118,7 +118,7 @@ public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?,
|
||||||
|
|
||||||
if (connectionHandle == null) {
|
if (connectionHandle == null) {
|
||||||
logger.error(
|
logger.error(
|
||||||
"Failed to obtain connection for command %1s; retrying",
|
"Failed to obtain connection for command %1$s; retrying",
|
||||||
command);
|
command);
|
||||||
commandQueue.add(command);
|
commandQueue.add(command);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -64,7 +64,7 @@ public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandC
|
||||||
HttpResponse response) {
|
HttpResponse response) {
|
||||||
int code = response.getStatusCode();
|
int code = response.getStatusCode();
|
||||||
if (command.getRequest().isReplayable() && code >= 500) {
|
if (command.getRequest().isReplayable() && code >= 500) {
|
||||||
logger.info("resubmitting command: %1s", command);
|
logger.info("resubmitting command: %1$s", command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,7 +25,7 @@ package org.jclouds.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.jclouds.Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -34,9 +34,13 @@ import org.apache.commons.io.IOUtils;
|
||||||
public class CloseContentAndSetExceptionHandler implements HttpResponseHandler {
|
public class CloseContentAndSetExceptionHandler implements HttpResponseHandler {
|
||||||
|
|
||||||
public void handle(HttpFutureCommand<?> command, HttpResponse response) {
|
public void handle(HttpFutureCommand<?> command, HttpResponse response) {
|
||||||
String message = String.format("Command: %2s failed; response: %1s",
|
String content;
|
||||||
response, command);
|
try {
|
||||||
command.setException(new IOException(message));
|
content = Utils.toStringAndClose(response.getContent());
|
||||||
IOUtils.closeQuietly(response.getContent());
|
command.setException(new HttpResponseException(command, response,
|
||||||
|
content));
|
||||||
|
} catch (IOException e) {
|
||||||
|
command.setException(new HttpResponseException(command, response));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,5 +78,12 @@ public interface HttpHeaders {
|
||||||
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
|
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
|
||||||
public static final String LAST_MODIFIED = "Last-Modified";
|
public static final String LAST_MODIFIED = "Last-Modified";
|
||||||
public static final String SERVER = "Server";
|
public static final String SERVER = "Server";
|
||||||
|
public static final String ETAG = "ETag";
|
||||||
|
public static final String RANGE = "Range";
|
||||||
|
public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||||
|
public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
|
||||||
|
public static final String IF_MATCH = "If-Match";
|
||||||
|
public static final String IF_NONE_MATCH = "If-None-Match";
|
||||||
|
public static final String CONTENT_RANGE = "Content-Range";
|
||||||
|
|
||||||
}
|
}
|
|
@ -74,7 +74,7 @@ public class HttpRequest extends HttpMessage {
|
||||||
public boolean isReplayable() {
|
public boolean isReplayable() {
|
||||||
Object content = getPayload();
|
Object content = getPayload();
|
||||||
if (content != null && content instanceof InputStream) {
|
if (content != null && content instanceof InputStream) {
|
||||||
logger.warn("%1s: InputStreams are not replayable", toString());
|
logger.warn("%1$s: InputStreams are not replayable", toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package org.jclouds.http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an error obtained from an HttpResponse.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HttpResponseException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
protected final HttpFutureCommand<?> command;
|
||||||
|
protected final HttpResponse response;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
public HttpResponseException(String message, HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.command = command;
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(String message, HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, String content, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.command = command;
|
||||||
|
this.response = response;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, Throwable cause) {
|
||||||
|
this(String.format("command: %1$s failed with response: %2$s", command,
|
||||||
|
response), command, response, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, String content, Throwable cause) {
|
||||||
|
this(String.format(
|
||||||
|
"command: %1$s failed with response: %2$s; content: [%3$s]",
|
||||||
|
command, response), command, response, content, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(String message, HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response) {
|
||||||
|
super(message);
|
||||||
|
this.command = command;
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(String message, HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, String content) {
|
||||||
|
super(message);
|
||||||
|
this.command = command;
|
||||||
|
this.response = response;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response) {
|
||||||
|
this(String.format("command: %1$s failed with response: %2$s", command,
|
||||||
|
response), command, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseException(HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, String content) {
|
||||||
|
this(String.format(
|
||||||
|
"command: %1$s failed with response: %2$s; content: [%3$s]",
|
||||||
|
command, response, content), command, response, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpFutureCommand<?> getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponse getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -59,13 +59,13 @@ public class JavaUrlHttpFutureCommandClient extends BaseHttpFutureCommandClient
|
||||||
for (HttpRequestFilter filter : requestFilters) {
|
for (HttpRequestFilter filter : requestFilters) {
|
||||||
filter.filter(request);
|
filter.filter(request);
|
||||||
}
|
}
|
||||||
logger.trace("%1s - converting request %2s", target, request);
|
logger.trace("%1$s - converting request %2$s", target, request);
|
||||||
connection = openJavaConnection(request);
|
connection = openJavaConnection(request);
|
||||||
logger
|
logger
|
||||||
.trace("%1s - submitting request %2s", target,
|
.trace("%1$s - submitting request %2$s", target,
|
||||||
connection);
|
connection);
|
||||||
response = getResponse(connection);
|
response = getResponse(connection);
|
||||||
logger.trace("%1s - received response %2s", target, response);
|
logger.trace("%1$s - received response %2$s", target, response);
|
||||||
if (isRetryable(command, response))
|
if (isRetryable(command, response))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -56,13 +56,13 @@ public class ReturnStringIf200 extends
|
||||||
toReturn = Utils.toStringAndClose(entity);
|
toReturn = Utils.toStringAndClose(entity);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpException(String.format(
|
throw new HttpException(String.format(
|
||||||
"Couldn't receive response %1s, entity: %2s ",
|
"Couldn't receive response %1$s, entity: %2$s ",
|
||||||
getResponse(), toReturn), e);
|
getResponse(), toReturn), e);
|
||||||
}
|
}
|
||||||
return toReturn;
|
return toReturn;
|
||||||
} else {
|
} else {
|
||||||
throw new HttpException(String.format(
|
throw new HttpException(String.format(
|
||||||
"Unhandled status code - %1s", getResponse()));
|
"Unhandled status code - %1$s", getResponse()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -70,7 +70,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
||||||
this.status = Status.SHUTTING_DOWN;
|
this.status = Status.SHUTTING_DOWN;
|
||||||
doShutdown();
|
doShutdown();
|
||||||
this.status = Status.SHUT_DOWN;
|
this.status = Status.SHUT_DOWN;
|
||||||
logger.info("%1s", this);
|
logger.info("%1$s", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void doWork() throws Exception;
|
protected abstract void doWork() throws Exception;
|
||||||
|
@ -88,7 +88,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void start() {
|
public void start() {
|
||||||
logger.info("starting %1s", this);
|
logger.info("starting %1$s", this);
|
||||||
synchronized (this.statusLock) {
|
synchronized (this.statusLock) {
|
||||||
if (this.status.compareTo(Status.SHUTDOWN_REQUEST) >= 0) {
|
if (this.status.compareTo(Status.SHUTDOWN_REQUEST) >= 0) {
|
||||||
doShutdown();
|
doShutdown();
|
||||||
|
@ -116,7 +116,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
||||||
for (BaseLifeCycle dependency : dependencies) {
|
for (BaseLifeCycle dependency : dependencies) {
|
||||||
if (dependency.status.compareTo(Status.ACTIVE) != 0) {
|
if (dependency.status.compareTo(Status.ACTIVE) != 0) {
|
||||||
throw new IllegalStateException(String.format(
|
throw new IllegalStateException(String.format(
|
||||||
"Illegal state: %1s for component: %2s",
|
"Illegal state: %1$s for component: %2$s",
|
||||||
dependency.status, dependency));
|
dependency.status, dependency));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
||||||
|
|
||||||
protected void exceptionIfNotActive() {
|
protected void exceptionIfNotActive() {
|
||||||
if (!status.equals(Status.ACTIVE))
|
if (!status.equals(Status.ACTIVE))
|
||||||
throw new IllegalStateException(String.format("not active: %1s",
|
throw new IllegalStateException(String.format("not active: %1$s",
|
||||||
this));
|
this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ public abstract class BaseHttpFutureCommandClientTest {
|
||||||
get.getRequest().getHeaders().put("filterme", "filterme");
|
get.getRequest().getHeaders().put("filterme", "filterme");
|
||||||
client.submit(get);
|
client.submit(get);
|
||||||
assert get.get(10, TimeUnit.SECONDS).trim().equals("test") : String
|
assert get.get(10, TimeUnit.SECONDS).trim().equals("test") : String
|
||||||
.format("expected: [%1s], but got [%2s]", "test", get.get(10,
|
.format("expected: [%1$s], but got [%2$s]", "test", get.get(10,
|
||||||
TimeUnit.SECONDS));
|
TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ public abstract class BaseHttpFutureCommandClientTest {
|
||||||
get.getRequest().getHeaders().put("test", "test");
|
get.getRequest().getHeaders().put("test", "test");
|
||||||
client.submit(get);
|
client.submit(get);
|
||||||
assert get.get(10, TimeUnit.SECONDS).trim().equals("test") : String
|
assert get.get(10, TimeUnit.SECONDS).trim().equals("test") : String
|
||||||
.format("expected: [%1s], but got [%2s]", "test", get.get(10,
|
.format("expected: [%1$s], but got [%2$s]", "test", get.get(10,
|
||||||
TimeUnit.SECONDS));
|
TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ public abstract class BaseHttpFutureCommandClientTest {
|
||||||
assert get != null;
|
assert get != null;
|
||||||
client.submit(get);
|
client.submit(get);
|
||||||
assert get.get(10, TimeUnit.SECONDS).trim().equals(XML) : String
|
assert get.get(10, TimeUnit.SECONDS).trim().equals(XML) : String
|
||||||
.format("expected: [%1s], but got [%2s]", XML, get.get(10,
|
.format("expected: [%1$s], but got [%2$s]", XML, get.get(10,
|
||||||
TimeUnit.SECONDS));
|
TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class HttpNioFutureCommandConnectionHandle extends
|
||||||
|
|
||||||
public void startConnection() {
|
public void startConnection() {
|
||||||
conn.getContext().setAttribute("command", command);
|
conn.getContext().setAttribute("command", command);
|
||||||
logger.trace("invoking %1s on connection %2s", command, conn);
|
logger.trace("invoking %1$s on connection %2$s", command, conn);
|
||||||
conn.requestOutput();
|
conn.requestOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
ioReactor.execute(dispatch);
|
ioReactor.execute(dispatch);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
exception.set(e);
|
exception.set(e);
|
||||||
logger.error(e, "Error dispatching %1s", dispatch);
|
logger.error(e, "Error dispatching %1$s", dispatch);
|
||||||
status = Status.SHUTDOWN_REQUEST;
|
status = Status.SHUTDOWN_REQUEST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
public void shutdownConnection(NHttpConnection conn) {
|
public void shutdownConnection(NHttpConnection conn) {
|
||||||
if (conn.getMetrics().getRequestCount() >= maxConnectionReuse)
|
if (conn.getMetrics().getRequestCount() >= maxConnectionReuse)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"%1s - %2d - closing connection due to overuse %1s/%2s",
|
"%1$s - %2$d - closing connection due to overuse %1$s/%2$s",
|
||||||
conn, conn.hashCode(), conn.getMetrics().getRequestCount(),
|
conn, conn.hashCode(), conn.getMetrics().getRequestCount(),
|
||||||
maxConnectionReuse);
|
maxConnectionReuse);
|
||||||
if (conn.getStatus() == NHttpConnection.ACTIVE) {
|
if (conn.getStatus() == NHttpConnection.ACTIVE) {
|
||||||
|
@ -155,7 +155,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS);
|
boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS);
|
||||||
if (acquired) {
|
if (acquired) {
|
||||||
if (shouldDoWork()) {
|
if (shouldDoWork()) {
|
||||||
logger.debug("%1s - opening new connection", target);
|
logger.debug("%1$s - opening new connection", target);
|
||||||
ioReactor.connect(target, null, null, sessionCallback);
|
ioReactor.connect(target, null, null, sessionCallback);
|
||||||
} else {
|
} else {
|
||||||
allConnections.release();
|
allConnections.release();
|
||||||
|
@ -181,13 +181,13 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
SessionRequestCallback {
|
SessionRequestCallback {
|
||||||
|
|
||||||
public void completed(SessionRequest request) {
|
public void completed(SessionRequest request) {
|
||||||
logger.trace("%1s->%2s[%3s] - SessionRequest complete", request
|
logger.trace("%1$s->%2$s[%3$s] - SessionRequest complete", request
|
||||||
.getLocalAddress(), request.getRemoteAddress(), request
|
.getLocalAddress(), request.getRemoteAddress(), request
|
||||||
.getAttachment());
|
.getAttachment());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelled(SessionRequest request) {
|
public void cancelled(SessionRequest request) {
|
||||||
logger.trace("%1s->%2s[%3s] - SessionRequest cancelled", request
|
logger.trace("%1$s->%2$s[%3$s] - SessionRequest cancelled", request
|
||||||
.getLocalAddress(), request.getRemoteAddress(), request
|
.getLocalAddress(), request.getRemoteAddress(), request
|
||||||
.getAttachment());
|
.getAttachment());
|
||||||
releaseConnectionAndCancelResponse(request);
|
releaseConnectionAndCancelResponse(request);
|
||||||
|
@ -198,7 +198,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
FutureCommand<?, ?, ?> frequest = (FutureCommand<?, ?, ?>) request
|
FutureCommand<?, ?, ?> frequest = (FutureCommand<?, ?, ?>) request
|
||||||
.getAttachment();
|
.getAttachment();
|
||||||
if (frequest != null) {
|
if (frequest != null) {
|
||||||
logger.error("%1s->%2s[%3s] - Cancelling FutureCommand",
|
logger.error("%1$s->%2$s[%3$s] - Cancelling FutureCommand",
|
||||||
request.getLocalAddress(), request.getRemoteAddress(),
|
request.getLocalAddress(), request.getRemoteAddress(),
|
||||||
frequest);
|
frequest);
|
||||||
frequest.cancel(true);
|
frequest.cancel(true);
|
||||||
|
@ -212,7 +212,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
.getAttachment();
|
.getAttachment();
|
||||||
if (frequest != null) {
|
if (frequest != null) {
|
||||||
logger.error(e,
|
logger.error(e,
|
||||||
"%1s->%2s[%3s] - Setting Exception on FutureCommand",
|
"%1$s->%2$s[%3$s] - Setting Exception on FutureCommand",
|
||||||
request.getLocalAddress(), request.getRemoteAddress(),
|
request.getLocalAddress(), request.getRemoteAddress(),
|
||||||
frequest);
|
frequest);
|
||||||
frequest.setException(e);
|
frequest.setException(e);
|
||||||
|
@ -221,7 +221,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
|
|
||||||
public void failed(SessionRequest request) {
|
public void failed(SessionRequest request) {
|
||||||
int count = currentSessionFailures.getAndIncrement();
|
int count = currentSessionFailures.getAndIncrement();
|
||||||
logger.warn("%1s->%2s[%3s] - SessionRequest failed", request
|
logger.warn("%1$s->%2$s[%3$s] - SessionRequest failed", request
|
||||||
.getLocalAddress(), request.getRemoteAddress(), request
|
.getLocalAddress(), request.getRemoteAddress(), request
|
||||||
.getAttachment());
|
.getAttachment());
|
||||||
releaseConnectionAndSetResponseException(request, request
|
releaseConnectionAndSetResponseException(request, request
|
||||||
|
@ -230,7 +230,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
logger
|
logger
|
||||||
.error(
|
.error(
|
||||||
request.getException(),
|
request.getException(),
|
||||||
"%1s->%2s[%3s] - SessionRequest failures: %4s, Disabling pool for %5s",
|
"%1$s->%2$s[%3$s] - SessionRequest failures: %4$s, Disabling pool for %5$s",
|
||||||
request.getLocalAddress(), request
|
request.getLocalAddress(), request
|
||||||
.getRemoteAddress(),
|
.getRemoteAddress(),
|
||||||
maxSessionFailures, target);
|
maxSessionFailures, target);
|
||||||
|
@ -240,7 +240,7 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
}
|
}
|
||||||
|
|
||||||
public void timeout(SessionRequest request) {
|
public void timeout(SessionRequest request) {
|
||||||
logger.warn("%1s->%2s[%3s] - SessionRequest timeout", request
|
logger.warn("%1$s->%2$s[%3$s] - SessionRequest timeout", request
|
||||||
.getLocalAddress(), request.getRemoteAddress(), request
|
.getLocalAddress(), request.getRemoteAddress(), request
|
||||||
.getAttachment());
|
.getAttachment());
|
||||||
releaseConnectionAndCancelResponse(request);
|
releaseConnectionAndCancelResponse(request);
|
||||||
|
@ -251,28 +251,28 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
public void connectionOpen(NHttpConnection conn) {
|
public void connectionOpen(NHttpConnection conn) {
|
||||||
conn.setSocketTimeout(0);
|
conn.setSocketTimeout(0);
|
||||||
available.offer(conn);
|
available.offer(conn);
|
||||||
logger.trace("%1s - %2d - open", conn, conn.hashCode());
|
logger.trace("%1$s - %2$d - open", conn, conn.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectionTimeout(NHttpConnection conn) {
|
public void connectionTimeout(NHttpConnection conn) {
|
||||||
String message = String.format("%1s - %2d - timeout %2d", conn, conn
|
String message = String.format("%1$s - %2$d - timeout %2$d", conn, conn
|
||||||
.hashCode(), conn.getSocketTimeout());
|
.hashCode(), conn.getSocketTimeout());
|
||||||
logger.warn(message);
|
logger.warn(message);
|
||||||
resubmitIfRequestIsReplayable(conn, new TimeoutException(message));
|
resubmitIfRequestIsReplayable(conn, new TimeoutException(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectionClosed(NHttpConnection conn) {
|
public void connectionClosed(NHttpConnection conn) {
|
||||||
logger.trace("%1s - %2d - closed", conn, conn.hashCode());
|
logger.trace("%1$s - %2$d - closed", conn, conn.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fatalIOException(IOException ex, NHttpConnection conn) {
|
public void fatalIOException(IOException ex, NHttpConnection conn) {
|
||||||
logger.error(ex, "%3s-%1d{%2s} - io error", conn, conn.hashCode(),
|
logger.error(ex, "%3$s-%1$d{%2$s} - io error", conn, conn.hashCode(),
|
||||||
target);
|
target);
|
||||||
resubmitIfRequestIsReplayable(conn, ex);
|
resubmitIfRequestIsReplayable(conn, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fatalProtocolException(HttpException ex, NHttpConnection conn) {
|
public void fatalProtocolException(HttpException ex, NHttpConnection conn) {
|
||||||
logger.error(ex, "%3s-%1d{%2s} - http error", conn, conn.hashCode(),
|
logger.error(ex, "%3$s-%1$d{%2$s} - http error", conn, conn.hashCode(),
|
||||||
target);
|
target);
|
||||||
setExceptionOnCommand(conn, ex);
|
setExceptionOnCommand(conn, ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,13 +134,13 @@ public class HttpNioFutureCommandExecutionHandler implements
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(String.format(
|
throw new IllegalStateException(String.format(
|
||||||
"No command-handle associated with command %1s", context));
|
"No command-handle associated with command %1$s", context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isRetryable(HttpFutureCommand<?> command) {
|
protected boolean isRetryable(HttpFutureCommand<?> command) {
|
||||||
if (command.getRequest().isReplayable()) {
|
if (command.getRequest().isReplayable()) {
|
||||||
logger.info("resubmitting command: %1s", command);
|
logger.info("resubmitting command: %1$s", command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -151,14 +151,14 @@ public class HttpNioFutureCommandExecutionHandler implements
|
||||||
try {
|
try {
|
||||||
handle.release();
|
handle.release();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.error(e, "Interrupted releasing handle %1s", handle);
|
logger.error(e, "Interrupted releasing handle %1$s", handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processResponse(org.jclouds.http.HttpResponse response,
|
protected void processResponse(org.jclouds.http.HttpResponse response,
|
||||||
HttpFutureCommand<?> command) throws IOException {
|
HttpFutureCommand<?> command) throws IOException {
|
||||||
command.getResponseFuture().setResponse(response);
|
command.getResponseFuture().setResponse(response);
|
||||||
logger.trace("submitting response task %1s", command
|
logger.trace("submitting response task %1$s", command
|
||||||
.getResponseFuture());
|
.getResponseFuture());
|
||||||
executor.submit(command.getResponseFuture());
|
executor.submit(command.getResponseFuture());
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ public class HttpNioFutureCommandExecutionHandler implements
|
||||||
try {
|
try {
|
||||||
handle.cancel();
|
handle.cancel();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e, "Error cancelling handle %1s", handle);
|
logger.error(e, "Error cancelling handle %1$s", handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,8 @@ public class JCloudsS3Service extends S3Service {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3ServiceException(String.format(
|
throw new S3ServiceException(String.format(
|
||||||
"error deleting object: %1s:%2s", bucketName, objectKey), e);
|
"error deleting object: %1$s:%2$s", bucketName, objectKey),
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,16 +209,16 @@ public class JCloudsS3Service extends S3Service {
|
||||||
protected S3Bucket[] listAllBucketsImpl() throws S3ServiceException {
|
protected S3Bucket[] listAllBucketsImpl() throws S3ServiceException {
|
||||||
try {
|
try {
|
||||||
List<org.jclouds.aws.s3.domain.S3Bucket.Metadata> jcBucketList = connection
|
List<org.jclouds.aws.s3.domain.S3Bucket.Metadata> jcBucketList = connection
|
||||||
.getOwnedBuckets().get(
|
.listOwnedBuckets().get(requestTimeoutMilliseconds,
|
||||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
ArrayList<org.jets3t.service.model.S3Bucket> jsBucketList = new ArrayList<org.jets3t.service.model.S3Bucket>();
|
ArrayList<org.jets3t.service.model.S3Bucket> jsBucketList = new ArrayList<org.jets3t.service.model.S3Bucket>();
|
||||||
for (org.jclouds.aws.s3.domain.S3Bucket.Metadata jcBucket : jcBucketList) {
|
for (org.jclouds.aws.s3.domain.S3Bucket.Metadata jcBucket : jcBucketList) {
|
||||||
org.jets3t.service.model.S3Bucket jsBucket = new org.jets3t.service.model.S3Bucket(
|
org.jets3t.service.model.S3Bucket jsBucket = new org.jets3t.service.model.S3Bucket(
|
||||||
jcBucket.getName());
|
jcBucket.getName());
|
||||||
jsBucket.setOwner(new org.jets3t.service.model.S3Owner(jcBucket
|
jsBucket.setOwner(new org.jets3t.service.model.S3Owner(jcBucket
|
||||||
.getCanonicalUser().getId(), jcBucket
|
.getOwner().getId(), jcBucket.getOwner()
|
||||||
.getCanonicalUser().getDisplayName()));
|
.getDisplayName()));
|
||||||
jsBucketList.add(jsBucket);
|
jsBucketList.add(jsBucket);
|
||||||
}
|
}
|
||||||
return (org.jets3t.service.model.S3Bucket[]) jsBucketList
|
return (org.jets3t.service.model.S3Bucket[]) jsBucketList
|
||||||
|
|
|
@ -184,7 +184,7 @@ public class JCloudsS3ServiceTest extends S3IntegrationTest {
|
||||||
S3Bucket[] jsBuckets = service.listAllBuckets();
|
S3Bucket[] jsBuckets = service.listAllBuckets();
|
||||||
|
|
||||||
List<org.jclouds.aws.s3.domain.S3Bucket.Metadata> jcBuckets = client
|
List<org.jclouds.aws.s3.domain.S3Bucket.Metadata> jcBuckets = client
|
||||||
.getOwnedBuckets().get(10, TimeUnit.SECONDS);
|
.listOwnedBuckets().get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
assert jsBuckets.length == jcBuckets.size();
|
assert jsBuckets.length == jcBuckets.size();
|
||||||
|
|
||||||
|
@ -197,9 +197,9 @@ public class JCloudsS3ServiceTest extends S3IntegrationTest {
|
||||||
.next();
|
.next();
|
||||||
assert jsBucket.getName().equals(jcBucket.getName());
|
assert jsBucket.getName().equals(jcBucket.getName());
|
||||||
assert jsBucket.getOwner().getId().equals(
|
assert jsBucket.getOwner().getId().equals(
|
||||||
jcBucket.getCanonicalUser().getId());
|
jcBucket.getOwner().getId());
|
||||||
assert jsBucket.getOwner().getDisplayName().equals(
|
assert jsBucket.getOwner().getDisplayName().equals(
|
||||||
jcBucket.getCanonicalUser().getDisplayName());
|
jcBucket.getOwner().getDisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
client.deleteBucketIfEmpty(bucketName);
|
client.deleteBucketIfEmpty(bucketName);
|
||||||
|
|
|
@ -31,12 +31,13 @@ import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Optional;
|
import org.testng.annotations.Optional;
|
||||||
import org.testng.annotations.Parameters;
|
import org.testng.annotations.Parameters;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs operations that amazon s3 sample code is capable of performing.
|
* Runs operations that amazon s3 sample code is capable of performing.
|
||||||
*
|
*
|
||||||
|
|
|
@ -56,7 +56,7 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
|
||||||
String contentType) throws Exception {
|
String contentType) throws Exception {
|
||||||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
||||||
key);
|
key);
|
||||||
object.getMetaData().setContentType(contentType);
|
object.getMetadata().setContentType(contentType);
|
||||||
object.setData(data);
|
object.setData(data);
|
||||||
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
|
||||||
String contentType) throws Exception {
|
String contentType) throws Exception {
|
||||||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
||||||
key);
|
key);
|
||||||
object.getMetaData().setContentType(contentType);
|
object.getMetadata().setContentType(contentType);
|
||||||
object.setData(data);
|
object.setData(data);
|
||||||
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,9 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
|
||||||
InputStream data, String contentType) throws Exception {
|
InputStream data, String contentType) throws Exception {
|
||||||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
||||||
key);
|
key);
|
||||||
object.getMetaData().setContentType(contentType);
|
object.getMetadata().setContentType(contentType);
|
||||||
object.setData(data);
|
object.setData(data);
|
||||||
object.getMetaData().setSize(data.available());
|
object.getMetadata().setSize(data.available());
|
||||||
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
|
||||||
String contentType) throws Exception {
|
String contentType) throws Exception {
|
||||||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
|
||||||
key);
|
key);
|
||||||
object.getMetaData().setContentType(contentType);
|
object.getMetadata().setContentType(contentType);
|
||||||
object.setData(data);
|
object.setData(data);
|
||||||
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,14 +36,15 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Optional;
|
import org.testng.annotations.Optional;
|
||||||
import org.testng.annotations.Parameters;
|
import org.testng.annotations.Parameters;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -256,7 +257,7 @@ public abstract class BasePerformance extends S3IntegrationTest {
|
||||||
// }
|
// }
|
||||||
// for (Future<Boolean> isdeleted : deletes)
|
// for (Future<Boolean> isdeleted : deletes)
|
||||||
// assert isdeleted.get(10,TimeUnit.SECONDS) :
|
// assert isdeleted.get(10,TimeUnit.SECONDS) :
|
||||||
// String.format("failed to delete %1s",
|
// String.format("failed to delete %1$ss",
|
||||||
// isdeleted);
|
// isdeleted);
|
||||||
// return
|
// return
|
||||||
// clientProvider.get(10,TimeUnit.SECONDS).deleteBucket(bucket).get(10,TimeUnit.SECONDS);
|
// clientProvider.get(10,TimeUnit.SECONDS).deleteBucket(bucket).get(10,TimeUnit.SECONDS);
|
||||||
|
|
|
@ -26,7 +26,7 @@ package com.amazon.s3;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import org.jclouds.aws.PerformanceTest;
|
import org.jclouds.aws.PerformanceTest;
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ public class S3ParserTest extends org.jclouds.aws.s3.commands.S3ParserTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test(enabled = false)
|
||||||
public void testAmazonCanParseListAllMyBuckets() throws IOException {
|
public void testAmazonCanParseListAllMyBuckets() throws IOException {
|
||||||
ListAllMyBucketsResponse response = runAmazonParseListAllMyBuckets();
|
ListAllMyBucketsResponse response = runAmazonParseListAllMyBuckets();
|
||||||
List<Bucket> buckets = response.entries;
|
List<Bucket> buckets = response.entries;
|
||||||
|
|
|
@ -42,63 +42,79 @@ import org.jclouds.aws.s3.domain.S3Object;
|
||||||
* during processing will be wrapped in an {@link ExecutionException} as
|
* during processing will be wrapped in an {@link ExecutionException} as
|
||||||
* documented in {@link Future#get()}.
|
* documented in {@link Future#get()}.
|
||||||
*
|
*
|
||||||
|
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html
|
||||||
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface S3Connection {
|
public interface S3Connection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the object and metadata associated with the key.
|
* Retrieve a complete <code>S3Object</code>.
|
||||||
*
|
*
|
||||||
|
* @see GetObject
|
||||||
* @param bucketName
|
* @param bucketName
|
||||||
* namespace of the object you are retrieving
|
* namespace of the object you are retrieving
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* unique key in the s3Bucket identifying the object
|
* unique key in the s3Bucket identifying the object
|
||||||
* @return fully populated S3Object containing data stored in S3
|
* @return Future reference to a fully populated S3Object including data
|
||||||
|
* stored in S3 or {@link S3Object#NOT_FOUND} if not present.
|
||||||
*/
|
*/
|
||||||
Future<S3Object> getObject(String bucketName, String key);
|
Future<S3Object> getObject(String bucketName, String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the object and metadata associated with the key.
|
* Like {@link #getObject(String, String)} except you can use
|
||||||
|
* {@link GetObjectOptions} to control delivery.
|
||||||
*
|
*
|
||||||
* @param bucketName
|
* @see #getObject(String, String)
|
||||||
* namespace of the object you are retrieving
|
* @see GetObjectOptions
|
||||||
|
* @return S3Object containing data relevant to the
|
||||||
|
* <code>options</options> specified or {@link S3Object#NOT_FOUND} if not present.
|
||||||
*
|
*
|
||||||
* @param key
|
* @throws HttpResponseException
|
||||||
* unique key in the s3Bucket identifying the object
|
* if the conditions requested set were not satisfied by the
|
||||||
* @param options
|
* object on the server.
|
||||||
* options for retrieving the object
|
|
||||||
* @return fully populated S3Object containing data stored in S3
|
|
||||||
*/
|
*/
|
||||||
Future<S3Object> getObject(String bucketName, String key,
|
Future<S3Object> getObject(String bucketName, String key,
|
||||||
GetObjectOptions options);
|
GetObjectOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the metadata of the object associated with the key.
|
* Retrieves the {@link S3Object.Metadata metadata} of the object associated
|
||||||
|
* with the key.
|
||||||
*
|
*
|
||||||
|
* @see HeadObject
|
||||||
* @param bucketName
|
* @param bucketName
|
||||||
* namespace of the metadata you are retrieving
|
* namespace of the metadata you are retrieving
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* unique key in the s3Bucket identifying the object
|
* unique key in the s3Bucket identifying the object
|
||||||
* @return metadata associated with the key
|
* @return metadata associated with the key or
|
||||||
|
* {@link S3Object.Metadata#NOT_FOUND} if not present;
|
||||||
*/
|
*/
|
||||||
Future<S3Object.Metadata> headObject(String bucketName, String key);
|
Future<S3Object.Metadata> headObject(String bucketName, String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the object and metadata associated with the key.
|
* Removes the object and metadata associated with the key.
|
||||||
*
|
*
|
||||||
|
* @see DeleteObject
|
||||||
* @param bucketName
|
* @param bucketName
|
||||||
* namespace of the object you are deleting
|
* namespace of the object you are deleting
|
||||||
* @param key
|
* @param key
|
||||||
* unique key in the s3Bucket identifying the object
|
* unique key in the s3Bucket identifying the object
|
||||||
* @return true if deleted
|
* @return true if deleted
|
||||||
|
* @throws HttpResponseException
|
||||||
|
* if the bucket is not available
|
||||||
*/
|
*/
|
||||||
Future<Boolean> deleteObject(String bucketName, String key);
|
Future<Boolean> deleteObject(String bucketName, String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store data by creating or overwriting an object.
|
* Store data by creating or overwriting an object.
|
||||||
|
* <p/>
|
||||||
|
* This method will store the object with the default <code>private</code>
|
||||||
|
* acl.
|
||||||
*
|
*
|
||||||
|
* @see CannedAccessPolicy#PRIVATE
|
||||||
|
* @see PutObject
|
||||||
* @param bucketName
|
* @param bucketName
|
||||||
* namespace of the object you are storing
|
* namespace of the object you are storing
|
||||||
* @param object
|
* @param object
|
||||||
|
@ -108,15 +124,19 @@ public interface S3Connection {
|
||||||
Future<byte[]> putObject(String bucketName, S3Object object);
|
Future<byte[]> putObject(String bucketName, S3Object object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store data by creating or overwriting an object.
|
* Like {@link #putObject(String, S3Object)} except you can use
|
||||||
|
* {@link CopyObjectOptions} to specify an alternate
|
||||||
|
* {@link CannedAccessPolicy acl}, override
|
||||||
|
* {@link S3Object.Metadata#getUserMetadata() userMetadata}, or specify
|
||||||
|
* conditions for copying the object.
|
||||||
*
|
*
|
||||||
* @param bucketName
|
* @see S3Connection#putObject(String, S3Object)
|
||||||
* namespace of the object you are storing
|
* @see PutObjectOptions
|
||||||
* @param object
|
|
||||||
* contains the data and metadata to create or overwrite
|
|
||||||
* @param options
|
* @param options
|
||||||
* options for creating the object
|
* options for creating the object
|
||||||
* @return MD5 hash of the content uploaded
|
* @throws HttpResponseException
|
||||||
|
* if the conditions requested set are not satisfied by the
|
||||||
|
* object on the server.
|
||||||
*/
|
*/
|
||||||
Future<byte[]> putObject(String bucketName, S3Object object,
|
Future<byte[]> putObject(String bucketName, S3Object object,
|
||||||
PutObjectOptions options);
|
PutObjectOptions options);
|
||||||
|
@ -124,23 +144,25 @@ public interface S3Connection {
|
||||||
/**
|
/**
|
||||||
* Create and name your own bucket in which to store your objects.
|
* Create and name your own bucket in which to store your objects.
|
||||||
*
|
*
|
||||||
* @return true, if the bucket was created
|
* @see PutBucket
|
||||||
|
* @return true, if the bucket was created or already exists
|
||||||
*/
|
*/
|
||||||
Future<Boolean> putBucketIfNotExists(String name);
|
Future<Boolean> putBucketIfNotExists(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and name your own bucket in which to store your objects.
|
* Like {@link #putBucketIfNotExists(String)} except that you can use
|
||||||
|
* {@link PutBucketOptions} to create the bucket in EU. Create and name your
|
||||||
*
|
*
|
||||||
|
* @see PutBucketOptions
|
||||||
* @param options
|
* @param options
|
||||||
* for creating your bucket
|
* for creating your bucket
|
||||||
* @return true, if the bucket was created
|
|
||||||
* @see PutBucketOptions
|
|
||||||
*/
|
*/
|
||||||
Future<Boolean> putBucketIfNotExists(String name, PutBucketOptions options);
|
Future<Boolean> putBucketIfNotExists(String name, PutBucketOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the bucket, if it is empty.
|
* Deletes the bucket, if it is empty.
|
||||||
*
|
*
|
||||||
|
* @see DeleteBucket
|
||||||
* @param s3Bucket
|
* @param s3Bucket
|
||||||
* what to delete
|
* what to delete
|
||||||
* @return false, if the bucket was not empty and therefore not deleted
|
* @return false, if the bucket was not empty and therefore not deleted
|
||||||
|
@ -148,34 +170,68 @@ public interface S3Connection {
|
||||||
Future<Boolean> deleteBucketIfEmpty(String s3Bucket);
|
Future<Boolean> deleteBucketIfEmpty(String s3Bucket);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies one object to another bucket
|
* Copies one object to another bucket, retaining UserMetadata from the
|
||||||
|
* source. The destination will have a private acl.
|
||||||
*
|
*
|
||||||
* @return metaData populated with lastModified and etag of the new object
|
* @see CopyObject
|
||||||
|
* @return metadata populated with lastModified and md5 of the new object
|
||||||
*/
|
*/
|
||||||
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
||||||
String sourceObject, String destinationBucket,
|
String sourceObject, String destinationBucket,
|
||||||
String destinationObject);
|
String destinationObject);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies one object to another bucket using the specifid options
|
* Like {@link #putObject(String, S3Object)} except you can use
|
||||||
|
* {@link PutObjectOptions} to specify an alternate
|
||||||
|
* {@link CannedAccessPolicy acl}.
|
||||||
*
|
*
|
||||||
* @return metaData populated with lastModified and etag of the new object
|
* @see S3Connection#putObject(String, S3Object)
|
||||||
* @see CopyObjectOptions
|
* @see PutObjectOptions
|
||||||
|
* @param options
|
||||||
|
* options for creating the object
|
||||||
|
* @throws HttpResponseException
|
||||||
|
* if the conditions requested set are not satisfied by the
|
||||||
|
* object on the server.
|
||||||
*/
|
*/
|
||||||
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
||||||
String sourceObject, String destinationBucket,
|
String sourceObject, String destinationBucket,
|
||||||
String destinationObject, CopyObjectOptions options);
|
String destinationObject, CopyObjectOptions options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HeadBucket
|
||||||
|
*/
|
||||||
Future<Boolean> bucketExists(String name);
|
Future<Boolean> bucketExists(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Retrieve a complete <code>S3Bucket</code> listing.
|
||||||
*
|
*
|
||||||
* @param s3Bucket
|
* @see ListBucket
|
||||||
* @return
|
* @param bucketName
|
||||||
|
* namespace of the objects you wish to list
|
||||||
|
*
|
||||||
|
* @return Future reference to a fully populated S3Bucket including metadata
|
||||||
|
* of the S3Objects it contains or {@link S3Bucket#NOT_FOUND} if not
|
||||||
|
* present.
|
||||||
*/
|
*/
|
||||||
Future<S3Bucket> listBucket(String name);
|
Future<S3Bucket> listBucket(String bucketName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like {@link #listBucket(String)} except you can use
|
||||||
|
* {@link ListObjectOptions} to control the amount of S3Objects to return.
|
||||||
|
*
|
||||||
|
* @see #listBucket(String)
|
||||||
|
* @see ListBucketOptions
|
||||||
|
* @return S3Bucket containing a subset of {@link S3Object.Metadata}
|
||||||
|
* depending on
|
||||||
|
* <code>options</options> specified or {@link S3Bucket#NOT_FOUND} if not present.
|
||||||
|
*
|
||||||
|
*/
|
||||||
Future<S3Bucket> listBucket(String name, ListBucketOptions options);
|
Future<S3Bucket> listBucket(String name, ListBucketOptions options);
|
||||||
|
|
||||||
Future<List<S3Bucket.Metadata>> getOwnedBuckets();
|
/**
|
||||||
|
* @see ListOwnedBuckets
|
||||||
|
* @return list of all of the buckets owned by the authenticated sender of
|
||||||
|
* the request.
|
||||||
|
*/
|
||||||
|
Future<List<S3Bucket.Metadata>> listOwnedBuckets();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an authenticated context to S3.
|
||||||
|
*
|
||||||
|
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this
|
||||||
|
* context in order to release resources.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @see S3Connection
|
||||||
|
* @see S3InputStreamMap
|
||||||
|
* @see S3ObjectMap
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
public interface S3Context {
|
public interface S3Context {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* low-level api to S3. Threadsafe implementations will return a singleton.
|
||||||
|
*
|
||||||
* @return a connection to S3
|
* @return a connection to S3
|
||||||
*/
|
*/
|
||||||
S3Connection getConnection();
|
S3Connection getConnection();
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.aws.s3.S3Constants.PROPERTY_AWS_ACCESSKEYID;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_ACCESSKEYID;
|
||||||
import static org.jclouds.aws.s3.S3Constants.PROPERTY_AWS_SECRETACCESSKEY;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||||
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
|
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
|
||||||
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
|
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
|
||||||
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
|
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
|
||||||
|
@ -58,7 +58,17 @@ import com.google.inject.name.Names;
|
||||||
/**
|
/**
|
||||||
* Creates {@link S3Context} or {@link Injector} instances based on the most
|
* Creates {@link S3Context} or {@link Injector} instances based on the most
|
||||||
* commonly requested arguments.
|
* commonly requested arguments.
|
||||||
|
* <p/>
|
||||||
|
* Note that Threadsafe objects will be bound as singletons to the Injector or
|
||||||
|
* Context provided.
|
||||||
*
|
*
|
||||||
|
* <p/>
|
||||||
|
* If no <code>Module</code>s are specified, the default
|
||||||
|
* {@link JDKLoggingModule logging} and
|
||||||
|
* {@link JavaUrlHttpFutureCommandClientModule http transports} will be
|
||||||
|
* installed.
|
||||||
|
*
|
||||||
|
* @see S3Context
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class S3ContextFactory {
|
public class S3ContextFactory {
|
||||||
|
|
|
@ -27,7 +27,20 @@ import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface S3InputStreamMap extends Map<String, InputStream>, S3Map {
|
/**
|
||||||
|
* Map view of an {@link S3Bucket}. Provides additional methods for inserting
|
||||||
|
* common object types.
|
||||||
|
*
|
||||||
|
* <h2>Note</h2> All <code>put</code> operations will invoke
|
||||||
|
* {@link S3Object#generateMd5}. By extension, {@link #put(String, InputStream)}
|
||||||
|
* will result in the InputStream being converted to a byte array. For this
|
||||||
|
* reason, do not use {@link #put(String, InputStream)} to store files. Use
|
||||||
|
* {@link #putFile(String, File)} or {@link S3ObjectMap} instead.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface S3InputStreamMap extends S3Map<String, InputStream> {
|
||||||
InputStream putString(String key, String value);
|
InputStream putString(String key, String value);
|
||||||
|
|
||||||
InputStream putFile(String key, File value);
|
InputStream putFile(String key, File value);
|
||||||
|
|
|
@ -23,10 +23,23 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
|
||||||
public interface S3Map {
|
/**
|
||||||
|
* All Map views of {@link S3Bucket}s provide means to access the underlying S3
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface S3Map<K, V> extends Map<K, V> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return s3 bucket listing that this map represents
|
||||||
|
*/
|
||||||
S3Bucket getBucket();
|
S3Bucket getBucket();
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,10 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import java.util.Map;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
|
||||||
public interface S3ObjectMap extends Map<String, S3Object>, S3Map {
|
/**
|
||||||
|
* Map view of an {@link S3Bucket}.
|
||||||
|
*
|
||||||
|
* <p/>
|
||||||
|
* This allows you to acces the underlying {@link S3Object} so that you can
|
||||||
|
* manually set metadata such as length, content-type, or md5 hash.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface S3ObjectMap extends S3Map<String, S3Object> {
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,31 +26,50 @@ package org.jclouds.aws.s3;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
import org.jclouds.aws.s3.domain.S3Error;
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates an S3 Error from Amazon.
|
||||||
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html
|
||||||
|
* @see S3Error
|
||||||
|
* @see ParseS3ErrorFromXmlContent
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class S3ResponseException extends HttpResponseException {
|
||||||
|
|
||||||
public class S3ResponseException extends RuntimeException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final HttpFutureCommand<?> command;
|
private S3Error error = new S3Error();
|
||||||
private final HttpResponse response;
|
|
||||||
private S3Error error;
|
|
||||||
|
|
||||||
public S3ResponseException(HttpFutureCommand<?> command,
|
public S3ResponseException(HttpFutureCommand<?> command,
|
||||||
HttpResponse response, S3Error error) {
|
HttpResponse response, S3Error error) {
|
||||||
super(String.format(
|
super(error.toString(), command, response);
|
||||||
"command: %1s failed with response: %2s; error from s3: %3s",
|
|
||||||
command, response, error));
|
|
||||||
this.command = command;
|
|
||||||
this.response = response;
|
|
||||||
this.setError(error);
|
this.setError(error);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3ResponseException(HttpFutureCommand<?> command,
|
public S3ResponseException(HttpFutureCommand<?> command,
|
||||||
HttpResponse response) {
|
HttpResponse response, S3Error error, Throwable cause) {
|
||||||
super(String.format("command: %1s failed with response: %2s", command,
|
super(error.toString(), command, response, cause);
|
||||||
response));
|
this.setError(error);
|
||||||
this.command = command;
|
|
||||||
this.response = response;
|
}
|
||||||
|
|
||||||
|
public S3ResponseException(String message, HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, S3Error error) {
|
||||||
|
super(message, command, response);
|
||||||
|
this.setError(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public S3ResponseException(String message, HttpFutureCommand<?> command,
|
||||||
|
HttpResponse response, S3Error error, Throwable cause) {
|
||||||
|
super(message, command, response, cause);
|
||||||
|
this.setError(error);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setError(S3Error error) {
|
public void setError(S3Error error) {
|
||||||
|
@ -61,12 +80,4 @@ public class S3ResponseException extends RuntimeException {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpFutureCommand<?> getCommand() {
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpResponse getResponse() {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -37,6 +37,12 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issues a HEAD command to determine if the bucket exists or not.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class BucketExists extends S3FutureCommand<Boolean> {
|
public class BucketExists extends S3FutureCommand<Boolean> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -57,8 +63,9 @@ public class BucketExists extends S3FutureCommand<Boolean> {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||||
if (e.getCause() != null && e.getCause() instanceof S3ResponseException) {
|
if (e.getCause() != null
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
&& e.getCause() instanceof HttpResponseException) {
|
||||||
|
HttpResponseException responseException = (HttpResponseException) e
|
||||||
.getCause();
|
.getCause();
|
||||||
if (responseException.getResponse().getStatusCode() == 404) {
|
if (responseException.getResponse().getStatusCode() == 404) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -34,6 +34,25 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The copy operation creates a copy of an object that is already storedin
|
||||||
|
* Amazon S3.
|
||||||
|
* <p/>
|
||||||
|
* When copying an object, you can preserve all metadata (default) or
|
||||||
|
* {@link CopyObjectOptions#overrideMetadataWith(com.google.common.collect.Multimap)
|
||||||
|
* specify new metadata}. However, the ACL is not preserved and is set to
|
||||||
|
* private for the user making the request. To override the default ACL setting,
|
||||||
|
* {@link CopyObjectOptions#overrideAcl(org.jclouds.aws.s3.domain.acl.CannedAccessPolicy)
|
||||||
|
* specify a new ACL} when generating a copy request.
|
||||||
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY
|
||||||
|
* .html
|
||||||
|
* @see CopyObjectOptions
|
||||||
|
* @see CannedAccessPolicy
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CopyObject extends S3FutureCommand<S3Object.Metadata> {
|
public class CopyObject extends S3FutureCommand<S3Object.Metadata> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -51,9 +70,9 @@ public class CopyObject extends S3FutureCommand<S3Object.Metadata> {
|
||||||
handler.setKey(destinationObject);
|
handler.setKey(destinationObject);
|
||||||
getRequest().getHeaders().put(
|
getRequest().getHeaders().put(
|
||||||
"x-amz-copy-source",
|
"x-amz-copy-source",
|
||||||
String.format("/%1s/%2s", checkNotNull(sourceBucket,
|
String.format("/%1$s/%2$s", checkNotNull(sourceBucket,
|
||||||
"sourceBucket"), checkNotNull(
|
"sourceBucket"), checkNotNull(sourceObject,
|
||||||
sourceObject, "sourceObject")));
|
"sourceObject")));
|
||||||
getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.aws.s3.S3ResponseException;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -35,6 +36,17 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DELETE request operation deletes the bucket named in the URI. All objects
|
||||||
|
* in the bucket must be deleted before the bucket itself can be deleted.
|
||||||
|
* <p />
|
||||||
|
* Only the owner of a bucket can delete it, regardless of the bucket's access
|
||||||
|
* control policy.
|
||||||
|
*
|
||||||
|
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
|
||||||
|
* RESTBucketDELETE.html
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
public class DeleteBucket extends S3FutureCommand<Boolean> {
|
public class DeleteBucket extends S3FutureCommand<Boolean> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -54,7 +66,8 @@ public class DeleteBucket extends S3FutureCommand<Boolean> {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
Boolean attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||||
if (e.getCause() != null && e.getCause() instanceof S3ResponseException) {
|
if (e.getCause() != null
|
||||||
|
&& e.getCause() instanceof HttpResponseException) {
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
S3ResponseException responseException = (S3ResponseException) e
|
||||||
.getCause();
|
.getCause();
|
||||||
if (responseException.getResponse().getStatusCode() == 404) {
|
if (responseException.getResponse().getStatusCode() == 404) {
|
||||||
|
|
|
@ -31,6 +31,14 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DELETE request operation removes the specified object from Amazon S3.
|
||||||
|
* Once deleted, there is no method to restore or undelete an object.
|
||||||
|
*
|
||||||
|
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
|
||||||
|
* RESTObjectDELETE.html
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
public class DeleteObject extends S3FutureCommand<Boolean> {
|
public class DeleteObject extends S3FutureCommand<Boolean> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
|
@ -43,8 +43,28 @@ import com.google.inject.name.Named;
|
||||||
* Retrieves the S3Object associated with the Key or {@link S3Object#NOT_FOUND}
|
* Retrieves the S3Object associated with the Key or {@link S3Object#NOT_FOUND}
|
||||||
* if not available;
|
* if not available;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* <p/>
|
||||||
|
* To use GET, you must have READ access to the object. If READ access is
|
||||||
|
* granted to the anonymous user, you can request the object without an
|
||||||
|
* authorization header.
|
||||||
|
* <p />
|
||||||
|
* <p/>
|
||||||
|
* This command allows you to specify {@link GetObjectOptions} to control
|
||||||
|
* delivery of content.
|
||||||
*
|
*
|
||||||
|
* <h2>Note</h2> If you specify any of the below options, you will receive
|
||||||
|
* partial content:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link GetObjectOptions#range}</li>
|
||||||
|
* <li>{@link GetObjectOptions#startAt}</li>
|
||||||
|
* <li>{@link GetObjectOptions#tail}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see GetObjectOptions
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET
|
||||||
|
* .html
|
||||||
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class GetObject extends S3FutureCommand<S3Object> {
|
public class GetObject extends S3FutureCommand<S3Object> {
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,9 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
|
||||||
import org.jclouds.aws.s3.commands.callables.ParseMetadataFromHeaders;
|
import org.jclouds.aws.s3.commands.callables.ParseMetadataFromHeaders;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
@ -40,15 +40,25 @@ import com.google.inject.name.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the metadata associated with the Key or
|
* Retrieves the metadata associated with the Key or
|
||||||
* {@link S3Object.Metadata#NOT_FOUND} if not available;
|
* {@link S3Object.Metadata#NOT_FOUND} if not available.
|
||||||
*
|
*
|
||||||
|
* <p/>
|
||||||
|
* The HEAD operation is used to retrieve information about a specific object or
|
||||||
|
* object size, without actually fetching the object itself. This is useful if
|
||||||
|
* you're only interested in the object metadata, and don't want to waste
|
||||||
|
* bandwidth on the object data.
|
||||||
|
*
|
||||||
|
* @see GetObject
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD
|
||||||
|
* .html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HeadMetaData extends S3FutureCommand<S3Object.Metadata> {
|
public class HeadObject extends S3FutureCommand<S3Object.Metadata> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HeadMetaData(@Named("jclouds.http.address") String amazonHost,
|
public HeadObject(@Named("jclouds.http.address") String amazonHost,
|
||||||
ParseMetadataFromHeaders callable,
|
ParseMetadataFromHeaders callable,
|
||||||
@Assisted("bucketName") String bucket, @Assisted("key") String key) {
|
@Assisted("bucketName") String bucket, @Assisted("key") String key) {
|
||||||
super("HEAD", "/" + checkNotNull(key), callable, amazonHost, bucket);
|
super("HEAD", "/" + checkNotNull(key), callable, amazonHost, bucket);
|
||||||
|
@ -68,8 +78,9 @@ public class HeadMetaData extends S3FutureCommand<S3Object.Metadata> {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
S3Object.Metadata attemptNotFound(ExecutionException e)
|
S3Object.Metadata attemptNotFound(ExecutionException e)
|
||||||
throws ExecutionException {
|
throws ExecutionException {
|
||||||
if (e.getCause() != null && e.getCause() instanceof S3ResponseException) {
|
if (e.getCause() != null
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
&& e.getCause() instanceof HttpResponseException) {
|
||||||
|
HttpResponseException responseException = (HttpResponseException) e
|
||||||
.getCause();
|
.getCause();
|
||||||
if (responseException.getResponse().getStatusCode() == 404) {
|
if (responseException.getResponse().getStatusCode() == 404) {
|
||||||
return S3Object.Metadata.NOT_FOUND;
|
return S3Object.Metadata.NOT_FOUND;
|
|
@ -31,6 +31,7 @@ import org.jclouds.aws.s3.S3ResponseException;
|
||||||
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -38,6 +39,21 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A GET request operation using a bucket URI lists information about the
|
||||||
|
* objects in the bucket.
|
||||||
|
* <p />
|
||||||
|
* To list the keys of a bucket, you must have READ access to the bucket.
|
||||||
|
* <p/>
|
||||||
|
* List output is controllable via {@link ListBucketOptions}
|
||||||
|
*
|
||||||
|
* @see ListBucketOptions
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET
|
||||||
|
* .html
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class ListBucket extends S3FutureCommand<S3Bucket> {
|
public class ListBucket extends S3FutureCommand<S3Bucket> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -62,7 +78,8 @@ public class ListBucket extends S3FutureCommand<S3Bucket> {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
S3Bucket attemptNotFound(ExecutionException e) throws ExecutionException {
|
S3Bucket attemptNotFound(ExecutionException e) throws ExecutionException {
|
||||||
if (e.getCause() != null && e.getCause() instanceof S3ResponseException) {
|
if (e.getCause() != null
|
||||||
|
&& e.getCause() instanceof HttpResponseException) {
|
||||||
S3ResponseException responseException = (S3ResponseException) e
|
S3ResponseException responseException = (S3ResponseException) e
|
||||||
.getCause();
|
.getCause();
|
||||||
if ("NoSuchBucket".equals(responseException.getError().getCode())) {
|
if ("NoSuchBucket".equals(responseException.getError().getCode())) {
|
||||||
|
|
|
@ -35,13 +35,16 @@ import com.google.inject.name.Named;
|
||||||
* Returns a list of all of the buckets owned by the authenticated sender of the
|
* Returns a list of all of the buckets owned by the authenticated sender of the
|
||||||
* request.
|
* request.
|
||||||
*
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET
|
||||||
|
* .html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GetMetaDataForOwnedBuckets extends S3FutureCommand<List<S3Bucket.Metadata>> {
|
public class ListOwnedBuckets extends S3FutureCommand<List<S3Bucket.Metadata>> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GetMetaDataForOwnedBuckets(@Named("jclouds.http.address") String amazonHost,
|
public ListOwnedBuckets(@Named("jclouds.http.address") String amazonHost,
|
||||||
ParseSax<List<S3Bucket.Metadata>> callable) {
|
ParseSax<List<S3Bucket.Metadata>> callable) {
|
||||||
super("GET", "/", callable, amazonHost);
|
super("GET", "/", callable, amazonHost);
|
||||||
}
|
}
|
|
@ -23,8 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
|
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpHeaders;
|
import org.jclouds.http.HttpHeaders;
|
||||||
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
|
||||||
|
|
||||||
|
@ -34,7 +34,16 @@ import com.google.inject.name.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and name your own bucket in which to store your objects.
|
* Create and name your own bucket in which to store your objects.
|
||||||
|
* <p/>
|
||||||
|
* The PUT request operation with a bucket URI creates a new bucket. Depending
|
||||||
|
* on your latency and legal requirements, you can specify a location constraint
|
||||||
|
* that will affect where your data physically resides. You can currently
|
||||||
|
* specify a Europe (EU) location constraint via {@link PutBucketOptions}.
|
||||||
*
|
*
|
||||||
|
* @see PutBucketOptions
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT
|
||||||
|
* .html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,18 +23,36 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.commands.callables.ParseMd5FromETagHeader;
|
import org.jclouds.aws.s3.commands.callables.ParseMd5FromETagHeader;
|
||||||
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
|
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpHeaders;
|
import org.jclouds.http.HttpHeaders;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store data by creating or overwriting an object.
|
||||||
|
*
|
||||||
|
* <p/>
|
||||||
|
* This returns a byte[] of the md5 hash of what Amazon S3 received
|
||||||
|
* <p />
|
||||||
|
* <p/>
|
||||||
|
* This command allows you to specify {@link PutObjectOptions} to control
|
||||||
|
* delivery of content.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @see PutObjectOptions
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT
|
||||||
|
* .html
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
public class PutObject extends S3FutureCommand<byte[]> {
|
public class PutObject extends S3FutureCommand<byte[]> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -43,38 +61,38 @@ public class PutObject extends S3FutureCommand<byte[]> {
|
||||||
@Assisted S3Object object, @Assisted PutObjectOptions options) {
|
@Assisted S3Object object, @Assisted PutObjectOptions options) {
|
||||||
super("PUT", "/" + checkNotNull(object.getKey()), callable, amazonHost,
|
super("PUT", "/" + checkNotNull(object.getKey()), callable, amazonHost,
|
||||||
s3Bucket);
|
s3Bucket);
|
||||||
checkArgument(object.getMetaData().getSize() >=0,"size must be set");
|
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
||||||
|
|
||||||
getRequest().setPayload(
|
getRequest().setPayload(
|
||||||
checkNotNull(object.getData(), "object.getContent()"));
|
checkNotNull(object.getData(), "object.getContent()"));
|
||||||
|
|
||||||
getRequest().getHeaders().put(
|
getRequest().getHeaders().put(
|
||||||
HttpHeaders.CONTENT_TYPE,
|
HttpHeaders.CONTENT_TYPE,
|
||||||
checkNotNull(object.getMetaData().getContentType(),
|
checkNotNull(object.getMetadata().getContentType(),
|
||||||
"object.metaData.contentType()"));
|
"object.metadata.contentType()"));
|
||||||
|
|
||||||
getRequest().getHeaders().put(HttpHeaders.CONTENT_LENGTH,
|
getRequest().getHeaders().put(HttpHeaders.CONTENT_LENGTH,
|
||||||
object.getMetaData().getSize() + "");
|
object.getMetadata().getSize() + "");
|
||||||
|
|
||||||
if (object.getMetaData().getCacheControl() != null) {
|
if (object.getMetadata().getCacheControl() != null) {
|
||||||
getRequest().getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
getRequest().getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
||||||
object.getMetaData().getCacheControl());
|
object.getMetadata().getCacheControl());
|
||||||
}
|
}
|
||||||
if (object.getMetaData().getContentDisposition() != null) {
|
if (object.getMetadata().getContentDisposition() != null) {
|
||||||
getRequest().getHeaders().put(HttpHeaders.CONTENT_DISPOSITION,
|
getRequest().getHeaders().put(HttpHeaders.CONTENT_DISPOSITION,
|
||||||
object.getMetaData().getContentDisposition());
|
object.getMetadata().getContentDisposition());
|
||||||
}
|
}
|
||||||
if (object.getMetaData().getContentEncoding() != null) {
|
if (object.getMetadata().getContentEncoding() != null) {
|
||||||
getRequest().getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
getRequest().getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
||||||
object.getMetaData().getContentEncoding());
|
object.getMetadata().getContentEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object.getMetaData().getMd5() != null)
|
if (object.getMetadata().getMd5() != null)
|
||||||
getRequest().getHeaders().put(HttpHeaders.CONTENT_MD5,
|
getRequest().getHeaders().put(HttpHeaders.CONTENT_MD5,
|
||||||
S3Utils.toBase64String(object.getMetaData().getMd5()));
|
S3Utils.toBase64String(object.getMetadata().getMd5()));
|
||||||
|
|
||||||
getRequest().getHeaders()
|
getRequest().getHeaders()
|
||||||
.putAll(object.getMetaData().getUserMetadata());
|
.putAll(object.getMetadata().getUserMetadata());
|
||||||
getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
getRequest().getHeaders().putAll(options.buildRequestHeaders());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,23 +116,23 @@ public class S3CommandFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HeadMetaDataFactory headMetaDataFactory;
|
private HeadMetadataFactory headMetadataFactory;
|
||||||
|
|
||||||
public static interface HeadMetaDataFactory {
|
public static interface HeadMetadataFactory {
|
||||||
HeadMetaData create(@Assisted("bucketName") String bucket,
|
HeadObject create(@Assisted("bucketName") String bucket,
|
||||||
@Assisted("key") String key);
|
@Assisted("key") String key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeadMetaData createHeadMetaData(String bucket, String key) {
|
public HeadObject createHeadMetadata(String bucket, String key) {
|
||||||
return headMetaDataFactory.create(bucket, key);
|
return headMetadataFactory.create(bucket, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Named("jclouds.http.address")
|
@Named("jclouds.http.address")
|
||||||
String amazonHost;
|
String amazonHost;
|
||||||
|
|
||||||
public GetMetaDataForOwnedBuckets createGetMetaDataForOwnedBuckets() {
|
public ListOwnedBuckets createGetMetadataForOwnedBuckets() {
|
||||||
return new GetMetaDataForOwnedBuckets(amazonHost, parserFactory
|
return new ListOwnedBuckets(amazonHost, parserFactory
|
||||||
.createListBucketsParser());
|
.createListBucketsParser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,12 @@
|
||||||
package org.jclouds.aws.s3.commands.callables;
|
package org.jclouds.aws.s3.commands.callables;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an MD5 checksum from the header {@link S3Headers#ETAG}.
|
* Parses an MD5 checksum from the header {@link S3Headers#ETAG}.
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,10 +25,11 @@ package org.jclouds.aws.s3.commands.callables;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object.Metadata;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
import org.jclouds.http.HttpHeaders;
|
import org.jclouds.http.HttpHeaders;
|
||||||
|
@ -52,30 +53,36 @@ public class ParseMetadataFromHeaders extends
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parses the http response headers to create a new
|
* parses the http response headers to create a new
|
||||||
* {@link S3Object.MetaData} object.
|
* {@link S3Object.Metadata} object.
|
||||||
*/
|
*/
|
||||||
public S3Object.Metadata call() throws HttpException {
|
public S3Object.Metadata call() throws HttpException {
|
||||||
checkCode();
|
checkCode();
|
||||||
|
|
||||||
S3Object.Metadata metaData = new S3Object.Metadata(key);
|
S3Object.Metadata metadata = new S3Object.Metadata(key);
|
||||||
|
addAllHeadersTo(metadata);
|
||||||
|
|
||||||
extractUserMetadata(metaData);
|
addUserMetadataTo(metadata);
|
||||||
addMd5(metaData);
|
addMd5To(metadata);
|
||||||
|
|
||||||
parseLastModifiedOrThrowException(metaData);
|
parseLastModifiedOrThrowException(metadata);
|
||||||
setContentTypeOrThrowException(metaData);
|
setContentTypeOrThrowException(metadata);
|
||||||
|
setContentLengthOrThrowException(metadata);
|
||||||
|
|
||||||
metaData.setCacheControl(getResponse().getFirstHeaderOrNull(
|
metadata.setCacheControl(getResponse().getFirstHeaderOrNull(
|
||||||
HttpHeaders.CACHE_CONTROL));
|
HttpHeaders.CACHE_CONTROL));
|
||||||
metaData.setContentDisposition(getResponse().getFirstHeaderOrNull(
|
metadata.setContentDisposition(getResponse().getFirstHeaderOrNull(
|
||||||
HttpHeaders.CONTENT_DISPOSITION));
|
HttpHeaders.CONTENT_DISPOSITION));
|
||||||
metaData.setContentEncoding(getResponse().getFirstHeaderOrNull(
|
metadata.setContentEncoding(getResponse().getFirstHeaderOrNull(
|
||||||
HttpHeaders.CONTENT_ENCODING));
|
HttpHeaders.CONTENT_ENCODING));
|
||||||
return metaData;
|
return metadata;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setContentTypeOrThrowException(S3Object.Metadata metaData)
|
private void addAllHeadersTo(Metadata metadata) {
|
||||||
|
metadata.getAllHeaders().putAll(getResponse().getHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setContentTypeOrThrowException(S3Object.Metadata metadata)
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
String contentType = getResponse().getFirstHeaderOrNull(
|
String contentType = getResponse().getFirstHeaderOrNull(
|
||||||
HttpHeaders.CONTENT_TYPE);
|
HttpHeaders.CONTENT_TYPE);
|
||||||
|
@ -83,39 +90,50 @@ public class ParseMetadataFromHeaders extends
|
||||||
throw new HttpException(HttpHeaders.CONTENT_TYPE
|
throw new HttpException(HttpHeaders.CONTENT_TYPE
|
||||||
+ " not found in headers");
|
+ " not found in headers");
|
||||||
else
|
else
|
||||||
metaData.setContentType(contentType);
|
metadata.setContentType(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseLastModifiedOrThrowException(S3Object.Metadata metaData)
|
private void setContentLengthOrThrowException(S3Object.Metadata metadata)
|
||||||
|
throws HttpException {
|
||||||
|
String contentLength = getResponse().getFirstHeaderOrNull(
|
||||||
|
HttpHeaders.CONTENT_LENGTH);
|
||||||
|
if (contentLength == null)
|
||||||
|
throw new HttpException(HttpHeaders.CONTENT_LENGTH
|
||||||
|
+ " not found in headers");
|
||||||
|
else
|
||||||
|
metadata.setSize(Long.parseLong(contentLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseLastModifiedOrThrowException(S3Object.Metadata metadata)
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
String lastModified = getResponse().getFirstHeaderOrNull(
|
String lastModified = getResponse().getFirstHeaderOrNull(
|
||||||
HttpHeaders.LAST_MODIFIED);
|
HttpHeaders.LAST_MODIFIED);
|
||||||
metaData.setLastModified(dateParser
|
metadata.setLastModified(dateParser
|
||||||
.dateTimeFromHeaderFormat(lastModified));
|
.dateTimeFromHeaderFormat(lastModified));
|
||||||
if (metaData.getLastModified() == null)
|
if (metadata.getLastModified() == null)
|
||||||
throw new HttpException("could not parse: "
|
throw new HttpException("could not parse: "
|
||||||
+ HttpHeaders.LAST_MODIFIED + ": " + lastModified);
|
+ HttpHeaders.LAST_MODIFIED + ": " + lastModified);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMd5(S3Object.Metadata metaData) {
|
private void addMd5To(S3Object.Metadata metadata) {
|
||||||
String md5Header = getResponse()
|
String md5Header = getResponse()
|
||||||
.getFirstHeaderOrNull(S3Headers.AMZ_MD5);
|
.getFirstHeaderOrNull(S3Headers.AMZ_MD5);
|
||||||
if (md5Header != null) {
|
if (md5Header != null) {
|
||||||
metaData.setMd5(S3Utils.fromHexString(md5Header));
|
metadata.setMd5(S3Utils.fromHexString(md5Header));
|
||||||
}
|
}
|
||||||
String eTag = getResponse().getFirstHeaderOrNull(S3Headers.ETAG);
|
String eTag = getResponse().getFirstHeaderOrNull(S3Headers.ETAG);
|
||||||
if (metaData.getMd5() == null && eTag != null) {
|
if (metadata.getMd5() == null && eTag != null) {
|
||||||
metaData.setMd5(S3Utils.fromHexString(eTag.replaceAll("\"", "")));
|
metadata.setMd5(S3Utils.fromHexString(eTag.replaceAll("\"", "")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void extractUserMetadata(S3Object.Metadata metaData) {
|
private void addUserMetadataTo(S3Object.Metadata metadata) {
|
||||||
for (Entry<String, String> header : getResponse().getHeaders()
|
for (Entry<String, String> header : getResponse().getHeaders()
|
||||||
.entries()) {
|
.entries()) {
|
||||||
if (header.getKey() != null
|
if (header.getKey() != null
|
||||||
&& header.getKey().startsWith(
|
&& header.getKey().startsWith(
|
||||||
S3Headers.USER_METADATA_PREFIX))
|
S3Headers.USER_METADATA_PREFIX))
|
||||||
metaData.getUserMetadata().put(header.getKey(),
|
metadata.getUserMetadata().put(header.getKey(),
|
||||||
header.getValue());
|
header.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
package org.jclouds.aws.s3.commands.callables;
|
package org.jclouds.aws.s3.commands.callables;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.domain.S3Object.Metadata;
|
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
import org.jclouds.http.HttpHeaders;
|
import org.jclouds.http.HttpHeaders;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,11 +39,12 @@ import com.google.inject.Inject;
|
||||||
*/
|
*/
|
||||||
public class ParseObjectFromHeadersAndHttpContent extends
|
public class ParseObjectFromHeadersAndHttpContent extends
|
||||||
HttpFutureCommand.ResponseCallable<S3Object> {
|
HttpFutureCommand.ResponseCallable<S3Object> {
|
||||||
private final ParseMetadataFromHeaders metaDataParser;
|
private final ParseMetadataFromHeaders metadataParser;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ParseObjectFromHeadersAndHttpContent(ParseMetadataFromHeaders metaDataParser) {
|
public ParseObjectFromHeadersAndHttpContent(
|
||||||
this.metaDataParser = metaDataParser;
|
ParseMetadataFromHeaders metadataParser) {
|
||||||
|
this.metadataParser = metadataParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,26 +57,38 @@ public class ParseObjectFromHeadersAndHttpContent extends
|
||||||
*/
|
*/
|
||||||
public S3Object call() throws HttpException {
|
public S3Object call() throws HttpException {
|
||||||
checkCode();
|
checkCode();
|
||||||
metaDataParser.setResponse(getResponse());
|
metadataParser.setResponse(getResponse());
|
||||||
S3Object.Metadata metaData = metaDataParser.call();
|
S3Object.Metadata metadata = metadataParser.call();
|
||||||
|
S3Object object = new S3Object(metadata, getResponse().getContent());
|
||||||
parseContentLengthOrThrowException(metaData);
|
parseContentLengthOrThrowException(object);
|
||||||
return new S3Object(metaData, getResponse().getContent());
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseContentLengthOrThrowException(Metadata metaData)
|
@VisibleForTesting
|
||||||
|
void parseContentLengthOrThrowException(S3Object object)
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
String contentLength = getResponse().getFirstHeaderOrNull(
|
String contentLength = getResponse().getFirstHeaderOrNull(
|
||||||
HttpHeaders.CONTENT_LENGTH);
|
HttpHeaders.CONTENT_LENGTH);
|
||||||
|
String contentRange = getResponse().getFirstHeaderOrNull(
|
||||||
|
HttpHeaders.CONTENT_RANGE);
|
||||||
if (contentLength == null)
|
if (contentLength == null)
|
||||||
throw new HttpException(HttpHeaders.CONTENT_LENGTH
|
throw new HttpException(HttpHeaders.CONTENT_LENGTH
|
||||||
+ " header not present in headers: "
|
+ " header not present in headers: "
|
||||||
+ getResponse().getHeaders());
|
+ getResponse().getHeaders());
|
||||||
metaData.setSize(Long.parseLong(contentLength));
|
object.setContentLength(Long.parseLong(contentLength));
|
||||||
|
|
||||||
|
if (contentRange == null) {
|
||||||
|
object.getMetadata().setSize(object.getContentLength());
|
||||||
|
} else {
|
||||||
|
object.setContentRange(contentRange);
|
||||||
|
object.getMetadata().setSize(
|
||||||
|
Long.parseLong(contentRange.substring(contentRange
|
||||||
|
.lastIndexOf('/')+1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(String key) {
|
public void setKey(String key) {
|
||||||
this.metaDataParser.setKey(key);
|
this.metadataParser.setKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -27,7 +27,7 @@ import org.jclouds.aws.s3.commands.BucketExists;
|
||||||
import org.jclouds.aws.s3.commands.DeleteBucket;
|
import org.jclouds.aws.s3.commands.DeleteBucket;
|
||||||
import org.jclouds.aws.s3.commands.DeleteObject;
|
import org.jclouds.aws.s3.commands.DeleteObject;
|
||||||
import org.jclouds.aws.s3.commands.GetObject;
|
import org.jclouds.aws.s3.commands.GetObject;
|
||||||
import org.jclouds.aws.s3.commands.HeadMetaData;
|
import org.jclouds.aws.s3.commands.HeadObject;
|
||||||
import org.jclouds.aws.s3.commands.PutBucket;
|
import org.jclouds.aws.s3.commands.PutBucket;
|
||||||
import org.jclouds.aws.s3.commands.PutObject;
|
import org.jclouds.aws.s3.commands.PutObject;
|
||||||
import org.jclouds.aws.s3.commands.S3CommandFactory;
|
import org.jclouds.aws.s3.commands.S3CommandFactory;
|
||||||
|
@ -76,10 +76,10 @@ public class S3CommandsModule extends AbstractModule {
|
||||||
S3CommandFactory.GetObjectFactory.class,
|
S3CommandFactory.GetObjectFactory.class,
|
||||||
GetObject.class));
|
GetObject.class));
|
||||||
|
|
||||||
bind(S3CommandFactory.HeadMetaDataFactory.class).toProvider(
|
bind(S3CommandFactory.HeadMetadataFactory.class).toProvider(
|
||||||
FactoryProvider.newFactory(
|
FactoryProvider.newFactory(
|
||||||
S3CommandFactory.HeadMetaDataFactory.class,
|
S3CommandFactory.HeadMetadataFactory.class,
|
||||||
HeadMetaData.class));
|
HeadObject.class));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,10 @@ import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ import com.google.common.collect.Multimap;
|
||||||
*
|
*
|
||||||
* // this will copy the object, provided it wasn't modified since yesterday.
|
* // this will copy the object, provided it wasn't modified since yesterday.
|
||||||
* // it will not use metadata from the source, and instead use what we pass in.
|
* // it will not use metadata from the source, and instead use what we pass in.
|
||||||
* Future<S3Object.MetaData> object = connection.copyObject("sourceBucket", "objectName",
|
* Future<S3Object.Metadata> object = connection.copyObject("sourceBucket", "objectName",
|
||||||
* "destinationBucket", "destinationName",
|
* "destinationBucket", "destinationName",
|
||||||
* overrideMetadataWith(meta).
|
* overrideMetadataWith(meta).
|
||||||
* ifSourceModifiedSince(new DateTime().minusDays(1))
|
* ifSourceModifiedSince(new DateTime().minusDays(1))
|
||||||
|
@ -75,6 +77,27 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
private Multimap<String, String> metadata;
|
private Multimap<String, String> metadata;
|
||||||
|
|
||||||
|
private CannedAccessPolicy acl = CannedAccessPolicy.PRIVATE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the default ACL (private) with the specified one.
|
||||||
|
*
|
||||||
|
* @see CannedAccessPolicy
|
||||||
|
*/
|
||||||
|
public CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
|
||||||
|
this.acl = checkNotNull(acl, "acl");
|
||||||
|
if (!acl.equals(CannedAccessPolicy.PRIVATE))
|
||||||
|
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
|
||||||
|
*/
|
||||||
|
public CannedAccessPolicy getAcl() {
|
||||||
|
return acl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use in the header x-amz-copy-source-if-unmodified-since
|
* For use in the header x-amz-copy-source-if-unmodified-since
|
||||||
* <p />
|
* <p />
|
||||||
|
@ -201,7 +224,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
"ifMd5DoesntMatch() is not compatible with ifMd5Matches()");
|
"ifMd5DoesntMatch() is not compatible with ifMd5Matches()");
|
||||||
checkState(getIfModifiedSince() == null,
|
checkState(getIfModifiedSince() == null,
|
||||||
"ifModifiedSince() is not compatible with ifMd5Matches()");
|
"ifModifiedSince() is not compatible with ifMd5Matches()");
|
||||||
replaceHeader("x-amz-copy-source-if-match", String.format("\"%1s\"",
|
replaceHeader("x-amz-copy-source-if-match", String.format("\"%1$s\"",
|
||||||
S3Utils.toHexString(checkNotNull(md5, "md5"))));
|
S3Utils.toHexString(checkNotNull(md5, "md5"))));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +249,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
.checkState(getIfUnmodifiedSince() == null,
|
.checkState(getIfUnmodifiedSince() == null,
|
||||||
"ifUnmodifiedSince() is not compatible with ifMd5DoesntMatch()");
|
"ifUnmodifiedSince() is not compatible with ifMd5DoesntMatch()");
|
||||||
replaceHeader("x-amz-copy-source-if-none-match", String.format(
|
replaceHeader("x-amz-copy-source-if-none-match", String.format(
|
||||||
"\"%1s\"", S3Utils.toHexString(checkNotNull(md5,
|
"\"%1$s\"", S3Utils.toHexString(checkNotNull(md5,
|
||||||
"ifMd5DoesntMatch"))));
|
"ifMd5DoesntMatch"))));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -257,6 +280,13 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
/**
|
||||||
|
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
|
||||||
|
*/
|
||||||
|
public static CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
|
||||||
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
|
return options.overrideAcl(acl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#getIfModifiedSince()
|
* @see CopyObjectOptions#getIfModifiedSince()
|
||||||
|
|
|
@ -24,16 +24,20 @@
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.http.HttpHeaders;
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported in the REST API for the GET object operation. <h2>
|
* Contains options supported in the REST API for the GET object operation. <h2>
|
||||||
* Usage</h2> The recommended way to instantiate a GetObjectOptions object is to
|
* Usage</h2> The recommended way to instantiate a GetObjectOptions object is to
|
||||||
|
@ -58,16 +62,42 @@ import org.joda.time.DateTime;
|
||||||
public class GetObjectOptions extends BaseHttpRequestOptions {
|
public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
private final static DateService dateService = new DateService();
|
private final static DateService dateService = new DateService();
|
||||||
public static final GetObjectOptions NONE = new GetObjectOptions();
|
public static final GetObjectOptions NONE = new GetObjectOptions();
|
||||||
|
private final List<String> ranges = new ArrayList<String>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Multimap<String, String> buildRequestHeaders() {
|
||||||
|
Multimap<String, String> headers = super.buildRequestHeaders();
|
||||||
|
String range = getRange();
|
||||||
|
if (range != null)
|
||||||
|
headers.put(HttpHeaders.RANGE, this.getRange());
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only download the specified range of the object.
|
* download the specified range of the object.
|
||||||
*/
|
*/
|
||||||
public GetObjectOptions range(long start, long end) {
|
public GetObjectOptions range(long start, long end) {
|
||||||
checkState(start >= 0, "start must be >= 0");
|
checkArgument(start >= 0, "start must be >= 0");
|
||||||
checkState(end >= 0, "end must be >= 0");
|
checkArgument(end >= 0, "end must be >= 0");
|
||||||
headers
|
ranges.add(String.format("%d-%d", start, end));
|
||||||
.put(S3Headers.RANGE, String
|
return this;
|
||||||
.format("bytes=%1d-%2d", start, end));
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* download the object offset at <code>start</code>
|
||||||
|
*/
|
||||||
|
public GetObjectOptions startAt(long start) {
|
||||||
|
checkArgument(start >= 0, "start must be >= 0");
|
||||||
|
ranges.add(String.format("%d-", start));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* download the last <code>count</code> bytes of the object
|
||||||
|
*/
|
||||||
|
public GetObjectOptions tail(long count) {
|
||||||
|
checkArgument(count > 0, "count must be > 0");
|
||||||
|
ranges.add(String.format("-%d", count));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +108,8 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see GetObjectOptions#range(long, long)
|
* @see GetObjectOptions#range(long, long)
|
||||||
*/
|
*/
|
||||||
public String getRange() {
|
public String getRange() {
|
||||||
return this.getFirstHeaderOrNull(S3Headers.RANGE);
|
return (ranges.size() > 0) ? String.format("bytes=%s", Joiner.on(",")
|
||||||
|
.join(ranges)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,11 +119,11 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* {@link #ifUnmodifiedSince(DateTime)}
|
* {@link #ifUnmodifiedSince(DateTime)}
|
||||||
*/
|
*/
|
||||||
public GetObjectOptions ifModifiedSince(DateTime ifModifiedSince) {
|
public GetObjectOptions ifModifiedSince(DateTime ifModifiedSince) {
|
||||||
checkState(getIfMatch() == null,
|
checkArgument(getIfMatch() == null,
|
||||||
"ifMd5Matches() is not compatible with ifModifiedSince()");
|
"ifMd5Matches() is not compatible with ifModifiedSince()");
|
||||||
checkState(getIfUnmodifiedSince() == null,
|
checkArgument(getIfUnmodifiedSince() == null,
|
||||||
"ifUnmodifiedSince() is not compatible with ifModifiedSince()");
|
"ifUnmodifiedSince() is not compatible with ifModifiedSince()");
|
||||||
this.headers.put(S3Headers.OBJECT_IF_MODIFIED_SINCE,
|
this.headers.put(HttpHeaders.IF_MODIFIED_SINCE,
|
||||||
dateService.toHeaderString(checkNotNull(ifModifiedSince,
|
dateService.toHeaderString(checkNotNull(ifModifiedSince,
|
||||||
"ifModifiedSince")));
|
"ifModifiedSince")));
|
||||||
return this;
|
return this;
|
||||||
|
@ -107,7 +138,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see GetObjectOptions#ifModifiedSince(DateTime)
|
* @see GetObjectOptions#ifModifiedSince(DateTime)
|
||||||
*/
|
*/
|
||||||
public String getIfModifiedSince() {
|
public String getIfModifiedSince() {
|
||||||
return this.getFirstHeaderOrNull(S3Headers.OBJECT_IF_MODIFIED_SINCE);
|
return this.getFirstHeaderOrNull(HttpHeaders.IF_MODIFIED_SINCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,11 +148,11 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* {@link #ifModifiedSince(DateTime)}
|
* {@link #ifModifiedSince(DateTime)}
|
||||||
*/
|
*/
|
||||||
public GetObjectOptions ifUnmodifiedSince(DateTime ifUnmodifiedSince) {
|
public GetObjectOptions ifUnmodifiedSince(DateTime ifUnmodifiedSince) {
|
||||||
checkState(getIfNoneMatch() == null,
|
checkArgument(getIfNoneMatch() == null,
|
||||||
"ifMd5DoesntMatch() is not compatible with ifUnmodifiedSince()");
|
"ifMd5DoesntMatch() is not compatible with ifUnmodifiedSince()");
|
||||||
checkState(getIfModifiedSince() == null,
|
checkArgument(getIfModifiedSince() == null,
|
||||||
"ifModifiedSince() is not compatible with ifUnmodifiedSince()");
|
"ifModifiedSince() is not compatible with ifUnmodifiedSince()");
|
||||||
this.headers.put(S3Headers.OBJECT_IF_UNMODIFIED_SINCE, dateService
|
this.headers.put(HttpHeaders.IF_UNMODIFIED_SINCE, dateService
|
||||||
.toHeaderString(checkNotNull(ifUnmodifiedSince,
|
.toHeaderString(checkNotNull(ifUnmodifiedSince,
|
||||||
"ifUnmodifiedSince")));
|
"ifUnmodifiedSince")));
|
||||||
return this;
|
return this;
|
||||||
|
@ -136,7 +167,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see GetObjectOptions#ifUnmodifiedSince(DateTime)
|
* @see GetObjectOptions#ifUnmodifiedSince(DateTime)
|
||||||
*/
|
*/
|
||||||
public String getIfUnmodifiedSince() {
|
public String getIfUnmodifiedSince() {
|
||||||
return this.getFirstHeaderOrNull(S3Headers.OBJECT_IF_UNMODIFIED_SINCE);
|
return this.getFirstHeaderOrNull(HttpHeaders.IF_UNMODIFIED_SINCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,11 +184,11 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
*/
|
*/
|
||||||
public GetObjectOptions ifMd5Matches(byte[] md5)
|
public GetObjectOptions ifMd5Matches(byte[] md5)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
checkState(getIfNoneMatch() == null,
|
checkArgument(getIfNoneMatch() == null,
|
||||||
"ifMd5DoesntMatch() is not compatible with ifMd5Matches()");
|
"ifMd5DoesntMatch() is not compatible with ifMd5Matches()");
|
||||||
checkState(getIfModifiedSince() == null,
|
checkArgument(getIfModifiedSince() == null,
|
||||||
"ifModifiedSince() is not compatible with ifMd5Matches()");
|
"ifModifiedSince() is not compatible with ifMd5Matches()");
|
||||||
this.headers.put(S3Headers.OBJECT_IF_MATCH, String.format("\"%1s\"",
|
this.headers.put(HttpHeaders.IF_MATCH, String.format("\"%1$s\"",
|
||||||
S3Utils.toHexString(checkNotNull(md5, "md5"))));
|
S3Utils.toHexString(checkNotNull(md5, "md5"))));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +202,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see GetObjectOptions#ifMd5Matches(String)
|
* @see GetObjectOptions#ifMd5Matches(String)
|
||||||
*/
|
*/
|
||||||
public String getIfMatch() {
|
public String getIfMatch() {
|
||||||
return this.getFirstHeaderOrNull(S3Headers.OBJECT_IF_MATCH);
|
return this.getFirstHeaderOrNull(HttpHeaders.IF_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,13 +219,12 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
*/
|
*/
|
||||||
public GetObjectOptions ifMd5DoesntMatch(byte[] md5)
|
public GetObjectOptions ifMd5DoesntMatch(byte[] md5)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
checkState(getIfMatch() == null,
|
checkArgument(getIfMatch() == null,
|
||||||
"ifMd5Matches() is not compatible with ifMd5DoesntMatch()");
|
"ifMd5Matches() is not compatible with ifMd5DoesntMatch()");
|
||||||
checkState(getIfUnmodifiedSince() == null,
|
checkArgument(getIfUnmodifiedSince() == null,
|
||||||
"ifUnmodifiedSince() is not compatible with ifMd5DoesntMatch()");
|
"ifUnmodifiedSince() is not compatible with ifMd5DoesntMatch()");
|
||||||
this.headers.put(S3Headers.OBJECT_IF_NONE_MATCH, String.format(
|
this.headers.put(HttpHeaders.IF_NONE_MATCH, String.format("\"%1$s\"",
|
||||||
"\"%1s\"", S3Utils.toHexString(checkNotNull(md5,
|
S3Utils.toHexString(checkNotNull(md5, "ifMd5DoesntMatch"))));
|
||||||
"ifMd5DoesntMatch"))));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +237,8 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see GetObjectOptions#ifMd5DoesntMatch(String)
|
* @see GetObjectOptions#ifMd5DoesntMatch(String)
|
||||||
*/
|
*/
|
||||||
public String getIfNoneMatch() {
|
public String getIfNoneMatch() {
|
||||||
return this.getFirstHeaderOrNull(S3Headers.OBJECT_IF_NONE_MATCH);
|
return this
|
||||||
|
.getFirstHeaderOrNull(org.jclouds.http.HttpHeaders.IF_NONE_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
@ -220,6 +251,22 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
|
||||||
return options.range(start, end);
|
return options.range(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see GetObjectOptions#startAt(long)
|
||||||
|
*/
|
||||||
|
public static GetObjectOptions startAt(long start) {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
return options.startAt(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see GetObjectOptions#tail(long)
|
||||||
|
*/
|
||||||
|
public static GetObjectOptions tail(long count) {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
return options.tail(count);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see GetObjectOptions#getIfModifiedSince()
|
* @see GetObjectOptions#getIfModifiedSince()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,11 +23,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +39,7 @@ import static com.google.common.base.Preconditions.*;
|
||||||
* <p/>
|
* <p/>
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
|
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
|
||||||
* import static org.jclouds.aws.s3.domain.S3Bucket.MetaData.LocationConstraint.*;
|
* import static org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint.*;
|
||||||
* import org.jclouds.aws.s3.S3Connection;
|
* import org.jclouds.aws.s3.S3Connection;
|
||||||
*
|
*
|
||||||
* S3Connection connection = // get connection
|
* S3Connection connection = // get connection
|
||||||
|
@ -64,7 +65,7 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
|
||||||
this.constraint = checkNotNull(constraint, "constraint");
|
this.constraint = checkNotNull(constraint, "constraint");
|
||||||
this.payload = String
|
this.payload = String
|
||||||
.format(
|
.format(
|
||||||
"<CreateBucketConfiguration><LocationConstraint>%1s</LocationConstraint></CreateBucketConfiguration>",
|
"<CreateBucketConfiguration><LocationConstraint>%1$s</LocationConstraint></CreateBucketConfiguration>",
|
||||||
constraint.toString());
|
constraint.toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.jclouds.aws.s3.internal.GuiceS3Context;
|
||||||
import org.jclouds.aws.s3.internal.LiveS3Connection;
|
import org.jclouds.aws.s3.internal.LiveS3Connection;
|
||||||
import org.jclouds.aws.s3.internal.LiveS3InputStreamMap;
|
import org.jclouds.aws.s3.internal.LiveS3InputStreamMap;
|
||||||
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
|
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
|
||||||
|
import org.jclouds.http.CloseContentAndSetExceptionHandler;
|
||||||
import org.jclouds.http.HttpConstants;
|
import org.jclouds.http.HttpConstants;
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
|
@ -88,13 +89,14 @@ public class S3ContextModule extends AbstractModule {
|
||||||
LiveS3InputStreamMap.class));
|
LiveS3InputStreamMap.class));
|
||||||
bind(S3Context.class).to(GuiceS3Context.class);
|
bind(S3Context.class).to(GuiceS3Context.class);
|
||||||
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class)
|
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class)
|
||||||
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
.to(CloseContentAndSetExceptionHandler.class).in(
|
||||||
|
Scopes.SINGLETON);
|
||||||
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class)
|
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class)
|
||||||
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||||
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
|
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
|
||||||
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||||
requestInjection(this);
|
requestInjection(this);
|
||||||
logger.info("S3 Context = %1s://%2s:%3s",
|
logger.info("S3 Context = %1$s://%2$s:%3$s",
|
||||||
(isSecure ? "https" : "http"), address, port);
|
(isSecure ? "https" : "http"), address, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,47 +24,69 @@
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO: Adrian: Document this!
|
* Every bucket and object in Amazon S3 has an owner, the user that created the
|
||||||
|
* bucket or object. The owner of a bucket or object cannot be changed. However,
|
||||||
|
* if the object is overwritten by another user (deleted and rewritten), the new
|
||||||
|
* object will have a new owner.
|
||||||
|
* <p/>
|
||||||
*
|
*
|
||||||
|
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
|
||||||
|
* RESTAccessPolicy.html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class S3Owner {
|
public class CanonicalUser {
|
||||||
private String id;
|
private final String id;
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
|
||||||
public String getId() {
|
public CanonicalUser(String id) {
|
||||||
return id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(String id) {
|
@Override
|
||||||
this.id = id;
|
public String toString() {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("S3Owner");
|
||||||
|
sb.append("{id='").append(id).append('\'');
|
||||||
|
sb.append(", displayName='").append(displayName).append('\'');
|
||||||
|
sb.append('}');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(String displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o)
|
||||||
if (!(o instanceof S3Owner)) return false;
|
return true;
|
||||||
|
if (!(o instanceof CanonicalUser))
|
||||||
|
return false;
|
||||||
|
|
||||||
S3Owner s3Owner = (S3Owner) o;
|
CanonicalUser s3Owner = (CanonicalUser) o;
|
||||||
|
|
||||||
if (displayName != null ? !displayName.equals(s3Owner.displayName) : s3Owner.displayName != null) return false;
|
if (displayName != null ? !displayName.equals(s3Owner.displayName)
|
||||||
if (!id.equals(s3Owner.id)) return false;
|
: s3Owner.displayName != null)
|
||||||
|
return false;
|
||||||
|
if (!id.equals(s3Owner.id))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = id.hashCode();
|
int result = id.hashCode();
|
||||||
result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
|
result = 31 * result
|
||||||
return result;
|
+ (displayName != null ? displayName.hashCode() : 0);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -42,7 +42,7 @@ public class S3Bucket {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("S3Bucket");
|
sb.append("S3Bucket");
|
||||||
sb.append("{metaData=").append(metaData);
|
sb.append("{metadata=").append(metadata);
|
||||||
sb.append(", isComplete=").append(isComplete);
|
sb.append(", isComplete=").append(isComplete);
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -59,7 +59,7 @@ public class S3Bucket {
|
||||||
|
|
||||||
if (isComplete != s3Bucket.isComplete)
|
if (isComplete != s3Bucket.isComplete)
|
||||||
return false;
|
return false;
|
||||||
if (!metaData.equals(s3Bucket.metaData))
|
if (!metadata.equals(s3Bucket.metadata))
|
||||||
return false;
|
return false;
|
||||||
if (objects != null ? !objects.equals(s3Bucket.objects)
|
if (objects != null ? !objects.equals(s3Bucket.objects)
|
||||||
: s3Bucket.objects != null)
|
: s3Bucket.objects != null)
|
||||||
|
@ -71,7 +71,7 @@ public class S3Bucket {
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = objects != null ? objects.hashCode() : 0;
|
int result = objects != null ? objects.hashCode() : 0;
|
||||||
result = 31 * result + metaData.hashCode();
|
result = 31 * result + metadata.hashCode();
|
||||||
result = 31 * result + (isComplete ? 1 : 0);
|
result = 31 * result + (isComplete ? 1 : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public class S3Bucket {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("MetaData");
|
sb.append("Metadata");
|
||||||
sb.append("{name='").append(name).append('\'');
|
sb.append("{name='").append(name).append('\'');
|
||||||
sb.append(", creationDate=").append(creationDate);
|
sb.append(", creationDate=").append(creationDate);
|
||||||
sb.append(", canonicalUser=").append(canonicalUser);
|
sb.append(", canonicalUser=").append(canonicalUser);
|
||||||
|
@ -95,17 +95,12 @@ public class S3Bucket {
|
||||||
if (!(o instanceof Metadata))
|
if (!(o instanceof Metadata))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Metadata metaData = (Metadata) o;
|
Metadata metadata = (Metadata) o;
|
||||||
|
|
||||||
if (canonicalUser != null ? !canonicalUser
|
if (canonicalUser != null ? !canonicalUser
|
||||||
.equals(metaData.canonicalUser)
|
.equals(metadata.canonicalUser)
|
||||||
: metaData.canonicalUser != null)
|
: metadata.canonicalUser != null)
|
||||||
return false;
|
return false;
|
||||||
if (creationDate != null ? !creationDate
|
if (!name.equals(metadata.name))
|
||||||
.equals(metaData.creationDate)
|
|
||||||
: metaData.creationDate != null)
|
|
||||||
return false;
|
|
||||||
if (!name.equals(metaData.name))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -114,8 +109,6 @@ public class S3Bucket {
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = name.hashCode();
|
int result = name.hashCode();
|
||||||
result = 31 * result
|
|
||||||
+ (creationDate != null ? creationDate.hashCode() : 0);
|
|
||||||
result = 31 * result
|
result = 31 * result
|
||||||
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
|
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
|
@ -127,7 +120,7 @@ public class S3Bucket {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private DateTime creationDate;
|
private DateTime creationDate;
|
||||||
private S3Owner canonicalUser;
|
private CanonicalUser canonicalUser;
|
||||||
|
|
||||||
public Metadata(String name) {
|
public Metadata(String name) {
|
||||||
this.name = checkNotNull(name, "name");
|
this.name = checkNotNull(name, "name");
|
||||||
|
@ -145,11 +138,17 @@ public class S3Bucket {
|
||||||
this.creationDate = creationDate;
|
this.creationDate = creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Owner getCanonicalUser() {
|
/**
|
||||||
|
* Every bucket and object in Amazon S3 has an owner, the user that
|
||||||
|
* created the bucket or object. The owner of a bucket or object cannot
|
||||||
|
* be changed. However, if the object is overwritten by another user
|
||||||
|
* (deleted and rewritten), the new object will have a new owner.
|
||||||
|
*/
|
||||||
|
public CanonicalUser getOwner() {
|
||||||
return canonicalUser;
|
return canonicalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCanonicalUser(S3Owner canonicalUser) {
|
public void setOwner(CanonicalUser canonicalUser) {
|
||||||
this.canonicalUser = canonicalUser;
|
this.canonicalUser = canonicalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,20 +162,20 @@ public class S3Bucket {
|
||||||
private String marker;
|
private String marker;
|
||||||
private String delimiter;
|
private String delimiter;
|
||||||
private long maxKeys;
|
private long maxKeys;
|
||||||
private final Metadata metaData;
|
private final Metadata metadata;
|
||||||
|
|
||||||
private boolean isComplete;
|
private boolean isComplete;
|
||||||
|
|
||||||
public S3Bucket(String name) {
|
public S3Bucket(String name) {
|
||||||
this.metaData = new Metadata(name);
|
this.metadata = new Metadata(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.metaData.getName();
|
return this.metadata.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Bucket(Metadata metaData) {
|
public S3Bucket(Metadata metadata) {
|
||||||
this.metaData = checkNotNull(metaData, "metaData");
|
this.metadata = checkNotNull(metadata, "metadata");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<S3Object.Metadata> getContents() {
|
public Set<S3Object.Metadata> getContents() {
|
||||||
|
@ -195,8 +194,8 @@ public class S3Bucket {
|
||||||
isComplete = complete;
|
isComplete = complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Metadata getMetaData() {
|
public Metadata getMetadata() {
|
||||||
return metaData;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommonPrefixes(Set<String> commonPrefixes) {
|
public void setCommonPrefixes(Set<String> commonPrefixes) {
|
||||||
|
|
|
@ -23,17 +23,25 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an Amazon S3 request is in error, the client receives an error response.
|
||||||
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?ErrorResponse
|
||||||
|
* .html
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class S3Error {
|
public class S3Error {
|
||||||
private String code;
|
private String code;
|
||||||
private String message;
|
private String message;
|
||||||
private String resource;
|
|
||||||
private String requestId;
|
private String requestId;
|
||||||
private String hostId;
|
private String requestToken;
|
||||||
private String header;
|
private Map<String, String> details = new HashMap<String, String>();
|
||||||
private String signatureProvided;
|
|
||||||
private String stringToSign;
|
|
||||||
private String stringSigned;
|
private String stringSigned;
|
||||||
private String stringToSignBytes;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -41,17 +49,12 @@ public class S3Error {
|
||||||
sb.append("S3Error");
|
sb.append("S3Error");
|
||||||
sb.append("{code='").append(code).append('\'');
|
sb.append("{code='").append(code).append('\'');
|
||||||
sb.append(", message='").append(message).append('\'');
|
sb.append(", message='").append(message).append('\'');
|
||||||
sb.append(", resource='").append(resource).append('\'');
|
|
||||||
sb.append(", requestId='").append(requestId).append('\'');
|
sb.append(", requestId='").append(requestId).append('\'');
|
||||||
sb.append(", hostId='").append(hostId).append('\'');
|
sb.append(", requestToken='").append(requestToken).append('\'');
|
||||||
sb.append(", header='").append(header).append('\'');
|
if (stringSigned != null)
|
||||||
sb.append(", signatureProvided='").append(signatureProvided).append(
|
sb.append(", stringSigned='").append(stringSigned).append('\'');
|
||||||
'\'');
|
sb.append(", context='").append(details.toString()).append('\'')
|
||||||
sb.append(", stringToSign='").append(stringToSign).append('\'');
|
.append('}');
|
||||||
sb.append(", stringSigned='").append(getStringSigned()).append('\'');
|
|
||||||
sb.append(", stringToSignBytes='").append(stringToSignBytes).append(
|
|
||||||
'\'');
|
|
||||||
sb.append('}');
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +62,13 @@ public class S3Error {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error code is a string that uniquely identifies an error condition.
|
||||||
|
* It is meant to be read and understood by programs that detect and handle
|
||||||
|
* errors by type
|
||||||
|
*
|
||||||
|
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorCode.html
|
||||||
|
*/
|
||||||
public String getCode() {
|
public String getCode() {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -67,71 +77,58 @@ public class S3Error {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error message contains a generic description of the error condition
|
||||||
|
* in English.
|
||||||
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorMessage.html
|
||||||
|
*/
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResource(String resource) {
|
|
||||||
this.resource = resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResource() {
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequestId(String requestId) {
|
public void setRequestId(String requestId) {
|
||||||
this.requestId = requestId;
|
this.requestId = requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * A unique ID assigned to each request by the system. In the unlikely
|
||||||
|
* event that you have problems with Amazon S3, Amazon can use this to help
|
||||||
|
* troubleshoot the problem.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public String getRequestId() {
|
public String getRequestId() {
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHostId(String hostId) {
|
|
||||||
this.hostId = hostId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHostId() {
|
|
||||||
return hostId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignatureProvided(String signatureProvided) {
|
|
||||||
this.signatureProvided = signatureProvided;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignatureProvided() {
|
|
||||||
return signatureProvided;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStringToSign(String stringToSign) {
|
|
||||||
this.stringToSign = stringToSign;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStringToSign() {
|
|
||||||
return stringToSign;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStringToSignBytes(String stringToSignBytes) {
|
|
||||||
this.stringToSignBytes = stringToSignBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStringToSignBytes() {
|
|
||||||
return stringToSignBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeader(String header) {
|
|
||||||
this.header = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeader() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStringSigned(String stringSigned) {
|
public void setStringSigned(String stringSigned) {
|
||||||
this.stringSigned = stringSigned;
|
this.stringSigned = stringSigned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return what jclouds signed before sending the request.
|
||||||
|
*/
|
||||||
public String getStringSigned() {
|
public String getStringSigned() {
|
||||||
return stringSigned;
|
return stringSigned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDetails(Map<String, String> context) {
|
||||||
|
this.details = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return additional details surrounding the error.
|
||||||
|
*/
|
||||||
|
public Map<String, String> getDetails() {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestToken(String requestToken) {
|
||||||
|
this.requestToken = requestToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestToken() {
|
||||||
|
return requestToken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.aws.s3.S3Utils.Md5InputStreamResult;
|
import org.jclouds.aws.s3.util.S3Utils.Md5InputStreamResult;
|
||||||
import org.jclouds.http.ContentTypes;
|
import org.jclouds.http.ContentTypes;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
@ -48,18 +48,20 @@ public class S3Object {
|
||||||
public static final S3Object NOT_FOUND = new S3Object(Metadata.NOT_FOUND);
|
public static final S3Object NOT_FOUND = new S3Object(Metadata.NOT_FOUND);
|
||||||
|
|
||||||
private Object data;
|
private Object data;
|
||||||
private Metadata metaData;
|
private Metadata metadata;
|
||||||
|
private long contentLength = -1;
|
||||||
|
private String contentRange;
|
||||||
|
|
||||||
public S3Object(String key) {
|
public S3Object(String key) {
|
||||||
this(new Metadata(key));
|
this(new Metadata(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Object(Metadata metaData) {
|
public S3Object(Metadata metadata) {
|
||||||
this.metaData = metaData;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Object(Metadata metaData, Object data) {
|
public S3Object(Metadata metadata, Object data) {
|
||||||
this(metaData);
|
this(metadata);
|
||||||
setData(data);
|
setData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +79,7 @@ public class S3Object {
|
||||||
private volatile long size = -1;
|
private volatile long size = -1;
|
||||||
|
|
||||||
// only parsed during head or get
|
// only parsed during head or get
|
||||||
|
private Multimap<String, String> allHeaders = HashMultimap.create();
|
||||||
private Multimap<String, String> userMetadata = HashMultimap.create();
|
private Multimap<String, String> userMetadata = HashMultimap.create();
|
||||||
private DateTime lastModified;
|
private DateTime lastModified;
|
||||||
private String dataType = ContentTypes.UNKNOWN_MIME_TYPE;
|
private String dataType = ContentTypes.UNKNOWN_MIME_TYPE;
|
||||||
|
@ -85,7 +88,7 @@ public class S3Object {
|
||||||
private String dataEncoding;
|
private String dataEncoding;
|
||||||
|
|
||||||
// only parsed on list
|
// only parsed on list
|
||||||
private S3Owner owner = null;
|
private CanonicalUser owner = null;
|
||||||
private String storageClass = null;
|
private String storageClass = null;
|
||||||
|
|
||||||
public Metadata(String key) {
|
public Metadata(String key) {
|
||||||
|
@ -97,7 +100,7 @@ public class S3Object {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("MetaData");
|
sb.append("Metadata");
|
||||||
sb.append("{key='").append(key).append('\'');
|
sb.append("{key='").append(key).append('\'');
|
||||||
sb.append(", lastModified=").append(lastModified);
|
sb.append(", lastModified=").append(lastModified);
|
||||||
sb.append(", md5=").append(
|
sb.append(", md5=").append(
|
||||||
|
@ -116,20 +119,20 @@ public class S3Object {
|
||||||
if (!(o instanceof Metadata))
|
if (!(o instanceof Metadata))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Metadata metaData = (Metadata) o;
|
Metadata metadata = (Metadata) o;
|
||||||
|
|
||||||
if (size != metaData.size)
|
if (size != metadata.size)
|
||||||
return false;
|
return false;
|
||||||
if (dataType != null ? !dataType.equals(metaData.dataType)
|
if (dataType != null ? !dataType.equals(metadata.dataType)
|
||||||
: metaData.dataType != null)
|
: metadata.dataType != null)
|
||||||
return false;
|
return false;
|
||||||
if (!key.equals(metaData.key))
|
if (!key.equals(metadata.key))
|
||||||
return false;
|
return false;
|
||||||
if (lastModified != null ? !lastModified
|
if (lastModified != null ? !lastModified
|
||||||
.equals(metaData.lastModified)
|
.equals(metadata.lastModified)
|
||||||
: metaData.lastModified != null)
|
: metadata.lastModified != null)
|
||||||
return false;
|
return false;
|
||||||
if (!Arrays.equals(getMd5(), metaData.getMd5()))
|
if (!Arrays.equals(getMd5(), metadata.getMd5()))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -190,11 +193,17 @@ public class S3Object {
|
||||||
return userMetadata;
|
return userMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOwner(S3Owner owner) {
|
public void setOwner(CanonicalUser owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Owner getOwner() {
|
/**
|
||||||
|
* Every bucket and object in Amazon S3 has an owner, the user that
|
||||||
|
* created the bucket or object. The owner of a bucket or object cannot
|
||||||
|
* be changed. However, if the object is overwritten by another user
|
||||||
|
* (deleted and rewritten), the new object will have a new owner.
|
||||||
|
*/
|
||||||
|
public CanonicalUser getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,16 +238,24 @@ public class S3Object {
|
||||||
public String getContentEncoding() {
|
public String getContentEncoding() {
|
||||||
return dataEncoding;
|
return dataEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAllHeaders(Multimap<String, String> allHeaders) {
|
||||||
|
this.allHeaders = allHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Multimap<String, String> getAllHeaders() {
|
||||||
|
return allHeaders;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return metaData.getKey();
|
return metadata.getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(Object data) {
|
public void setData(Object data) {
|
||||||
this.data = checkNotNull(data, "data");
|
this.data = checkNotNull(data, "data");
|
||||||
if (getMetaData().getSize() == -1)
|
if (getMetadata().getSize() == -1)
|
||||||
this.getMetaData().setSize(S3Utils.calculateSize(data));
|
this.getMetadata().setSize(S3Utils.calculateSize(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateMd5() throws IOException {
|
public void generateMd5() throws IOException {
|
||||||
|
@ -246,11 +263,11 @@ public class S3Object {
|
||||||
if (data instanceof InputStream) {
|
if (data instanceof InputStream) {
|
||||||
Md5InputStreamResult result = S3Utils
|
Md5InputStreamResult result = S3Utils
|
||||||
.generateMd5Result((InputStream) data);
|
.generateMd5Result((InputStream) data);
|
||||||
getMetaData().setSize(result.length);
|
getMetadata().setSize(result.length);
|
||||||
getMetaData().setMd5(result.md5);
|
getMetadata().setMd5(result.md5);
|
||||||
setData(result.data);
|
setData(result.data);
|
||||||
} else {
|
} else {
|
||||||
getMetaData().setMd5(S3Utils.md5(data));
|
getMetadata().setMd5(S3Utils.md5(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,19 +275,19 @@ public class S3Object {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMetaData(Metadata metaData) {
|
public void setMetadata(Metadata metadata) {
|
||||||
this.metaData = metaData;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Metadata getMetaData() {
|
public Metadata getMetadata() {
|
||||||
return metaData;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("S3Object");
|
sb.append("S3Object");
|
||||||
sb.append("{metaData=").append(metaData);
|
sb.append("{metadata=").append(metadata);
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -286,7 +303,7 @@ public class S3Object {
|
||||||
|
|
||||||
if (data != null ? !data.equals(s3Object.data) : s3Object.data != null)
|
if (data != null ? !data.equals(s3Object.data) : s3Object.data != null)
|
||||||
return false;
|
return false;
|
||||||
if (!metaData.equals(s3Object.metaData))
|
if (!metadata.equals(s3Object.metadata))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -295,8 +312,24 @@ public class S3Object {
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = data != null ? data.hashCode() : 0;
|
int result = data != null ? data.hashCode() : 0;
|
||||||
result = 31 * result + metaData.hashCode();
|
result = 31 * result + metadata.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContentLength(long contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getContentLength() {
|
||||||
|
return contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentRange(String contentRange) {
|
||||||
|
this.contentRange = contentRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentRange() {
|
||||||
|
return contentRange;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,14 @@ import javax.annotation.Resource;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.aws.s3.S3ResponseException;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
import org.jclouds.aws.s3.domain.S3Error;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
||||||
import org.jclouds.http.HttpException;
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,29 +58,26 @@ public class ParseS3ErrorFromXmlContent implements HttpResponseHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(HttpFutureCommand<?> command, HttpResponse response) {
|
public void handle(HttpFutureCommand<?> command, HttpResponse response) {
|
||||||
int code = response.getStatusCode();
|
S3Error error = new S3Error();
|
||||||
if (code >= 300) {
|
error.setRequestId(response.getFirstHeaderOrNull(S3Headers.REQUEST_ID));
|
||||||
InputStream errorStream = response.getContent();
|
error.setRequestToken(response
|
||||||
|
.getFirstHeaderOrNull(S3Headers.REQUEST_TOKEN));
|
||||||
|
InputStream errorStream = response.getContent();
|
||||||
|
try {
|
||||||
if (errorStream != null) {
|
if (errorStream != null) {
|
||||||
try {
|
error = parserFactory.createErrorParser().parse(errorStream);
|
||||||
S3Error error = parserFactory.createErrorParser().parse(
|
if ("SignatureDoesNotMatch".equals(error.getCode()))
|
||||||
errorStream);
|
error.setStringSigned(RequestAuthorizeSignature
|
||||||
if ("SignatureDoesNotMatch".equals(error.getCode()))
|
.createStringToSign(command.getRequest()));
|
||||||
error.setStringSigned(RequestAuthorizeSignature
|
error.setRequestToken(response
|
||||||
.createStringToSign(command.getRequest()));
|
.getFirstHeaderOrNull(S3Headers.REQUEST_TOKEN));
|
||||||
logger.trace("received the following error from s3: %1s",
|
|
||||||
error);
|
|
||||||
command.setException(new S3ResponseException(command,
|
|
||||||
response, error));
|
|
||||||
} catch (HttpException he) {
|
|
||||||
logger.error(he, "error parsing response %1s", response);
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(errorStream);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
command
|
|
||||||
.setException(new S3ResponseException(command, response));
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn(e, "error parsing XML reponse: %1$s", response);
|
||||||
|
} finally {
|
||||||
|
command.setException(new S3ResponseException(command, response,
|
||||||
|
error));
|
||||||
|
IOUtils.closeQuietly(errorStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,15 @@ import java.util.TreeSet;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpHeaders;
|
import org.jclouds.http.HttpHeaders;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -40,16 +39,16 @@ import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.Utils;
|
import org.jclouds.Utils;
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
|
||||||
import org.jclouds.aws.s3.S3Map;
|
import org.jclouds.aws.s3.S3Map;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
public abstract class BaseS3Map<T> implements Map<String, T>, S3Map {
|
public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
||||||
|
|
||||||
protected final S3Connection connection;
|
protected final S3Connection connection;
|
||||||
protected final String bucket;
|
protected final String bucket;
|
||||||
|
@ -88,8 +87,8 @@ public abstract class BaseS3Map<T> implements Map<String, T>, S3Map {
|
||||||
|
|
||||||
protected boolean containsMd5(byte[] md5) throws InterruptedException,
|
protected boolean containsMd5(byte[] md5) throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
for (S3Object.Metadata metaData : refreshBucket().getContents()) {
|
for (S3Object.Metadata metadata : refreshBucket().getContents()) {
|
||||||
if (Arrays.equals(md5, metaData.getMd5()))
|
if (Arrays.equals(md5, metadata.getMd5()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -104,9 +103,9 @@ public abstract class BaseS3Map<T> implements Map<String, T>, S3Map {
|
||||||
} else {
|
} else {
|
||||||
object = new S3Object("dummy", value);
|
object = new S3Object("dummy", value);
|
||||||
}
|
}
|
||||||
if (object.getMetaData().getMd5() == null)
|
if (object.getMetadata().getMd5() == null)
|
||||||
object.generateMd5();
|
object.generateMd5();
|
||||||
return object.getMetaData().getMd5();
|
return object.getMetadata().getMd5();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<S3Object> getAllObjects() {
|
protected Set<S3Object> getAllObjects() {
|
||||||
|
@ -123,7 +122,7 @@ public abstract class BaseS3Map<T> implements Map<String, T>, S3Map {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error getting value from bucket %1s:%2s", bucket,
|
"Error getting value from bucket %1$s:%2$s", bucket,
|
||||||
object != null ? object.getKey() : "unknown"), e);
|
object != null ? object.getKey() : "unknown"), e);
|
||||||
}
|
}
|
||||||
if (object != S3Object.NOT_FOUND)
|
if (object != S3Object.NOT_FOUND)
|
||||||
|
@ -146,7 +145,7 @@ public abstract class BaseS3Map<T> implements Map<String, T>, S3Map {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error searching for ETAG of value: [%2s] in bucket:%1s",
|
"Error searching for ETAG of value: [%2$s] in bucket:%1$s",
|
||||||
bucket, value), e);
|
bucket, value), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +209,7 @@ public abstract class BaseS3Map<T> implements Map<String, T>, S3Map {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error searching for %1s:%2s", bucket, key), e);
|
"Error searching for %1$s:%2$s", bucket, key), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ import org.jclouds.aws.s3.commands.BucketExists;
|
||||||
import org.jclouds.aws.s3.commands.CopyObject;
|
import org.jclouds.aws.s3.commands.CopyObject;
|
||||||
import org.jclouds.aws.s3.commands.DeleteBucket;
|
import org.jclouds.aws.s3.commands.DeleteBucket;
|
||||||
import org.jclouds.aws.s3.commands.DeleteObject;
|
import org.jclouds.aws.s3.commands.DeleteObject;
|
||||||
import org.jclouds.aws.s3.commands.GetMetaDataForOwnedBuckets;
|
import org.jclouds.aws.s3.commands.ListOwnedBuckets;
|
||||||
import org.jclouds.aws.s3.commands.GetObject;
|
import org.jclouds.aws.s3.commands.GetObject;
|
||||||
import org.jclouds.aws.s3.commands.HeadMetaData;
|
import org.jclouds.aws.s3.commands.HeadObject;
|
||||||
import org.jclouds.aws.s3.commands.ListBucket;
|
import org.jclouds.aws.s3.commands.ListBucket;
|
||||||
import org.jclouds.aws.s3.commands.PutBucket;
|
import org.jclouds.aws.s3.commands.PutBucket;
|
||||||
import org.jclouds.aws.s3.commands.PutObject;
|
import org.jclouds.aws.s3.commands.PutObject;
|
||||||
|
@ -96,12 +96,12 @@ public class LiveS3Connection implements S3Connection {
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* @see HeadMetaData
|
* @see HeadObject
|
||||||
*/
|
*/
|
||||||
public Future<S3Object.Metadata> headObject(String s3Bucket, String key) {
|
public Future<S3Object.Metadata> headObject(String s3Bucket, String key) {
|
||||||
HeadMetaData headMetaData = factory.createHeadMetaData(s3Bucket, key);
|
HeadObject headMetadata = factory.createHeadMetadata(s3Bucket, key);
|
||||||
client.submit(headMetaData);
|
client.submit(headMetadata);
|
||||||
return headMetaData;
|
return headMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,11 +230,11 @@ public class LiveS3Connection implements S3Connection {
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* @see GetMetaDataForOwnedBuckets
|
* @see ListOwnedBuckets
|
||||||
*/
|
*/
|
||||||
public Future<List<Metadata>> getOwnedBuckets() {
|
public Future<List<Metadata>> listOwnedBuckets() {
|
||||||
GetMetaDataForOwnedBuckets listRequest = factory
|
ListOwnedBuckets listRequest = factory
|
||||||
.createGetMetaDataForOwnedBuckets();
|
.createGetMetadataForOwnedBuckets();
|
||||||
client.submit(listRequest);
|
client.submit(listRequest);
|
||||||
return listRequest;
|
return listRequest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error geting object %1s:%2s", bucket, o), e);
|
"Error geting object %1$s:%2$s", bucket, o), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error removing object %1s:%2s", bucket, o), e);
|
"Error removing object %1$s:%2$s", bucket, o), e);
|
||||||
}
|
}
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error adding object %1s:%2s", bucket, object), e);
|
"Error adding object %1$s:%2$s", bucket, object), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error geting object %1s:%2s", bucket, key), e);
|
"Error geting object %1$s:%2$s", bucket, key), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error putting object %1s:%2s%n%1s", bucket, key, value), e);
|
"Error putting object %1$s:%2$s%n%1$s", bucket, key, value), e);
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException(String.format(
|
throw new S3RuntimeException(String.format(
|
||||||
"Error removing object %1s:%2s", bucket, key), e);
|
"Error removing object %1$s:%2$s", bucket, key), e);
|
||||||
}
|
}
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
/**
|
||||||
|
* This package contains an Amazon S3 client implemented by {@link HttpFutureCommand} commands.
|
||||||
|
*
|
||||||
|
* @see http://aws.amazon.com/s3/
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws.s3;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3.reference;
|
||||||
|
|
||||||
import org.jclouds.command.pool.PoolConstants;
|
import org.jclouds.command.pool.PoolConstants;
|
||||||
import org.jclouds.http.HttpConstants;
|
import org.jclouds.http.HttpConstants;
|
|
@ -21,9 +21,11 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3.reference;
|
||||||
|
|
||||||
public interface S3Headers {
|
import org.jclouds.http.HttpHeaders;
|
||||||
|
|
||||||
|
public interface S3Headers extends HttpHeaders{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The canned ACL to apply to the object. Options include private,
|
* The canned ACL to apply to the object. Options include private,
|
||||||
|
@ -38,12 +40,8 @@ public interface S3Headers {
|
||||||
* 8 KB.
|
* 8 KB.
|
||||||
*/
|
*/
|
||||||
public static final String USER_METADATA_PREFIX = "x-amz-meta-";
|
public static final String USER_METADATA_PREFIX = "x-amz-meta-";
|
||||||
public static final String ETAG = "ETag";
|
|
||||||
public static final String AMZ_MD5 = "x-amz-meta-object-md5";
|
public static final String AMZ_MD5 = "x-amz-meta-object-md5";
|
||||||
public static final String RANGE = "Range";
|
public static final String REQUEST_ID = "x-amz-request-id";
|
||||||
public static final String OBJECT_IF_MODIFIED_SINCE = "If-Modified-Since";
|
public static final String REQUEST_TOKEN = "x-amz-id-2";
|
||||||
public static final String OBJECT_IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
|
|
||||||
public static final String OBJECT_IF_MATCH = "If-Match";
|
|
||||||
public static final String OBJECT_IF_NONE_MATCH = "If-None-Match";
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3.util;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3.util;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
@ -231,7 +231,7 @@ public class S3Utils extends Utils {
|
||||||
|
|
||||||
if (o instanceof InputStream) {
|
if (o instanceof InputStream) {
|
||||||
String returnVal = toStringAndClose((InputStream) o);
|
String returnVal = toStringAndClose((InputStream) o);
|
||||||
if (object.getMetaData().getContentType().indexOf("xml") >= 0) {
|
if (object.getMetadata().getContentType().indexOf("xml") >= 0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
|
@ -23,9 +23,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
@ -38,25 +38,25 @@ import com.google.inject.Inject;
|
||||||
public class CopyObjectHandler extends
|
public class CopyObjectHandler extends
|
||||||
ParseSax.HandlerWithResult<S3Object.Metadata> {
|
ParseSax.HandlerWithResult<S3Object.Metadata> {
|
||||||
|
|
||||||
private S3Object.Metadata metaData;
|
private S3Object.Metadata metadata;
|
||||||
private StringBuilder currentText = new StringBuilder();
|
private StringBuilder currentText = new StringBuilder();
|
||||||
@Inject
|
@Inject
|
||||||
private DateService dateParser;
|
private DateService dateParser;
|
||||||
|
|
||||||
public void setKey(String key) {
|
public void setKey(String key) {
|
||||||
metaData = new S3Object.Metadata(key);
|
metadata = new S3Object.Metadata(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Object.Metadata getResult() {
|
public S3Object.Metadata getResult() {
|
||||||
return metaData;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
if (qName.equals("ETag")) {
|
if (qName.equals("ETag")) {
|
||||||
metaData.setMd5(S3Utils.fromHexString(currentText.toString()
|
metadata.setMd5(S3Utils.fromHexString(currentText.toString()
|
||||||
.replaceAll("\"", "")));
|
.replaceAll("\"", "")));
|
||||||
} else if (qName.equals("LastModified")) {
|
} else if (qName.equals("LastModified")) {
|
||||||
metaData.setLastModified(dateParser
|
metadata.setLastModified(dateParser
|
||||||
.dateTimeFromXMLFormat(currentText.toString()));
|
.dateTimeFromXMLFormat(currentText.toString()));
|
||||||
}
|
}
|
||||||
currentText = new StringBuilder();
|
currentText = new StringBuilder();
|
||||||
|
|
|
@ -29,6 +29,9 @@ import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
/**
|
/**
|
||||||
* Parses the error from the Amazon S3 REST API.
|
* Parses the error from the Amazon S3 REST API.
|
||||||
*
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingRESTError
|
||||||
|
* .html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ErrorHandler extends ParseSax.HandlerWithResult<S3Error> {
|
public class ErrorHandler extends ParseSax.HandlerWithResult<S3Error> {
|
||||||
|
@ -46,20 +49,10 @@ public class ErrorHandler extends ParseSax.HandlerWithResult<S3Error> {
|
||||||
error.setCode(currentText.toString());
|
error.setCode(currentText.toString());
|
||||||
} else if (qName.equals("Message")) {
|
} else if (qName.equals("Message")) {
|
||||||
error.setMessage(currentText.toString());
|
error.setMessage(currentText.toString());
|
||||||
} else if (qName.equals("Resource")) {
|
|
||||||
error.setResource(currentText.toString());
|
|
||||||
} else if (qName.equals("RequestId")) {
|
} else if (qName.equals("RequestId")) {
|
||||||
error.setRequestId(currentText.toString());
|
error.setRequestId(currentText.toString());
|
||||||
} else if (qName.equals("HostId")) {
|
} else if (!qName.equals("Error")) {
|
||||||
error.setHostId(currentText.toString());
|
error.getDetails().put(qName, currentText.toString());
|
||||||
} else if (qName.equals("Header")) {
|
|
||||||
error.setHeader(currentText.toString());
|
|
||||||
} else if (qName.equals("SignatureProvided")) {
|
|
||||||
error.setSignatureProvided(currentText.toString());
|
|
||||||
} else if (qName.equals("StringToSign")) {
|
|
||||||
error.setStringToSign(currentText.toString());
|
|
||||||
} else if (qName.equals("StringToSignBytes")) {
|
|
||||||
error.setStringToSignBytes(currentText.toString());
|
|
||||||
}
|
}
|
||||||
currentText = new StringBuilder();
|
currentText = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,17 +26,21 @@ package org.jclouds.aws.s3.xml;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Owner;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import org.xml.sax.Attributes;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the response from Amazon S3 GET Service command.
|
* Parses the following XML document:
|
||||||
|
* <p/>
|
||||||
|
* ListAllMyBucketsResult xmlns="http://doc.s3.amazonaws.com/2006-03-01"
|
||||||
*
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET
|
||||||
|
* .html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ListAllMyBucketsHandler extends
|
public class ListAllMyBucketsHandler extends
|
||||||
|
@ -44,7 +48,7 @@ public class ListAllMyBucketsHandler extends
|
||||||
|
|
||||||
private List<S3Bucket.Metadata> buckets = new ArrayList<S3Bucket.Metadata>();
|
private List<S3Bucket.Metadata> buckets = new ArrayList<S3Bucket.Metadata>();
|
||||||
private S3Bucket.Metadata currentS3Bucket;
|
private S3Bucket.Metadata currentS3Bucket;
|
||||||
private S3Owner currentOwner;
|
private CanonicalUser currentOwner;
|
||||||
private StringBuilder currentText = new StringBuilder();
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
private final DateService dateParser;
|
private final DateService dateParser;
|
||||||
|
@ -58,21 +62,13 @@ public class ListAllMyBucketsHandler extends
|
||||||
return buckets;
|
return buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startElement(String uri, String name, String qName,
|
|
||||||
Attributes attrs) {
|
|
||||||
if (qName.equals("Bucket")) {
|
|
||||||
} else if (qName.equals("Owner")) {
|
|
||||||
currentOwner = new S3Owner();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
if (qName.equals("ID")) { // owner stuff
|
if (qName.equals("ID")) { // owner stuff
|
||||||
currentOwner.setId(currentText.toString());
|
currentOwner = new CanonicalUser(currentText.toString());
|
||||||
} else if (qName.equals("DisplayName")) {
|
} else if (qName.equals("DisplayName")) {
|
||||||
currentOwner.setDisplayName(currentText.toString());
|
currentOwner.setDisplayName(currentText.toString());
|
||||||
} else if (qName.equals("Bucket")) {
|
} else if (qName.equals("Bucket")) {
|
||||||
currentS3Bucket.setCanonicalUser(currentOwner);
|
currentS3Bucket.setOwner(currentOwner);
|
||||||
buckets.add(currentS3Bucket);
|
buckets.add(currentS3Bucket);
|
||||||
} else if (qName.equals("Name")) {
|
} else if (qName.equals("Name")) {
|
||||||
currentS3Bucket = new S3Bucket.Metadata(currentText.toString());
|
currentS3Bucket = new S3Bucket.Metadata(currentText.toString());
|
||||||
|
|
|
@ -25,82 +25,79 @@ package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.domain.S3Owner;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO: Adrian: Document this!
|
* Parses the following XML document:
|
||||||
|
* <p/>
|
||||||
|
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
|
||||||
*
|
*
|
||||||
|
* @see http
|
||||||
|
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET
|
||||||
|
* .html
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
||||||
|
private S3Bucket s3Bucket;
|
||||||
|
private S3Object.Metadata currentObjectMetadata;
|
||||||
|
private CanonicalUser currentOwner;
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private final DateService dateParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ListBucketHandler(DateService dateParser) {
|
||||||
|
this.dateParser = dateParser;
|
||||||
|
}
|
||||||
|
|
||||||
public S3Bucket getResult() {
|
public S3Bucket getResult() {
|
||||||
return s3Bucket;
|
return s3Bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBucketName(String bucketName) {
|
public void setBucketName(String bucketName) {
|
||||||
this.s3Bucket = new S3Bucket(bucketName);
|
this.s3Bucket = new S3Bucket(checkNotNull(bucketName, "bucketName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private S3Bucket s3Bucket;
|
|
||||||
private S3Object.Metadata currentObjectMetaData;
|
|
||||||
private S3Owner currentOwner;
|
|
||||||
private StringBuilder currentText = new StringBuilder();
|
|
||||||
@Inject
|
|
||||||
private DateService dateParser;
|
|
||||||
private boolean inCommonPrefixes;
|
private boolean inCommonPrefixes;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startDocument() throws SAXException {
|
|
||||||
checkNotNull(s3Bucket, "s3Bucket");
|
|
||||||
s3Bucket.getContents().clear();
|
|
||||||
s3Bucket.getCommonPrefixes().clear();
|
|
||||||
super.startDocument();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startElement(String uri, String name, String qName,
|
public void startElement(String uri, String name, String qName,
|
||||||
Attributes attrs) {
|
Attributes attrs) {
|
||||||
if (qName.equals("Contents")) {
|
if (qName.equals("CommonPrefixes")) {
|
||||||
} else if (qName.equals("Owner")) {
|
|
||||||
currentOwner = new S3Owner();
|
|
||||||
} else if (qName.equals("CommonPrefixes")) {
|
|
||||||
inCommonPrefixes = true;
|
inCommonPrefixes = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
|
if (qName.equals("ID")) {
|
||||||
if (qName.equals("ID")) { // owner stuff
|
currentOwner = new CanonicalUser(currentText.toString());
|
||||||
currentOwner.setId(currentText.toString());
|
|
||||||
} else if (qName.equals("DisplayName")) {
|
} else if (qName.equals("DisplayName")) {
|
||||||
currentOwner.setDisplayName(currentText.toString());
|
currentOwner.setDisplayName(currentText.toString());
|
||||||
} else if (qName.equals("Key")) { // content stuff
|
} else if (qName.equals("Key")) { // content stuff
|
||||||
currentObjectMetaData = new S3Object.Metadata(currentText
|
currentObjectMetadata = new S3Object.Metadata(currentText
|
||||||
.toString());
|
.toString());
|
||||||
} else if (qName.equals("LastModified")) {
|
} else if (qName.equals("LastModified")) {
|
||||||
currentObjectMetaData.setLastModified(dateParser
|
currentObjectMetadata.setLastModified(dateParser
|
||||||
.dateTimeFromXMLFormat(currentText.toString()));
|
.dateTimeFromXMLFormat(currentText.toString()));
|
||||||
} else if (qName.equals("ETag")) {
|
} else if (qName.equals("ETag")) {
|
||||||
currentObjectMetaData.setMd5(S3Utils.fromHexString(currentText
|
currentObjectMetadata.setMd5(S3Utils.fromHexString(currentText
|
||||||
.toString().replaceAll("\"", "")));
|
.toString().replaceAll("\"", "")));
|
||||||
} else if (qName.equals("Size")) {
|
} else if (qName.equals("Size")) {
|
||||||
currentObjectMetaData.setSize(Long
|
currentObjectMetadata.setSize(Long
|
||||||
.parseLong(currentText.toString()));
|
.parseLong(currentText.toString()));
|
||||||
} else if (qName.equals("Owner")) {
|
} else if (qName.equals("Owner")) {
|
||||||
currentObjectMetaData.setOwner(currentOwner);
|
currentObjectMetadata.setOwner(currentOwner);
|
||||||
} else if (qName.equals("StorageClass")) {
|
} else if (qName.equals("StorageClass")) {
|
||||||
currentObjectMetaData.setStorageClass(currentText.toString());
|
currentObjectMetadata.setStorageClass(currentText.toString());
|
||||||
} else if (qName.equals("Contents")) {
|
} else if (qName.equals("Contents")) {
|
||||||
s3Bucket.getContents().add(currentObjectMetaData);
|
s3Bucket.getContents().add(currentObjectMetadata);
|
||||||
} else if (qName.equals("Name")) {// bucket stuff last, as least likely
|
} else if (qName.equals("Name")) {// bucket stuff last, as least likely
|
||||||
} else if (qName.equals("Prefix")) {
|
} else if (qName.equals("Prefix")) {
|
||||||
String prefix = currentText.toString().trim();
|
String prefix = currentText.toString().trim();
|
||||||
|
|
|
@ -35,7 +35,9 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates Parsers needed to interpret S3 Server responses
|
* Creates Parsers needed to interpret S3 Server messages. This class uses guice
|
||||||
|
* assisted inject, which mandates the creation of many single-method
|
||||||
|
* interfaces. These interfaces are not intended for public api.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -44,6 +46,7 @@ public class S3ParserFactory {
|
||||||
@Inject
|
@Inject
|
||||||
private GenericParseFactory<List<S3Bucket.Metadata>> parseListAllMyBucketsFactory;
|
private GenericParseFactory<List<S3Bucket.Metadata>> parseListAllMyBucketsFactory;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
public static interface GenericParseFactory<T> {
|
public static interface GenericParseFactory<T> {
|
||||||
ParseSax<T> create(ParseSax.HandlerWithResult<T> handler);
|
ParseSax<T> create(ParseSax.HandlerWithResult<T> handler);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +54,9 @@ public class S3ParserFactory {
|
||||||
@Inject
|
@Inject
|
||||||
Provider<ListAllMyBucketsHandler> ListAllMyBucketsHandlerprovider;
|
Provider<ListAllMyBucketsHandler> ListAllMyBucketsHandlerprovider;
|
||||||
|
|
||||||
@VisibleForTesting
|
/**
|
||||||
|
* @return a parser used to handle {@link ListOwnedBuckets} responses
|
||||||
|
*/
|
||||||
public ParseSax<List<S3Bucket.Metadata>> createListBucketsParser() {
|
public ParseSax<List<S3Bucket.Metadata>> createListBucketsParser() {
|
||||||
return parseListAllMyBucketsFactory
|
return parseListAllMyBucketsFactory
|
||||||
.create(ListAllMyBucketsHandlerprovider.get());
|
.create(ListAllMyBucketsHandlerprovider.get());
|
||||||
|
@ -63,7 +68,9 @@ public class S3ParserFactory {
|
||||||
@Inject
|
@Inject
|
||||||
Provider<ListBucketHandler> ListBucketHandlerprovider;
|
Provider<ListBucketHandler> ListBucketHandlerprovider;
|
||||||
|
|
||||||
@VisibleForTesting
|
/**
|
||||||
|
* @return a parser used to handle {@link ListBucket} responses
|
||||||
|
*/
|
||||||
public ParseSax<S3Bucket> createListBucketParser() {
|
public ParseSax<S3Bucket> createListBucketParser() {
|
||||||
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
|
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
|
||||||
}
|
}
|
||||||
|
@ -74,7 +81,9 @@ public class S3ParserFactory {
|
||||||
@Inject
|
@Inject
|
||||||
Provider<CopyObjectHandler> copyObjectHandlerProvider;
|
Provider<CopyObjectHandler> copyObjectHandlerProvider;
|
||||||
|
|
||||||
@VisibleForTesting
|
/**
|
||||||
|
* @return a parser used to handle {@link CopyObject} responses
|
||||||
|
*/
|
||||||
public ParseSax<S3Object.Metadata> createCopyObjectParser() {
|
public ParseSax<S3Object.Metadata> createCopyObjectParser() {
|
||||||
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
|
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
|
||||||
}
|
}
|
||||||
|
@ -85,6 +94,9 @@ public class S3ParserFactory {
|
||||||
@Inject
|
@Inject
|
||||||
Provider<ErrorHandler> errorHandlerProvider;
|
Provider<ErrorHandler> errorHandlerProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a parser used to handle error conditions.
|
||||||
|
*/
|
||||||
public ParseSax<S3Error> createErrorParser() {
|
public ParseSax<S3Error> createErrorParser() {
|
||||||
return parseErrorFactory.create(errorHandlerProvider.get());
|
return parseErrorFactory.create(errorHandlerProvider.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,37 +46,23 @@ import com.google.inject.assistedinject.FactoryProvider;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class S3ParserModule extends AbstractModule {
|
public class S3ParserModule extends AbstractModule {
|
||||||
|
private final TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>> listBucketsTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>>() {
|
||||||
|
};
|
||||||
|
private final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>> bucketTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>>() {
|
||||||
|
};
|
||||||
|
private final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>> objectMetadataTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>>() {
|
||||||
|
};
|
||||||
|
private final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>>() {
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new SaxModule());
|
install(new SaxModule());
|
||||||
|
bindCallablesThatReturnParseResults();
|
||||||
|
bindParserImplementationsToReturnTypes();
|
||||||
|
}
|
||||||
|
|
||||||
final TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>> listBucketsTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>>() {
|
private void bindParserImplementationsToReturnTypes() {
|
||||||
};
|
|
||||||
final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>> bucketTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>>() {
|
|
||||||
};
|
|
||||||
final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>> objectMetaDataTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>>() {
|
|
||||||
};
|
|
||||||
final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Error>>() {
|
|
||||||
};
|
|
||||||
|
|
||||||
bind(listBucketsTypeLiteral).toProvider(
|
|
||||||
FactoryProvider.newFactory(listBucketsTypeLiteral,
|
|
||||||
new TypeLiteral<ParseSax<List<S3Bucket.Metadata>>>() {
|
|
||||||
}));
|
|
||||||
bind(bucketTypeLiteral).toProvider(
|
|
||||||
FactoryProvider.newFactory(bucketTypeLiteral,
|
|
||||||
new TypeLiteral<ParseSax<S3Bucket>>() {
|
|
||||||
}));
|
|
||||||
bind(objectMetaDataTypeLiteral).toProvider(
|
|
||||||
FactoryProvider.newFactory(objectMetaDataTypeLiteral,
|
|
||||||
new TypeLiteral<ParseSax<S3Object.Metadata>>() {
|
|
||||||
}));
|
|
||||||
bind(errorTypeLiteral).toProvider(
|
|
||||||
FactoryProvider.newFactory(errorTypeLiteral,
|
|
||||||
new TypeLiteral<ParseSax<S3Error>>() {
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Bind the implementations of handlers to the interfaces they implement
|
|
||||||
bind(
|
bind(
|
||||||
new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
|
new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
|
||||||
}).to(ListAllMyBucketsHandler.class);
|
}).to(ListAllMyBucketsHandler.class);
|
||||||
|
@ -88,4 +74,23 @@ public class S3ParserModule extends AbstractModule {
|
||||||
}).to(ErrorHandler.class);
|
}).to(ErrorHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void bindCallablesThatReturnParseResults() {
|
||||||
|
bind(listBucketsTypeLiteral).toProvider(
|
||||||
|
FactoryProvider.newFactory(listBucketsTypeLiteral,
|
||||||
|
new TypeLiteral<ParseSax<List<S3Bucket.Metadata>>>() {
|
||||||
|
}));
|
||||||
|
bind(bucketTypeLiteral).toProvider(
|
||||||
|
FactoryProvider.newFactory(bucketTypeLiteral,
|
||||||
|
new TypeLiteral<ParseSax<S3Bucket>>() {
|
||||||
|
}));
|
||||||
|
bind(objectMetadataTypeLiteral).toProvider(
|
||||||
|
FactoryProvider.newFactory(objectMetadataTypeLiteral,
|
||||||
|
new TypeLiteral<ParseSax<S3Object.Metadata>>() {
|
||||||
|
}));
|
||||||
|
bind(errorTypeLiteral).toProvider(
|
||||||
|
FactoryProvider.newFactory(errorTypeLiteral,
|
||||||
|
new TypeLiteral<ParseSax<S3Error>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -40,7 +40,7 @@ public class S3ConnectionTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testListBuckets() throws Exception {
|
void testListBuckets() throws Exception {
|
||||||
List<S3Bucket.Metadata> myBuckets = client.getOwnedBuckets().get(10,
|
List<S3Bucket.Metadata> myBuckets = client.listOwnedBuckets().get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
for (S3Bucket.Metadata bucket : myBuckets) {
|
for (S3Bucket.Metadata bucket : myBuckets) {
|
||||||
context.createInputStreamMap(bucket.getName()).size();
|
context.createInputStreamMap(bucket.getName()).size();
|
||||||
|
|
|
@ -46,6 +46,8 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpConstants;
|
import org.jclouds.http.HttpConstants;
|
||||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
|
@ -54,10 +56,15 @@ import org.testng.annotations.Optional;
|
||||||
import org.testng.annotations.Parameters;
|
import org.testng.annotations.Parameters;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public class S3IntegrationTest {
|
public class S3IntegrationTest {
|
||||||
|
protected static final String TEST_STRING = "<apples><apple name=\"fuji\" /></apples>";
|
||||||
|
|
||||||
|
protected byte[] goodMd5;
|
||||||
|
protected byte[] badMd5;
|
||||||
|
|
||||||
protected void createBucketAndEnsureEmpty(String sourceBucket)
|
protected void createBucketAndEnsureEmpty(String sourceBucket)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
@ -66,13 +73,11 @@ public class S3IntegrationTest {
|
||||||
.getContents().size(), 0);
|
.getContents().size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final String TEST_STRING = "<apples><apple name=\"fuji\" /></apples>";
|
|
||||||
|
|
||||||
protected void addObjectToBucket(String sourceBucket, String key)
|
protected void addObjectToBucket(String sourceBucket, String key)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
S3Object sourceObject = new S3Object(key);
|
S3Object sourceObject = new S3Object(key);
|
||||||
sourceObject.getMetaData().setContentType("text/xml");
|
sourceObject.getMetadata().setContentType("text/xml");
|
||||||
sourceObject.setData(TEST_STRING);
|
sourceObject.setData(TEST_STRING);
|
||||||
addObjectToBucket(sourceBucket, sourceObject);
|
addObjectToBucket(sourceBucket, sourceObject);
|
||||||
}
|
}
|
||||||
|
@ -146,6 +151,8 @@ public class S3IntegrationTest {
|
||||||
: sysAWSSecretAccessKey);
|
: sysAWSSecretAccessKey);
|
||||||
client = context.getConnection();
|
client = context.getConnection();
|
||||||
deleteEverything();
|
deleteEverything();
|
||||||
|
goodMd5 = S3Utils.md5(TEST_STRING);
|
||||||
|
badMd5 = S3Utils.md5("alf");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean debugEnabled() {
|
protected boolean debugEnabled() {
|
||||||
|
@ -168,7 +175,6 @@ public class S3IntegrationTest {
|
||||||
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"));
|
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"));
|
||||||
properties.setProperty(HttpConstants.PROPERTY_HTTP_SECURE, "false");
|
properties.setProperty(HttpConstants.PROPERTY_HTTP_SECURE, "false");
|
||||||
properties.setProperty(HttpConstants.PROPERTY_HTTP_PORT, "80");
|
properties.setProperty(HttpConstants.PROPERTY_HTTP_PORT, "80");
|
||||||
// properties.setProperty("jclouds.http.sax.debug", "true");
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,10 +184,10 @@ public class S3IntegrationTest {
|
||||||
|
|
||||||
protected void deleteEverything() throws Exception {
|
protected void deleteEverything() throws Exception {
|
||||||
try {
|
try {
|
||||||
List<S3Bucket.Metadata> metaData = client.getOwnedBuckets().get(10,
|
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
|
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
|
||||||
for (S3Bucket.Metadata metaDatum : metaData) {
|
for (S3Bucket.Metadata metaDatum : metadata) {
|
||||||
if (metaDatum.getName().startsWith(bucketPrefix.toLowerCase())) {
|
if (metaDatum.getName().startsWith(bucketPrefix.toLowerCase())) {
|
||||||
S3Bucket bucket = client.listBucket(metaDatum.getName())
|
S3Bucket bucket = client.listBucket(metaDatum.getName())
|
||||||
.get(10, TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
|
|
|
@ -37,6 +37,7 @@ import java.util.Map.Entry;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.internal.BaseS3Map;
|
import org.jclouds.aws.s3.internal.BaseS3Map;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,7 +142,7 @@ public class S3ObjectMapTest extends BaseS3MapTest<S3Object> {
|
||||||
for (String key : fiveInputs.keySet()) {
|
for (String key : fiveInputs.keySet()) {
|
||||||
S3Object object = new S3Object(key);
|
S3Object object = new S3Object(key);
|
||||||
object.setData(fiveInputs.get(key));
|
object.setData(fiveInputs.get(key));
|
||||||
object.getMetaData().setSize(fiveBytes.get(key).length);
|
object.getMetadata().setSize(fiveBytes.get(key).length);
|
||||||
newMap.put(key, object);
|
newMap.put(key, object);
|
||||||
}
|
}
|
||||||
map.putAll(newMap);
|
map.putAll(newMap);
|
||||||
|
|
|
@ -25,6 +25,7 @@ package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import org.bouncycastle.util.encoders.Base64;
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.jclouds.aws.PerformanceTest;
|
import org.jclouds.aws.PerformanceTest;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@ public class StubS3Connection implements S3Connection {
|
||||||
.get(s3Bucket);
|
.get(s3Bucket);
|
||||||
if (!realContents.containsKey(key))
|
if (!realContents.containsKey(key))
|
||||||
return S3Object.Metadata.NOT_FOUND;
|
return S3Object.Metadata.NOT_FOUND;
|
||||||
S3Object.Metadata metaData = new S3Object.Metadata(key);
|
S3Object.Metadata metadata = new S3Object.Metadata(key);
|
||||||
return metaData;
|
return metadata;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -173,8 +173,8 @@ public class StubS3Connection implements S3Connection {
|
||||||
.get(s3Bucket);
|
.get(s3Bucket);
|
||||||
if (realContents != null) {
|
if (realContents != null) {
|
||||||
for (String key : realContents.keySet()) {
|
for (String key : realContents.keySet()) {
|
||||||
S3Object.Metadata metaData = new S3Object.Metadata(key);
|
S3Object.Metadata metadata = new S3Object.Metadata(key);
|
||||||
contents.add(metaData);
|
contents.add(metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
S3Bucket returnVal = new S3Bucket(s3Bucket);
|
S3Bucket returnVal = new S3Bucket(s3Bucket);
|
||||||
|
@ -205,7 +205,7 @@ public class StubS3Connection implements S3Connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<List<Metadata>> getOwnedBuckets() {
|
public Future<List<Metadata>> listOwnedBuckets() {
|
||||||
return new FutureBase<List<S3Bucket.Metadata>>() {
|
return new FutureBase<List<S3Bucket.Metadata>>() {
|
||||||
public List<S3Bucket.Metadata> get() throws InterruptedException,
|
public List<S3Bucket.Metadata> get() throws InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
|
|
|
@ -27,22 +27,26 @@ import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSo
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideAcl;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
@ -60,6 +64,25 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
String sourceKey = "apples";
|
String sourceKey = "apples";
|
||||||
String destinationKey = "pears";
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void testCannedAccessPolicyPublic() throws Exception {
|
||||||
|
String sourceBucket = bucketPrefix + "tcapp";
|
||||||
|
String destinationBucket = sourceBucket + "dest";
|
||||||
|
|
||||||
|
setupSourceBucket(sourceBucket, sourceKey);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey,overrideAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
|
||||||
|
destinationBucket, destinationKey));
|
||||||
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
|
|
||||||
|
}
|
||||||
@Test()
|
@Test()
|
||||||
void testCopyObject() throws Exception {
|
void testCopyObject() throws Exception {
|
||||||
String sourceBucket = bucketPrefix + "testcopyobject";
|
String sourceBucket = bucketPrefix + "testcopyobject";
|
||||||
|
@ -110,7 +133,7 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
destinationKey, ifSourceModifiedSince(after)).get(10,
|
destinationKey, ifSourceModifiedSince(after)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
S3ResponseException ex = (S3ResponseException) e.getCause();
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +159,7 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
S3ResponseException ex = (S3ResponseException) e.getCause();
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,8 +168,6 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
String sourceBucket = bucketPrefix + "tcim";
|
String sourceBucket = bucketPrefix + "tcim";
|
||||||
byte[] realMd5 = S3Utils.md5(TEST_STRING);
|
|
||||||
byte[] badMd5 = S3Utils.md5("alf");
|
|
||||||
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
String destinationBucket = sourceBucket + "dest";
|
||||||
|
|
||||||
|
@ -154,7 +175,7 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
destinationKey, ifSourceMd5Matches(realMd5)).get(10,
|
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
validateContent(destinationBucket, destinationKey);
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
@ -163,7 +184,7 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
S3ResponseException ex = (S3ResponseException) e.getCause();
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,8 +193,6 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
String sourceBucket = bucketPrefix + "tcinm";
|
String sourceBucket = bucketPrefix + "tcinm";
|
||||||
byte[] realMd5 = S3Utils.md5(TEST_STRING);
|
|
||||||
byte[] badMd5 = S3Utils.md5("alf");
|
|
||||||
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
String destinationBucket = sourceBucket + "dest";
|
||||||
|
|
||||||
|
@ -187,10 +206,10 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
destinationKey, ifSourceMd5DoesntMatch(realMd5)).get(10,
|
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
S3ResponseException ex = (S3ResponseException) e.getCause();
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@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.aws.s3.commands;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests integrated functionality of all deleteBucket commands.
|
||||||
|
* <p/>
|
||||||
|
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||||
|
* in parallel.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test(groups = "integration", testName = "s3.DeleteBucketIntegrationTest")
|
||||||
|
public class DeleteBucketIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void deleteBucketIfEmptyNotFound() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "dbienf";
|
||||||
|
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void deleteBucketIfEmptyButHasContents() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "dbiebhc";
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
addObjectToBucket(bucketName,"test");
|
||||||
|
assert !client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void deleteBucketIfEmpty() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "dbie";
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
|
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@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.aws.s3.commands;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.S3ResponseException;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests integrated functionality of all deleteObject commands.
|
||||||
|
* <p/>
|
||||||
|
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||||
|
* in parallel.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test(groups = "integration", testName = "s3.DeleteObjectIntegrationTest")
|
||||||
|
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void deleteObjectNotFound() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "donf";
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
addObjectToBucket(bucketName, "test");
|
||||||
|
assert client.deleteObject(bucketName, "test")
|
||||||
|
.get(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deleteObjectNoBucket() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "donb";
|
||||||
|
try {
|
||||||
|
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
assert e.getCause() instanceof S3ResponseException;
|
||||||
|
assertEquals(((S3ResponseException) e.getCause()).getResponse()
|
||||||
|
.getStatusCode(), 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void deleteObject() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "do";
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
addObjectToBucket(bucketName, "test");
|
||||||
|
assert client.deleteObject(bucketName, "test")
|
||||||
|
.get(10, TimeUnit.SECONDS);
|
||||||
|
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
* Getright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
||||||
*
|
*
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,11 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,14 +47,181 @@ import org.testng.annotations.Test;
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.GetObjectIntegrationTest")
|
@Test(groups = "integration", testName = "s3.GetObjectIntegrationTest")
|
||||||
public class GetObjectIntegrationTest extends S3IntegrationTest {
|
public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// void testGetIfModifiedSince() throws InterruptedException,
|
||||||
|
// ExecutionException, TimeoutException, IOException {
|
||||||
|
// String bucket = bucketPrefix + "testGetIfModifiedSince".toLowerCase();
|
||||||
|
// String key = "apples";
|
||||||
|
//
|
||||||
|
// DateTime before = new DateTime();
|
||||||
|
// setUpBucket(bucket, key);
|
||||||
|
// DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
//
|
||||||
|
// client.getObject(bucket, key, ifModifiedSince(before)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// client.getObject(bucket, key, ifModifiedSince(after)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
// } catch (ExecutionException e) {
|
||||||
|
// if (e.getCause() instanceof HttpResponseException) {
|
||||||
|
// HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
// assertEquals(ex.getResponse().getStatusCode(), 304);
|
||||||
|
// } else {
|
||||||
|
// throw e;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// void testGetIfUnmodifiedSince() throws InterruptedException,
|
||||||
|
// ExecutionException, TimeoutException, IOException {
|
||||||
|
// String bucket = bucketPrefix + "testGetIfUnmodifiedSince".toLowerCase();
|
||||||
|
// String key = "apples";
|
||||||
|
//
|
||||||
|
// DateTime before = new DateTime();
|
||||||
|
// setUpBucket(bucket, key);
|
||||||
|
// DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
//
|
||||||
|
// client.getObject(bucket, key, ifUnmodifiedSince(after)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// client.getObject(bucket, key, ifUnmodifiedSince(before)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
// } catch (ExecutionException e) {
|
||||||
|
// if (e.getCause() instanceof S3ResponseException) {
|
||||||
|
// S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||||
|
// assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
// } else {
|
||||||
|
// throw e;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// void testGetIfMatch() throws InterruptedException, ExecutionException,
|
||||||
|
// TimeoutException, IOException {
|
||||||
|
// String bucket = bucketPrefix + "testGetIfMatch".toLowerCase();
|
||||||
|
// String key = "apples";
|
||||||
|
//
|
||||||
|
// setUpBucket(bucket, key);
|
||||||
|
//
|
||||||
|
// client.getObject(bucket, key, ifMd5Matches(goodMd5)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// client.getObject(bucket, key, ifMd5Matches(badMd5)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
// } catch (ExecutionException e) {
|
||||||
|
// if (e.getCause() instanceof S3ResponseException) {
|
||||||
|
// S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||||
|
// assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
// } else {
|
||||||
|
// throw e;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// void testGetIfNoneMatch() throws InterruptedException,
|
||||||
|
// ExecutionException,
|
||||||
|
// TimeoutException, IOException {
|
||||||
|
// String bucket = bucketPrefix + "testGetIfNoneMatch".toLowerCase();
|
||||||
|
// String key = "apples";
|
||||||
|
//
|
||||||
|
// setUpBucket(bucket, key);
|
||||||
|
//
|
||||||
|
// client.getObject(bucket, key, ifMd5DoesntMatch(badMd5)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// client.getObject(bucket, key, ifMd5DoesntMatch(goodMd5)).get(10,
|
||||||
|
// TimeUnit.SECONDS);
|
||||||
|
// validateContent(bucket, key);
|
||||||
|
// } catch (ExecutionException e) {
|
||||||
|
// if (e.getCause() instanceof HttpResponseException) {
|
||||||
|
// HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
// assertEquals(ex.getResponse().getStatusCode(), 304);
|
||||||
|
// } else {
|
||||||
|
// throw e;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetIfModifiedSince() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
void testGetRange() throws InterruptedException, ExecutionException,
|
||||||
String bucket = bucketPrefix + "testGetIfModifiedSince".toLowerCase();
|
TimeoutException, IOException {
|
||||||
|
String bucket = bucketPrefix + "testGetRange".toLowerCase();
|
||||||
String key = "apples";
|
String key = "apples";
|
||||||
|
|
||||||
setUpBucket(bucket, key);
|
setUpBucket(bucket, key);
|
||||||
|
S3Object object1 = client.getObject(bucket, key, range(0, 5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
|
||||||
|
.substring(0, 6));
|
||||||
|
|
||||||
|
S3Object object2 = client.getObject(bucket, key,
|
||||||
|
range(5, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
|
||||||
|
.substring(5, TEST_STRING.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
String bucket = bucketPrefix + "testGetTwoRanges".toLowerCase();
|
||||||
|
String key = "apples";
|
||||||
|
|
||||||
|
setUpBucket(bucket, key);
|
||||||
|
S3Object object = client.getObject(bucket, key,
|
||||||
|
range(0, 5).range(5, TEST_STRING.length())).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetTail() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
String bucket = bucketPrefix + "testGetTail".toLowerCase();
|
||||||
|
String key = "apples";
|
||||||
|
|
||||||
|
setUpBucket(bucket, key);
|
||||||
|
S3Object object = client.getObject(bucket, key, tail(5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||||
|
.substring(TEST_STRING.length() - 5));
|
||||||
|
assertEquals(object.getContentLength(), 5);
|
||||||
|
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetStartAt() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
String bucket = bucketPrefix + "testGetStartAt".toLowerCase();
|
||||||
|
String key = "apples";
|
||||||
|
|
||||||
|
setUpBucket(bucket, key);
|
||||||
|
S3Object object = client.getObject(bucket, key, startAt(5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||||
|
.substring(5, TEST_STRING.length()));
|
||||||
|
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
||||||
|
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpBucket(String sourceBucket, String sourceKey)
|
private void setUpBucket(String sourceBucket, String sourceKey)
|
||||||
|
@ -58,29 +231,4 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||||
addObjectToBucket(sourceBucket, sourceKey);
|
addObjectToBucket(sourceBucket, sourceKey);
|
||||||
validateContent(sourceBucket, sourceKey);
|
validateContent(sourceBucket, sourceKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetIfUnmodifiedSince() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetIfMatch() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetIfNoneMatch() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetWithMetadata() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetRange() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@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.aws.s3.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests integrated functionality of all listOwnedBucket commands.
|
||||||
|
* <p/>
|
||||||
|
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||||
|
* in parallel.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test(groups = "integration", testName = "s3.ListOwnedBucketsIntegrationTest")
|
||||||
|
public class ListOwnedBucketsIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void bucketDoesntExist() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "shouldntexist";
|
||||||
|
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
assert !list.contains(new S3Bucket(bucketName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void bucketExists() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "needstoexist";
|
||||||
|
assert client.putBucketIfNotExists(bucketName)
|
||||||
|
.get(10, TimeUnit.SECONDS);
|
||||||
|
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
S3Bucket.Metadata firstBucket = list.get(0);
|
||||||
|
S3Bucket.Metadata toMatch = new S3Bucket.Metadata(bucketName);
|
||||||
|
toMatch.setOwner(firstBucket.getOwner());
|
||||||
|
|
||||||
|
assert list.contains(toMatch);
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,9 +31,9 @@ import java.net.URL;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +55,7 @@ public class PutBucketIntegrationTest extends S3IntegrationTest {
|
||||||
client.putBucketIfNotExists(bucketName,
|
client.putBucketIfNotExists(bucketName,
|
||||||
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
URL url = new URL(String.format("http://%1s.s3.amazonaws.com",
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
|
||||||
bucketName));
|
bucketName));
|
||||||
S3Utils.toStringAndClose(url.openStream());
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public class PutBucketIntegrationTest extends S3IntegrationTest {
|
||||||
String bucketName = bucketPrefix + "private";
|
String bucketName = bucketPrefix + "private";
|
||||||
|
|
||||||
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
URL url = new URL(String.format("http://%1s.s3.amazonaws.com",
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
|
||||||
bucketName));
|
bucketName));
|
||||||
S3Utils.toStringAndClose(url.openStream());
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public class PutBucketIntegrationTest extends S3IntegrationTest {
|
||||||
CannedAccessPolicy.PUBLIC_READ)).get(10,
|
CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
URL url = new URL(String.format("http://%1s.s3.amazonaws.com",
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
|
||||||
bucketName));
|
bucketName));
|
||||||
S3Utils.toStringAndClose(url.openStream());
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,15 +35,16 @@ import java.net.URL;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.*;
|
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.*;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all PutObject commands.
|
* Tests integrated functionality of all PutObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -70,13 +71,13 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||||
@Test(dataProvider = "putTests")
|
@Test(dataProvider = "putTests")
|
||||||
void testPutObject(String key, String type, Object content,
|
void testPutObject(String key, String type, Object content,
|
||||||
Object realObject) throws Exception {
|
Object realObject) throws Exception {
|
||||||
String bucketName = bucketPrefix + "filetestsforadrian";
|
String bucketName = bucketPrefix + "tpo";
|
||||||
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
context.createS3ObjectMap(bucketName).clear();
|
context.createS3ObjectMap(bucketName).clear();
|
||||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
||||||
.getContents().size(), 0);
|
.getContents().size(), 0);
|
||||||
S3Object object = new S3Object(key);
|
S3Object object = new S3Object(key);
|
||||||
object.getMetaData().setContentType(type);
|
object.getMetadata().setContentType(type);
|
||||||
object.setData(content);
|
object.setData(content);
|
||||||
if (content instanceof InputStream) {
|
if (content instanceof InputStream) {
|
||||||
object.generateMd5();
|
object.generateMd5();
|
||||||
|
@ -92,42 +93,42 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMetaData() throws Exception {
|
void testMetadata() throws Exception {
|
||||||
String bucketName = bucketPrefix + "header";
|
String bucketName = bucketPrefix + "tmd";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
String key = "hello";
|
String key = "hello";
|
||||||
|
|
||||||
S3Object object = new S3Object(key, TEST_STRING);
|
S3Object object = new S3Object(key, TEST_STRING);
|
||||||
object.getMetaData().setCacheControl("no-cache");
|
object.getMetadata().setCacheControl("no-cache");
|
||||||
object.getMetaData().setContentType("text/plain");
|
object.getMetadata().setContentType("text/plain");
|
||||||
object.getMetaData().setContentEncoding("x-compress");
|
object.getMetadata().setContentEncoding("x-compress");
|
||||||
object.getMetaData().setSize(TEST_STRING.length());
|
object.getMetadata().setSize(TEST_STRING.length());
|
||||||
object.getMetaData().setContentDisposition(
|
object.getMetadata().setContentDisposition(
|
||||||
"attachment; filename=hello.txt");
|
"attachment; filename=hello.txt");
|
||||||
object.getMetaData().getUserMetadata().put(
|
object.getMetadata().getUserMetadata().put(
|
||||||
S3Headers.USER_METADATA_PREFIX + "adrian", "powderpuff");
|
S3Headers.USER_METADATA_PREFIX + "adrian", "powderpuff");
|
||||||
object.getMetaData().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
|
object.getMetadata().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
|
||||||
|
|
||||||
addObjectToBucket(bucketName, object);
|
addObjectToBucket(bucketName, object);
|
||||||
S3Object newObject = validateContent(bucketName, key);
|
S3Object newObject = validateContent(bucketName, key);
|
||||||
|
|
||||||
// TODO.. why does this come back as binary/octetstring
|
// TODO.. why does this come back as binary/octetstring
|
||||||
assertEquals(newObject.getMetaData().getContentType(),
|
assertEquals(newObject.getMetadata().getContentType(),
|
||||||
"binary/octet-stream");
|
"binary/octet-stream");
|
||||||
assertEquals(newObject.getMetaData().getContentEncoding(), "x-compress");
|
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||||
assertEquals(newObject.getMetaData().getContentDisposition(),
|
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||||
"attachment; filename=hello.txt");
|
"attachment; filename=hello.txt");
|
||||||
assertEquals(newObject.getMetaData().getCacheControl(), "no-cache");
|
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||||
assertEquals(newObject.getMetaData().getSize(), TEST_STRING.length());
|
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
|
||||||
assertEquals(newObject.getMetaData().getUserMetadata().values()
|
assertEquals(newObject.getMetadata().getUserMetadata().values()
|
||||||
.iterator().next(), "powderpuff");
|
.iterator().next(), "powderpuff");
|
||||||
assertEquals(newObject.getMetaData().getMd5(), S3Utils.md5(TEST_STRING
|
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
|
||||||
.getBytes()));
|
.getBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void testCannedAccessPolicyPublic() throws Exception {
|
void testCannedAccessPolicyPublic() throws Exception {
|
||||||
String bucketName = bucketPrefix + "aclpublic";
|
String bucketName = bucketPrefix + "tcapp";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
String key = "hello";
|
String key = "hello";
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
URL url = new URL(String.format("http://%1s.s3.amazonaws.com/%1s",
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
|
||||||
bucketName, key));
|
bucketName, key));
|
||||||
S3Utils.toStringAndClose(url.openStream());
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
|
|
||||||
|
|
|
@ -116,22 +116,22 @@ public class S3CommandFactoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreatePutObject() {
|
void testCreatePutObject() {
|
||||||
S3Object.Metadata metaData = createMock(S3Object.Metadata.class);
|
S3Object.Metadata metadata = createMock(S3Object.Metadata.class);
|
||||||
S3Object object = new S3Object(metaData);
|
S3Object object = new S3Object(metadata);
|
||||||
expect(metaData.getSize()).andReturn(4L).atLeastOnce();
|
expect(metadata.getSize()).andReturn(4L).atLeastOnce();
|
||||||
expect(metaData.getKey()).andReturn("rawr");
|
expect(metadata.getKey()).andReturn("rawr");
|
||||||
expect(metaData.getContentType()).andReturn("text/xml").atLeastOnce();
|
expect(metadata.getContentType()).andReturn("text/xml").atLeastOnce();
|
||||||
expect(metaData.getCacheControl()).andReturn("no-cache").atLeastOnce();
|
expect(metadata.getCacheControl()).andReturn("no-cache").atLeastOnce();
|
||||||
expect(metaData.getContentDisposition()).andReturn("disposition")
|
expect(metadata.getContentDisposition()).andReturn("disposition")
|
||||||
.atLeastOnce();
|
.atLeastOnce();
|
||||||
expect(metaData.getContentEncoding()).andReturn("encoding")
|
expect(metadata.getContentEncoding()).andReturn("encoding")
|
||||||
.atLeastOnce();
|
.atLeastOnce();
|
||||||
expect(metaData.getMd5()).andReturn("encoding".getBytes())
|
expect(metadata.getMd5()).andReturn("encoding".getBytes())
|
||||||
.atLeastOnce();
|
.atLeastOnce();
|
||||||
Multimap<String, String> userMdata = HashMultimap.create();
|
Multimap<String, String> userMdata = HashMultimap.create();
|
||||||
expect(metaData.getUserMetadata()).andReturn(userMdata).atLeastOnce();
|
expect(metadata.getUserMetadata()).andReturn(userMdata).atLeastOnce();
|
||||||
|
|
||||||
replay(metaData);
|
replay(metadata);
|
||||||
object.setData("<a></a>");
|
object.setData("<a></a>");
|
||||||
|
|
||||||
assert commandFactory.createPutObject("test", object,
|
assert commandFactory.createPutObject("test", object,
|
||||||
|
@ -145,13 +145,13 @@ public class S3CommandFactoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateHeadMetaData() {
|
void testCreateHeadMetadata() {
|
||||||
assert commandFactory.createHeadMetaData("test", "blah") != null;
|
assert commandFactory.createHeadMetadata("test", "blah") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateListAllMyBuckets() {
|
void testCreateListAllMyBuckets() {
|
||||||
assert commandFactory.createGetMetaDataForOwnedBuckets() != null;
|
assert commandFactory.createGetMetadataForOwnedBuckets() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -35,10 +35,10 @@ import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.PerformanceTest;
|
import org.jclouds.aws.PerformanceTest;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.domain.S3Owner;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.aws.s3.xml.CopyObjectHandler;
|
import org.jclouds.aws.s3.xml.CopyObjectHandler;
|
||||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||||
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
import org.jclouds.aws.s3.xml.S3ParserFactory;
|
||||||
|
@ -122,11 +122,10 @@ public class S3ParserTest extends PerformanceTest {
|
||||||
DateTime date2 = bucket2.getCreationDate();
|
DateTime date2 = bucket2.getCreationDate();
|
||||||
assert date2.equals(expectedDate2);
|
assert date2.equals(expectedDate2);
|
||||||
assert s3Buckets.size() == 2;
|
assert s3Buckets.size() == 2;
|
||||||
S3Owner owner = new S3Owner();
|
CanonicalUser owner = new CanonicalUser(
|
||||||
owner
|
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
||||||
.setId("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
assert bucket1.getOwner().equals(owner);
|
||||||
assert bucket1.getCanonicalUser().equals(owner);
|
assert bucket2.getOwner().equals(owner);
|
||||||
assert bucket2.getCanonicalUser().equals(owner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String listBucketResult = "<ListBucketHandler xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adrianjbosstest</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>3366</Key><LastModified>2009-03-12T02:00:13.000Z</LastModified><ETag>"9d7bb64e8e18ee34eec06dd2cf37b766"</ETag><Size>136</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketHandler>";
|
public static final String listBucketResult = "<ListBucketHandler xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adrianjbosstest</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>3366</Key><LastModified>2009-03-12T02:00:13.000Z</LastModified><ETag>"9d7bb64e8e18ee34eec06dd2cf37b766"</ETag><Size>136</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketHandler>";
|
||||||
|
@ -140,15 +139,14 @@ public class S3ParserTest extends PerformanceTest {
|
||||||
S3Object.Metadata object = bucket.getContents().iterator().next();
|
S3Object.Metadata object = bucket.getContents().iterator().next();
|
||||||
assert object.getKey().equals("3366");
|
assert object.getKey().equals("3366");
|
||||||
DateTime expected = new DateTime("2009-03-12T02:00:13.000Z");
|
DateTime expected = new DateTime("2009-03-12T02:00:13.000Z");
|
||||||
assert object.getLastModified().equals(expected) : String
|
assert object.getLastModified().equals(expected) : String.format(
|
||||||
.format("expected %1s, but got %1s", expected, object
|
"expected %1$s, but got %1$s", expected, object
|
||||||
.getLastModified());
|
.getLastModified());
|
||||||
assertEquals(S3Utils.toHexString(object.getMd5()),
|
assertEquals(S3Utils.toHexString(object.getMd5()),
|
||||||
"9d7bb64e8e18ee34eec06dd2cf37b766");
|
"9d7bb64e8e18ee34eec06dd2cf37b766");
|
||||||
assert object.getSize() == 136;
|
assert object.getSize() == 136;
|
||||||
S3Owner owner = new S3Owner();
|
CanonicalUser owner = new CanonicalUser(
|
||||||
owner
|
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
||||||
.setId("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
|
||||||
owner.setDisplayName("ferncam");
|
owner.setDisplayName("ferncam");
|
||||||
assert object.getOwner().equals(owner);
|
assert object.getOwner().equals(owner);
|
||||||
assert object.getStorageClass().equals("STANDARD");
|
assert object.getStorageClass().equals("STANDARD");
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@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.aws.s3.commands.callables;
|
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public class DeleteBucketCallableTest {
|
|
||||||
|
|
||||||
// private HttpFutureCommand.ResponseCallable<Boolean> callable = null;
|
|
||||||
//
|
|
||||||
// @BeforeMethod
|
|
||||||
// void setUp() {
|
|
||||||
// callable = new DeleteBucketCallable();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @AfterMethod
|
|
||||||
// void tearDown() {
|
|
||||||
// callable = null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Test(expectedExceptions = HttpException.class)
|
|
||||||
// public void testExceptionWhenNoContentOn409() throws Exception {
|
|
||||||
// HttpResponse response = createMock(HttpResponse.class);
|
|
||||||
// expect(response.getStatusCode()).andReturn(409).atLeastOnce();
|
|
||||||
// expect(response.getContent()).andReturn(null);
|
|
||||||
// replay(response);
|
|
||||||
// callable.setResponse(response);
|
|
||||||
// callable.call();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Test
|
|
||||||
// public void testExceptionWhenIOExceptionOn409() throws
|
|
||||||
// ExecutionException,
|
|
||||||
// InterruptedException, TimeoutException, IOException {
|
|
||||||
// HttpResponse response = createMock(HttpResponse.class);
|
|
||||||
// expect(response.getStatusCode()).andReturn(409).atLeastOnce();
|
|
||||||
// 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 testFalseWhenBucketNotEmptyOn409() throws Exception {
|
|
||||||
// HttpResponse response = createMock(HttpResponse.class);
|
|
||||||
// expect(response.getStatusCode()).andReturn(409).atLeastOnce();
|
|
||||||
// expect(response.getContent()).andReturn(
|
|
||||||
// IOUtils.toInputStream("BucketNotEmpty")).atLeastOnce();
|
|
||||||
// replay(response);
|
|
||||||
// callable.setResponse(response);
|
|
||||||
// assert !callable.call().booleanValue();
|
|
||||||
// verify(response);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Test
|
|
||||||
// public void testResponseOk() throws Exception {
|
|
||||||
// HttpResponse response = createMock(HttpResponse.class);
|
|
||||||
// expect(response.getStatusCode()).andReturn(204).atLeastOnce();
|
|
||||||
// replay(response);
|
|
||||||
// callable.setResponse(response);
|
|
||||||
// assertEquals(callable.call(), new Boolean(true));
|
|
||||||
// verify(response);
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package org.jclouds.aws.s3.commands.callables;
|
||||||
|
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
import static org.easymock.classextension.EasyMock.*;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object.Metadata;
|
||||||
|
import org.jclouds.http.HttpException;
|
||||||
|
import org.jclouds.http.HttpHeaders;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.testng.annotations.AfterMethod;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public class ParseObjectFromHeadersAndHttpContentTest {
|
||||||
|
ParseObjectFromHeadersAndHttpContent callable;
|
||||||
|
ParseMetadataFromHeaders metadataParser;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
void setUp() {
|
||||||
|
metadataParser = createMock(ParseMetadataFromHeaders.class);
|
||||||
|
callable = new ParseObjectFromHeadersAndHttpContent(metadataParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterMethod
|
||||||
|
void tearDown() {
|
||||||
|
callable = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
|
public void testCall() throws HttpException {
|
||||||
|
HttpResponse response = createMock(HttpResponse.class);
|
||||||
|
expect(response.getStatusCode()).andReturn(409).atLeastOnce();
|
||||||
|
expect(response.getContent()).andReturn(null);
|
||||||
|
replay(response);
|
||||||
|
callable.setResponse(response);
|
||||||
|
callable.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseContentLengthWhenContentRangeSet()
|
||||||
|
throws HttpException {
|
||||||
|
HttpResponse response = createMock(HttpResponse.class);
|
||||||
|
metadataParser.setResponse(response);
|
||||||
|
Metadata meta = createMock(Metadata.class);
|
||||||
|
expect(metadataParser.call()).andReturn(meta);
|
||||||
|
expect(meta.getSize()).andReturn(-1l);
|
||||||
|
meta.setSize(-1l);
|
||||||
|
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH))
|
||||||
|
.andReturn("10485760").atLeastOnce();
|
||||||
|
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_RANGE))
|
||||||
|
.andReturn("0-10485759/20232760").atLeastOnce();
|
||||||
|
meta.setSize(20232760l);
|
||||||
|
expect(meta.getSize()).andReturn(20232760l);
|
||||||
|
|
||||||
|
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
|
||||||
|
expect(response.getContent()).andReturn(IOUtils.toInputStream("test"));
|
||||||
|
replay(response);
|
||||||
|
replay(metadataParser);
|
||||||
|
replay(meta);
|
||||||
|
|
||||||
|
callable.setResponse(response);
|
||||||
|
S3Object object = callable.call();
|
||||||
|
assertEquals(object.getContentLength(), 10485760);
|
||||||
|
assertEquals(object.getMetadata().getSize(), 20232760);
|
||||||
|
assertEquals(object.getContentRange(), "0-10485759/20232760");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSo
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideAcl;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
@ -34,8 +35,10 @@ import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -311,4 +314,26 @@ public class CopyObjectOptionsTest {
|
||||||
assertTrue(headers.containsValue(value));
|
assertTrue(headers.containsValue(value));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAclDefault() {
|
||||||
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
|
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAclStatic() {
|
||||||
|
CopyObjectOptions options = overrideAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
|
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildRequestHeadersACL() throws UnsupportedEncodingException {
|
||||||
|
|
||||||
|
Multimap<String, String> headers = overrideAcl(
|
||||||
|
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
||||||
|
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
||||||
|
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.startAt;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.tail;
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5DoesntMatch;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5DoesntMatch;
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5Matches;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5Matches;
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifModifiedSince;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifModifiedSince;
|
||||||
|
@ -33,8 +35,8 @@ import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.jclouds.aws.s3.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -128,6 +130,58 @@ public class GetObjectOptionsTest {
|
||||||
assertEquals(options.getRange(), "bytes=0-1024");
|
assertEquals(options.getRange(), "bytes=0-1024");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRangeZeroToFive() {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
options.range(0, 5);
|
||||||
|
assertEquals(options.getRange(), "bytes=0-5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTail() {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
options.tail(100);
|
||||||
|
assertEquals(options.getRange(), "bytes=-100");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTailStatic() {
|
||||||
|
GetObjectOptions options = tail(100);
|
||||||
|
assertEquals(options.getRange(), "bytes=-100");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testTailFail() {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
options.tail(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartAt() {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
options.startAt(100);
|
||||||
|
assertEquals(options.getRange(), "bytes=100-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartAtStatic() {
|
||||||
|
GetObjectOptions options = startAt(100);
|
||||||
|
assertEquals(options.getRange(), "bytes=100-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testStartAtFail() {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
options.startAt(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRangeZeroToFiveAnd10through100() {
|
||||||
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
options.range(0, 5).range(10, 100);
|
||||||
|
assertEquals(options.getRange(), "bytes=0-5,10-100");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullRange() {
|
public void testNullRange() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
|
@ -140,17 +194,17 @@ public class GetObjectOptionsTest {
|
||||||
bytes1to1024(options);
|
bytes1to1024(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testRangeNegative1() {
|
public void testRangeNegative1() {
|
||||||
range(-1, 0);
|
range(-1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testRangeNegative2() {
|
public void testRangeNegative2() {
|
||||||
range(0, -1);
|
range(0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testRangeNegative() {
|
public void testRangeNegative() {
|
||||||
range(-1, -1);
|
range(-1, -1);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +263,7 @@ public class GetObjectOptionsTest {
|
||||||
assertEquals(match, expected);
|
assertEquals(match, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfUnmodifiedAfterModified() {
|
public void testIfUnmodifiedAfterModified() {
|
||||||
ifModifiedSince(now).ifUnmodifiedSince(now);
|
ifModifiedSince(now).ifUnmodifiedSince(now);
|
||||||
|
|
||||||
|
@ -221,19 +275,19 @@ public class GetObjectOptionsTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfUnmodifiedAfterMd5DoesntMatch()
|
public void testIfUnmodifiedAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5DoesntMatch(testBytes).ifUnmodifiedSince(now);
|
ifMd5DoesntMatch(testBytes).ifUnmodifiedSince(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfModifiedAfterUnmodified() {
|
public void testIfModifiedAfterUnmodified() {
|
||||||
ifUnmodifiedSince(now).ifModifiedSince(now);
|
ifUnmodifiedSince(now).ifModifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfModifiedAfterMd5Matches()
|
public void testIfModifiedAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5Matches(testBytes).ifModifiedSince(now);
|
ifMd5Matches(testBytes).ifModifiedSince(now);
|
||||||
|
@ -245,7 +299,7 @@ public class GetObjectOptionsTest {
|
||||||
ifMd5DoesntMatch(testBytes).ifModifiedSince(now);
|
ifMd5DoesntMatch(testBytes).ifModifiedSince(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5MatchesAfterIfModified()
|
public void testMd5MatchesAfterIfModified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifModifiedSince(now).ifMd5Matches(testBytes);
|
ifModifiedSince(now).ifMd5Matches(testBytes);
|
||||||
|
@ -258,7 +312,7 @@ public class GetObjectOptionsTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5MatchesAfterMd5DoesntMatch()
|
public void testMd5MatchesAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5DoesntMatch(testBytes).ifMd5Matches(testBytes);
|
ifMd5DoesntMatch(testBytes).ifMd5Matches(testBytes);
|
||||||
|
@ -270,14 +324,14 @@ public class GetObjectOptionsTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5DoesntMatchAfterIfUnmodified()
|
public void testMd5DoesntMatchAfterIfUnmodified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifUnmodifiedSince(now).ifMd5DoesntMatch(testBytes);
|
ifUnmodifiedSince(now).ifMd5DoesntMatch(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5DoesntMatchAfterMd5Matches()
|
public void testMd5DoesntMatchAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5Matches(testBytes).ifMd5DoesntMatch(testBytes);
|
ifMd5Matches(testBytes).ifMd5DoesntMatch(testBytes);
|
||||||
|
|
|
@ -30,11 +30,12 @@ import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,10 +28,11 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Headers;
|
|
||||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Headers;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,8 +25,9 @@ package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
|
||||||
import org.jclouds.aws.s3.filters.ParseS3ErrorFromXmlContent;
|
import org.jclouds.aws.s3.filters.ParseS3ErrorFromXmlContent;
|
||||||
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
|
import org.jclouds.http.CloseContentAndSetExceptionHandler;
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
import org.jclouds.http.annotation.ClientErrorHandler;
|
import org.jclouds.http.annotation.ClientErrorHandler;
|
||||||
import org.jclouds.http.annotation.RedirectHandler;
|
import org.jclouds.http.annotation.RedirectHandler;
|
||||||
|
@ -36,6 +37,7 @@ import org.testng.annotations.AfterMethod;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -118,7 +120,7 @@ public class S3ContextModuleTest {
|
||||||
RedirectHandlerTest error = injector
|
RedirectHandlerTest error = injector
|
||||||
.getInstance(RedirectHandlerTest.class);
|
.getInstance(RedirectHandlerTest.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
assertEquals(error.errorHandler.getClass(),
|
||||||
ParseS3ErrorFromXmlContent.class);
|
CloseContentAndSetExceptionHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,7 +39,7 @@ public class S3ObjectTest {
|
||||||
S3Object object = new S3Object("test");
|
S3Object object = new S3Object("test");
|
||||||
File file = new File("hello.txt");
|
File file = new File("hello.txt");
|
||||||
object.setData(file);
|
object.setData(file);
|
||||||
assertEquals(object.getMetaData().getContentType(),
|
assertEquals(object.getMetadata().getContentType(),
|
||||||
ContentTypes.UNKNOWN_MIME_TYPE);
|
ContentTypes.UNKNOWN_MIME_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,13 @@ package org.jclouds.aws.s3.filters;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.name.Names;
|
import com.google.inject.name.Names;
|
||||||
import org.jclouds.aws.s3.DateService;
|
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.RequestAuthorizeSignatureTest")
|
@Test(groups = "unit", sequential = true, testName = "s3.RequestAuthorizeSignatureTest")
|
||||||
public class RequestAuthorizeSignatureTest {
|
public class RequestAuthorizeSignatureTest {
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
import org.jclouds.aws.s3.domain.S3Error;
|
||||||
|
@ -31,7 +31,6 @@ import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public class ErrorHandlerTest extends BaseHandlerTest {
|
public class ErrorHandlerTest extends BaseHandlerTest {
|
||||||
public static final String errorFromAmazonIfYouDontRemoveTransferEncodingHeader = "<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>7C59925D75D15561</RequestId><HostId>fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb</HostId></Error>";
|
public static final String errorFromAmazonIfYouDontRemoveTransferEncodingHeader = "<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>7C59925D75D15561</RequestId><HostId>fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb</HostId></Error>";
|
||||||
|
@ -46,9 +45,9 @@ public class ErrorHandlerTest extends BaseHandlerTest {
|
||||||
assertEquals(error.getCode(), "NotImplemented");
|
assertEquals(error.getCode(), "NotImplemented");
|
||||||
assertEquals(error.getMessage(),
|
assertEquals(error.getMessage(),
|
||||||
"A header you provided implies functionality that is not implemented");
|
"A header you provided implies functionality that is not implemented");
|
||||||
assertEquals(error.getHeader(), "Transfer-Encoding");
|
assertEquals(error.getDetails().get("Header"), "Transfer-Encoding");
|
||||||
assertEquals(error.getRequestId(), "7C59925D75D15561");
|
assertEquals(error.getRequestId(), "7C59925D75D15561");
|
||||||
assertEquals(error.getHostId(),
|
assertEquals(error.getDetails().get("HostId"),
|
||||||
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
|
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
====
|
|
||||||
|
|
||||||
Copyright (C) 2009 Adrian Cole <adrian@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.
|
|
||||||
====================================================================
|
|
||||||
====
|
|
||||||
This samples uses the Google App Engine for Java SDK located at http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.0.zip
|
|
||||||
|
|
||||||
Please unzip the above file and modify your maven settings.xml like below before attempting to run 'mvn install'
|
|
||||||
|
|
||||||
<profile>
|
|
||||||
<id>appengine</id>
|
|
||||||
<activation>
|
|
||||||
<activeByDefault>true</activeByDefault>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<appengine.home>/path/to/appengine-java-sdk-1.2.0</appengine.home>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
<profile>
|
|
||||||
<id>aws</id>
|
|
||||||
<activation>
|
|
||||||
<activeByDefault>true</activeByDefault>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<jclouds.aws.accesskeyid>YOUR_ACCESS_KEY_ID</jclouds.aws.accesskeyid>
|
|
||||||
<jclouds.aws.secretaccesskey>YOUR_SECRET_KEY</jclouds.aws.secretaccesskey>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>jclouds</id>
|
|
||||||
<url>http://jclouds.googlecode.com/svn/trunk/repo</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
|
@ -1,194 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
$HeadURL$
|
|
||||||
$Revision$
|
|
||||||
$Date$
|
|
||||||
|
|
||||||
Copyright (C) 2009 Adrian Cole <adrian@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-gae-s3-example</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>JClouds Sample for Google App Engine</name>
|
|
||||||
<description>JClouds Sample for Google App Engine</description>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<!-- note you must set the property ${appengine.home} to a valid extraction of appengine-java-sdk -->
|
|
||||||
<appengine.home>/Users/adriancole/Desktop/appengine-java-sdk-1.2.0</appengine.home>
|
|
||||||
<devappserver.address>localhost</devappserver.address>
|
|
||||||
<devappserver.port>8088</devappserver.port>
|
|
||||||
<jclouds.aws.accesskeyid></jclouds.aws.accesskeyid>
|
|
||||||
<jclouds.aws.secretaccesskey></jclouds.aws.secretaccesskey>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>guice-snapshot</id>
|
|
||||||
<url>http://guice-maven.googlecode.com/svn/trunk</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<pluginRepositories>
|
|
||||||
<pluginRepository>
|
|
||||||
<id>Main Maven Repo</id>
|
|
||||||
<url>http://repo1.maven.org/maven2/</url>
|
|
||||||
</pluginRepository>
|
|
||||||
</pluginRepositories>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>${project.groupId}</groupId>
|
|
||||||
<artifactId>jclouds-gae</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>${project.groupId}</groupId>
|
|
||||||
<artifactId>jclouds-s3</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>${project.groupId}</groupId>
|
|
||||||
<artifactId>jclouds-s3</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
<type>test-jar</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.guice</groupId>
|
|
||||||
<artifactId>guice-servlet</artifactId>
|
|
||||||
<version>2.0-r943</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<artifactId>standard</artifactId>
|
|
||||||
<groupId>taglibs</groupId>
|
|
||||||
<version>1.1.2</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<artifactId>jstl</artifactId>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<version>1.1.2</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.geronimo.specs</groupId>
|
|
||||||
<artifactId>geronimo-el_1.0_spec</artifactId>
|
|
||||||
<version>1.0.1</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.geronimo.specs</groupId>
|
|
||||||
<artifactId>geronimo-jsp_2.1_spec</artifactId>
|
|
||||||
<version>1.0.1</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.geronimo.specs</groupId>
|
|
||||||
<artifactId>geronimo-servlet_2.5_spec</artifactId>
|
|
||||||
<version>1.2</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.appengine</groupId>
|
|
||||||
<artifactId>appengine-tools-api</artifactId>
|
|
||||||
<version>1.2.0</version>
|
|
||||||
<scope>system</scope>
|
|
||||||
<systemPath>${appengine.home}/lib/appengine-tools-api.jar</systemPath>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
<build>
|
|
||||||
<finalName>${project.artifactId}</finalName>
|
|
||||||
<testSourceDirectory>src/it/java</testSourceDirectory>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.4.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>integration</id>
|
|
||||||
<phase>integration-test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>test</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<testClassesDirectory>target/test-classes</testClassesDirectory>
|
|
||||||
<systemProperties>
|
|
||||||
<property>
|
|
||||||
<name>jclouds.aws.accesskeyid</name>
|
|
||||||
<value>${jclouds.aws.accesskeyid}</value>
|
|
||||||
</property>
|
|
||||||
<property>
|
|
||||||
<name>jclouds.aws.secretaccesskey</name>
|
|
||||||
<value>${jclouds.aws.secretaccesskey}</value>
|
|
||||||
</property>
|
|
||||||
<property>
|
|
||||||
<name>appengine.home</name>
|
|
||||||
<value>${appengine.home}</value>
|
|
||||||
</property>
|
|
||||||
<property>
|
|
||||||
<name>devappserver.address</name>
|
|
||||||
<value>${devappserver.address}</value>
|
|
||||||
</property>
|
|
||||||
<property>
|
|
||||||
<name>devappserver.port</name>
|
|
||||||
<value>${devappserver.port}</value>
|
|
||||||
</property>
|
|
||||||
<property>
|
|
||||||
<name>warfile</name>
|
|
||||||
<value>${project.build.directory}/${project.artifactId}</value>
|
|
||||||
</property>
|
|
||||||
</systemProperties>
|
|
||||||
<additionalClasspathElements>
|
|
||||||
<additionalClasspathElement>${appengine.home}/lib/appengine-tools-api.jar
|
|
||||||
</additionalClasspathElement>
|
|
||||||
</additionalClasspathElements>
|
|
||||||
<environmentVariables>
|
|
||||||
<DEBUG>true</DEBUG>
|
|
||||||
<SDK_BIN>${appengine.home}/bin</SDK_BIN>
|
|
||||||
<SDK_LIB>${appengine.home}/lib</SDK_LIB>
|
|
||||||
<SDK_CONFIG>${appengine.home}/config/sdk</SDK_CONFIG>
|
|
||||||
</environmentVariables>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<!-- fool default surefire execution in 'test' to not find any test classes -->
|
|
||||||
<testClassesDirectory>target/classes</testClassesDirectory>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
|
|
||||||
</build>
|
|
||||||
</project>
|
|
|
@ -1,75 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@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.samples.googleappengine.functest;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.testng.annotations.AfterTest;
|
|
||||||
|
|
||||||
import com.google.appengine.tools.KickStart;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic functionality to start a local google app engine instance.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class BaseGoogleAppEngineTest {
|
|
||||||
|
|
||||||
Thread server;
|
|
||||||
URL url;
|
|
||||||
|
|
||||||
protected void writePropertiesAndStartServer(final String address,
|
|
||||||
final String port, final String warfile, Properties props)
|
|
||||||
throws IOException, FileNotFoundException, InterruptedException {
|
|
||||||
url = new URL(String.format("http://%1s:%2s", address, port));
|
|
||||||
|
|
||||||
props.store(new FileOutputStream(String.format(
|
|
||||||
"%1s/WEB-INF/jclouds.properties", warfile)), "test");
|
|
||||||
this.server = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
KickStart
|
|
||||||
.main(new String[] {
|
|
||||||
"com.google.appengine.tools.development.DevAppServerMain",
|
|
||||||
"--disable_update_check", "-a", address, "-p",
|
|
||||||
port, warfile });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
server.start();
|
|
||||||
Thread.sleep(7 * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@AfterTest
|
|
||||||
public void stopDevAppServer() throws Exception {
|
|
||||||
server.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@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.samples.googleappengine.functest;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
|
||||||
import org.testng.annotations.BeforeTest;
|
|
||||||
import org.testng.annotations.Optional;
|
|
||||||
import org.testng.annotations.Parameters;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts up the Google App Engine for Java Development environment and deploys
|
|
||||||
* an application which tests S3.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Test(groups = "integration", enabled = true, sequential = true, testName = "functionalTests")
|
|
||||||
public class GoogleAppEngineTest extends BaseGoogleAppEngineTest {
|
|
||||||
|
|
||||||
private static final String sysAWSAccessKeyId = System
|
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
|
||||||
private static final String sysAWSSecretAccessKey = System
|
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
|
||||||
|
|
||||||
@BeforeTest
|
|
||||||
@Parameters( { "warfile", "devappserver.address", "devappserver.port",
|
|
||||||
S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
|
||||||
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
|
||||||
public void startDevAppServer(final String warfile, final String address,
|
|
||||||
final String port, @Optional String AWSAccessKeyId,
|
|
||||||
@Optional String AWSSecretAccessKey) throws Exception {
|
|
||||||
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId
|
|
||||||
: sysAWSAccessKeyId;
|
|
||||||
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey
|
|
||||||
: sysAWSSecretAccessKey;
|
|
||||||
|
|
||||||
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId");
|
|
||||||
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey");
|
|
||||||
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.put(S3Constants.PROPERTY_AWS_ACCESSKEYID, AWSAccessKeyId);
|
|
||||||
props.put(S3Constants.PROPERTY_AWS_SECRETACCESSKEY, AWSSecretAccessKey);
|
|
||||||
writePropertiesAndStartServer(address, port, warfile, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldPass() throws InterruptedException, IOException {
|
|
||||||
InputStream i = url.openStream();
|
|
||||||
String string = IOUtils.toString(i);
|
|
||||||
assert string.indexOf("Hello World!") >= 0 : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(invocationCount = 5, enabled = true)
|
|
||||||
public void testGuiceJCloudsSerial() throws InterruptedException,
|
|
||||||
IOException {
|
|
||||||
URL gurl = new URL(url, "/guice/listbuckets.s3");
|
|
||||||
InputStream i = gurl.openStream();
|
|
||||||
String string = IOUtils.toString(i);
|
|
||||||
assert string.indexOf("List") >= 0 : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(invocationCount = 50, enabled = false, threadPoolSize = 10)
|
|
||||||
public void testGuiceJCloudsParallel() throws InterruptedException,
|
|
||||||
IOException {
|
|
||||||
URL gurl = new URL(url, "/guice/listbuckets.s3");
|
|
||||||
InputStream i = gurl.openStream();
|
|
||||||
String string = IOUtils.toString(i);
|
|
||||||
assert string.indexOf("List") >= 0 : string;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@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.samples.googleappengine;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Context;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Singleton;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows an example of how to use @{link S3Connection} injected with Guice.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class JCloudsServlet extends HttpServlet {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
S3Context context;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest httpServletRequest,
|
|
||||||
HttpServletResponse httpServletResponse) throws ServletException,
|
|
||||||
IOException {
|
|
||||||
httpServletResponse.setContentType("text/plain");
|
|
||||||
Writer writer = httpServletResponse.getWriter();
|
|
||||||
try {
|
|
||||||
List<S3Bucket.Metadata> myBuckets = context.getConnection()
|
|
||||||
.getOwnedBuckets().get(10, TimeUnit.SECONDS);
|
|
||||||
writer.write("List:\n");
|
|
||||||
for (S3Bucket.Metadata bucket : myBuckets) {
|
|
||||||
writer.write(String.format(" %1s: %2s entries%n", bucket
|
|
||||||
.getName(), context.createInputStreamMap(
|
|
||||||
bucket.getName()).size()));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ServletException(e);
|
|
||||||
}
|
|
||||||
writer.flush();
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@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.samples.googleappengine.config;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.S3Constants;
|
|
||||||
import org.jclouds.aws.s3.S3Context;
|
|
||||||
import org.jclouds.aws.s3.S3ContextFactory;
|
|
||||||
import org.jclouds.gae.config.URLFetchServiceClientModule;
|
|
||||||
import org.jclouds.samples.googleappengine.JCloudsServlet;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
import com.google.inject.servlet.GuiceServletContextListener;
|
|
||||||
import com.google.inject.servlet.ServletModule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup Logging and create Injector for use in testing S3.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GuiceServletConfig extends GuiceServletContextListener {
|
|
||||||
@Inject
|
|
||||||
S3Context context;
|
|
||||||
String accessKeyId;
|
|
||||||
String secretAccessKey;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
|
||||||
Properties props = loadJCloudsProperties(servletContextEvent);
|
|
||||||
this.accessKeyId = props
|
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
|
||||||
this.secretAccessKey = props
|
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
|
||||||
super.contextInitialized(servletContextEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Properties loadJCloudsProperties(
|
|
||||||
ServletContextEvent servletContextEvent) {
|
|
||||||
InputStream input = servletContextEvent.getServletContext()
|
|
||||||
.getResourceAsStream("/WEB-INF/jclouds.properties");
|
|
||||||
Properties props = new Properties();
|
|
||||||
try {
|
|
||||||
props.load(input);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(input);
|
|
||||||
}
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Injector getInjector() {
|
|
||||||
return S3ContextFactory.createInjector(accessKeyId, secretAccessKey,
|
|
||||||
false, new URLFetchServiceClientModule(),
|
|
||||||
new ServletModule() {
|
|
||||||
@Override
|
|
||||||
protected void configureServlets() {
|
|
||||||
serve("*.s3").with(JCloudsServlet.class);
|
|
||||||
requestInjection(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
|
||||||
context.close();
|
|
||||||
super.contextDestroyed(servletContextEvent);
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue