mirror of https://github.com/apache/jclouds.git
separated out unit tests from integration tests and fixed javadoc
git-svn-id: http://jclouds.googlecode.com/svn/trunk@810 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
40067b58f0
commit
69deb933e8
|
@ -23,26 +23,20 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.http.internal;
|
package org.jclouds.http.internal;
|
||||||
|
|
||||||
import java.net.URL;
|
import com.google.inject.Inject;
|
||||||
import java.util.Collections;
|
import org.jclouds.http.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
|
||||||
import org.jclouds.http.HttpFutureCommandClient;
|
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
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;
|
||||||
import org.jclouds.http.annotation.ServerErrorHandler;
|
import org.jclouds.http.annotation.ServerErrorHandler;
|
||||||
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import javax.annotation.Resource;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandClient {
|
public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandClient {
|
||||||
|
|
||||||
protected final URL target;
|
protected final URL target;
|
||||||
|
|
||||||
|
@ -63,30 +57,30 @@ public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandC
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BaseHttpFutureCommandClient(URL target) {
|
public BaseHttpFutureCommandClient(URL target) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isRetryable(HttpFutureCommand<?> command,
|
protected boolean isRetryable(HttpFutureCommand<?> command,
|
||||||
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: %1$s", command);
|
logger.debug("resubmitting command: %1$s", command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleResponse(HttpFutureCommand<?> command, HttpResponse response) {
|
protected void handleResponse(HttpFutureCommand<?> command, HttpResponse response) {
|
||||||
int code = response.getStatusCode();
|
int code = response.getStatusCode();
|
||||||
if (code >= 500) {
|
if (code >= 500) {
|
||||||
this.serverErrorHandler.handle(command, response);
|
this.serverErrorHandler.handle(command, response);
|
||||||
} else if (code >= 400 && code < 500) {
|
} else if (code >= 400 && code < 500) {
|
||||||
this.clientErrorHandler.handle(command, response);
|
this.clientErrorHandler.handle(command, response);
|
||||||
} else if (code >= 300 && code < 400) {
|
} else if (code >= 300 && code < 400) {
|
||||||
this.redirectHandler.handle(command, response);
|
this.redirectHandler.handle(command, response);
|
||||||
} else {
|
} else {
|
||||||
command.getResponseFuture().setResponse(response);
|
command.getResponseFuture().setResponse(response);
|
||||||
command.getResponseFuture().run();
|
command.getResponseFuture().run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,44 +23,41 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.logging.config;
|
package org.jclouds.logging.config;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.logging.Logger.LoggerFactory;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import static com.google.common.collect.Sets.filter;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.ProvisionException;
|
import com.google.inject.ProvisionException;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.spi.InjectionListener;
|
import com.google.inject.spi.InjectionListener;
|
||||||
import com.google.inject.spi.TypeEncounter;
|
import com.google.inject.spi.TypeEncounter;
|
||||||
import com.google.inject.spi.TypeListener;
|
import com.google.inject.spi.TypeListener;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.logging.Logger.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TypeListener that will bind {@link org.jclouds.logging.Logger} to members annotated with
|
* TypeListener that will bind {@link org.jclouds.logging.Logger} to members annotated with
|
||||||
* {@link javax.annotation.Resource}
|
* {@link javax.annotation.Resource}
|
||||||
*
|
* <p/>
|
||||||
* This class is a TypeListener so that it can create a logger whose category is
|
* This class is a TypeListener so that it can create a logger whose category is
|
||||||
* the same as the name of the injected instance's class.
|
* the same as the name of the injected instance's class.
|
||||||
*
|
* <p/>
|
||||||
* Note that this occurs post-object construction through
|
* Note that this occurs post-object construction through
|
||||||
* {@link com.google.inject.Binder#bindListener}.
|
* {@link com.google.inject.Binder#bindListener}.
|
||||||
*
|
* <p/>
|
||||||
* Here's an example usage:
|
* Here's an example usage:
|
||||||
* <pre>
|
* <pre>
|
||||||
* class A {
|
* class A {
|
||||||
* @Resource private Logger logger = Logger.NULL;
|
* @Resource private Logger logger = Logger.NULL;
|
||||||
* }
|
* }
|
||||||
*
|
* <p/>
|
||||||
* Injector i = Guice.createInjector(new AbstractModule() {
|
* Injector i = Guice.createInjector(new AbstractModule() {
|
||||||
* @Override protected void configure() {
|
* @Override protected void configure() {
|
||||||
* bindListener(any(), new
|
* bindListener(any(), new
|
||||||
|
@ -68,79 +65,72 @@ import com.google.inject.spi.TypeListener;
|
||||||
* JDKLogger.JDKLoggerFactory()));
|
* JDKLogger.JDKLoggerFactory()));
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
*
|
* <p/>
|
||||||
* A = i.getInstance(A.class);
|
* A = i.getInstance(A.class);
|
||||||
* // A will now have a logger associated with it
|
* // A will now have a logger associated with it
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class BindLoggersAnnotatedWithResource implements TypeListener {
|
public class BindLoggersAnnotatedWithResource implements TypeListener {
|
||||||
|
|
||||||
static class AssignLoggerToField<I> implements InjectionListener<I> {
|
static class AssignLoggerToField<I> implements InjectionListener<I> {
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final Field field;
|
private final Field field;
|
||||||
|
|
||||||
AssignLoggerToField(Logger logger, Field field) {
|
AssignLoggerToField(Logger logger, Field field) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.field = field;
|
this.field = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterInjection(I injectee) {
|
public void afterInjection(I injectee) {
|
||||||
try {
|
try {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(injectee, logger);
|
field.set(injectee, logger);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new ProvisionException(e.getMessage(), e);
|
throw new ProvisionException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class LoggerFieldsAnnotatedWithResource implements
|
static class LoggerFieldsAnnotatedWithResource implements
|
||||||
Function<Field, Field> {
|
Predicate<Field> {
|
||||||
public Field apply(Field from) {
|
public boolean apply(Field from) {
|
||||||
Annotation inject = from.getAnnotation(Resource.class);
|
Annotation inject = from.getAnnotation(Resource.class);
|
||||||
if (inject != null && from.getType().isAssignableFrom(Logger.class)) {
|
return (inject != null && from.getType().isAssignableFrom(Logger.class));
|
||||||
return from;
|
}
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LoggerFactory loggerFactory;
|
private final LoggerFactory loggerFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BindLoggersAnnotatedWithResource(LoggerFactory loggerFactory) {
|
public BindLoggersAnnotatedWithResource(LoggerFactory loggerFactory) {
|
||||||
this.loggerFactory = loggerFactory;
|
this.loggerFactory = loggerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <I> void hear(TypeLiteral<I> injectableType,
|
public <I> void hear(TypeLiteral<I> injectableType,
|
||||||
TypeEncounter<I> encounter) {
|
TypeEncounter<I> encounter) {
|
||||||
|
|
||||||
Class<? super I> type = injectableType.getRawType();
|
Class<? super I> type = injectableType.getRawType();
|
||||||
Set<Field> loggerFields = getLoggerFieldsAnnotatedWithResource(type);
|
Set<Field> loggerFields = getLoggerFieldsAnnotatedWithResource(type);
|
||||||
if (loggerFields.size() == 0)
|
if (loggerFields.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger logger = loggerFactory.getLogger(type.getName());
|
Logger logger = loggerFactory.getLogger(type.getName());
|
||||||
|
|
||||||
for (Field field : loggerFields) {
|
for (Field field : loggerFields) {
|
||||||
encounter.register(new AssignLoggerToField<I>(logger, field));
|
encounter.register(new AssignLoggerToField<I>(logger, field));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Set<Field> getLoggerFieldsAnnotatedWithResource(Class<?> declaredType) {
|
Set<Field> getLoggerFieldsAnnotatedWithResource(Class<?> declaredType) {
|
||||||
Set<Field> fields = new HashSet<Field>();
|
Set<Field> fields = new HashSet<Field>();
|
||||||
Class<?> type = declaredType;
|
Class<?> type = declaredType;
|
||||||
while (type != null) {
|
while (type != null) {
|
||||||
fields.addAll(Arrays.asList(type.getDeclaredFields()));
|
fields.addAll(Arrays.asList(type.getDeclaredFields()));
|
||||||
type = type.getSuperclass();
|
type = type.getSuperclass();
|
||||||
}
|
}
|
||||||
Set<Field> loggerFields = Sets.newHashSet(Iterables.transform(fields,
|
return filter(fields, new LoggerFieldsAnnotatedWithResource());
|
||||||
new LoggerFieldsAnnotatedWithResource()));
|
|
||||||
loggerFields.remove(null);
|
|
||||||
return loggerFields;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -37,6 +37,12 @@ import org.apache.commons.io.IOUtils;
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param <E> Exception type you'd like rethrown
|
||||||
|
* @param e Exception you are inspecting
|
||||||
|
* @throws E
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <E extends Exception> void rethrowIfRuntimeOrSameType(Exception e) throws E {
|
public static <E extends Exception> void rethrowIfRuntimeOrSameType(Exception e) throws E {
|
||||||
if (e instanceof ExecutionException) {
|
if (e instanceof ExecutionException) {
|
||||||
|
|
|
@ -23,129 +23,126 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.logging.config;
|
package org.jclouds.logging.config;
|
||||||
|
|
||||||
import static com.google.inject.matcher.Matchers.any;
|
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.AssignLoggerToField;
|
|
||||||
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.LoggerFieldsAnnotatedWithResource;
|
|
||||||
import org.jclouds.logging.jdk.JDKLogger;
|
|
||||||
import org.testng.annotations.BeforeMethod;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
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;
|
||||||
|
import static com.google.inject.matcher.Matchers.any;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.AssignLoggerToField;
|
||||||
|
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.LoggerFieldsAnnotatedWithResource;
|
||||||
|
import org.jclouds.logging.jdk.JDKLogger;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Test
|
||||||
public class BindLoggersAnnotatedWithResourceTest {
|
public class BindLoggersAnnotatedWithResourceTest {
|
||||||
|
|
||||||
private BindLoggersAnnotatedWithResource blawr;
|
private BindLoggersAnnotatedWithResource blawr;
|
||||||
|
|
||||||
public static class A {
|
public static class A {
|
||||||
@Resource
|
@Resource
|
||||||
private Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class B {
|
public static class B {
|
||||||
@Resource
|
@Resource
|
||||||
private Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void createBlawr() {
|
void createBlawr() {
|
||||||
blawr = new BindLoggersAnnotatedWithResource(
|
blawr = new BindLoggersAnnotatedWithResource(
|
||||||
new JDKLogger.JDKLoggerFactory());
|
new JDKLogger.JDKLoggerFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testHear() {
|
void testHear() {
|
||||||
Injector i = Guice.createInjector(new AbstractModule() {
|
Injector i = Guice.createInjector(new AbstractModule() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bindListener(any(), blawr);
|
bindListener(any(), blawr);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
assertEquals(i.getInstance(A.class).logger.getCategory(), getClass()
|
assertEquals(i.getInstance(A.class).logger.getCategory(), getClass()
|
||||||
.getName()
|
.getName()
|
||||||
+ "$A");
|
+ "$A");
|
||||||
assertEquals(i.getInstance(B.class).logger.getCategory(), getClass()
|
assertEquals(i.getInstance(B.class).logger.getCategory(), getClass()
|
||||||
.getName()
|
.getName()
|
||||||
+ "$B");
|
+ "$B");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAssignLoggerToField() throws SecurityException,
|
public void testAssignLoggerToField() throws SecurityException,
|
||||||
NoSuchFieldException, IllegalArgumentException,
|
NoSuchFieldException, IllegalArgumentException,
|
||||||
IllegalAccessException {
|
IllegalAccessException {
|
||||||
Logger logger = createMock(Logger.class);
|
Logger logger = createMock(Logger.class);
|
||||||
A a = new A();
|
A a = new A();
|
||||||
Field field = A.class.getDeclaredField("logger");
|
Field field = A.class.getDeclaredField("logger");
|
||||||
AssignLoggerToField<A> assigner = new AssignLoggerToField<A>(logger,
|
AssignLoggerToField<A> assigner = new AssignLoggerToField<A>(logger,
|
||||||
field);
|
field);
|
||||||
assigner.afterInjection(a);
|
assigner.afterInjection(a);
|
||||||
assert field.get(a).equals(logger);
|
assert field.get(a).equals(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoggerFieldsAnnotatedWithResource()
|
public void testLoggerFieldsAnnotatedWithResource()
|
||||||
throws SecurityException, NoSuchFieldException {
|
throws SecurityException, NoSuchFieldException {
|
||||||
LoggerFieldsAnnotatedWithResource function = new LoggerFieldsAnnotatedWithResource();
|
LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource();
|
||||||
assertEquals(function.apply(A.class.getDeclaredField("logger")),
|
assert predicate.apply(A.class.getDeclaredField("logger"));
|
||||||
A.class.getDeclaredField("logger"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class C {
|
public static class C {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Inject
|
@Inject
|
||||||
private Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoggerFieldsAnnotatedWithInjectReturnsNull()
|
public void testLoggerFieldsAnnotatedWithInjectReturnsNull()
|
||||||
throws SecurityException, NoSuchFieldException {
|
throws SecurityException, NoSuchFieldException {
|
||||||
LoggerFieldsAnnotatedWithResource function = new LoggerFieldsAnnotatedWithResource();
|
LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource();
|
||||||
assertNull(function.apply(C.class.getDeclaredField("logger")));
|
assert ! predicate.apply(C.class.getDeclaredField("logger"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class D {
|
public static class D {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Resource
|
@Resource
|
||||||
private Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Resource
|
@Resource
|
||||||
private Logger blogger;
|
private Logger blogger;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLoggerFieldsAnnotatedWithResourceNoLogger() {
|
public void testGetLoggerFieldsAnnotatedWithResourceNoLogger() {
|
||||||
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(this
|
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(this
|
||||||
.getClass());
|
.getClass());
|
||||||
assertEquals(fields.size(), 0);
|
assertEquals(fields.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLoggerFieldsAnnotatedWithResourceOneLogger() {
|
public void testGetLoggerFieldsAnnotatedWithResourceOneLogger() {
|
||||||
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(A.class);
|
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(A.class);
|
||||||
assertEquals(fields.size(), 1);
|
assertEquals(fields.size(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLoggerFieldsAnnotatedWithResourceTwoLoggers() {
|
public void testGetLoggerFieldsAnnotatedWithResourceTwoLoggers() {
|
||||||
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(D.class);
|
Set<Field> fields = blawr.getLoggerFieldsAnnotatedWithResource(D.class);
|
||||||
assertEquals(fields.size(), 2);
|
assertEquals(fields.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,32 +24,18 @@
|
||||||
package org.jclouds.gae;
|
package org.jclouds.gae;
|
||||||
|
|
||||||
import static com.google.appengine.api.urlfetch.FetchOptions.Builder.disallowTruncate;
|
import static com.google.appengine.api.urlfetch.FetchOptions.Builder.disallowTruncate;
|
||||||
|
import com.google.appengine.api.urlfetch.*;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.http.*;
|
||||||
|
import org.jclouds.http.internal.BaseHttpFutureCommandClient;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
|
||||||
import org.jclouds.http.HttpFutureCommandClient;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.jclouds.http.internal.BaseHttpFutureCommandClient;
|
|
||||||
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPHeader;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPMethod;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPRequest;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPResponse;
|
|
||||||
import com.google.appengine.api.urlfetch.URLFetchService;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Google App Engine version of {@link HttpFutureCommandClient}
|
* Google App Engine version of {@link HttpFutureCommandClient}
|
||||||
*
|
*
|
||||||
|
@ -60,56 +46,56 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public URLFetchServiceClient(URL target, URLFetchService urlFetchService)
|
public URLFetchServiceClient(URL target, URLFetchService urlFetchService)
|
||||||
throws MalformedURLException {
|
throws MalformedURLException {
|
||||||
super(target);
|
super(target);
|
||||||
this.urlFetchService = urlFetchService;
|
this.urlFetchService = urlFetchService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submit(HttpFutureCommand<?> command) {
|
public void submit(HttpFutureCommand<?> command) {
|
||||||
HttpRequest request = command.getRequest();
|
HttpRequest request = command.getRequest();
|
||||||
HTTPResponse gaeResponse = null;
|
HTTPResponse gaeResponse = null;
|
||||||
try {
|
try {
|
||||||
for (HttpRequestFilter filter : requestFilters) {
|
for (HttpRequestFilter filter : requestFilters) {
|
||||||
filter.filter(request);
|
filter.filter(request);
|
||||||
}
|
}
|
||||||
HttpResponse response = null;
|
HttpResponse response = null;
|
||||||
for (;;) {
|
for (; ;) {
|
||||||
logger.trace("%1$s - converting request %2$s", target, request);
|
logger.trace("%1$s - converting request %2$s", target, request);
|
||||||
HTTPRequest gaeRequest = convert(request);
|
HTTPRequest gaeRequest = convert(request);
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
logger.trace(
|
logger.trace(
|
||||||
"%1$s - submitting request %2$s, headers: %3$s",
|
"%1$s - submitting request %2$s, headers: %3$s",
|
||||||
target, gaeRequest.getURL(),
|
target, gaeRequest.getURL(),
|
||||||
headersAsString(gaeRequest.getHeaders()));
|
headersAsString(gaeRequest.getHeaders()));
|
||||||
gaeResponse = this.urlFetchService.fetch(gaeRequest);
|
gaeResponse = this.urlFetchService.fetch(gaeRequest);
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
logger
|
logger
|
||||||
.trace(
|
.trace(
|
||||||
"%1$s - received response code %2$s, headers: %3$s",
|
"%1$s - received response code %2$s, headers: %3$s",
|
||||||
target, gaeResponse.getResponseCode(),
|
target, gaeResponse.getResponseCode(),
|
||||||
headersAsString(gaeResponse.getHeaders()));
|
headersAsString(gaeResponse.getHeaders()));
|
||||||
response = convert(gaeResponse);
|
response = convert(gaeResponse);
|
||||||
if (isRetryable(command, response))
|
if (isRetryable(command, response))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
handleResponse(command, response);
|
handleResponse(command, response);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (gaeResponse != null && gaeResponse.getContent() != null) {
|
if (gaeResponse != null && gaeResponse.getContent() != null) {
|
||||||
logger.error(e,
|
logger.error(e,
|
||||||
"error encountered during the execution: %1$s%n%2$s",
|
"error encountered during the execution: %1$s%n%2$s",
|
||||||
gaeResponse, new String(gaeResponse.getContent()));
|
gaeResponse, new String(gaeResponse.getContent()));
|
||||||
}
|
}
|
||||||
command.setException(e);
|
command.setException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String headersAsString(List<HTTPHeader> headers) {
|
String headersAsString(List<HTTPHeader> headers) {
|
||||||
StringBuilder builder = new StringBuilder("");
|
StringBuilder builder = new StringBuilder("");
|
||||||
for (HTTPHeader header : headers)
|
for (HTTPHeader header : headers)
|
||||||
builder.append("[").append(header.getName()).append("=").append(
|
builder.append("[").append(header.getName()).append("=").append(
|
||||||
header.getValue()).append("],");
|
header.getValue()).append("],");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,54 +104,54 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void changeRequestContentToBytes(HttpRequest request) throws IOException {
|
void changeRequestContentToBytes(HttpRequest request) throws IOException {
|
||||||
Object content = request.getPayload();
|
Object content = request.getPayload();
|
||||||
if (content == null || content instanceof byte[]) {
|
if (content == null || content instanceof byte[]) {
|
||||||
return;
|
return;
|
||||||
} else if (content instanceof String) {
|
} else if (content instanceof String) {
|
||||||
String string = (String) content;
|
String string = (String) content;
|
||||||
request.setPayload(string.getBytes());
|
request.setPayload(string.getBytes());
|
||||||
} else if (content instanceof InputStream || content instanceof File) {
|
} else if (content instanceof InputStream || content instanceof File) {
|
||||||
InputStream i = content instanceof InputStream ? (InputStream) content
|
InputStream i = content instanceof InputStream ? (InputStream) content
|
||||||
: new FileInputStream((File) content);
|
: new FileInputStream((File) content);
|
||||||
try {
|
try {
|
||||||
request.setPayload(IOUtils.toByteArray(i));
|
request.setPayload(IOUtils.toByteArray(i));
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(i);
|
IOUtils.closeQuietly(i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException("Content not supported "
|
throw new UnsupportedOperationException("Content not supported "
|
||||||
+ content.getClass());
|
+ content.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
HttpResponse convert(HTTPResponse gaeResponse) {
|
HttpResponse convert(HTTPResponse gaeResponse) {
|
||||||
HttpResponse response = new HttpResponse();
|
HttpResponse response = new HttpResponse();
|
||||||
response.setStatusCode(gaeResponse.getResponseCode());
|
response.setStatusCode(gaeResponse.getResponseCode());
|
||||||
for (HTTPHeader header : gaeResponse.getHeaders()) {
|
for (HTTPHeader header : gaeResponse.getHeaders()) {
|
||||||
response.getHeaders().put(header.getName(), header.getValue());
|
response.getHeaders().put(header.getName(), header.getValue());
|
||||||
}
|
}
|
||||||
if (gaeResponse.getContent() != null) {
|
if (gaeResponse.getContent() != null) {
|
||||||
response.setContent(new ByteArrayInputStream(gaeResponse
|
response.setContent(new ByteArrayInputStream(gaeResponse
|
||||||
.getContent()));
|
.getContent()));
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
HTTPRequest convert(HttpRequest request) throws IOException {
|
HTTPRequest convert(HttpRequest request) throws IOException {
|
||||||
URL url = new URL(target, request.getUri());
|
URL url = new URL(target, request.getUri());
|
||||||
HTTPRequest gaeRequest = new HTTPRequest(url, HTTPMethod
|
HTTPRequest gaeRequest = new HTTPRequest(url, HTTPMethod
|
||||||
.valueOf(request.getMethod()), disallowTruncate());
|
.valueOf(request.getMethod()), disallowTruncate());
|
||||||
for (String header : request.getHeaders().keySet()) {
|
for (String header : request.getHeaders().keySet()) {
|
||||||
for (String value : request.getHeaders().get(header))
|
for (String value : request.getHeaders().get(header))
|
||||||
gaeRequest.addHeader(new HTTPHeader(header, value));
|
gaeRequest.addHeader(new HTTPHeader(header, value));
|
||||||
}
|
}
|
||||||
if (request.getPayload() != null) {
|
if (request.getPayload() != null) {
|
||||||
changeRequestContentToBytes(request);
|
changeRequestContentToBytes(request);
|
||||||
gaeRequest.setPayload((byte[]) request.getPayload());
|
gaeRequest.setPayload((byte[]) request.getPayload());
|
||||||
}
|
}
|
||||||
return gaeRequest;
|
return gaeRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,22 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.http.httpnio.pool;
|
package org.jclouds.http.httpnio.pool;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
import org.apache.http.nio.NHttpConnection;
|
||||||
|
import org.jclouds.command.pool.FutureCommandConnectionPoolClient;
|
||||||
|
import org.jclouds.http.*;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.apache.http.nio.NHttpConnection;
|
|
||||||
import org.jclouds.command.pool.FutureCommandConnectionPoolClient;
|
|
||||||
import org.jclouds.http.HttpException;
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
|
||||||
import org.jclouds.http.HttpFutureCommandClient;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Singleton;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO: Adrian: Document this!
|
* // TODO: Adrian: Document this!
|
||||||
*
|
*
|
||||||
|
@ -46,41 +41,41 @@ import com.google.inject.Singleton;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class HttpNioConnectionPoolClient
|
public class HttpNioConnectionPoolClient
|
||||||
extends
|
extends
|
||||||
FutureCommandConnectionPoolClient<NHttpConnection, HttpFutureCommand<?>>
|
FutureCommandConnectionPoolClient<NHttpConnection, HttpFutureCommand<?>>
|
||||||
implements HttpFutureCommandClient {
|
implements HttpFutureCommandClient {
|
||||||
private List<HttpRequestFilter> requestFilters = Collections.emptyList();
|
private List<HttpRequestFilter> requestFilters = Collections.emptyList();
|
||||||
|
|
||||||
public List<HttpRequestFilter> getRequestFilters() {
|
public List<HttpRequestFilter> getRequestFilters() {
|
||||||
return requestFilters;
|
return requestFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
public void setRequestFilters(List<HttpRequestFilter> requestFilters) {
|
public void setRequestFilters(List<HttpRequestFilter> requestFilters) {
|
||||||
this.requestFilters = requestFilters;
|
this.requestFilters = requestFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void invoke(HttpFutureCommand<?> command) {
|
protected void invoke(HttpFutureCommand<?> command) {
|
||||||
HttpRequest request = (HttpRequest) command.getRequest();
|
HttpRequest request = (HttpRequest) command.getRequest();
|
||||||
try {
|
try {
|
||||||
for (HttpRequestFilter filter : getRequestFilters()) {
|
for (HttpRequestFilter filter : getRequestFilters()) {
|
||||||
filter.filter(request);
|
filter.filter(request);
|
||||||
}
|
}
|
||||||
super.invoke(command);
|
super.invoke(command);
|
||||||
} catch (HttpException e) {
|
} catch (HttpException e) {
|
||||||
command.setException(e);
|
command.setException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HttpNioConnectionPoolClient(
|
public HttpNioConnectionPoolClient(
|
||||||
ExecutorService executor,
|
ExecutorService executor,
|
||||||
HttpNioFutureCommandConnectionPool httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool,
|
HttpNioFutureCommandConnectionPool httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool,
|
||||||
BlockingQueue<HttpFutureCommand<?>> commandQueue) {
|
BlockingQueue<HttpFutureCommand<?>> commandQueue) {
|
||||||
super(
|
super(
|
||||||
executor,
|
executor,
|
||||||
httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool,
|
httpFutureCommandConnectionHandleNHttpConnectionNioFutureCommandConnectionPool,
|
||||||
commandQueue);
|
commandQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.http.httpnio.pool;
|
package org.jclouds.http.httpnio.pool;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.google.inject.Inject;
|
||||||
import java.net.InetSocketAddress;
|
import com.google.inject.name.Named;
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import org.apache.http.HttpException;
|
import org.apache.http.HttpException;
|
||||||
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||||
import org.apache.http.nio.NHttpConnection;
|
import org.apache.http.nio.NHttpConnection;
|
||||||
|
@ -46,8 +40,9 @@ import org.jclouds.command.pool.FutureCommandConnectionPool;
|
||||||
import org.jclouds.command.pool.PoolConstants;
|
import org.jclouds.command.pool.PoolConstants;
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
import org.jclouds.http.HttpFutureCommand;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import java.io.IOException;
|
||||||
import com.google.inject.name.Named;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection Pool for HTTP requests that utilizes Apache HTTPNio
|
* Connection Pool for HTTP requests that utilizes Apache HTTPNio
|
||||||
|
@ -55,8 +50,8 @@ import com.google.inject.name.Named;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class HttpNioFutureCommandConnectionPool extends
|
public class HttpNioFutureCommandConnectionPool extends
|
||||||
FutureCommandConnectionPool<NHttpConnection, HttpFutureCommand<?>>
|
FutureCommandConnectionPool<NHttpConnection, HttpFutureCommand<?>>
|
||||||
implements EventListener {
|
implements EventListener {
|
||||||
|
|
||||||
private final NHttpClientConnectionPoolSessionRequestCallback sessionCallback;
|
private final NHttpClientConnectionPoolSessionRequestCallback sessionCallback;
|
||||||
private final DefaultConnectingIOReactor ioReactor;
|
private final DefaultConnectingIOReactor ioReactor;
|
||||||
|
@ -66,227 +61,227 @@ public class HttpNioFutureCommandConnectionPool extends
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HttpNioFutureCommandConnectionPool(
|
public HttpNioFutureCommandConnectionPool(
|
||||||
ExecutorService executor,
|
ExecutorService executor,
|
||||||
Semaphore allConnections,
|
Semaphore allConnections,
|
||||||
BlockingQueue<HttpFutureCommand<?>> commandQueue,
|
BlockingQueue<HttpFutureCommand<?>> commandQueue,
|
||||||
BlockingQueue<NHttpConnection> available,
|
BlockingQueue<NHttpConnection> available,
|
||||||
AsyncNHttpClientHandler clientHandler,
|
AsyncNHttpClientHandler clientHandler,
|
||||||
DefaultConnectingIOReactor ioReactor,
|
DefaultConnectingIOReactor ioReactor,
|
||||||
IOEventDispatch dispatch,
|
IOEventDispatch dispatch,
|
||||||
FutureCommandConnectionHandleFactory requestHandleFactory,
|
FutureCommandConnectionHandleFactory requestHandleFactory,
|
||||||
InetSocketAddress target,
|
InetSocketAddress target,
|
||||||
@Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE) int maxConnectionReuse,
|
@Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE) int maxConnectionReuse,
|
||||||
@Named(PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES) int maxSessionFailures) {
|
@Named(PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES) int maxSessionFailures) {
|
||||||
super(executor, allConnections, commandQueue, requestHandleFactory,
|
super(executor, allConnections, commandQueue, requestHandleFactory,
|
||||||
maxConnectionReuse, available);
|
maxConnectionReuse, available);
|
||||||
this.ioReactor = ioReactor;
|
this.ioReactor = ioReactor;
|
||||||
this.dispatch = dispatch;
|
this.dispatch = dispatch;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.maxSessionFailures = maxSessionFailures;
|
this.maxSessionFailures = maxSessionFailures;
|
||||||
this.sessionCallback = new NHttpClientConnectionPoolSessionRequestCallback();
|
this.sessionCallback = new NHttpClientConnectionPoolSessionRequestCallback();
|
||||||
clientHandler.setEventListener(this);
|
clientHandler.setEventListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
synchronized (this.statusLock) {
|
synchronized (this.statusLock) {
|
||||||
if (this.status.compareTo(Status.INACTIVE) == 0) {
|
if (this.status.compareTo(Status.INACTIVE) == 0) {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
ioReactor.execute(dispatch);
|
ioReactor.execute(dispatch);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
exception.set(e);
|
exception.set(e);
|
||||||
logger.error(e, "Error dispatching %1$s", dispatch);
|
logger.error(e, "Error dispatching %1$s", dispatch);
|
||||||
status = Status.SHUTDOWN_REQUEST;
|
status = Status.SHUTDOWN_REQUEST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdownReactor(long waitMs) {
|
public void shutdownReactor(long waitMs) {
|
||||||
try {
|
try {
|
||||||
this.ioReactor.shutdown(waitMs);
|
this.ioReactor.shutdown(waitMs);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error(e, "Error shutting down reactor");
|
logger.error(e, "Error shutting down reactor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connectionValid(NHttpConnection conn) {
|
public boolean connectionValid(NHttpConnection conn) {
|
||||||
return conn.isOpen() && !conn.isStale()
|
return conn.isOpen() && !conn.isStale()
|
||||||
&& conn.getMetrics().getRequestCount() < maxConnectionReuse;
|
&& conn.getMetrics().getRequestCount() < maxConnectionReuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdownConnection(NHttpConnection conn) {
|
public void shutdownConnection(NHttpConnection conn) {
|
||||||
if (conn.getMetrics().getRequestCount() >= maxConnectionReuse)
|
if (conn.getMetrics().getRequestCount() >= maxConnectionReuse)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"%1$s - %2$d - closing connection due to overuse %1$s/%2$s",
|
"%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) {
|
||||||
try {
|
try {
|
||||||
conn.shutdown();
|
conn.shutdown();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error(e, "Error shutting down connection");
|
logger.error(e, "Error shutting down connection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doWork() throws Exception {
|
protected void doWork() throws Exception {
|
||||||
createNewConnection();
|
createNewConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doShutdown() {
|
protected void doShutdown() {
|
||||||
// Give the I/O reactor 1 sec to shut down
|
// Give the I/O reactor 1 sec to shut down
|
||||||
shutdownReactor(1000);
|
shutdownReactor(1000);
|
||||||
assert this.ioReactor.getStatus().equals(IOReactorStatus.SHUT_DOWN) : "incorrect status after io reactor shutdown :"
|
assert this.ioReactor.getStatus().equals(IOReactorStatus.SHUT_DOWN) : "incorrect status after io reactor shutdown :"
|
||||||
+ this.ioReactor.getStatus();
|
+ this.ioReactor.getStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createNewConnection() throws InterruptedException {
|
protected void createNewConnection() throws InterruptedException {
|
||||||
boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS);
|
boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS);
|
||||||
if (acquired) {
|
if (acquired) {
|
||||||
if (shouldDoWork()) {
|
if (shouldDoWork()) {
|
||||||
logger.debug("%1$s - opening new connection", 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void associateHandleWithConnection(
|
protected void associateHandleWithConnection(
|
||||||
FutureCommandConnectionHandle<NHttpConnection, HttpFutureCommand<?>> handle,
|
FutureCommandConnectionHandle<NHttpConnection, HttpFutureCommand<?>> handle,
|
||||||
NHttpConnection connection) {
|
NHttpConnection connection) {
|
||||||
connection.getContext().setAttribute("command-handle", handle);
|
connection.getContext().setAttribute("command-handle", handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HttpNioFutureCommandConnectionHandle getHandleFromConnection(
|
protected HttpNioFutureCommandConnectionHandle getHandleFromConnection(
|
||||||
NHttpConnection connection) {
|
NHttpConnection connection) {
|
||||||
return (HttpNioFutureCommandConnectionHandle) connection.getContext()
|
return (HttpNioFutureCommandConnectionHandle) connection.getContext()
|
||||||
.getAttribute("command-handle");
|
.getAttribute("command-handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
class NHttpClientConnectionPoolSessionRequestCallback implements
|
class NHttpClientConnectionPoolSessionRequestCallback implements
|
||||||
SessionRequestCallback {
|
SessionRequestCallback {
|
||||||
|
|
||||||
public void completed(SessionRequest request) {
|
public void completed(SessionRequest request) {
|
||||||
logger.trace("%1$s->%2$s[%3$s] - 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("%1$s->%2$s[%3$s] - 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void releaseConnectionAndCancelResponse(SessionRequest request) {
|
private void releaseConnectionAndCancelResponse(SessionRequest request) {
|
||||||
allConnections.release();
|
allConnections.release();
|
||||||
FutureCommand<?, ?, ?> frequest = (FutureCommand<?, ?, ?>) request
|
FutureCommand<?, ?, ?> frequest = (FutureCommand<?, ?, ?>) request
|
||||||
.getAttachment();
|
.getAttachment();
|
||||||
if (frequest != null) {
|
if (frequest != null) {
|
||||||
logger.error("%1$s->%2$s[%3$s] - 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void releaseConnectionAndSetResponseException(
|
private void releaseConnectionAndSetResponseException(
|
||||||
SessionRequest request, Exception e) {
|
SessionRequest request, Exception e) {
|
||||||
allConnections.release();
|
allConnections.release();
|
||||||
HttpFutureCommand<?> frequest = (HttpFutureCommand<?>) request
|
HttpFutureCommand<?> frequest = (HttpFutureCommand<?>) request
|
||||||
.getAttachment();
|
.getAttachment();
|
||||||
if (frequest != null) {
|
if (frequest != null) {
|
||||||
logger.error(e,
|
logger.error(e,
|
||||||
"%1$s->%2$s[%3$s] - 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void failed(SessionRequest request) {
|
public void failed(SessionRequest request) {
|
||||||
int count = currentSessionFailures.getAndIncrement();
|
int count = currentSessionFailures.getAndIncrement();
|
||||||
logger.warn("%1$s->%2$s[%3$s] - SessionRequest failed", request
|
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
|
||||||
.getException());
|
.getException());
|
||||||
if (count >= maxSessionFailures) {
|
if (count >= maxSessionFailures) {
|
||||||
logger
|
logger
|
||||||
.error(
|
.error(
|
||||||
request.getException(),
|
request.getException(),
|
||||||
"%1$s->%2$s[%3$s] - SessionRequest failures: %4$s, Disabling pool for %5$s",
|
"%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);
|
||||||
exception.set(request.getException());
|
exception.set(request.getException());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void timeout(SessionRequest request) {
|
public void timeout(SessionRequest request) {
|
||||||
logger.warn("%1$s->%2$s[%3$s] - SessionRequest timeout", request
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectionOpen(NHttpConnection conn) {
|
public void connectionOpen(NHttpConnection conn) {
|
||||||
conn.setSocketTimeout(0);
|
conn.setSocketTimeout(0);
|
||||||
available.offer(conn);
|
available.offer(conn);
|
||||||
logger.trace("%1$s - %2$d - open", conn, conn.hashCode());
|
logger.trace("%1$s - %2$d - open", conn, conn.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectionTimeout(NHttpConnection conn) {
|
public void connectionTimeout(NHttpConnection conn) {
|
||||||
String message = String.format("%1$s - %2$d - timeout %2$d", 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("%1$s - %2$d - 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, "%3$s-%1$d{%2$s} - 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, "%3$s-%1$d{%2$s} - 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface FutureCommandConnectionHandleFactory
|
public static interface FutureCommandConnectionHandleFactory
|
||||||
extends
|
extends
|
||||||
FutureCommandConnectionPool.FutureCommandConnectionHandleFactory<NHttpConnection, HttpFutureCommand<?>> {
|
FutureCommandConnectionPool.FutureCommandConnectionHandleFactory<NHttpConnection, HttpFutureCommand<?>> {
|
||||||
HttpNioFutureCommandConnectionHandle create(
|
HttpNioFutureCommandConnectionHandle create(
|
||||||
HttpFutureCommand<?> command, NHttpConnection conn);
|
HttpFutureCommand<?> command, NHttpConnection conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReplayable(HttpFutureCommand<?> command) {
|
protected boolean isReplayable(HttpFutureCommand<?> command) {
|
||||||
return command.getRequest().isReplayable();
|
return command.getRequest().isReplayable();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,12 +23,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.http.httpnio.pool;
|
package org.jclouds.http.httpnio.pool;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.google.inject.Inject;
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpEntityEnclosingRequest;
|
import org.apache.http.HttpEntityEnclosingRequest;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
|
@ -45,7 +40,10 @@ import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
||||||
import org.jclouds.http.httpnio.util.HttpNioUtils;
|
import org.jclouds.http.httpnio.util.HttpNioUtils;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import javax.annotation.Resource;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO: Adrian: Document this!
|
* // TODO: Adrian: Document this!
|
||||||
|
@ -53,7 +51,7 @@ import com.google.inject.Inject;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class HttpNioFutureCommandExecutionHandler implements
|
public class HttpNioFutureCommandExecutionHandler implements
|
||||||
NHttpRequestExecutionHandler {
|
NHttpRequestExecutionHandler {
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
@ -73,105 +71,105 @@ public class HttpNioFutureCommandExecutionHandler implements
|
||||||
private HttpResponseHandler serverErrorHandler = new CloseContentAndSetExceptionHandler();
|
private HttpResponseHandler serverErrorHandler = new CloseContentAndSetExceptionHandler();
|
||||||
|
|
||||||
public interface ConsumingNHttpEntityFactory {
|
public interface ConsumingNHttpEntityFactory {
|
||||||
public ConsumingNHttpEntity create(HttpEntity httpEntity);
|
public ConsumingNHttpEntity create(HttpEntity httpEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HttpNioFutureCommandExecutionHandler(
|
public HttpNioFutureCommandExecutionHandler(
|
||||||
ConsumingNHttpEntityFactory entityFactory,
|
ConsumingNHttpEntityFactory entityFactory,
|
||||||
ExecutorService executor,
|
ExecutorService executor,
|
||||||
BlockingQueue<HttpFutureCommand<?>> commandQueue) {
|
BlockingQueue<HttpFutureCommand<?>> commandQueue) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.entityFactory = entityFactory;
|
this.entityFactory = entityFactory;
|
||||||
this.commandQueue = commandQueue;
|
this.commandQueue = commandQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initalizeContext(HttpContext context, Object attachment) {
|
public void initalizeContext(HttpContext context, Object attachment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpEntityEnclosingRequest submitRequest(HttpContext context) {
|
public HttpEntityEnclosingRequest submitRequest(HttpContext context) {
|
||||||
HttpFutureCommand<?> command = (HttpFutureCommand<?>) context
|
HttpFutureCommand<?> command = (HttpFutureCommand<?>) context
|
||||||
.removeAttribute("command");
|
.removeAttribute("command");
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
HttpRequest object = command.getRequest();
|
HttpRequest object = command.getRequest();
|
||||||
return HttpNioUtils.convertToApacheRequest(object);
|
return HttpNioUtils.convertToApacheRequest(object);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsumingNHttpEntity responseEntity(HttpResponse response,
|
public ConsumingNHttpEntity responseEntity(HttpResponse response,
|
||||||
HttpContext context) throws IOException {
|
HttpContext context) throws IOException {
|
||||||
return entityFactory.create(response.getEntity());
|
return entityFactory.create(response.getEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleResponse(HttpResponse apacheResponse, HttpContext context)
|
public void handleResponse(HttpResponse apacheResponse, HttpContext context)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context
|
HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context
|
||||||
.removeAttribute("command-handle");
|
.removeAttribute("command-handle");
|
||||||
if (handle != null) {
|
if (handle != null) {
|
||||||
try {
|
try {
|
||||||
HttpFutureCommand<?> command = handle.getCommand();
|
HttpFutureCommand<?> command = handle.getCommand();
|
||||||
org.jclouds.http.HttpResponse response = HttpNioUtils
|
org.jclouds.http.HttpResponse response = HttpNioUtils
|
||||||
.convertToJavaCloudsResponse(apacheResponse);
|
.convertToJavaCloudsResponse(apacheResponse);
|
||||||
|
|
||||||
int code = response.getStatusCode();
|
int code = response.getStatusCode();
|
||||||
if (code >= 500) {
|
if (code >= 500) {
|
||||||
if (isRetryable(command)) {
|
if (isRetryable(command)) {
|
||||||
commandQueue.add(command);
|
commandQueue.add(command);
|
||||||
} else {
|
} else {
|
||||||
this.serverErrorHandler.handle(command, response);
|
this.serverErrorHandler.handle(command, response);
|
||||||
}
|
}
|
||||||
} else if (code >= 400 && code < 500) {
|
} else if (code >= 400 && code < 500) {
|
||||||
this.clientErrorHandler.handle(command, response);
|
this.clientErrorHandler.handle(command, response);
|
||||||
} else if (code >= 300 && code < 400) {
|
} else if (code >= 300 && code < 400) {
|
||||||
this.redirectHandler.handle(command, response);
|
this.redirectHandler.handle(command, response);
|
||||||
} else {
|
} else {
|
||||||
processResponse(response, command);
|
processResponse(response, command);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
releaseConnectionToPool(handle);
|
releaseConnectionToPool(handle);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(String.format(
|
throw new IllegalStateException(String.format(
|
||||||
"No command-handle associated with command %1$s", 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: %1$s", command);
|
logger.debug("resubmitting command: %1$s", command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void releaseConnectionToPool(
|
protected void releaseConnectionToPool(
|
||||||
HttpNioFutureCommandConnectionHandle handle) {
|
HttpNioFutureCommandConnectionHandle handle) {
|
||||||
try {
|
try {
|
||||||
handle.release();
|
handle.release();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.error(e, "Interrupted releasing handle %1$s", 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 %1$s", command
|
logger.trace("submitting response task %1$s", command
|
||||||
.getResponseFuture());
|
.getResponseFuture());
|
||||||
executor.submit(command.getResponseFuture());
|
executor.submit(command.getResponseFuture());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finalizeContext(HttpContext context) {
|
public void finalizeContext(HttpContext context) {
|
||||||
HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context
|
HttpNioFutureCommandConnectionHandle handle = (HttpNioFutureCommandConnectionHandle) context
|
||||||
.removeAttribute("command-handle");
|
.removeAttribute("command-handle");
|
||||||
if (handle != null) {
|
if (handle != null) {
|
||||||
try {
|
try {
|
||||||
handle.cancel();
|
handle.cancel();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e, "Error cancelling handle %1$s", handle);
|
logger.error(e, "Error cancelling handle %1$s", handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,8 +55,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.java.dev.jets3t</groupId>
|
<groupId>net.java.dev.jets3t</groupId>
|
||||||
<artifactId>jets3t</artifactId>
|
<artifactId>jets3t</artifactId>
|
||||||
<version>0.7.0</version>
|
<version>0.7.1</version>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
|
1
pom.xml
1
pom.xml
|
@ -51,6 +51,7 @@
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<quiet>true</quiet>
|
||||||
<links>
|
<links>
|
||||||
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
|
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
|
||||||
<link>http://java.sun.com/javaee/5/docs/api/</link>
|
<link>http://java.sun.com/javaee/5/docs/api/</link>
|
||||||
|
|
|
@ -182,6 +182,7 @@
|
||||||
<goal>jar</goal>
|
<goal>jar</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<quiet>true</quiet>
|
||||||
<links>
|
<links>
|
||||||
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
|
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
|
||||||
<link>http://java.sun.com/javaee/5/docs/api/</link>
|
<link>http://java.sun.com/javaee/5/docs/api/</link>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
<metadata xsi:schemaLocation="http://maven.apache.org/METADATA/1.0.0 http://maven.apache.org/xsd/metadata-1.0.0.xsd" xmlns="http://maven.apache.org/METADATA/1.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
|
|
@ -80,8 +80,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.java.dev.jets3t</groupId>
|
<groupId>net.java.dev.jets3t</groupId>
|
||||||
<artifactId>jets3t</artifactId>
|
<artifactId>jets3t</artifactId>
|
||||||
<version>0.7.0</version>
|
<version>0.7.1</version>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
113
s3/pom.xml
113
s3/pom.xml
|
@ -49,6 +49,9 @@
|
||||||
<properties>
|
<properties>
|
||||||
<jclouds.aws.accesskeyid></jclouds.aws.accesskeyid>
|
<jclouds.aws.accesskeyid></jclouds.aws.accesskeyid>
|
||||||
<jclouds.aws.secretaccesskey></jclouds.aws.secretaccesskey>
|
<jclouds.aws.secretaccesskey></jclouds.aws.secretaccesskey>
|
||||||
|
<jclouds.s3.httpstream.url>http://apache.rediris.es/maven/binaries/apache-maven-2.1.0-bin.tar.bz2
|
||||||
|
</jclouds.s3.httpstream.url>
|
||||||
|
<jclouds.s3.httpstream.md5>9268c9de2cccfd0d8fbcdbcfaf517a87</jclouds.s3.httpstream.md5>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -67,25 +70,115 @@
|
||||||
<artifactId>bcprov-jdk15</artifactId>
|
<artifactId>bcprov-jdk15</artifactId>
|
||||||
<version>140</version>
|
<version>140</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>xstream</groupId>
|
||||||
|
<artifactId>xstream</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<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>
|
||||||
|
<!-- note that the groups/excluded groups don't work due to some problem
|
||||||
|
in surefire or testng. instead, we have to exclude via file path
|
||||||
|
<groups>integration</groups>
|
||||||
|
<excludedGroups>unit,performance,live</excludedGroups> -->
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*IntegrationTest.java</include>
|
||||||
|
</includes>
|
||||||
|
<systemProperties>
|
||||||
|
<property>
|
||||||
|
<name>jclouds.s3.httpstream.url</name>
|
||||||
|
<value>${jclouds.s3.httpstream.url}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>jclouds.s3.httpstream.md5</name>
|
||||||
|
<value>${jclouds.s3.httpstream.md5}</value>
|
||||||
|
</property>
|
||||||
|
</systemProperties>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemProperties>
|
<!-- note that the groups/excluded groups don't work due to some problem
|
||||||
<property>
|
in surefire or testng. instead, we have to exclude via file path
|
||||||
<name>jclouds.aws.accesskeyid</name>
|
<groups>unit,performance</groups>
|
||||||
<value>${jclouds.aws.accesskeyid}</value>
|
<excludedGroups>integration,live</excludedGroups> -->
|
||||||
</property>
|
<excludes>
|
||||||
<property>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
<name>jclouds.aws.secretaccesskey</name>
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
<value>${jclouds.aws.secretaccesskey}</value>
|
</excludes>
|
||||||
</property>
|
|
||||||
</systemProperties>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>live</id>
|
||||||
|
<build>
|
||||||
|
<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>
|
||||||
|
<!-- note that the groups/excluded groups don't work due to some problem
|
||||||
|
in surefire or testng. instead, we have to exclude via file path
|
||||||
|
<groups>live,integration</groups>
|
||||||
|
<excludedGroups>unit,performance</excludedGroups> -->
|
||||||
|
<excludes>
|
||||||
|
<exclude>none</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*IntegrationTest.java</include>
|
||||||
|
<include>**/*LiveTest.java</include>
|
||||||
|
</includes>
|
||||||
|
<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>jclouds.s3.httpstream.url</name>
|
||||||
|
<value>${jclouds.s3.httpstream.url}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>jclouds.s3.httpstream.md5</name>
|
||||||
|
<value>${jclouds.s3.httpstream.md5}</value>
|
||||||
|
</property>
|
||||||
|
</systemProperties>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -23,42 +23,34 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.commands.options.*;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to S3 via their REST API.
|
* Provides access to S3 via their REST API.
|
||||||
*
|
* <p/>
|
||||||
* All commands return a Future of the result from S3. Any exceptions incurred
|
* All commands return a Future of the result from S3. Any exceptions incurred
|
||||||
* 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 <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
|
||||||
*/
|
*/
|
||||||
public interface S3Connection {
|
public interface S3Connection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a complete <code>S3Object</code>.
|
* Retrieve a complete <code>S3Object</code>.
|
||||||
*
|
*
|
||||||
* @see GetObject
|
* @param bucketName namespace of the object you are retrieving
|
||||||
* @param bucketName
|
* @param key unique key in the s3Bucket identifying the object
|
||||||
* namespace of the object you are retrieving
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* unique key in the s3Bucket identifying the object
|
|
||||||
* @return Future reference to a fully populated S3Object including data
|
* @return Future reference to a fully populated S3Object including data
|
||||||
* stored in S3 or {@link S3Object#NOT_FOUND} if not present.
|
* stored in S3 or {@link S3Object#NOT_FOUND} if not present.
|
||||||
|
* @see org.jclouds.aws.s3.commands.GetObject
|
||||||
*/
|
*/
|
||||||
Future<S3Object> getObject(String bucketName, String key);
|
Future<S3Object> getObject(String bucketName, String key);
|
||||||
|
|
||||||
|
@ -66,44 +58,38 @@ public interface S3Connection {
|
||||||
* Like {@link #getObject(String, String)} except you can use
|
* Like {@link #getObject(String, String)} except you can use
|
||||||
* {@link GetObjectOptions} to control delivery.
|
* {@link GetObjectOptions} to control delivery.
|
||||||
*
|
*
|
||||||
* @see #getObject(String, String)
|
|
||||||
* @see GetObjectOptions
|
|
||||||
* @return S3Object containing data relevant to the
|
* @return S3Object containing data relevant to the
|
||||||
* <code>options</options> specified or {@link S3Object#NOT_FOUND} if not present.
|
* <code>options</options> specified or {@link S3Object#NOT_FOUND} if not present.
|
||||||
*
|
* @throws org.jclouds.http.HttpResponseException
|
||||||
* @throws HttpResponseException
|
* if the conditions requested set were not satisfied by the
|
||||||
* if the conditions requested set were not satisfied by the
|
* object on the server.
|
||||||
* object on the server.
|
* @see #getObject(String, String)
|
||||||
|
* @see GetObjectOptions
|
||||||
*/
|
*/
|
||||||
Future<S3Object> getObject(String bucketName, String key,
|
Future<S3Object> getObject(String bucketName, String key,
|
||||||
GetObjectOptions options);
|
GetObjectOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@link S3Object.Metadata metadata} of the object associated
|
* Retrieves the {@link org.jclouds.aws.s3.domain.S3Object.Metadata metadata} of the object associated
|
||||||
* with the key.
|
* with the key.
|
||||||
*
|
*
|
||||||
* @see HeadObject
|
* @param bucketName namespace of the metadata you are retrieving
|
||||||
* @param bucketName
|
* @param key unique key in the s3Bucket identifying the object
|
||||||
* namespace of the metadata you are retrieving
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* unique key in the s3Bucket identifying the object
|
|
||||||
* @return metadata associated with the key or
|
* @return metadata associated with the key or
|
||||||
* {@link S3Object.Metadata#NOT_FOUND} if not present;
|
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata#NOT_FOUND} if not present;
|
||||||
|
* @see org.jclouds.aws.s3.commands.HeadObject
|
||||||
*/
|
*/
|
||||||
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 namespace of the object you are deleting
|
||||||
* @param bucketName
|
* @param key unique key in the s3Bucket identifying the object
|
||||||
* namespace of the object you are deleting
|
|
||||||
* @param key
|
|
||||||
* unique key in the s3Bucket identifying the object
|
|
||||||
* @return true if deleted
|
* @return true if deleted
|
||||||
* @throws HttpResponseException
|
* @throws org.jclouds.http.HttpResponseException
|
||||||
* if the bucket is not available
|
* if the bucket is not available
|
||||||
|
* @see org.jclouds.aws.s3.commands.DeleteObject
|
||||||
*/
|
*/
|
||||||
Future<Boolean> deleteObject(String bucketName, String key);
|
Future<Boolean> deleteObject(String bucketName, String key);
|
||||||
|
|
||||||
|
@ -113,39 +99,36 @@ public interface S3Connection {
|
||||||
* This method will store the object with the default <code>private</code>
|
* This method will store the object with the default <code>private</code>
|
||||||
* acl.
|
* acl.
|
||||||
*
|
*
|
||||||
* @see CannedAccessPolicy#PRIVATE
|
* @param bucketName namespace of the object you are storing
|
||||||
* @see PutObject
|
* @param object contains the data and metadata to create or overwrite
|
||||||
* @param bucketName
|
|
||||||
* namespace of the object you are storing
|
|
||||||
* @param object
|
|
||||||
* contains the data and metadata to create or overwrite
|
|
||||||
* @return MD5 hash of the content uploaded
|
* @return MD5 hash of the content uploaded
|
||||||
|
* @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy#PRIVATE
|
||||||
|
* @see org.jclouds.aws.s3.commands.PutObject
|
||||||
*/
|
*/
|
||||||
Future<byte[]> putObject(String bucketName, S3Object object);
|
Future<byte[]> putObject(String bucketName, S3Object object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like {@link #putObject(String, S3Object)} except you can use
|
* Like {@link #putObject(String, S3Object)} except you can use
|
||||||
* {@link CopyObjectOptions} to specify an alternate
|
* {@link CopyObjectOptions} to specify an alternate
|
||||||
* {@link CannedAccessPolicy acl}, override
|
* {@link org.jclouds.aws.s3.domain.acl.CannedAccessPolicy acl}, override
|
||||||
* {@link S3Object.Metadata#getUserMetadata() userMetadata}, or specify
|
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata#getUserMetadata() userMetadata}, or specify
|
||||||
* conditions for copying the object.
|
* conditions for copying the object.
|
||||||
*
|
*
|
||||||
|
* @param options options for creating the object
|
||||||
|
* @throws org.jclouds.http.HttpResponseException
|
||||||
|
* if the conditions requested set are not satisfied by the
|
||||||
|
* object on the server.
|
||||||
* @see S3Connection#putObject(String, S3Object)
|
* @see S3Connection#putObject(String, S3Object)
|
||||||
* @see PutObjectOptions
|
* @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<byte[]> putObject(String bucketName, S3Object object,
|
Future<byte[]> putObject(String bucketName, S3Object object,
|
||||||
PutObjectOptions options);
|
PutObjectOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and name your own bucket in which to store your objects.
|
* Create and name your own bucket in which to store your objects.
|
||||||
*
|
*
|
||||||
* @see PutBucket
|
|
||||||
* @return true, if the bucket was created or already exists
|
* @return true, if the bucket was created or already exists
|
||||||
|
* @see org.jclouds.aws.s3.commands.PutBucket
|
||||||
*/
|
*/
|
||||||
Future<Boolean> putBucketIfNotExists(String name);
|
Future<Boolean> putBucketIfNotExists(String name);
|
||||||
|
|
||||||
|
@ -153,19 +136,17 @@ public interface S3Connection {
|
||||||
* Like {@link #putBucketIfNotExists(String)} except that you can use
|
* Like {@link #putBucketIfNotExists(String)} except that you can use
|
||||||
* {@link PutBucketOptions} to create the bucket in EU. Create and name your
|
* {@link PutBucketOptions} to create the bucket in EU. Create and name your
|
||||||
*
|
*
|
||||||
|
* @param options for creating your bucket
|
||||||
* @see PutBucketOptions
|
* @see PutBucketOptions
|
||||||
* @param options
|
|
||||||
* for creating your bucket
|
|
||||||
*/
|
*/
|
||||||
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 what to delete
|
||||||
* @param s3Bucket
|
|
||||||
* 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
|
||||||
|
* @see org.jclouds.aws.s3.commands.DeleteBucket
|
||||||
*/
|
*/
|
||||||
Future<Boolean> deleteBucketIfEmpty(String s3Bucket);
|
Future<Boolean> deleteBucketIfEmpty(String s3Bucket);
|
||||||
|
|
||||||
|
@ -173,65 +154,61 @@ public interface S3Connection {
|
||||||
* Copies one object to another bucket, retaining UserMetadata from the
|
* Copies one object to another bucket, retaining UserMetadata from the
|
||||||
* source. The destination will have a private acl.
|
* source. The destination will have a private acl.
|
||||||
*
|
*
|
||||||
* @see CopyObject
|
|
||||||
* @return metadata populated with lastModified and md5 of the new object
|
* @return metadata populated with lastModified and md5 of the new object
|
||||||
|
* @see org.jclouds.aws.s3.commands.CopyObject
|
||||||
*/
|
*/
|
||||||
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
||||||
String sourceObject, String destinationBucket,
|
String sourceObject, String destinationBucket,
|
||||||
String destinationObject);
|
String destinationObject);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like {@link #putObject(String, S3Object)} except you can use
|
* Like {@link #putObject(String, S3Object)} except you can use
|
||||||
* {@link PutObjectOptions} to specify an alternate
|
* {@link PutObjectOptions} to specify an alternate
|
||||||
* {@link CannedAccessPolicy acl}.
|
* {@link org.jclouds.aws.s3.domain.acl.CannedAccessPolicy acl}.
|
||||||
*
|
*
|
||||||
|
* @param options options for creating the object
|
||||||
|
* @throws org.jclouds.http.HttpResponseException
|
||||||
|
* if the conditions requested set are not satisfied by the
|
||||||
|
* object on the server.
|
||||||
* @see S3Connection#putObject(String, S3Object)
|
* @see S3Connection#putObject(String, S3Object)
|
||||||
* @see PutObjectOptions
|
* @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
|
* @see org.jclouds.aws.s3.commands.BucketExists
|
||||||
*/
|
*/
|
||||||
Future<Boolean> bucketExists(String name);
|
Future<Boolean> bucketExists(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a complete <code>S3Bucket</code> listing.
|
* Retrieve a complete <code>S3Bucket</code> listing.
|
||||||
*
|
*
|
||||||
* @see ListBucket
|
* @param bucketName namespace of the objects you wish to list
|
||||||
* @param bucketName
|
|
||||||
* namespace of the objects you wish to list
|
|
||||||
*
|
|
||||||
* @return Future reference to a fully populated S3Bucket including metadata
|
* @return Future reference to a fully populated S3Bucket including metadata
|
||||||
* of the S3Objects it contains or {@link S3Bucket#NOT_FOUND} if not
|
* of the S3Objects it contains or {@link S3Bucket#NOT_FOUND} if not
|
||||||
* present.
|
* present.
|
||||||
|
* @see org.jclouds.aws.s3.commands.ListBucket
|
||||||
*/
|
*/
|
||||||
Future<S3Bucket> listBucket(String bucketName);
|
Future<S3Bucket> listBucket(String bucketName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like {@link #listBucket(String)} except you can use
|
* Like {@link #listBucket(String)} except you can use
|
||||||
* {@link ListObjectOptions} to control the amount of S3Objects to return.
|
* {@link ListBucketOptions} to control the amount of S3Objects to return.
|
||||||
*
|
*
|
||||||
* @see #listBucket(String)
|
* @return S3Bucket containing a subset of {@link org.jclouds.aws.s3.domain.S3Object.Metadata}
|
||||||
* @see ListBucketOptions
|
|
||||||
* @return S3Bucket containing a subset of {@link S3Object.Metadata}
|
|
||||||
* depending on
|
* depending on
|
||||||
* <code>options</options> specified or {@link S3Bucket#NOT_FOUND} if not present.
|
* <code>options</options> specified or {@link S3Bucket#NOT_FOUND} if not present.
|
||||||
*
|
* @see #listBucket(String)
|
||||||
|
* @see ListBucketOptions
|
||||||
*/
|
*/
|
||||||
Future<S3Bucket> listBucket(String name, ListBucketOptions options);
|
Future<S3Bucket> listBucket(String name, ListBucketOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ListOwnedBuckets
|
|
||||||
* @return list of all of the buckets owned by the authenticated sender of
|
* @return list of all of the buckets owned by the authenticated sender of
|
||||||
* the request.
|
* the request.
|
||||||
|
* @see org.jclouds.aws.s3.commands.ListOwnedBuckets
|
||||||
*/
|
*/
|
||||||
Future<List<S3Bucket.Metadata>> listOwnedBuckets();
|
Future<List<S3Bucket.Metadata>> listOwnedBuckets();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ public interface S3Context {
|
||||||
* bucket.
|
* bucket.
|
||||||
*
|
*
|
||||||
* @param bucket
|
* @param bucket
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
S3InputStreamMap createInputStreamMap(String bucket);
|
S3InputStreamMap createInputStreamMap(String bucket);
|
||||||
|
|
||||||
|
@ -58,7 +57,6 @@ public interface S3Context {
|
||||||
* Creates a <code>Map<String,S3Object></code> view of the specified bucket.
|
* Creates a <code>Map<String,S3Object></code> view of the specified bucket.
|
||||||
*
|
*
|
||||||
* @param bucket
|
* @param bucket
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
S3ObjectMap createS3ObjectMap(String bucket);
|
S3ObjectMap createS3ObjectMap(String bucket);
|
||||||
|
|
||||||
|
|
|
@ -23,28 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_ACCESSKEYID;
|
|
||||||
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_MAX_CONNECTIONS;
|
|
||||||
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
|
|
||||||
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
|
|
||||||
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
|
|
||||||
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
|
|
||||||
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_PORT;
|
|
||||||
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
|
||||||
import org.jclouds.http.config.HttpFutureCommandClientModule;
|
|
||||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
|
||||||
import org.jclouds.logging.config.LoggingModule;
|
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -54,6 +34,21 @@ import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.name.Names;
|
import com.google.inject.name.Names;
|
||||||
|
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
|
||||||
|
import org.jclouds.aws.s3.config.S3ConnectionModule;
|
||||||
|
import org.jclouds.aws.s3.config.S3ContextModule;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_ACCESSKEYID;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||||
|
import org.jclouds.aws.s3.internal.LiveS3Connection;
|
||||||
|
import static org.jclouds.command.pool.PoolConstants.*;
|
||||||
|
import static org.jclouds.http.HttpConstants.*;
|
||||||
|
import org.jclouds.http.config.HttpFutureCommandClientModule;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||||
|
import org.jclouds.logging.config.LoggingModule;
|
||||||
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link S3Context} or {@link Injector} instances based on the most
|
* Creates {@link S3Context} or {@link Injector} instances based on the most
|
||||||
|
@ -61,115 +56,115 @@ import com.google.inject.name.Names;
|
||||||
* <p/>
|
* <p/>
|
||||||
* Note that Threadsafe objects will be bound as singletons to the Injector or
|
* Note that Threadsafe objects will be bound as singletons to the Injector or
|
||||||
* Context provided.
|
* Context provided.
|
||||||
*
|
* <p/>
|
||||||
* <p/>
|
* <p/>
|
||||||
* If no <code>Module</code>s are specified, the default
|
* If no <code>Module</code>s are specified, the default
|
||||||
* {@link JDKLoggingModule logging} and
|
* {@link JDKLoggingModule logging} and
|
||||||
* {@link JavaUrlHttpFutureCommandClientModule http transports} will be
|
* {@link JavaUrlHttpFutureCommandClientModule http transports} will be
|
||||||
* installed.
|
* installed.
|
||||||
*
|
*
|
||||||
* @see S3Context
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
* @see S3Context
|
||||||
*/
|
*/
|
||||||
public class S3ContextFactory {
|
public class S3ContextFactory {
|
||||||
|
|
||||||
public static final Properties DEFAULT_PROPERTIES;
|
public static final Properties DEFAULT_PROPERTIES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DEFAULT_PROPERTIES = new Properties();
|
DEFAULT_PROPERTIES = new Properties();
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_ADDRESS,
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_ADDRESS,
|
||||||
"s3.amazonaws.com");
|
"s3.amazonaws.com");
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_PORT, "443");
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_PORT, "443");
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_SECURE, "true");
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_SECURE, "true");
|
||||||
DEFAULT_PROPERTIES
|
DEFAULT_PROPERTIES
|
||||||
.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
|
.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS,
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS,
|
||||||
"1");
|
"1");
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, "2");
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, "2");
|
||||||
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, "12");
|
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, "12");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Injector createInjector(String awsAccessKeyId,
|
public static Injector createInjector(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, Module... modules) {
|
String awsSecretAccessKey, Module... modules) {
|
||||||
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
||||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
||||||
return createInjector(properties, modules);
|
return createInjector(properties, modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S3Context createS3Context(String awsAccessKeyId,
|
public static S3Context createS3Context(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, Module... modules) {
|
String awsSecretAccessKey, Module... modules) {
|
||||||
return createInjector(awsAccessKeyId, awsSecretAccessKey, modules)
|
return createInjector(awsAccessKeyId, awsSecretAccessKey, modules)
|
||||||
.getInstance(S3Context.class);
|
.getInstance(S3Context.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Injector createInjector(String awsAccessKeyId,
|
public static Injector createInjector(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, boolean isSecure, Module... modules) {
|
String awsSecretAccessKey, boolean isSecure, Module... modules) {
|
||||||
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
||||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
|
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
|
||||||
if (!isSecure)
|
if (!isSecure)
|
||||||
properties.setProperty(PROPERTY_HTTP_PORT, "80");
|
properties.setProperty(PROPERTY_HTTP_PORT, "80");
|
||||||
return createInjector(properties, modules);
|
return createInjector(properties, modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S3Context createS3Context(String awsAccessKeyId,
|
public static S3Context createS3Context(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, boolean isSecure, Module... modules) {
|
String awsSecretAccessKey, boolean isSecure, Module... modules) {
|
||||||
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
|
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
|
||||||
modules).getInstance(S3Context.class);
|
modules).getInstance(S3Context.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Injector createInjector(String awsAccessKeyId,
|
public static Injector createInjector(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, boolean isSecure, String server,
|
String awsSecretAccessKey, boolean isSecure, String server,
|
||||||
Module... modules) {
|
Module... modules) {
|
||||||
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
||||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
|
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
|
||||||
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
|
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
|
||||||
if (!isSecure)
|
if (!isSecure)
|
||||||
properties.setProperty(PROPERTY_HTTP_PORT, "80");
|
properties.setProperty(PROPERTY_HTTP_PORT, "80");
|
||||||
return createInjector(properties, modules);
|
return createInjector(properties, modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S3Context createS3Context(String awsAccessKeyId,
|
public static S3Context createS3Context(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, boolean isSecure, String server,
|
String awsSecretAccessKey, boolean isSecure, String server,
|
||||||
Module... modules) {
|
Module... modules) {
|
||||||
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
|
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
|
||||||
server, modules).getInstance(S3Context.class);
|
server, modules).getInstance(S3Context.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S3Context createS3Context(String awsAccessKeyId,
|
public static S3Context createS3Context(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, boolean isSecure, String server,
|
String awsSecretAccessKey, boolean isSecure, String server,
|
||||||
int port, Module... modules) {
|
int port, Module... modules) {
|
||||||
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
|
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
|
||||||
server, port, modules).getInstance(S3Context.class);
|
server, port, modules).getInstance(S3Context.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Injector createInjector(String awsAccessKeyId,
|
public static Injector createInjector(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, boolean isSecure, String server,
|
String awsSecretAccessKey, boolean isSecure, String server,
|
||||||
int port, Module... modules) {
|
int port, Module... modules) {
|
||||||
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
Properties properties = new Properties(DEFAULT_PROPERTIES);
|
||||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
|
||||||
properties
|
properties
|
||||||
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
|
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
|
||||||
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
|
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
|
||||||
properties.setProperty(PROPERTY_HTTP_PORT, port + "");
|
properties.setProperty(PROPERTY_HTTP_PORT, port + "");
|
||||||
return createInjector(properties, modules);
|
return createInjector(properties, modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S3Context createS3Context(Properties properties,
|
public static S3Context createS3Context(Properties properties,
|
||||||
Module... modules) {
|
Module... modules) {
|
||||||
return createInjector(properties, modules).getInstance(S3Context.class);
|
return createInjector(properties, modules).getInstance(S3Context.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,46 +172,65 @@ public class S3ContextFactory {
|
||||||
* are specified, install the default {@link JDKLoggingModule}
|
* are specified, install the default {@link JDKLoggingModule}
|
||||||
* {@link JavaUrlHttpFutureCommandClientModule}
|
* {@link JavaUrlHttpFutureCommandClientModule}
|
||||||
*
|
*
|
||||||
* @param properties
|
* @param properties - contains constants used by jclouds
|
||||||
* - contains constants used by jclouds
|
* {@link #DEFAULT_PROPERTIES}
|
||||||
* {@link #DEFAULT_PROPERTIES}
|
* @param configModules - alternative configuration modules
|
||||||
* @param configModules
|
|
||||||
* - alternative configuration modules
|
|
||||||
*/
|
*/
|
||||||
public static Injector createInjector(final Properties properties,
|
public static Injector createInjector(final Properties properties,
|
||||||
Module... configModules) {
|
Module... configModules) {
|
||||||
final List<Module> modules = Lists.newArrayList(configModules);
|
final List<Module> modules = Lists.newArrayList(configModules);
|
||||||
|
|
||||||
addLoggingModuleIfNotPresent(modules);
|
addLoggingModuleIfNotPresent(modules);
|
||||||
|
|
||||||
addHttpModuleIfNotPresent(modules);
|
addHttpModuleIfNeededAndNotPresent(modules);
|
||||||
|
|
||||||
return Guice.createInjector(new AbstractModule() {
|
addS3ConnectionModuleIfNotPresent(modules);
|
||||||
@Override
|
|
||||||
protected void configure() {
|
return Guice.createInjector(new AbstractModule() {
|
||||||
Names.bindProperties(binder(), checkNotNull(properties,
|
@Override
|
||||||
"properties"));
|
protected void configure() {
|
||||||
for (Module module : modules)
|
Names.bindProperties(binder(), checkNotNull(properties,
|
||||||
install(module);
|
"properties"));
|
||||||
}
|
for (Module module : modules)
|
||||||
}, new S3ContextModule());
|
install(module);
|
||||||
|
}
|
||||||
|
}, new S3ContextModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static void addHttpModuleIfNotPresent(final List<Module> modules) {
|
static void addHttpModuleIfNeededAndNotPresent(final List<Module> modules) {
|
||||||
if (!Iterables.any(modules, new Predicate<Module>() {
|
if (Iterables.any(modules, new Predicate<Module>() {
|
||||||
public boolean apply(Module input) {
|
public boolean apply(Module input) {
|
||||||
return input.getClass().isAnnotationPresent(
|
return input instanceof LiveS3ConnectionModule;
|
||||||
HttpFutureCommandClientModule.class);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}))
|
}) && (!Iterables.any(modules, new Predicate<Module>() {
|
||||||
modules.add(new JavaUrlHttpFutureCommandClientModule());
|
public boolean apply(Module input) {
|
||||||
|
return input.getClass().isAnnotationPresent(
|
||||||
|
HttpFutureCommandClientModule.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
})))
|
||||||
|
modules.add(new JavaUrlHttpFutureCommandClientModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static void addS3ConnectionModuleIfNotPresent(final List<Module> modules) {
|
||||||
|
if (!Iterables.any(modules, new Predicate<Module>() {
|
||||||
|
public boolean apply(Module input) {
|
||||||
|
return input.getClass().isAnnotationPresent(
|
||||||
|
S3ConnectionModule
|
||||||
|
.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
})){
|
||||||
|
modules.add(new LiveS3ConnectionModule());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static void addLoggingModuleIfNotPresent(final List<Module> modules) {
|
static void addLoggingModuleIfNotPresent(final List<Module> modules) {
|
||||||
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
|
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
|
||||||
modules.add(new JDKLoggingModule());
|
modules.add(new JDKLoggingModule());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,16 @@ import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map view of an {@link S3Bucket}. Provides additional methods for inserting
|
* Map view of an {@link org.jclouds.aws.s3.domain.S3Bucket}. Provides additional methods for inserting
|
||||||
* common object types.
|
* common object types.
|
||||||
*
|
* <p/>
|
||||||
* <h2>Note</h2> All <code>put</code> operations will invoke
|
* <h2>Note</h2> All <code>put</code> operations will invoke
|
||||||
* {@link S3Object#generateMd5}. By extension, {@link #put(String, InputStream)}
|
* {@link org.jclouds.aws.s3.domain.S3Object#generateMd5}. By extension, {@link #put(Object, Object)}
|
||||||
* will result in the InputStream being converted to a byte array. For this
|
* 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
|
* reason, do not use {@link #put(Object, Object)} to store files. Use
|
||||||
* {@link #putFile(String, File)} or {@link S3ObjectMap} instead.
|
* {@link #putFile(String, File)} or {@link S3ObjectMap} instead.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface S3InputStreamMap extends S3Map<String, InputStream> {
|
public interface S3InputStreamMap extends S3Map<String, InputStream> {
|
||||||
InputStream putString(String key, String value);
|
InputStream putString(String key, String value);
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.jclouds.http.HttpResponseException;
|
||||||
*
|
*
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html" />
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html" />
|
||||||
* @see S3Error
|
* @see S3Error
|
||||||
* @see ParseS3ErrorFromXmlContent
|
* @see org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,12 +23,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import com.google.common.base.Preconditions;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.*;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
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.reference.S3Headers;
|
||||||
import org.jclouds.aws.s3.util.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
@ -36,9 +34,7 @@ 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;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import java.io.UnsupportedEncodingException;
|
||||||
import com.google.common.collect.HashMultimap;
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported in the REST API for the COPY object operation.
|
* Contains options supported in the REST API for the COPY object operation.
|
||||||
|
@ -49,26 +45,24 @@ import com.google.common.collect.Multimap;
|
||||||
* <p/>
|
* <p/>
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
|
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
|
||||||
*
|
* <p/>
|
||||||
* S3Connection connection = // get connection
|
* S3Connection connection = // get connection
|
||||||
*
|
* <p/>
|
||||||
* Multimap<String,String> metadata = HashMultimap.create();
|
* Multimap<String,String> metadata = HashMultimap.create();
|
||||||
* metadata.put("x-amz-meta-adrian", "foo");
|
* metadata.put("x-amz-meta-adrian", "foo");
|
||||||
*
|
* <p/>
|
||||||
* // 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))
|
||||||
* );
|
* );
|
||||||
* <code>
|
* <code>
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html?"
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html?"
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CopyObjectOptions extends BaseHttpRequestOptions {
|
public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
private final static DateService dateService = new DateService();
|
private final static DateService dateService = new DateService();
|
||||||
|
@ -85,56 +79,56 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see CannedAccessPolicy
|
* @see CannedAccessPolicy
|
||||||
*/
|
*/
|
||||||
public CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
|
public CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
|
||||||
this.acl = checkNotNull(acl, "acl");
|
this.acl = checkNotNull(acl, "acl");
|
||||||
if (!acl.equals(CannedAccessPolicy.PRIVATE))
|
if (!acl.equals(CannedAccessPolicy.PRIVATE))
|
||||||
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
|
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
|
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
|
||||||
*/
|
*/
|
||||||
public CannedAccessPolicy getAcl() {
|
public CannedAccessPolicy getAcl() {
|
||||||
return acl;
|
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/>
|
||||||
* Copies the object if it hasn't been modified since the specified time;
|
* Copies the object if it hasn't been modified since the specified time;
|
||||||
* otherwise returns a 412 (precondition failed).
|
* otherwise returns a 412 (precondition failed).
|
||||||
* <p />
|
* <p/>
|
||||||
* This header can be used with x-amz-copy-source-if-match, but cannot be
|
* This header can be used with x-amz-copy-source-if-match, but cannot be
|
||||||
* used with other conditional copy headers.
|
* used with other conditional copy headers.
|
||||||
*
|
*
|
||||||
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
|
||||||
* @return valid HTTP date
|
* @return valid HTTP date
|
||||||
|
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
||||||
* @see CopyObjectOptions#ifSourceModifiedSince(DateTime)
|
* @see CopyObjectOptions#ifSourceModifiedSince(DateTime)
|
||||||
*/
|
*/
|
||||||
public String getIfModifiedSince() {
|
public String getIfModifiedSince() {
|
||||||
return getFirstHeaderOrNull("x-amz-copy-source-if-modified-since");
|
return getFirstHeaderOrNull("x-amz-copy-source-if-modified-since");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use in the header x-amz-copy-source-if-modified-since
|
* For use in the header x-amz-copy-source-if-modified-since
|
||||||
* <p />
|
* <p/>
|
||||||
* Copies the object if it has been modified since the specified time;
|
* Copies the object if it has been modified since the specified time;
|
||||||
* otherwise returns a 412 (failed condition).
|
* otherwise returns a 412 (failed condition).
|
||||||
* <p/>
|
* <p/>
|
||||||
* This header can be used with x-amz-copy-source-if-none-match, but cannot
|
* This header can be used with x-amz-copy-source-if-none-match, but cannot
|
||||||
* be used with other conditional copy headers.
|
* be used with other conditional copy headers.
|
||||||
*
|
*
|
||||||
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
|
||||||
* @return valid HTTP date
|
* @return valid HTTP date
|
||||||
|
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
||||||
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
|
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
|
||||||
*/
|
*/
|
||||||
public String getIfUnmodifiedSince() {
|
public String getIfUnmodifiedSince() {
|
||||||
return getFirstHeaderOrNull("x-amz-copy-source-if-unmodified-since");
|
return getFirstHeaderOrNull("x-amz-copy-source-if-unmodified-since");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use in the request header: x-amz-copy-source-if-match
|
* For use in the request header: x-amz-copy-source-if-match
|
||||||
* <p />
|
* <p/>
|
||||||
* Copies the object if its entity tag (ETag) matches the specified tag;
|
* Copies the object if its entity tag (ETag) matches the specified tag;
|
||||||
* otherwise return a 412 (precondition failed).
|
* otherwise return a 412 (precondition failed).
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -144,12 +138,12 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
|
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
|
||||||
*/
|
*/
|
||||||
public String getIfMatch() {
|
public String getIfMatch() {
|
||||||
return getFirstHeaderOrNull("x-amz-copy-source-if-match");
|
return getFirstHeaderOrNull("x-amz-copy-source-if-match");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use in the request header: x-amz-copy-source-if-none-match
|
* For use in the request header: x-amz-copy-source-if-none-match
|
||||||
* <p />
|
* <p/>
|
||||||
* Copies the object if its entity tag (ETag) is different than the
|
* Copies the object if its entity tag (ETag) is different than the
|
||||||
* specified Etag; otherwise returns a 412 (failed condition).
|
* specified Etag; otherwise returns a 412 (failed condition).
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -159,7 +153,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
|
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
|
||||||
*/
|
*/
|
||||||
public String getIfNoneMatch() {
|
public String getIfNoneMatch() {
|
||||||
return getFirstHeaderOrNull("x-amz-copy-source-if-none-match");
|
return getFirstHeaderOrNull("x-amz-copy-source-if-none-match");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,168 +164,164 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
* @see #overrideMetadataWith(Multimap)
|
* @see #overrideMetadataWith(Multimap)
|
||||||
*/
|
*/
|
||||||
public Multimap<String, String> getMetadata() {
|
public Multimap<String, String> getMetadata() {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only return the object if it has changed since this time.
|
* Only return the object if it has changed since this time.
|
||||||
* <p />
|
* <p/>
|
||||||
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
|
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
|
||||||
* {@link #ifSourceUnmodifiedSince(DateTime)}
|
* {@link #ifSourceUnmodifiedSince(DateTime)}
|
||||||
*/
|
*/
|
||||||
public CopyObjectOptions ifSourceModifiedSince(DateTime ifModifiedSince) {
|
public CopyObjectOptions ifSourceModifiedSince(DateTime ifModifiedSince) {
|
||||||
checkState(getIfMatch() == null,
|
checkState(getIfMatch() == null,
|
||||||
"ifMd5Matches() is not compatible with ifModifiedSince()");
|
"ifMd5Matches() is not compatible with ifModifiedSince()");
|
||||||
checkState(getIfUnmodifiedSince() == null,
|
checkState(getIfUnmodifiedSince() == null,
|
||||||
"ifUnmodifiedSince() is not compatible with ifModifiedSince()");
|
"ifUnmodifiedSince() is not compatible with ifModifiedSince()");
|
||||||
replaceHeader("x-amz-copy-source-if-modified-since",
|
replaceHeader("x-amz-copy-source-if-modified-since",
|
||||||
dateService.toHeaderString(checkNotNull(ifModifiedSince,
|
dateService.toHeaderString(checkNotNull(ifModifiedSince,
|
||||||
"ifModifiedSince")));
|
"ifModifiedSince")));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only return the object if it hasn't changed since this time.
|
* Only return the object if it hasn't changed since this time.
|
||||||
* <p />
|
* <p/>
|
||||||
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
|
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
|
||||||
* {@link #ifSourceModifiedSince(DateTime)}
|
* {@link #ifSourceModifiedSince(DateTime)}
|
||||||
*/
|
*/
|
||||||
public CopyObjectOptions ifSourceUnmodifiedSince(DateTime ifUnmodifiedSince) {
|
public CopyObjectOptions ifSourceUnmodifiedSince(DateTime ifUnmodifiedSince) {
|
||||||
checkState(getIfNoneMatch() == null,
|
checkState(getIfNoneMatch() == null,
|
||||||
"ifMd5DoesntMatch() is not compatible with ifUnmodifiedSince()");
|
"ifMd5DoesntMatch() is not compatible with ifUnmodifiedSince()");
|
||||||
checkState(getIfModifiedSince() == null,
|
checkState(getIfModifiedSince() == null,
|
||||||
"ifModifiedSince() is not compatible with ifUnmodifiedSince()");
|
"ifModifiedSince() is not compatible with ifUnmodifiedSince()");
|
||||||
replaceHeader("x-amz-copy-source-if-unmodified-since", dateService
|
replaceHeader("x-amz-copy-source-if-unmodified-since", dateService
|
||||||
.toHeaderString(checkNotNull(ifUnmodifiedSince,
|
.toHeaderString(checkNotNull(ifUnmodifiedSince,
|
||||||
"ifUnmodifiedSince")));
|
"ifUnmodifiedSince")));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object's md5 hash should match the parameter <code>md5</code>.
|
* The object's md5 hash should match the parameter <code>md5</code>.
|
||||||
*
|
* <p/>
|
||||||
* <p />
|
* <p/>
|
||||||
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
|
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
|
||||||
* {@link #ifSourceModifiedSince(DateTime)}
|
* {@link #ifSourceModifiedSince(DateTime)}
|
||||||
*
|
*
|
||||||
* @param md5
|
* @param md5 hash representing the entity
|
||||||
* hash representing the entity
|
* @throws UnsupportedEncodingException if there was a problem converting this into an S3 eTag string
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* if there was a problem converting this into an S3 eTag string
|
|
||||||
*/
|
*/
|
||||||
public CopyObjectOptions ifSourceMd5Matches(byte[] md5)
|
public CopyObjectOptions ifSourceMd5Matches(byte[] md5)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
checkState(getIfNoneMatch() == null,
|
checkState(getIfNoneMatch() == null,
|
||||||
"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("\"%1$s\"",
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object should not have a md5 hash corresponding with the parameter
|
* The object should not have a md5 hash corresponding with the parameter
|
||||||
* <code>md5</code>.
|
* <code>md5</code>.
|
||||||
* <p />
|
* <p/>
|
||||||
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
|
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
|
||||||
* {@link #ifSourceUnmodifiedSince(DateTime)}
|
* {@link #ifSourceUnmodifiedSince(DateTime)}
|
||||||
*
|
*
|
||||||
* @param md5
|
* @param md5 hash representing the entity
|
||||||
* hash representing the entity
|
* @throws UnsupportedEncodingException if there was a problem converting this into an S3 eTag string
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* if there was a problem converting this into an S3 eTag string
|
|
||||||
*/
|
*/
|
||||||
public CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
|
public CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
checkState(getIfMatch() == null,
|
checkState(getIfMatch() == null,
|
||||||
"ifMd5Matches() is not compatible with ifMd5DoesntMatch()");
|
"ifMd5Matches() is not compatible with ifMd5DoesntMatch()");
|
||||||
Preconditions
|
Preconditions
|
||||||
.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(
|
||||||
"\"%1$s\"", S3Utils.toHexString(checkNotNull(md5,
|
"\"%1$s\"", S3Utils.toHexString(checkNotNull(md5,
|
||||||
"ifMd5DoesntMatch"))));
|
"ifMd5DoesntMatch"))));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Multimap<String, String> buildRequestHeaders() {
|
public Multimap<String, String> buildRequestHeaders() {
|
||||||
Multimap<String, String> returnVal = HashMultimap.create();
|
Multimap<String, String> returnVal = HashMultimap.create();
|
||||||
returnVal.putAll(headers);
|
returnVal.putAll(headers);
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
returnVal.putAll(metadata);
|
returnVal.putAll(metadata);
|
||||||
returnVal.put("x-amz-metadata-directive", "REPLACE");
|
returnVal.put("x-amz-metadata-directive", "REPLACE");
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the provided metadata instead of what is on the source object.
|
* Use the provided metadata instead of what is on the source object.
|
||||||
*/
|
*/
|
||||||
public CopyObjectOptions overrideMetadataWith(
|
public CopyObjectOptions overrideMetadataWith(
|
||||||
Multimap<String, String> metadata) {
|
Multimap<String, String> metadata) {
|
||||||
checkNotNull(metadata, "metadata");
|
checkNotNull(metadata, "metadata");
|
||||||
for (String header : metadata.keySet()) {
|
for (String header : metadata.keySet()) {
|
||||||
checkArgument(header.startsWith("x-amz-meta-"),
|
checkArgument(header.startsWith("x-amz-meta-"),
|
||||||
"Metadata keys must start with x-amz-meta-");
|
"Metadata keys must start with x-amz-meta-");
|
||||||
}
|
}
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
|
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
|
||||||
*/
|
*/
|
||||||
public static CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
|
public static CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
return options.overrideAcl(acl);
|
return options.overrideAcl(acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#getIfModifiedSince()
|
* @see CopyObjectOptions#getIfModifiedSince()
|
||||||
*/
|
*/
|
||||||
public static CopyObjectOptions ifSourceModifiedSince(
|
public static CopyObjectOptions ifSourceModifiedSince(
|
||||||
DateTime ifModifiedSince) {
|
DateTime ifModifiedSince) {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
return options.ifSourceModifiedSince(ifModifiedSince);
|
return options.ifSourceModifiedSince(ifModifiedSince);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
|
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
|
||||||
*/
|
*/
|
||||||
public static CopyObjectOptions ifSourceUnmodifiedSince(
|
public static CopyObjectOptions ifSourceUnmodifiedSince(
|
||||||
DateTime ifUnmodifiedSince) {
|
DateTime ifUnmodifiedSince) {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
return options.ifSourceUnmodifiedSince(ifUnmodifiedSince);
|
return options.ifSourceUnmodifiedSince(ifUnmodifiedSince);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
|
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
|
||||||
*/
|
*/
|
||||||
public static CopyObjectOptions ifSourceMd5Matches(byte[] md5)
|
public static CopyObjectOptions ifSourceMd5Matches(byte[] md5)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
return options.ifSourceMd5Matches(md5);
|
return options.ifSourceMd5Matches(md5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
|
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
|
||||||
*/
|
*/
|
||||||
public static CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
|
public static CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
return options.ifSourceMd5DoesntMatch(md5);
|
return options.ifSourceMd5DoesntMatch(md5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #overrideMetadataWith(Multimap)
|
* @see #overrideMetadataWith(Multimap)
|
||||||
*/
|
*/
|
||||||
public static CopyObjectOptions overrideMetadataWith(
|
public static CopyObjectOptions overrideMetadataWith(
|
||||||
Multimap<String, String> metadata) {
|
Multimap<String, String> metadata) {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
return options.overrideMetadataWith(metadata);
|
return options.overrideMetadataWith(metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,11 @@ 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.checkState;
|
||||||
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported in the REST API for the GET bucket operation. <h2>
|
* Contains options supported in the REST API for the GET bucket operation. <h2>
|
||||||
* Usage</h2> The recommended way to instantiate a GetBucketOptions object is to
|
* Usage</h2> The recommended way to instantiate a GetBucketOptions object is to
|
||||||
|
@ -39,17 +38,14 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
* <p/>
|
* <p/>
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
|
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
|
||||||
*
|
* <p/>
|
||||||
* S3Connection connection = // get connection
|
* S3Connection connection = // get connection
|
||||||
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
|
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
|
||||||
* <code>
|
* <code>
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html?"
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html?"
|
||||||
* />
|
* />
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ListBucketOptions extends BaseHttpRequestOptions {
|
public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||||
public static final ListBucketOptions NONE = new ListBucketOptions();
|
public static final ListBucketOptions NONE = new ListBucketOptions();
|
||||||
|
@ -62,17 +58,17 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
*/
|
*/
|
||||||
public ListBucketOptions withPrefix(String prefix)
|
public ListBucketOptions withPrefix(String prefix)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
options.put("prefix", URLEncoder.encode(checkNotNull(prefix, "prefix"),
|
options.put("prefix", URLEncoder.encode(checkNotNull(prefix, "prefix"),
|
||||||
"UTF-8"));
|
"UTF-8"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ListBucketOptions#withPrefix(String)
|
* @see ListBucketOptions#withPrefix(String)
|
||||||
*/
|
*/
|
||||||
public String getPrefix() {
|
public String getPrefix() {
|
||||||
return options.get("prefix");
|
return options.get("prefix");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,17 +80,17 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
*/
|
*/
|
||||||
public ListBucketOptions afterMarker(String marker)
|
public ListBucketOptions afterMarker(String marker)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
options.put("marker", URLEncoder.encode(checkNotNull(marker, "marker"),
|
options.put("marker", URLEncoder.encode(checkNotNull(marker, "marker"),
|
||||||
"UTF-8"));
|
"UTF-8"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ListBucketOptions#afterMarker(String)
|
* @see ListBucketOptions#afterMarker(String)
|
||||||
*/
|
*/
|
||||||
public String getMarker() {
|
public String getMarker() {
|
||||||
return options.get("marker");
|
return options.get("marker");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,16 +98,16 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||||
* server might return fewer than this many keys, but will not return more.
|
* server might return fewer than this many keys, but will not return more.
|
||||||
*/
|
*/
|
||||||
public ListBucketOptions maxResults(long maxKeys) {
|
public ListBucketOptions maxResults(long maxKeys) {
|
||||||
checkState(maxKeys >= 0, "maxKeys must be >= 0");
|
checkState(maxKeys >= 0, "maxKeys must be >= 0");
|
||||||
options.put("max-keys", Long.toString(maxKeys));
|
options.put("max-keys", Long.toString(maxKeys));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ListBucketOptions#maxResults(long)
|
* @see ListBucketOptions#maxResults(long)
|
||||||
*/
|
*/
|
||||||
public String getMaxKeys() {
|
public String getMaxKeys() {
|
||||||
return options.get("max-keys");
|
return options.get("max-keys");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,59 +118,59 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||||
*
|
*
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
*/
|
*/
|
||||||
public ListBucketOptions setDelimiter(String delimiter)
|
public ListBucketOptions delimiter(String delimiter)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
options.put("delimiter", URLEncoder.encode(checkNotNull(delimiter,
|
options.put("delimiter", URLEncoder.encode(checkNotNull(delimiter,
|
||||||
"delimiter"), "UTF-8"));
|
"delimiter"), "UTF-8"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ListBucketOptions#setDelimiter(String)
|
* @see ListBucketOptions#delimiter(String)
|
||||||
*/
|
*/
|
||||||
public String getDelimiter() {
|
public String getDelimiter() {
|
||||||
return options.get("delimiter");
|
return options.get("delimiter");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* @see ListBucketOptions#withPrefix(String)
|
* @see ListBucketOptions#withPrefix(String)
|
||||||
*/
|
*/
|
||||||
public static ListBucketOptions withPrefix(String prefix)
|
public static ListBucketOptions withPrefix(String prefix)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ListBucketOptions options = new ListBucketOptions();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
return options.withPrefix(prefix);
|
return options.withPrefix(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* @see ListBucketOptions#afterMarker(String)
|
* @see ListBucketOptions#afterMarker(String)
|
||||||
*/
|
*/
|
||||||
public static ListBucketOptions afterMarker(String marker)
|
public static ListBucketOptions afterMarker(String marker)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ListBucketOptions options = new ListBucketOptions();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
return options.afterMarker(marker);
|
return options.afterMarker(marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ListBucketOptions#maxResults(long)
|
* @see ListBucketOptions#maxResults(long)
|
||||||
*/
|
*/
|
||||||
public static ListBucketOptions maxResults(long maxKeys) {
|
public static ListBucketOptions maxResults(long maxKeys) {
|
||||||
ListBucketOptions options = new ListBucketOptions();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
return options.maxResults(maxKeys);
|
return options.maxResults(maxKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* @see ListBucketOptions#delimiter(String)
|
* @see ListBucketOptions#delimiter(String)
|
||||||
*/
|
*/
|
||||||
public static ListBucketOptions delimiter(String delimiter)
|
public static ListBucketOptions delimiter(String delimiter)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ListBucketOptions options = new ListBucketOptions();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
return options.setDelimiter(delimiter);
|
return options.delimiter(delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,13 +23,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
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.aws.s3.reference.S3Headers;
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported in the REST API for the PUT bucket operation. <h2>
|
* Contains options supported in the REST API for the PUT bucket operation. <h2>
|
||||||
* Usage</h2> The recommended way to instantiate a PutBucketOptions object is to
|
* Usage</h2> The recommended way to instantiate a PutBucketOptions object is to
|
||||||
|
@ -40,16 +39,14 @@ import static com.google.common.base.Preconditions.*;
|
||||||
* 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;
|
||||||
*
|
* <p/>
|
||||||
* S3Connection connection = // get connection
|
* S3Connection connection = // get connection
|
||||||
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
|
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
|
||||||
* <code>
|
* <code>
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html?"
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html?"
|
||||||
* />
|
* />
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class PutBucketOptions extends BaseHttpRequestOptions {
|
public class PutBucketOptions extends BaseHttpRequestOptions {
|
||||||
public static final PutBucketOptions NONE = new PutBucketOptions();
|
public static final PutBucketOptions NONE = new PutBucketOptions();
|
||||||
|
@ -62,12 +59,12 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
|
||||||
* You can currently specify a Europe (EU) location constraint.
|
* You can currently specify a Europe (EU) location constraint.
|
||||||
*/
|
*/
|
||||||
public PutBucketOptions createIn(LocationConstraint constraint) {
|
public PutBucketOptions createIn(LocationConstraint constraint) {
|
||||||
this.constraint = checkNotNull(constraint, "constraint");
|
this.constraint = checkNotNull(constraint, "constraint");
|
||||||
this.payload = String
|
this.payload = String
|
||||||
.format(
|
.format(
|
||||||
"<CreateBucketConfiguration><LocationConstraint>%1$s</LocationConstraint></CreateBucketConfiguration>",
|
"<CreateBucketConfiguration><LocationConstraint>%1$s</LocationConstraint></CreateBucketConfiguration>",
|
||||||
constraint.toString());
|
constraint.toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,41 +73,41 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
|
||||||
* @see CannedAccessPolicy
|
* @see CannedAccessPolicy
|
||||||
*/
|
*/
|
||||||
public PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
|
public PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
|
||||||
this.acl = checkNotNull(acl, "acl");
|
this.acl = checkNotNull(acl, "acl");
|
||||||
if (!acl.equals(CannedAccessPolicy.PRIVATE))
|
if (!acl.equals(CannedAccessPolicy.PRIVATE))
|
||||||
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
|
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
|
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
|
||||||
*/
|
*/
|
||||||
public CannedAccessPolicy getAcl() {
|
public CannedAccessPolicy getAcl() {
|
||||||
return acl;
|
return acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see PutBucketOptions#createIn(LocationConstraint)
|
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint)
|
||||||
*/
|
*/
|
||||||
public LocationConstraint getLocationConstraint() {
|
public LocationConstraint getLocationConstraint() {
|
||||||
return constraint;
|
return constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
/**
|
/**
|
||||||
* @see PutBucketOptions#createIn(LocationConstraint)
|
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint)
|
||||||
*/
|
*/
|
||||||
public static PutBucketOptions createIn(LocationConstraint constraint) {
|
public static PutBucketOptions createIn(LocationConstraint constraint) {
|
||||||
PutBucketOptions options = new PutBucketOptions();
|
PutBucketOptions options = new PutBucketOptions();
|
||||||
return options.createIn(constraint);
|
return options.createIn(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
|
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
|
||||||
*/
|
*/
|
||||||
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
|
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
|
||||||
PutBucketOptions options = new PutBucketOptions();
|
PutBucketOptions options = new PutBucketOptions();
|
||||||
return options.withBucketAcl(acl);
|
return options.withBucketAcl(acl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.config;
|
||||||
|
|
||||||
|
import com.google.inject.*;
|
||||||
|
import com.google.inject.assistedinject.FactoryProvider;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
|
import org.jclouds.aws.s3.S3Context;
|
||||||
|
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
|
||||||
|
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||||
|
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
|
||||||
|
import org.jclouds.aws.s3.internal.GuiceS3Context;
|
||||||
|
import org.jclouds.aws.s3.internal.LiveS3Connection;
|
||||||
|
import org.jclouds.aws.s3.internal.LiveS3InputStreamMap;
|
||||||
|
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
|
||||||
|
import org.jclouds.http.HttpConstants;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
|
import org.jclouds.http.annotation.ClientErrorHandler;
|
||||||
|
import org.jclouds.http.annotation.RedirectHandler;
|
||||||
|
import org.jclouds.http.annotation.ServerErrorHandler;
|
||||||
|
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the S3 connection, including logging and http transport.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@S3ConnectionModule
|
||||||
|
public class LiveS3ConnectionModule extends AbstractModule {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS)
|
||||||
|
String address;
|
||||||
|
@Inject
|
||||||
|
@Named(HttpConstants.PROPERTY_HTTP_PORT)
|
||||||
|
int port;
|
||||||
|
@Inject
|
||||||
|
@Named(HttpConstants.PROPERTY_HTTP_SECURE)
|
||||||
|
boolean isSecure;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(S3Connection.class).to(LiveS3Connection.class)
|
||||||
|
.in(Scopes.SINGLETON);
|
||||||
|
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class)
|
||||||
|
.to(CloseContentAndSetExceptionHandler.class).in(
|
||||||
|
Scopes.SINGLETON);
|
||||||
|
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class)
|
||||||
|
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||||
|
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
|
||||||
|
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
||||||
|
requestInjection(this);
|
||||||
|
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https"
|
||||||
|
: "http"), address, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
List<HttpRequestFilter> provideRequestFilters(
|
||||||
|
RequestAuthorizeSignature requestAuthorizeSignature) {
|
||||||
|
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
|
||||||
|
filters.add(requestAuthorizeSignature);
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.TYPE;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpFutureCommandClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* designates the the module configures a {@link org.jclouds.aws.s3.S3Connection}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Target(TYPE)
|
||||||
|
public @interface S3ConnectionModule {
|
||||||
|
|
||||||
|
}
|
|
@ -23,89 +23,37 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.config;
|
package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.google.inject.AbstractModule;
|
||||||
import java.util.List;
|
import com.google.inject.assistedinject.FactoryProvider;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
import org.jclouds.aws.s3.S3Context;
|
import org.jclouds.aws.s3.S3Context;
|
||||||
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
|
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
|
||||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
|
||||||
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
|
|
||||||
import org.jclouds.aws.s3.internal.GuiceS3Context;
|
import org.jclouds.aws.s3.internal.GuiceS3Context;
|
||||||
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.HttpConstants;
|
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
|
||||||
import org.jclouds.http.annotation.ClientErrorHandler;
|
|
||||||
import org.jclouds.http.annotation.RedirectHandler;
|
|
||||||
import org.jclouds.http.annotation.ServerErrorHandler;
|
|
||||||
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import com.google.inject.Scopes;
|
|
||||||
import com.google.inject.Singleton;
|
|
||||||
import com.google.inject.assistedinject.FactoryProvider;
|
|
||||||
import com.google.inject.name.Named;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the S3 connection, including logging and http transport.
|
* Configures the {@link S3Context}; requires {@link S3Connection} bound.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class S3ContextModule extends AbstractModule {
|
public class S3ContextModule extends AbstractModule {
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS)
|
|
||||||
String address;
|
|
||||||
@Inject
|
|
||||||
@Named(HttpConstants.PROPERTY_HTTP_PORT)
|
|
||||||
int port;
|
|
||||||
@Inject
|
|
||||||
@Named(HttpConstants.PROPERTY_HTTP_SECURE)
|
|
||||||
boolean isSecure;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new S3CommandsModule());
|
this.requireBinding(S3Connection.class);
|
||||||
bind(S3Connection.class).to(LiveS3Connection.class)
|
install(new S3CommandsModule());
|
||||||
.in(Scopes.SINGLETON);
|
bind(GuiceS3Context.S3ObjectMapFactory.class).toProvider(
|
||||||
bind(GuiceS3Context.S3ObjectMapFactory.class).toProvider(
|
FactoryProvider.newFactory(
|
||||||
FactoryProvider.newFactory(
|
GuiceS3Context.S3ObjectMapFactory.class,
|
||||||
GuiceS3Context.S3ObjectMapFactory.class,
|
LiveS3ObjectMap.class));
|
||||||
LiveS3ObjectMap.class));
|
bind(GuiceS3Context.S3InputStreamMapFactory.class).toProvider(
|
||||||
bind(GuiceS3Context.S3InputStreamMapFactory.class).toProvider(
|
FactoryProvider.newFactory(
|
||||||
FactoryProvider.newFactory(
|
GuiceS3Context.S3InputStreamMapFactory.class,
|
||||||
GuiceS3Context.S3InputStreamMapFactory.class,
|
LiveS3InputStreamMap.class));
|
||||||
LiveS3InputStreamMap.class));
|
bind(S3Context.class).to(GuiceS3Context.class);
|
||||||
bind(S3Context.class).to(GuiceS3Context.class);
|
|
||||||
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class)
|
|
||||||
.to(CloseContentAndSetExceptionHandler.class).in(
|
|
||||||
Scopes.SINGLETON);
|
|
||||||
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class)
|
|
||||||
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
|
||||||
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
|
|
||||||
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
|
|
||||||
requestInjection(this);
|
|
||||||
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https"
|
|
||||||
: "http"), address, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
List<HttpRequestFilter> provideRequestFilters(
|
|
||||||
RequestAuthorizeSignature requestAuthorizeSignature) {
|
|
||||||
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
|
|
||||||
filters.add(requestAuthorizeSignature);
|
|
||||||
return filters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,29 +24,28 @@
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container that provides namespace, access control and aggregation of
|
* A container that provides namespace, access control and aggregation of
|
||||||
* {@link S3Object}s
|
* {@link S3Object}s
|
||||||
*
|
* <p/>
|
||||||
* <p/>
|
* <p/>
|
||||||
* Every object stored in Amazon S3 is contained in a bucket. Buckets partition
|
* Every object stored in Amazon S3 is contained in a bucket. Buckets partition
|
||||||
* the namespace of objects stored in Amazon S3 at the top level. Within a
|
* the namespace of objects stored in Amazon S3 at the top level. Within a
|
||||||
* bucket, you can use any names for your objects, but bucket names must be
|
* bucket, you can use any names for your objects, but bucket names must be
|
||||||
* unique across all of Amazon S3.
|
* unique across all of Amazon S3.
|
||||||
*
|
* <p/>
|
||||||
* Buckets are similar to Internet domain names. Just as Amazon is the only
|
* Buckets are similar to Internet domain names. Just as Amazon is the only
|
||||||
* owner of the domain name Amazon.com, only one person or organization can own
|
* owner of the domain name Amazon.com, only one person or organization can own
|
||||||
* a bucket within Amazon S3. Once you create a uniquely named bucket in Amazon
|
* a bucket within Amazon S3. Once you create a uniquely named bucket in Amazon
|
||||||
* S3, you can organize and name the objects within the bucket in any way you
|
* S3, you can organize and name the objects within the bucket in any way you
|
||||||
* like and the bucket will remain yours for as long as you like and as long as
|
* like and the bucket will remain yours for as long as you like and as long as
|
||||||
* you have the Amazon S3 account.
|
* you have the Amazon S3 account.
|
||||||
*
|
* <p/>
|
||||||
* The similarities between buckets and domain names is not a coincidenceÑthere
|
* The similarities between buckets and domain names is not a coincidenceÑthere
|
||||||
* is a direct mapping between Amazon S3 buckets and subdomains of
|
* is a direct mapping between Amazon S3 buckets and subdomains of
|
||||||
* s3.amazonaws.com. Objects stored in Amazon S3 are addressable using the REST
|
* s3.amazonaws.com. Objects stored in Amazon S3 are addressable using the REST
|
||||||
|
@ -62,148 +61,145 @@ import org.joda.time.DateTime;
|
||||||
public class S3Bucket {
|
public class S3Bucket {
|
||||||
@Override
|
@Override
|
||||||
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(", isTruncated=").append(isTruncated);
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
if (!(o instanceof S3Bucket))
|
if (!(o instanceof S3Bucket))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
S3Bucket s3Bucket = (S3Bucket) o;
|
S3Bucket s3Bucket = (S3Bucket) o;
|
||||||
|
|
||||||
if (isComplete != s3Bucket.isComplete)
|
if (isTruncated != s3Bucket.isTruncated)
|
||||||
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)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 + (isTruncated ? 1 : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System metadata of the S3Bucket
|
* System metadata of the S3Bucket
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Metadata {
|
public static class Metadata {
|
||||||
@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);
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
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 (!name.equals(metadata.name))
|
if (!name.equals(metadata.name))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = name.hashCode();
|
int result = name.hashCode();
|
||||||
result = 31 * result
|
result = 31 * result
|
||||||
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
|
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Location constraint of the bucket.
|
* Location constraint of the bucket.
|
||||||
*
|
*
|
||||||
* @see <a href=
|
* @author Adrian Cole
|
||||||
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
|
* @see <a href=
|
||||||
* />
|
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
|
||||||
* @author Adrian Cole
|
* />
|
||||||
*
|
*/
|
||||||
*/
|
public static enum LocationConstraint {
|
||||||
public static enum LocationConstraint {
|
EU
|
||||||
EU
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private DateTime creationDate;
|
private DateTime creationDate;
|
||||||
private CanonicalUser canonicalUser;
|
private CanonicalUser canonicalUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #getName()
|
* @see #getName()
|
||||||
*/
|
*/
|
||||||
public Metadata(String name) {
|
public Metadata(String name) {
|
||||||
this.name = checkNotNull(name, "name");
|
this.name = checkNotNull(name, "name");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To comply with Amazon S3 requirements, bucket names must:
|
* To comply with Amazon S3 requirements, bucket names must:
|
||||||
*
|
* <p/>
|
||||||
* Contain lowercase letters, numbers, periods (.), underscores (_), and
|
* Contain lowercase letters, numbers, periods (.), underscores (_), and
|
||||||
* dashes (-)
|
* dashes (-)
|
||||||
*
|
* <p/>
|
||||||
* Start with a number or letter
|
* Start with a number or letter
|
||||||
*
|
* <p/>
|
||||||
* Be between 3 and 255 characters long
|
* Be between 3 and 255 characters long
|
||||||
*
|
* <p/>
|
||||||
* Not be in an IP address style (e.g., "192.168.5.4")
|
* Not be in an IP address style (e.g., "192.168.5.4")
|
||||||
*
|
*/
|
||||||
*/
|
public String getName() {
|
||||||
public String getName() {
|
return name;
|
||||||
return name;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public DateTime getCreationDate() {
|
public DateTime getCreationDate() {
|
||||||
return creationDate;
|
return creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreationDate(DateTime creationDate) {
|
public void setCreationDate(DateTime creationDate) {
|
||||||
this.creationDate = creationDate;
|
this.creationDate = creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every bucket and object in Amazon S3 has an owner, the user that
|
* 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
|
* created the bucket or object. The owner of a bucket or object cannot
|
||||||
* be changed. However, if the object is overwritten by another user
|
* be changed. However, if the object is overwritten by another user
|
||||||
* (deleted and rewritten), the new object will have a new owner.
|
* (deleted and rewritten), the new object will have a new owner.
|
||||||
*/
|
*/
|
||||||
public CanonicalUser getOwner() {
|
public CanonicalUser getOwner() {
|
||||||
return canonicalUser;
|
return canonicalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOwner(CanonicalUser canonicalUser) {
|
public void setOwner(CanonicalUser canonicalUser) {
|
||||||
this.canonicalUser = canonicalUser;
|
this.canonicalUser = canonicalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,71 +213,71 @@ public class S3Bucket {
|
||||||
private long maxKeys;
|
private long maxKeys;
|
||||||
private final Metadata metadata;
|
private final Metadata metadata;
|
||||||
|
|
||||||
private boolean isComplete;
|
private boolean isTruncated;
|
||||||
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.jclouds.aws.s3.S3Connection#listBucket(String)
|
* @see org.jclouds.aws.s3.S3Connection#listBucket(String)
|
||||||
*/
|
*/
|
||||||
public Set<S3Object.Metadata> getContents() {
|
public Set<S3Object.Metadata> getContents() {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContents(Set<S3Object.Metadata> objects) {
|
public void setContents(Set<S3Object.Metadata> objects) {
|
||||||
this.objects = objects;
|
this.objects = objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true, if the list contains all objects.
|
* @return true, if the list contains all objects.
|
||||||
*/
|
*/
|
||||||
public boolean isComplete() {
|
public boolean isTruncated() {
|
||||||
return isComplete;
|
return isTruncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setComplete(boolean complete) {
|
public void setTruncated(boolean truncated) {
|
||||||
isComplete = complete;
|
isTruncated = truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Metadata getMetadata() {
|
public Metadata getMetadata() {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommonPrefixes(Set<String> commonPrefixes) {
|
public void setCommonPrefixes(Set<String> commonPrefixes) {
|
||||||
this.commonPrefixes = commonPrefixes;
|
this.commonPrefixes = commonPrefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example:
|
* Example:
|
||||||
* <p />
|
* <p/>
|
||||||
* if the following keys are in the bucket
|
* if the following keys are in the bucket
|
||||||
*
|
* <p/>
|
||||||
* a/1/a<br/>
|
* a/1/a<br/>
|
||||||
* a/1/b<br/>
|
* a/1/b<br/>
|
||||||
* a/2/a<br/>
|
* a/2/a<br/>
|
||||||
* a/2/b<br/>
|
* a/2/b<br/>
|
||||||
* <p />
|
* <p/>
|
||||||
* and prefix is set to <code>a/</code> and delimiter is set to
|
* and prefix is set to <code>a/</code> and delimiter is set to
|
||||||
* <code>/</code> then commonprefixes would return 1,2
|
* <code>/</code> then commonprefixes would return 1,2
|
||||||
*
|
*
|
||||||
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
|
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
|
||||||
*/
|
*/
|
||||||
public Set<String> getCommonPrefixes() {
|
public Set<String> getCommonPrefixes() {
|
||||||
return commonPrefixes;
|
return commonPrefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrefix(String prefix) {
|
public void setPrefix(String prefix) {
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -290,11 +286,11 @@ public class S3Bucket {
|
||||||
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
|
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
|
||||||
*/
|
*/
|
||||||
public String getPrefix() {
|
public String getPrefix() {
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxKeys(long maxKeys) {
|
public void setMaxKeys(long maxKeys) {
|
||||||
this.maxKeys = maxKeys;
|
this.maxKeys = maxKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -302,11 +298,11 @@ public class S3Bucket {
|
||||||
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMaxKeys()
|
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMaxKeys()
|
||||||
*/
|
*/
|
||||||
public long getMaxKeys() {
|
public long getMaxKeys() {
|
||||||
return maxKeys;
|
return maxKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMarker(String marker) {
|
public void setMarker(String marker) {
|
||||||
this.marker = marker;
|
this.marker = marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -316,11 +312,11 @@ public class S3Bucket {
|
||||||
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
|
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
|
||||||
*/
|
*/
|
||||||
public String getMarker() {
|
public String getMarker() {
|
||||||
return marker;
|
return marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDelimiter(String delimiter) {
|
public void setDelimiter(String delimiter) {
|
||||||
this.delimiter = delimiter;
|
this.delimiter = delimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,32 +23,28 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.*;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import com.google.common.collect.HashMultimap;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.aws.s3.util.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;
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import java.io.IOException;
|
||||||
import com.google.common.collect.Multimap;
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amazon S3 is designed to store objects. Objects are stored in
|
* Amazon S3 is designed to store objects. Objects are stored in
|
||||||
* {@link S3Bucket buckets} and consist of a {@link S3Object#getValue() value},
|
* {@link S3Bucket buckets} and consist of a {@link org.jclouds.aws.s3.domain.S3Object#getData() value},
|
||||||
* a {@link S3Object#getKey key}, {@link S3Object.Metadata#getUserMetadata()
|
* a {@link S3Object#getKey key}, {@link S3Object.Metadata#getUserMetadata()
|
||||||
* metadata}, and an access control policy.
|
* metadata}, and an access control policy.
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
*/
|
||||||
public class S3Object {
|
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);
|
||||||
|
@ -59,381 +55,372 @@ public class S3Object {
|
||||||
private String contentRange;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Object(String key, Object data) {
|
public S3Object(String key, Object data) {
|
||||||
this(key);
|
this(key);
|
||||||
setData(data);
|
setData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System and user Metadata for the {@link S3Object}.
|
* System and user Metadata for the {@link S3Object}.
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html"
|
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html"
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Metadata {
|
public static class Metadata implements Comparable<Metadata> {
|
||||||
public static final Metadata NOT_FOUND = new Metadata("NOT_FOUND");
|
public static final Metadata NOT_FOUND = new Metadata("NOT_FOUND");
|
||||||
|
|
||||||
// parsed during list, head, or get
|
// parsed during list, head, or get
|
||||||
private final String key;
|
private final String key;
|
||||||
private byte[] md5;
|
private byte[] md5;
|
||||||
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> 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.BINARY;
|
private String dataType = ContentTypes.BINARY;
|
||||||
private String cacheControl;
|
private String cacheControl;
|
||||||
private String dataDisposition;
|
private String dataDisposition;
|
||||||
private String dataEncoding;
|
private String dataEncoding;
|
||||||
|
|
||||||
// only parsed on list
|
// only parsed on list
|
||||||
private CanonicalUser owner = null;
|
private CanonicalUser owner = null;
|
||||||
private String storageClass = null;
|
private String storageClass = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #getKey()
|
* @param key
|
||||||
* @param key
|
* @see #getKey()
|
||||||
*/
|
*/
|
||||||
public Metadata(String key) {
|
public Metadata(String key) {
|
||||||
checkNotNull(key, "key");
|
checkNotNull(key, "key");
|
||||||
checkArgument(!key.startsWith("/"), "keys cannot start with /");
|
checkArgument(!key.startsWith("/"), "keys cannot start with /");
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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(
|
||||||
getMd5() == null ? "null" : Arrays.asList(getMd5())
|
getMd5() == null ? "null" : Arrays.asList(getMd5())
|
||||||
.toString());
|
.toString());
|
||||||
sb.append(", size=").append(size);
|
sb.append(", size=").append(size);
|
||||||
sb.append(", dataType='").append(dataType).append('\'');
|
sb.append(", dataType='").append(dataType).append('\'');
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = key.hashCode();
|
int result = key.hashCode();
|
||||||
result = 31 * result
|
result = 31 * result
|
||||||
+ (lastModified != null ? lastModified.hashCode() : 0);
|
+ (lastModified != null ? lastModified.hashCode() : 0);
|
||||||
result = 31 * result
|
result = 31 * result
|
||||||
+ (getMd5() != null ? Arrays.hashCode(getMd5()) : 0);
|
+ (getMd5() != null ? Arrays.hashCode(getMd5()) : 0);
|
||||||
result = 31 * result + (int) (size ^ (size >>> 32));
|
result = 31 * result + (int) (size ^ (size >>> 32));
|
||||||
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
|
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key is the handle that you assign to an object that allows you
|
* The key is the handle that you assign to an object that allows you
|
||||||
* retrieve it later. A key is a sequence of Unicode characters whose
|
* retrieve it later. A key is a sequence of Unicode characters whose
|
||||||
* UTF-8 encoding is at most 1024 bytes long. Each object in a bucket
|
* UTF-8 encoding is at most 1024 bytes long. Each object in a bucket
|
||||||
* must have a unique key.
|
* must have a unique key.
|
||||||
*
|
*
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingKeys.html"
|
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingKeys.html"
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime getLastModified() {
|
public DateTime getLastModified() {
|
||||||
return lastModified;
|
return lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastModified(DateTime lastModified) {
|
public void setLastModified(DateTime lastModified) {
|
||||||
this.lastModified = lastModified;
|
this.lastModified = lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The size of the object, in bytes.
|
* The size of the object, in bytes.
|
||||||
*
|
*
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13."
|
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13."
|
||||||
* />
|
* />
|
||||||
*
|
*/
|
||||||
* @return
|
public long getSize() {
|
||||||
*/
|
return size;
|
||||||
public long getSize() {
|
}
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(long size) {
|
public void setSize(long size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A standard MIME type describing the format of the contents. If none
|
* A standard MIME type describing the format of the contents. If none
|
||||||
* is provided, the default is binary/octet-stream.
|
* is provided, the default is binary/octet-stream.
|
||||||
*
|
* @see <a href=
|
||||||
* @see <a href=
|
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17."
|
||||||
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17."
|
* />
|
||||||
* />
|
*/
|
||||||
*
|
public String getContentType() {
|
||||||
* @return
|
return dataType;
|
||||||
*/
|
}
|
||||||
public String getContentType() {
|
|
||||||
return dataType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentType(String dataType) {
|
public void setContentType(String dataType) {
|
||||||
this.dataType = dataType;
|
this.dataType = dataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMd5(byte[] md5) {
|
public void setMd5(byte[] md5) {
|
||||||
this.md5 = md5;
|
this.md5 = Arrays.copyOf(md5, md5.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the md5 value stored in the Etag header returned by S3.
|
* @return the md5 value stored in the Etag header returned by S3.
|
||||||
*/
|
*/
|
||||||
public byte[] getMd5() {
|
public byte[] getMd5() {
|
||||||
return md5;
|
return (md5 == null) ? null : Arrays.copyOf(md5, md5.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserMetadata(Multimap<String, String> userMetadata) {
|
public void setUserMetadata(Multimap<String, String> userMetadata) {
|
||||||
this.userMetadata = userMetadata;
|
this.userMetadata = userMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Any header starting with <code>x-amz-meta-</code> is considered user
|
||||||
* Any header starting with <code>x-amz-meta-</code> is considered user
|
* metadata. It will be stored with the object and returned when you
|
||||||
* metadata. It will be stored with the object and returned when you
|
* retrieve the object. The total size of the HTTP request, not
|
||||||
* retrieve the object. The total size of the HTTP request, not
|
* including the body, must be less than 8 KB.
|
||||||
* including the body, must be less than 8 KB.
|
*/
|
||||||
*
|
public Multimap<String, String> getUserMetadata() {
|
||||||
*/
|
return userMetadata;
|
||||||
public Multimap<String, String> getUserMetadata() {
|
}
|
||||||
return userMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(CanonicalUser owner) {
|
public void setOwner(CanonicalUser owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every bucket and object in Amazon S3 has an owner, the user that
|
* 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
|
* created the bucket or object. The owner of a bucket or object cannot
|
||||||
* be changed. However, if the object is overwritten by another user
|
* be changed. However, if the object is overwritten by another user
|
||||||
* (deleted and rewritten), the new object will have a new owner.
|
* (deleted and rewritten), the new object will have a new owner.
|
||||||
*/
|
*/
|
||||||
public CanonicalUser getOwner() {
|
public CanonicalUser getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStorageClass(String storageClass) {
|
public void setStorageClass(String storageClass) {
|
||||||
this.storageClass = storageClass;
|
this.storageClass = storageClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently defaults to 'STANDARD' and not used.
|
* Currently defaults to 'STANDARD' and not used.
|
||||||
*/
|
*/
|
||||||
public String getStorageClass() {
|
public String getStorageClass() {
|
||||||
return storageClass;
|
return storageClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCacheControl(String cacheControl) {
|
public void setCacheControl(String cacheControl) {
|
||||||
this.cacheControl = cacheControl;
|
this.cacheControl = cacheControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be used to specify caching behavior along the request/reply
|
* Can be used to specify caching behavior along the request/reply
|
||||||
* chain.
|
* chain.
|
||||||
*
|
*
|
||||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
|
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
|
||||||
*/
|
*/
|
||||||
public String getCacheControl() {
|
public String getCacheControl() {
|
||||||
return cacheControl;
|
return cacheControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentDisposition(String dataDisposition) {
|
public void setContentDisposition(String dataDisposition) {
|
||||||
this.dataDisposition = dataDisposition;
|
this.dataDisposition = dataDisposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies presentational information for the object.
|
* Specifies presentational information for the object.
|
||||||
*
|
*
|
||||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||||
*/
|
*/
|
||||||
public String getContentDisposition() {
|
public String getContentDisposition() {
|
||||||
return dataDisposition;
|
return dataDisposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentEncoding(String dataEncoding) {
|
public void setContentEncoding(String dataEncoding) {
|
||||||
this.dataEncoding = dataEncoding;
|
this.dataEncoding = dataEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies what content encodings have been applied to the object and
|
* Specifies what content encodings have been applied to the object and
|
||||||
* thus what decoding mechanisms must be applied in order to obtain the
|
* thus what decoding mechanisms must be applied in order to obtain the
|
||||||
* media-type referenced by the Content-Type header field.
|
* media-type referenced by the Content-Type header field.
|
||||||
*
|
*
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11"
|
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11"
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
public String getContentEncoding() {
|
public String getContentEncoding() {
|
||||||
return dataEncoding;
|
return dataEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllHeaders(Multimap<String, String> allHeaders) {
|
public void setAllHeaders(Multimap<String, String> allHeaders) {
|
||||||
this.allHeaders = allHeaders;
|
this.allHeaders = allHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return all http response headers associated with this S3Object
|
||||||
* @return all http response headers associated with this S3Object
|
*/
|
||||||
*/
|
public Multimap<String, String> getAllHeaders() {
|
||||||
public Multimap<String, String> getAllHeaders() {
|
return allHeaders;
|
||||||
return allHeaders;
|
}
|
||||||
}
|
|
||||||
|
public int compareTo(Metadata o) {
|
||||||
|
return (this == o) ? 0 : getKey().compareTo(o.getKey());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Metadata#getKey()
|
* @see Metadata#getKey()
|
||||||
*/
|
*/
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return metadata.getKey();
|
return metadata.getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets payload for the request or the content from the response. If size
|
* Sets payload for the request or the content from the response. If size
|
||||||
* isn't set, this will attempt to discover it.
|
* isn't set, this will attempt to discover it.
|
||||||
*
|
*
|
||||||
* @param data
|
* @param data typically InputStream for downloads, or File, byte [], String,
|
||||||
* typically InputStream for downloads, or File, byte [], String,
|
* or InputStream for uploads.
|
||||||
* or InputStream for uploads.
|
|
||||||
*/
|
*/
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generate an MD5 Hash for the current data.
|
* generate an MD5 Hash for the current data.
|
||||||
*
|
* <p/>
|
||||||
* <h2>Note</h2>
|
* <h2>Note</h2>
|
||||||
* <p/>
|
* <p/>
|
||||||
* If this is an InputStream, it will be converted to a byte array first.
|
* If this is an InputStream, it will be converted to a byte array first.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException if there is a problem generating the hash.
|
||||||
* if there is a problem generating the hash.
|
|
||||||
*/
|
*/
|
||||||
public void generateMd5() throws IOException {
|
public void generateMd5() throws IOException {
|
||||||
checkState(data != null, "data");
|
checkState(data != null, "data");
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return InputStream, if downloading, or whatever was set during
|
* @return InputStream, if downloading, or whatever was set during
|
||||||
* {@link #setData(Object)}
|
* {@link #setData(Object)}
|
||||||
*/
|
*/
|
||||||
public Object getData() {
|
public Object getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMetadata(Metadata metadata) {
|
public void setMetadata(Metadata metadata) {
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return System and User metadata relevant to this object.
|
* @return System and User metadata relevant to this object.
|
||||||
*/
|
*/
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
if (!(o instanceof S3Object))
|
if (!(o instanceof S3Object))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
S3Object s3Object = (S3Object) o;
|
S3Object s3Object = (S3Object) o;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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) {
|
public void setContentLength(long contentLength) {
|
||||||
this.contentLength = contentLength;
|
this.contentLength = contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -444,18 +431,17 @@ public class S3Object {
|
||||||
* {@link org.jclouds.aws.s3.S3Connection#getObject(String, String, org.jclouds.aws.s3.commands.options.GetObjectOptions) }
|
* {@link org.jclouds.aws.s3.S3Connection#getObject(String, String, org.jclouds.aws.s3.commands.options.GetObjectOptions) }
|
||||||
* is called with options like tail, range, or startAt.
|
* is called with options like tail, range, or startAt.
|
||||||
*
|
*
|
||||||
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
|
|
||||||
* @see GetObjectOptions
|
|
||||||
* @return the length in bytes that can be be obtained from
|
* @return the length in bytes that can be be obtained from
|
||||||
* {@link #getData()}
|
* {@link #getData()}
|
||||||
*
|
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
|
||||||
|
* @see GetObjectOptions
|
||||||
*/
|
*/
|
||||||
public long getContentLength() {
|
public long getContentLength() {
|
||||||
return contentLength;
|
return contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentRange(String contentRange) {
|
public void setContentRange(String contentRange) {
|
||||||
this.contentRange = contentRange;
|
this.contentRange = contentRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -466,7 +452,7 @@ public class S3Object {
|
||||||
* @see GetObjectOptions
|
* @see GetObjectOptions
|
||||||
*/
|
*/
|
||||||
public String getContentRange() {
|
public String getContentRange() {
|
||||||
return contentRange;
|
return contentRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,19 +24,9 @@
|
||||||
package org.jclouds.aws.s3.internal;
|
package org.jclouds.aws.s3.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import com.google.inject.Inject;
|
||||||
import java.io.FileNotFoundException;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import java.io.IOException;
|
import com.google.inject.name.Named;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
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;
|
||||||
|
@ -44,9 +34,13 @@ import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import java.io.FileNotFoundException;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import java.io.IOException;
|
||||||
import com.google.inject.name.Named;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements core Map functionality with an {@link S3Connection}
|
* Implements core Map functionality with an {@link S3Connection}
|
||||||
|
@ -55,9 +49,8 @@ import com.google.inject.name.Named;
|
||||||
* complete before throwing an exception.
|
* complete before throwing an exception.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
* @param <V>
|
* @param <V>
|
||||||
* value of the map
|
* value of the map
|
||||||
*/
|
*/
|
||||||
public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
||||||
|
|
||||||
|
@ -73,8 +66,8 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BaseS3Map(S3Connection connection, @Assisted String bucket) {
|
public BaseS3Map(S3Connection connection, @Assisted String bucket) {
|
||||||
this.connection = checkNotNull(connection, "connection");
|
this.connection = checkNotNull(connection, "connection");
|
||||||
this.bucket = checkNotNull(bucket, "bucket");
|
this.bucket = checkNotNull(bucket, "bucketName");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,38 +78,38 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
||||||
* @see S3Bucket#getContents()
|
* @see S3Bucket#getContents()
|
||||||
*/
|
*/
|
||||||
public int size() {
|
public int size() {
|
||||||
try {
|
try {
|
||||||
S3Bucket bucket = refreshBucket();
|
S3Bucket bucket = refreshBucket();
|
||||||
Set<S3Object.Metadata> contents = bucket.getContents();
|
Set<S3Object.Metadata> contents = bucket.getContents();
|
||||||
return contents.size();
|
return contents.size();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException("Error getting size of bucket"
|
throw new S3RuntimeException("Error getting size of bucketName"
|
||||||
+ bucket, e);
|
+ bucket, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] getMd5(Object value) throws IOException,
|
protected byte[] getMd5(Object value) throws IOException,
|
||||||
FileNotFoundException, InterruptedException, ExecutionException,
|
FileNotFoundException, InterruptedException, ExecutionException,
|
||||||
TimeoutException {
|
TimeoutException {
|
||||||
S3Object object = null;
|
S3Object object = null;
|
||||||
if (value instanceof S3Object) {
|
if (value instanceof S3Object) {
|
||||||
object = (S3Object) value;
|
object = (S3Object) value;
|
||||||
} 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,120 +118,119 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
||||||
* @see S3Connection#getObject(String, String)
|
* @see S3Connection#getObject(String, String)
|
||||||
*/
|
*/
|
||||||
protected Set<S3Object> getAllObjects() {
|
protected Set<S3Object> getAllObjects() {
|
||||||
Set<S3Object> objects = new HashSet<S3Object>();
|
Set<S3Object> objects = new HashSet<S3Object>();
|
||||||
Set<Future<S3Object>> futureObjects = new HashSet<Future<S3Object>>();
|
Set<Future<S3Object>> futureObjects = new HashSet<Future<S3Object>>();
|
||||||
for (String key : keySet()) {
|
for (String key : keySet()) {
|
||||||
futureObjects.add(connection.getObject(bucket, key));
|
futureObjects.add(connection.getObject(bucket, key));
|
||||||
}
|
}
|
||||||
for (Future<S3Object> futureObject : futureObjects) {
|
for (Future<S3Object> futureObject : futureObjects) {
|
||||||
S3Object object = null;
|
S3Object object = null;
|
||||||
try {
|
try {
|
||||||
object = futureObject.get(requestTimeoutMilliseconds,
|
object = futureObject.get(requestTimeoutMilliseconds,
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
} 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 %1$s:%2$s", bucket,
|
"Error getting value from bucket %1$s", bucket), e);
|
||||||
object != null ? object.getKey() : "unknown"), e);
|
}
|
||||||
}
|
if (object != S3Object.NOT_FOUND)
|
||||||
if (object != S3Object.NOT_FOUND)
|
objects.add(object);
|
||||||
objects.add(object);
|
}
|
||||||
}
|
return objects;
|
||||||
return objects;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
* <p/>
|
||||||
* Note that if value is an instance of InputStream, it will be read and
|
* Note that if value is an instance of InputStream, it will be read and
|
||||||
* closed following this method. To reuse data from InputStreams, pass
|
* closed following this method. To reuse data from InputStreams, pass
|
||||||
* {@link InputStream}s inside {@link S3Object}s
|
* {@link java.io.InputStream}s inside {@link S3Object}s
|
||||||
*/
|
*/
|
||||||
public boolean containsValue(Object value) {
|
public boolean containsValue(Object value) {
|
||||||
try {
|
try {
|
||||||
byte[] md5 = getMd5(value);
|
byte[] md5 = getMd5(value);
|
||||||
return containsMd5(md5);
|
return containsMd5(md5);
|
||||||
} 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: [%2$s] in bucket:%1$s",
|
"Error searching for ETAG of value: [%2$s] in bucketName:%1$s",
|
||||||
bucket, value), e);
|
bucket, value), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class S3RuntimeException extends RuntimeException {
|
public static class S3RuntimeException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
S3RuntimeException(String s) {
|
S3RuntimeException(String s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3RuntimeException(String s, Throwable throwable) {
|
public S3RuntimeException(String s, Throwable throwable) {
|
||||||
super(s, throwable);
|
super(s, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
try {
|
try {
|
||||||
List<Future<Boolean>> deletes = new ArrayList<Future<Boolean>>();
|
List<Future<Boolean>> deletes = new ArrayList<Future<Boolean>>();
|
||||||
for (String key : keySet()) {
|
for (String key : keySet()) {
|
||||||
deletes.add(connection.deleteObject(bucket, key));
|
deletes.add(connection.deleteObject(bucket, key));
|
||||||
}
|
}
|
||||||
for (Future<Boolean> isdeleted : deletes)
|
for (Future<Boolean> isdeleted : deletes)
|
||||||
if (!isdeleted.get(requestTimeoutMilliseconds,
|
if (!isdeleted.get(requestTimeoutMilliseconds,
|
||||||
TimeUnit.MILLISECONDS)) {
|
TimeUnit.MILLISECONDS)) {
|
||||||
throw new S3RuntimeException("failed to delete entry");
|
throw new S3RuntimeException("failed to delete entry");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException("Error clearing bucket" + bucket, e);
|
throw new S3RuntimeException("Error clearing bucketName" + bucket, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected S3Bucket refreshBucket() throws InterruptedException,
|
protected S3Bucket refreshBucket() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
S3Bucket currentBucket = connection.listBucket(bucket).get(
|
S3Bucket currentBucket = connection.listBucket(bucket).get(
|
||||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
if (currentBucket == S3Bucket.NOT_FOUND)
|
if (currentBucket == S3Bucket.NOT_FOUND)
|
||||||
throw new S3RuntimeException("bucket not found: " + bucket);
|
throw new S3RuntimeException("bucketName not found: " + bucket);
|
||||||
else
|
else
|
||||||
return currentBucket;
|
return currentBucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> keySet() {
|
public Set<String> keySet() {
|
||||||
try {
|
try {
|
||||||
Set<String> keys = new HashSet<String>();
|
Set<String> keys = new HashSet<String>();
|
||||||
for (S3Object.Metadata object : refreshBucket().getContents())
|
for (S3Object.Metadata object : refreshBucket().getContents())
|
||||||
keys.add(object.getKey());
|
keys.add(object.getKey());
|
||||||
return keys;
|
return keys;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException("Error getting keys in bucket: "
|
throw new S3RuntimeException("Error getting keys in bucketName: "
|
||||||
+ bucket, e);
|
+ bucket, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(Object key) {
|
public boolean containsKey(Object key) {
|
||||||
try {
|
try {
|
||||||
return connection.headObject(bucket, key.toString()).get(
|
return connection.headObject(bucket, key.toString()).get(
|
||||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS) != S3Object.Metadata.NOT_FOUND;
|
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS) != S3Object.Metadata.NOT_FOUND;
|
||||||
} 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 %1$s:%2$s", bucket, key), e);
|
"Error searching for %1$s:%2$s", bucket, key), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return keySet().size() == 0;
|
return keySet().size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3Bucket getBucket() {
|
public S3Bucket getBucket() {
|
||||||
try {
|
try {
|
||||||
return refreshBucket();
|
return refreshBucket();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException("Error getting bucket" + bucket, e);
|
throw new S3RuntimeException("Error getting bucketName" + bucket, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,10 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.internal;
|
package org.jclouds.aws.s3.internal;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
import org.jclouds.aws.s3.S3Context;
|
import org.jclouds.aws.s3.S3Context;
|
||||||
import org.jclouds.aws.s3.S3InputStreamMap;
|
import org.jclouds.aws.s3.S3InputStreamMap;
|
||||||
|
@ -34,22 +32,22 @@ import org.jclouds.aws.s3.S3ObjectMap;
|
||||||
import org.jclouds.lifecycle.Closer;
|
import org.jclouds.lifecycle.Closer;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import javax.annotation.Resource;
|
||||||
import com.google.inject.Injector;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses a Guice Injector to configure the objects served by S3Context methods.
|
* Uses a Guice Injector to configure the objects served by S3Context methods.
|
||||||
*
|
*
|
||||||
* @see Injector
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
* @see Injector
|
||||||
*/
|
*/
|
||||||
public class GuiceS3Context implements S3Context {
|
public class GuiceS3Context implements S3Context {
|
||||||
public interface S3ObjectMapFactory {
|
public interface S3ObjectMapFactory {
|
||||||
S3ObjectMap createMapView(String bucket);
|
S3ObjectMap createMapView(String bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface S3InputStreamMapFactory {
|
public interface S3InputStreamMapFactory {
|
||||||
S3InputStreamMap createMapView(String bucket);
|
S3InputStreamMap createMapView(String bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -61,35 +59,35 @@ public class GuiceS3Context implements S3Context {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GuiceS3Context(Injector injector, Closer closer,
|
private GuiceS3Context(Injector injector, Closer closer,
|
||||||
S3ObjectMapFactory s3ObjectMapFactory,
|
S3ObjectMapFactory s3ObjectMapFactory,
|
||||||
S3InputStreamMapFactory s3InputStreamMapFactory) {
|
S3InputStreamMapFactory s3InputStreamMapFactory) {
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
|
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
|
||||||
this.s3ObjectMapFactory = s3ObjectMapFactory;
|
this.s3ObjectMapFactory = s3ObjectMapFactory;
|
||||||
this.closer = closer;
|
this.closer = closer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public S3Connection getConnection() {
|
public S3Connection getConnection() {
|
||||||
return injector.getInstance(S3Connection.class);
|
return injector.getInstance(S3Connection.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public S3InputStreamMap createInputStreamMap(String bucket) {
|
public S3InputStreamMap createInputStreamMap(String bucket) {
|
||||||
getConnection().putBucketIfNotExists(bucket);
|
getConnection().putBucketIfNotExists(bucket);
|
||||||
return s3InputStreamMapFactory.createMapView(bucket);
|
return s3InputStreamMapFactory.createMapView(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public S3ObjectMap createS3ObjectMap(String bucket) {
|
public S3ObjectMap createS3ObjectMap(String bucket) {
|
||||||
getConnection().putBucketIfNotExists(bucket);
|
getConnection().putBucketIfNotExists(bucket);
|
||||||
return s3ObjectMapFactory.createMapView(bucket);
|
return s3ObjectMapFactory.createMapView(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,11 +96,11 @@ public class GuiceS3Context implements S3Context {
|
||||||
* @see Closer
|
* @see Closer
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
closer.close();
|
closer.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error(e, "error closing content");
|
logger.error(e, "error closing content");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,42 +23,35 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.internal;
|
package org.jclouds.aws.s3.internal;
|
||||||
|
|
||||||
import java.io.File;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.io.InputStream;
|
import com.google.inject.Inject;
|
||||||
import java.util.ArrayList;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
import org.jclouds.aws.s3.S3InputStreamMap;
|
import org.jclouds.aws.s3.S3InputStreamMap;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import java.io.File;
|
||||||
import com.google.inject.Inject;
|
import java.io.InputStream;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map representation of a live connection to S3. All put operations will result
|
* Map representation of a live connection to S3. All put operations will result
|
||||||
* in Md5 calculation. If this is not desired, use {@link LiveS3ObjectMap}
|
* in Md5 calculation. If this is not desired, use {@link LiveS3ObjectMap}
|
||||||
* instead.
|
* instead.
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see S3Connection
|
* @see S3Connection
|
||||||
* @see BaseS3Map
|
* @see BaseS3Map
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
*/
|
||||||
public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
S3InputStreamMap {
|
S3InputStreamMap {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public LiveS3InputStreamMap(S3Connection connection, @Assisted String bucket) {
|
public LiveS3InputStreamMap(S3Connection connection, @Assisted String bucket) {
|
||||||
super(connection, bucket);
|
super(connection, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,15 +60,15 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see S3Connection#getObject(String, String)
|
* @see S3Connection#getObject(String, String)
|
||||||
*/
|
*/
|
||||||
public InputStream get(Object o) {
|
public InputStream get(Object o) {
|
||||||
try {
|
try {
|
||||||
return (InputStream) (connection.getObject(bucket, o.toString())
|
return (InputStream) (connection.getObject(bucket, o.toString())
|
||||||
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS))
|
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS))
|
||||||
.getData();
|
.getData();
|
||||||
} 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 %1$s:%2$s", bucket, o), e);
|
"Error geting object %1$s:%2$s", bucket, o), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,16 +77,16 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see S3Connection#deleteObject(String, String)
|
* @see S3Connection#deleteObject(String, String)
|
||||||
*/
|
*/
|
||||||
public InputStream remove(Object o) {
|
public InputStream remove(Object o) {
|
||||||
InputStream old = get(o);
|
InputStream old = get(o);
|
||||||
try {
|
try {
|
||||||
connection.deleteObject(bucket, o.toString()).get(
|
connection.deleteObject(bucket, o.toString()).get(
|
||||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
} 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 %1$s:%2$s", bucket, o), e);
|
"Error removing object %1$s:%2$s", bucket, o), e);
|
||||||
}
|
}
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,12 +95,12 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #getAllObjects()
|
* @see #getAllObjects()
|
||||||
*/
|
*/
|
||||||
public Collection<InputStream> values() {
|
public Collection<InputStream> values() {
|
||||||
Collection<InputStream> values = new LinkedList<InputStream>();
|
Collection<InputStream> values = new LinkedList<InputStream>();
|
||||||
Set<S3Object> objects = getAllObjects();
|
Set<S3Object> objects = getAllObjects();
|
||||||
for (S3Object object : objects) {
|
for (S3Object object : objects) {
|
||||||
values.add((InputStream) object.getData());
|
values.add((InputStream) object.getData());
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,43 +109,40 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #getAllObjects()
|
* @see #getAllObjects()
|
||||||
*/
|
*/
|
||||||
public Set<Map.Entry<String, InputStream>> entrySet() {
|
public Set<Map.Entry<String, InputStream>> entrySet() {
|
||||||
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
|
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
|
||||||
for (S3Object object : getAllObjects()) {
|
for (S3Object object : getAllObjects()) {
|
||||||
entrySet.add(new Entry(object.getKey(), (InputStream) object
|
entrySet.add(new Entry(object.getKey(), (InputStream) object
|
||||||
.getData()));
|
.getData()));
|
||||||
}
|
}
|
||||||
return entrySet;
|
return entrySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public class Entry implements java.util.Map.Entry<String, InputStream> {
|
public class Entry implements java.util.Map.Entry<String, InputStream> {
|
||||||
|
|
||||||
private InputStream value;
|
private InputStream value;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
Entry(String key, InputStream value) {
|
Entry(String key, InputStream value) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getValue() {
|
public InputStream getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* @see LiveS3InputStreamMap#put(String, InputStream)
|
* @see LiveS3InputStreamMap#put(String, InputStream)
|
||||||
*/
|
*/
|
||||||
public InputStream setValue(InputStream value) {
|
public InputStream setValue(InputStream value) {
|
||||||
return put(key, value);
|
return put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +152,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putAllInternal(Map)
|
* @see #putAllInternal(Map)
|
||||||
*/
|
*/
|
||||||
public void putAll(Map<? extends String, ? extends InputStream> map) {
|
public void putAll(Map<? extends String, ? extends InputStream> map) {
|
||||||
putAllInternal(map);
|
putAllInternal(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,7 +161,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putAllInternal(Map)
|
* @see #putAllInternal(Map)
|
||||||
*/
|
*/
|
||||||
public void putAllBytes(Map<? extends String, ? extends byte[]> map) {
|
public void putAllBytes(Map<? extends String, ? extends byte[]> map) {
|
||||||
putAllInternal(map);
|
putAllInternal(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,7 +170,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putAllInternal(Map)
|
* @see #putAllInternal(Map)
|
||||||
*/
|
*/
|
||||||
public void putAllFiles(Map<? extends String, ? extends File> map) {
|
public void putAllFiles(Map<? extends String, ? extends File> map) {
|
||||||
putAllInternal(map);
|
putAllInternal(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +179,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putAllInternal(Map)
|
* @see #putAllInternal(Map)
|
||||||
*/
|
*/
|
||||||
public void putAllStrings(Map<? extends String, ? extends String> map) {
|
public void putAllStrings(Map<? extends String, ? extends String> map) {
|
||||||
putAllInternal(map);
|
putAllInternal(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,22 +191,22 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void putAllInternal(Map<? extends String, ? extends Object> map) {
|
void putAllInternal(Map<? extends String, ? extends Object> map) {
|
||||||
try {
|
try {
|
||||||
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
|
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
|
||||||
for (String key : map.keySet()) {
|
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
|
||||||
S3Object object = new S3Object(key);
|
S3Object object = new S3Object(entry.getKey());
|
||||||
object.setData(map.get(key));
|
object.setData(entry.getValue());
|
||||||
object.generateMd5();
|
object.generateMd5();
|
||||||
puts.add(connection.putObject(bucket, object));
|
puts.add(connection.putObject(bucket, object));
|
||||||
}
|
}
|
||||||
for (Future<byte[]> put : puts)
|
for (Future<byte[]> put : puts)
|
||||||
// this will throw an exception if there was a problem
|
// this will throw an exception if there was a problem
|
||||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException("Error putting into bucket" + bucket,
|
throw new S3RuntimeException("Error putting into bucketName" + bucket,
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,7 +215,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putInternal(String, Object)
|
* @see #putInternal(String, Object)
|
||||||
*/
|
*/
|
||||||
public InputStream putString(String key, String value) {
|
public InputStream putString(String key, String value) {
|
||||||
return putInternal(key, value);
|
return putInternal(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,7 +224,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putInternal(String, Object)
|
* @see #putInternal(String, Object)
|
||||||
*/
|
*/
|
||||||
public InputStream putFile(String key, File value) {
|
public InputStream putFile(String key, File value) {
|
||||||
return putInternal(key, value);
|
return putInternal(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,7 +233,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putInternal(String, Object)
|
* @see #putInternal(String, Object)
|
||||||
*/
|
*/
|
||||||
public InputStream putBytes(String key, byte[] value) {
|
public InputStream putBytes(String key, byte[] value) {
|
||||||
return putInternal(key, value);
|
return putInternal(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,11 +242,10 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
* @see #putInternal(String, Object)
|
* @see #putInternal(String, Object)
|
||||||
*/
|
*/
|
||||||
public InputStream put(String key, InputStream value) {
|
public InputStream put(String key, InputStream value) {
|
||||||
return putInternal(key, value);
|
return putInternal(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* calculates md5 before adding the object to s3. As a side-effect of this,
|
* calculates md5 before adding the object to s3. As a side-effect of this,
|
||||||
* the content will be copied into a byte []. *
|
* the content will be copied into a byte []. *
|
||||||
*
|
*
|
||||||
|
@ -264,19 +253,19 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
InputStream putInternal(String s, Object o) {
|
InputStream putInternal(String s, Object o) {
|
||||||
S3Object object = new S3Object(s);
|
S3Object object = new S3Object(s);
|
||||||
try {
|
try {
|
||||||
InputStream returnVal = containsKey(s) ? get(s) : null;
|
InputStream returnVal = containsKey(s) ? get(s) : null;
|
||||||
object.setData(o);
|
object.setData(o);
|
||||||
object.generateMd5();
|
object.generateMd5();
|
||||||
connection.putObject(bucket, object).get(
|
connection.putObject(bucket, object).get(
|
||||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
return returnVal;
|
return returnVal;
|
||||||
} 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 %1$s:%2$s", bucket, object), e);
|
"Error adding object %1$s:%2$s", bucket, object), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,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(
|
throw new S3RuntimeException(
|
||||||
String.format("Error putting object %1$s:%2$s%n%1$s",
|
String.format("Error putting object %1$s:%2$s%n%3$s",
|
||||||
bucket, key, value), e);
|
bucket, key, value), e);
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
|
@ -149,7 +149,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
|
||||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new S3RuntimeException("Error putting into bucket" + bucket,
|
throw new S3RuntimeException("Error putting into bucketName" + bucket,
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* This package contains an Amazon S3 client implemented by {@link HttpFutureCommand} commands.
|
* This package contains an Amazon S3 client implemented by {@link org.jclouds.http.HttpFutureCommandClient} commands.
|
||||||
*
|
*
|
||||||
* @see <a href="http://aws.amazon.com/s3"/>
|
* @see <a href="http://aws.amazon.com/s3"/>
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
|
|
@ -25,17 +25,6 @@ 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;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||||
import org.bouncycastle.crypto.digests.MD5Digest;
|
import org.bouncycastle.crypto.digests.MD5Digest;
|
||||||
|
@ -46,205 +35,211 @@ import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption, Hashing, and IO Utilities needed to sign and verify S3 requests
|
* Encryption, Hashing, and IO Utilities needed to sign and verify S3 requests
|
||||||
* and responses.
|
* and responses.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class S3Utils extends Utils {
|
public class S3Utils extends Utils {
|
||||||
|
|
||||||
private static final Pattern IP_PATTERN = Pattern
|
private static final Pattern IP_PATTERN = Pattern
|
||||||
.compile("b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)"
|
.compile("b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)"
|
||||||
+ "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b");
|
+ "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b");
|
||||||
|
|
||||||
public static String validateBucketName(String bucketName) {
|
public static String validateBucketName(String bucketName) {
|
||||||
checkNotNull(bucketName, "bucketName");
|
checkNotNull(bucketName, "bucketName");
|
||||||
checkArgument(bucketName.matches("^[a-z0-9].*"),
|
checkArgument(bucketName.matches("^[a-z0-9].*"),
|
||||||
"bucket name must start with a number or letter");
|
"bucketName name must start with a number or letter");
|
||||||
checkArgument(
|
checkArgument(
|
||||||
bucketName.matches("^[-_.a-z0-9]+"),
|
bucketName.matches("^[-_.a-z0-9]+"),
|
||||||
"bucket name can only contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)");
|
"bucketName name can only contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)");
|
||||||
checkArgument(bucketName.length() > 2 && bucketName.length() < 256,
|
checkArgument(bucketName.length() > 2 && bucketName.length() < 256,
|
||||||
"bucket name must be between 3 and 255 characters long");
|
"bucketName name must be between 3 and 255 characters long");
|
||||||
checkArgument(!IP_PATTERN.matcher(bucketName).matches(),
|
checkArgument(!IP_PATTERN.matcher(bucketName).matches(),
|
||||||
"bucket name cannot be ip address style");
|
"bucketName name cannot be ip address style");
|
||||||
return bucketName;
|
return bucketName;
|
||||||
}
|
}
|
||||||
|
|
||||||
static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2',
|
static final byte[] HEX_CHAR_TABLE = {(byte) '0', (byte) '1', (byte) '2',
|
||||||
(byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
|
(byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
|
||||||
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
|
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
|
||||||
(byte) 'd', (byte) 'e', (byte) 'f' };
|
(byte) 'd', (byte) 'e', (byte) 'f'};
|
||||||
|
|
||||||
public static String toHexString(byte[] raw)
|
public static String toHexString(byte[] raw)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
byte[] hex = new byte[2 * raw.length];
|
byte[] hex = new byte[2 * raw.length];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (byte b : raw) {
|
for (byte b : raw) {
|
||||||
int v = b & 0xFF;
|
int v = b & 0xFF;
|
||||||
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
|
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
|
||||||
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
|
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
|
||||||
}
|
}
|
||||||
return new String(hex, "ASCII");
|
return new String(hex, "ASCII");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long calculateSize(Object data) {
|
public static long calculateSize(Object data) {
|
||||||
long size = -1;
|
long size = -1;
|
||||||
if (data instanceof byte[]) {
|
if (data instanceof byte[]) {
|
||||||
size = ((byte[]) data).length;
|
size = ((byte[]) data).length;
|
||||||
} else if (data instanceof String) {
|
} else if (data instanceof String) {
|
||||||
size = ((String) data).length();
|
size = ((String) data).length();
|
||||||
} else if (data instanceof File) {
|
} else if (data instanceof File) {
|
||||||
size = ((File) data).length();
|
size = ((File) data).length();
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static byte[] md5(Object data) throws IOException {
|
public static byte[] md5(Object data) throws IOException {
|
||||||
checkNotNull(data, "data must be set before calling generateMd5()");
|
checkNotNull(data, "data must be set before calling generateMd5()");
|
||||||
byte[] md5 = null;
|
byte[] md5 = null;
|
||||||
if (data == null || data instanceof byte[]) {
|
if (data == null) {
|
||||||
md5 = S3Utils.md5((byte[]) data);
|
} else if (data instanceof byte[]) {
|
||||||
} else if (data instanceof String) {
|
md5 = S3Utils.md5((byte[]) data);
|
||||||
md5 = S3Utils.md5(((String) data).getBytes());
|
} else if (data instanceof String) {
|
||||||
} else if (data instanceof File) {
|
md5 = S3Utils.md5(((String) data).getBytes());
|
||||||
md5 = S3Utils.md5(((File) data));
|
} else if (data instanceof File) {
|
||||||
} else {
|
md5 = S3Utils.md5(((File) data));
|
||||||
throw new UnsupportedOperationException("Content not supported "
|
} else {
|
||||||
+ data.getClass());
|
throw new UnsupportedOperationException("Content not supported "
|
||||||
}
|
+ data.getClass());
|
||||||
return md5;
|
}
|
||||||
|
return md5;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] fromHexString(String hex) {
|
public static byte[] fromHexString(String hex) {
|
||||||
byte[] bytes = new byte[hex.length() / 2];
|
byte[] bytes = new byte[hex.length() / 2];
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
|
bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
|
||||||
16);
|
16);
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String hmacSha1Base64(String toEncode, byte[] key)
|
public static String hmacSha1Base64(String toEncode, byte[] key)
|
||||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||||
InvalidKeyException {
|
InvalidKeyException {
|
||||||
HMac hmac = new HMac(new SHA1Digest());
|
HMac hmac = new HMac(new SHA1Digest());
|
||||||
byte[] resBuf = new byte[hmac.getMacSize()];
|
byte[] resBuf = new byte[hmac.getMacSize()];
|
||||||
byte[] plainBytes = toEncode.getBytes();
|
byte[] plainBytes = toEncode.getBytes();
|
||||||
byte[] keyBytes = key;
|
byte[] keyBytes = key;
|
||||||
hmac.init(new KeyParameter(keyBytes));
|
hmac.init(new KeyParameter(keyBytes));
|
||||||
hmac.update(plainBytes, 0, plainBytes.length);
|
hmac.update(plainBytes, 0, plainBytes.length);
|
||||||
hmac.doFinal(resBuf, 0);
|
hmac.doFinal(resBuf, 0);
|
||||||
return toBase64String(resBuf);
|
return toBase64String(resBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String md5Hex(byte[] toEncode)
|
public static String md5Hex(byte[] toEncode)
|
||||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||||
InvalidKeyException, UnsupportedEncodingException {
|
InvalidKeyException, UnsupportedEncodingException {
|
||||||
byte[] resBuf = md5(toEncode);
|
byte[] resBuf = md5(toEncode);
|
||||||
return toHexString(resBuf);
|
return toHexString(resBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String md5Base64(byte[] toEncode)
|
public static String md5Base64(byte[] toEncode)
|
||||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||||
InvalidKeyException {
|
InvalidKeyException {
|
||||||
byte[] resBuf = md5(toEncode);
|
byte[] resBuf = md5(toEncode);
|
||||||
return toBase64String(resBuf);
|
return toBase64String(resBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toBase64String(byte[] resBuf) {
|
public static String toBase64String(byte[] resBuf) {
|
||||||
return new String(Base64.encode(resBuf));
|
return new String(Base64.encode(resBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] md5(byte[] plainBytes) {
|
public static byte[] md5(byte[] plainBytes) {
|
||||||
MD5Digest md5 = new MD5Digest();
|
MD5Digest md5 = new MD5Digest();
|
||||||
byte[] resBuf = new byte[md5.getDigestSize()];
|
byte[] resBuf = new byte[md5.getDigestSize()];
|
||||||
md5.update(plainBytes, 0, plainBytes.length);
|
md5.update(plainBytes, 0, plainBytes.length);
|
||||||
md5.doFinal(resBuf, 0);
|
md5.doFinal(resBuf, 0);
|
||||||
return resBuf;
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] md5(File toEncode) throws IOException {
|
public static byte[] md5(File toEncode) throws IOException {
|
||||||
MD5Digest md5 = new MD5Digest();
|
MD5Digest md5 = new MD5Digest();
|
||||||
byte[] resBuf = new byte[md5.getDigestSize()];
|
byte[] resBuf = new byte[md5.getDigestSize()];
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int numRead = -1;
|
int numRead = -1;
|
||||||
InputStream i = new FileInputStream(toEncode);
|
InputStream i = new FileInputStream(toEncode);
|
||||||
try {
|
try {
|
||||||
do {
|
do {
|
||||||
numRead = i.read(buffer);
|
numRead = i.read(buffer);
|
||||||
if (numRead > 0) {
|
if (numRead > 0) {
|
||||||
md5.update(buffer, 0, numRead);
|
md5.update(buffer, 0, numRead);
|
||||||
}
|
}
|
||||||
} while (numRead != -1);
|
} while (numRead != -1);
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(i);
|
IOUtils.closeQuietly(i);
|
||||||
}
|
}
|
||||||
md5.doFinal(resBuf, 0);
|
md5.doFinal(resBuf, 0);
|
||||||
return resBuf;
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Md5InputStreamResult generateMd5Result(InputStream toEncode)
|
public static Md5InputStreamResult generateMd5Result(InputStream toEncode)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
MD5Digest md5 = new MD5Digest();
|
MD5Digest md5 = new MD5Digest();
|
||||||
byte[] resBuf = new byte[md5.getDigestSize()];
|
byte[] resBuf = new byte[md5.getDigestSize()];
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
long length = 0;
|
long length = 0;
|
||||||
int numRead = -1;
|
int numRead = -1;
|
||||||
try {
|
try {
|
||||||
do {
|
do {
|
||||||
numRead = toEncode.read(buffer);
|
numRead = toEncode.read(buffer);
|
||||||
if (numRead > 0) {
|
if (numRead > 0) {
|
||||||
length += numRead;
|
length += numRead;
|
||||||
md5.update(buffer, 0, numRead);
|
md5.update(buffer, 0, numRead);
|
||||||
out.write(buffer, 0, numRead);
|
out.write(buffer, 0, numRead);
|
||||||
}
|
}
|
||||||
} while (numRead != -1);
|
} while (numRead != -1);
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(toEncode);
|
out.close();
|
||||||
}
|
IOUtils.closeQuietly(toEncode);
|
||||||
md5.doFinal(resBuf, 0);
|
}
|
||||||
return new Md5InputStreamResult(out.toByteArray(), resBuf, length);
|
md5.doFinal(resBuf, 0);
|
||||||
|
return new Md5InputStreamResult(out.toByteArray(), resBuf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Md5InputStreamResult {
|
public static class Md5InputStreamResult {
|
||||||
public final byte[] data;
|
public final byte[] data;
|
||||||
public final byte[] md5;
|
public final byte[] md5;
|
||||||
public final long length;
|
public final long length;
|
||||||
|
|
||||||
Md5InputStreamResult(byte[] data, byte[] md5, long length) {
|
Md5InputStreamResult(byte[] data, byte[] md5, long length) {
|
||||||
this.data = checkNotNull(data, "data");
|
this.data = checkNotNull(data, "data");
|
||||||
this.md5 = checkNotNull(md5, "md5");
|
this.md5 = checkNotNull(md5, "md5");
|
||||||
checkArgument(length >= 0, "length cannot me negative");
|
checkArgument(length >= 0, "length cannot me negative");
|
||||||
this.length = length;
|
this.length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getContentAsStringAndClose(S3Object object)
|
public static String getContentAsStringAndClose(S3Object object)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
checkNotNull(object, "s3Object");
|
checkNotNull(object, "s3Object");
|
||||||
checkNotNull(object.getData(), "s3Object.content");
|
checkNotNull(object.getData(), "s3Object.content");
|
||||||
Object o = object.getData();
|
Object o = object.getData();
|
||||||
|
|
||||||
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;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Object type not supported: "
|
throw new IllegalArgumentException("Object type not supported: "
|
||||||
+ o.getClass().getName());
|
+ o.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import com.google.inject.Inject;
|
||||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
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;
|
||||||
|
@ -33,16 +33,14 @@ 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 com.google.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the following XML document:
|
* Parses the following XML document:
|
||||||
* <p/>
|
* <p/>
|
||||||
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
|
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
|
||||||
*
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
*/
|
||||||
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
||||||
private S3Bucket s3Bucket;
|
private S3Bucket s3Bucket;
|
||||||
|
@ -54,72 +52,72 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ListBucketHandler(DateService dateParser) {
|
public ListBucketHandler(DateService dateParser) {
|
||||||
this.dateParser = 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(checkNotNull(bucketName, "bucketName"));
|
this.s3Bucket = new S3Bucket(checkNotNull(bucketName, "bucketName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean inCommonPrefixes;
|
private boolean inCommonPrefixes;
|
||||||
|
|
||||||
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("CommonPrefixes")) {
|
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")) {
|
||||||
currentOwner = new CanonicalUser(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("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")) {// bucketName 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();
|
||||||
if (inCommonPrefixes)
|
if (inCommonPrefixes)
|
||||||
s3Bucket.getCommonPrefixes().add(prefix);
|
s3Bucket.getCommonPrefixes().add(prefix);
|
||||||
else
|
else
|
||||||
s3Bucket.setPrefix(prefix);
|
s3Bucket.setPrefix(prefix);
|
||||||
} else if (qName.equals("Delimiter")) {
|
} else if (qName.equals("Delimiter")) {
|
||||||
if (!currentText.toString().equals(""))
|
if (!currentText.toString().equals(""))
|
||||||
s3Bucket.setDelimiter(currentText.toString().trim());
|
s3Bucket.setDelimiter(currentText.toString().trim());
|
||||||
} else if (qName.equals("Marker")) {
|
} else if (qName.equals("Marker")) {
|
||||||
if (!currentText.toString().equals(""))
|
if (!currentText.toString().equals(""))
|
||||||
s3Bucket.setMarker(currentText.toString());
|
s3Bucket.setMarker(currentText.toString());
|
||||||
} else if (qName.equals("MaxKeys")) {
|
} else if (qName.equals("MaxKeys")) {
|
||||||
s3Bucket.setMaxKeys(Long.parseLong(currentText.toString()));
|
s3Bucket.setMaxKeys(Long.parseLong(currentText.toString()));
|
||||||
} else if (qName.equals("IsTruncated")) {
|
} else if (qName.equals("IsTruncated")) {
|
||||||
boolean isTruncated = Boolean.parseBoolean(currentText.toString());
|
boolean isTruncated = Boolean.parseBoolean(currentText.toString());
|
||||||
s3Bucket.setComplete(!isTruncated);
|
s3Bucket.setTruncated(isTruncated);
|
||||||
}
|
}
|
||||||
currentText = new StringBuilder();
|
currentText = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void characters(char ch[], int start, int length) {
|
public void characters(char ch[], int start, int length) {
|
||||||
currentText.append(ch, start, length);
|
currentText.append(ch, start, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.aws.s3.domain.S3Error;
|
import org.jclouds.aws.s3.domain.S3Error;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import java.util.List;
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates Parsers needed to interpret S3 Server messages. This class uses guice
|
* Creates Parsers needed to interpret S3 Server messages. This class uses guice
|
||||||
|
@ -48,18 +47,18 @@ public class S3ParserFactory {
|
||||||
|
|
||||||
@VisibleForTesting
|
@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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Provider<ListAllMyBucketsHandler> ListAllMyBucketsHandlerprovider;
|
Provider<ListAllMyBucketsHandler> ListAllMyBucketsHandlerprovider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a parser used to handle {@link ListOwnedBuckets} responses
|
* @return a parser used to handle {@link org.jclouds.aws.s3.commands.ListOwnedBuckets} responses
|
||||||
*/
|
*/
|
||||||
public ParseSax<List<S3Bucket.Metadata>> createListBucketsParser() {
|
public ParseSax<List<S3Bucket.Metadata>> createListBucketsParser() {
|
||||||
return parseListAllMyBucketsFactory
|
return parseListAllMyBucketsFactory
|
||||||
.create(ListAllMyBucketsHandlerprovider.get());
|
.create(ListAllMyBucketsHandlerprovider.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -69,10 +68,10 @@ public class S3ParserFactory {
|
||||||
Provider<ListBucketHandler> ListBucketHandlerprovider;
|
Provider<ListBucketHandler> ListBucketHandlerprovider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a parser used to handle {@link ListBucket} responses
|
* @return a parser used to handle {@link org.jclouds.aws.s3.commands.ListBucket} responses
|
||||||
*/
|
*/
|
||||||
public ParseSax<S3Bucket> createListBucketParser() {
|
public ParseSax<S3Bucket> createListBucketParser() {
|
||||||
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
|
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -82,10 +81,10 @@ public class S3ParserFactory {
|
||||||
Provider<CopyObjectHandler> copyObjectHandlerProvider;
|
Provider<CopyObjectHandler> copyObjectHandlerProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a parser used to handle {@link CopyObject} responses
|
* @return a parser used to handle {@link org.jclouds.aws.s3.commands.CopyObject} responses
|
||||||
*/
|
*/
|
||||||
public ParseSax<S3Object.Metadata> createCopyObjectParser() {
|
public ParseSax<S3Object.Metadata> createCopyObjectParser() {
|
||||||
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
|
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -98,7 +97,7 @@ public class S3ParserFactory {
|
||||||
* @return a parser used to handle error conditions.
|
* @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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -35,7 +35,7 @@ import java.util.concurrent.Executors;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.PerformanceTest")
|
@Test(groups = "performance", sequential = true, testName = "s3.PerformanceTest")
|
||||||
public class PerformanceTest {
|
public class PerformanceTest {
|
||||||
protected static int LOOP_COUNT = 1000;
|
protected static int LOOP_COUNT = 1000;
|
||||||
protected ExecutorService exec;
|
protected ExecutorService exec;
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.internal.BaseS3Map;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Parameters;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public abstract class BaseS3MapIntegrationTest<T> extends S3IntegrationTest {
|
||||||
|
|
||||||
|
public abstract void testPutAll();
|
||||||
|
|
||||||
|
public abstract void testEntrySet() throws IOException;
|
||||||
|
|
||||||
|
public abstract void testValues() throws IOException;
|
||||||
|
|
||||||
|
protected BaseS3Map<T> map;
|
||||||
|
protected Map<String, String> fiveStrings = ImmutableMap.of("one", "apple",
|
||||||
|
"two", "bear", "three", "candy", "four", "dogma", "five", "emma");
|
||||||
|
protected Map<String, byte[]> fiveBytes = ImmutableMap.of("one", "apple"
|
||||||
|
.getBytes(), "two", "bear".getBytes(), "three", "candy".getBytes(),
|
||||||
|
"four", "dogma".getBytes(), "five", "emma".getBytes());
|
||||||
|
protected Map<String, InputStream> fiveInputs;
|
||||||
|
protected Map<String, File> fiveFiles;
|
||||||
|
String tmpDirectory;
|
||||||
|
|
||||||
|
@BeforeMethod(dependsOnMethods = "setUpBucket", groups = {"integration", "live"})
|
||||||
|
@Parameters({"basedir"})
|
||||||
|
protected void setUpTempDir(String basedir) throws InterruptedException,
|
||||||
|
ExecutionException, FileNotFoundException, IOException,
|
||||||
|
TimeoutException {
|
||||||
|
tmpDirectory = basedir + File.separator + "target" + File.separator
|
||||||
|
+ "testFiles" + File.separator + getClass().getSimpleName();
|
||||||
|
new File(tmpDirectory).mkdirs();
|
||||||
|
|
||||||
|
fiveFiles = ImmutableMap.of("one", new File(tmpDirectory, "apple"),
|
||||||
|
"two", new File(tmpDirectory, "bear"), "three", new File(
|
||||||
|
tmpDirectory, "candy"), "four", new File(tmpDirectory,
|
||||||
|
"dogma"), "five", new File(tmpDirectory, "emma"));
|
||||||
|
|
||||||
|
for (File file : fiveFiles.values()) {
|
||||||
|
IOUtils.write(file.getName(), new FileOutputStream(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"),
|
||||||
|
"two", IOUtils.toInputStream("bear"), "three", IOUtils
|
||||||
|
.toInputStream("candy"), "four", IOUtils
|
||||||
|
.toInputStream("dogma"), "five", IOUtils
|
||||||
|
.toInputStream("emma"));
|
||||||
|
map = createMap(context, bucketName);
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract BaseS3Map<T> createMap(S3Context context, String bucket);
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testClear() {
|
||||||
|
map.clear();
|
||||||
|
assertEquals(map.size(), 0);
|
||||||
|
putString("one", "apple");
|
||||||
|
assertEquals(map.size(), 1);
|
||||||
|
map.clear();
|
||||||
|
assertEquals(map.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public abstract void testRemove() throws IOException;
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testKeySet() {
|
||||||
|
assertEquals(map.keySet().size(), 0);
|
||||||
|
putString("one", "two");
|
||||||
|
assertEquals(map.keySet(), ImmutableSet.of("one"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testContainsKey() {
|
||||||
|
assert !map.containsKey("one");
|
||||||
|
putString("one", "apple");
|
||||||
|
assert map.containsKey("one");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testIsEmpty() {
|
||||||
|
assert map.isEmpty();
|
||||||
|
putString("one", "apple");
|
||||||
|
assert !map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected void putString(String key, String value);
|
||||||
|
|
||||||
|
protected void fourLeftRemovingOne() {
|
||||||
|
map.remove("one");
|
||||||
|
assertEquals(map.size(), 4);
|
||||||
|
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
||||||
|
ImmutableSet.of("two", "three", "four", "five")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public abstract void testPut() throws IOException;
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testGetBucket() {
|
||||||
|
assertEquals(map.getBucket().getName(), bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,156 +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;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.internal.BaseS3Map;
|
|
||||||
import org.testng.annotations.AfterMethod;
|
|
||||||
import org.testng.annotations.BeforeMethod;
|
|
||||||
import org.testng.annotations.Parameters;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
|
|
||||||
public abstract class BaseS3MapTest<T> extends S3IntegrationTest {
|
|
||||||
|
|
||||||
public abstract void testPutAll();
|
|
||||||
|
|
||||||
public abstract void testEntrySet() throws IOException;
|
|
||||||
|
|
||||||
public abstract void testValues() throws IOException;
|
|
||||||
|
|
||||||
protected BaseS3Map<T> map;
|
|
||||||
protected Map<String, String> fiveStrings = ImmutableMap.of("one", "apple",
|
|
||||||
"two", "bear", "three", "candy", "four", "dogma", "five", "emma");
|
|
||||||
protected Map<String, byte[]> fiveBytes = ImmutableMap.of("one", "apple"
|
|
||||||
.getBytes(), "two", "bear".getBytes(), "three", "candy".getBytes(),
|
|
||||||
"four", "dogma".getBytes(), "five", "emma".getBytes());
|
|
||||||
protected Map<String, InputStream> fiveInputs;
|
|
||||||
protected Map<String, File> fiveFiles;
|
|
||||||
String tmpDirectory;
|
|
||||||
private String bucket;
|
|
||||||
|
|
||||||
@BeforeMethod
|
|
||||||
@Parameters( { "basedir" })
|
|
||||||
protected void setUpTempDir(String basedir) throws InterruptedException,
|
|
||||||
ExecutionException, FileNotFoundException, IOException,
|
|
||||||
TimeoutException {
|
|
||||||
tmpDirectory = basedir + File.separator + "target" + File.separator
|
|
||||||
+ "testFiles" + File.separator + getClass().getSimpleName();
|
|
||||||
new File(tmpDirectory).mkdirs();
|
|
||||||
|
|
||||||
fiveFiles = ImmutableMap.of("one", new File(tmpDirectory, "apple"),
|
|
||||||
"two", new File(tmpDirectory, "bear"), "three", new File(
|
|
||||||
tmpDirectory, "candy"), "four", new File(tmpDirectory,
|
|
||||||
"dogma"), "five", new File(tmpDirectory, "emma"));
|
|
||||||
|
|
||||||
for (File file : fiveFiles.values()) {
|
|
||||||
IOUtils.write(file.getName(), new FileOutputStream(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"),
|
|
||||||
"two", IOUtils.toInputStream("bear"), "three", IOUtils
|
|
||||||
.toInputStream("candy"), "four", IOUtils
|
|
||||||
.toInputStream("dogma"), "five", IOUtils
|
|
||||||
.toInputStream("emma"));
|
|
||||||
bucket = (bucketPrefix + ".mimi").toLowerCase();
|
|
||||||
client.putBucketIfNotExists(bucket).get(10, TimeUnit.SECONDS);
|
|
||||||
map = createMap(context, bucket);
|
|
||||||
map.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract BaseS3Map<T> createMap(S3Context context, String bucket);
|
|
||||||
|
|
||||||
@AfterMethod
|
|
||||||
public void tearDown() {
|
|
||||||
map.clear();
|
|
||||||
map = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testClear() {
|
|
||||||
map.clear();
|
|
||||||
assertEquals(map.size(), 0);
|
|
||||||
putString("one", "apple");
|
|
||||||
assertEquals(map.size(), 1);
|
|
||||||
map.clear();
|
|
||||||
assertEquals(map.size(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public abstract void testRemove() throws IOException;
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testKeySet() {
|
|
||||||
assertEquals(map.keySet().size(), 0);
|
|
||||||
putString("one", "two");
|
|
||||||
assertEquals(map.keySet(), ImmutableSet.of("one"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testContainsKey() {
|
|
||||||
assert !map.containsKey("one");
|
|
||||||
putString("one", "apple");
|
|
||||||
assert map.containsKey("one");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testIsEmpty() {
|
|
||||||
assert map.isEmpty();
|
|
||||||
putString("one", "apple");
|
|
||||||
assert !map.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected void putString(String key, String value);
|
|
||||||
|
|
||||||
protected void fourLeftRemovingOne() {
|
|
||||||
map.remove("one");
|
|
||||||
assertEquals(map.size(), 4);
|
|
||||||
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
|
||||||
ImmutableSet.of("two", "three", "four", "five")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public abstract void testPut() throws IOException;
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testGetBucket() {
|
|
||||||
assertEquals(map.getBucket().getName(), bucket);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.Optional;
|
||||||
|
import org.testng.annotations.Parameters;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests connection by listing all the buckets and their size
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(testName = "s3.S3ConnectionIntegrationTest")
|
||||||
|
public class S3ConnectionIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
|
@Test(groups = {"integration"})
|
||||||
|
void testListBuckets() throws Exception {
|
||||||
|
List<S3Bucket.Metadata> myBuckets = client.listOwnedBuckets().get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
for (S3Bucket.Metadata bucket : myBuckets) {
|
||||||
|
context.createInputStreamMap(bucket.getName()).size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String sysHttpStreamUrl = System
|
||||||
|
.getProperty("jclouds.s3.httpstream.url");
|
||||||
|
private static final String sysHttpStreamMd5 = System
|
||||||
|
.getProperty("jclouds.s3.httpstream.md5");
|
||||||
|
|
||||||
|
@Test(groups = {"integration"})
|
||||||
|
@Parameters({"jclouds.s3.httpstream.url", "jclouds.s3.httpstream.md5"})
|
||||||
|
public void testCopyUrl(@Optional String httpStreamUrl,
|
||||||
|
@Optional String httpStreamMd5) throws Exception {
|
||||||
|
httpStreamUrl = checkNotNull(httpStreamUrl != null ? httpStreamUrl
|
||||||
|
: sysHttpStreamUrl, "httpStreamUrl");
|
||||||
|
|
||||||
|
httpStreamMd5 = checkNotNull(httpStreamMd5 != null ? httpStreamMd5
|
||||||
|
: sysHttpStreamMd5, "httpStreamMd5");
|
||||||
|
|
||||||
|
String bucketName = bucketPrefix + "tcu";
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
String key = "hello";
|
||||||
|
|
||||||
|
URL url = new URL(httpStreamUrl);
|
||||||
|
byte[] md5 = S3Utils
|
||||||
|
.fromHexString(httpStreamMd5);
|
||||||
|
|
||||||
|
URLConnection connection = url.openConnection();
|
||||||
|
int length = connection.getContentLength();
|
||||||
|
InputStream input = connection.getInputStream();
|
||||||
|
|
||||||
|
S3Object object = new S3Object(key, input);
|
||||||
|
object.setContentLength(length);
|
||||||
|
object.getMetadata().setMd5(md5);
|
||||||
|
object.getMetadata().setSize(length);
|
||||||
|
|
||||||
|
byte[] newMd5 = client.putObject(bucketName, object).get(30,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
assertEquals(newMd5, md5);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,50 +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;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests connection by listing all the buckets and their size
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit", testName = "s3.S3ConnectionTest")
|
|
||||||
public class S3ConnectionTest extends S3IntegrationTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testListBuckets() throws Exception {
|
|
||||||
List<S3Bucket.Metadata> myBuckets = client.listOwnedBuckets().get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
for (S3Bucket.Metadata bucket : myBuckets) {
|
|
||||||
context.createInputStreamMap(bucket.getName()).size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,79 +23,89 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Module;
|
||||||
import java.util.ArrayList;
|
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jclouds.http.config.HttpFutureCommandClientModule;
|
import org.jclouds.http.config.HttpFutureCommandClientModule;
|
||||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||||
import org.jclouds.logging.config.LoggingModule;
|
import org.jclouds.logging.config.LoggingModule;
|
||||||
import org.jclouds.logging.config.NullLoggingModule;
|
import org.jclouds.logging.config.NullLoggingModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import java.util.ArrayList;
|
||||||
import com.google.inject.Module;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of modules configured in S3ContextFactory
|
* Tests behavior of modules configured in S3ContextFactory
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Test(groups = "unit", testName = "s3.S3ContextFactoryTest")
|
||||||
public class S3ContextFactoryTest {
|
public class S3ContextFactoryTest {
|
||||||
|
|
||||||
@HttpFutureCommandClientModule
|
@HttpFutureCommandClientModule
|
||||||
static class HttpModule extends AbstractModule {
|
static class HttpModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddHttpModuleIfNotPresent() {
|
public void testAddHttpModuleIfNotPresent() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
HttpModule module = new HttpModule();
|
HttpModule module = new HttpModule();
|
||||||
modules.add(module);
|
modules.add(module);
|
||||||
S3ContextFactory.addHttpModuleIfNotPresent(modules);
|
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||||
assertEquals(modules.size(), 1);
|
assertEquals(modules.size(), 1);
|
||||||
assertEquals(modules.remove(0), module);
|
assertEquals(modules.remove(0), module);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddLoggingModuleIfNotPresent() {
|
public void testAddLoggingModuleIfNotPresent() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
LoggingModule module = new NullLoggingModule();
|
LoggingModule module = new NullLoggingModule();
|
||||||
modules.add(module);
|
modules.add(module);
|
||||||
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
||||||
assertEquals(modules.size(), 1);
|
assertEquals(modules.size(), 1);
|
||||||
assertEquals(modules.remove(0), module);
|
assertEquals(modules.remove(0), module);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddNone() {
|
public void testAddNone() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
LoggingModule loggingModule = new NullLoggingModule();
|
LoggingModule loggingModule = new NullLoggingModule();
|
||||||
modules.add(loggingModule);
|
modules.add(loggingModule);
|
||||||
HttpModule httpModule = new HttpModule();
|
HttpModule httpModule = new HttpModule();
|
||||||
modules.add(httpModule);
|
modules.add(httpModule);
|
||||||
S3ContextFactory.addHttpModuleIfNotPresent(modules);
|
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||||
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
||||||
assertEquals(modules.size(), 2);
|
assertEquals(modules.size(), 2);
|
||||||
assertEquals(modules.remove(0), loggingModule);
|
assertEquals(modules.remove(0), loggingModule);
|
||||||
assertEquals(modules.remove(0), httpModule);
|
assertEquals(modules.remove(0), httpModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddBoth() {
|
public void testAddBothWhenNotLive() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
S3ContextFactory.addHttpModuleIfNotPresent(modules);
|
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||||
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
||||||
assertEquals(modules.size(), 2);
|
assertEquals(modules.size(), 1);
|
||||||
assert modules.remove(0) instanceof JavaUrlHttpFutureCommandClientModule;
|
assert modules.remove(0) instanceof JDKLoggingModule;
|
||||||
assert modules.remove(0) instanceof JDKLoggingModule;
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddBothWhenLive() {
|
||||||
|
List<Module> modules = new ArrayList<Module>();
|
||||||
|
modules.add(new LiveS3ConnectionModule());
|
||||||
|
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||||
|
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
||||||
|
assertEquals(modules.size(), 3);
|
||||||
|
assert modules.remove(0) instanceof LiveS3ConnectionModule;
|
||||||
|
assert modules.remove(0) instanceof JavaUrlHttpFutureCommandClientModule;
|
||||||
|
assert modules.remove(0) instanceof JDKLoggingModule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.internal.BaseS3Map;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests to cover @{link LiveS3ObjectMap}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(testName = "s3.S3InputStreamMapIntegrationTest")
|
||||||
|
public class S3InputStreamMapIntegrationTest extends BaseS3MapIntegrationTest<InputStream> {
|
||||||
|
S3InputStreamMap map = null;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected BaseS3Map<InputStream> createMap(S3Context context, String bucket) {
|
||||||
|
map = context.createInputStreamMap(bucket);
|
||||||
|
return (BaseS3Map<InputStream>) map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testValues() throws IOException {
|
||||||
|
map.putAll(this.fiveInputs);
|
||||||
|
Collection<InputStream> values = map.values();
|
||||||
|
assertEquals(values.size(), 5);
|
||||||
|
Set<String> valuesAsString = new HashSet<String>();
|
||||||
|
for (InputStream stream : values) {
|
||||||
|
valuesAsString.add(Utils.toStringAndClose(stream));
|
||||||
|
}
|
||||||
|
valuesAsString.removeAll(fiveStrings.values());
|
||||||
|
assert valuesAsString.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testRemove() throws IOException {
|
||||||
|
putString("one", "two");
|
||||||
|
InputStream old = map.remove("one");
|
||||||
|
assertEquals(Utils.toStringAndClose(old), "two");
|
||||||
|
old = map.remove("one");
|
||||||
|
assert old == null;
|
||||||
|
old = map.get("one");
|
||||||
|
assert old == null;
|
||||||
|
assertEquals(map.keySet().size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testEntrySet() throws IOException {
|
||||||
|
map.putAllStrings(this.fiveStrings);
|
||||||
|
Set<Entry<String, InputStream>> entries = map.entrySet();
|
||||||
|
assertEquals(entries.size(), 5);
|
||||||
|
for (Entry<String, InputStream> entry : entries) {
|
||||||
|
assertEquals(IOUtils.toString(entry.getValue()), fiveStrings
|
||||||
|
.get(entry.getKey()));
|
||||||
|
entry.setValue(IOUtils.toInputStream(""));
|
||||||
|
}
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
for (InputStream value : map.values()) {
|
||||||
|
assertEquals(IOUtils.toString(value), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testContainsStringValue() {
|
||||||
|
map.putString("one", "apple");
|
||||||
|
assert map.containsValue(fiveStrings.get("one"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testContainsFileValue() {
|
||||||
|
map.putString("one", "apple");
|
||||||
|
assert map.containsValue(fiveFiles.get("one"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testContainsInputStreamValue() {
|
||||||
|
map.putString("one", "apple");
|
||||||
|
assert map.containsValue(this.fiveInputs.get("one"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testContainsBytesValue() {
|
||||||
|
map.putString("one", "apple");
|
||||||
|
assert map.containsValue(this.fiveBytes.get("one"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutAll() {
|
||||||
|
map.putAll(this.fiveInputs);
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
||||||
|
fiveInputs.keySet()));
|
||||||
|
fourLeftRemovingOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutAllBytes() {
|
||||||
|
map.putAllBytes(this.fiveBytes);
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
||||||
|
fiveBytes.keySet()));
|
||||||
|
fourLeftRemovingOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutAllFiles() {
|
||||||
|
map.putAllFiles(this.fiveFiles);
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
||||||
|
fiveFiles.keySet()));
|
||||||
|
fourLeftRemovingOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutAllStrings() {
|
||||||
|
map.putAllStrings(this.fiveStrings);
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
||||||
|
fiveStrings.keySet()));
|
||||||
|
fourLeftRemovingOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutString() throws IOException {
|
||||||
|
InputStream old = map.putString("one", "apple");
|
||||||
|
getOneReturnsAppleAndOldValueIsNull(old);
|
||||||
|
InputStream apple = map.putString("one", "bear");
|
||||||
|
getOneReturnsBearAndOldValueIsApple(apple);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getOneReturnsAppleAndOldValueIsNull(InputStream old)
|
||||||
|
throws IOException {
|
||||||
|
assert old == null;
|
||||||
|
assertEquals(Utils.toStringAndClose(map.get("one")), "apple");
|
||||||
|
assertEquals(map.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getOneReturnsBearAndOldValueIsApple(InputStream oldValue)
|
||||||
|
throws IOException {
|
||||||
|
assertEquals(Utils.toStringAndClose(map.get("one")), "bear");
|
||||||
|
assertEquals(Utils.toStringAndClose(oldValue), "apple");
|
||||||
|
assertEquals(map.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutFile() throws IOException {
|
||||||
|
InputStream old = map.putFile("one", fiveFiles.get("one"));
|
||||||
|
getOneReturnsAppleAndOldValueIsNull(old);
|
||||||
|
InputStream apple = map.putFile("one", fiveFiles.get("two"));
|
||||||
|
getOneReturnsBearAndOldValueIsApple(apple);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutBytes() throws IOException {
|
||||||
|
InputStream old = map.putBytes("one", "apple".getBytes());
|
||||||
|
getOneReturnsAppleAndOldValueIsNull(old);
|
||||||
|
InputStream apple = map.putBytes("one", "bear".getBytes());
|
||||||
|
getOneReturnsBearAndOldValueIsApple(apple);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPut() throws IOException {
|
||||||
|
InputStream old = map.put("one", IOUtils.toInputStream("apple"));
|
||||||
|
getOneReturnsAppleAndOldValueIsNull(old);
|
||||||
|
InputStream apple = map.put("one", IOUtils.toInputStream("bear"));
|
||||||
|
getOneReturnsBearAndOldValueIsApple(apple);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void putString(String key, String value) {
|
||||||
|
map.putString(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,211 +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;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.internal.BaseS3Map;
|
|
||||||
import org.jclouds.util.Utils;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests to cover @{link LiveS3ObjectMap}
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.S3InputStreamMapTest")
|
|
||||||
public class S3InputStreamMapTest extends BaseS3MapTest<InputStream> {
|
|
||||||
S3InputStreamMap map = null;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected BaseS3Map<InputStream> createMap(S3Context context, String bucket) {
|
|
||||||
map = context.createInputStreamMap(bucket);
|
|
||||||
return (BaseS3Map<InputStream>) map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Test()
|
|
||||||
public void testValues() throws IOException {
|
|
||||||
map.putAll(this.fiveInputs);
|
|
||||||
Collection<InputStream> values = map.values();
|
|
||||||
assertEquals(values.size(), 5);
|
|
||||||
Set<String> valuesAsString = new HashSet<String>();
|
|
||||||
for (InputStream stream : values) {
|
|
||||||
valuesAsString.add(Utils.toStringAndClose(stream));
|
|
||||||
}
|
|
||||||
valuesAsString.removeAll(fiveStrings.values());
|
|
||||||
assert valuesAsString.size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testRemove() throws IOException {
|
|
||||||
putString("one", "two");
|
|
||||||
InputStream old = map.remove("one");
|
|
||||||
assertEquals(Utils.toStringAndClose(old), "two");
|
|
||||||
old = map.remove("one");
|
|
||||||
assert old == null;
|
|
||||||
old = map.get("one");
|
|
||||||
assert old == null;
|
|
||||||
assertEquals(map.keySet().size(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Test()
|
|
||||||
public void testEntrySet() throws IOException {
|
|
||||||
map.putAllStrings(this.fiveStrings);
|
|
||||||
Set<Entry<String, InputStream>> entries = map.entrySet();
|
|
||||||
assertEquals(entries.size(), 5);
|
|
||||||
for (Entry<String, InputStream> entry : entries) {
|
|
||||||
assertEquals(IOUtils.toString(entry.getValue()), fiveStrings
|
|
||||||
.get(entry.getKey()));
|
|
||||||
entry.setValue(IOUtils.toInputStream(""));
|
|
||||||
}
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
for (InputStream value : map.values()) {
|
|
||||||
assertEquals(IOUtils.toString(value), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testContainsStringValue() {
|
|
||||||
map.putString("one", "apple");
|
|
||||||
assert map.containsValue(fiveStrings.get("one"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testContainsFileValue() {
|
|
||||||
map.putString("one", "apple");
|
|
||||||
assert map.containsValue(fiveFiles.get("one"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testContainsInputStreamValue() {
|
|
||||||
map.putString("one", "apple");
|
|
||||||
assert map.containsValue(this.fiveInputs.get("one"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testContainsBytesValue() {
|
|
||||||
map.putString("one", "apple");
|
|
||||||
assert map.containsValue(this.fiveBytes.get("one"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Test()
|
|
||||||
public void testPutAll() {
|
|
||||||
map.putAll(this.fiveInputs);
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
|
||||||
fiveInputs.keySet()));
|
|
||||||
fourLeftRemovingOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testPutAllBytes() {
|
|
||||||
map.putAllBytes(this.fiveBytes);
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
|
||||||
fiveBytes.keySet()));
|
|
||||||
fourLeftRemovingOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPutAllFiles() {
|
|
||||||
map.putAllFiles(this.fiveFiles);
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
|
||||||
fiveFiles.keySet()));
|
|
||||||
fourLeftRemovingOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testPutAllStrings() {
|
|
||||||
map.putAllStrings(this.fiveStrings);
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
|
||||||
fiveStrings.keySet()));
|
|
||||||
fourLeftRemovingOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testPutString() throws IOException {
|
|
||||||
InputStream old = map.putString("one", "apple");
|
|
||||||
getOneReturnsAppleAndOldValueIsNull(old);
|
|
||||||
InputStream apple = map.putString("one", "bear");
|
|
||||||
getOneReturnsBearAndOldValueIsApple(apple);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getOneReturnsAppleAndOldValueIsNull(InputStream old)
|
|
||||||
throws IOException {
|
|
||||||
assert old == null;
|
|
||||||
assertEquals(Utils.toStringAndClose(map.get("one")), "apple");
|
|
||||||
assertEquals(map.size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getOneReturnsBearAndOldValueIsApple(InputStream oldValue)
|
|
||||||
throws IOException {
|
|
||||||
assertEquals(Utils.toStringAndClose(map.get("one")), "bear");
|
|
||||||
assertEquals(Utils.toStringAndClose(oldValue), "apple");
|
|
||||||
assertEquals(map.size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testPutFile() throws IOException {
|
|
||||||
InputStream old = map.putFile("one", fiveFiles.get("one"));
|
|
||||||
getOneReturnsAppleAndOldValueIsNull(old);
|
|
||||||
InputStream apple = map.putFile("one", fiveFiles.get("two"));
|
|
||||||
getOneReturnsBearAndOldValueIsApple(apple);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testPutBytes() throws IOException {
|
|
||||||
InputStream old = map.putBytes("one", "apple".getBytes());
|
|
||||||
getOneReturnsAppleAndOldValueIsNull(old);
|
|
||||||
InputStream apple = map.putBytes("one", "bear".getBytes());
|
|
||||||
getOneReturnsBearAndOldValueIsApple(apple);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testPut() throws IOException {
|
|
||||||
InputStream old = map.put("one", IOUtils.toInputStream("apple"));
|
|
||||||
getOneReturnsAppleAndOldValueIsNull(old);
|
|
||||||
InputStream apple = map.put("one", IOUtils.toInputStream("bear"));
|
|
||||||
getOneReturnsBearAndOldValueIsApple(apple);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void putString(String key, String value) {
|
|
||||||
map.putString(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,196 +24,215 @@
|
||||||
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.testng.Assert.assertEquals;
|
import com.google.inject.Module;
|
||||||
|
import org.jclouds.aws.s3.config.StubS3ConnectionModule;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.CancellationException;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.logging.ConsoleHandler;
|
|
||||||
import java.util.logging.Formatter;
|
|
||||||
import java.util.logging.Handler;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.LogRecord;
|
|
||||||
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.reference.S3Constants;
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
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 static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.ITestContext;
|
||||||
import org.testng.annotations.Optional;
|
import org.testng.annotations.*;
|
||||||
import org.testng.annotations.Parameters;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.inject.Module;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import java.util.logging.Formatter;
|
||||||
|
|
||||||
@Test
|
|
||||||
public class S3IntegrationTest {
|
public class S3IntegrationTest {
|
||||||
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
|
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
|
||||||
|
|
||||||
protected byte[] goodMd5;
|
protected byte[] goodMd5;
|
||||||
protected byte[] badMd5;
|
protected byte[] badMd5;
|
||||||
|
protected String bucketName;
|
||||||
|
|
||||||
protected void createBucketAndEnsureEmpty(String sourceBucket)
|
protected void createBucketAndEnsureEmpty(String sourceBucket)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
client.putBucketIfNotExists(sourceBucket).get(10, TimeUnit.SECONDS);
|
client.putBucketIfNotExists(sourceBucket).get(10, TimeUnit.SECONDS);
|
||||||
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
|
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
|
||||||
.getContents().size(), 0);
|
.getContents().size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addObjectToBucket(String sourceBucket, S3Object object)
|
protected void addObjectToBucket(String sourceBucket, S3Object object)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
;
|
client.putObject(sourceBucket, object).get(10, TimeUnit.SECONDS);
|
||||||
client.putObject(sourceBucket, object).get(10, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected S3Object validateContent(String sourceBucket, String key)
|
protected S3Object validateContent(String sourceBucket, String key)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
|
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
|
||||||
.getContents().size(), 1);
|
.getContents().size(), 1);
|
||||||
S3Object newObject = client.getObject(sourceBucket, key).get(10,
|
S3Object newObject = client.getObject(sourceBucket, key).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assert newObject != S3Object.NOT_FOUND;
|
assert newObject != S3Object.NOT_FOUND;
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(newObject), TEST_STRING);
|
assertEquals(S3Utils.getContentAsStringAndClose(newObject), TEST_STRING);
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeClass(groups = {"integration", "live"})
|
||||||
void enableDebug() {
|
void enableDebug() {
|
||||||
if (debugEnabled()) {
|
if (debugEnabled()) {
|
||||||
Handler HANDLER = new ConsoleHandler() {
|
Handler HANDLER = new ConsoleHandler() {
|
||||||
{
|
{
|
||||||
setLevel(Level.ALL);
|
setLevel(Level.ALL);
|
||||||
setFormatter(new Formatter() {
|
setFormatter(new Formatter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String format(LogRecord record) {
|
public String format(LogRecord record) {
|
||||||
return String.format(
|
return String.format(
|
||||||
"[%tT %-7s] [%-7s] [%s]: %s %s\n",
|
"[%tT %-7s] [%-7s] [%s]: %s %s\n",
|
||||||
new Date(record.getMillis()), record
|
new Date(record.getMillis()), record
|
||||||
.getLevel(), Thread.currentThread()
|
.getLevel(), Thread.currentThread()
|
||||||
.getName(), record.getLoggerName(),
|
.getName(), record.getLoggerName(),
|
||||||
record.getMessage(),
|
record.getMessage(),
|
||||||
record.getThrown() == null ? "" : record
|
record.getThrown() == null ? "" : record
|
||||||
.getThrown());
|
.getThrown());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Logger guiceLogger = Logger.getLogger("org.jclouds");
|
Logger guiceLogger = Logger.getLogger("org.jclouds");
|
||||||
guiceLogger.addHandler(HANDLER);
|
guiceLogger.addHandler(HANDLER);
|
||||||
guiceLogger.setLevel(Level.ALL);
|
guiceLogger.setLevel(Level.ALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected S3Connection client;
|
protected S3Connection client;
|
||||||
protected S3Context context = null;
|
protected S3Context context = null;
|
||||||
|
|
||||||
protected String bucketPrefix = (System.getProperty("user.name") + "." + this
|
protected String bucketPrefix = (System.getProperty("user.name") + "." + this
|
||||||
.getClass().getSimpleName()).toLowerCase();
|
.getClass().getSimpleName()).toLowerCase();
|
||||||
|
|
||||||
private static final String sysAWSAccessKeyId = System
|
private static final String sysAWSAccessKeyId = System
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
||||||
private static final String sysAWSSecretAccessKey = System
|
private static final String sysAWSSecretAccessKey = System
|
||||||
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeClass(inheritGroups = false, groups = {"integration", "live"})
|
||||||
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
@Parameters({S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
||||||
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
S3Constants.PROPERTY_AWS_SECRETACCESSKEY})
|
||||||
protected void setUpClient(@Optional String AWSAccessKeyId,
|
protected void setUpCredentials(@Optional String AWSAccessKeyId,
|
||||||
@Optional String AWSSecretAccessKey) throws Exception {
|
@Optional String AWSSecretAccessKey, ITestContext testContext) throws Exception {
|
||||||
context = createS3Context(AWSAccessKeyId != null ? AWSAccessKeyId
|
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId
|
||||||
: sysAWSAccessKeyId,
|
: sysAWSAccessKeyId;
|
||||||
AWSSecretAccessKey != null ? AWSSecretAccessKey
|
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey
|
||||||
: sysAWSSecretAccessKey);
|
: sysAWSSecretAccessKey;
|
||||||
client = context.getConnection();
|
if (AWSAccessKeyId != null)
|
||||||
deleteEverything();
|
testContext.setAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID, AWSAccessKeyId);
|
||||||
goodMd5 = S3Utils.md5(TEST_STRING);
|
if (AWSSecretAccessKey != null)
|
||||||
badMd5 = S3Utils.md5("alf");
|
testContext.setAttribute(S3Constants.PROPERTY_AWS_SECRETACCESSKEY, AWSSecretAccessKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass(dependsOnMethods = {"setUpCredentials"}, groups = {"integration", "live"})
|
||||||
|
protected void setUpClient(ITestContext testContext) throws Exception {
|
||||||
|
if (testContext.getAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID) != null) {
|
||||||
|
String AWSAccessKeyId = (String) testContext.getAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
||||||
|
String AWSSecretAccessKey = (String) testContext.getAttribute(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||||
|
context = S3ContextFactory.createS3Context(buildS3Properties(
|
||||||
|
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"),
|
||||||
|
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey")),
|
||||||
|
createHttpModule());
|
||||||
|
} else {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty(S3Constants.PROPERTY_HTTP_ADDRESS, "stub");
|
||||||
|
context = S3ContextFactory.createS3Context(props, new StubS3ConnectionModule());
|
||||||
|
}
|
||||||
|
client = context.getConnection();
|
||||||
|
assert client != null;
|
||||||
|
deleteEverything();
|
||||||
|
goodMd5 = S3Utils.md5(TEST_STRING);
|
||||||
|
badMd5 = S3Utils.md5("alf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod(dependsOnMethods = "deleteBucket", groups = {"integration", "live"})
|
||||||
|
public void setUpBucket(Method method) throws TimeoutException, ExecutionException, InterruptedException {
|
||||||
|
bucketName = (bucketPrefix + method.getName()).toLowerCase();
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod(groups = {"integration", "live"})
|
||||||
|
@AfterMethod(groups = {"integration", "live"})
|
||||||
|
public void deleteBucket() throws TimeoutException, ExecutionException, InterruptedException {
|
||||||
|
if (bucketName != null)
|
||||||
|
deleteBucket(bucketName);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean debugEnabled() {
|
protected boolean debugEnabled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
protected S3Context createS3Context(String AWSAccessKeyId,
|
|
||||||
String AWSSecretAccessKey) {
|
|
||||||
return S3ContextFactory.createS3Context(buildS3Properties(
|
|
||||||
AWSAccessKeyId, AWSSecretAccessKey), createHttpModule());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties buildS3Properties(String AWSAccessKeyId,
|
protected Properties buildS3Properties(String AWSAccessKeyId,
|
||||||
String AWSSecretAccessKey) {
|
String AWSSecretAccessKey) {
|
||||||
Properties properties = new Properties(
|
Properties properties = new Properties(
|
||||||
S3ContextFactory.DEFAULT_PROPERTIES);
|
S3ContextFactory.DEFAULT_PROPERTIES);
|
||||||
properties.setProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
properties.setProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
||||||
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"));
|
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"));
|
||||||
properties.setProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY,
|
properties.setProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY,
|
||||||
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");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Module createHttpModule() {
|
protected Module createHttpModule() {
|
||||||
return new JavaUrlHttpFutureCommandClientModule();
|
return new JavaUrlHttpFutureCommandClientModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void deleteEverything() throws Exception {
|
protected void deleteEverything() throws Exception {
|
||||||
try {
|
try {
|
||||||
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(
|
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(
|
||||||
10, TimeUnit.SECONDS);
|
10, TimeUnit.SECONDS);
|
||||||
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())) {
|
deleteBucket(metaDatum.getName());
|
||||||
S3Bucket bucket = client.listBucket(metaDatum.getName())
|
}
|
||||||
.get(10, TimeUnit.SECONDS);
|
|
||||||
for (S3Object.Metadata objectMeta : bucket.getContents()) {
|
|
||||||
results.add(client.deleteObject(metaDatum.getName(),
|
|
||||||
objectMeta.getKey()));
|
|
||||||
}
|
|
||||||
Iterator<Future<Boolean>> iterator = results.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
iterator.next().get(10, TimeUnit.SECONDS);
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
client.deleteBucketIfEmpty(metaDatum.getName()).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (CancellationException e) {
|
} catch (CancellationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTest
|
private void deleteBucket(String name) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
if (client.bucketExists(name).get(10, TimeUnit.SECONDS)) {
|
||||||
|
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
|
||||||
|
|
||||||
|
S3Bucket bucket = client.listBucket(name)
|
||||||
|
.get(10, TimeUnit.SECONDS);
|
||||||
|
for (S3Object.Metadata objectMeta : bucket.getContents()) {
|
||||||
|
results.add(client.deleteObject(name,
|
||||||
|
objectMeta.getKey()));
|
||||||
|
}
|
||||||
|
Iterator<Future<Boolean>> iterator = results.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
iterator.next().get(10, TimeUnit.SECONDS);
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
client.deleteBucketIfEmpty(name).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
protected void tearDownClient() throws Exception {
|
protected void tearDownClient() throws Exception {
|
||||||
deleteEverything();
|
deleteEverything();
|
||||||
context.close();
|
context.close();
|
||||||
context = null;
|
context = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.internal.BaseS3Map;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests to cover @{link LiveS3ObjectMap}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(testName = "s3.S3ObjectMapIntegrationTest")
|
||||||
|
public class S3ObjectMapIntegrationTest extends BaseS3MapIntegrationTest<S3Object> {
|
||||||
|
S3ObjectMap map = null;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected BaseS3Map<S3Object> createMap(S3Context context, String bucket) {
|
||||||
|
map = context.createS3ObjectMap(bucket);
|
||||||
|
return (BaseS3Map<S3Object>) map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testValues() throws IOException {
|
||||||
|
putFiveStrings();
|
||||||
|
Collection<S3Object> values = map.values();
|
||||||
|
assertEquals(values.size(), 5);
|
||||||
|
Set<String> valuesAsString = new HashSet<String>();
|
||||||
|
for (S3Object object : values) {
|
||||||
|
valuesAsString.add(S3Utils.getContentAsStringAndClose(object));
|
||||||
|
}
|
||||||
|
valuesAsString.removeAll(fiveStrings.values());
|
||||||
|
assert valuesAsString.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testRemove() throws IOException {
|
||||||
|
putString("one", "two");
|
||||||
|
S3Object old = map.remove("one");
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(old), "two");
|
||||||
|
old = map.remove("one");
|
||||||
|
assert old == S3Object.NOT_FOUND;
|
||||||
|
old = map.get("one");
|
||||||
|
assert old == S3Object.NOT_FOUND;
|
||||||
|
assertEquals(map.keySet().size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testEntrySet() throws IOException {
|
||||||
|
putFiveStrings();
|
||||||
|
Set<Entry<String, S3Object>> entries = map.entrySet();
|
||||||
|
assertEquals(entries.size(), 5);
|
||||||
|
for (Entry<String, S3Object> entry : entries) {
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()),
|
||||||
|
fiveStrings.get(entry.getKey()));
|
||||||
|
S3Object value = entry.getValue();
|
||||||
|
value.setData("");
|
||||||
|
value.generateMd5();
|
||||||
|
entry.setValue(value);
|
||||||
|
}
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
for (S3Object value : map.values()) {
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(value), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testContains() {
|
||||||
|
putString("one", "apple");
|
||||||
|
S3Object object = new S3Object("one");
|
||||||
|
object.setData("apple");
|
||||||
|
assert map.containsValue(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException {
|
||||||
|
assert old == S3Object.NOT_FOUND;
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")),
|
||||||
|
"apple");
|
||||||
|
assert map.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getOneReturnsBearAndOldValueIsApple(S3Object oldValue)
|
||||||
|
throws IOException {
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear");
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple");
|
||||||
|
assert map.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPut() throws IOException {
|
||||||
|
S3Object object = new S3Object("one");
|
||||||
|
object.setData(IOUtils.toInputStream("apple"));
|
||||||
|
object.generateMd5();
|
||||||
|
S3Object old = map.put(object.getKey(), object);
|
||||||
|
getOneReturnsAppleAndOldValueIsNull(old);
|
||||||
|
object.setData(IOUtils.toInputStream("bear"));
|
||||||
|
object.generateMd5();
|
||||||
|
S3Object apple = map.put(object.getKey(), object);
|
||||||
|
getOneReturnsBearAndOldValueIsApple(apple);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = {"integration", "live"})
|
||||||
|
public void testPutAll() {
|
||||||
|
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
|
||||||
|
for (String key : fiveInputs.keySet()) {
|
||||||
|
S3Object object = new S3Object(key);
|
||||||
|
object.setData(fiveInputs.get(key));
|
||||||
|
object.getMetadata().setSize(fiveBytes.get(key).length);
|
||||||
|
newMap.put(key, object);
|
||||||
|
}
|
||||||
|
map.putAll(newMap);
|
||||||
|
assertEquals(map.size(), 5);
|
||||||
|
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
||||||
|
fiveInputs.keySet()));
|
||||||
|
fourLeftRemovingOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void putString(String key, String value) {
|
||||||
|
S3Object object = new S3Object(key);
|
||||||
|
object.setData(value);
|
||||||
|
map.put(key, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void putFiveStrings() {
|
||||||
|
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
|
||||||
|
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
|
||||||
|
S3Object object = new S3Object(entry.getKey());
|
||||||
|
object.setData(entry.getValue());
|
||||||
|
newMap.put(entry.getKey(), object);
|
||||||
|
}
|
||||||
|
map.putAll(newMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,172 +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;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
import org.jclouds.aws.s3.internal.BaseS3Map;
|
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests to cover @{link LiveS3ObjectMap}
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.S3ObjectMapTest")
|
|
||||||
public class S3ObjectMapTest extends BaseS3MapTest<S3Object> {
|
|
||||||
S3ObjectMap map = null;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected BaseS3Map<S3Object> createMap(S3Context context, String bucket) {
|
|
||||||
map = context.createS3ObjectMap(bucket);
|
|
||||||
return (BaseS3Map<S3Object>) map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Test()
|
|
||||||
public void testValues() throws IOException {
|
|
||||||
putFiveStrings();
|
|
||||||
Collection<S3Object> values = map.values();
|
|
||||||
assertEquals(values.size(), 5);
|
|
||||||
Set<String> valuesAsString = new HashSet<String>();
|
|
||||||
for (S3Object object : values) {
|
|
||||||
valuesAsString.add(S3Utils.getContentAsStringAndClose(object));
|
|
||||||
}
|
|
||||||
valuesAsString.removeAll(fiveStrings.values());
|
|
||||||
assert valuesAsString.size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testRemove() throws IOException {
|
|
||||||
putString("one", "two");
|
|
||||||
S3Object old = map.remove("one");
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(old), "two");
|
|
||||||
old = map.remove("one");
|
|
||||||
assert old == S3Object.NOT_FOUND;
|
|
||||||
old = map.get("one");
|
|
||||||
assert old == S3Object.NOT_FOUND;
|
|
||||||
assertEquals(map.keySet().size(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Test()
|
|
||||||
public void testEntrySet() throws IOException {
|
|
||||||
putFiveStrings();
|
|
||||||
Set<Entry<String, S3Object>> entries = map.entrySet();
|
|
||||||
assertEquals(entries.size(), 5);
|
|
||||||
for (Entry<String, S3Object> entry : entries) {
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()),
|
|
||||||
fiveStrings.get(entry.getKey()));
|
|
||||||
S3Object value = entry.getValue();
|
|
||||||
value.setData("");
|
|
||||||
value.generateMd5();
|
|
||||||
entry.setValue(value);
|
|
||||||
}
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
for (S3Object value : map.values()) {
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(value), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
public void testContains() {
|
|
||||||
putString("one", "apple");
|
|
||||||
S3Object object = new S3Object("one");
|
|
||||||
object.setData("apple");
|
|
||||||
assert map.containsValue(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException {
|
|
||||||
assert old == S3Object.NOT_FOUND;
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")),
|
|
||||||
"apple");
|
|
||||||
assert map.size() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void getOneReturnsBearAndOldValueIsApple(S3Object oldValue)
|
|
||||||
throws IOException {
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear");
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple");
|
|
||||||
assert map.size() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPut() throws IOException {
|
|
||||||
S3Object object = new S3Object("one");
|
|
||||||
object.setData(IOUtils.toInputStream("apple"));
|
|
||||||
object.generateMd5();
|
|
||||||
S3Object old = map.put(object.getKey(), object);
|
|
||||||
getOneReturnsAppleAndOldValueIsNull(old);
|
|
||||||
object.setData(IOUtils.toInputStream("bear"));
|
|
||||||
object.generateMd5();
|
|
||||||
S3Object apple = map.put(object.getKey(), object);
|
|
||||||
getOneReturnsBearAndOldValueIsApple(apple);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPutAll() {
|
|
||||||
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
|
|
||||||
for (String key : fiveInputs.keySet()) {
|
|
||||||
S3Object object = new S3Object(key);
|
|
||||||
object.setData(fiveInputs.get(key));
|
|
||||||
object.getMetadata().setSize(fiveBytes.get(key).length);
|
|
||||||
newMap.put(key, object);
|
|
||||||
}
|
|
||||||
map.putAll(newMap);
|
|
||||||
assertEquals(map.size(), 5);
|
|
||||||
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
|
|
||||||
fiveInputs.keySet()));
|
|
||||||
fourLeftRemovingOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void putString(String key, String value) {
|
|
||||||
S3Object object = new S3Object(key);
|
|
||||||
object.setData(value);
|
|
||||||
map.put(key, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void putFiveStrings() {
|
|
||||||
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
|
|
||||||
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
|
|
||||||
S3Object object = new S3Object(entry.getKey());
|
|
||||||
object.setData(entry.getValue());
|
|
||||||
newMap.put(entry.getKey(), object);
|
|
||||||
}
|
|
||||||
map.putAll(newMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -26,6 +26,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.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -38,90 +39,89 @@ import java.util.concurrent.CompletionService;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorCompletionService;
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
|
||||||
import static org.testng.Assert.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This tests the performance of Digest commands.
|
* This tests the performance of Digest commands.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.PerformanceTest")
|
@Test(groups = "performance", sequential = true, testName = "s3.PerformanceTest")
|
||||||
public class S3UtilsTest extends PerformanceTest {
|
public class S3UtilsTest extends PerformanceTest {
|
||||||
|
|
||||||
@Test(dataProvider = "hmacsha1")
|
@Test(dataProvider = "hmacsha1")
|
||||||
void testBouncyCastleDigestSerialResponseTime(byte[] key, String message,
|
void testBouncyCastleDigestSerialResponseTime(byte[] key, String message,
|
||||||
String base64Digest) throws NoSuchProviderException,
|
String base64Digest) throws NoSuchProviderException,
|
||||||
NoSuchAlgorithmException, InvalidKeyException {
|
NoSuchAlgorithmException, InvalidKeyException {
|
||||||
for (int i = 0; i < 10000; i++)
|
for (int i = 0; i < 10000; i++)
|
||||||
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
|
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "hmacsha1")
|
@Test(dataProvider = "hmacsha1")
|
||||||
void testBouncyCastleDigestParallelResponseTime(final byte[] key,
|
void testBouncyCastleDigestParallelResponseTime(final byte[] key,
|
||||||
final String message, final String base64Digest)
|
final String message, final String base64Digest)
|
||||||
throws NoSuchProviderException, NoSuchAlgorithmException,
|
throws NoSuchProviderException, NoSuchAlgorithmException,
|
||||||
InvalidKeyException, InterruptedException, ExecutionException {
|
InvalidKeyException, InterruptedException, ExecutionException {
|
||||||
CompletionService<Boolean> completer = new ExecutorCompletionService<Boolean>(
|
CompletionService<Boolean> completer = new ExecutorCompletionService<Boolean>(
|
||||||
exec);
|
exec);
|
||||||
for (int i = 0; i < 10000; i++)
|
for (int i = 0; i < 10000; i++)
|
||||||
completer.submit(new Callable<Boolean>() {
|
completer.submit(new Callable<Boolean>() {
|
||||||
public Boolean call() throws Exception {
|
public Boolean call() throws Exception {
|
||||||
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
|
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (int i = 0; i < 10000; i++)
|
for (int i = 0; i < 10000; i++)
|
||||||
assert completer.take().get();
|
assert completer.take().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataProvider(name = "md5")
|
@DataProvider(name = "md5")
|
||||||
public Object[][] createMD5Data() {
|
public Object[][] createMD5Data() {
|
||||||
return base64MD5MessageDigest;
|
return base64MD5MessageDigest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static Object[][] base64MD5MessageDigest = {
|
public final static Object[][] base64MD5MessageDigest = {
|
||||||
{ "apple", "1f3870be274f6c49b3e31a0c6728957f" },
|
{"apple", "1f3870be274f6c49b3e31a0c6728957f"},
|
||||||
{ "bear", "893b56e3cfe153fb770a120b83bac20c" },
|
{"bear", "893b56e3cfe153fb770a120b83bac20c"},
|
||||||
{ "candy", "c48ba993d35c3abe0380f91738fe2a34" },
|
{"candy", "c48ba993d35c3abe0380f91738fe2a34"},
|
||||||
{ "dogma", "95eb470e4faee302e9cd3063b1923dab" },
|
{"dogma", "95eb470e4faee302e9cd3063b1923dab"},
|
||||||
{ "emma", "00a809937eddc44521da9521269e75c6" } };
|
{"emma", "00a809937eddc44521da9521269e75c6"}};
|
||||||
|
|
||||||
public final static Object[][] base64KeyMessageDigest = {
|
public final static Object[][] base64KeyMessageDigest = {
|
||||||
{ Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There",
|
{Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There",
|
||||||
"thcxhlUFcmTii8C2+zeMjvFGvgA=" },
|
"thcxhlUFcmTii8C2+zeMjvFGvgA="},
|
||||||
{ Base64.decode("SmVmZQ=="), "what do ya want for nothing?",
|
{Base64.decode("SmVmZQ=="), "what do ya want for nothing?",
|
||||||
"7/zfauXrL6LSdBbV8YTfnCWafHk=" },
|
"7/zfauXrL6LSdBbV8YTfnCWafHk="},
|
||||||
{ Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="),
|
{Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="),
|
||||||
"Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ=" },
|
"Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ="},
|
||||||
{
|
{
|
||||||
Base64
|
Base64
|
||||||
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
|
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
|
||||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||||
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" },
|
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI="},
|
||||||
{
|
{
|
||||||
Base64
|
Base64
|
||||||
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
|
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
|
||||||
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
|
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
|
||||||
"6OmdD0UjfXhta7qnllx4CLv/GpE=" } };
|
"6OmdD0UjfXhta7qnllx4CLv/GpE="}};
|
||||||
|
|
||||||
@DataProvider(name = "hmacsha1")
|
@DataProvider(name = "hmacsha1")
|
||||||
public Object[][] createData1() {
|
public Object[][] createData1() {
|
||||||
return base64KeyMessageDigest;
|
return base64KeyMessageDigest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "hmacsha1")
|
@Test(dataProvider = "hmacsha1")
|
||||||
public void testBouncyCastleHmacSha1Base64(byte[] key, String message,
|
public void testBouncyCastleHmacSha1Base64(byte[] key, String message,
|
||||||
String base64Digest) throws NoSuchProviderException,
|
String base64Digest) throws NoSuchProviderException,
|
||||||
NoSuchAlgorithmException, InvalidKeyException {
|
NoSuchAlgorithmException, InvalidKeyException {
|
||||||
String b64 = S3Utils.hmacSha1Base64(message, key);
|
String b64 = S3Utils.hmacSha1Base64(message, key);
|
||||||
assertEquals(b64, base64Digest);
|
assertEquals(b64, base64Digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "md5")
|
@Test(dataProvider = "md5")
|
||||||
public void testBouncyCastleMD5Digest(String message,
|
public void testBouncyCastleMD5Digest(String message,
|
||||||
String base64Digest) throws NoSuchProviderException,
|
String base64Digest) throws NoSuchProviderException,
|
||||||
NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
|
NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
|
||||||
String b64 = S3Utils.md5Hex(message.getBytes());
|
String b64 = S3Utils.md5Hex(message.getBytes());
|
||||||
assertEquals(base64Digest,b64);
|
assertEquals(base64Digest, b64);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,20 +28,20 @@ import org.testng.annotations.Test;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This performs the same test as {@link S3ConnectionTest}, except using SSL.
|
* This performs the same test as {@link S3ConnectionIntegrationTest}, except using SSL.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "s3.SecureS3ConnectionTest")
|
@Test(groups = {"live"}, testName = "s3.SecureS3ConnectionIntegrationTest")
|
||||||
public class SecureS3ConnectionTest extends S3ConnectionTest {
|
public class SecureS3ConnectionIntegrationTest extends S3ConnectionIntegrationTest {
|
||||||
@Override
|
@Override
|
||||||
protected Properties buildS3Properties(String AWSAccessKeyId,
|
protected Properties buildS3Properties(String AWSAccessKeyId,
|
||||||
String AWSSecretAccessKey) {
|
String AWSSecretAccessKey) {
|
||||||
Properties properties = super.buildS3Properties(AWSAccessKeyId,
|
Properties properties = super.buildS3Properties(AWSAccessKeyId,
|
||||||
AWSSecretAccessKey);
|
AWSSecretAccessKey);
|
||||||
properties.setProperty("jclouds.http.secure", Boolean.toString(true));
|
properties.setProperty("jclouds.http.secure", Boolean.toString(true));
|
||||||
properties.setProperty("jclouds.http.port", "443");
|
properties.setProperty("jclouds.http.port", "443");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,25 +23,32 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.google.common.base.Function;
|
||||||
import java.util.HashSet;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.List;
|
import com.google.common.base.Predicate;
|
||||||
import java.util.Map;
|
import com.google.common.collect.Iterables;
|
||||||
import java.util.Set;
|
import com.google.common.collect.Lists;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import com.google.common.collect.Sets;
|
||||||
import java.util.concurrent.ExecutionException;
|
import com.thoughtworks.xstream.XStream;
|
||||||
import java.util.concurrent.Future;
|
import org.apache.commons.io.IOUtils;
|
||||||
import java.util.concurrent.TimeUnit;
|
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||||
import java.util.concurrent.TimeoutException;
|
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||||
|
import org.jclouds.aws.s3.commands.CopyObject;
|
||||||
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
|
import org.jclouds.aws.s3.commands.options.*;
|
||||||
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
|
|
||||||
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.S3Bucket.Metadata;
|
import org.jclouds.aws.s3.domain.S3Bucket.Metadata;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO: Adrian: Document this!
|
* // TODO: Adrian: Document this!
|
||||||
|
@ -49,200 +56,426 @@ import org.jclouds.aws.s3.domain.S3Bucket.Metadata;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class StubS3Connection implements S3Connection {
|
public class StubS3Connection implements S3Connection {
|
||||||
private static Map<String, Map<String, Object>> bucketToContents = new ConcurrentHashMap<String, Map<String, Object>>();
|
private static Map<String, Map<String, S3Object>> bucketToContents = new ConcurrentHashMap<String, Map<String, S3Object>>();
|
||||||
|
private static Map<String, Metadata.LocationConstraint> bucketToLocation = new ConcurrentHashMap<String, Metadata.LocationConstraint>();
|
||||||
|
private static Map<String, CannedAccessPolicy> keyToAcl = new ConcurrentHashMap<String, CannedAccessPolicy>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.io.IOException
|
||||||
|
*/
|
||||||
|
public static byte[] toByteArray(Object data) throws IOException {
|
||||||
|
checkNotNull(data, "data must be set before calling generateMd5()");
|
||||||
|
byte[] bytes = null;
|
||||||
|
if (data == null || data instanceof byte[]) {
|
||||||
|
bytes = (byte[]) data;
|
||||||
|
} else if (data instanceof String) {
|
||||||
|
bytes = ((String) data).getBytes();
|
||||||
|
} else if (data instanceof File || data instanceof InputStream) {
|
||||||
|
InputStream io = (data instanceof InputStream) ? (InputStream) data : new FileInputStream((File) data);
|
||||||
|
bytes = IOUtils.toByteArray(io);
|
||||||
|
IOUtils.closeQuietly(io);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("Content not supported "
|
||||||
|
+ data.getClass());
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public Future<S3Object> getObject(final String s3Bucket, final String key) {
|
public Future<S3Object> getObject(final String s3Bucket, final String key) {
|
||||||
return new FutureBase<S3Object>() {
|
return getObject(s3Bucket, key, new GetObjectOptions());
|
||||||
public S3Object get() throws InterruptedException,
|
|
||||||
ExecutionException {
|
}
|
||||||
if (!bucketToContents.containsKey(s3Bucket))
|
|
||||||
return S3Object.NOT_FOUND;
|
public S3Object.Metadata copy(S3Object.Metadata in) {
|
||||||
Map<String, Object> realContents = bucketToContents
|
return (S3Object.Metadata) xstream.fromXML(xstream.toXML(in));
|
||||||
.get(s3Bucket);
|
}
|
||||||
if (!realContents.containsKey(key))
|
|
||||||
return S3Object.NOT_FOUND;
|
public S3Object.Metadata copy(S3Object.Metadata in, String newKey) {
|
||||||
S3Object object = new S3Object(key);
|
return (S3Object.Metadata) xstream.fromXML(xstream.toXML(in).replaceAll(in.getKey(), newKey));
|
||||||
object.setData(realContents.get(key));
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<S3Object.Metadata> headObject(final String s3Bucket,
|
public Future<S3Object.Metadata> headObject(final String s3Bucket,
|
||||||
final String key) {
|
final String key) {
|
||||||
return new FutureBase<S3Object.Metadata>() {
|
return new FutureBase<S3Object.Metadata>() {
|
||||||
public S3Object.Metadata get() throws InterruptedException,
|
public S3Object.Metadata get() throws InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
if (!bucketToContents.containsKey(s3Bucket))
|
if (!bucketToContents.containsKey(s3Bucket))
|
||||||
return S3Object.Metadata.NOT_FOUND;
|
return S3Object.Metadata.NOT_FOUND;
|
||||||
Map<String, Object> realContents = bucketToContents
|
Map<String, S3Object> realContents = bucketToContents
|
||||||
.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);
|
return realContents.get(key).getMetadata();
|
||||||
return metadata;
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> deleteObject(final String s3Bucket, final String key) {
|
public Future<Boolean> deleteObject(final String s3Bucket, final String key) {
|
||||||
return new FutureBase<Boolean>() {
|
return new FutureBase<Boolean>() {
|
||||||
public Boolean get() throws InterruptedException,
|
public Boolean get() throws InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
if (bucketToContents.containsKey(s3Bucket)) {
|
if (bucketToContents.containsKey(s3Bucket)) {
|
||||||
bucketToContents.get(s3Bucket).remove(key);
|
bucketToContents.get(s3Bucket).remove(key);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<byte[]> putObject(final String s3Bucket, final S3Object object) {
|
public Future<byte[]> putObject(final String s3Bucket, final S3Object object) {
|
||||||
return new FutureBase<byte[]>() {
|
return putObject(s3Bucket, object, new PutObjectOptions());
|
||||||
public byte[] get() throws InterruptedException, ExecutionException {
|
|
||||||
if (!bucketToContents.containsKey(s3Bucket)) {
|
|
||||||
throw new ExecutionException(new RuntimeException(
|
|
||||||
"bucket not found: " + s3Bucket));
|
|
||||||
}
|
|
||||||
bucketToContents.get(s3Bucket).put(object.getKey(),
|
|
||||||
object.getClass());
|
|
||||||
return object.getKey().getBytes();// todo actually md5
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> putBucketIfNotExists(final String s3Bucket) {
|
public Future<Boolean> putBucketIfNotExists(final String s3Bucket) {
|
||||||
return new FutureBase<Boolean>() {
|
return new FutureBase<Boolean>() {
|
||||||
public Boolean get() throws InterruptedException,
|
public Boolean get() throws InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
if (!bucketToContents.containsKey(s3Bucket)) {
|
if (!bucketToContents.containsKey(s3Bucket)) {
|
||||||
bucketToContents.put(s3Bucket,
|
bucketToContents.put(s3Bucket,
|
||||||
new ConcurrentHashMap<String, Object>());
|
new ConcurrentHashMap<String, S3Object>());
|
||||||
}
|
}
|
||||||
return bucketToContents.containsKey(s3Bucket);
|
return bucketToContents.containsKey(s3Bucket);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> deleteBucketIfEmpty(final String s3Bucket) {
|
public Future<Boolean> deleteBucketIfEmpty(final String s3Bucket) {
|
||||||
return new FutureBase<Boolean>() {
|
return new FutureBase<Boolean>() {
|
||||||
public Boolean get() throws InterruptedException,
|
public Boolean get() throws InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
if (bucketToContents.containsKey(s3Bucket)) {
|
if (bucketToContents.containsKey(s3Bucket)) {
|
||||||
if (bucketToContents.get(s3Bucket).size() == 0)
|
if (bucketToContents.get(s3Bucket).size() == 0)
|
||||||
return true;
|
bucketToContents.remove(s3Bucket);
|
||||||
}
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XStream xstream = new XStream();
|
||||||
|
|
||||||
public Future<S3Object.Metadata> copyObject(final String sourceBucket,
|
public Future<S3Object.Metadata> copyObject(final String sourceBucket,
|
||||||
final String sourceObject, final String destinationBucket,
|
final String sourceObject, final String destinationBucket,
|
||||||
final String destinationObject) {
|
final String destinationObject) {
|
||||||
return new FutureBase<S3Object.Metadata>() {
|
return copyObject(sourceBucket, sourceObject, destinationBucket, destinationObject, new CopyObjectOptions());
|
||||||
public S3Object.Metadata get() throws InterruptedException,
|
|
||||||
ExecutionException {
|
|
||||||
Map<String, Object> source = bucketToContents.get(sourceBucket);
|
|
||||||
Map<String, Object> dest = bucketToContents
|
|
||||||
.get(destinationBucket);
|
|
||||||
if (source.containsKey(sourceObject)) {
|
|
||||||
dest.put(destinationObject, source.get(sourceObject));
|
|
||||||
return new S3Object.Metadata(destinationObject);
|
|
||||||
}
|
|
||||||
return S3Object.Metadata.NOT_FOUND;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> bucketExists(final String s3Bucket) {
|
public Future<Boolean> bucketExists(final String s3Bucket) {
|
||||||
return new FutureBase<Boolean>() {
|
return new FutureBase<Boolean>() {
|
||||||
public Boolean get() throws InterruptedException,
|
public Boolean get() throws InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
return bucketToContents.containsKey(s3Bucket);
|
return bucketToContents.containsKey(s3Bucket);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<S3Bucket> listBucket(final String s3Bucket) {
|
public Future<S3Bucket> listBucket(final String s3Bucket) {
|
||||||
return new FutureBase<S3Bucket>() {
|
return listBucket(s3Bucket, new ListBucketOptions());
|
||||||
public S3Bucket get() throws InterruptedException,
|
|
||||||
ExecutionException {
|
|
||||||
Set<S3Object.Metadata> contents = new HashSet<S3Object.Metadata>();
|
|
||||||
Map<String, Object> realContents = bucketToContents
|
|
||||||
.get(s3Bucket);
|
|
||||||
if (realContents != null) {
|
|
||||||
for (String key : realContents.keySet()) {
|
|
||||||
S3Object.Metadata metadata = new S3Object.Metadata(key);
|
|
||||||
contents.add(metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
S3Bucket returnVal = new S3Bucket(s3Bucket);
|
|
||||||
returnVal.setContents(contents);
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class FutureBase<V> implements Future<V> {
|
private abstract class FutureBase<V> implements Future<V> {
|
||||||
public boolean cancel(boolean b) {
|
public boolean cancel(boolean b) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public V get(long l, TimeUnit timeUnit) throws InterruptedException,
|
public V get(long l, TimeUnit timeUnit) throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
return get();
|
return get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<List<Metadata>> listOwnedBuckets() {
|
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 {
|
||||||
List<S3Bucket.Metadata> list = new ArrayList<S3Bucket.Metadata>();
|
return Lists.newArrayList(Iterables.transform(
|
||||||
for (String name : bucketToContents.keySet())
|
bucketToContents.keySet(),
|
||||||
list.add(new S3Bucket.Metadata(name));
|
new Function<String, Metadata>() {
|
||||||
return list;
|
public Metadata apply(String name) {
|
||||||
}
|
return new S3Bucket.Metadata(name);
|
||||||
};
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> putBucketIfNotExists(String name,
|
public Future<Boolean> putBucketIfNotExists(String name,
|
||||||
PutBucketOptions options) {
|
PutBucketOptions options) {
|
||||||
throw new UnsupportedOperationException("todo");
|
if (options.getLocationConstraint() != null)
|
||||||
|
bucketToLocation.put(name, options.getLocationConstraint());
|
||||||
|
keyToAcl.put(name, options.getAcl());
|
||||||
|
return putBucketIfNotExists(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<S3Bucket> listBucket(String name, ListBucketOptions options) {
|
class DelimiterFilter implements Predicate<S3Object.Metadata> {
|
||||||
throw new UnsupportedOperationException("todo");
|
private final String prefix;
|
||||||
|
private final String delimiter;
|
||||||
|
|
||||||
|
DelimiterFilter(String prefix, String delimiter) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.delimiter = delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(S3Object.Metadata metadata) {
|
||||||
|
if (prefix == null)
|
||||||
|
return metadata.getKey().indexOf(delimiter) == -1;
|
||||||
|
if (metadata.getKey().startsWith(prefix))
|
||||||
|
return metadata.getKey().replaceFirst(prefix, "").indexOf(delimiter) == -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommonPrefixes implements Function<S3Object.Metadata, String> {
|
||||||
|
private final String prefix;
|
||||||
|
private final String delimiter;
|
||||||
|
static final String NO_PREFIX = "NO_PREFIX";
|
||||||
|
|
||||||
|
CommonPrefixes(String prefix, String delimiter) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.delimiter = delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String apply(S3Object.Metadata metadata) {
|
||||||
|
String working = metadata.getKey();
|
||||||
|
|
||||||
|
if (prefix != null) {
|
||||||
|
if (working.startsWith(prefix)) {
|
||||||
|
working = working.replaceFirst(prefix, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (working.contains(delimiter)) {
|
||||||
|
return working.substring(0, working.indexOf(delimiter));
|
||||||
|
}
|
||||||
|
return NO_PREFIX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<S3Bucket> listBucket(final String name, final ListBucketOptions options) {
|
||||||
|
return new FutureBase<S3Bucket>() {
|
||||||
|
public S3Bucket get() throws InterruptedException,
|
||||||
|
ExecutionException {
|
||||||
|
final Map<String, S3Object> realContents = bucketToContents
|
||||||
|
.get(name);
|
||||||
|
|
||||||
|
if (realContents == null) return S3Bucket.NOT_FOUND;
|
||||||
|
SortedSet<S3Object.Metadata> contents = Sets.newTreeSet(
|
||||||
|
Iterables.transform(realContents.keySet(),
|
||||||
|
new Function<String, S3Object.Metadata>() {
|
||||||
|
public S3Object.Metadata apply(String key) {
|
||||||
|
return realContents.get(key).getMetadata();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
S3Bucket returnVal = new S3Bucket(name);
|
||||||
|
|
||||||
|
if (options.getMarker() != null) {
|
||||||
|
contents = contents.tailSet(new S3Object.Metadata(URLDecoder.decode(options.getMarker())));
|
||||||
|
// amazon spec means after the marker, not including it.
|
||||||
|
contents.remove(new S3Object.Metadata(options.getMarker()));
|
||||||
|
returnVal.setMarker(URLDecoder.decode(options.getMarker()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (options.getPrefix() != null) {
|
||||||
|
contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<S3Object.Metadata>() {
|
||||||
|
|
||||||
|
public boolean apply(S3Object.Metadata o) {
|
||||||
|
return (o != null && o.getKey().startsWith(URLDecoder.decode(options.getPrefix())));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
returnVal.setPrefix(URLDecoder.decode(options.getPrefix()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.getDelimiter() != null) {
|
||||||
|
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(
|
||||||
|
options.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null, URLDecoder.decode(options.getDelimiter())));
|
||||||
|
Set<String> commonPrefixes = iterable != null ? Sets.newTreeSet(iterable) : new HashSet<String>();
|
||||||
|
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
|
||||||
|
|
||||||
|
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(
|
||||||
|
options.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null, URLDecoder.decode(options.getDelimiter()))));
|
||||||
|
|
||||||
|
returnVal.setCommonPrefixes(commonPrefixes);
|
||||||
|
returnVal.setDelimiter(URLDecoder.decode(options.getDelimiter()));
|
||||||
|
}
|
||||||
|
if (options.getMaxKeys() != null) {
|
||||||
|
contents = firstSliceOfSize(contents, Integer.parseInt(options.getMaxKeys()));
|
||||||
|
returnVal.setMaxKeys(Integer.parseInt(options.getMaxKeys()));
|
||||||
|
returnVal.setTruncated(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
returnVal.setContents(contents);
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Comparable> SortedSet<T> firstSliceOfSize(Iterable<T> elements, int size) {
|
||||||
|
List<List<T>> slices = Lists.partition(
|
||||||
|
Lists.newArrayList(elements), size);
|
||||||
|
return Sets.newTreeSet(slices.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<org.jclouds.aws.s3.domain.S3Object.Metadata> copyObject(
|
public Future<org.jclouds.aws.s3.domain.S3Object.Metadata> copyObject(
|
||||||
String sourceBucket, String sourceObject, String destinationBucket,
|
final String sourceBucket, final String sourceObject, final String destinationBucket,
|
||||||
String destinationObject, CopyObjectOptions options) {
|
final String destinationObject, final CopyObjectOptions options) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
return new FutureBase<S3Object.Metadata>() {
|
||||||
|
public S3Object.Metadata get() throws InterruptedException,
|
||||||
|
ExecutionException {
|
||||||
|
Map<String, S3Object> source = bucketToContents.get(sourceBucket);
|
||||||
|
Map<String, S3Object> dest = bucketToContents
|
||||||
|
.get(destinationBucket);
|
||||||
|
if (source.containsKey(sourceObject)) {
|
||||||
|
S3Object object = source.get(sourceObject);
|
||||||
|
if (options.getIfMatch() != null) {
|
||||||
|
if (!Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfMatch().replaceAll("\"", ""))))
|
||||||
|
throwResponseException(412);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (options.getIfNoneMatch() != null) {
|
||||||
|
if (Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfNoneMatch().replaceAll("\"", ""))))
|
||||||
|
throwResponseException(412);
|
||||||
|
}
|
||||||
|
if (options.getIfModifiedSince() != null) {
|
||||||
|
DateTime modifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfModifiedSince());
|
||||||
|
if (modifiedSince.isAfter(object.getMetadata().getLastModified()))
|
||||||
|
throw new ExecutionException(new RuntimeException("after"));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (options.getIfUnmodifiedSince() != null) {
|
||||||
|
DateTime unmodifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfUnmodifiedSince());
|
||||||
|
if (unmodifiedSince.isAfter(object.getMetadata().getLastModified()))
|
||||||
|
throw new ExecutionException(new RuntimeException("after"));
|
||||||
|
}
|
||||||
|
S3Object sourceS3 = source.get(sourceObject);
|
||||||
|
S3Object.Metadata newMd = copy(sourceS3.getMetadata(), destinationObject);
|
||||||
|
if (options.getAcl() != null)
|
||||||
|
keyToAcl.put(destinationBucket + destinationObject, options.getAcl());
|
||||||
|
if (options.getMetadata() != null) {
|
||||||
|
newMd.setUserMetadata(options.getMetadata());
|
||||||
|
}
|
||||||
|
newMd.setLastModified(new DateTime());
|
||||||
|
dest.put(destinationObject, new S3Object(newMd,
|
||||||
|
sourceS3.getData()));
|
||||||
|
return copy(newMd);
|
||||||
|
}
|
||||||
|
return S3Object.Metadata.NOT_FOUND;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<byte[]> putObject(String bucketName, S3Object object,
|
private void throwResponseException(int code) throws ExecutionException {
|
||||||
PutObjectOptions options) {
|
HttpResponse response = new HttpResponse();
|
||||||
// TODO Auto-generated method stub
|
response.setStatusCode(code);
|
||||||
return null;
|
throw new ExecutionException(
|
||||||
|
new HttpResponseException(createNiceMock(CopyObject.class), response));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<S3Object> getObject(String bucketName, String key,
|
public Future<byte[]> putObject(final String bucketName, final S3Object object,
|
||||||
GetObjectOptions options) {
|
final PutObjectOptions options) {
|
||||||
// TODO Auto-generated method stub
|
if (!bucketToContents.containsKey(bucketName)) {
|
||||||
return null;
|
new RuntimeException(
|
||||||
|
"bucketName not found: " + bucketName);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
S3Object.Metadata newMd = copy(object.getMetadata());
|
||||||
|
newMd.setLastModified(new DateTime());
|
||||||
|
byte[] data = toByteArray(object.getData());
|
||||||
|
final byte[] md5 = S3Utils.md5(data);
|
||||||
|
newMd.setMd5(md5);
|
||||||
|
newMd.setContentType("binary/octet-stream");
|
||||||
|
if (options.getAcl() != null)
|
||||||
|
keyToAcl.put(bucketName + object, options.getAcl());
|
||||||
|
bucketToContents.get(bucketName).put(object.getKey(),
|
||||||
|
new S3Object(newMd, data));
|
||||||
|
return new FutureBase<byte[]>() {
|
||||||
|
public byte[] get() throws InterruptedException, ExecutionException {
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DateService dateService = new DateService();
|
||||||
|
|
||||||
|
public Future<S3Object> getObject(final String bucketName, final String key,
|
||||||
|
final GetObjectOptions options) {
|
||||||
|
return new FutureBase<S3Object>() {
|
||||||
|
public S3Object get() throws InterruptedException,
|
||||||
|
ExecutionException {
|
||||||
|
if (!bucketToContents.containsKey(bucketName))
|
||||||
|
return S3Object.NOT_FOUND;
|
||||||
|
Map<String, S3Object> realContents = bucketToContents
|
||||||
|
.get(bucketName);
|
||||||
|
if (!realContents.containsKey(key))
|
||||||
|
return S3Object.NOT_FOUND;
|
||||||
|
|
||||||
|
S3Object object = realContents.get(key);
|
||||||
|
|
||||||
|
if (options.getIfMatch() != null) {
|
||||||
|
if (!Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfMatch().replaceAll("\"", ""))))
|
||||||
|
throwResponseException(412);
|
||||||
|
}
|
||||||
|
if (options.getIfNoneMatch() != null) {
|
||||||
|
if (Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfNoneMatch().replaceAll("\"", ""))))
|
||||||
|
throwResponseException(304);
|
||||||
|
}
|
||||||
|
if (options.getIfModifiedSince() != null) {
|
||||||
|
DateTime modifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfModifiedSince());
|
||||||
|
if (modifiedSince.isAfter(object.getMetadata().getLastModified()))
|
||||||
|
throw new ExecutionException(new RuntimeException("after"));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (options.getIfUnmodifiedSince() != null) {
|
||||||
|
DateTime unmodifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfUnmodifiedSince());
|
||||||
|
if (unmodifiedSince.isAfter(object.getMetadata().getLastModified()))
|
||||||
|
throw new ExecutionException(new RuntimeException("after"));
|
||||||
|
}
|
||||||
|
S3Object returnVal = new S3Object(copy(object.getMetadata()), object.getData());
|
||||||
|
if (options.getRange() != null) {
|
||||||
|
byte[] data = (byte[]) returnVal.getData();
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
for (String s : options.getRange().replaceAll("bytes=", "").split(",")) {
|
||||||
|
if (s.startsWith("-")) {
|
||||||
|
int length = Integer.parseInt(s.replaceAll("\\-", ""));
|
||||||
|
out.write(data, data.length - length, length);
|
||||||
|
} else if (s.endsWith("-")) {
|
||||||
|
int offset = Integer.parseInt(s.replaceAll("\\-", ""));
|
||||||
|
out.write(data, offset, data.length - offset);
|
||||||
|
} else if (s.contains("-")) {
|
||||||
|
String[] firstLast = s.split("\\-");
|
||||||
|
int offset = Integer.parseInt(firstLast[0]);
|
||||||
|
int last = Integer.parseInt(firstLast[1]);
|
||||||
|
int length = (last < data.length) ? last + 1 : data.length - offset;
|
||||||
|
|
||||||
|
out.write(data, offset, length);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("first and last were null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
returnVal.setData(out.toByteArray());
|
||||||
|
returnVal.setContentLength(out.size());
|
||||||
|
returnVal.getMetadata().setSize(data.length);
|
||||||
|
}
|
||||||
|
returnVal.setData(new ByteArrayInputStream((byte[]) returnVal.getData()));
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all bucketExists commands.
|
* Tests integrated functionality of all bucketExists commands.
|
||||||
|
@ -35,23 +36,22 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.BucketExistsIntegrationTest")
|
@Test(groups = {"integration", "live"}, testName = "s3.BucketExistsIntegrationTest")
|
||||||
public class BucketExistsIntegrationTest extends S3IntegrationTest {
|
public class BucketExistsIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
@Test
|
||||||
void bucketDoesntExist() throws Exception {
|
void bucketDoesntExist() throws Exception {
|
||||||
String bucketName = bucketPrefix + "shouldntexist";
|
String bucketName= bucketPrefix+"be";
|
||||||
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test
|
||||||
void bucketExists() throws Exception {
|
void bucketExists() throws Exception {
|
||||||
String bucketName = bucketPrefix + "needstoexist";
|
String bucketName= bucketPrefix+"bde";
|
||||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,32 +23,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
import com.google.common.collect.HashMultimap;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
import com.google.common.collect.Multimap;
|
||||||
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.overrideAcl;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.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.reference.S3Headers;
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import com.google.common.collect.HashMultimap;
|
import java.net.URL;
|
||||||
import com.google.common.collect.Multimap;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all copyObject commands.
|
* Tests integrated functionality of all copyObject commands.
|
||||||
|
@ -57,185 +49,159 @@ import com.google.common.collect.Multimap;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.CopyObjectIntegrationTest")
|
@Test(testName = "s3.CopyObjectIntegrationTest")
|
||||||
public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
String sourceKey = "apples";
|
String sourceKey = "apples";
|
||||||
String destinationKey = "pears";
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
@Test(groups = {"integration","live"})
|
||||||
@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()
|
|
||||||
void testCopyObject() throws Exception {
|
void testCopyObject() throws Exception {
|
||||||
String sourceBucket = bucketPrefix + "testcopyobject";
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
|
||||||
|
|
||||||
setupSourceBucket(sourceBucket, sourceKey);
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
|
||||||
destinationKey).get(10, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
|
destinationKey).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupSourceBucket(String sourceBucket, String sourceKey)
|
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
private void addToBucketAndValidate(String bucketName, String sourceKey)
|
||||||
IOException {
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
createBucketAndEnsureEmpty(sourceBucket);
|
IOException {
|
||||||
addToBucketAndValidate(sourceBucket, sourceKey);
|
addObjectToBucket(bucketName, sourceKey);
|
||||||
|
validateContent(bucketName, sourceKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToBucketAndValidate(String sourceBucket, String sourceKey)
|
@Test(groups = {"integration","live"})
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
|
||||||
IOException {
|
|
||||||
addObjectToBucket(sourceBucket, sourceKey);
|
|
||||||
validateContent(sourceBucket, sourceKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCopyIfModifiedSince() throws InterruptedException,
|
void testCopyIfModifiedSince() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, IOException {
|
ExecutionException, TimeoutException, IOException {
|
||||||
String sourceBucket = bucketPrefix + "tcims";
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
|
||||||
|
|
||||||
DateTime before = new DateTime();
|
String destinationBucket = bucketName + "dest";
|
||||||
setupSourceBucket(sourceBucket, sourceKey);
|
|
||||||
DateTime after = new DateTime().plusSeconds(1);
|
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
DateTime before = new DateTime();
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
|
||||||
|
|
||||||
try {
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
destinationKey, ifSourceModifiedSince(after)).get(10,
|
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
validateContent(destinationBucket, destinationKey);
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
try {
|
||||||
}
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceModifiedSince(after)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(groups = {"integration","live"})
|
||||||
void testCopyIfUnmodifiedSince() throws InterruptedException,
|
void testCopyIfUnmodifiedSince() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, IOException {
|
ExecutionException, TimeoutException, IOException {
|
||||||
String sourceBucket = bucketPrefix + "tcius";
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
|
||||||
|
|
||||||
DateTime before = new DateTime();
|
String destinationBucket = bucketName + "dest";
|
||||||
setupSourceBucket(sourceBucket, sourceKey);
|
|
||||||
DateTime after = new DateTime().plusSeconds(1);
|
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
DateTime before = new DateTime();
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
|
||||||
|
|
||||||
try {
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
validateContent(destinationBucket, destinationKey);
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
try {
|
||||||
}
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(groups = {"integration","live"})
|
||||||
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
String sourceBucket = bucketPrefix + "tcim";
|
|
||||||
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
|
||||||
|
|
||||||
setupSourceBucket(sourceBucket, sourceKey);
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
|
||||||
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
|
||||||
|
|
||||||
try {
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
validateContent(destinationBucket, destinationKey);
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
try {
|
||||||
}
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(groups = {"integration","live"})
|
||||||
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
String sourceBucket = bucketPrefix + "tcinm";
|
|
||||||
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
|
||||||
|
|
||||||
setupSourceBucket(sourceBucket, sourceKey);
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
|
||||||
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
|
||||||
|
|
||||||
try {
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
|
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
validateContent(destinationBucket, destinationKey);
|
||||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
|
||||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
try {
|
||||||
}
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(groups = {"integration","live"})
|
||||||
void testCopyWithMetadata() throws InterruptedException,
|
void testCopyWithMetadata() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, IOException {
|
ExecutionException, TimeoutException, IOException {
|
||||||
String sourceBucket = bucketPrefix + "tcwm";
|
|
||||||
String destinationBucket = sourceBucket + "dest";
|
|
||||||
|
|
||||||
setupSourceBucket(sourceBucket, sourceKey);
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
Multimap<String, String> metadata = HashMultimap.create();
|
addToBucketAndValidate(bucketName, sourceKey);
|
||||||
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
|
||||||
|
|
||||||
createBucketAndEnsureEmpty(destinationBucket);
|
Multimap<String, String> metadata = HashMultimap.create();
|
||||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
||||||
destinationKey, overrideMetadataWith(metadata)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
validateContent(destinationBucket, destinationKey);
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||||
|
destinationKey, overrideMetadataWith(metadata)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
|
validateContent(destinationBucket, destinationKey);
|
||||||
destinationKey).get(10, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
assertEquals(objectMeta.getUserMetadata(), metadata);
|
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
|
||||||
|
destinationKey).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
assertEquals(objectMeta.getUserMetadata(), metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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 org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideAcl;
|
||||||
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests integrated functionality of all copyObject commands.
|
||||||
|
* <p/>
|
||||||
|
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||||
|
* in parallel.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(testName = "s3.CopyObjectLiveTest")
|
||||||
|
public class CopyObjectLiveTest extends S3IntegrationTest {
|
||||||
|
String sourceKey = "apples";
|
||||||
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
|
||||||
|
@Test(groups = "live")
|
||||||
|
void testCannedAccessPolicyPublic() throws Exception {
|
||||||
|
String destinationBucket = bucketName + "dest";
|
||||||
|
|
||||||
|
addObjectToBucket(bucketName, sourceKey);
|
||||||
|
validateContent(bucketName, sourceKey);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(bucketName, 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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,11 +23,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all deleteBucket commands.
|
* Tests integrated functionality of all deleteBucket commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -35,30 +35,28 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.DeleteBucketIntegrationTest")
|
@Test(groups = {"integration", "live"}, testName = "s3.DeleteBucketIntegrationTest")
|
||||||
public class DeleteBucketIntegrationTest extends S3IntegrationTest {
|
public class DeleteBucketIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
@Test
|
||||||
|
/**
|
||||||
|
* this method overrides bucketName to ensure it isn't found
|
||||||
|
*/
|
||||||
void deleteBucketIfEmptyNotFound() throws Exception {
|
void deleteBucketIfEmptyNotFound() throws Exception {
|
||||||
String bucketName = bucketPrefix + "dbienf";
|
String bucketName = bucketPrefix + "dbienf";
|
||||||
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void deleteBucketIfEmptyButHasContents() throws Exception {
|
void deleteBucketIfEmptyButHasContents() throws Exception {
|
||||||
String bucketName = bucketPrefix + "dbiebhc";
|
addObjectToBucket(bucketName, "test");
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
assert !client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
addObjectToBucket(bucketName,"test");
|
|
||||||
assert !client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void deleteBucketIfEmpty() throws Exception {
|
void deleteBucketIfEmpty() throws Exception {
|
||||||
String bucketName = bucketPrefix + "dbie";
|
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||||
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
|
||||||
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,14 +23,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
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.S3IntegrationTest;
|
||||||
import org.jclouds.aws.s3.S3ResponseException;
|
import org.jclouds.aws.s3.S3ResponseException;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.testng.annotations.Test;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all deleteObject commands.
|
* Tests integrated functionality of all deleteObject commands.
|
||||||
|
@ -39,40 +39,39 @@ import static org.testng.Assert.assertEquals;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.DeleteObjectIntegrationTest")
|
@Test(groups = {"integration", "live"}, testName = "s3.DeleteObjectIntegrationTest")
|
||||||
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void deleteObjectNotFound() throws Exception {
|
void deleteObjectNotFound() throws Exception {
|
||||||
String bucketName = bucketPrefix + "donf";
|
String bucketName = bucketPrefix + "donf";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
addObjectToBucket(bucketName, "test");
|
addObjectToBucket(bucketName, "test");
|
||||||
assert client.deleteObject(bucketName, "test")
|
assert client.deleteObject(bucketName, "test")
|
||||||
.get(10, TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deleteObjectNoBucket() throws Exception {
|
void deleteObjectNoBucket() throws Exception {
|
||||||
String bucketName = bucketPrefix + "donb";
|
String bucketName = bucketPrefix + "donb";
|
||||||
try {
|
try {
|
||||||
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
assert e.getCause() instanceof S3ResponseException;
|
assert e.getCause() instanceof S3ResponseException;
|
||||||
assertEquals(((S3ResponseException) e.getCause()).getResponse()
|
assertEquals(((S3ResponseException) e.getCause()).getResponse()
|
||||||
.getStatusCode(), 404);
|
.getStatusCode(), 404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void deleteObject() throws Exception {
|
void deleteObject() throws Exception {
|
||||||
String bucketName = bucketPrefix + "do";
|
String bucketName = bucketPrefix + "do";
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
addObjectToBucket(bucketName, "test");
|
addObjectToBucket(bucketName, "test");
|
||||||
assert client.deleteObject(bucketName, "test")
|
assert client.deleteObject(bucketName, "test")
|
||||||
.get(10, TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
|
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@
|
||||||
* "License"); you may not use this file except in compliance
|
* "License"); you may not use this file except in compliance
|
||||||
* with the License. You may obtain a copy of the License at
|
* with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http:www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing,
|
||||||
* software distributed under the License is distributed on an
|
* software distributed under the License is distributed on an
|
||||||
|
@ -23,19 +23,21 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.S3ResponseException;
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
|
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
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.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all GetObject commands.
|
* Tests integrated functionality of all GetObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -43,192 +45,187 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.GetObjectIntegrationTest")
|
@Test(groups = {"integration", "live"}, 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
|
||||||
// @Test
|
void testGetIfModifiedSince() throws InterruptedException,
|
||||||
// void testGetIfUnmodifiedSince() throws InterruptedException,
|
ExecutionException, TimeoutException, IOException {
|
||||||
// ExecutionException, TimeoutException, IOException {
|
|
||||||
// String bucket = bucketPrefix + "testGetIfUnmodifiedSince".toLowerCase();
|
String key = "apples";
|
||||||
// String key = "apples";
|
|
||||||
//
|
DateTime before = new DateTime();
|
||||||
// DateTime before = new DateTime();
|
addObjectAndValidateContent(bucketName, key);
|
||||||
// setUpBucket(bucket, key);
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
// DateTime after = new DateTime().plusSeconds(1);
|
|
||||||
//
|
client.getObject(bucketName, key, ifModifiedSince(before)).get(10,
|
||||||
// client.getObject(bucket, key, ifUnmodifiedSince(after)).get(10,
|
TimeUnit.SECONDS);
|
||||||
// TimeUnit.SECONDS);
|
validateContent(bucketName, key);
|
||||||
// validateContent(bucket, key);
|
|
||||||
//
|
try {
|
||||||
// try {
|
client.getObject(bucketName, key, ifModifiedSince(after)).get(10,
|
||||||
// client.getObject(bucket, key, ifUnmodifiedSince(before)).get(10,
|
TimeUnit.SECONDS);
|
||||||
// TimeUnit.SECONDS);
|
validateContent(bucketName, key);
|
||||||
// validateContent(bucket, key);
|
} catch (ExecutionException e) {
|
||||||
// } catch (ExecutionException e) {
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
// if (e.getCause() instanceof S3ResponseException) {
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
// S3ResponseException ex = (S3ResponseException) e.getCause();
|
assertEquals(ex.getResponse().getStatusCode(), 304);
|
||||||
// assertEquals(ex.getResponse().getStatusCode(), 412);
|
} else {
|
||||||
// } else {
|
throw e;
|
||||||
// throw e;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
//
|
}
|
||||||
// }
|
|
||||||
//
|
@Test
|
||||||
// @Test
|
void testGetIfUnmodifiedSince() throws InterruptedException,
|
||||||
// void testGetIfMatch() throws InterruptedException, ExecutionException,
|
ExecutionException, TimeoutException, IOException {
|
||||||
// TimeoutException, IOException {
|
|
||||||
// String bucket = bucketPrefix + "testGetIfMatch".toLowerCase();
|
String key = "apples";
|
||||||
// String key = "apples";
|
|
||||||
//
|
DateTime before = new DateTime();
|
||||||
// setUpBucket(bucket, key);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
//
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
// client.getObject(bucket, key, ifMd5Matches(goodMd5)).get(10,
|
|
||||||
// TimeUnit.SECONDS);
|
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10,
|
||||||
// validateContent(bucket, key);
|
TimeUnit.SECONDS);
|
||||||
//
|
validateContent(bucketName, key);
|
||||||
// try {
|
|
||||||
// client.getObject(bucket, key, ifMd5Matches(badMd5)).get(10,
|
try {
|
||||||
// TimeUnit.SECONDS);
|
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10,
|
||||||
// validateContent(bucket, key);
|
TimeUnit.SECONDS);
|
||||||
// } catch (ExecutionException e) {
|
validateContent(bucketName, key);
|
||||||
// if (e.getCause() instanceof S3ResponseException) {
|
} catch (ExecutionException e) {
|
||||||
// S3ResponseException ex = (S3ResponseException) e.getCause();
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
// assertEquals(ex.getResponse().getStatusCode(), 412);
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
// } else {
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
// throw e;
|
} else {
|
||||||
// }
|
throw e;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Test
|
}
|
||||||
// void testGetIfNoneMatch() throws InterruptedException,
|
|
||||||
// ExecutionException,
|
@Test
|
||||||
// TimeoutException, IOException {
|
void testGetIfMatch() throws InterruptedException, ExecutionException,
|
||||||
// String bucket = bucketPrefix + "testGetIfNoneMatch".toLowerCase();
|
TimeoutException, IOException {
|
||||||
// String key = "apples";
|
|
||||||
//
|
String key = "apples";
|
||||||
// setUpBucket(bucket, key);
|
|
||||||
//
|
addObjectAndValidateContent(bucketName, key);
|
||||||
// client.getObject(bucket, key, ifMd5DoesntMatch(badMd5)).get(10,
|
|
||||||
// TimeUnit.SECONDS);
|
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10,
|
||||||
// validateContent(bucket, key);
|
TimeUnit.SECONDS);
|
||||||
//
|
validateContent(bucketName, key);
|
||||||
// try {
|
|
||||||
// client.getObject(bucket, key, ifMd5DoesntMatch(goodMd5)).get(10,
|
try {
|
||||||
// TimeUnit.SECONDS);
|
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10,
|
||||||
// validateContent(bucket, key);
|
TimeUnit.SECONDS);
|
||||||
// } catch (ExecutionException e) {
|
validateContent(bucketName, key);
|
||||||
// if (e.getCause() instanceof HttpResponseException) {
|
} catch (ExecutionException e) {
|
||||||
// HttpResponseException ex = (HttpResponseException) e.getCause();
|
if (e.getCause() instanceof HttpResponseException) {
|
||||||
// assertEquals(ex.getResponse().getStatusCode(), 304);
|
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||||
// } else {
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
// throw e;
|
} else {
|
||||||
// }
|
throw e;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetIfNoneMatch() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
|
||||||
|
String key = "apples";
|
||||||
|
|
||||||
|
addObjectAndValidateContent(bucketName, key);
|
||||||
|
|
||||||
|
client.getObject(bucketName, key, ifMd5DoesntMatch(badMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
validateContent(bucketName, key);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.getObject(bucketName, key, ifMd5DoesntMatch(goodMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
validateContent(bucketName, 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 testGetRange() throws InterruptedException, ExecutionException,
|
void testGetRange() throws InterruptedException, ExecutionException,
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
String bucket = bucketPrefix + "testGetRange".toLowerCase();
|
|
||||||
String key = "apples";
|
|
||||||
|
|
||||||
setUpBucket(bucket, key);
|
String key = "apples";
|
||||||
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,
|
addObjectAndValidateContent(bucketName, key);
|
||||||
range(5, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10,
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
|
TimeUnit.SECONDS);
|
||||||
.substring(5, TEST_STRING.length()));
|
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
|
||||||
|
.substring(0, 6));
|
||||||
|
|
||||||
|
S3Object object2 = client.getObject(bucketName, key,
|
||||||
|
range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
|
||||||
|
.substring(6, TEST_STRING.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
String bucket = bucketPrefix + "testGetTwoRanges".toLowerCase();
|
|
||||||
String key = "apples";
|
|
||||||
|
|
||||||
setUpBucket(bucket, key);
|
String key = "apples";
|
||||||
S3Object object = client.getObject(bucket, key,
|
|
||||||
range(0, 5).range(5, TEST_STRING.length())).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
|
S3Object object = client.getObject(bucketName, key,
|
||||||
|
range(0, 5).range(6, TEST_STRING.length())).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTail() throws InterruptedException, ExecutionException,
|
void testGetTail() throws InterruptedException, ExecutionException,
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
String bucket = bucketPrefix + "testGetTail".toLowerCase();
|
|
||||||
String key = "apples";
|
|
||||||
|
|
||||||
setUpBucket(bucket, key);
|
String key = "apples";
|
||||||
S3Object object = client.getObject(bucket, key, tail(5)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
S3Object object = client.getObject(bucketName, key, tail(5)).get(10,
|
||||||
.substring(TEST_STRING.length() - 5));
|
TimeUnit.SECONDS);
|
||||||
assertEquals(object.getContentLength(), 5);
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||||
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
.substring(TEST_STRING.length() - 5));
|
||||||
|
assertEquals(object.getContentLength(), 5);
|
||||||
|
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetStartAt() throws InterruptedException, ExecutionException,
|
void testGetStartAt() throws InterruptedException, ExecutionException,
|
||||||
TimeoutException, IOException {
|
TimeoutException, IOException {
|
||||||
String bucket = bucketPrefix + "testGetStartAt".toLowerCase();
|
|
||||||
String key = "apples";
|
|
||||||
|
|
||||||
setUpBucket(bucket, key);
|
String key = "apples";
|
||||||
S3Object object = client.getObject(bucket, key, startAt(5)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
addObjectAndValidateContent(bucketName, key);
|
||||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10,
|
||||||
.substring(5, TEST_STRING.length()));
|
TimeUnit.SECONDS);
|
||||||
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||||
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
.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 addObjectAndValidateContent(String sourcebucketName, String sourceKey)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
createBucketAndEnsureEmpty(sourceBucket);
|
addObjectToBucket(sourcebucketName, sourceKey);
|
||||||
addObjectToBucket(sourceBucket, sourceKey);
|
validateContent(sourcebucketName, sourceKey);
|
||||||
validateContent(sourceBucket, sourceKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,23 +23,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.delimiter;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.afterMarker;
|
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.*;
|
||||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.withPrefix;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.maxResults;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
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.S3IntegrationTest;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all getBucket commands.
|
* Tests integrated functionality of all getBucket commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -47,92 +42,93 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.ListBucketIntegrationTest")
|
@Test(groups = {"integration", "live"}, testName = "s3.ListBucketIntegrationTest")
|
||||||
public class ListBucketIntegrationTest extends S3IntegrationTest {
|
public class ListBucketIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void testListBucketDelimiter() throws InterruptedException,
|
void testListBucketDelimiter() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||||
String bucketName = bucketPrefix + "delimiter";
|
String prefix = "apps";
|
||||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
addTenObjectsUnderPrefix(bucketName, prefix);
|
||||||
TimeUnit.SECONDS);
|
add15UnderRoot(bucketName);
|
||||||
String prefix = "apps";
|
S3Bucket bucket = client.listBucket(bucketName, delimiter("/")).get(10,
|
||||||
addTenObjectsUnderPrefix(bucketName, prefix);
|
TimeUnit.SECONDS);
|
||||||
add15UnderRoot(bucketName);
|
assertEquals(bucket.getDelimiter(), "/");
|
||||||
S3Bucket bucket = client.listBucket(bucketName, delimiter("/")).get(10,
|
assert !bucket.isTruncated();
|
||||||
TimeUnit.SECONDS);
|
assertEquals(bucket.getContents().size(), 15);
|
||||||
assertEquals(bucket.getDelimiter(), "/");
|
assertEquals(bucket.getCommonPrefixes().size(), 1);
|
||||||
assertEquals(bucket.getContents().size(), 15);
|
|
||||||
assertEquals(bucket.getCommonPrefixes().size(), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAlphabetUnderRoot(String bucketName)
|
private void addAlphabetUnderRoot(String bucketName)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
for (char letter = 'a'; letter <= 'z'; letter++) {
|
for (char letter = 'a'; letter <= 'z'; letter++) {
|
||||||
client.putObject(bucketName,
|
client.putObject(bucketName,
|
||||||
new S3Object(letter + "", letter + "content")).get(10,
|
new S3Object(letter + "", letter + "content")).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testListBucketMarker() throws InterruptedException,
|
void testListBucketMarker() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||||
String bucketName = bucketPrefix + "marker";
|
addAlphabetUnderRoot(bucketName);
|
||||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
S3Bucket bucket = client.listBucket(bucketName, afterMarker("y")).get(
|
||||||
TimeUnit.SECONDS);
|
10, TimeUnit.SECONDS);
|
||||||
addAlphabetUnderRoot(bucketName);
|
assertEquals(bucket.getMarker(), "y");
|
||||||
S3Bucket bucket = client.listBucket(bucketName, afterMarker("y")).get(
|
assert !bucket.isTruncated();
|
||||||
10, TimeUnit.SECONDS);
|
assertEquals(bucket.getContents().size(), 1);
|
||||||
assertEquals(bucket.getMarker(), "y");
|
|
||||||
assertEquals(bucket.getContents().size(), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testListBucketMaxResults() throws InterruptedException,
|
void testListBucketMaxResults() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||||
String bucketName = bucketPrefix + "max";
|
addAlphabetUnderRoot(bucketName);
|
||||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
S3Bucket bucket = client.listBucket(bucketName, maxResults(5)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
addAlphabetUnderRoot(bucketName);
|
assertEquals(bucket.getMaxKeys(), 5);
|
||||||
S3Bucket bucket = client.listBucket(bucketName, maxResults(5)).get(10,
|
assert bucket.isTruncated();
|
||||||
TimeUnit.SECONDS);
|
assertEquals(bucket.getContents().size(), 5);
|
||||||
assertEquals(bucket.getMaxKeys(), 5);
|
|
||||||
assertEquals(bucket.getContents().size(), 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void testListBucketPrefix() throws InterruptedException,
|
void testListBucketPrefix() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||||
String bucketName = bucketPrefix + "prefix";
|
String prefix = "apps";
|
||||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
addTenObjectsUnderPrefix(bucketName, prefix);
|
||||||
TimeUnit.SECONDS);
|
add15UnderRoot(bucketName);
|
||||||
String prefix = "apps";
|
|
||||||
addTenObjectsUnderPrefix(bucketName, prefix);
|
|
||||||
add15UnderRoot(bucketName);
|
|
||||||
|
|
||||||
S3Bucket bucket = client.listBucket(bucketName, withPrefix("apps/"))
|
S3Bucket bucket = client.listBucket(bucketName, withPrefix("apps/"))
|
||||||
.get(10, TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
assertEquals(bucket.getContents().size(), 10);
|
assert !bucket.isTruncated();
|
||||||
assertEquals(bucket.getPrefix(), "apps/");
|
assertEquals(bucket.getContents().size(), 10);
|
||||||
|
assertEquals(bucket.getPrefix(), "apps/");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
void testListBucket() throws InterruptedException,
|
||||||
|
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||||
|
String prefix = "apps";
|
||||||
|
addTenObjectsUnderPrefix(bucketName, prefix);
|
||||||
|
S3Bucket bucket = client.listBucket(bucketName)
|
||||||
|
.get(10, TimeUnit.SECONDS);
|
||||||
|
assertEquals(bucket.getContents().size(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
private void add15UnderRoot(String bucketName) throws InterruptedException,
|
private void add15UnderRoot(String bucketName) throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
for (int i = 0; i < 15; i++)
|
for (int i = 0; i < 15; i++)
|
||||||
client.putObject(bucketName, new S3Object(i + "", i + "content"))
|
client.putObject(bucketName, new S3Object(i + "", i + "content"))
|
||||||
.get(10, TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTenObjectsUnderPrefix(String bucketName, String prefix)
|
private void addTenObjectsUnderPrefix(String bucketName, String prefix)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
client.putObject(bucketName,
|
client.putObject(bucketName,
|
||||||
new S3Object(prefix + "/" + i, i + "content")).get(10,
|
new S3Object(prefix + "/" + i, i + "content")).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,13 +23,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
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.S3IntegrationTest;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all listOwnedBucket commands.
|
* Tests integrated functionality of all listOwnedBucket commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -37,30 +37,29 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.ListOwnedBucketsIntegrationTest")
|
@Test(groups = {"integration", "live"}, testName = "s3.ListOwnedBucketsIntegrationTest")
|
||||||
public class ListOwnedBucketsIntegrationTest extends S3IntegrationTest {
|
public class ListOwnedBucketsIntegrationTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void bucketDoesntExist() throws Exception {
|
void bucketDoesntExist() throws Exception {
|
||||||
String bucketName = bucketPrefix + "shouldntexist";
|
String bucketName = bucketPrefix + "shouldntexist";
|
||||||
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
|
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assert !list.contains(new S3Bucket(bucketName));
|
assert !list.contains(new S3Bucket(bucketName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
void bucketExists() throws Exception {
|
void bucketExists() throws Exception {
|
||||||
String bucketName = bucketPrefix + "needstoexist";
|
String bucketName = bucketPrefix + "needstoexist";
|
||||||
assert client.putBucketIfNotExists(bucketName)
|
assert client.putBucketIfNotExists(bucketName)
|
||||||
.get(10, TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
|
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
S3Bucket.Metadata firstBucket = list.get(0);
|
S3Bucket.Metadata firstBucket = list.get(0);
|
||||||
S3Bucket.Metadata toMatch = new S3Bucket.Metadata(bucketName);
|
S3Bucket.Metadata toMatch = new S3Bucket.Metadata(bucketName);
|
||||||
toMatch.setOwner(firstBucket.getOwner());
|
toMatch.setOwner(firstBucket.getOwner());
|
||||||
|
|
||||||
assert list.contains(toMatch);
|
assert list.contains(toMatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,19 +23,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.createIn;
|
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.createIn;
|
||||||
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
|
||||||
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.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all PutBucket commands.
|
* Tests integrated functionality of all PutBucket commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -43,44 +42,46 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.PutBucketIntegrationTest")
|
@Test(testName = "s3.PutBucketLiveTest")
|
||||||
public class PutBucketIntegrationTest extends S3IntegrationTest {
|
public class PutBucketLiveTest extends S3IntegrationTest {
|
||||||
|
|
||||||
@Test()
|
/**
|
||||||
|
* overriding bucketName as we are changing access permissions
|
||||||
|
*/
|
||||||
|
@Test(groups = {"live"})
|
||||||
void testPublicReadAccessPolicy() throws Exception {
|
void testPublicReadAccessPolicy() throws Exception {
|
||||||
String bucketName = bucketPrefix + "public";
|
String bucketName = bucketPrefix + "public";
|
||||||
|
|
||||||
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://%1$s.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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IOException.class)
|
@Test(expectedExceptions = IOException.class, groups = {"live"})
|
||||||
void testDefaultAccessPolicy() throws Exception {
|
void testDefaultAccessPolicy() throws Exception {
|
||||||
String bucketName = bucketPrefix + "private";
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
|
||||||
|
bucketName));
|
||||||
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
|
|
||||||
bucketName));
|
|
||||||
S3Utils.toStringAndClose(url.openStream());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
/**
|
||||||
|
* overriding bucketName as we are changing location
|
||||||
|
*/
|
||||||
|
@Test(groups = "live")
|
||||||
void testEu() throws Exception {
|
void testEu() throws Exception {
|
||||||
String bucketName = (bucketPrefix + "wow").toLowerCase();
|
String bucketName = (bucketPrefix + "wow").toLowerCase();
|
||||||
client.putBucketIfNotExists(
|
client.putBucketIfNotExists(
|
||||||
bucketName,
|
bucketName,
|
||||||
createIn(LocationConstraint.EU).withBucketAcl(
|
createIn(LocationConstraint.EU).withBucketAcl(
|
||||||
CannedAccessPolicy.PUBLIC_READ)).get(10,
|
CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
URL url = new URL(String.format("http://%1$s.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());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,9 +23,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
|
||||||
|
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 static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -34,16 +43,6 @@ import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.*;
|
|
||||||
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.testng.annotations.DataProvider;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all PutObject commands.
|
* Tests integrated functionality of all PutObject commands.
|
||||||
|
@ -52,97 +51,77 @@ import org.testng.annotations.Test;
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test(groups = "integration", testName = "s3.PutObjectIntegrationTest")
|
@Test(testName = "s3.PutObjectIntegrationTest")
|
||||||
public class PutObjectIntegrationTest extends S3IntegrationTest {
|
public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||||
@DataProvider(name = "putTests")
|
@DataProvider(name = "putTests")
|
||||||
public Object[][] createData1() throws IOException {
|
public Object[][] createData1() throws IOException {
|
||||||
|
|
||||||
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
|
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
|
||||||
|
|
||||||
return new Object[][] {
|
return new Object[][]{
|
||||||
{ "file", "text/xml", new File("pom.xml"), realObject },
|
{"file", "text/xml", new File("pom.xml"), realObject},
|
||||||
{ "string", "text/xml", realObject, realObject },
|
{"string", "text/xml", realObject, realObject},
|
||||||
{ "bytes", "application/octet-stream", realObject.getBytes(),
|
{"bytes", "application/octet-stream", realObject.getBytes(),
|
||||||
realObject } };
|
realObject}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "putTests")
|
@Test(dataProvider = "putTests", groups = {"integration", "live"})
|
||||||
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 + "tpo";
|
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();
|
||||||
}
|
}
|
||||||
assertNotNull(client.putObject(bucketName, object).get(10,
|
assertNotNull(client.putObject(bucketName, object).get(10,
|
||||||
TimeUnit.SECONDS));
|
TimeUnit.SECONDS));
|
||||||
object = client.getObject(bucketName, object.getKey()).get(10,
|
object = client.getObject(bucketName, object.getKey()).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
String returnedString = S3Utils.getContentAsStringAndClose(object);
|
String returnedString = S3Utils.getContentAsStringAndClose(object);
|
||||||
assertEquals(returnedString, realObject);
|
assertEquals(returnedString, realObject);
|
||||||
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
|
||||||
.getContents().size(), 1);
|
.getContents().size(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(groups = {"integration", "live"})
|
||||||
void testMetadata() throws Exception {
|
void testMetadata() throws Exception {
|
||||||
String bucketName = bucketPrefix + "tmd";
|
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
|
|
||||||
assertEquals(newObject.getMetadata().getContentType(),
|
|
||||||
"binary/octet-stream");
|
|
||||||
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
|
||||||
assertEquals(newObject.getMetadata().getContentDisposition(),
|
|
||||||
"attachment; filename=hello.txt");
|
|
||||||
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
|
||||||
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
|
|
||||||
assertEquals(newObject.getMetadata().getUserMetadata().values()
|
|
||||||
.iterator().next(), "powderpuff");
|
|
||||||
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
|
|
||||||
.getBytes()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test()
|
|
||||||
void testCannedAccessPolicyPublic() throws Exception {
|
|
||||||
String bucketName = bucketPrefix + "tcapp";
|
|
||||||
createBucketAndEnsureEmpty(bucketName);
|
|
||||||
String key = "hello";
|
|
||||||
|
|
||||||
client.putBucketIfNotExists(bucketName,
|
|
||||||
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
client.putObject(bucketName, new S3Object(key, TEST_STRING),
|
|
||||||
|
|
||||||
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
|
|
||||||
bucketName, key));
|
|
||||||
S3Utils.toStringAndClose(url.openStream());
|
|
||||||
|
|
||||||
|
// TODO.. why does this come back as binary/octetstring
|
||||||
|
assertEquals(newObject.getMetadata().getContentType(),
|
||||||
|
"binary/octet-stream");
|
||||||
|
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||||
|
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||||
|
"attachment; filename=hello.txt");
|
||||||
|
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||||
|
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
|
||||||
|
assertEquals(newObject.getMetadata().getUserMetadata().values()
|
||||||
|
.iterator().next(), "powderpuff");
|
||||||
|
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
|
||||||
|
.getBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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 org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||||
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests integrated functionality of all PutObject commands.
|
||||||
|
* <p/>
|
||||||
|
* Each test uses a different bucket name, so it should be perfectly fine to run
|
||||||
|
* in parallel.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(testName = "s3.PutObjectLiveTest")
|
||||||
|
public class PutObjectLiveTest extends S3IntegrationTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test(groups = {"live"})
|
||||||
|
void testCannedAccessPolicyPublic() throws Exception {
|
||||||
|
String bucketName = bucketPrefix + "tcapp";
|
||||||
|
createBucketAndEnsureEmpty(bucketName);
|
||||||
|
String key = "hello";
|
||||||
|
|
||||||
|
client.putBucketIfNotExists(bucketName,
|
||||||
|
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
client.putObject(bucketName, new S3Object(key, TEST_STRING),
|
||||||
|
|
||||||
|
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
|
||||||
|
bucketName, key));
|
||||||
|
S3Utils.toStringAndClose(url.openStream());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,140 +23,131 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import static org.easymock.EasyMock.expect;
|
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
|
|
||||||
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
|
|
||||||
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
|
||||||
import org.testng.annotations.AfterMethod;
|
|
||||||
import org.testng.annotations.BeforeMethod;
|
|
||||||
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;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.name.Names;
|
import com.google.inject.name.Names;
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
|
||||||
|
import org.jclouds.aws.s3.commands.options.*;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.testng.annotations.AfterMethod;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test(groups = {"unit"}, testName = "s3.S3CommandFactoryTest")
|
||||||
public class S3CommandFactoryTest {
|
public class S3CommandFactoryTest {
|
||||||
|
|
||||||
Injector injector = null;
|
Injector injector = null;
|
||||||
S3CommandFactory commandFactory = null;
|
S3CommandFactory commandFactory = null;
|
||||||
|
|
||||||
public static final String listAllMyBucketsResult = "<ListAllMyBucketsResult xmlns=\"http://s3.amazonaws.com/doc/callables/\"><Owner ><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID></Owner><Buckets><Bucket><Name>adrianjbosstest</Name><CreationDate>2009-03-12T02:00:07.000Z</CreationDate></Bucket><Bucket><Name>adrianjbosstest2</Name><CreationDate>2009-03-12T02:00:09.000Z</CreationDate></Bucket></Buckets></ListAllMyBucketsResult>";
|
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUpInjector() {
|
void setUpInjector() {
|
||||||
injector = Guice.createInjector(new S3CommandsModule() {
|
injector = Guice.createInjector(new S3CommandsModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(
|
||||||
Names.named("jclouds.http.address")).to("localhost");
|
Names.named("jclouds.http.address")).to("localhost");
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
commandFactory = injector.getInstance(S3CommandFactory.class);
|
commandFactory = injector.getInstance(S3CommandFactory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
void tearDownInjector() {
|
void tearDownInjector() {
|
||||||
commandFactory = null;
|
commandFactory = null;
|
||||||
injector = null;
|
injector = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateCopyObject() {
|
void testCreateCopyObject() {
|
||||||
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
|
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
|
||||||
"destbucket", "destObject", CopyObjectOptions.NONE) != null;
|
"destbucket", "destObject", CopyObjectOptions.NONE) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateCopyObjectOptions() {
|
void testCreateCopyObjectOptions() {
|
||||||
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
|
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
|
||||||
"destbucket", "destObject", new CopyObjectOptions()) != null;
|
"destbucket", "destObject", new CopyObjectOptions()) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateDeleteBucket() {
|
void testCreateDeleteBucket() {
|
||||||
assert commandFactory.createDeleteBucket("test") != null;
|
assert commandFactory.createDeleteBucket("test") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateDeleteObject() {
|
void testCreateDeleteObject() {
|
||||||
assert commandFactory.createDeleteObject("test", "blah") != null;
|
assert commandFactory.createDeleteObject("test", "blah") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateHeadBucket() {
|
void testCreateHeadBucket() {
|
||||||
assert commandFactory.createHeadBucket("test") != null;
|
assert commandFactory.createHeadBucket("test") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreatePutBucket() {
|
void testCreatePutBucket() {
|
||||||
assert commandFactory.createPutBucket("test", PutBucketOptions.NONE) != null;
|
assert commandFactory.createPutBucket("test", PutBucketOptions.NONE) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreatePutBucketOptions() {
|
void testCreatePutBucketOptions() {
|
||||||
assert commandFactory.createPutBucket("test", PutBucketOptions.Builder
|
assert commandFactory.createPutBucket("test", PutBucketOptions.Builder
|
||||||
.createIn(LocationConstraint.EU)) != null;
|
.createIn(LocationConstraint.EU)) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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,
|
||||||
PutObjectOptions.NONE) != null;
|
PutObjectOptions.NONE) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateGetObject() {
|
void testCreateGetObject() {
|
||||||
assert commandFactory.createGetObject("test", "blah",
|
assert commandFactory.createGetObject("test", "blah",
|
||||||
GetObjectOptions.NONE) != null;
|
GetObjectOptions.NONE) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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
|
||||||
void testCreateListBucket() {
|
void testCreateListBucket() {
|
||||||
assert commandFactory.createListBucket("test", ListBucketOptions.NONE) != null;
|
assert commandFactory.createListBucket("test", ListBucketOptions.NONE) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,16 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.CompletionService;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
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.domain.CanonicalUser;
|
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||||
|
@ -46,20 +38,26 @@ import org.jclouds.aws.s3.xml.config.S3ParserModule;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.AfterMethod;
|
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 org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import com.google.inject.Guice;
|
import java.io.IOException;
|
||||||
import com.google.inject.Injector;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletionService;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests parsing of S3 responses
|
* Tests parsing of S3 responses
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.S3ParserTest")
|
@Test(groups = {"performance"}, testName = "s3.S3ParserTest")
|
||||||
public class S3ParserTest extends PerformanceTest {
|
public class S3ParserTest extends PerformanceTest {
|
||||||
Injector injector = null;
|
Injector injector = null;
|
||||||
|
|
||||||
|
@ -69,136 +67,136 @@ public class S3ParserTest extends PerformanceTest {
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
protected void setUpInjector() {
|
protected void setUpInjector() {
|
||||||
injector = Guice.createInjector(new S3ParserModule());
|
injector = Guice.createInjector(new S3ParserModule());
|
||||||
parserFactory = injector.getInstance(S3ParserFactory.class);
|
parserFactory = injector.getInstance(S3ParserFactory.class);
|
||||||
assert parserFactory != null;
|
assert parserFactory != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
protected void tearDownInjector() {
|
protected void tearDownInjector() {
|
||||||
parserFactory = null;
|
parserFactory = null;
|
||||||
injector = null;
|
injector = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseListAllMyBucketsSerialResponseTime() throws HttpException {
|
void testParseListAllMyBucketsSerialResponseTime() throws HttpException {
|
||||||
for (int i = 0; i < LOOP_COUNT; i++)
|
for (int i = 0; i < LOOP_COUNT; i++)
|
||||||
runParseListAllMyBuckets();
|
runParseListAllMyBuckets();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<S3Bucket.Metadata> runParseListAllMyBuckets()
|
private List<S3Bucket.Metadata> runParseListAllMyBuckets()
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
return parserFactory.createListBucketsParser().parse(
|
return parserFactory.createListBucketsParser().parse(
|
||||||
IOUtils.toInputStream(listAllMyBucketsResultOn200));
|
IOUtils.toInputStream(listAllMyBucketsResultOn200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseListAllMyBucketsParallelResponseTime()
|
void testParseListAllMyBucketsParallelResponseTime()
|
||||||
throws InterruptedException, ExecutionException {
|
throws InterruptedException, ExecutionException {
|
||||||
CompletionService<List<S3Bucket.Metadata>> completer = new ExecutorCompletionService<List<S3Bucket.Metadata>>(
|
CompletionService<List<S3Bucket.Metadata>> completer = new ExecutorCompletionService<List<S3Bucket.Metadata>>(
|
||||||
exec);
|
exec);
|
||||||
for (int i = 0; i < LOOP_COUNT; i++)
|
for (int i = 0; i < LOOP_COUNT; i++)
|
||||||
completer.submit(new Callable<List<S3Bucket.Metadata>>() {
|
completer.submit(new Callable<List<S3Bucket.Metadata>>() {
|
||||||
public List<S3Bucket.Metadata> call() throws IOException,
|
public List<S3Bucket.Metadata> call() throws IOException,
|
||||||
SAXException, HttpException {
|
SAXException, HttpException {
|
||||||
return runParseListAllMyBuckets();
|
return runParseListAllMyBuckets();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (int i = 0; i < LOOP_COUNT; i++)
|
for (int i = 0; i < LOOP_COUNT; i++)
|
||||||
assert completer.take().get() != null;
|
assert completer.take().get() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCanParseListAllMyBuckets() throws HttpException {
|
public void testCanParseListAllMyBuckets() throws HttpException {
|
||||||
List<S3Bucket.Metadata> s3Buckets = runParseListAllMyBuckets();
|
List<S3Bucket.Metadata> s3Buckets = runParseListAllMyBuckets();
|
||||||
S3Bucket.Metadata bucket1 = s3Buckets.get(0);
|
S3Bucket.Metadata bucket1 = s3Buckets.get(0);
|
||||||
assert bucket1.getName().equals("adrianjbosstest");
|
assert bucket1.getName().equals("adrianjbosstest");
|
||||||
DateTime expectedDate1 = new DateTime("2009-03-12T02:00:07.000Z");
|
DateTime expectedDate1 = new DateTime("2009-03-12T02:00:07.000Z");
|
||||||
DateTime date1 = bucket1.getCreationDate();
|
DateTime date1 = bucket1.getCreationDate();
|
||||||
assert date1.equals(expectedDate1);
|
assert date1.equals(expectedDate1);
|
||||||
S3Bucket.Metadata bucket2 = s3Buckets.get(1);
|
S3Bucket.Metadata bucket2 = s3Buckets.get(1);
|
||||||
assert bucket2.getName().equals("adrianjbosstest2");
|
assert bucket2.getName().equals("adrianjbosstest2");
|
||||||
DateTime expectedDate2 = new DateTime("2009-03-12T02:00:09.000Z");
|
DateTime expectedDate2 = new DateTime("2009-03-12T02:00:09.000Z");
|
||||||
DateTime date2 = bucket2.getCreationDate();
|
DateTime date2 = bucket2.getCreationDate();
|
||||||
assert date2.equals(expectedDate2);
|
assert date2.equals(expectedDate2);
|
||||||
assert s3Buckets.size() == 2;
|
assert s3Buckets.size() == 2;
|
||||||
CanonicalUser owner = new CanonicalUser(
|
CanonicalUser owner = new CanonicalUser(
|
||||||
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
||||||
assert bucket1.getOwner().equals(owner);
|
assert bucket1.getOwner().equals(owner);
|
||||||
assert bucket2.getOwner().equals(owner);
|
assert bucket2.getOwner().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>";
|
||||||
|
|
||||||
public void testCanParseListBucketResult() throws HttpException,
|
public void testCanParseListBucketResult() throws HttpException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
S3Bucket bucket = runParseListBucketResult();
|
S3Bucket bucket = runParseListBucketResult();
|
||||||
assert bucket.isComplete();
|
assert !bucket.isTruncated();
|
||||||
assert bucket.getName().equals("adrianjbosstest");
|
assert bucket.getName().equals("adrianjbosstest");
|
||||||
assert bucket.getContents().size() == 1;
|
assert bucket.getContents().size() == 1;
|
||||||
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.format(
|
assert object.getLastModified().equals(expected) : String.format(
|
||||||
"expected %1$s, but got %1$s", 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;
|
||||||
CanonicalUser owner = new CanonicalUser(
|
CanonicalUser owner = new CanonicalUser(
|
||||||
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
"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");
|
||||||
}
|
}
|
||||||
|
|
||||||
private S3Bucket runParseListBucketResult() throws HttpException {
|
private S3Bucket runParseListBucketResult() throws HttpException {
|
||||||
ParseSax<S3Bucket> parser = parserFactory.createListBucketParser();
|
ParseSax<S3Bucket> parser = parserFactory.createListBucketParser();
|
||||||
ListBucketHandler handler = (ListBucketHandler) parser.getHandler();
|
ListBucketHandler handler = (ListBucketHandler) parser.getHandler();
|
||||||
handler.setBucketName("adrianjbosstest");
|
handler.setBucketName("adrianjbosstest");
|
||||||
return parser.parse(IOUtils.toInputStream(listBucketResult));
|
return parser.parse(IOUtils.toInputStream(listBucketResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String successfulCopyObject200 = "<CopyObjectResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><LastModified>2009-03-19T13:23:27.000Z</LastModified><ETag>\"92836a3ea45a6984d1b4d23a747d46bb\"</ETag></CopyObjectResult>";
|
public static final String successfulCopyObject200 = "<CopyObjectResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><LastModified>2009-03-19T13:23:27.000Z</LastModified><ETag>\"92836a3ea45a6984d1b4d23a747d46bb\"</ETag></CopyObjectResult>";
|
||||||
|
|
||||||
private S3Object.Metadata runParseCopyObjectResult() throws HttpException {
|
private S3Object.Metadata runParseCopyObjectResult() throws HttpException {
|
||||||
ParseSax<S3Object.Metadata> parser = parserFactory
|
ParseSax<S3Object.Metadata> parser = parserFactory
|
||||||
.createCopyObjectParser();
|
.createCopyObjectParser();
|
||||||
CopyObjectHandler handler = (CopyObjectHandler) parser.getHandler();
|
CopyObjectHandler handler = (CopyObjectHandler) parser.getHandler();
|
||||||
handler.setKey("adrianjbosstest");
|
handler.setKey("adrianjbosstest");
|
||||||
return parser.parse(IOUtils.toInputStream(successfulCopyObject200));
|
return parser.parse(IOUtils.toInputStream(successfulCopyObject200));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCanParseCopyObjectResult() throws HttpException,
|
public void testCanParseCopyObjectResult() throws HttpException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
S3Object.Metadata metadata = runParseCopyObjectResult();
|
S3Object.Metadata metadata = runParseCopyObjectResult();
|
||||||
DateTime expected = new DateTime("2009-03-19T13:23:27.000Z");
|
DateTime expected = new DateTime("2009-03-19T13:23:27.000Z");
|
||||||
assertEquals(metadata.getLastModified(), expected);
|
assertEquals(metadata.getLastModified(), expected);
|
||||||
assertEquals(S3Utils.toHexString(metadata.getMd5()),
|
assertEquals(S3Utils.toHexString(metadata.getMd5()),
|
||||||
"92836a3ea45a6984d1b4d23a747d46bb");
|
"92836a3ea45a6984d1b4d23a747d46bb");
|
||||||
assertEquals(metadata.getKey(), "adrianjbosstest");
|
assertEquals(metadata.getKey(), "adrianjbosstest");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseListBucketResultSerialResponseTime() throws HttpException {
|
void testParseListBucketResultSerialResponseTime() throws HttpException {
|
||||||
for (int i = 0; i < LOOP_COUNT; i++)
|
for (int i = 0; i < LOOP_COUNT; i++)
|
||||||
runParseListBucketResult();
|
runParseListBucketResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseListBucketResultParallelResponseTime()
|
void testParseListBucketResultParallelResponseTime()
|
||||||
throws InterruptedException, ExecutionException {
|
throws InterruptedException, ExecutionException {
|
||||||
CompletionService<S3Bucket> completer = new ExecutorCompletionService<S3Bucket>(
|
CompletionService<S3Bucket> completer = new ExecutorCompletionService<S3Bucket>(
|
||||||
exec);
|
exec);
|
||||||
for (int i = 0; i < LOOP_COUNT; i++)
|
for (int i = 0; i < LOOP_COUNT; i++)
|
||||||
completer.submit(new Callable<S3Bucket>() {
|
completer.submit(new Callable<S3Bucket>() {
|
||||||
public S3Bucket call() throws IOException, SAXException,
|
public S3Bucket call() throws IOException, SAXException,
|
||||||
HttpException {
|
HttpException {
|
||||||
return runParseListBucketResult();
|
return runParseListBucketResult();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (int i = 0; i < LOOP_COUNT; i++)
|
for (int i = 0; i < LOOP_COUNT; i++)
|
||||||
assert completer.take().get() != null;
|
assert completer.take().get() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,77 +23,74 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.callables;
|
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.apache.commons.io.IOUtils;
|
||||||
|
import static org.easymock.classextension.EasyMock.*;
|
||||||
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.domain.S3Object.Metadata;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpHeaders;
|
import org.jclouds.http.HttpHeaders;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.AfterMethod;
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test(groups = "unit", testName = "s3.ParseObjectFromHeadersAndHttpContentTest")
|
||||||
public class ParseObjectFromHeadersAndHttpContentTest {
|
public class ParseObjectFromHeadersAndHttpContentTest {
|
||||||
ParseObjectFromHeadersAndHttpContent callable;
|
ParseObjectFromHeadersAndHttpContent callable;
|
||||||
ParseMetadataFromHeaders metadataParser;
|
ParseMetadataFromHeaders metadataParser;
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUp() {
|
void setUp() {
|
||||||
metadataParser = createMock(ParseMetadataFromHeaders.class);
|
metadataParser = createMock(ParseMetadataFromHeaders.class);
|
||||||
callable = new ParseObjectFromHeadersAndHttpContent(metadataParser);
|
callable = new ParseObjectFromHeadersAndHttpContent(metadataParser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
void tearDown() {
|
void tearDown() {
|
||||||
callable = null;
|
callable = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testCall() throws HttpException {
|
public void testCall() throws HttpException {
|
||||||
HttpResponse response = createMock(HttpResponse.class);
|
HttpResponse response = createMock(HttpResponse.class);
|
||||||
expect(response.getStatusCode()).andReturn(409).atLeastOnce();
|
expect(response.getStatusCode()).andReturn(409).atLeastOnce();
|
||||||
expect(response.getContent()).andReturn(null);
|
expect(response.getContent()).andReturn(null);
|
||||||
replay(response);
|
replay(response);
|
||||||
callable.setResponse(response);
|
callable.setResponse(response);
|
||||||
callable.call();
|
callable.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseContentLengthWhenContentRangeSet()
|
public void testParseContentLengthWhenContentRangeSet()
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
HttpResponse response = createMock(HttpResponse.class);
|
HttpResponse response = createMock(HttpResponse.class);
|
||||||
metadataParser.setResponse(response);
|
metadataParser.setResponse(response);
|
||||||
Metadata meta = createMock(Metadata.class);
|
Metadata meta = createMock(Metadata.class);
|
||||||
expect(metadataParser.call()).andReturn(meta);
|
expect(metadataParser.call()).andReturn(meta);
|
||||||
expect(meta.getSize()).andReturn(-1l);
|
expect(meta.getSize()).andReturn(-1l);
|
||||||
meta.setSize(-1l);
|
meta.setSize(-1l);
|
||||||
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH))
|
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH))
|
||||||
.andReturn("10485760").atLeastOnce();
|
.andReturn("10485760").atLeastOnce();
|
||||||
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_RANGE))
|
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_RANGE))
|
||||||
.andReturn("0-10485759/20232760").atLeastOnce();
|
.andReturn("0-10485759/20232760").atLeastOnce();
|
||||||
meta.setSize(20232760l);
|
meta.setSize(20232760l);
|
||||||
expect(meta.getSize()).andReturn(20232760l);
|
expect(meta.getSize()).andReturn(20232760l);
|
||||||
|
|
||||||
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
|
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
|
||||||
expect(response.getContent()).andReturn(IOUtils.toInputStream("test"));
|
expect(response.getContent()).andReturn(IOUtils.toInputStream("test"));
|
||||||
replay(response);
|
replay(response);
|
||||||
replay(metadataParser);
|
replay(metadataParser);
|
||||||
replay(meta);
|
replay(meta);
|
||||||
|
|
||||||
callable.setResponse(response);
|
callable.setResponse(response);
|
||||||
S3Object object = callable.call();
|
S3Object object = callable.call();
|
||||||
assertEquals(object.getContentLength(), 10485760);
|
assertEquals(object.getContentLength(), 10485760);
|
||||||
assertEquals(object.getMetadata().getSize(), 20232760);
|
assertEquals(object.getMetadata().getSize(), 20232760);
|
||||||
assertEquals(object.getContentRange(), "0-10485759/20232760");
|
assertEquals(object.getContentRange(), "0-10485759/20232760");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,34 +23,26 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
import com.google.common.collect.HashMultimap;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
import com.google.common.collect.Multimap;
|
||||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*;
|
||||||
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.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
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.reference.S3Headers;
|
||||||
import org.jclouds.aws.s3.util.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import static org.testng.Assert.*;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import java.io.UnsupportedEncodingException;
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests possible uses of CopyObjectOptions and CopyObjectOptions.Builder.*
|
* Tests possible uses of CopyObjectOptions and CopyObjectOptions.Builder.*
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Test(groups = "unit", testName = "s3.CopyObjectOptionsTest")
|
||||||
public class CopyObjectOptionsTest {
|
public class CopyObjectOptionsTest {
|
||||||
|
|
||||||
private byte[] testBytes;
|
private byte[] testBytes;
|
||||||
|
@ -61,279 +53,279 @@ public class CopyObjectOptionsTest {
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUp() {
|
void setUp() {
|
||||||
goodMeta = HashMultimap.create();
|
goodMeta = HashMultimap.create();
|
||||||
goodMeta.put("x-amz-meta-adrian", "foo");
|
goodMeta.put("x-amz-meta-adrian", "foo");
|
||||||
badMeta = HashMultimap.create();
|
badMeta = HashMultimap.create();
|
||||||
badMeta.put("x-google-meta-adrian", "foo");
|
badMeta.put("x-google-meta-adrian", "foo");
|
||||||
|
|
||||||
now = new DateTime();
|
now = new DateTime();
|
||||||
nowExpected = new DateService().toHeaderString(now);
|
nowExpected = new DateService().toHeaderString(now);
|
||||||
testBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
|
testBytes = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGoodMetaStatic() {
|
void testGoodMetaStatic() {
|
||||||
CopyObjectOptions options = overrideMetadataWith(goodMeta);
|
CopyObjectOptions options = overrideMetadataWith(goodMeta);
|
||||||
assertGoodMeta(options);
|
assertGoodMeta(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testMetaNPE() {
|
public void testMetaNPE() {
|
||||||
overrideMetadataWith(null);
|
overrideMetadataWith(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testBadMeta() {
|
public void testBadMeta() {
|
||||||
overrideMetadataWith(badMeta);
|
overrideMetadataWith(badMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testBadMetaStatic() {
|
public void testBadMetaStatic() {
|
||||||
overrideMetadataWith(badMeta);
|
overrideMetadataWith(badMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertGoodMeta(CopyObjectOptions options) {
|
private void assertGoodMeta(CopyObjectOptions options) {
|
||||||
assert options != null;
|
assert options != null;
|
||||||
assert options.getMetadata() != null;
|
assert options.getMetadata() != null;
|
||||||
Multimap<String,String> headers = options.buildRequestHeaders();
|
Multimap<String, String> headers = options.buildRequestHeaders();
|
||||||
assertEquals(headers.size(), 2);
|
assertEquals(headers.size(), 2);
|
||||||
assertEquals(headers.get(
|
assertEquals(headers.get(
|
||||||
"x-amz-metadata-directive").iterator().next(),
|
"x-amz-metadata-directive").iterator().next(),
|
||||||
"REPLACE");
|
"REPLACE");
|
||||||
assertEquals(options.getMetadata().size(), 1);
|
assertEquals(options.getMetadata().size(), 1);
|
||||||
assertEquals(headers.get("x-amz-meta-adrian").iterator()
|
assertEquals(headers.get("x-amz-meta-adrian").iterator()
|
||||||
.next(), "foo");
|
.next(), "foo");
|
||||||
assertEquals(options.getMetadata().get("x-amz-meta-adrian").iterator()
|
assertEquals(options.getMetadata().get("x-amz-meta-adrian").iterator()
|
||||||
.next(), "foo");
|
.next(), "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGoodMeta() {
|
void testGoodMeta() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
options.overrideMetadataWith(goodMeta);
|
options.overrideMetadataWith(goodMeta);
|
||||||
assertGoodMeta(options);
|
assertGoodMeta(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfModifiedSince() {
|
public void testIfModifiedSince() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
options.ifSourceModifiedSince(now);
|
options.ifSourceModifiedSince(now);
|
||||||
assertEquals(options.getIfModifiedSince(), nowExpected);
|
assertEquals(options.getIfModifiedSince(), nowExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfModifiedSince() {
|
public void testNullIfModifiedSince() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
assertNull(options.getIfModifiedSince());
|
assertNull(options.getIfModifiedSince());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfModifiedSinceStatic() {
|
public void testIfModifiedSinceStatic() {
|
||||||
CopyObjectOptions options = ifSourceModifiedSince(now);
|
CopyObjectOptions options = ifSourceModifiedSince(now);
|
||||||
assertEquals(options.getIfModifiedSince(), nowExpected);
|
assertEquals(options.getIfModifiedSince(), nowExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfModifiedSinceNPE() {
|
public void testIfModifiedSinceNPE() {
|
||||||
ifSourceModifiedSince(null);
|
ifSourceModifiedSince(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfUnmodifiedSince() {
|
public void testIfUnmodifiedSince() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
options.ifSourceUnmodifiedSince(now);
|
options.ifSourceUnmodifiedSince(now);
|
||||||
isNowExpected(options);
|
isNowExpected(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfUnmodifiedSince() {
|
public void testNullIfUnmodifiedSince() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
assertNull(options.getIfUnmodifiedSince());
|
assertNull(options.getIfUnmodifiedSince());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfUnmodifiedSinceStatic() {
|
public void testIfUnmodifiedSinceStatic() {
|
||||||
CopyObjectOptions options = ifSourceUnmodifiedSince(now);
|
CopyObjectOptions options = ifSourceUnmodifiedSince(now);
|
||||||
isNowExpected(options);
|
isNowExpected(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void isNowExpected(CopyObjectOptions options) {
|
private void isNowExpected(CopyObjectOptions options) {
|
||||||
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
|
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfUnmodifiedSinceNPE() {
|
public void testIfUnmodifiedSinceNPE() {
|
||||||
ifSourceUnmodifiedSince(null);
|
ifSourceUnmodifiedSince(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5Matches() throws UnsupportedEncodingException {
|
public void testIfMd5Matches() throws UnsupportedEncodingException {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
options.ifSourceMd5Matches(testBytes);
|
options.ifSourceMd5Matches(testBytes);
|
||||||
matchesHex(options.getIfMatch());
|
matchesHex(options.getIfMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfMd5Matches() {
|
public void testNullIfMd5Matches() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
assertNull(options.getIfMatch());
|
assertNull(options.getIfMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5MatchesStatic() throws UnsupportedEncodingException {
|
public void testIfMd5MatchesStatic() throws UnsupportedEncodingException {
|
||||||
CopyObjectOptions options = ifSourceMd5Matches(testBytes);
|
CopyObjectOptions options = ifSourceMd5Matches(testBytes);
|
||||||
matchesHex(options.getIfMatch());
|
matchesHex(options.getIfMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfMd5MatchesNPE() throws UnsupportedEncodingException {
|
public void testIfMd5MatchesNPE() throws UnsupportedEncodingException {
|
||||||
ifSourceMd5Matches(null);
|
ifSourceMd5Matches(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5DoesntMatch() throws UnsupportedEncodingException {
|
public void testIfMd5DoesntMatch() throws UnsupportedEncodingException {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
options.ifSourceMd5DoesntMatch(testBytes);
|
options.ifSourceMd5DoesntMatch(testBytes);
|
||||||
matchesHex(options.getIfNoneMatch());
|
matchesHex(options.getIfNoneMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfMd5DoesntMatch() {
|
public void testNullIfMd5DoesntMatch() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
assertNull(options.getIfNoneMatch());
|
assertNull(options.getIfNoneMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5DoesntMatchStatic()
|
public void testIfMd5DoesntMatchStatic()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
CopyObjectOptions options = ifSourceMd5DoesntMatch(testBytes);
|
CopyObjectOptions options = ifSourceMd5DoesntMatch(testBytes);
|
||||||
matchesHex(options.getIfNoneMatch());
|
matchesHex(options.getIfNoneMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfMd5DoesntMatchNPE() throws UnsupportedEncodingException {
|
public void testIfMd5DoesntMatchNPE() throws UnsupportedEncodingException {
|
||||||
ifSourceMd5DoesntMatch(null);
|
ifSourceMd5DoesntMatch(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void matchesHex(String match) throws UnsupportedEncodingException {
|
private void matchesHex(String match) throws UnsupportedEncodingException {
|
||||||
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
|
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
|
||||||
assertEquals(match, expected);
|
assertEquals(match, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testIfUnmodifiedAfterModified() {
|
public void testIfUnmodifiedAfterModified() {
|
||||||
ifSourceModifiedSince(now).ifSourceUnmodifiedSince(now);
|
ifSourceModifiedSince(now).ifSourceUnmodifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIfUnmodifiedAfterMd5Matches()
|
public void testIfUnmodifiedAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceMd5Matches(testBytes).ifSourceUnmodifiedSince(now);
|
ifSourceMd5Matches(testBytes).ifSourceUnmodifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testIfUnmodifiedAfterMd5DoesntMatch()
|
public void testIfUnmodifiedAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceMd5DoesntMatch(testBytes).ifSourceUnmodifiedSince(now);
|
ifSourceMd5DoesntMatch(testBytes).ifSourceUnmodifiedSince(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testIfModifiedAfterUnmodified() {
|
public void testIfModifiedAfterUnmodified() {
|
||||||
ifSourceUnmodifiedSince(now).ifSourceModifiedSince(now);
|
ifSourceUnmodifiedSince(now).ifSourceModifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testIfModifiedAfterMd5Matches()
|
public void testIfModifiedAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceMd5Matches(testBytes).ifSourceModifiedSince(now);
|
ifSourceMd5Matches(testBytes).ifSourceModifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIfModifiedAfterMd5DoesntMatch()
|
public void testIfModifiedAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceMd5DoesntMatch(testBytes).ifSourceModifiedSince(now);
|
ifSourceMd5DoesntMatch(testBytes).ifSourceModifiedSince(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMd5MatchesAfterIfModified()
|
public void testMd5MatchesAfterIfModified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceModifiedSince(now).ifSourceMd5Matches(testBytes);
|
ifSourceModifiedSince(now).ifSourceMd5Matches(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMd5MatchesAfterIfUnmodified()
|
public void testMd5MatchesAfterIfUnmodified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceUnmodifiedSince(now).ifSourceMd5Matches(testBytes);
|
ifSourceUnmodifiedSince(now).ifSourceMd5Matches(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMd5MatchesAfterMd5DoesntMatch()
|
public void testMd5MatchesAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceMd5DoesntMatch(testBytes).ifSourceMd5Matches(testBytes);
|
ifSourceMd5DoesntMatch(testBytes).ifSourceMd5Matches(testBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMd5DoesntMatchAfterIfModified()
|
public void testMd5DoesntMatchAfterIfModified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceModifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
|
ifSourceModifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMd5DoesntMatchAfterIfUnmodified()
|
public void testMd5DoesntMatchAfterIfUnmodified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceUnmodifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
|
ifSourceUnmodifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMd5DoesntMatchAfterMd5Matches()
|
public void testMd5DoesntMatchAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifSourceMd5Matches(testBytes).ifSourceMd5DoesntMatch(testBytes);
|
ifSourceMd5Matches(testBytes).ifSourceMd5DoesntMatch(testBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuildRequestHeadersWhenMetadataNull()
|
void testBuildRequestHeadersWhenMetadataNull()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
assert new CopyObjectOptions().buildRequestHeaders() != null;
|
assert new CopyObjectOptions().buildRequestHeaders() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuildRequestHeaders() throws UnsupportedEncodingException {
|
void testBuildRequestHeaders() throws UnsupportedEncodingException {
|
||||||
|
|
||||||
Multimap<String, String> headers = ifSourceModifiedSince(now)
|
Multimap<String, String> headers = ifSourceModifiedSince(now)
|
||||||
.ifSourceMd5DoesntMatch(testBytes).overrideMetadataWith(
|
.ifSourceMd5DoesntMatch(testBytes).overrideMetadataWith(
|
||||||
goodMeta).buildRequestHeaders();
|
goodMeta).buildRequestHeaders();
|
||||||
assertEquals(headers.get("x-amz-copy-source-if-modified-since")
|
assertEquals(headers.get("x-amz-copy-source-if-modified-since")
|
||||||
.iterator().next(), new DateService().toHeaderString(now));
|
.iterator().next(), new DateService().toHeaderString(now));
|
||||||
assertEquals(headers.get("x-amz-copy-source-if-none-match").iterator()
|
assertEquals(headers.get("x-amz-copy-source-if-none-match").iterator()
|
||||||
.next(), "\"" + S3Utils.toHexString(testBytes) + "\"");
|
.next(), "\"" + S3Utils.toHexString(testBytes) + "\"");
|
||||||
for (String value : goodMeta.values())
|
for (String value : goodMeta.values())
|
||||||
assertTrue(headers.containsValue(value));
|
assertTrue(headers.containsValue(value));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAclDefault() {
|
public void testAclDefault() {
|
||||||
CopyObjectOptions options = new CopyObjectOptions();
|
CopyObjectOptions options = new CopyObjectOptions();
|
||||||
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAclStatic() {
|
public void testAclStatic() {
|
||||||
CopyObjectOptions options = overrideAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
CopyObjectOptions options = overrideAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuildRequestHeadersACL() throws UnsupportedEncodingException {
|
void testBuildRequestHeadersACL() throws UnsupportedEncodingException {
|
||||||
|
|
||||||
Multimap<String, String> headers = overrideAcl(
|
Multimap<String, String> headers = overrideAcl(
|
||||||
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
||||||
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
||||||
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,29 +23,23 @@
|
||||||
*/
|
*/
|
||||||
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.*;
|
||||||
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.ifMd5Matches;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifModifiedSince;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifUnmodifiedSince;
|
|
||||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.range;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.util.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.jclouds.aws.s3.util.S3Utils;
|
import org.jclouds.aws.s3.util.S3Utils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests possible uses of GetObjectOptions and GetObjectOptions.Builder.*
|
* Tests possible uses of GetObjectOptions and GetObjectOptions.Builder.*
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Test(groups = "unit", testName = "s3.GetObjectOptionsTest")
|
||||||
public class GetObjectOptionsTest {
|
public class GetObjectOptionsTest {
|
||||||
|
|
||||||
private byte[] testBytes;
|
private byte[] testBytes;
|
||||||
|
@ -54,287 +48,287 @@ public class GetObjectOptionsTest {
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
void setUp() {
|
void setUp() {
|
||||||
now = new DateTime();
|
now = new DateTime();
|
||||||
nowExpected = new DateService().toHeaderString(now);
|
nowExpected = new DateService().toHeaderString(now);
|
||||||
testBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
|
testBytes = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfModifiedSince() {
|
public void testIfModifiedSince() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.ifModifiedSince(now);
|
options.ifModifiedSince(now);
|
||||||
assertEquals(options.getIfModifiedSince(), nowExpected);
|
assertEquals(options.getIfModifiedSince(), nowExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfModifiedSince() {
|
public void testNullIfModifiedSince() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
assertNull(options.getIfModifiedSince());
|
assertNull(options.getIfModifiedSince());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfModifiedSinceStatic() {
|
public void testIfModifiedSinceStatic() {
|
||||||
GetObjectOptions options = ifModifiedSince(now);
|
GetObjectOptions options = ifModifiedSince(now);
|
||||||
assertEquals(options.getIfModifiedSince(), nowExpected);
|
assertEquals(options.getIfModifiedSince(), nowExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfModifiedSinceNPE() {
|
public void testIfModifiedSinceNPE() {
|
||||||
ifModifiedSince(null);
|
ifModifiedSince(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfUnmodifiedSince() {
|
public void testIfUnmodifiedSince() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.ifUnmodifiedSince(now);
|
options.ifUnmodifiedSince(now);
|
||||||
isNowExpected(options);
|
isNowExpected(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfUnmodifiedSince() {
|
public void testNullIfUnmodifiedSince() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
assertNull(options.getIfUnmodifiedSince());
|
assertNull(options.getIfUnmodifiedSince());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfUnmodifiedSinceStatic() {
|
public void testIfUnmodifiedSinceStatic() {
|
||||||
GetObjectOptions options = ifUnmodifiedSince(now);
|
GetObjectOptions options = ifUnmodifiedSince(now);
|
||||||
isNowExpected(options);
|
isNowExpected(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void isNowExpected(GetObjectOptions options) {
|
private void isNowExpected(GetObjectOptions options) {
|
||||||
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
|
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfUnmodifiedSinceNPE() {
|
public void testIfUnmodifiedSinceNPE() {
|
||||||
ifUnmodifiedSince(null);
|
ifUnmodifiedSince(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testModifiedSinceAndRange() {
|
public void testModifiedSinceAndRange() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.ifModifiedSince(now);
|
options.ifModifiedSince(now);
|
||||||
options.range(0, 1024);
|
options.range(0, 1024);
|
||||||
isNowExpected(options);
|
assertEquals(options.getIfModifiedSince(), nowExpected);
|
||||||
bytes1to1024(options);
|
bytes1to1024(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRange() {
|
public void testRange() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.range(0, 1024);
|
options.range(0, 1024);
|
||||||
bytes1to1024(options);
|
bytes1to1024(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bytes1to1024(GetObjectOptions options) {
|
private void bytes1to1024(GetObjectOptions options) {
|
||||||
assertEquals(options.getRange(), "bytes=0-1024");
|
assertEquals(options.getRange(), "bytes=0-1024");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRangeZeroToFive() {
|
public void testRangeZeroToFive() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.range(0, 5);
|
options.range(0, 5);
|
||||||
assertEquals(options.getRange(), "bytes=0-5");
|
assertEquals(options.getRange(), "bytes=0-5");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTail() {
|
public void testTail() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.tail(100);
|
options.tail(100);
|
||||||
assertEquals(options.getRange(), "bytes=-100");
|
assertEquals(options.getRange(), "bytes=-100");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTailStatic() {
|
public void testTailStatic() {
|
||||||
GetObjectOptions options = tail(100);
|
GetObjectOptions options = tail(100);
|
||||||
assertEquals(options.getRange(), "bytes=-100");
|
assertEquals(options.getRange(), "bytes=-100");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testTailFail() {
|
public void testTailFail() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.tail(0);
|
options.tail(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartAt() {
|
public void testStartAt() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.startAt(100);
|
options.startAt(100);
|
||||||
assertEquals(options.getRange(), "bytes=100-");
|
assertEquals(options.getRange(), "bytes=100-");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartAtStatic() {
|
public void testStartAtStatic() {
|
||||||
GetObjectOptions options = startAt(100);
|
GetObjectOptions options = startAt(100);
|
||||||
assertEquals(options.getRange(), "bytes=100-");
|
assertEquals(options.getRange(), "bytes=100-");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testStartAtFail() {
|
public void testStartAtFail() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.startAt(-1);
|
options.startAt(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRangeZeroToFiveAnd10through100() {
|
public void testRangeZeroToFiveAnd10through100() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.range(0, 5).range(10, 100);
|
options.range(0, 5).range(10, 100);
|
||||||
assertEquals(options.getRange(), "bytes=0-5,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();
|
||||||
assertNull(options.getRange());
|
assertNull(options.getRange());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRangeStatic() {
|
public void testRangeStatic() {
|
||||||
GetObjectOptions options = range(0, 1024);
|
GetObjectOptions options = range(0, 1024);
|
||||||
bytes1to1024(options);
|
bytes1to1024(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testRangeNegative1() {
|
public void testRangeNegative1() {
|
||||||
range(-1, 0);
|
range(-1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testRangeNegative2() {
|
public void testRangeNegative2() {
|
||||||
range(0, -1);
|
range(0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testRangeNegative() {
|
public void testRangeNegative() {
|
||||||
range(-1, -1);
|
range(-1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5Matches() throws UnsupportedEncodingException {
|
public void testIfMd5Matches() throws UnsupportedEncodingException {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.ifMd5Matches(testBytes);
|
options.ifMd5Matches(testBytes);
|
||||||
matchesHex(options.getIfMatch());
|
matchesHex(options.getIfMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfMd5Matches() {
|
public void testNullIfMd5Matches() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
assertNull(options.getIfMatch());
|
assertNull(options.getIfMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5MatchesStatic() throws UnsupportedEncodingException {
|
public void testIfMd5MatchesStatic() throws UnsupportedEncodingException {
|
||||||
GetObjectOptions options = ifMd5Matches(testBytes);
|
GetObjectOptions options = ifMd5Matches(testBytes);
|
||||||
matchesHex(options.getIfMatch());
|
matchesHex(options.getIfMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfMd5MatchesNPE() throws UnsupportedEncodingException {
|
public void testIfMd5MatchesNPE() throws UnsupportedEncodingException {
|
||||||
ifMd5Matches(null);
|
ifMd5Matches(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5DoesntMatch() throws UnsupportedEncodingException {
|
public void testIfMd5DoesntMatch() throws UnsupportedEncodingException {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
options.ifMd5DoesntMatch(testBytes);
|
options.ifMd5DoesntMatch(testBytes);
|
||||||
matchesHex(options.getIfNoneMatch());
|
matchesHex(options.getIfNoneMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullIfMd5DoesntMatch() {
|
public void testNullIfMd5DoesntMatch() {
|
||||||
GetObjectOptions options = new GetObjectOptions();
|
GetObjectOptions options = new GetObjectOptions();
|
||||||
assertNull(options.getIfNoneMatch());
|
assertNull(options.getIfNoneMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfMd5DoesntMatchStatic()
|
public void testIfMd5DoesntMatchStatic()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
GetObjectOptions options = ifMd5DoesntMatch(testBytes);
|
GetObjectOptions options = ifMd5DoesntMatch(testBytes);
|
||||||
matchesHex(options.getIfNoneMatch());
|
matchesHex(options.getIfNoneMatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testIfMd5DoesntMatchNPE() throws UnsupportedEncodingException {
|
public void testIfMd5DoesntMatchNPE() throws UnsupportedEncodingException {
|
||||||
ifMd5DoesntMatch(null);
|
ifMd5DoesntMatch(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void matchesHex(String match) throws UnsupportedEncodingException {
|
private void matchesHex(String match) throws UnsupportedEncodingException {
|
||||||
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
|
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
|
||||||
assertEquals(match, expected);
|
assertEquals(match, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfUnmodifiedAfterModified() {
|
public void testIfUnmodifiedAfterModified() {
|
||||||
ifModifiedSince(now).ifUnmodifiedSince(now);
|
ifModifiedSince(now).ifUnmodifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIfUnmodifiedAfterMd5Matches()
|
public void testIfUnmodifiedAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5Matches(testBytes).ifUnmodifiedSince(now);
|
ifMd5Matches(testBytes).ifUnmodifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.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 = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfModifiedAfterUnmodified() {
|
public void testIfModifiedAfterUnmodified() {
|
||||||
ifUnmodifiedSince(now).ifModifiedSince(now);
|
ifUnmodifiedSince(now).ifModifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testIfModifiedAfterMd5Matches()
|
public void testIfModifiedAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5Matches(testBytes).ifModifiedSince(now);
|
ifMd5Matches(testBytes).ifModifiedSince(now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIfModifiedAfterMd5DoesntMatch()
|
public void testIfModifiedAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5DoesntMatch(testBytes).ifModifiedSince(now);
|
ifMd5DoesntMatch(testBytes).ifModifiedSince(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5MatchesAfterIfModified()
|
public void testMd5MatchesAfterIfModified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifModifiedSince(now).ifMd5Matches(testBytes);
|
ifModifiedSince(now).ifMd5Matches(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMd5MatchesAfterIfUnmodified()
|
public void testMd5MatchesAfterIfUnmodified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifUnmodifiedSince(now).ifMd5Matches(testBytes);
|
ifUnmodifiedSince(now).ifMd5Matches(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5MatchesAfterMd5DoesntMatch()
|
public void testMd5MatchesAfterMd5DoesntMatch()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5DoesntMatch(testBytes).ifMd5Matches(testBytes);
|
ifMd5DoesntMatch(testBytes).ifMd5Matches(testBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMd5DoesntMatchAfterIfModified()
|
public void testMd5DoesntMatchAfterIfModified()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifModifiedSince(now).ifMd5DoesntMatch(testBytes);
|
ifModifiedSince(now).ifMd5DoesntMatch(testBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.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 = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMd5DoesntMatchAfterMd5Matches()
|
public void testMd5DoesntMatchAfterMd5Matches()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ifMd5Matches(testBytes).ifMd5DoesntMatch(testBytes);
|
ifMd5Matches(testBytes).ifMd5DoesntMatch(testBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class ListBucketOptionsTest {
|
||||||
public void testPrefixAndDelimiterUrlEncodingQueryString()
|
public void testPrefixAndDelimiterUrlEncodingQueryString()
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ListBucketOptions options = new ListBucketOptions();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
options.withPrefix("/test").setDelimiter("/");
|
options.withPrefix("/test").delimiter("/");
|
||||||
String query = options.buildQueryString();
|
String query = options.buildQueryString();
|
||||||
checkEncodedQuery(query);
|
checkEncodedQuery(query);
|
||||||
checkEncodedQuery(checkNotNull(query));
|
checkEncodedQuery(checkNotNull(query));
|
||||||
|
@ -165,7 +165,7 @@ public class ListBucketOptionsTest {
|
||||||
@Test
|
@Test
|
||||||
public void testDelimiter() throws UnsupportedEncodingException {
|
public void testDelimiter() throws UnsupportedEncodingException {
|
||||||
ListBucketOptions options = new ListBucketOptions();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
options.setDelimiter("test");
|
options.delimiter("test");
|
||||||
assertEquals(options.getDelimiter(), "test");
|
assertEquals(options.getDelimiter(), "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,79 +23,77 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.createIn;
|
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.createIn;
|
||||||
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
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.aws.s3.reference.S3Headers;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests possible uses of PutBucketOptions and PutBucketOptions.Builder.*
|
* Tests possible uses of PutBucketOptions and PutBucketOptions.Builder.*
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Test(groups = "unit", testName = "s3.PutBucketOptionsTest")
|
||||||
public class PutBucketOptionsTest {
|
public class PutBucketOptionsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLocationConstraint() {
|
public void testLocationConstraint() {
|
||||||
PutBucketOptions options = new PutBucketOptions();
|
PutBucketOptions options = new PutBucketOptions();
|
||||||
options.createIn(LocationConstraint.EU);
|
options.createIn(LocationConstraint.EU);
|
||||||
assertEquals(options.getLocationConstraint(), LocationConstraint.EU);
|
assertEquals(options.getLocationConstraint(), LocationConstraint.EU);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPayload() {
|
public void testPayload() {
|
||||||
PutBucketOptions options = new PutBucketOptions();
|
PutBucketOptions options = new PutBucketOptions();
|
||||||
options.createIn(LocationConstraint.EU);
|
options.createIn(LocationConstraint.EU);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
options.buildPayload(),
|
options.buildPayload(),
|
||||||
"<CreateBucketConfiguration><LocationConstraint>EU</LocationConstraint></CreateBucketConfiguration>");
|
"<CreateBucketConfiguration><LocationConstraint>EU</LocationConstraint></CreateBucketConfiguration>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullLocationConstraint() {
|
public void testNullLocationConstraint() {
|
||||||
PutBucketOptions options = new PutBucketOptions();
|
PutBucketOptions options = new PutBucketOptions();
|
||||||
assertNull(options.getLocationConstraint());
|
assertNull(options.getLocationConstraint());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLocationConstraintStatic() {
|
public void testLocationConstraintStatic() {
|
||||||
PutBucketOptions options = createIn(LocationConstraint.EU);
|
PutBucketOptions options = createIn(LocationConstraint.EU);
|
||||||
assertEquals(options.getLocationConstraint(), LocationConstraint.EU);
|
assertEquals(options.getLocationConstraint(), LocationConstraint.EU);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testNPE() {
|
public void testNPE() {
|
||||||
createIn(null);
|
createIn(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAclDefault() {
|
public void testAclDefault() {
|
||||||
PutBucketOptions options = new PutBucketOptions();
|
PutBucketOptions options = new PutBucketOptions();
|
||||||
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAclStatic() {
|
public void testAclStatic() {
|
||||||
PutBucketOptions options = withBucketAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
PutBucketOptions options = withBucketAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuildRequestHeaders() throws UnsupportedEncodingException {
|
void testBuildRequestHeaders() throws UnsupportedEncodingException {
|
||||||
|
|
||||||
Multimap<String, String> headers = withBucketAcl(
|
Multimap<String, String> headers = withBucketAcl(
|
||||||
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
||||||
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
||||||
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,43 +23,41 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands.options;
|
package org.jclouds.aws.s3.commands.options;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
|
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
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.reference.S3Headers;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests possible uses of PutObjectOptions and PutObjectOptions.Builder.*
|
* Tests possible uses of PutObjectOptions and PutObjectOptions.Builder.*
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Test(groups = "unit", testName = "s3.PutObjectOptionsTest")
|
||||||
public class PutObjectOptionsTest {
|
public class PutObjectOptionsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAclDefault() {
|
public void testAclDefault() {
|
||||||
PutObjectOptions options = new PutObjectOptions();
|
PutObjectOptions options = new PutObjectOptions();
|
||||||
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAclStatic() {
|
public void testAclStatic() {
|
||||||
PutObjectOptions options = withAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
PutObjectOptions options = withAcl(CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuildRequestHeaders() throws UnsupportedEncodingException {
|
void testBuildRequestHeaders() throws UnsupportedEncodingException {
|
||||||
|
|
||||||
Multimap<String, String> headers = withAcl(
|
Multimap<String, String> headers = withAcl(
|
||||||
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
|
||||||
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
|
||||||
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
CannedAccessPolicy.AUTHENTICATED_READ.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.config;
|
package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
|
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.jclouds.http.HttpResponseHandler;
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
|
@ -33,94 +35,88 @@ import org.jclouds.http.annotation.RedirectHandler;
|
||||||
import org.jclouds.http.annotation.ServerErrorHandler;
|
import org.jclouds.http.annotation.ServerErrorHandler;
|
||||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||||
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.AfterMethod;
|
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.Inject;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
import com.google.inject.name.Names;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test(groups = "unit", testName = "s3.S3ContextModuleTest")
|
||||||
public class S3ContextModuleTest {
|
public class S3ContextModuleTest {
|
||||||
|
|
||||||
Injector injector = null;
|
Injector injector = null;
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUpInjector() {
|
void setUpInjector() {
|
||||||
injector = Guice.createInjector(new S3ContextModule() {
|
injector = Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(
|
||||||
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||||
"localhost");
|
"localhost");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(
|
||||||
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||||
.to("localhost");
|
.to("localhost");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(
|
||||||
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
||||||
"localhost");
|
"localhost");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(
|
||||||
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
||||||
bindConstant().annotatedWith(
|
bindConstant().annotatedWith(
|
||||||
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
|
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
|
||||||
"false");
|
"false");
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
}, new JavaUrlHttpFutureCommandClientModule());
|
}, new JavaUrlHttpFutureCommandClientModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
void tearDownInjector() {
|
void tearDownInjector() {
|
||||||
injector = null;
|
injector = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ClientErrorHandlerTest {
|
private static class ClientErrorHandlerTest {
|
||||||
@Inject
|
@Inject
|
||||||
@ClientErrorHandler
|
@ClientErrorHandler
|
||||||
HttpResponseHandler errorHandler;
|
HttpResponseHandler errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testClientErrorHandler() {
|
void testClientErrorHandler() {
|
||||||
ClientErrorHandlerTest error = injector
|
ClientErrorHandlerTest error = injector
|
||||||
.getInstance(ClientErrorHandlerTest.class);
|
.getInstance(ClientErrorHandlerTest.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
assertEquals(error.errorHandler.getClass(),
|
||||||
ParseS3ErrorFromXmlContent.class);
|
ParseS3ErrorFromXmlContent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ServerErrorHandlerTest {
|
private static class ServerErrorHandlerTest {
|
||||||
@Inject
|
@Inject
|
||||||
@ServerErrorHandler
|
@ServerErrorHandler
|
||||||
HttpResponseHandler errorHandler;
|
HttpResponseHandler errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testServerErrorHandler() {
|
void testServerErrorHandler() {
|
||||||
ServerErrorHandlerTest error = injector
|
ServerErrorHandlerTest error = injector
|
||||||
.getInstance(ServerErrorHandlerTest.class);
|
.getInstance(ServerErrorHandlerTest.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
assertEquals(error.errorHandler.getClass(),
|
||||||
ParseS3ErrorFromXmlContent.class);
|
ParseS3ErrorFromXmlContent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class RedirectHandlerTest {
|
private static class RedirectHandlerTest {
|
||||||
@Inject
|
@Inject
|
||||||
@RedirectHandler
|
@RedirectHandler
|
||||||
HttpResponseHandler errorHandler;
|
HttpResponseHandler errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRedirectHandler() {
|
void testRedirectHandler() {
|
||||||
RedirectHandlerTest error = injector
|
RedirectHandlerTest error = injector
|
||||||
.getInstance(RedirectHandlerTest.class);
|
.getInstance(RedirectHandlerTest.class);
|
||||||
assertEquals(error.errorHandler.getClass(),
|
assertEquals(error.errorHandler.getClass(),
|
||||||
CloseContentAndSetExceptionHandler.class);
|
CloseContentAndSetExceptionHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import org.jclouds.aws.s3.S3Connection;
|
||||||
|
import org.jclouds.aws.s3.StubS3Connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // TODO: Adrian: Document this!
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@S3ConnectionModule
|
||||||
|
public class StubS3ConnectionModule extends AbstractModule {
|
||||||
|
protected void configure() {
|
||||||
|
bind(S3Connection.class).to(StubS3Connection.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,23 +23,21 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import static org.testng.Assert.*;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
|
||||||
import org.jclouds.http.ContentTypes;
|
import org.jclouds.http.ContentTypes;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@Test
|
import java.io.File;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "s3.S3ObjectTest")
|
||||||
public class S3ObjectTest {
|
public class S3ObjectTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSetNoContentType() {
|
void testSetNoContentType() {
|
||||||
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.BINARY);
|
ContentTypes.BINARY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,12 @@ 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.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.jclouds.aws.s3.util.DateService;
|
import org.jclouds.aws.s3.util.DateService;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "s3.RequestAuthorizeSignatureTest")
|
||||||
@Test(groups = "unit", sequential = true, testName = "s3.RequestAuthorizeSignatureTest")
|
|
||||||
public class RequestAuthorizeSignatureTest {
|
public class RequestAuthorizeSignatureTest {
|
||||||
|
|
||||||
RequestAuthorizeSignature filter = null;
|
RequestAuthorizeSignature filter = null;
|
||||||
|
|
|
@ -23,20 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import org.jclouds.aws.s3.xml.config.S3ParserModule;
|
import org.jclouds.aws.s3.xml.config.S3ParserModule;
|
||||||
import org.testng.annotations.AfterMethod;
|
import org.testng.annotations.AfterMethod;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
|
||||||
import com.google.inject.Guice;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
|
|
||||||
public class BaseHandlerTest {
|
public class BaseHandlerTest {
|
||||||
|
|
||||||
protected S3ParserFactory parserFactory = null;
|
protected S3ParserFactory parserFactory = null;
|
||||||
private Injector injector;
|
private Injector injector;
|
||||||
|
|
||||||
public BaseHandlerTest() {
|
public BaseHandlerTest() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
|
|
|
@ -23,43 +23,42 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
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;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@Test
|
@Test(groups = "unit", testName = "s3.ErrorHandlerTest")
|
||||||
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>";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader()
|
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader()
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
ParseSax<S3Error> parser = parserFactory.createErrorParser();
|
ParseSax<S3Error> parser = parserFactory.createErrorParser();
|
||||||
S3Error error = parser
|
S3Error error = parser
|
||||||
.parse(IOUtils
|
.parse(IOUtils
|
||||||
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
|
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
|
||||||
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.getDetails().get("Header"), "Transfer-Encoding");
|
assertEquals(error.getDetails().get("Header"), "Transfer-Encoding");
|
||||||
assertEquals(error.getRequestId(), "7C59925D75D15561");
|
assertEquals(error.getRequestId(), "7C59925D75D15561");
|
||||||
assertEquals(error.getDetails().get("HostId"),
|
assertEquals(error.getDetails().get("HostId"),
|
||||||
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
|
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String badRequestWhenSourceIsDestBucketOnCopy400 = "<Error><Code>InvalidRequest</Code><Message>The Source and Destination may not be the same when the MetadataDirective is Copy.</Message><RequestId>54C77CAF4D42474B</RequestId><HostId>SJecknEUUUx88/65VAKbCdKSOCkpuVTeu7ZG9in9x9NTNglGnoxdbALCfS4k/DUZ</HostId></Error>";
|
public static final String badRequestWhenSourceIsDestBucketOnCopy400 = "<Error><Code>InvalidRequest</Code><Message>The Source and Destination may not be the same when the MetadataDirective is Copy.</Message><RequestId>54C77CAF4D42474B</RequestId><HostId>SJecknEUUUx88/65VAKbCdKSOCkpuVTeu7ZG9in9x9NTNglGnoxdbALCfS4k/DUZ</HostId></Error>";
|
||||||
public static final String noSuchSourceKeyOrBucketOnCopy404 = "<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>null</Key><RequestId>9CCDF1DACA78B36F</RequestId><HostId>63cqk9YsTFBVfBfks840JVGsepPEdQM42mU+r7HN35sF4Nk5xAcWDEUPaQpK2eFU</HostId></Error>";
|
public static final String noSuchSourceKeyOrBucketOnCopy404 = "<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>null</Key><RequestId>9CCDF1DACA78B36F</RequestId><HostId>63cqk9YsTFBVfBfks840JVGsepPEdQM42mU+r7HN35sF4Nk5xAcWDEUPaQpK2eFU</HostId></Error>";
|
||||||
public static final String noSuchDestinationBucketOnCopy404 = "<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>copydestination</BucketName><RequestId>4F0CF319C5535975</RequestId><HostId>hdZyHOm7VK+JI2UCdye3d6TVkKhRBIoWflldXVDTKbgipYlamy8HgPBzHrUAVQNJ</HostId></Error>";
|
public static final String noSuchDestinationBucketOnCopy404 = "<Error><Code>NoSuchBucket</Code><Message>The specified bucketName does not exist</Message><BucketName>copydestination</BucketName><RequestId>4F0CF319C5535975</RequestId><HostId>hdZyHOm7VK+JI2UCdye3d6TVkKhRBIoWflldXVDTKbgipYlamy8HgPBzHrUAVQNJ</HostId></Error>";
|
||||||
public static final String badSign403 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
public static final String badSign403 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
+ "<Error><Code>SignatureDoesNotMatch</Code><Message>The operation signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>47 45 54 0a 0a 0a 54 68 75 2c 20 31 39 20 4d 61 72 20 32 30 30 39 20 31 37 3a 34 38 3a 30 31 20 47 4d 54 0a 2f 61 64 72 69 61 6e 63 6f 6c 65 2e 73 33 2e 61 6d 61 7a 6f 6e 73 33 74 65 73 74 2e 66 69 6c 65 74 65 73 74 73 66 6f 72 61 64 72 69 61 6e 2f 66 69 6c 65</StringToSignBytes><RequestId>514AA22EB75A6E42</RequestId><HostId>H5nqnZkGjuKvB+seutvx5hnp1P+WAuC9c3Y7MdQCcYDr1TGwNX/mt+FHstK0pVld</HostId><SignatureProvided>Qm6Wss7e5e/eNXV50AxChH+xkLI=</SignatureProvided><StringToSign>GET\n"
|
+ "<Error><Code>SignatureDoesNotMatch</Code><Message>The operation signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>47 45 54 0a 0a 0a 54 68 75 2c 20 31 39 20 4d 61 72 20 32 30 30 39 20 31 37 3a 34 38 3a 30 31 20 47 4d 54 0a 2f 61 64 72 69 61 6e 63 6f 6c 65 2e 73 33 2e 61 6d 61 7a 6f 6e 73 33 74 65 73 74 2e 66 69 6c 65 74 65 73 74 73 66 6f 72 61 64 72 69 61 6e 2f 66 69 6c 65</StringToSignBytes><RequestId>514AA22EB75A6E42</RequestId><HostId>H5nqnZkGjuKvB+seutvx5hnp1P+WAuC9c3Y7MdQCcYDr1TGwNX/mt+FHstK0pVld</HostId><SignatureProvided>Qm6Wss7e5e/eNXV50AxChH+xkLI=</SignatureProvided><StringToSign>GET\n"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ "Thu, 19 Mar 2009 17:48:01 GMT\n"
|
+ "Thu, 19 Mar 2009 17:48:01 GMT\n"
|
||||||
+ "/adriancole.s3.amazons3test.filetestsforadrian/file</StringToSign><AWSAccessKeyId>0101100101001001</AWSAccessKeyId></Error>";
|
+ "/adriancole.s3.amazons3test.filetestsforadrian/file</StringToSign><AWSAccessKeyId>0101100101001001</AWSAccessKeyId></Error>";
|
||||||
public static final String amazonHadAnError500 = "<Error><Code>InternalError</Code><Message>We encountered an internal error. Please try again.</Message><RequestId>EF6FA7A639CAFF15</RequestId><HostId>tBkX23mIeq2riHsNw2YShupMlZ9+iy3V/uN+lRhqCR4qHTE07ujFeyAUPTowvuH/</HostId></Error>";
|
public static final String amazonHadAnError500 = "<Error><Code>InternalError</Code><Message>We encountered an internal error. Please try again.</Message><RequestId>EF6FA7A639CAFF15</RequestId><HostId>tBkX23mIeq2riHsNw2YShupMlZ9+iy3V/uN+lRhqCR4qHTE07ujFeyAUPTowvuH/</HostId></Error>";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@Test
|
@Test(groups = "unit", testName = "s3.ListBucketHandlerTest")
|
||||||
public class ListBucketHandlerTest extends BaseHandlerTest {
|
public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>"c82e6a0025c31c5de5947fda62ac51ab"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"944fab2c5a9a6bacf07db5e688310d7a"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"a227b8888045c8fd159fb495214000f0"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"c9caa76c3dec53e2a192608ce73eef03"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"1ce5d0dcc6154a647ea90c7bdf82a224"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"79433524d87462ee05708a8ef894ed55"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"dd00a060b28ddca8bc5a21a49e306f67"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"8cd06eca6e819a927b07a285d750b100"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"174495094d0633b92cbe46603eee6bad"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"cd8a19b26fea8a827276df0ad11c580d"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>";
|
public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>"c82e6a0025c31c5de5947fda62ac51ab"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"944fab2c5a9a6bacf07db5e688310d7a"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"a227b8888045c8fd159fb495214000f0"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"c9caa76c3dec53e2a192608ce73eef03"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"1ce5d0dcc6154a647ea90c7bdf82a224"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>"79433524d87462ee05708a8ef894ed55"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"dd00a060b28ddca8bc5a21a49e306f67"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"8cd06eca6e819a927b07a285d750b100"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"174495094d0633b92cbe46603eee6bad"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>"cd8a19b26fea8a827276df0ad11c580d"</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>";
|
||||||
public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
|
public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
|
||||||
|
@ -40,29 +39,29 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUpParser() {
|
void setUpParser() {
|
||||||
parser = parserFactory.createListBucketParser();
|
parser = parserFactory.createListBucketParser();
|
||||||
((ListBucketHandler) parser.getHandler()).setBucketName("test");
|
((ListBucketHandler) parser.getHandler()).setBucketName("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash()
|
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash()
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
|
|
||||||
S3Bucket bucket = parser.parse(IOUtils
|
S3Bucket bucket = parser.parse(IOUtils
|
||||||
.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
|
.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
|
||||||
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
|
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
|
||||||
assertEquals(bucket.getDelimiter(), "/");
|
assertEquals(bucket.getDelimiter(), "/");
|
||||||
assert bucket.getMarker() == null;
|
assert bucket.getMarker() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListMyBucketsWithPrefixAppsSlash() throws HttpException {
|
public void testListMyBucketsWithPrefixAppsSlash() throws HttpException {
|
||||||
|
|
||||||
S3Bucket bucket = parser.parse(IOUtils
|
S3Bucket bucket = parser.parse(IOUtils
|
||||||
.toInputStream(listBucketWithPrefixAppsSlash));
|
.toInputStream(listBucketWithPrefixAppsSlash));
|
||||||
assertEquals(bucket.getPrefix(), "apps/");
|
assertEquals(bucket.getPrefix(), "apps/");
|
||||||
assertEquals(bucket.getMaxKeys(), 1000);
|
assertEquals(bucket.getMaxKeys(), 1000);
|
||||||
assert bucket.getMarker() == null;
|
assert bucket.getMarker() == null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,19 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.xml;
|
package org.jclouds.aws.s3.xml;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import org.jclouds.aws.s3.xml.config.S3ParserModule;
|
import org.jclouds.aws.s3.xml.config.S3ParserModule;
|
||||||
import org.testng.annotations.AfterMethod;
|
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.Injector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test(groups = "unit", testName = "s3.S3ParserFactoryTest")
|
||||||
public class S3ParserFactoryTest {
|
public class S3ParserFactoryTest {
|
||||||
|
|
||||||
Injector injector = null;
|
Injector injector = null;
|
||||||
|
@ -43,34 +41,34 @@ public class S3ParserFactoryTest {
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
void setUpInjector() {
|
void setUpInjector() {
|
||||||
injector = Guice.createInjector(new S3ParserModule());
|
injector = Guice.createInjector(new S3ParserModule());
|
||||||
parserFactory = injector.getInstance(S3ParserFactory.class);
|
parserFactory = injector.getInstance(S3ParserFactory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
void tearDownInjector() {
|
void tearDownInjector() {
|
||||||
parserFactory = null;
|
parserFactory = null;
|
||||||
injector = null;
|
injector = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateListBucketsParser() {
|
void testCreateListBucketsParser() {
|
||||||
assert parserFactory.createListBucketsParser() != null;
|
assert parserFactory.createListBucketsParser() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateListBucketParser() {
|
void testCreateListBucketParser() {
|
||||||
assert parserFactory.createListBucketParser() != null;
|
assert parserFactory.createListBucketParser() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateCopyObjectParser() {
|
void testCreateCopyObjectParser() {
|
||||||
assert parserFactory.createCopyObjectParser() != null;
|
assert parserFactory.createCopyObjectParser() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateErrorParser() {
|
void testCreateErrorParser() {
|
||||||
assert parserFactory.createErrorParser() != null;
|
assert parserFactory.createErrorParser() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue