changed domain object keys to be immutable and hardened with null checks

git-svn-id: http://jclouds.googlecode.com/svn/trunk@140 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-05-01 19:43:02 +00:00
parent 9e3341bfc7
commit 89d86de812
51 changed files with 858 additions and 417 deletions

View File

@ -24,6 +24,7 @@
package org.jclouds.command;
import java.util.concurrent.*;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* // TODO: Adrian: Document this!
@ -32,8 +33,8 @@ import java.util.concurrent.*;
*/
public class FutureCommand<Q, R, T> implements Future<T> {
private Q request;
private ResponseRunnableFuture<R, T> responseRunnableFuture;
private final Q request;
private final ResponseRunnableFuture<R, T> responseRunnableFuture;
private volatile int failureCount;
public int incrementFailureCount() {
@ -45,8 +46,9 @@ public class FutureCommand<Q, R, T> implements Future<T> {
}
public FutureCommand(Q request, ResponseCallable<R, T> responseCallable) {
this.request = request;
this.responseRunnableFuture = new ResponseRunnableFutureTask<R, T>(responseCallable);
this.request = checkNotNull(request, "request");
this.responseRunnableFuture = new ResponseRunnableFutureTask<R, T>(
checkNotNull(responseCallable, "responseCallable"));
}
public Q getRequest() {
@ -77,7 +79,8 @@ public class FutureCommand<Q, R, T> implements Future<T> {
return responseRunnableFuture.get();
}
public T get(long l, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
public T get(long l, TimeUnit timeUnit) throws InterruptedException,
ExecutionException, TimeoutException {
return responseRunnableFuture.get(l, timeUnit);
}
@ -86,7 +89,8 @@ public class FutureCommand<Q, R, T> implements Future<T> {
*
* @author Adrian Cole
*/
public static class ResponseRunnableFutureTask<R, T> extends FutureTask<T> implements ResponseRunnableFuture<R, T> {
public static class ResponseRunnableFutureTask<R, T> extends FutureTask<T>
implements ResponseRunnableFuture<R, T> {
private final ResponseCallable<R, T> tCallable;
public ResponseRunnableFutureTask(ResponseCallable<R, T> tCallable) {
@ -96,9 +100,8 @@ public class FutureCommand<Q, R, T> implements Future<T> {
@Override
public String toString() {
return "ApacheHttpResponseFuture{" +
"tCallable=" + tCallable +
'}';
return "ResponseRunnableFutureTask{" + "tCallable=" + tCallable
+ '}';
}
public R getResponse() {
@ -110,7 +113,8 @@ public class FutureCommand<Q, R, T> implements Future<T> {
}
/**
* opening this to public so that other errors can be associated with the request, for example i/o errors.
* opening this to public so that other errors can be associated with
* the request, for example i/o errors.
*
* @param throwable
*/
@ -121,7 +125,8 @@ public class FutureCommand<Q, R, T> implements Future<T> {
}
public interface ResponseRunnableFuture<R, T> extends Response<R>, Runnable, Future<T> {
public interface ResponseRunnableFuture<R, T> extends Response<R>,
Runnable, Future<T> {
public void setException(Throwable throwable);
}

View File

@ -23,6 +23,8 @@
*/
package org.jclouds.http;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.command.FutureCommand;
import org.jclouds.Logger;
@ -31,9 +33,22 @@ import org.jclouds.Logger;
*
* @author Adrian Cole
*/
public class HttpFutureCommand<T> extends FutureCommand<HttpRequest, HttpResponse, T> {
public HttpFutureCommand(String method, String uri, ResponseCallable<T> responseCallable) {
super(new HttpRequest(method, uri), responseCallable);
public class HttpFutureCommand<T> extends
FutureCommand<HttpRequest, HttpResponse, T> {
public HttpFutureCommand(String method, String uri,
ResponseCallable<T> responseCallable) {
super(new HttpRequest(checkNotNull(method, "method"), checkNotNull(uri,
"uri")), responseCallable);
}
protected void addHostHeader(String host) {
getRequest().getHeaders().put("Host", host);
}
@Override
public String toString() {
return this.getClass().getName() + "{" + "request=" + this.getRequest()
+ "," + "responseFuture=" + this.getResponseFuture() + '}';
}
/**
@ -41,7 +56,8 @@ public class HttpFutureCommand<T> extends FutureCommand<HttpRequest, HttpRespons
*
* @author Adrian Cole
*/
public abstract static class ResponseCallable<T> implements FutureCommand.ResponseCallable<HttpResponse, T> {
public abstract static class ResponseCallable<T> implements
FutureCommand.ResponseCallable<HttpResponse, T> {
protected final Logger logger;
private HttpResponse response;

View File

@ -25,6 +25,8 @@ package org.jclouds.http.commands.callables.xml;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
import org.apache.commons.io.IOUtils;
import org.jclouds.Logger;
import org.jclouds.Utils;
@ -34,25 +36,30 @@ import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.InputStream;
/**
* // TODO: Adrian: Document this!
* This object will parse the body of an HttpResponse and return the result of
* type <T> back to the caller.
*
* @author Adrian Cole
*/
public class ParseSax<T> extends HttpFutureCommand.ResponseCallable<T> {
private XMLReader parser;
private HandlerWithResult<T> handler;
private final XMLReader parser;
private final HandlerWithResult<T> handler;
@Inject(optional = true)
@Named("jclouds.http.sax.debug")
private boolean suckFirst = false;
@Inject
public ParseSax(java.util.logging.Logger logger, XMLReader parser, @Assisted HandlerWithResult<T> handler) {
super(new Logger(logger));
this.parser = parser;
this.handler = handler;
public ParseSax(java.util.logging.Logger logger, XMLReader parser,
@Assisted HandlerWithResult<T> handler) {
super(new Logger(checkNotNull(logger, "logger")));
this.parser = checkNotNull(parser, "parser");
this.handler = checkNotNull(handler, "handler");
}
public T call() throws HttpException {
@ -66,16 +73,18 @@ public class ParseSax<T> extends HttpFutureCommand.ResponseCallable<T> {
}
} catch (Exception e) {
Utils.<HttpException> rethrowIfRuntimeOrSameType(e);
throw new HttpException("Error parsing input for " + getResponse(), e);
throw new HttpException("Error parsing input for " + getResponse(),
e);
}
}
public T parse(InputStream xml) throws HttpException {
parseAndCloseStream(xml, handler);
return handler.getResult();
parseAndCloseStream(xml, getHandler());
return getHandler().getResult();
}
private void parseAndCloseStream(InputStream xml, ContentHandler handler) throws HttpException {
private void parseAndCloseStream(InputStream xml, ContentHandler handler)
throws HttpException {
parser.setContentHandler(handler);
String response = null;
try {
@ -100,6 +109,10 @@ public class ParseSax<T> extends HttpFutureCommand.ResponseCallable<T> {
}
}
public HandlerWithResult<T> getHandler() {
return handler;
}
/**
* // TODO: Adrian: Document this!
*

View File

@ -139,7 +139,7 @@ public abstract class BaseHttpFutureCommandClientTest {
server.stop();
}
@Test(invocationCount = 500, timeOut = 1000)
@Test(invocationCount = 500, timeOut = 1500)
void testRequestFilter() throws MalformedURLException, ExecutionException,
InterruptedException {
GetString get = factory.createGetString("/");
@ -149,7 +149,7 @@ public abstract class BaseHttpFutureCommandClientTest {
"expected: [%1s], but got [%2s]", "test", get.get());
}
@Test(invocationCount = 500, timeOut = 1000)
@Test(invocationCount = 500, timeOut = 1500)
void testGetStringWithHeader() throws MalformedURLException,
ExecutionException, InterruptedException {
GetString get = factory.createGetString("/");
@ -159,7 +159,7 @@ public abstract class BaseHttpFutureCommandClientTest {
"expected: [%1s], but got [%2s]", "test", get.get());
}
@Test(invocationCount = 500, timeOut = 1000)
@Test(invocationCount = 500, timeOut = 1500)
void testGetString() throws MalformedURLException, ExecutionException,
InterruptedException {
GetString get = factory.createGetString("/");
@ -169,7 +169,7 @@ public abstract class BaseHttpFutureCommandClientTest {
"expected: [%1s], but got [%2s]", XML, get.get());
}
@Test(invocationCount = 500, timeOut = 1000)
@Test(invocationCount = 500, timeOut = 1500)
void testHead() throws MalformedURLException, ExecutionException,
InterruptedException {
Head head = factory.createHead("/");
@ -178,7 +178,7 @@ public abstract class BaseHttpFutureCommandClientTest {
assert head.get();
}
@Test(invocationCount = 500, timeOut = 1000)
@Test(invocationCount = 500, timeOut = 1500)
void testGetAndParseSax() throws MalformedURLException, ExecutionException,
InterruptedException {
GetAndParseSax getAndParseSax = factory.createGetAndParseSax("/",

View File

@ -23,7 +23,7 @@
*/
package org.jclouds.gae;
import static junit.framework.Assert.assertEquals;
import static org.testng.Assert.*;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.createNiceMock;

View File

@ -143,7 +143,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.8</version>
<version>5.9</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>com.google.appengine</groupId>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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>

View File

@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
-->
<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.testng</groupId>

View File

@ -53,6 +53,12 @@
<packaging>jar</packaging>
<description>Performance test verses Amazon samples implementation</description>
<properties>
<jclouds.aws.accesskeyid></jclouds.aws.accesskeyid>
<jclouds.aws.secretaccesskey></jclouds.aws.secretaccesskey>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
@ -94,4 +100,25 @@
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<property>
<name>jclouds.aws.accesskeyid</name>
<value>${jclouds.aws.accesskeyid}</value>
</property>
<property>
<name>jclouds.aws.secretaccesskey</name>
<value>${jclouds.aws.secretaccesskey}</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -54,10 +54,9 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
@Override
protected boolean putByteArray(String bucket, String key, byte[] data,
String contentType) throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object();
object.setKey(key);
S3Bucket s3Bucket = new S3Bucket(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.setContentType(contentType);
object.setContent(data);
return client.addObject(s3Bucket, object).get() != null;
@ -66,10 +65,9 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
@Override
protected boolean putFile(String bucket, String key, File data,
String contentType) throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object();
object.setKey(key);
S3Bucket s3Bucket = new S3Bucket(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.setContentType(contentType);
object.setContent(data);
return client.addObject(s3Bucket, object).get() != null;
@ -78,10 +76,9 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
@Override
protected boolean putInputStream(String bucket, String key,
InputStream data, String contentType) throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object();
object.setKey(key);
S3Bucket s3Bucket = new S3Bucket(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.setContentType(contentType);
object.setContent(data);
object.setSize(data.available());
@ -91,10 +88,9 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
@Override
protected boolean putString(String bucket, String key, String data,
String contentType) throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object();
object.setKey(key);
S3Bucket s3Bucket = new S3Bucket(bucket);
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.setContentType(contentType);
object.setContent(data);
return client.addObject(s3Bucket, object).get() != null;

View File

@ -50,7 +50,6 @@ import com.google.inject.Provider;
*
* @author Adrian Cole
*/
@Test(sequential = true, timeOut = 2 * 60 * 1000, groups = "performance")
public abstract class BasePerformance extends S3IntegrationTest {
protected static int LOOP_COUNT = 100;
@ -80,14 +79,13 @@ public abstract class BasePerformance extends S3IntegrationTest {
@Override
@BeforeTest
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID, S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID,
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
protected void setUpClient(@Optional String AWSAccessKeyId,
@Optional String AWSSecretAccessKey) throws Exception {
super.setUpClient(AWSAccessKeyId, AWSSecretAccessKey);
S3Bucket s3Bucket = new S3Bucket();
for (String bucket : BUCKETS) {
s3Bucket.setName(bucket);
client.createBucketIfNotExists(s3Bucket).get();
client.createBucketIfNotExists(new S3Bucket(bucket)).get();
}
}

View File

@ -67,11 +67,6 @@
<artifactId>bcprov-jdk15</artifactId>
<version>140</version>
</dependency>
<dependency>
<groupId>eu.medsea.mimeutil</groupId>
<artifactId>mime-util</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -33,13 +33,21 @@ public interface S3Context {
S3Connection getConnection();
/**
* Creates a <code>Map<String,InputStream</code> view of the specified
* Creates a <code>Map<String,InputStream></code> view of the specified
* bucket.
*
* @param bucket
* @return
*/
S3ObjectMap createMapView(S3Bucket bucket);
S3InputStreamMap createS3InputStreamMap(S3Bucket bucket);
/**
* Creates a <code>Map<String,S3Object></code> view of the specified bucket.
*
* @param bucket
* @return
*/
S3ObjectMap createS3ObjectMap(S3Bucket bucket);
/**
* Closes all connections to S3.

View File

@ -45,7 +45,7 @@ public class S3Utils extends Utils {
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
(byte) 'd', (byte) 'e', (byte) 'f' };
public static String getHexString(byte[] raw)
public static String toHexString(byte[] raw)
throws UnsupportedEncodingException {
byte[] hex = new byte[2 * raw.length];
int index = 0;
@ -58,6 +58,15 @@ public class S3Utils extends Utils {
return new String(hex, "ASCII");
}
public static byte[] fromHexString(String hex) {
byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
16);
}
return bytes;
}
public static String hmacSha1Base64(String toEncode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
@ -75,7 +84,7 @@ public class S3Utils extends Utils {
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException {
byte[] resBuf = md5(toEncode);
return getHexString(resBuf);
return toHexString(resBuf);
}
public static String md5Base64(byte[] toEncode)

View File

@ -23,23 +23,31 @@
*/
package org.jclouds.aws.s3.commands;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.commands.callables.CopyObjectCallable;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class CopyObject extends HttpFutureCommand<Boolean> {
public class CopyObject extends S3FutureCommand<Boolean> {
@Inject
public CopyObject(@Named("jclouds.http.address") String amazonHost, CopyObjectCallable callable, @Assisted("sourceBucket") S3Bucket sourceBucket, @Assisted("sourceObject") S3Object sourceObject, @Assisted("destinationBucket") S3Bucket destinationBucket, @Assisted("destinationObject") S3Object destinationObject) {
super("PUT", "/" + destinationObject.getKey(), callable);
getRequest().getHeaders().put("Host",
destinationBucket.getName() + "." + amazonHost);
getRequest().getHeaders().put("x-amz-copy-source", String.format("/%1s/%2s", sourceBucket.getName(), sourceObject.getKey()));
public CopyObject(@Named("jclouds.http.address") String amazonHost,
CopyObjectCallable callable,
@Assisted("sourceBucket") S3Bucket sourceBucket,
@Assisted("sourceObject") S3Object sourceObject,
@Assisted("destinationBucket") S3Bucket destinationBucket,
@Assisted("destinationObject") S3Object destinationObject) {
super("PUT", "/" + checkNotNull(destinationObject.getKey(),"destinationObject.getKey()"), callable,
amazonHost, destinationBucket);
getRequest().getHeaders().put(
"x-amz-copy-source",
String.format("/%1s/%2s", checkNotNull(sourceBucket.getName(),
"sourceBucket.getName()"), checkNotNull(sourceObject
.getKey(), "sourceObject.getKey()")));
}
}

View File

@ -25,19 +25,16 @@ package org.jclouds.aws.s3.commands;
import org.jclouds.aws.s3.commands.callables.DeleteBucketCallable;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class DeleteBucket extends HttpFutureCommand<Boolean> {
public class DeleteBucket extends S3FutureCommand<Boolean> {
@Inject
public DeleteBucket(@Named("jclouds.http.address") String amazonHost,
DeleteBucketCallable callable, @Assisted S3Bucket s3Bucket) {
super("DELETE", "/", callable);
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
super("DELETE", "/", callable, amazonHost, s3Bucket);
}
}

View File

@ -23,22 +23,21 @@
*/
package org.jclouds.aws.s3.commands;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.commands.callables.DeleteCallable;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class DeleteObject extends HttpFutureCommand<Boolean> {
public class DeleteObject extends S3FutureCommand<Boolean> {
@Inject
public DeleteObject(@Named("jclouds.http.address") String amazonHost,
DeleteCallable callable, @Assisted S3Bucket s3Bucket,
@Assisted String key) {
super("DELETE", "/" + key, callable);
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
super("DELETE", "/" + checkNotNull(key), callable, amazonHost, s3Bucket);
}
}

View File

@ -24,20 +24,17 @@
package org.jclouds.aws.s3.commands;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.commands.callables.ReturnTrueIf200;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class HeadBucket extends HttpFutureCommand<Boolean> {
public class HeadBucket extends S3FutureCommand<Boolean> {
@Inject
public HeadBucket(@Named("jclouds.http.address") String amazonHost,
ReturnTrueIf200 callable, @Assisted S3Bucket s3Bucket) {
super("HEAD", "/", callable);
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
super("HEAD", "/", callable, amazonHost, s3Bucket);
}
}

View File

@ -26,19 +26,17 @@ package org.jclouds.aws.s3.commands;
import java.util.List;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.commands.callables.xml.ParseSax;
import com.google.inject.Inject;
import com.google.inject.name.Named;
public class ListAllMyBuckets extends HttpFutureCommand<List<S3Bucket>> {
public class ListAllMyBuckets extends S3FutureCommand<List<S3Bucket>> {
@Inject
public ListAllMyBuckets(@Named("jclouds.http.address") String amazonHost,
ParseSax<List<S3Bucket>> callable) {
super("GET", "/", callable);
getRequest().getHeaders().put("Host", amazonHost);
super("GET", "/", callable, amazonHost);
}
}

View File

@ -23,22 +23,22 @@
*/
package org.jclouds.aws.s3.commands;
import org.jclouds.aws.s3.commands.callables.xml.ListBucketHandler;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.commands.callables.xml.ParseSax;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class ListBucket extends HttpFutureCommand<S3Bucket> {
public class ListBucket extends S3FutureCommand<S3Bucket> {
@Inject
public ListBucket(@Named("jclouds.http.address") String amazonHost,
ParseSax<S3Bucket> callable, @Assisted S3Bucket s3Bucket) {
super("GET", "/", callable);
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
super("GET", "/", callable, amazonHost, s3Bucket);
ListBucketHandler handler = (ListBucketHandler) callable.getHandler();
handler.setBucket(s3Bucket);
}
}

View File

@ -25,20 +25,17 @@ package org.jclouds.aws.s3.commands;
import org.jclouds.aws.s3.commands.callables.PutBucketCallable;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class PutBucket extends HttpFutureCommand<Boolean> {
public class PutBucket extends S3FutureCommand<Boolean> {
@Inject
public PutBucket(@Named("jclouds.http.address") String amazonHost,
PutBucketCallable callable, @Assisted S3Bucket s3Bucket) {
super("PUT", "/", callable);
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
super("PUT", "/", callable, amazonHost, s3Bucket);
}
}

View File

@ -23,34 +23,30 @@
*/
package org.jclouds.aws.s3.commands;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.commands.callables.PutObjectCallable;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class PutObject extends HttpFutureCommand<String> {
public class PutObject extends S3FutureCommand<String> {
@Inject
public PutObject(@Named("jclouds.http.address") String amazonHost,
PutObjectCallable callable, @Assisted S3Bucket s3Bucket,
@Assisted S3Object object) {
super("PUT", "/" + object.getKey(), callable);
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
if (object.getContentType() == null) {
throw new IllegalArgumentException(
"PUT requests need content type set");
}
Object o = object.getContent();
if (o == null) {
throw new IllegalArgumentException("PUT requests need object");
}
getRequest().setContent(o);
getRequest().setContentType(object.getContentType());
super("PUT", "/" + checkNotNull(object.getKey()), callable, amazonHost,
s3Bucket);
getRequest().setContent(
checkNotNull(object.getContent(), "object.getContent()"));
getRequest()
.setContentType(
checkNotNull(object.getContentType(),
"object.getContentType()"));
getRequest().setContentLength(object.getSize());
}

View File

@ -23,44 +23,24 @@
*/
package org.jclouds.aws.s3.commands;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.commands.callables.RetrieveObjectCallable;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
public class RetrieveObject extends HttpFutureCommand<S3Object> {
private String key;
public class RetrieveObject extends S3FutureCommand<S3Object> {
@Inject
public RetrieveObject(@Named("jclouds.http.address") String amazonHost,
RetrieveObjectCallable callable, @Assisted S3Bucket s3Bucket,
@Assisted String key, @Assisted boolean getContent) {
super(getContent ? "GET" : "HEAD", "/" + key, callable);
this.key = key;
getRequest().getHeaders().put("Host",
s3Bucket.getName() + "." + amazonHost);
}
@Override
public S3Object get() throws InterruptedException, ExecutionException {
S3Object object = super.get();
object.setKey(key);
return object;
}
@Override
public S3Object get(long l, TimeUnit timeUnit) throws InterruptedException,
ExecutionException, TimeoutException {
S3Object object = super.get(l, timeUnit);
object.setKey(key);
return object;
super(getContent ? "GET" : "HEAD", "/" + checkNotNull(key), callable,
amazonHost, s3Bucket);
callable.setKey(key);
}
}

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adriancole@jclouds.org>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.commands;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpFutureCommand;
public class S3FutureCommand<T> extends HttpFutureCommand<T> {
public S3FutureCommand(String method, String uri,
ResponseCallable<T> responseCallable, String amazonHost,
S3Bucket s3Bucket) {
super(method, uri, responseCallable);
addHostHeader(checkNotNull(amazonHost, "amazonHost"), checkNotNull(
s3Bucket, "s3Bucket"));
}
public S3FutureCommand(String method, String uri,
ResponseCallable<T> responseCallable, String amazonHost) {
super(method, uri, responseCallable);
addHostHeader(checkNotNull(amazonHost, "amazonHost"));
}
protected void addHostHeader(String amazonHost, S3Bucket s3Bucket) {
String host = checkNotNull(s3Bucket.getName(), "s3Bucket.getName()")
+ "." + amazonHost;
addHostHeader(host);
}
}

View File

@ -28,7 +28,6 @@ import java.io.IOException;
import org.jclouds.Logger;
import org.jclouds.Utils;
import org.jclouds.aws.s3.DateService;
import org.jclouds.aws.s3.S3Utils;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpFutureCommand;
@ -43,13 +42,12 @@ import com.google.inject.Inject;
public class RetrieveObjectCallable extends
HttpFutureCommand.ResponseCallable<S3Object> {
private final DateService dateParser;
private final S3Utils utils;
private String key;
@Inject
public RetrieveObjectCallable(java.util.logging.Logger logger,
DateService dateParser, S3Utils utils) {
DateService dateParser) {
super(new Logger(logger));
this.utils = utils;
this.dateParser = dateParser;
}
@ -59,7 +57,7 @@ public class RetrieveObjectCallable extends
*/
public S3Object call() throws HttpException {
if (getResponse().getStatusCode() == 200) {
S3Object object = new S3Object();
S3Object object = new S3Object(key);
String md5Header = getResponse().getFirstHeaderOrNull(
"x-amz-meta-object-md5");
if (md5Header != null)
@ -93,4 +91,12 @@ public class RetrieveObjectCallable extends
+ " reason: " + reason);
}
}
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
}

View File

@ -38,7 +38,8 @@ import java.util.List;
*
* @author Adrian Cole
*/
public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<List<S3Bucket>> {
public class ListAllMyBucketsHandler extends
ParseSax.HandlerWithResult<List<S3Bucket>> {
private List<S3Bucket> buckets = new ArrayList<S3Bucket>();
private S3Bucket currentS3Bucket;
@ -56,11 +57,9 @@ public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<List<S3B
return buckets;
}
public void startElement(String uri, String name, String qName, Attributes attrs) {
public void startElement(String uri, String name, String qName,
Attributes attrs) {
if (qName.equals("Bucket")) {
currentS3Bucket = new S3Bucket();
currentS3Bucket.setHasData(false);
currentS3Bucket.setComplete(false);
} else if (qName.equals("Owner")) {
currentOwner = new S3Owner();
}
@ -75,9 +74,12 @@ public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<List<S3B
currentS3Bucket.setCanonicalUser(currentOwner);
buckets.add(currentS3Bucket);
} else if (qName.equals("Name")) {
currentS3Bucket.setName(currentText.toString());
currentS3Bucket = new S3Bucket(currentText.toString());
currentS3Bucket.setHasData(false);
currentS3Bucket.setComplete(false);
} else if (qName.equals("CreationDate")) {
currentS3Bucket.setCreationDate(dateParser.dateTimeFromXMLFormat(currentText.toString()));
currentS3Bucket.setCreationDate(dateParser
.dateTimeFromXMLFormat(currentText.toString()));
}
currentText = new StringBuilder();
}

View File

@ -23,13 +23,17 @@
*/
package org.jclouds.aws.s3.commands.callables.xml;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.DateService;
import com.google.inject.Inject;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.S3Owner;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.inject.Inject;
/**
* // TODO: Adrian: Document this!
@ -42,16 +46,27 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
return s3Bucket;
}
private S3Bucket s3Bucket = new S3Bucket();
public void setBucket(S3Bucket s3Bucket) {
this.s3Bucket = s3Bucket;
}
private S3Bucket s3Bucket;
private S3Object currentObject;
private S3Owner currentOwner;
private StringBuilder currentText = new StringBuilder();
@Inject
private DateService dateParser;
public void startElement(String uri, String name, String qName, Attributes attrs) {
@Override
public void startDocument() throws SAXException {
checkNotNull(s3Bucket, "s3Bucket");
s3Bucket.getContents().clear();
super.startDocument();
}
public void startElement(String uri, String name, String qName,
Attributes attrs) {
if (qName.equals("Contents")) {
currentObject = new S3Object();
} else if (qName.equals("Owner")) {
currentOwner = new S3Owner();
}
@ -64,9 +79,10 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
} else if (qName.equals("DisplayName")) {
currentOwner.setDisplayName(currentText.toString());
} else if (qName.equals("Key")) { // content stuff
currentObject.setKey(currentText.toString());
currentObject = new S3Object(currentText.toString());
} else if (qName.equals("LastModified")) {
currentObject.setLastModified(dateParser.dateTimeFromXMLFormat(currentText.toString()));
currentObject.setLastModified(dateParser
.dateTimeFromXMLFormat(currentText.toString()));
} else if (qName.equals("ETag")) {
currentObject.setETag(currentText.toString().replaceAll("\"", ""));
} else if (qName.equals("Size")) {
@ -78,7 +94,6 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
} else if (qName.equals("Contents")) {
s3Bucket.getContents().add(currentObject);
} else if (qName.equals("Name")) {// bucket stuff last, as least likely
s3Bucket.setName(currentText.toString());
// } else if (qName.equals("Prefix")) {
// // no-op
// } else if (qName.equals("Marker")) {

View File

@ -33,6 +33,7 @@ import org.jclouds.aws.s3.filters.RemoveTransferEncodingHeader;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
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.aws.s3.internal.GuiceS3Context.S3ObjectMapFactory;
import org.jclouds.http.HttpRequestFilter;
@ -59,6 +60,10 @@ public class S3ContextModule extends AbstractModule {
FactoryProvider.newFactory(
GuiceS3Context.S3ObjectMapFactory.class,
LiveS3ObjectMap.class));
bind(GuiceS3Context.S3InputStreamMapFactory.class).toProvider(
FactoryProvider.newFactory(
GuiceS3Context.S3InputStreamMapFactory.class,
LiveS3InputStreamMap.class));
bind(S3Context.class).to(GuiceS3Context.class);
}

View File

@ -26,6 +26,7 @@ package org.jclouds.aws.s3.domain;
import org.joda.time.DateTime;
import org.jclouds.aws.s3.domain.S3Owner;
import org.jclouds.aws.s3.domain.S3Object;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.HashSet;
import java.util.Set;
@ -36,21 +37,21 @@ import java.util.Set;
* @author Adrian Cole
*/
public class S3Bucket {
public static final S3Bucket NOT_FOUND = new S3Bucket();
public static final S3Bucket NOT_FOUND = new S3Bucket("NOT_FOUND");
private String name;
private final String name;
private DateTime creationDate;
private S3Owner canonicalUser;
private Set<S3Object> objects = new HashSet<S3Object>();
boolean isComplete;
boolean hasData;
public String getName() {
return name;
public S3Bucket(String name) {
this.name = checkNotNull(name).toLowerCase();
}
public void setName(String name) {
this.name = name.toLowerCase();
public String getName() {
return name;
}
public DateTime getCreationDate() {
@ -77,7 +78,6 @@ public class S3Bucket {
this.objects = objects;
}
public boolean isComplete() {
return isComplete;
}
@ -96,19 +96,29 @@ public class S3Bucket {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof S3Bucket)) return false;
if (this == o)
return true;
if (!(o instanceof S3Bucket))
return false;
S3Bucket s3Bucket = (S3Bucket) o;
if (hasData != s3Bucket.hasData) return false;
if (isComplete != s3Bucket.isComplete) return false;
if (canonicalUser != null ? !canonicalUser.equals(s3Bucket.canonicalUser) : s3Bucket.canonicalUser != null)
if (hasData != s3Bucket.hasData)
return false;
if (objects != null ? !objects.equals(s3Bucket.objects) : s3Bucket.objects != null) return false;
if (creationDate != null ? !creationDate.equals(s3Bucket.creationDate) : s3Bucket.creationDate != null)
if (isComplete != s3Bucket.isComplete)
return false;
if (canonicalUser != null ? !canonicalUser
.equals(s3Bucket.canonicalUser)
: s3Bucket.canonicalUser != null)
return false;
if (objects != null ? !objects.equals(s3Bucket.objects)
: s3Bucket.objects != null)
return false;
if (creationDate != null ? !creationDate.equals(s3Bucket.creationDate)
: s3Bucket.creationDate != null)
return false;
if (!name.equals(s3Bucket.name))
return false;
if (!name.equals(s3Bucket.name)) return false;
return true;
}
@ -116,8 +126,10 @@ public class S3Bucket {
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + (creationDate != null ? creationDate.hashCode() : 0);
result = 31 * result + (canonicalUser != null ? canonicalUser.hashCode() : 0);
result = 31 * result
+ (creationDate != null ? creationDate.hashCode() : 0);
result = 31 * result
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
result = 31 * result + (objects != null ? objects.hashCode() : 0);
result = 31 * result + (isComplete ? 1 : 0);
result = 31 * result + (hasData ? 1 : 0);

View File

@ -24,6 +24,7 @@
package org.jclouds.aws.s3.domain;
import org.joda.time.DateTime;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* // TODO: Adrian: Document this!
@ -31,11 +32,11 @@ import org.joda.time.DateTime;
* @author Adrian Cole
*/
public class S3Object {
public static final S3Object NOT_FOUND = new S3Object();
public static final S3Object NOT_FOUND = new S3Object("NOT_FOUND");
public static final String UNKNOWN_MIME_TYPE = "application/x-unknown-mime-type";
private String key;
private final String key;
private DateTime lastModified;
private String eTag;
private long size = -1;
@ -47,12 +48,12 @@ public class S3Object {
private String server;
private Object content;
public String getKey() {
return key;
public S3Object(String key) {
this.key = checkNotNull(key);
}
public void setKey(String key) {
this.key = key;
public String getKey() {
return key;
}
public DateTime getLastModified() {

View File

@ -28,6 +28,7 @@ import java.io.IOException;
import org.jclouds.Logger;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3InputStreamMap;
import org.jclouds.aws.s3.S3ObjectMap;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.lifecycle.Closer;
@ -45,16 +46,23 @@ public class GuiceS3Context implements S3Context {
S3ObjectMap createMapView(S3Bucket bucket);
}
public interface S3InputStreamMapFactory {
S3InputStreamMap createMapView(S3Bucket bucket);
}
private final Logger logger;
private final Injector injector;
private final S3InputStreamMapFactory s3InputStreamMapFactory;
private final S3ObjectMapFactory s3ObjectMapFactory;
private final Closer closer;
@Inject
private GuiceS3Context(java.util.logging.Logger logger, Injector injector,
Closer closer, S3ObjectMapFactory s3ObjectMapFactory) {
Closer closer, S3ObjectMapFactory s3ObjectMapFactory,
S3InputStreamMapFactory s3InputStreamMapFactory) {
this.logger = new Logger(logger);
this.injector = injector;
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
this.s3ObjectMapFactory = s3ObjectMapFactory;
this.closer = closer;
}
@ -69,7 +77,15 @@ public class GuiceS3Context implements S3Context {
/**
* {@inheritDoc}
*/
public S3ObjectMap createMapView(S3Bucket bucket) {
public S3InputStreamMap createS3InputStreamMap(S3Bucket bucket) {
getConnection().createBucketIfNotExists(bucket);
return s3InputStreamMapFactory.createMapView(bucket);
}
/**
* {@inheritDoc}
*/
public S3ObjectMap createS3ObjectMap(S3Bucket bucket) {
getConnection().createBucketIfNotExists(bucket);
return s3ObjectMapFactory.createMapView(bucket);
}

View File

@ -47,16 +47,13 @@ public class AmazonS3Test extends S3IntegrationTest {
}
S3Object getObject() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.getObject(s3Bucket, "3366").get();
}
String putFileObject() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Object object = new S3Object();
object.setKey("meat");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
S3Object object = new S3Object("meat");
object.setContentType("text/xml");
object.setContent(new File("pom.xml"));
return client.addObject(s3Bucket, object).get();
@ -77,49 +74,55 @@ public class AmazonS3Test extends S3IntegrationTest {
@Test(dataProvider = "putTests")
void testPutObject(String key, String type, Object content,
Object realObject) throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "filetestsforadrian");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "filetestsforadrian");
client.createBucketIfNotExists(s3Bucket).get();
S3Object object = new S3Object();
object.setKey(key);
context.createS3ObjectMap(s3Bucket).clear();
assertEquals(client.getBucket(s3Bucket).get().getContents().size(), 0);
S3Object object = new S3Object(key);
object.setContentType(type);
object.setContent(content);
assertNotNull(client.addObject(s3Bucket, object).get());
object = client.getObject(s3Bucket, object.getKey()).get();
returnedString = S3Utils.getContentAsStringAndClose(object);
assertEquals(returnedString, realObject);
assertEquals(client.getBucket(s3Bucket).get().getContents().size(), 1);
}
@Test
void testCopyObject() throws Exception {
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
S3Bucket sourceBucket = new S3Bucket();
sourceBucket.setName(bucketPrefix + "copysource");
S3Bucket sourceBucket = new S3Bucket(bucketPrefix + "copysource");
client.createBucketIfNotExists(sourceBucket).get();
assertEquals(client.getBucket(sourceBucket).get().getContents().size(),
0);
S3Object sourceObject = new S3Object();
sourceObject.setKey("file");
S3Object sourceObject = new S3Object("file");
sourceObject.setContentType("text/xml");
sourceObject.setContent(new File("pom.xml"));
client.addObject(sourceBucket, sourceObject).get();
assertEquals(client.getBucket(sourceBucket).get().getContents().size(),
1);
sourceObject = client.getObject(sourceBucket, sourceObject.getKey())
.get();
assertEquals(S3Utils.getContentAsStringAndClose(sourceObject),
realObject);
S3Bucket destinationBucket = new S3Bucket();
destinationBucket.setName(bucketPrefix + "copydestination");
S3Bucket destinationBucket = new S3Bucket(bucketPrefix
+ "copydestination");
client.createBucketIfNotExists(destinationBucket).get();
assertEquals(client.getBucket(destinationBucket).get().getContents()
.size(), 0);
S3Object destinationObject = new S3Object();
destinationObject.setKey(sourceObject.getKey());
S3Object destinationObject = new S3Object(sourceObject.getKey());
client.copyObject(sourceBucket, sourceObject, destinationBucket,
destinationObject).get();
assertEquals(client.getBucket(destinationBucket).get().getContents()
.size(), 1);
destinationObject = client.getObject(destinationBucket,
destinationObject.getKey()).get();
@ -129,38 +132,32 @@ public class AmazonS3Test extends S3IntegrationTest {
}
S3Object headObject() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.headObject(s3Bucket, "3366").get();
}
Boolean bucketExists() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.bucketExists(s3Bucket).get();
}
Boolean deleteBucket() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.deleteBucket(s3Bucket).get();
}
Boolean deleteObject() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.deleteObject(s3Bucket, "3366").get();
}
Boolean createBucketIfNotExists() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.createBucketIfNotExists(s3Bucket).get();
}
S3Bucket getBucket() throws Exception {
S3Bucket s3Bucket = new S3Bucket();
s3Bucket.setName(bucketPrefix + "adrianjbosstest");
S3Bucket s3Bucket = new S3Bucket(bucketPrefix + "adrianjbosstest");
return client.getBucket(s3Bucket).get();
}

View File

@ -129,6 +129,7 @@ public class S3IntegrationTest {
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"));
properties.setProperty(HttpConstants.PROPERTY_HTTP_SECURE, "false");
properties.setProperty(HttpConstants.PROPERTY_HTTP_PORT, "80");
// properties.setProperty("jclouds.http.sax.debug", "true");
return properties;
}
@ -163,7 +164,7 @@ public class S3IntegrationTest {
@AfterTest
protected void tearDownClient() throws Exception {
deleteEverything();
// deleteEverything();
context.close();
context = null;
}

View File

@ -37,7 +37,7 @@ import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import static junit.framework.Assert.*;
import static org.testng.Assert.*;
/**
* This tests the performance of Digest commands.

View File

@ -55,8 +55,7 @@ public class StubS3Connection implements S3Connection {
.get(s3Bucket);
if (!realContents.containsKey(key))
return S3Object.NOT_FOUND;
S3Object object = new S3Object();
object.setKey(key);
S3Object object = new S3Object(key);
object.setContent(realContents.get(key));
return object;
}
@ -158,8 +157,7 @@ public class StubS3Connection implements S3Connection {
.get(s3Bucket);
if (realContents != null) {
for (String key : realContents.keySet()) {
S3Object object = new S3Object();
object.setKey(key);
S3Object object = new S3Object(key);
object.setContent(realContents.get(key));
contents.add(object);
}

View File

@ -72,30 +72,30 @@ public class S3CommandFactoryTest {
@Test
void testCreateCopyObject() {
assert commandFactory.createCopyObject(createMock(S3Bucket.class),
createMock(S3Object.class), createMock(S3Bucket.class),
createMock(S3Object.class)) != null;
assert commandFactory.createCopyObject(new S3Bucket("sourceBucket"),
new S3Object("sourceObject"), new S3Bucket("destBucket"),
new S3Object("destObject")) != null;
}
@Test
void testCreateDeleteBucket() {
assert commandFactory.createDeleteBucket(createMock(S3Bucket.class)) != null;
assert commandFactory.createDeleteBucket(new S3Bucket("test")) != null;
}
@Test
void testCreateDeleteObject() {
assert commandFactory.createDeleteObject(createMock(S3Bucket.class),
assert commandFactory.createDeleteObject(new S3Bucket("test"),
"blah") != null;
}
@Test
void testCreateHeadBucket() {
assert commandFactory.createHeadBucket(createMock(S3Bucket.class)) != null;
assert commandFactory.createHeadBucket(new S3Bucket("test")) != null;
}
@Test
void testCreatePutBucket() {
assert commandFactory.createPutBucket(createMock(S3Bucket.class)) != null;
assert commandFactory.createPutBucket(new S3Bucket("test")) != null;
}
@Test
@ -108,13 +108,13 @@ public class S3CommandFactoryTest {
replay(object);
assert commandFactory.createPutObject(createMock(S3Bucket.class),
assert commandFactory.createPutObject(new S3Bucket("test"),
object) != null;
}
@Test
void testCreateRetrieveObject() {
assert commandFactory.createRetrieveObject(createMock(S3Bucket.class),
assert commandFactory.createRetrieveObject(new S3Bucket("test"),
"blah", false) != null;
}
@ -135,7 +135,7 @@ public class S3CommandFactoryTest {
@Test
void testCreateListBucket() {
assert commandFactory.createListBucket(createMock(S3Bucket.class)) != null;
assert commandFactory.createListBucket(new S3Bucket("test")) != null;
}
}

View File

@ -34,11 +34,13 @@ import java.util.concurrent.ExecutorCompletionService;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.PerformanceTest;
import org.jclouds.aws.s3.commands.callables.xml.ListBucketHandler;
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.S3Owner;
import org.jclouds.http.HttpException;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.joda.time.DateTime;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
@ -68,6 +70,8 @@ public class S3ParserTest extends PerformanceTest {
protected void configure() {
bindConstant().annotatedWith(
Names.named("jclouds.http.address")).to("localhost");
// bindConstant().annotatedWith(
// Names.named("jclouds.http.sax.debug")).to(true);
super.configure();
}
});
@ -161,8 +165,10 @@ public class S3ParserTest extends PerformanceTest {
}
private S3Bucket runParseListBucketResult() throws HttpException {
return commandFactory.createListBucketParser().parse(
IOUtils.toInputStream(listBucketResult));
ParseSax<S3Bucket> parser = commandFactory.createListBucketParser();
ListBucketHandler handler = (ListBucketHandler) parser.getHandler();
handler.setBucket(new S3Bucket("adrianjbosstest"));
return parser.parse(IOUtils.toInputStream(listBucketResult));
}
@Test

View File

@ -25,7 +25,7 @@ package org.jclouds.aws.s3.domain;
import java.io.File;
import junit.framework.Assert;
import static org.testng.Assert.*;
import org.jclouds.aws.s3.domain.S3Object;
import org.testng.annotations.Test;
@ -35,9 +35,10 @@ public class S3ObjectTest {
@Test
void testSetNoContentType() {
S3Object object = new S3Object();
S3Object object = new S3Object("test");
File file = new File("hello.txt");
object.setContent(file);
Assert.assertEquals(object.getContentType(), S3Object.UNKNOWN_MIME_TYPE);
assertEquals(object.getContentType(),
S3Object.UNKNOWN_MIME_TYPE);
}
}

View File

@ -85,18 +85,6 @@
<artifactId>guice-servlet</artifactId>
<version>2.0-r936</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.8</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<artifactId>standard</artifactId>
<groupId>taglibs</groupId>

View File

@ -24,10 +24,8 @@
package org.jclouds.samples.googleappengine;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
@ -48,6 +46,8 @@ import com.google.inject.Singleton;
*/
@Singleton
public class JCloudsServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Inject
S3Context context;
@ -62,7 +62,8 @@ public class JCloudsServlet extends HttpServlet {
writer.write("List:\n");
for (S3Bucket bucket : myBuckets) {
writer.write(String.format(" %1s: %2s entries%n", bucket
.getName(), context.createMapView(bucket).size()));
.getName(), context.createS3InputStreamMap(bucket)
.size()));
}
} catch (Exception e) {
throw new ServletException(e);

View File

@ -34,7 +34,6 @@ import org.jclouds.aws.s3.S3Constants;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.gae.config.URLFetchServiceClientModule;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.samples.googleappengine.JCloudsServlet;
import com.google.inject.Inject;
@ -76,6 +75,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
} finally {
IOUtils.closeQuietly(input);
}
props.setProperty("jclouds.http.sax.debug", "true");
return props;
}