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,24 +23,18 @@
|
|||
*/
|
||||
package org.jclouds.http.internal;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
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 com.google.inject.Inject;
|
||||
import org.jclouds.http.*;
|
||||
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.Inject;
|
||||
import javax.annotation.Resource;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandClient {
|
||||
|
||||
|
@ -70,7 +64,7 @@ public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandC
|
|||
HttpResponse response) {
|
||||
int code = response.getStatusCode();
|
||||
if (command.getRequest().isReplayable() && code >= 500) {
|
||||
logger.info("resubmitting command: %1$s", command);
|
||||
logger.debug("resubmitting command: %1$s", command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -23,44 +23,41 @@
|
|||
*/
|
||||
package org.jclouds.logging.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.base.Predicate;
|
||||
import static com.google.common.collect.Sets.filter;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.spi.InjectionListener;
|
||||
import com.google.inject.spi.TypeEncounter;
|
||||
import com.google.inject.spi.TypeListener;
|
||||
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
|
||||
* {@link javax.annotation.Resource}
|
||||
*
|
||||
* <p/>
|
||||
* 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.
|
||||
*
|
||||
* <p/>
|
||||
* Note that this occurs post-object construction through
|
||||
* {@link com.google.inject.Binder#bindListener}.
|
||||
*
|
||||
* <p/>
|
||||
* Here's an example usage:
|
||||
* <pre>
|
||||
* class A {
|
||||
* @Resource private Logger logger = Logger.NULL;
|
||||
* }
|
||||
*
|
||||
* <p/>
|
||||
* Injector i = Guice.createInjector(new AbstractModule() {
|
||||
* @Override protected void configure() {
|
||||
* bindListener(any(), new
|
||||
|
@ -68,13 +65,12 @@ import com.google.inject.spi.TypeListener;
|
|||
* JDKLogger.JDKLoggerFactory()));
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* <p/>
|
||||
* A = i.getInstance(A.class);
|
||||
* // A will now have a logger associated with it
|
||||
* </pre>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class BindLoggersAnnotatedWithResource implements TypeListener {
|
||||
|
||||
|
@ -98,13 +94,10 @@ public class BindLoggersAnnotatedWithResource implements TypeListener {
|
|||
}
|
||||
|
||||
static class LoggerFieldsAnnotatedWithResource implements
|
||||
Function<Field, Field> {
|
||||
public Field apply(Field from) {
|
||||
Predicate<Field> {
|
||||
public boolean apply(Field from) {
|
||||
Annotation inject = from.getAnnotation(Resource.class);
|
||||
if (inject != null && from.getType().isAssignableFrom(Logger.class)) {
|
||||
return from;
|
||||
}
|
||||
return null;
|
||||
return (inject != null && from.getType().isAssignableFrom(Logger.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,9 +131,6 @@ public class BindLoggersAnnotatedWithResource implements TypeListener {
|
|||
fields.addAll(Arrays.asList(type.getDeclaredFields()));
|
||||
type = type.getSuperclass();
|
||||
}
|
||||
Set<Field> loggerFields = Sets.newHashSet(Iterables.transform(fields,
|
||||
new LoggerFieldsAnnotatedWithResource()));
|
||||
loggerFields.remove(null);
|
||||
return loggerFields;
|
||||
return filter(fields, new LoggerFieldsAnnotatedWithResource());
|
||||
}
|
||||
}
|
|
@ -37,6 +37,12 @@ import org.apache.commons.io.IOUtils;
|
|||
public class Utils {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <E> Exception type you'd like rethrown
|
||||
* @param e Exception you are inspecting
|
||||
* @throws E
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E extends Exception> void rethrowIfRuntimeOrSameType(Exception e) throws E {
|
||||
if (e instanceof ExecutionException) {
|
||||
|
|
|
@ -23,28 +23,26 @@
|
|||
*/
|
||||
package org.jclouds.logging.config;
|
||||
|
||||
import static com.google.inject.matcher.Matchers.any;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.AssignLoggerToField;
|
||||
import org.jclouds.logging.config.BindLoggersAnnotatedWithResource.LoggerFieldsAnnotatedWithResource;
|
||||
import org.jclouds.logging.jdk.JDKLogger;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
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 {
|
||||
|
||||
private BindLoggersAnnotatedWithResource blawr;
|
||||
|
@ -100,9 +98,8 @@ public class BindLoggersAnnotatedWithResourceTest {
|
|||
@Test
|
||||
public void testLoggerFieldsAnnotatedWithResource()
|
||||
throws SecurityException, NoSuchFieldException {
|
||||
LoggerFieldsAnnotatedWithResource function = new LoggerFieldsAnnotatedWithResource();
|
||||
assertEquals(function.apply(A.class.getDeclaredField("logger")),
|
||||
A.class.getDeclaredField("logger"));
|
||||
LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource();
|
||||
assert predicate.apply(A.class.getDeclaredField("logger"));
|
||||
}
|
||||
|
||||
public static class C {
|
||||
|
@ -114,8 +111,8 @@ public class BindLoggersAnnotatedWithResourceTest {
|
|||
@Test
|
||||
public void testLoggerFieldsAnnotatedWithInjectReturnsNull()
|
||||
throws SecurityException, NoSuchFieldException {
|
||||
LoggerFieldsAnnotatedWithResource function = new LoggerFieldsAnnotatedWithResource();
|
||||
assertNull(function.apply(C.class.getDeclaredField("logger")));
|
||||
LoggerFieldsAnnotatedWithResource predicate = new LoggerFieldsAnnotatedWithResource();
|
||||
assert ! predicate.apply(C.class.getDeclaredField("logger"));
|
||||
}
|
||||
|
||||
public static class D {
|
||||
|
|
|
@ -24,32 +24,18 @@
|
|||
package org.jclouds.gae;
|
||||
|
||||
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.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
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}
|
||||
*
|
||||
|
@ -73,7 +59,7 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
|
|||
filter.filter(request);
|
||||
}
|
||||
HttpResponse response = null;
|
||||
for (;;) {
|
||||
for (; ;) {
|
||||
logger.trace("%1$s - converting request %2$s", target, request);
|
||||
HTTPRequest gaeRequest = convert(request);
|
||||
if (logger.isTraceEnabled())
|
||||
|
|
|
@ -23,22 +23,17 @@
|
|||
*/
|
||||
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.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
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!
|
||||
*
|
||||
|
|
|
@ -23,14 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.http.httpnio.pool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
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 com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||
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.http.HttpFutureCommand;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Connection Pool for HTTP requests that utilizes Apache HTTPNio
|
||||
|
|
|
@ -23,12 +23,7 @@
|
|||
*/
|
||||
package org.jclouds.http.httpnio.pool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
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.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!
|
||||
|
@ -140,7 +138,7 @@ public class HttpNioFutureCommandExecutionHandler implements
|
|||
|
||||
protected boolean isRetryable(HttpFutureCommand<?> command) {
|
||||
if (command.getRequest().isReplayable()) {
|
||||
logger.info("resubmitting command: %1$s", command);
|
||||
logger.debug("resubmitting command: %1$s", command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -55,8 +55,7 @@
|
|||
<dependency>
|
||||
<groupId>net.java.dev.jets3t</groupId>
|
||||
<artifactId>jets3t</artifactId>
|
||||
<version>0.7.0</version>
|
||||
<optional>true</optional>
|
||||
<version>0.7.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
|
|
1
pom.xml
1
pom.xml
|
@ -51,6 +51,7 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<quiet>true</quiet>
|
||||
<links>
|
||||
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
|
||||
<link>http://java.sun.com/javaee/5/docs/api/</link>
|
||||
|
|
|
@ -182,6 +182,7 @@
|
|||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<quiet>true</quiet>
|
||||
<links>
|
||||
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
|
||||
<link>http://java.sun.com/javaee/5/docs/api/</link>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
|
|
@ -80,8 +80,7 @@
|
|||
<dependency>
|
||||
<groupId>net.java.dev.jets3t</groupId>
|
||||
<artifactId>jets3t</artifactId>
|
||||
<version>0.7.0</version>
|
||||
<optional>true</optional>
|
||||
<version>0.7.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
93
s3/pom.xml
93
s3/pom.xml
|
@ -49,6 +49,9 @@
|
|||
<properties>
|
||||
<jclouds.aws.accesskeyid></jclouds.aws.accesskeyid>
|
||||
<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>
|
||||
|
||||
<dependencies>
|
||||
|
@ -67,13 +70,91 @@
|
|||
<artifactId>bcprov-jdk15</artifactId>
|
||||
<version>140</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<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>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>
|
||||
<!-- 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>unit,performance</groups>
|
||||
<excludedGroups>integration,live</excludedGroups> -->
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</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>
|
||||
|
@ -83,9 +164,21 @@
|
|||
<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>
|
||||
|
|
|
@ -23,42 +23,34 @@
|
|||
*/
|
||||
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.concurrent.ExecutionException;
|
||||
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.
|
||||
*
|
||||
* <p/>
|
||||
* All commands return a Future of the result from S3. Any exceptions incurred
|
||||
* during processing will be wrapped in an {@link ExecutionException} as
|
||||
* documented in {@link Future#get()}.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
|
||||
*/
|
||||
public interface S3Connection {
|
||||
|
||||
/**
|
||||
* Retrieve a complete <code>S3Object</code>.
|
||||
*
|
||||
* @see GetObject
|
||||
* @param bucketName
|
||||
* namespace of the object you are retrieving
|
||||
*
|
||||
* @param key
|
||||
* unique key in the s3Bucket identifying the object
|
||||
* @param bucketName 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
|
||||
* 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);
|
||||
|
||||
|
@ -66,44 +58,38 @@ public interface S3Connection {
|
|||
* Like {@link #getObject(String, String)} except you can use
|
||||
* {@link GetObjectOptions} to control delivery.
|
||||
*
|
||||
* @see #getObject(String, String)
|
||||
* @see GetObjectOptions
|
||||
* @return S3Object containing data relevant to the
|
||||
* <code>options</options> specified or {@link S3Object#NOT_FOUND} if not present.
|
||||
*
|
||||
* @throws HttpResponseException
|
||||
* @throws org.jclouds.http.HttpResponseException
|
||||
* if the conditions requested set were not satisfied by the
|
||||
* object on the server.
|
||||
* @see #getObject(String, String)
|
||||
* @see GetObjectOptions
|
||||
*/
|
||||
Future<S3Object> getObject(String bucketName, String key,
|
||||
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.
|
||||
*
|
||||
* @see HeadObject
|
||||
* @param bucketName
|
||||
* namespace of the metadata you are retrieving
|
||||
*
|
||||
* @param key
|
||||
* unique key in the s3Bucket identifying the object
|
||||
* @param bucketName namespace of the metadata you are retrieving
|
||||
* @param key unique key in the s3Bucket identifying the object
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Removes the object and metadata associated with the key.
|
||||
*
|
||||
* @see DeleteObject
|
||||
* @param bucketName
|
||||
* namespace of the object you are deleting
|
||||
* @param key
|
||||
* unique key in the s3Bucket identifying the object
|
||||
* @param bucketName namespace of the object you are deleting
|
||||
* @param key unique key in the s3Bucket identifying the object
|
||||
* @return true if deleted
|
||||
* @throws HttpResponseException
|
||||
* @throws org.jclouds.http.HttpResponseException
|
||||
* if the bucket is not available
|
||||
* @see org.jclouds.aws.s3.commands.DeleteObject
|
||||
*/
|
||||
Future<Boolean> deleteObject(String bucketName, String key);
|
||||
|
||||
|
@ -113,30 +99,27 @@ public interface S3Connection {
|
|||
* This method will store the object with the default <code>private</code>
|
||||
* acl.
|
||||
*
|
||||
* @see CannedAccessPolicy#PRIVATE
|
||||
* @see PutObject
|
||||
* @param bucketName
|
||||
* namespace of the object you are storing
|
||||
* @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
|
||||
* @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy#PRIVATE
|
||||
* @see org.jclouds.aws.s3.commands.PutObject
|
||||
*/
|
||||
Future<byte[]> putObject(String bucketName, S3Object object);
|
||||
|
||||
/**
|
||||
* Like {@link #putObject(String, S3Object)} except you can use
|
||||
* {@link CopyObjectOptions} to specify an alternate
|
||||
* {@link CannedAccessPolicy acl}, override
|
||||
* {@link S3Object.Metadata#getUserMetadata() userMetadata}, or specify
|
||||
* {@link org.jclouds.aws.s3.domain.acl.CannedAccessPolicy acl}, override
|
||||
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata#getUserMetadata() userMetadata}, or specify
|
||||
* conditions for copying the object.
|
||||
*
|
||||
* @see S3Connection#putObject(String, S3Object)
|
||||
* @see PutObjectOptions
|
||||
* @param options
|
||||
* options for creating the object
|
||||
* @throws HttpResponseException
|
||||
* @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 PutObjectOptions
|
||||
*/
|
||||
Future<byte[]> putObject(String bucketName, S3Object object,
|
||||
PutObjectOptions options);
|
||||
|
@ -144,8 +127,8 @@ public interface S3Connection {
|
|||
/**
|
||||
* Create and name your own bucket in which to store your objects.
|
||||
*
|
||||
* @see PutBucket
|
||||
* @return true, if the bucket was created or already exists
|
||||
* @see org.jclouds.aws.s3.commands.PutBucket
|
||||
*/
|
||||
Future<Boolean> putBucketIfNotExists(String name);
|
||||
|
||||
|
@ -153,19 +136,17 @@ public interface S3Connection {
|
|||
* Like {@link #putBucketIfNotExists(String)} except that you can use
|
||||
* {@link PutBucketOptions} to create the bucket in EU. Create and name your
|
||||
*
|
||||
* @param options for creating your bucket
|
||||
* @see PutBucketOptions
|
||||
* @param options
|
||||
* for creating your bucket
|
||||
*/
|
||||
Future<Boolean> putBucketIfNotExists(String name, PutBucketOptions options);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @see org.jclouds.aws.s3.commands.DeleteBucket
|
||||
*/
|
||||
Future<Boolean> deleteBucketIfEmpty(String s3Bucket);
|
||||
|
||||
|
@ -173,8 +154,8 @@ public interface S3Connection {
|
|||
* Copies one object to another bucket, retaining UserMetadata from the
|
||||
* source. The destination will have a private acl.
|
||||
*
|
||||
* @see CopyObject
|
||||
* @return metadata populated with lastModified and md5 of the new object
|
||||
* @see org.jclouds.aws.s3.commands.CopyObject
|
||||
*/
|
||||
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
||||
String sourceObject, String destinationBucket,
|
||||
|
@ -183,55 +164,51 @@ public interface S3Connection {
|
|||
/**
|
||||
* Like {@link #putObject(String, S3Object)} except you can use
|
||||
* {@link PutObjectOptions} to specify an alternate
|
||||
* {@link CannedAccessPolicy acl}.
|
||||
* {@link org.jclouds.aws.s3.domain.acl.CannedAccessPolicy acl}.
|
||||
*
|
||||
* @see S3Connection#putObject(String, S3Object)
|
||||
* @see PutObjectOptions
|
||||
* @param options
|
||||
* options for creating the object
|
||||
* @throws HttpResponseException
|
||||
* @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 PutObjectOptions
|
||||
*/
|
||||
Future<S3Object.Metadata> copyObject(String sourceBucket,
|
||||
String sourceObject, String destinationBucket,
|
||||
String destinationObject, CopyObjectOptions options);
|
||||
|
||||
/**
|
||||
* @see HeadBucket
|
||||
* @see org.jclouds.aws.s3.commands.BucketExists
|
||||
*/
|
||||
Future<Boolean> bucketExists(String name);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* of the S3Objects it contains or {@link S3Bucket#NOT_FOUND} if not
|
||||
* present.
|
||||
* @see org.jclouds.aws.s3.commands.ListBucket
|
||||
*/
|
||||
Future<S3Bucket> listBucket(String bucketName);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @see ListBucketOptions
|
||||
* @return S3Bucket containing a subset of {@link S3Object.Metadata}
|
||||
* @return S3Bucket containing a subset of {@link org.jclouds.aws.s3.domain.S3Object.Metadata}
|
||||
* depending on
|
||||
* <code>options</options> specified or {@link S3Bucket#NOT_FOUND} if not present.
|
||||
*
|
||||
* @see #listBucket(String)
|
||||
* @see ListBucketOptions
|
||||
*/
|
||||
Future<S3Bucket> listBucket(String name, ListBucketOptions options);
|
||||
|
||||
/**
|
||||
* @see ListOwnedBuckets
|
||||
* @return list of all of the buckets owned by the authenticated sender of
|
||||
* the request.
|
||||
* @see org.jclouds.aws.s3.commands.ListOwnedBuckets
|
||||
*/
|
||||
Future<List<S3Bucket.Metadata>> listOwnedBuckets();
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ public interface S3Context {
|
|||
* bucket.
|
||||
*
|
||||
* @param bucket
|
||||
* @return
|
||||
*/
|
||||
S3InputStreamMap createInputStreamMap(String bucket);
|
||||
|
||||
|
@ -58,7 +57,6 @@ public interface S3Context {
|
|||
* Creates a <code>Map<String,S3Object></code> view of the specified bucket.
|
||||
*
|
||||
* @param bucket
|
||||
* @return
|
||||
*/
|
||||
S3ObjectMap createS3ObjectMap(String bucket);
|
||||
|
||||
|
|
|
@ -23,28 +23,8 @@
|
|||
*/
|
||||
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 static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -54,6 +34,21 @@ import com.google.inject.Guice;
|
|||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
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
|
||||
|
@ -61,15 +56,15 @@ import com.google.inject.name.Names;
|
|||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or
|
||||
* Context provided.
|
||||
*
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default
|
||||
* {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpFutureCommandClientModule http transports} will be
|
||||
* installed.
|
||||
*
|
||||
* @see S3Context
|
||||
* @author Adrian Cole
|
||||
* @see S3Context
|
||||
*/
|
||||
public class S3ContextFactory {
|
||||
|
||||
|
@ -177,11 +172,9 @@ public class S3ContextFactory {
|
|||
* are specified, install the default {@link JDKLoggingModule}
|
||||
* {@link JavaUrlHttpFutureCommandClientModule}
|
||||
*
|
||||
* @param properties
|
||||
* - contains constants used by jclouds
|
||||
* @param properties - contains constants used by jclouds
|
||||
* {@link #DEFAULT_PROPERTIES}
|
||||
* @param configModules
|
||||
* - alternative configuration modules
|
||||
* @param configModules - alternative configuration modules
|
||||
*/
|
||||
public static Injector createInjector(final Properties properties,
|
||||
Module... configModules) {
|
||||
|
@ -189,7 +182,9 @@ public class S3ContextFactory {
|
|||
|
||||
addLoggingModuleIfNotPresent(modules);
|
||||
|
||||
addHttpModuleIfNotPresent(modules);
|
||||
addHttpModuleIfNeededAndNotPresent(modules);
|
||||
|
||||
addS3ConnectionModuleIfNotPresent(modules);
|
||||
|
||||
return Guice.createInjector(new AbstractModule() {
|
||||
@Override
|
||||
|
@ -203,17 +198,36 @@ public class S3ContextFactory {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void addHttpModuleIfNotPresent(final List<Module> modules) {
|
||||
if (!Iterables.any(modules, new Predicate<Module>() {
|
||||
static void addHttpModuleIfNeededAndNotPresent(final List<Module> modules) {
|
||||
if (Iterables.any(modules, new Predicate<Module>() {
|
||||
public boolean apply(Module input) {
|
||||
return input instanceof LiveS3ConnectionModule;
|
||||
}
|
||||
|
||||
}) && (!Iterables.any(modules, new Predicate<Module>() {
|
||||
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
|
||||
static void addLoggingModuleIfNotPresent(final List<Module> modules) {
|
||||
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
|
||||
|
|
|
@ -28,17 +28,16 @@ import java.io.InputStream;
|
|||
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.
|
||||
*
|
||||
* <p/>
|
||||
* <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
|
||||
* 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.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface S3InputStreamMap extends S3Map<String, InputStream> {
|
||||
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 S3Error
|
||||
* @see ParseS3ErrorFromXmlContent
|
||||
* @see org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -23,12 +23,10 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
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.joda.time.DateTime;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Contains options supported in the REST API for the COPY object operation.
|
||||
|
@ -49,12 +45,12 @@ import com.google.common.collect.Multimap;
|
|||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
|
||||
*
|
||||
* <p/>
|
||||
* S3Connection connection = // get connection
|
||||
*
|
||||
* <p/>
|
||||
* Multimap<String,String> metadata = HashMultimap.create();
|
||||
* metadata.put("x-amz-meta-adrian", "foo");
|
||||
*
|
||||
* <p/>
|
||||
* // 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.
|
||||
* Future<S3Object.Metadata> object = connection.copyObject("sourceBucket", "objectName",
|
||||
|
@ -64,11 +60,9 @@ import com.google.common.collect.Multimap;
|
|||
* );
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html?"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||
private final static DateService dateService = new DateService();
|
||||
|
@ -100,15 +94,15 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* 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;
|
||||
* otherwise returns a 412 (precondition failed).
|
||||
* <p />
|
||||
* <p/>
|
||||
* This header can be used with x-amz-copy-source-if-match, but cannot be
|
||||
* used with other conditional copy headers.
|
||||
*
|
||||
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
||||
* @return valid HTTP date
|
||||
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
||||
* @see CopyObjectOptions#ifSourceModifiedSince(DateTime)
|
||||
*/
|
||||
public String getIfModifiedSince() {
|
||||
|
@ -117,15 +111,15 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* 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;
|
||||
* otherwise returns a 412 (failed condition).
|
||||
* <p/>
|
||||
* This header can be used with x-amz-copy-source-if-none-match, but cannot
|
||||
* be used with other conditional copy headers.
|
||||
*
|
||||
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
||||
* @return valid HTTP date
|
||||
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
|
||||
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
|
||||
*/
|
||||
public String getIfUnmodifiedSince() {
|
||||
|
@ -134,7 +128,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* 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;
|
||||
* otherwise return a 412 (precondition failed).
|
||||
* <p/>
|
||||
|
@ -149,7 +143,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* 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
|
||||
* specified Etag; otherwise returns a 412 (failed condition).
|
||||
* <p/>
|
||||
|
@ -175,7 +169,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* Only return the object if it has changed since this time.
|
||||
* <p />
|
||||
* <p/>
|
||||
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
|
||||
* {@link #ifSourceUnmodifiedSince(DateTime)}
|
||||
*/
|
||||
|
@ -192,7 +186,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* Only return the object if it hasn't changed since this time.
|
||||
* <p />
|
||||
* <p/>
|
||||
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
|
||||
* {@link #ifSourceModifiedSince(DateTime)}
|
||||
*/
|
||||
|
@ -209,15 +203,13 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
|
||||
/**
|
||||
* The object's md5 hash should match the parameter <code>md5</code>.
|
||||
*
|
||||
* <p />
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
|
||||
* {@link #ifSourceModifiedSince(DateTime)}
|
||||
*
|
||||
* @param md5
|
||||
* hash representing the entity
|
||||
* @throws UnsupportedEncodingException
|
||||
* if there was a problem converting this into an S3 eTag string
|
||||
* @param md5 hash representing the entity
|
||||
* @throws UnsupportedEncodingException if there was a problem converting this into an S3 eTag string
|
||||
*/
|
||||
public CopyObjectOptions ifSourceMd5Matches(byte[] md5)
|
||||
throws UnsupportedEncodingException {
|
||||
|
@ -233,14 +225,12 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
|||
/**
|
||||
* The object should not have a md5 hash corresponding with the parameter
|
||||
* <code>md5</code>.
|
||||
* <p />
|
||||
* <p/>
|
||||
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
|
||||
* {@link #ifSourceUnmodifiedSince(DateTime)}
|
||||
*
|
||||
* @param md5
|
||||
* hash representing the entity
|
||||
* @throws UnsupportedEncodingException
|
||||
* if there was a problem converting this into an S3 eTag string
|
||||
* @param md5 hash representing the entity
|
||||
* @throws UnsupportedEncodingException if there was a problem converting this into an S3 eTag string
|
||||
*/
|
||||
public CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
|
||||
throws UnsupportedEncodingException {
|
||||
|
|
|
@ -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.checkState;
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -39,17 +38,14 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
|||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
|
||||
*
|
||||
* <p/>
|
||||
* S3Connection connection = // get connection
|
||||
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html?"
|
||||
* />
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||
public static final ListBucketOptions NONE = new ListBucketOptions();
|
||||
|
@ -122,7 +118,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
*
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public ListBucketOptions setDelimiter(String delimiter)
|
||||
public ListBucketOptions delimiter(String delimiter)
|
||||
throws UnsupportedEncodingException {
|
||||
options.put("delimiter", URLEncoder.encode(checkNotNull(delimiter,
|
||||
"delimiter"), "UTF-8"));
|
||||
|
@ -130,7 +126,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see ListBucketOptions#setDelimiter(String)
|
||||
* @see ListBucketOptions#delimiter(String)
|
||||
*/
|
||||
public String getDelimiter() {
|
||||
return options.get("delimiter");
|
||||
|
@ -173,7 +169,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
public static ListBucketOptions delimiter(String delimiter)
|
||||
throws UnsupportedEncodingException {
|
||||
ListBucketOptions options = new ListBucketOptions();
|
||||
return options.setDelimiter(delimiter);
|
||||
return options.delimiter(delimiter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
*/
|
||||
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.acl.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
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>
|
||||
* 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.domain.S3Bucket.Metadata.LocationConstraint.*;
|
||||
* import org.jclouds.aws.s3.S3Connection;
|
||||
*
|
||||
* <p/>
|
||||
* S3Connection connection = // get connection
|
||||
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html?"
|
||||
* />
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class PutBucketOptions extends BaseHttpRequestOptions {
|
||||
public static final PutBucketOptions NONE = new PutBucketOptions();
|
||||
|
@ -90,7 +87,7 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see PutBucketOptions#createIn(LocationConstraint)
|
||||
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint)
|
||||
*/
|
||||
public LocationConstraint getLocationConstraint() {
|
||||
return constraint;
|
||||
|
@ -98,7 +95,7 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
|
|||
|
||||
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) {
|
||||
PutBucketOptions options = new PutBucketOptions();
|
||||
|
|
|
@ -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,61 +23,27 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
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 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
|
||||
*/
|
||||
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
|
||||
protected void configure() {
|
||||
this.requireBinding(S3Connection.class);
|
||||
install(new S3CommandsModule());
|
||||
bind(S3Connection.class).to(LiveS3Connection.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
bind(GuiceS3Context.S3ObjectMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(
|
||||
GuiceS3Context.S3ObjectMapFactory.class,
|
||||
|
@ -87,25 +53,7 @@ public class S3ContextModule extends AbstractModule {
|
|||
GuiceS3Context.S3InputStreamMapFactory.class,
|
||||
LiveS3InputStreamMap.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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A container that provides namespace, access control and aggregation of
|
||||
* {@link S3Object}s
|
||||
*
|
||||
* <p/>
|
||||
* <p/>
|
||||
* 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
|
||||
* bucket, you can use any names for your objects, but bucket names must be
|
||||
* unique across all of Amazon S3.
|
||||
*
|
||||
* <p/>
|
||||
* 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
|
||||
* 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
|
||||
* like and the bucket will remain yours for as long as you like and as long as
|
||||
* you have the Amazon S3 account.
|
||||
*
|
||||
* <p/>
|
||||
* The similarities between buckets and domain names is not a coincidenceÑthere
|
||||
* is a direct mapping between Amazon S3 buckets and subdomains of
|
||||
* s3.amazonaws.com. Objects stored in Amazon S3 are addressable using the REST
|
||||
|
@ -65,7 +64,7 @@ public class S3Bucket {
|
|||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("S3Bucket");
|
||||
sb.append("{metadata=").append(metadata);
|
||||
sb.append(", isComplete=").append(isComplete);
|
||||
sb.append(", isTruncated=").append(isTruncated);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -79,7 +78,7 @@ public class S3Bucket {
|
|||
|
||||
S3Bucket s3Bucket = (S3Bucket) o;
|
||||
|
||||
if (isComplete != s3Bucket.isComplete)
|
||||
if (isTruncated != s3Bucket.isTruncated)
|
||||
return false;
|
||||
if (!metadata.equals(s3Bucket.metadata))
|
||||
return false;
|
||||
|
@ -94,7 +93,7 @@ public class S3Bucket {
|
|||
public int hashCode() {
|
||||
int result = objects != null ? objects.hashCode() : 0;
|
||||
result = 31 * result + metadata.hashCode();
|
||||
result = 31 * result + (isComplete ? 1 : 0);
|
||||
result = 31 * result + (isTruncated ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -102,7 +101,6 @@ public class S3Bucket {
|
|||
* System metadata of the S3Bucket
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public static class Metadata {
|
||||
@Override
|
||||
|
@ -145,11 +143,10 @@ public class S3Bucket {
|
|||
/**
|
||||
* Location constraint of the bucket.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public static enum LocationConstraint {
|
||||
EU
|
||||
|
@ -168,16 +165,15 @@ public class S3Bucket {
|
|||
|
||||
/**
|
||||
* To comply with Amazon S3 requirements, bucket names must:
|
||||
*
|
||||
* <p/>
|
||||
* Contain lowercase letters, numbers, periods (.), underscores (_), and
|
||||
* dashes (-)
|
||||
*
|
||||
* <p/>
|
||||
* Start with a number or letter
|
||||
*
|
||||
* <p/>
|
||||
* Be between 3 and 255 characters long
|
||||
*
|
||||
* <p/>
|
||||
* Not be in an IP address style (e.g., "192.168.5.4")
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
|
@ -217,7 +213,7 @@ public class S3Bucket {
|
|||
private long maxKeys;
|
||||
private final Metadata metadata;
|
||||
|
||||
private boolean isComplete;
|
||||
private boolean isTruncated;
|
||||
|
||||
public S3Bucket(String name) {
|
||||
this.metadata = new Metadata(name);
|
||||
|
@ -245,12 +241,12 @@ public class S3Bucket {
|
|||
/**
|
||||
* @return true, if the list contains all objects.
|
||||
*/
|
||||
public boolean isComplete() {
|
||||
return isComplete;
|
||||
public boolean isTruncated() {
|
||||
return isTruncated;
|
||||
}
|
||||
|
||||
public void setComplete(boolean complete) {
|
||||
isComplete = complete;
|
||||
public void setTruncated(boolean truncated) {
|
||||
isTruncated = truncated;
|
||||
}
|
||||
|
||||
public Metadata getMetadata() {
|
||||
|
@ -263,14 +259,14 @@ public class S3Bucket {
|
|||
|
||||
/**
|
||||
* Example:
|
||||
* <p />
|
||||
* <p/>
|
||||
* if the following keys are in the bucket
|
||||
*
|
||||
* <p/>
|
||||
* a/1/a<br/>
|
||||
* a/1/b<br/>
|
||||
* a/2/a<br/>
|
||||
* a/2/b<br/>
|
||||
* <p />
|
||||
* <p/>
|
||||
* and prefix is set to <code>a/</code> and delimiter is set to
|
||||
* <code>/</code> then commonprefixes would return 1,2
|
||||
*
|
||||
|
|
|
@ -23,32 +23,28 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
import org.jclouds.aws.s3.util.S3Utils.Md5InputStreamResult;
|
||||
import org.jclouds.http.ContentTypes;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* metadata}, and an access control policy.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3Object {
|
||||
public static final S3Object NOT_FOUND = new S3Object(Metadata.NOT_FOUND);
|
||||
|
@ -79,13 +75,12 @@ public class S3Object {
|
|||
/**
|
||||
* System and user Metadata for the {@link S3Object}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href=
|
||||
* "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");
|
||||
|
||||
// parsed during list, head, or get
|
||||
|
@ -107,8 +102,8 @@ public class S3Object {
|
|||
private String storageClass = null;
|
||||
|
||||
/**
|
||||
* @see #getKey()
|
||||
* @param key
|
||||
* @see #getKey()
|
||||
*/
|
||||
public Metadata(String key) {
|
||||
checkNotNull(key, "key");
|
||||
|
@ -196,8 +191,6 @@ public class S3Object {
|
|||
* @see <a href=
|
||||
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13."
|
||||
* />
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
|
@ -210,12 +203,9 @@ public class S3Object {
|
|||
/**
|
||||
* A standard MIME type describing the format of the contents. If none
|
||||
* is provided, the default is binary/octet-stream.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17."
|
||||
* />
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getContentType() {
|
||||
return dataType;
|
||||
|
@ -226,14 +216,14 @@ public class S3Object {
|
|||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
public byte[] getMd5() {
|
||||
return md5;
|
||||
return (md5 == null) ? null : Arrays.copyOf(md5, md5.length);
|
||||
}
|
||||
|
||||
public void setUserMetadata(Multimap<String, String> userMetadata) {
|
||||
|
@ -241,12 +231,10 @@ public class S3Object {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Any header starting with <code>x-amz-meta-</code> is considered user
|
||||
* metadata. It will be stored with the object and returned when you
|
||||
* retrieve the object. The total size of the HTTP request, not
|
||||
* including the body, must be less than 8 KB.
|
||||
*
|
||||
*/
|
||||
public Multimap<String, String> getUserMetadata() {
|
||||
return userMetadata;
|
||||
|
@ -326,12 +314,15 @@ public class S3Object {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return all http response headers associated with this S3Object
|
||||
*/
|
||||
public Multimap<String, String> getAllHeaders() {
|
||||
return allHeaders;
|
||||
}
|
||||
|
||||
public int compareTo(Metadata o) {
|
||||
return (this == o) ? 0 : getKey().compareTo(o.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,8 +336,7 @@ public class S3Object {
|
|||
* Sets payload for the request or the content from the response. If size
|
||||
* isn't set, this will attempt to discover it.
|
||||
*
|
||||
* @param data
|
||||
* typically InputStream for downloads, or File, byte [], String,
|
||||
* @param data typically InputStream for downloads, or File, byte [], String,
|
||||
* or InputStream for uploads.
|
||||
*/
|
||||
public void setData(Object data) {
|
||||
|
@ -357,13 +347,12 @@ public class S3Object {
|
|||
|
||||
/**
|
||||
* generate an MD5 Hash for the current data.
|
||||
*
|
||||
* <p/>
|
||||
* <h2>Note</h2>
|
||||
* <p/>
|
||||
* If this is an InputStream, it will be converted to a byte array first.
|
||||
*
|
||||
* @throws IOException
|
||||
* if there is a problem generating the hash.
|
||||
* @throws IOException if there is a problem generating the hash.
|
||||
*/
|
||||
public void generateMd5() throws IOException {
|
||||
checkState(data != null, "data");
|
||||
|
@ -379,7 +368,6 @@ public class S3Object {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return InputStream, if downloading, or whatever was set during
|
||||
* {@link #setData(Object)}
|
||||
*/
|
||||
|
@ -392,7 +380,6 @@ public class S3Object {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return System and User metadata relevant to this object.
|
||||
*/
|
||||
public Metadata getMetadata() {
|
||||
|
@ -444,11 +431,10 @@ public class S3Object {
|
|||
* {@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.
|
||||
*
|
||||
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
|
||||
* @see GetObjectOptions
|
||||
* @return the length in bytes that can be be obtained from
|
||||
* {@link #getData()}
|
||||
*
|
||||
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
|
||||
* @see GetObjectOptions
|
||||
*/
|
||||
public long getContentLength() {
|
||||
return contentLength;
|
||||
|
|
|
@ -24,19 +24,9 @@
|
|||
package org.jclouds.aws.s3.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
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 com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.name.Named;
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.S3Map;
|
||||
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.util.Utils;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
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}
|
||||
|
@ -55,7 +49,6 @@ import com.google.inject.name.Named;
|
|||
* complete before throwing an exception.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
* @param <V>
|
||||
* value of the map
|
||||
*/
|
||||
|
@ -74,7 +67,7 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
@Inject
|
||||
public BaseS3Map(S3Connection connection, @Assisted String bucket) {
|
||||
this.connection = checkNotNull(connection, "connection");
|
||||
this.bucket = checkNotNull(bucket, "bucket");
|
||||
this.bucket = checkNotNull(bucket, "bucketName");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,8 +83,8 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
Set<S3Object.Metadata> contents = bucket.getContents();
|
||||
return contents.size();
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error getting size of bucket"
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error getting size of bucketName"
|
||||
+ bucket, e);
|
||||
}
|
||||
}
|
||||
|
@ -136,10 +129,9 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
object = futureObject.get(requestTimeoutMilliseconds,
|
||||
TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException(String.format(
|
||||
"Error getting value from bucket %1$s:%2$s", bucket,
|
||||
object != null ? object.getKey() : "unknown"), e);
|
||||
"Error getting value from bucket %1$s", bucket), e);
|
||||
}
|
||||
if (object != S3Object.NOT_FOUND)
|
||||
objects.add(object);
|
||||
|
@ -149,19 +141,19 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p/>
|
||||
* Note that if value is an instance of InputStream, it will be read and
|
||||
* 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) {
|
||||
try {
|
||||
byte[] md5 = getMd5(value);
|
||||
return containsMd5(md5);
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -190,8 +182,8 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
throw new S3RuntimeException("failed to delete entry");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error clearing bucket" + bucket, e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error clearing bucketName" + bucket, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +192,7 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
S3Bucket currentBucket = connection.listBucket(bucket).get(
|
||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
if (currentBucket == S3Bucket.NOT_FOUND)
|
||||
throw new S3RuntimeException("bucket not found: " + bucket);
|
||||
throw new S3RuntimeException("bucketName not found: " + bucket);
|
||||
else
|
||||
return currentBucket;
|
||||
}
|
||||
|
@ -212,8 +204,8 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
keys.add(object.getKey());
|
||||
return keys;
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error getting keys in bucket: "
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error getting keys in bucketName: "
|
||||
+ bucket, e);
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +215,7 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
return connection.headObject(bucket, key.toString()).get(
|
||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS) != S3Object.Metadata.NOT_FOUND;
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException(String.format(
|
||||
"Error searching for %1$s:%2$s", bucket, key), e);
|
||||
}
|
||||
|
@ -237,8 +229,8 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
|
|||
try {
|
||||
return refreshBucket();
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error getting bucket" + bucket, e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error getting bucketName" + bucket, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,10 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.S3InputStreamMap;
|
||||
|
@ -34,14 +32,14 @@ import org.jclouds.aws.s3.S3ObjectMap;
|
|||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Uses a Guice Injector to configure the objects served by S3Context methods.
|
||||
*
|
||||
* @see Injector
|
||||
* @author Adrian Cole
|
||||
* @see Injector
|
||||
*/
|
||||
public class GuiceS3Context implements S3Context {
|
||||
public interface S3ObjectMapFactory {
|
||||
|
|
|
@ -23,35 +23,28 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
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 com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.S3InputStreamMap;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
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
|
||||
* in Md5 calculation. If this is not desired, use {@link LiveS3ObjectMap}
|
||||
* instead.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see S3Connection
|
||||
* @see BaseS3Map
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
||||
S3InputStreamMap {
|
||||
|
@ -72,7 +65,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS))
|
||||
.getData();
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException(String.format(
|
||||
"Error geting object %1$s:%2$s", bucket, o), e);
|
||||
}
|
||||
|
@ -89,7 +82,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
connection.deleteObject(bucket, o.toString()).get(
|
||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException(String.format(
|
||||
"Error removing object %1$s:%2$s", bucket, o), e);
|
||||
}
|
||||
|
@ -124,9 +117,6 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
return entrySet;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public class Entry implements java.util.Map.Entry<String, InputStream> {
|
||||
|
||||
private InputStream value;
|
||||
|
@ -203,9 +193,9 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
void putAllInternal(Map<? extends String, ? extends Object> map) {
|
||||
try {
|
||||
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
|
||||
for (String key : map.keySet()) {
|
||||
S3Object object = new S3Object(key);
|
||||
object.setData(map.get(key));
|
||||
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
|
||||
S3Object object = new S3Object(entry.getKey());
|
||||
object.setData(entry.getValue());
|
||||
object.generateMd5();
|
||||
puts.add(connection.putObject(bucket, object));
|
||||
}
|
||||
|
@ -213,8 +203,8 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
// this will throw an exception if there was a problem
|
||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error putting into bucket" + bucket,
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error putting into bucketName" + bucket,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +246,6 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* calculates md5 before adding the object to s3. As a side-effect of this,
|
||||
* the content will be copied into a byte []. *
|
||||
*
|
||||
|
@ -273,7 +262,7 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
|
|||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
return returnVal;
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException(String.format(
|
||||
"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) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
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);
|
||||
}
|
||||
return returnVal;
|
||||
|
@ -149,7 +149,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
|
|||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new S3RuntimeException("Error putting into bucket" + bucket,
|
||||
throw new S3RuntimeException("Error putting into bucketName" + bucket,
|
||||
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"/>
|
||||
* @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.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.output.ByteArrayOutputStream;
|
||||
import org.bouncycastle.crypto.digests.MD5Digest;
|
||||
|
@ -46,12 +35,17 @@ import org.bouncycastle.util.encoders.Base64;
|
|||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
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
|
||||
* and responses.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class S3Utils extends Utils {
|
||||
|
||||
|
@ -62,21 +56,21 @@ public class S3Utils extends Utils {
|
|||
public static String validateBucketName(String bucketName) {
|
||||
checkNotNull(bucketName, "bucketName");
|
||||
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(
|
||||
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,
|
||||
"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(),
|
||||
"bucket name cannot be ip address style");
|
||||
"bucketName name cannot be ip address style");
|
||||
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) '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)
|
||||
throws UnsupportedEncodingException {
|
||||
|
@ -104,13 +98,13 @@ public class S3Utils extends Utils {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] md5(Object data) throws IOException {
|
||||
checkNotNull(data, "data must be set before calling generateMd5()");
|
||||
byte[] md5 = null;
|
||||
if (data == null || data instanceof byte[]) {
|
||||
if (data == null) {
|
||||
} else if (data instanceof byte[]) {
|
||||
md5 = S3Utils.md5((byte[]) data);
|
||||
} else if (data instanceof String) {
|
||||
md5 = S3Utils.md5(((String) data).getBytes());
|
||||
|
@ -210,6 +204,7 @@ public class S3Utils extends Utils {
|
|||
}
|
||||
} while (numRead != -1);
|
||||
} finally {
|
||||
out.close();
|
||||
IOUtils.closeQuietly(toEncode);
|
||||
}
|
||||
md5.doFinal(resBuf, 0);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
package org.jclouds.aws.s3.xml;
|
||||
|
||||
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.S3Bucket;
|
||||
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.xml.sax.Attributes;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Parses the following XML document:
|
||||
* <p/>
|
||||
* 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"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
||||
private S3Bucket s3Bucket;
|
||||
|
@ -97,7 +95,7 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
|||
currentObjectMetadata.setStorageClass(currentText.toString());
|
||||
} else if (qName.equals("Contents")) {
|
||||
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")) {
|
||||
String prefix = currentText.toString().trim();
|
||||
if (inCommonPrefixes)
|
||||
|
@ -114,7 +112,7 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
|
|||
s3Bucket.setMaxKeys(Long.parseLong(currentText.toString()));
|
||||
} else if (qName.equals("IsTruncated")) {
|
||||
boolean isTruncated = Boolean.parseBoolean(currentText.toString());
|
||||
s3Bucket.setComplete(!isTruncated);
|
||||
s3Bucket.setTruncated(isTruncated);
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -23,16 +23,15 @@
|
|||
*/
|
||||
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.S3Error;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Creates Parsers needed to interpret S3 Server messages. This class uses guice
|
||||
|
@ -55,7 +54,7 @@ public class S3ParserFactory {
|
|||
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() {
|
||||
return parseListAllMyBucketsFactory
|
||||
|
@ -69,7 +68,7 @@ public class S3ParserFactory {
|
|||
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() {
|
||||
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
|
||||
|
@ -82,7 +81,7 @@ public class S3ParserFactory {
|
|||
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() {
|
||||
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.util.concurrent.Executors;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", sequential = true, testName = "s3.PerformanceTest")
|
||||
@Test(groups = "performance", sequential = true, testName = "s3.PerformanceTest")
|
||||
public class PerformanceTest {
|
||||
protected static int LOOP_COUNT = 1000;
|
||||
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,27 +23,26 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
|
||||
import org.jclouds.http.config.HttpFutureCommandClientModule;
|
||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||
import org.jclouds.logging.config.LoggingModule;
|
||||
import org.jclouds.logging.config.NullLoggingModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in S3ContextFactory
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.S3ContextFactoryTest")
|
||||
public class S3ContextFactoryTest {
|
||||
|
||||
@HttpFutureCommandClientModule
|
||||
|
@ -60,7 +59,7 @@ public class S3ContextFactoryTest {
|
|||
List<Module> modules = new ArrayList<Module>();
|
||||
HttpModule module = new HttpModule();
|
||||
modules.add(module);
|
||||
S3ContextFactory.addHttpModuleIfNotPresent(modules);
|
||||
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.remove(0), module);
|
||||
}
|
||||
|
@ -82,7 +81,7 @@ public class S3ContextFactoryTest {
|
|||
modules.add(loggingModule);
|
||||
HttpModule httpModule = new HttpModule();
|
||||
modules.add(httpModule);
|
||||
S3ContextFactory.addHttpModuleIfNotPresent(modules);
|
||||
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
||||
assertEquals(modules.size(), 2);
|
||||
assertEquals(modules.remove(0), loggingModule);
|
||||
|
@ -90,11 +89,22 @@ public class S3ContextFactoryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testAddBoth() {
|
||||
public void testAddBothWhenNotLive() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3ContextFactory.addHttpModuleIfNotPresent(modules);
|
||||
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
|
||||
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
|
||||
assertEquals(modules.size(), 2);
|
||||
assertEquals(modules.size(), 1);
|
||||
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,46 +24,31 @@
|
|||
package org.jclouds.aws.s3;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
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 com.google.inject.Module;
|
||||
import org.jclouds.aws.s3.config.StubS3ConnectionModule;
|
||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
import org.jclouds.http.HttpConstants;
|
||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Optional;
|
||||
import org.testng.annotations.Parameters;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
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 {
|
||||
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
|
||||
|
||||
protected byte[] goodMd5;
|
||||
protected byte[] badMd5;
|
||||
protected String bucketName;
|
||||
|
||||
protected void createBucketAndEnsureEmpty(String sourceBucket)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
|
@ -84,7 +69,6 @@ public class S3IntegrationTest {
|
|||
protected void addObjectToBucket(String sourceBucket, S3Object object)
|
||||
throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
;
|
||||
client.putObject(sourceBucket, object).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
@ -100,7 +84,7 @@ public class S3IntegrationTest {
|
|||
return newObject;
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
@BeforeClass(groups = {"integration", "live"})
|
||||
void enableDebug() {
|
||||
if (debugEnabled()) {
|
||||
Handler HANDLER = new ConsoleHandler() {
|
||||
|
@ -139,29 +123,57 @@ public class S3IntegrationTest {
|
|||
private static final String sysAWSSecretAccessKey = System
|
||||
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||
|
||||
@BeforeTest
|
||||
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
||||
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
|
||||
protected void setUpClient(@Optional String AWSAccessKeyId,
|
||||
@Optional String AWSSecretAccessKey) throws Exception {
|
||||
context = createS3Context(AWSAccessKeyId != null ? AWSAccessKeyId
|
||||
: sysAWSAccessKeyId,
|
||||
AWSSecretAccessKey != null ? AWSSecretAccessKey
|
||||
: sysAWSSecretAccessKey);
|
||||
@BeforeClass(inheritGroups = false, groups = {"integration", "live"})
|
||||
@Parameters({S3Constants.PROPERTY_AWS_ACCESSKEYID,
|
||||
S3Constants.PROPERTY_AWS_SECRETACCESSKEY})
|
||||
protected void setUpCredentials(@Optional String AWSAccessKeyId,
|
||||
@Optional String AWSSecretAccessKey, ITestContext testContext) throws Exception {
|
||||
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId
|
||||
: sysAWSAccessKeyId;
|
||||
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey
|
||||
: sysAWSSecretAccessKey;
|
||||
if (AWSAccessKeyId != null)
|
||||
testContext.setAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID, AWSAccessKeyId);
|
||||
if (AWSSecretAccessKey != null)
|
||||
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");
|
||||
}
|
||||
|
||||
protected boolean debugEnabled() {
|
||||
return false;
|
||||
@BeforeMethod(dependsOnMethods = "deleteBucket", groups = {"integration", "live"})
|
||||
public void setUpBucket(Method method) throws TimeoutException, ExecutionException, InterruptedException {
|
||||
bucketName = (bucketPrefix + method.getName()).toLowerCase();
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
}
|
||||
|
||||
protected S3Context createS3Context(String AWSAccessKeyId,
|
||||
String AWSSecretAccessKey) {
|
||||
return S3ContextFactory.createS3Context(buildS3Properties(
|
||||
AWSAccessKeyId, AWSSecretAccessKey), createHttpModule());
|
||||
@BeforeMethod(groups = {"integration", "live"})
|
||||
@AfterMethod(groups = {"integration", "live"})
|
||||
public void deleteBucket() throws TimeoutException, ExecutionException, InterruptedException {
|
||||
if (bucketName != null)
|
||||
deleteBucket(bucketName);
|
||||
}
|
||||
|
||||
protected boolean debugEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Properties buildS3Properties(String AWSAccessKeyId,
|
||||
|
@ -185,22 +197,9 @@ public class S3IntegrationTest {
|
|||
try {
|
||||
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(
|
||||
10, TimeUnit.SECONDS);
|
||||
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
|
||||
for (S3Bucket.Metadata metaDatum : metadata) {
|
||||
if (metaDatum.getName().startsWith(bucketPrefix.toLowerCase())) {
|
||||
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);
|
||||
deleteBucket(metaDatum.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -209,7 +208,27 @@ public class S3IntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
deleteEverything();
|
||||
context.close();
|
||||
|
|
|
@ -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.jclouds.aws.PerformanceTest;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -38,14 +39,12 @@ import java.util.concurrent.CompletionService;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* This tests the performance of Digest commands.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", sequential = true, testName = "s3.PerformanceTest")
|
||||
@Test(groups = "performance", sequential = true, testName = "s3.PerformanceTest")
|
||||
public class S3UtilsTest extends PerformanceTest {
|
||||
|
||||
@Test(dataProvider = "hmacsha1")
|
||||
|
@ -78,30 +77,31 @@ public class S3UtilsTest extends PerformanceTest {
|
|||
public Object[][] createMD5Data() {
|
||||
return base64MD5MessageDigest;
|
||||
}
|
||||
|
||||
public final static Object[][] base64MD5MessageDigest = {
|
||||
{ "apple", "1f3870be274f6c49b3e31a0c6728957f" },
|
||||
{ "bear", "893b56e3cfe153fb770a120b83bac20c" },
|
||||
{ "candy", "c48ba993d35c3abe0380f91738fe2a34" },
|
||||
{ "dogma", "95eb470e4faee302e9cd3063b1923dab" },
|
||||
{ "emma", "00a809937eddc44521da9521269e75c6" } };
|
||||
{"apple", "1f3870be274f6c49b3e31a0c6728957f"},
|
||||
{"bear", "893b56e3cfe153fb770a120b83bac20c"},
|
||||
{"candy", "c48ba993d35c3abe0380f91738fe2a34"},
|
||||
{"dogma", "95eb470e4faee302e9cd3063b1923dab"},
|
||||
{"emma", "00a809937eddc44521da9521269e75c6"}};
|
||||
|
||||
public final static Object[][] base64KeyMessageDigest = {
|
||||
{ Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There",
|
||||
"thcxhlUFcmTii8C2+zeMjvFGvgA=" },
|
||||
{ Base64.decode("SmVmZQ=="), "what do ya want for nothing?",
|
||||
"7/zfauXrL6LSdBbV8YTfnCWafHk=" },
|
||||
{ Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="),
|
||||
"Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ=" },
|
||||
{Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There",
|
||||
"thcxhlUFcmTii8C2+zeMjvFGvgA="},
|
||||
{Base64.decode("SmVmZQ=="), "what do ya want for nothing?",
|
||||
"7/zfauXrL6LSdBbV8YTfnCWafHk="},
|
||||
{Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="),
|
||||
"Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ="},
|
||||
{
|
||||
Base64
|
||||
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" },
|
||||
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI="},
|
||||
{
|
||||
Base64
|
||||
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
|
||||
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
|
||||
"6OmdD0UjfXhta7qnllx4CLv/GpE=" } };
|
||||
"6OmdD0UjfXhta7qnllx4CLv/GpE="}};
|
||||
|
||||
@DataProvider(name = "hmacsha1")
|
||||
public Object[][] createData1() {
|
||||
|
@ -121,7 +121,7 @@ public class S3UtilsTest extends PerformanceTest {
|
|||
String base64Digest) throws NoSuchProviderException,
|
||||
NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
|
||||
String b64 = S3Utils.md5Hex(message.getBytes());
|
||||
assertEquals(base64Digest,b64);
|
||||
assertEquals(base64Digest, b64);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,12 +28,12 @@ import org.testng.annotations.Test;
|
|||
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
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.SecureS3ConnectionTest")
|
||||
public class SecureS3ConnectionTest extends S3ConnectionTest {
|
||||
@Test(groups = {"live"}, testName = "s3.SecureS3ConnectionIntegrationTest")
|
||||
public class SecureS3ConnectionIntegrationTest extends S3ConnectionIntegrationTest {
|
||||
@Override
|
||||
protected Properties buildS3Properties(String AWSAccessKeyId,
|
||||
String AWSSecretAccessKey) {
|
|
@ -23,25 +23,32 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
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.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 com.google.common.base.Function;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import org.jclouds.aws.s3.commands.CopyObject;
|
||||
import org.jclouds.aws.s3.commands.options.*;
|
||||
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.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!
|
||||
|
@ -49,23 +56,43 @@ import org.jclouds.aws.s3.domain.S3Bucket.Metadata;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
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) {
|
||||
return new FutureBase<S3Object>() {
|
||||
public S3Object get() throws InterruptedException,
|
||||
ExecutionException {
|
||||
if (!bucketToContents.containsKey(s3Bucket))
|
||||
return S3Object.NOT_FOUND;
|
||||
Map<String, Object> realContents = bucketToContents
|
||||
.get(s3Bucket);
|
||||
if (!realContents.containsKey(key))
|
||||
return S3Object.NOT_FOUND;
|
||||
S3Object object = new S3Object(key);
|
||||
object.setData(realContents.get(key));
|
||||
return object;
|
||||
return getObject(s3Bucket, key, new GetObjectOptions());
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public S3Object.Metadata copy(S3Object.Metadata in) {
|
||||
return (S3Object.Metadata) xstream.fromXML(xstream.toXML(in));
|
||||
}
|
||||
|
||||
public S3Object.Metadata copy(S3Object.Metadata in, String newKey) {
|
||||
return (S3Object.Metadata) xstream.fromXML(xstream.toXML(in).replaceAll(in.getKey(), newKey));
|
||||
}
|
||||
|
||||
public Future<S3Object.Metadata> headObject(final String s3Bucket,
|
||||
|
@ -75,12 +102,11 @@ public class StubS3Connection implements S3Connection {
|
|||
ExecutionException {
|
||||
if (!bucketToContents.containsKey(s3Bucket))
|
||||
return S3Object.Metadata.NOT_FOUND;
|
||||
Map<String, Object> realContents = bucketToContents
|
||||
Map<String, S3Object> realContents = bucketToContents
|
||||
.get(s3Bucket);
|
||||
if (!realContents.containsKey(key))
|
||||
return S3Object.Metadata.NOT_FOUND;
|
||||
S3Object.Metadata metadata = new S3Object.Metadata(key);
|
||||
return metadata;
|
||||
return realContents.get(key).getMetadata();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -98,17 +124,7 @@ public class StubS3Connection implements S3Connection {
|
|||
}
|
||||
|
||||
public Future<byte[]> putObject(final String s3Bucket, final S3Object object) {
|
||||
return new FutureBase<byte[]>() {
|
||||
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
|
||||
}
|
||||
};
|
||||
return putObject(s3Bucket, object, new PutObjectOptions());
|
||||
}
|
||||
|
||||
public Future<Boolean> putBucketIfNotExists(final String s3Bucket) {
|
||||
|
@ -117,7 +133,7 @@ public class StubS3Connection implements S3Connection {
|
|||
ExecutionException {
|
||||
if (!bucketToContents.containsKey(s3Bucket)) {
|
||||
bucketToContents.put(s3Bucket,
|
||||
new ConcurrentHashMap<String, Object>());
|
||||
new ConcurrentHashMap<String, S3Object>());
|
||||
}
|
||||
return bucketToContents.containsKey(s3Bucket);
|
||||
}
|
||||
|
@ -130,29 +146,21 @@ public class StubS3Connection implements S3Connection {
|
|||
ExecutionException {
|
||||
if (bucketToContents.containsKey(s3Bucket)) {
|
||||
if (bucketToContents.get(s3Bucket).size() == 0)
|
||||
return true;
|
||||
}
|
||||
bucketToContents.remove(s3Bucket);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
XStream xstream = new XStream();
|
||||
|
||||
public Future<S3Object.Metadata> copyObject(final String sourceBucket,
|
||||
final String sourceObject, final String destinationBucket,
|
||||
final String destinationObject) {
|
||||
return new FutureBase<S3Object.Metadata>() {
|
||||
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;
|
||||
}
|
||||
};
|
||||
return copyObject(sourceBucket, sourceObject, destinationBucket, destinationObject, new CopyObjectOptions());
|
||||
}
|
||||
|
||||
public Future<Boolean> bucketExists(final String s3Bucket) {
|
||||
|
@ -165,25 +173,7 @@ public class StubS3Connection implements S3Connection {
|
|||
}
|
||||
|
||||
public Future<S3Bucket> listBucket(final String s3Bucket) {
|
||||
return new FutureBase<S3Bucket>() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
return listBucket(s3Bucket, new ListBucketOptions());
|
||||
}
|
||||
|
||||
private abstract class FutureBase<V> implements Future<V> {
|
||||
|
@ -209,40 +199,283 @@ public class StubS3Connection implements S3Connection {
|
|||
return new FutureBase<List<S3Bucket.Metadata>>() {
|
||||
public List<S3Bucket.Metadata> get() throws InterruptedException,
|
||||
ExecutionException {
|
||||
List<S3Bucket.Metadata> list = new ArrayList<S3Bucket.Metadata>();
|
||||
for (String name : bucketToContents.keySet())
|
||||
list.add(new S3Bucket.Metadata(name));
|
||||
return list;
|
||||
return Lists.newArrayList(Iterables.transform(
|
||||
bucketToContents.keySet(),
|
||||
new Function<String, Metadata>() {
|
||||
public Metadata apply(String name) {
|
||||
return new S3Bucket.Metadata(name);
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Future<Boolean> putBucketIfNotExists(String name,
|
||||
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) {
|
||||
throw new UnsupportedOperationException("todo");
|
||||
class DelimiterFilter implements Predicate<S3Object.Metadata> {
|
||||
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(
|
||||
String sourceBucket, String sourceObject, String destinationBucket,
|
||||
String destinationObject, CopyObjectOptions options) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
final String sourceBucket, final String sourceObject, final String destinationBucket,
|
||||
final String destinationObject, final CopyObjectOptions options) {
|
||||
|
||||
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,
|
||||
PutObjectOptions options) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
private void throwResponseException(int code) throws ExecutionException {
|
||||
HttpResponse response = new HttpResponse();
|
||||
response.setStatusCode(code);
|
||||
throw new ExecutionException(
|
||||
new HttpResponseException(createNiceMock(CopyObject.class), response));
|
||||
}
|
||||
|
||||
public Future<S3Object> getObject(String bucketName, String key,
|
||||
GetObjectOptions options) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
public Future<byte[]> putObject(final String bucketName, final S3Object object,
|
||||
final PutObjectOptions options) {
|
||||
if (!bucketToContents.containsKey(bucketName)) {
|
||||
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;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all bucketExists commands.
|
||||
|
@ -35,20 +36,19 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.BucketExistsIntegrationTest")
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.BucketExistsIntegrationTest")
|
||||
public class BucketExistsIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
@Test
|
||||
void bucketDoesntExist() throws Exception {
|
||||
String bucketName = bucketPrefix + "shouldntexist";
|
||||
String bucketName= bucketPrefix+"be";
|
||||
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test()
|
||||
@Test
|
||||
void bucketExists() throws Exception {
|
||||
String bucketName = bucketPrefix + "needstoexist";
|
||||
String bucketName= bucketPrefix+"bde";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
|
|
|
@ -23,32 +23,24 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.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 com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
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.acl.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.joda.time.DateTime;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all copyObject commands.
|
||||
|
@ -57,79 +49,53 @@ import com.google.common.collect.Multimap;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.CopyObjectIntegrationTest")
|
||||
@Test(testName = "s3.CopyObjectIntegrationTest")
|
||||
public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||
String sourceKey = "apples";
|
||||
String destinationKey = "pears";
|
||||
|
||||
|
||||
@Test()
|
||||
void testCannedAccessPolicyPublic() throws Exception {
|
||||
String sourceBucket = bucketPrefix + "tcapp";
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
destinationKey,overrideAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
|
||||
destinationBucket, destinationKey));
|
||||
S3Utils.toStringAndClose(url.openStream());
|
||||
|
||||
}
|
||||
@Test()
|
||||
@Test(groups = {"integration","live"})
|
||||
void testCopyObject() throws Exception {
|
||||
String sourceBucket = bucketPrefix + "testcopyobject";
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
||||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey).get(10, TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
}
|
||||
|
||||
private void setupSourceBucket(String sourceBucket, String sourceKey)
|
||||
|
||||
private void addToBucketAndValidate(String bucketName, String sourceKey)
|
||||
throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
createBucketAndEnsureEmpty(sourceBucket);
|
||||
addToBucketAndValidate(sourceBucket, sourceKey);
|
||||
addObjectToBucket(bucketName, sourceKey);
|
||||
validateContent(bucketName, sourceKey);
|
||||
}
|
||||
|
||||
private void addToBucketAndValidate(String sourceBucket, String sourceKey)
|
||||
throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
addObjectToBucket(sourceBucket, sourceKey);
|
||||
validateContent(sourceBucket, sourceKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"integration","live"})
|
||||
void testCopyIfModifiedSince() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
String sourceBucket = bucketPrefix + "tcims";
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
||||
DateTime before = new DateTime();
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceModifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -138,24 +104,24 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"integration","live"})
|
||||
void testCopyIfUnmodifiedSince() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
String sourceBucket = bucketPrefix + "tcius";
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
||||
DateTime before = new DateTime();
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -164,23 +130,23 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"integration","live"})
|
||||
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
String sourceBucket = bucketPrefix + "tcim";
|
||||
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
||||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -189,23 +155,23 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"integration","live"})
|
||||
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
String sourceBucket = bucketPrefix + "tcinm";
|
||||
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
||||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(destinationBucket, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -214,19 +180,19 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"integration","live"})
|
||||
void testCopyWithMetadata() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
String sourceBucket = bucketPrefix + "tcwm";
|
||||
String destinationBucket = sourceBucket + "dest";
|
||||
|
||||
setupSourceBucket(sourceBucket, sourceKey);
|
||||
String destinationBucket = bucketName + "dest";
|
||||
|
||||
addToBucketAndValidate(bucketName, sourceKey);
|
||||
|
||||
Multimap<String, String> metadata = HashMultimap.create();
|
||||
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
||||
|
||||
createBucketAndEnsureEmpty(destinationBucket);
|
||||
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||
client.copyObject(bucketName, sourceKey, destinationBucket,
|
||||
destinationKey, overrideMetadataWith(metadata)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all deleteBucket commands.
|
||||
* <p/>
|
||||
|
@ -35,12 +35,14 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.DeleteBucketIntegrationTest")
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.DeleteBucketIntegrationTest")
|
||||
public class DeleteBucketIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
@Test
|
||||
/**
|
||||
* this method overrides bucketName to ensure it isn't found
|
||||
*/
|
||||
void deleteBucketIfEmptyNotFound() throws Exception {
|
||||
String bucketName = bucketPrefix + "dbienf";
|
||||
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||
|
@ -48,16 +50,12 @@ public class DeleteBucketIntegrationTest extends S3IntegrationTest {
|
|||
|
||||
@Test()
|
||||
void deleteBucketIfEmptyButHasContents() throws Exception {
|
||||
String bucketName = bucketPrefix + "dbiebhc";
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
addObjectToBucket(bucketName,"test");
|
||||
addObjectToBucket(bucketName, "test");
|
||||
assert !client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test()
|
||||
void deleteBucketIfEmpty() throws Exception {
|
||||
String bucketName = bucketPrefix + "dbie";
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
|
||||
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import org.jclouds.aws.s3.S3ResponseException;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all deleteObject commands.
|
||||
|
@ -39,9 +39,8 @@ import static org.testng.Assert.assertEquals;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.DeleteObjectIntegrationTest")
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.DeleteObjectIntegrationTest")
|
||||
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* "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
|
||||
* 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
|
||||
|
@ -23,19 +23,21 @@
|
|||
*/
|
||||
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 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 org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
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.domain.S3Object;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all GetObject commands.
|
||||
* <p/>
|
||||
|
@ -43,151 +45,147 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.GetObjectIntegrationTest")
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.GetObjectIntegrationTest")
|
||||
public class GetObjectIntegrationTest extends S3IntegrationTest {
|
||||
//
|
||||
// @Test
|
||||
// void testGetIfModifiedSince() throws InterruptedException,
|
||||
// ExecutionException, TimeoutException, IOException {
|
||||
// String bucket = bucketPrefix + "testGetIfModifiedSince".toLowerCase();
|
||||
// String key = "apples";
|
||||
//
|
||||
// DateTime before = new DateTime();
|
||||
// setUpBucket(bucket, key);
|
||||
// DateTime after = new DateTime().plusSeconds(1);
|
||||
//
|
||||
// client.getObject(bucket, key, ifModifiedSince(before)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
//
|
||||
// try {
|
||||
// client.getObject(bucket, key, ifModifiedSince(after)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
// } catch (ExecutionException e) {
|
||||
// if (e.getCause() instanceof HttpResponseException) {
|
||||
// HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
// assertEquals(ex.getResponse().getStatusCode(), 304);
|
||||
// } else {
|
||||
// throw e;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
// @Test
|
||||
// void testGetIfUnmodifiedSince() throws InterruptedException,
|
||||
// ExecutionException, TimeoutException, IOException {
|
||||
// String bucket = bucketPrefix + "testGetIfUnmodifiedSince".toLowerCase();
|
||||
// String key = "apples";
|
||||
//
|
||||
// DateTime before = new DateTime();
|
||||
// setUpBucket(bucket, key);
|
||||
// DateTime after = new DateTime().plusSeconds(1);
|
||||
//
|
||||
// client.getObject(bucket, key, ifUnmodifiedSince(after)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
//
|
||||
// try {
|
||||
// client.getObject(bucket, key, ifUnmodifiedSince(before)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
// } catch (ExecutionException e) {
|
||||
// if (e.getCause() instanceof S3ResponseException) {
|
||||
// S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||
// assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
// } else {
|
||||
// throw e;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// void testGetIfMatch() throws InterruptedException, ExecutionException,
|
||||
// TimeoutException, IOException {
|
||||
// String bucket = bucketPrefix + "testGetIfMatch".toLowerCase();
|
||||
// String key = "apples";
|
||||
//
|
||||
// setUpBucket(bucket, key);
|
||||
//
|
||||
// client.getObject(bucket, key, ifMd5Matches(goodMd5)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
//
|
||||
// try {
|
||||
// client.getObject(bucket, key, ifMd5Matches(badMd5)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
// } catch (ExecutionException e) {
|
||||
// if (e.getCause() instanceof S3ResponseException) {
|
||||
// S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||
// assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
// } else {
|
||||
// throw e;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// void testGetIfNoneMatch() throws InterruptedException,
|
||||
// ExecutionException,
|
||||
// TimeoutException, IOException {
|
||||
// String bucket = bucketPrefix + "testGetIfNoneMatch".toLowerCase();
|
||||
// String key = "apples";
|
||||
//
|
||||
// setUpBucket(bucket, key);
|
||||
//
|
||||
// client.getObject(bucket, key, ifMd5DoesntMatch(badMd5)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
//
|
||||
// try {
|
||||
// client.getObject(bucket, key, ifMd5DoesntMatch(goodMd5)).get(10,
|
||||
// TimeUnit.SECONDS);
|
||||
// validateContent(bucket, key);
|
||||
// } catch (ExecutionException e) {
|
||||
// if (e.getCause() instanceof HttpResponseException) {
|
||||
// HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
// assertEquals(ex.getResponse().getStatusCode(), 304);
|
||||
// } else {
|
||||
// throw e;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@Test
|
||||
void testGetIfModifiedSince() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
DateTime before = new DateTime();
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.getObject(bucketName, key, ifModifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifModifiedSince(after)).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
|
||||
void testGetIfUnmodifiedSince() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
DateTime before = new DateTime();
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIfMatch() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
|
||||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
|
||||
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
|
||||
try {
|
||||
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(bucketName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
} 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
|
||||
void testGetRange() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
String bucket = bucketPrefix + "testGetRange".toLowerCase();
|
||||
|
||||
String key = "apples";
|
||||
|
||||
setUpBucket(bucket, key);
|
||||
S3Object object1 = client.getObject(bucket, key, range(0, 5)).get(10,
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
|
||||
.substring(0, 6));
|
||||
|
||||
S3Object object2 = client.getObject(bucket, key,
|
||||
range(5, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||
S3Object object2 = client.getObject(bucketName, key,
|
||||
range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
|
||||
.substring(5, TEST_STRING.length()));
|
||||
.substring(6, TEST_STRING.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
String bucket = bucketPrefix + "testGetTwoRanges".toLowerCase();
|
||||
|
||||
String key = "apples";
|
||||
|
||||
setUpBucket(bucket, key);
|
||||
S3Object object = client.getObject(bucket, key,
|
||||
range(0, 5).range(5, TEST_STRING.length())).get(10,
|
||||
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);
|
||||
|
@ -196,11 +194,11 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
@Test
|
||||
void testGetTail() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
String bucket = bucketPrefix + "testGetTail".toLowerCase();
|
||||
|
||||
String key = "apples";
|
||||
|
||||
setUpBucket(bucket, key);
|
||||
S3Object object = client.getObject(bucket, key, tail(5)).get(10,
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object = client.getObject(bucketName, key, tail(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||
.substring(TEST_STRING.length() - 5));
|
||||
|
@ -212,11 +210,11 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
@Test
|
||||
void testGetStartAt() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
String bucket = bucketPrefix + "testGetStartAt".toLowerCase();
|
||||
|
||||
String key = "apples";
|
||||
|
||||
setUpBucket(bucket, key);
|
||||
S3Object object = client.getObject(bucket, key, startAt(5)).get(10,
|
||||
addObjectAndValidateContent(bucketName, key);
|
||||
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
|
||||
.substring(5, TEST_STRING.length()));
|
||||
|
@ -224,11 +222,10 @@ public class GetObjectIntegrationTest extends S3IntegrationTest {
|
|||
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,
|
||||
IOException {
|
||||
createBucketAndEnsureEmpty(sourceBucket);
|
||||
addObjectToBucket(sourceBucket, sourceKey);
|
||||
validateContent(sourceBucket, sourceKey);
|
||||
addObjectToBucket(sourcebucketName, sourceKey);
|
||||
validateContent(sourcebucketName, sourceKey);
|
||||
}
|
||||
}
|
|
@ -23,23 +23,18 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.delimiter;
|
||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.afterMarker;
|
||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.withPrefix;
|
||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.maxResults;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.*;
|
||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
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.domain.S3Bucket;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all getBucket commands.
|
||||
* <p/>
|
||||
|
@ -47,23 +42,20 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.ListBucketIntegrationTest")
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.ListBucketIntegrationTest")
|
||||
public class ListBucketIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
void testListBucketDelimiter() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||
String bucketName = bucketPrefix + "delimiter";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(bucketName, prefix);
|
||||
add15UnderRoot(bucketName);
|
||||
S3Bucket bucket = client.listBucket(bucketName, delimiter("/")).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(bucket.getDelimiter(), "/");
|
||||
assert !bucket.isTruncated();
|
||||
assertEquals(bucket.getContents().size(), 15);
|
||||
assertEquals(bucket.getCommonPrefixes().size(), 1);
|
||||
}
|
||||
|
@ -80,46 +72,50 @@ public class ListBucketIntegrationTest extends S3IntegrationTest {
|
|||
@Test
|
||||
void testListBucketMarker() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||
String bucketName = bucketPrefix + "marker";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
addAlphabetUnderRoot(bucketName);
|
||||
S3Bucket bucket = client.listBucket(bucketName, afterMarker("y")).get(
|
||||
10, TimeUnit.SECONDS);
|
||||
assertEquals(bucket.getMarker(), "y");
|
||||
assert !bucket.isTruncated();
|
||||
assertEquals(bucket.getContents().size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testListBucketMaxResults() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||
String bucketName = bucketPrefix + "max";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
addAlphabetUnderRoot(bucketName);
|
||||
S3Bucket bucket = client.listBucket(bucketName, maxResults(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(bucket.getMaxKeys(), 5);
|
||||
assert bucket.isTruncated();
|
||||
assertEquals(bucket.getContents().size(), 5);
|
||||
}
|
||||
|
||||
@Test()
|
||||
void testListBucketPrefix() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, UnsupportedEncodingException {
|
||||
String bucketName = bucketPrefix + "prefix";
|
||||
assert client.putBucketIfNotExists(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(bucketName, prefix);
|
||||
add15UnderRoot(bucketName);
|
||||
|
||||
S3Bucket bucket = client.listBucket(bucketName, withPrefix("apps/"))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assert !bucket.isTruncated();
|
||||
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,
|
||||
ExecutionException, TimeoutException {
|
||||
for (int i = 0; i < 15; i++)
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Tests integrated functionality of all listOwnedBucket commands.
|
||||
* <p/>
|
||||
|
@ -37,9 +37,8 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.ListOwnedBucketsIntegrationTest")
|
||||
@Test(groups = {"integration", "live"}, testName = "s3.ListOwnedBucketsIntegrationTest")
|
||||
public class ListOwnedBucketsIntegrationTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
|
|
|
@ -23,19 +23,18 @@
|
|||
*/
|
||||
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.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.acl.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
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.
|
||||
* <p/>
|
||||
|
@ -43,12 +42,14 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.PutBucketIntegrationTest")
|
||||
public class PutBucketIntegrationTest extends S3IntegrationTest {
|
||||
@Test(testName = "s3.PutBucketLiveTest")
|
||||
public class PutBucketLiveTest extends S3IntegrationTest {
|
||||
|
||||
@Test()
|
||||
/**
|
||||
* overriding bucketName as we are changing access permissions
|
||||
*/
|
||||
@Test(groups = {"live"})
|
||||
void testPublicReadAccessPolicy() throws Exception {
|
||||
String bucketName = bucketPrefix + "public";
|
||||
|
||||
|
@ -60,17 +61,17 @@ public class PutBucketIntegrationTest extends S3IntegrationTest {
|
|||
S3Utils.toStringAndClose(url.openStream());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IOException.class)
|
||||
@Test(expectedExceptions = IOException.class, groups = {"live"})
|
||||
void testDefaultAccessPolicy() throws Exception {
|
||||
String bucketName = bucketPrefix + "private";
|
||||
|
||||
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
|
||||
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 {
|
||||
String bucketName = (bucketPrefix + "wow").toLowerCase();
|
||||
client.putBucketIfNotExists(
|
|
@ -23,9 +23,18 @@
|
|||
*/
|
||||
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.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.assertNotNull;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -34,16 +43,6 @@ import java.io.InputStream;
|
|||
import java.net.URL;
|
||||
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.
|
||||
|
@ -52,23 +51,22 @@ import org.testng.annotations.Test;
|
|||
* in parallel.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test(groups = "integration", testName = "s3.PutObjectIntegrationTest")
|
||||
@Test(testName = "s3.PutObjectIntegrationTest")
|
||||
public class PutObjectIntegrationTest extends S3IntegrationTest {
|
||||
@DataProvider(name = "putTests")
|
||||
public Object[][] createData1() throws IOException {
|
||||
|
||||
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
|
||||
|
||||
return new Object[][] {
|
||||
{ "file", "text/xml", new File("pom.xml"), realObject },
|
||||
{ "string", "text/xml", realObject, realObject },
|
||||
{ "bytes", "application/octet-stream", realObject.getBytes(),
|
||||
realObject } };
|
||||
return new Object[][]{
|
||||
{"file", "text/xml", new File("pom.xml"), realObject},
|
||||
{"string", "text/xml", realObject, realObject},
|
||||
{"bytes", "application/octet-stream", realObject.getBytes(),
|
||||
realObject}};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "putTests")
|
||||
@Test(dataProvider = "putTests", groups = {"integration", "live"})
|
||||
void testPutObject(String key, String type, Object content,
|
||||
Object realObject) throws Exception {
|
||||
String bucketName = bucketPrefix + "tpo";
|
||||
|
@ -92,7 +90,7 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
|||
.getContents().size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"integration", "live"})
|
||||
void testMetadata() throws Exception {
|
||||
String bucketName = bucketPrefix + "tmd";
|
||||
createBucketAndEnsureEmpty(bucketName);
|
||||
|
@ -126,23 +124,4 @@ public class PutObjectIntegrationTest extends S3IntegrationTest {
|
|||
.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());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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,40 +23,31 @@
|
|||
*/
|
||||
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.Multimap;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
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
|
||||
*/
|
||||
@Test
|
||||
@Test(groups = {"unit"}, testName = "s3.S3CommandFactoryTest")
|
||||
public class S3CommandFactoryTest {
|
||||
|
||||
Injector injector = 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
|
||||
void setUpInjector() {
|
||||
injector = Guice.createInjector(new S3CommandsModule() {
|
||||
|
|
|
@ -23,16 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
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 com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.PerformanceTest;
|
||||
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.commands.callables.xml.ParseSax;
|
||||
import org.joda.time.DateTime;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Tests parsing of S3 responses
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", sequential = true, testName = "s3.S3ParserTest")
|
||||
@Test(groups = {"performance"}, testName = "s3.S3ParserTest")
|
||||
public class S3ParserTest extends PerformanceTest {
|
||||
Injector injector = null;
|
||||
|
||||
|
@ -133,7 +131,7 @@ public class S3ParserTest extends PerformanceTest {
|
|||
public void testCanParseListBucketResult() throws HttpException,
|
||||
UnsupportedEncodingException {
|
||||
S3Bucket bucket = runParseListBucketResult();
|
||||
assert bucket.isComplete();
|
||||
assert !bucket.isTruncated();
|
||||
assert bucket.getName().equals("adrianjbosstest");
|
||||
assert bucket.getContents().size() == 1;
|
||||
S3Object.Metadata object = bucket.getContents().iterator().next();
|
||||
|
|
|
@ -23,25 +23,22 @@
|
|||
*/
|
||||
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 static org.easymock.classextension.EasyMock.*;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.domain.S3Object.Metadata;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpHeaders;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
@Test(groups = "unit", testName = "s3.ParseObjectFromHeadersAndHttpContentTest")
|
||||
public class ParseObjectFromHeadersAndHttpContentTest {
|
||||
ParseObjectFromHeadersAndHttpContent callable;
|
||||
ParseMetadataFromHeaders metadataParser;
|
||||
|
|
|
@ -23,34 +23,26 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands.options;
|
||||
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.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 com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*;
|
||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
import org.jclouds.aws.s3.util.DateService;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
import org.joda.time.DateTime;
|
||||
import static org.testng.Assert.*;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Tests possible uses of CopyObjectOptions and CopyObjectOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.CopyObjectOptionsTest")
|
||||
public class CopyObjectOptionsTest {
|
||||
|
||||
private byte[] testBytes;
|
||||
|
@ -68,7 +60,7 @@ public class CopyObjectOptionsTest {
|
|||
|
||||
now = new DateTime();
|
||||
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
|
||||
|
@ -95,7 +87,7 @@ public class CopyObjectOptionsTest {
|
|||
private void assertGoodMeta(CopyObjectOptions options) {
|
||||
assert options != null;
|
||||
assert options.getMetadata() != null;
|
||||
Multimap<String,String> headers = options.buildRequestHeaders();
|
||||
Multimap<String, String> headers = options.buildRequestHeaders();
|
||||
assertEquals(headers.size(), 2);
|
||||
assertEquals(headers.get(
|
||||
"x-amz-metadata-directive").iterator().next(),
|
||||
|
|
|
@ -23,29 +23,23 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.commands.options;
|
||||
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.startAt;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.tail;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5DoesntMatch;
|
||||
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.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 static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
|
||||
import org.jclouds.aws.s3.util.DateService;
|
||||
import org.jclouds.aws.s3.util.S3Utils;
|
||||
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.Test;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Tests possible uses of GetObjectOptions and GetObjectOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.GetObjectOptionsTest")
|
||||
public class GetObjectOptionsTest {
|
||||
|
||||
private byte[] testBytes;
|
||||
|
@ -56,7 +50,7 @@ public class GetObjectOptionsTest {
|
|||
void setUp() {
|
||||
now = new DateTime();
|
||||
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
|
||||
|
@ -115,7 +109,7 @@ public class GetObjectOptionsTest {
|
|||
GetObjectOptions options = new GetObjectOptions();
|
||||
options.ifModifiedSince(now);
|
||||
options.range(0, 1024);
|
||||
isNowExpected(options);
|
||||
assertEquals(options.getIfModifiedSince(), nowExpected);
|
||||
bytes1to1024(options);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ public class ListBucketOptionsTest {
|
|||
public void testPrefixAndDelimiterUrlEncodingQueryString()
|
||||
throws UnsupportedEncodingException {
|
||||
ListBucketOptions options = new ListBucketOptions();
|
||||
options.withPrefix("/test").setDelimiter("/");
|
||||
options.withPrefix("/test").delimiter("/");
|
||||
String query = options.buildQueryString();
|
||||
checkEncodedQuery(query);
|
||||
checkEncodedQuery(checkNotNull(query));
|
||||
|
@ -165,7 +165,7 @@ public class ListBucketOptionsTest {
|
|||
@Test
|
||||
public void testDelimiter() throws UnsupportedEncodingException {
|
||||
ListBucketOptions options = new ListBucketOptions();
|
||||
options.setDelimiter("test");
|
||||
options.delimiter("test");
|
||||
assertEquals(options.getDelimiter(), "test");
|
||||
}
|
||||
|
||||
|
|
|
@ -23,26 +23,24 @@
|
|||
*/
|
||||
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.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.acl.CannedAccessPolicy;
|
||||
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 com.google.common.collect.Multimap;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Tests possible uses of PutBucketOptions and PutBucketOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.PutBucketOptionsTest")
|
||||
public class PutBucketOptionsTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -23,23 +23,21 @@
|
|||
*/
|
||||
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.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Tests possible uses of PutObjectOptions and PutObjectOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.PutObjectOptionsTest")
|
||||
public class PutObjectOptionsTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
*/
|
||||
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.reference.S3Constants;
|
||||
import org.jclouds.http.HttpResponseHandler;
|
||||
|
@ -33,28 +35,22 @@ import org.jclouds.http.annotation.RedirectHandler;
|
|||
import org.jclouds.http.annotation.ServerErrorHandler;
|
||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
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
|
||||
*/
|
||||
@Test
|
||||
@Test(groups = "unit", testName = "s3.S3ContextModuleTest")
|
||||
public class S3ContextModuleTest {
|
||||
|
||||
Injector injector = null;
|
||||
|
||||
@BeforeMethod
|
||||
void setUpInjector() {
|
||||
injector = Guice.createInjector(new S3ContextModule() {
|
||||
injector = Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
|
|
|
@ -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,15 +23,13 @@
|
|||
*/
|
||||
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 static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test
|
||||
import java.io.File;
|
||||
|
||||
@Test(groups = "unit", testName = "s3.S3ObjectTest")
|
||||
public class S3ObjectTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -26,14 +26,12 @@ package org.jclouds.aws.s3.filters;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.aws.s3.util.DateService;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
|
||||
@Test(groups = "unit", sequential = true, testName = "s3.RequestAuthorizeSignatureTest")
|
||||
@Test(groups = "unit", testName = "s3.RequestAuthorizeSignatureTest")
|
||||
public class RequestAuthorizeSignatureTest {
|
||||
|
||||
RequestAuthorizeSignature filter = null;
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
*/
|
||||
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.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
public class BaseHandlerTest {
|
||||
|
||||
protected S3ParserFactory parserFactory = null;
|
||||
|
|
|
@ -23,15 +23,14 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.s3.domain.S3Error;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test
|
||||
@Test(groups = "unit", testName = "s3.ErrorHandlerTest")
|
||||
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>";
|
||||
|
||||
|
@ -53,7 +52,7 @@ public class ErrorHandlerTest extends BaseHandlerTest {
|
|||
|
||||
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 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"
|
||||
+ "<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"
|
||||
|
|
|
@ -23,16 +23,15 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test
|
||||
@Test(groups = "unit", testName = "s3.ListBucketHandlerTest")
|
||||
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 listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
|
||||
|
|
|
@ -23,19 +23,17 @@
|
|||
*/
|
||||
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.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test
|
||||
@Test(groups = "unit", testName = "s3.S3ParserFactoryTest")
|
||||
public class S3ParserFactoryTest {
|
||||
|
||||
Injector injector = null;
|
||||
|
|
Loading…
Reference in New Issue