updated google app engine sample

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1089 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-06-08 00:49:23 +00:00
parent bf3ba3e855
commit 9cec8159d4
10 changed files with 401 additions and 354 deletions

View File

@ -30,307 +30,296 @@ import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
/** /**
* A container that provides namespace, access control and aggregation of * A container that provides namespace, access control and aggregation of {@link S3Object}s
* {@link S3Object}s
* <p/> * <p/>
* <p/> * <p/>
* Every object stored in Amazon S3 is contained in a bucket. Buckets partition * Every object stored in Amazon S3 is contained in a bucket. Buckets partition the namespace of
* the namespace of objects stored in Amazon S3 at the top level. Within a * objects stored in Amazon S3 at the top level. Within a bucket, you can use any names for your
* bucket, you can use any names for your objects, but bucket names must be * objects, but bucket names must be unique across all of Amazon S3.
* unique across all of Amazon S3.
* <p/> * <p/>
* Buckets are similar to Internet domain names. Just as Amazon is the only * Buckets are similar to Internet domain names. Just as Amazon is the only owner of the domain name
* owner of the domain name Amazon.com, only one person or organization can own * Amazon.com, only one person or organization can own a bucket within Amazon S3. Once you create a
* a bucket within Amazon S3. Once you create a uniquely named bucket in Amazon * uniquely named bucket in Amazon S3, you can organize and name the objects within the bucket in
* S3, you can organize and name the objects within the bucket in any way you * any way you like and the bucket will remain yours for as long as you like and as long as you have
* like and the bucket will remain yours for as long as you like and as long as * the Amazon S3 account.
* you have the Amazon S3 account.
* <p/> * <p/>
* The similarities between buckets and domain names is not a coincidenceÑthere * The similarities between buckets and domain names is not a coincidenceÑthere is a direct mapping
* is a direct mapping between Amazon S3 buckets and subdomains of * between Amazon S3 buckets and subdomains of s3.amazonaws.com. Objects stored in Amazon S3 are
* s3.amazonaws.com. Objects stored in Amazon S3 are addressable using the REST * addressable using the REST API under the domain bucketname.s3.amazonaws.com. For example, if the
* API under the domain bucketname.s3.amazonaws.com. For example, if the object * object homepage.html?is stored in the Amazon S3 bucket mybucket its address would be
* homepage.html?is stored in the Amazon S3 bucket mybucket its address would be
* http://mybucket.s3.amazonaws.com/homepage.html? * http://mybucket.s3.amazonaws.com/homepage.html?
* *
* @author Adrian Cole * @author Adrian Cole
* @see <a * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html"
* />
*/ */
public class S3Bucket { public class S3Bucket {
@Override @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("S3Bucket"); sb.append("S3Bucket");
sb.append("{metadata=").append(metadata); sb.append("{metadata=").append(metadata);
sb.append(", isTruncated=").append(isTruncated); sb.append(", isTruncated=").append(isTruncated);
sb.append('}'); sb.append('}');
return sb.toString(); return sb.toString();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) if (this == o)
return true;
if (!(o instanceof S3Bucket))
return false;
S3Bucket s3Bucket = (S3Bucket) o;
if (isTruncated != s3Bucket.isTruncated)
return false;
if (!metadata.equals(s3Bucket.metadata))
return false;
if (objects != null ? !objects.equals(s3Bucket.objects) : s3Bucket.objects != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = objects != null ? objects.hashCode() : 0;
result = 31 * result + metadata.hashCode();
result = 31 * result + (isTruncated ? 1 : 0);
return result;
}
/**
* System metadata of the S3Bucket
*
* @author Adrian Cole
*/
public static class Metadata {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Metadata");
sb.append("{name='").append(name).append('\'');
sb.append(", creationDate=").append(creationDate);
sb.append(", canonicalUser=").append(canonicalUser);
sb.append('}');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true; return true;
if (!(o instanceof S3Bucket)) if (!(o instanceof Metadata))
return false; return false;
S3Bucket s3Bucket = (S3Bucket) o; Metadata metadata = (Metadata) o;
if (canonicalUser != null ? !canonicalUser.equals(metadata.canonicalUser)
if (isTruncated != s3Bucket.isTruncated) : metadata.canonicalUser != null)
return false; return false;
if (!metadata.equals(s3Bucket.metadata)) if (!name.equals(metadata.name))
return false;
if (objects != null ? !objects.equals(s3Bucket.objects)
: s3Bucket.objects != null)
return false; return false;
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = objects != null ? objects.hashCode() : 0; int result = name.hashCode();
result = 31 * result + metadata.hashCode(); result = 31 * result + (canonicalUser != null ? canonicalUser.hashCode() : 0);
result = 31 * result + (isTruncated ? 1 : 0); return result;
return result; }
}
/** /**
* System metadata of the S3Bucket * Location constraint of the bucket.
* *
* @author Adrian Cole * @author Adrian Cole
*/ * @see <a href=
public static class Metadata { * "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html" />
@Override */
public String toString() { public static enum LocationConstraint {
final StringBuilder sb = new StringBuilder(); EU
sb.append("Metadata"); }
sb.append("{name='").append(name).append('\'');
sb.append(", creationDate=").append(creationDate);
sb.append(", canonicalUser=").append(canonicalUser);
sb.append('}');
return sb.toString();
}
@Override private final String name;
public boolean equals(Object o) { private DateTime creationDate;
if (this == o) private CanonicalUser canonicalUser;
return true;
if (!(o instanceof Metadata))
return false;
Metadata metadata = (Metadata) o; /**
if (canonicalUser != null ? !canonicalUser * @see #getName()
.equals(metadata.canonicalUser) */
: metadata.canonicalUser != null) public Metadata(String name) {
return false; this.name = checkNotNull(name, "name");
if (!name.equals(metadata.name)) }
return false;
return true; /**
} * 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;
}
@Override public DateTime getCreationDate() {
public int hashCode() { return creationDate;
int result = name.hashCode(); }
result = 31 * result
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
return result;
}
/** public void setCreationDate(DateTime creationDate) {
* Location constraint of the bucket. this.creationDate = creationDate;
* }
* @author Adrian Cole
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
* />
*/
public static enum LocationConstraint {
EU
}
private final String name; /**
private DateTime creationDate; * Every bucket and object in Amazon S3 has an owner, the user that created the bucket or
private CanonicalUser canonicalUser; * object. The owner of a bucket or object cannot be changed. However, if the object is
* overwritten by another user (deleted and rewritten), the new object will have a new owner.
*/
public CanonicalUser getOwner() {
return canonicalUser;
}
/** public void setOwner(CanonicalUser canonicalUser) {
* @see #getName() this.canonicalUser = canonicalUser;
*/ }
public Metadata(String name) {
this.name = checkNotNull(name, "name");
}
/** }
* 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;
}
public DateTime getCreationDate() { public static final S3Bucket NOT_FOUND = new S3Bucket("NOT_FOUND");
return creationDate;
}
public void setCreationDate(DateTime creationDate) { private SortedSet<S3Object.Metadata> objects = new TreeSet<S3Object.Metadata>();
this.creationDate = creationDate; private SortedSet<String> commonPrefixes = new TreeSet<String>();
} private String prefix;
private String marker;
private String delimiter;
private long maxKeys;
private final Metadata metadata;
/** private boolean isTruncated;
* Every bucket and object in Amazon S3 has an owner, the user that
* created the bucket or object. The owner of a bucket or object cannot
* be changed. However, if the object is overwritten by another user
* (deleted and rewritten), the new object will have a new owner.
*/
public CanonicalUser getOwner() {
return canonicalUser;
}
public void setOwner(CanonicalUser canonicalUser) { public S3Bucket(String name) {
this.canonicalUser = canonicalUser; this.metadata = new Metadata(name);
} }
} public String getName() {
return this.metadata.getName();
}
public static final S3Bucket NOT_FOUND = new S3Bucket("NOT_FOUND"); public S3Bucket(Metadata metadata) {
this.metadata = checkNotNull(metadata, "metadata");
}
private SortedSet<S3Object.Metadata> objects = new TreeSet<S3Object.Metadata>(); /**
private SortedSet<String> commonPrefixes = new TreeSet<String>(); * @see org.jclouds.aws.s3.S3Connection#listBucket(String)
private String prefix; */
private String marker; public SortedSet<S3Object.Metadata> getContents() {
private String delimiter; return objects;
private long maxKeys; }
private final Metadata metadata;
private boolean isTruncated; public long getSize() {
return objects.size();
}
public S3Bucket(String name) { public void setContents(SortedSet<S3Object.Metadata> objects) {
this.metadata = new Metadata(name); this.objects = objects;
} }
public String getName() { /**
return this.metadata.getName(); * @return true, if the list contains all objects.
} */
public boolean isTruncated() {
return isTruncated;
}
public S3Bucket(Metadata metadata) { public void setTruncated(boolean truncated) {
this.metadata = checkNotNull(metadata, "metadata"); isTruncated = truncated;
} }
/** public Metadata getMetadata() {
* @see org.jclouds.aws.s3.S3Connection#listBucket(String) return metadata;
*/ }
public SortedSet<S3Object.Metadata> getContents() {
return objects;
}
public void setContents(SortedSet<S3Object.Metadata> objects) { public void setCommonPrefixes(SortedSet<String> commonPrefixes) {
this.objects = objects; this.commonPrefixes = commonPrefixes;
} }
/** /**
* @return true, if the list contains all objects. * Example:
*/ * <p/>
public boolean isTruncated() { * if the following keys are in the bucket
return isTruncated; * <p/>
} * a/1/a<br/>
* a/1/b<br/>
* a/2/a<br/>
* a/2/b<br/>
* <p/>
* and prefix is set to <code>a/</code> and delimiter is set to <code>/</code> then
* commonprefixes would return 1,2
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public SortedSet<String> getCommonPrefixes() {
return commonPrefixes;
}
public void setTruncated(boolean truncated) { public void setPrefix(String prefix) {
isTruncated = truncated; this.prefix = prefix;
} }
public Metadata getMetadata() { /**
return metadata; * return keys that start with this.
} *
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public String getPrefix() {
return prefix;
}
public void setCommonPrefixes(SortedSet<String> commonPrefixes) { public void setMaxKeys(long maxKeys) {
this.commonPrefixes = commonPrefixes; this.maxKeys = maxKeys;
} }
/** /**
* Example: * @return maximum results of the bucket.
* <p/> * @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMaxKeys()
* if the following keys are in the bucket */
* <p/> public long getMaxKeys() {
* a/1/a<br/> return maxKeys;
* a/1/b<br/> }
* a/2/a<br/>
* a/2/b<br/>
* <p/>
* and prefix is set to <code>a/</code> and delimiter is set to
* <code>/</code> then commonprefixes would return 1,2
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public SortedSet<String> getCommonPrefixes() {
return commonPrefixes;
}
public void setPrefix(String prefix) { public void setMarker(String marker) {
this.prefix = prefix; this.marker = marker;
} }
/** /**
* return keys that start with this. * when set, bucket contains results whose keys are lexigraphically after marker.
* *
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix() * @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/ */
public String getPrefix() { public String getMarker() {
return prefix; return marker;
} }
public void setMaxKeys(long maxKeys) { public void setDelimiter(String delimiter) {
this.maxKeys = maxKeys; this.delimiter = delimiter;
} }
/** /**
* @return maximum results of the bucket. * when set, bucket results will not contain keys that have text following this delimiter.
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMaxKeys() * <p/>
*/ * note that delimiter has no effect on prefix. prefix can contain the delimiter many times, or
public long getMaxKeys() { * not at all. delimiter only restricts after the prefix.
return maxKeys; *
} * @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public void setMarker(String marker) { public String getDelimiter() {
this.marker = marker; return delimiter;
} }
/**
* when set, bucket contains results whose keys are lexigraphically after
* marker.
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public String getMarker() {
return marker;
}
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
/**
* when set, bucket results will not contain keys that have text following
* this delimiter.
* <p/>
* note that delimiter has no effect on prefix. prefix can contain the
* delimiter many times, or not at all. delimiter only restricts after the
* prefix.
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public String getDelimiter() {
return delimiter;
}
} }

View File

@ -163,16 +163,13 @@ public class S3IntegrationTest {
} }
protected void createStubS3Context() { protected void createStubS3Context() {
context = S3ContextFactory.createContext("stub", "stub") context = S3ContextFactory.createContext("stub", "stub").withHttpAddress("stub").withModule(
.withHttpAddress("stub") new StubS3ConnectionModule()).build();
.withModule(new StubS3ConnectionModule())
.build();
} }
protected void createLiveS3Context(String AWSAccessKeyId, String AWSSecretAccessKey) { protected void createLiveS3Context(String AWSAccessKeyId, String AWSSecretAccessKey) {
context = buildS3ContextFactory(AWSAccessKeyId, AWSSecretAccessKey) context = buildS3ContextFactory(AWSAccessKeyId, AWSSecretAccessKey).withModule(
.withModule(createHttpModule()) createHttpModule()).build();
.build();
} }
@BeforeMethod(dependsOnMethods = "deleteBucket", groups = { "integration", "live" }) @BeforeMethod(dependsOnMethods = "deleteBucket", groups = { "integration", "live" })
@ -194,9 +191,8 @@ public class S3IntegrationTest {
} }
protected S3ContextFactory buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) { protected S3ContextFactory buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) {
return S3ContextFactory.createContext(AWSAccessKeyId, AWSSecretAccessKey) return S3ContextFactory.createContext(AWSAccessKeyId, AWSSecretAccessKey).withHttpSecure(
.withHttpSecure(false) false).withHttpPort(80);
.withHttpPort(80);
} }
protected Module createHttpModule() { protected Module createHttpModule() {
@ -226,8 +222,7 @@ public class S3IntegrationTest {
* @throws TimeoutException * @throws TimeoutException
*/ */
protected void emptyBucket(String name) throws InterruptedException, ExecutionException, protected void emptyBucket(String name) throws InterruptedException, ExecutionException,
TimeoutException TimeoutException {
{
if (client.bucketExists(name).get(10, TimeUnit.SECONDS)) { if (client.bucketExists(name).get(10, TimeUnit.SECONDS)) {
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>(); List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
@ -251,9 +246,8 @@ public class S3IntegrationTest {
* @throws ExecutionException * @throws ExecutionException
* @throws TimeoutException * @throws TimeoutException
*/ */
private void deleteBucket(String name) throws InterruptedException, ExecutionException, protected void deleteBucket(String name) throws InterruptedException, ExecutionException,
TimeoutException TimeoutException {
{
if (client.bucketExists(name).get(10, TimeUnit.SECONDS)) { if (client.bucketExists(name).get(10, TimeUnit.SECONDS)) {
emptyBucket(name); emptyBucket(name);
client.deleteBucketIfEmpty(name).get(10, TimeUnit.SECONDS); client.deleteBucketIfEmpty(name).get(10, TimeUnit.SECONDS);

View File

@ -23,32 +23,29 @@
*/ */
package org.jclouds.aws.s3.xml; package org.jclouds.aws.s3.xml;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
public class BaseHandlerTest { public class BaseHandlerTest {
protected S3ParserFactory parserFactory = null; protected S3ParserFactory parserFactory = null;
private Injector injector; private Injector injector;
public BaseHandlerTest() { @BeforeTest
super(); protected void setUpInjector() {
} injector = Guice.createInjector(new S3ParserModule());
parserFactory = injector.getInstance(S3ParserFactory.class);
assert parserFactory != null;
}
@BeforeMethod @AfterTest
protected void setUpInjector() { protected void tearDownInjector() {
injector = Guice.createInjector(new S3ParserModule()); parserFactory = null;
parserFactory = injector.getInstance(S3ParserFactory.class); injector = null;
assert parserFactory != null; }
}
@AfterMethod
protected void tearDownInjector() {
parserFactory = null;
injector = null;
}
} }

View File

@ -23,6 +23,8 @@
*/ */
package org.jclouds.aws.s3; package org.jclouds.aws.s3;
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.createIn;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
@ -36,7 +38,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.aws.s3.S3IntegrationTest; import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
import org.testng.annotations.AfterTest; import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -61,19 +63,39 @@ public abstract class BasePerformance extends S3IntegrationTest {
protected ExecutorService exec; protected ExecutorService exec;
protected CompletionService<Boolean> completer; protected CompletionService<Boolean> completer;
protected String bucketNameEU;
@BeforeTest @BeforeTest
protected void setUpCallables() { protected void setUpCallables() throws InterruptedException, ExecutionException,
TimeoutException {
exec = Executors.newCachedThreadPool(); exec = Executors.newCachedThreadPool();
completer = new ExecutorCompletionService<Boolean>(exec); completer = new ExecutorCompletionService<Boolean>(exec);
bucketNameEU = (bucketPrefix).toLowerCase() + ".eu";
} }
@AfterTest @AfterTest
protected void tearDownExecutor() throws Exception { protected void tearDownExecutor() throws Exception {
if (bucketNameEU != null)
deleteBucket(bucketNameEU);
exec.shutdownNow(); exec.shutdownNow();
exec = null; exec = null;
} }
@Test(enabled = true)
public void testPutBytesSerialEU() throws Exception {
client.putBucketIfNotExists(bucketNameEU, createIn(LocationConstraint.EU)).get(10,
TimeUnit.SECONDS);
doSerial(new PutBytesCallable(this.bucketNameEU), loopCount / 10);
}
@Test(enabled = true)
public void testPutBytesParallelEU() throws InterruptedException, ExecutionException,
TimeoutException {
client.putBucketIfNotExists(bucketNameEU, createIn(LocationConstraint.EU)).get(10,
TimeUnit.SECONDS);
doParallel(new PutBytesCallable(this.bucketNameEU), loopCount);
}
@Test(enabled = true) @Test(enabled = true)
public void testPutBytesSerial() throws Exception { public void testPutBytesSerial() throws Exception {
doSerial(new PutBytesCallable(this.bucketName), loopCount / 10); doSerial(new PutBytesCallable(this.bucketName), loopCount / 10);

View File

@ -56,6 +56,11 @@
<artifactId>guice-servlet</artifactId> <artifactId>guice-servlet</artifactId>
<version>2.0</version> <version>2.0</version>
</dependency> </dependency>
<dependency>
<groupId>displaytag</groupId>
<artifactId>displaytag</artifactId>
<version>1.2</version>
</dependency>
<dependency> <dependency>
<artifactId>standard</artifactId> <artifactId>standard</artifactId>
<groupId>taglibs</groupId> <groupId>taglibs</groupId>

View File

@ -24,17 +24,17 @@
package org.jclouds.samples.googleappengine; package org.jclouds.samples.googleappengine;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.s3.S3Context; import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.domain.S3Bucket; import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -69,32 +69,24 @@ public class JCloudsServlet extends HttpServlet {
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@Override @Override
protected void doGet(HttpServletRequest httpServletRequest, protected void doGet(HttpServletRequest request, HttpServletResponse response)
HttpServletResponse httpServletResponse) throws ServletException, IOException { throws ServletException, IOException {
httpServletResponse.setContentType("text/plain");
Writer writer = httpServletResponse.getWriter();
writer.write(className + "\n");
try { try {
List<S3Bucket.Metadata> myBuckets = context.getConnection().listOwnedBuckets().get(10, List<S3Bucket.Metadata> myBucketMetadata = context.getConnection().listOwnedBuckets().get(
TimeUnit.SECONDS); 25, TimeUnit.SECONDS);
writer.write("List:\n"); List<S3Bucket> myBuckets = new ArrayList<S3Bucket>();
for (S3Bucket.Metadata bucket : myBuckets) { for (S3Bucket.Metadata metadata : myBucketMetadata) {
writer.write(String.format(" %1$s", bucket)); S3Bucket bucket = context.getConnection().listBucket(metadata.getName()).get(10,
try { TimeUnit.SECONDS);
writer.write(String.format(": %1$s entries%n", context.createInputStreamMap( myBuckets.add(bucket);
bucket.getName()).size()));
} catch (AWSResponseException e) {
String message = String.format(": unable to list entries due to: %1$s%n", e
.getError().getCode());
writer.write(message);
logger.warn(e, "message");
}
} }
request.setAttribute("buckets", myBuckets);
request.setAttribute("className", className);
String nextJSP = "/WEB-INF/jsp/buckets.jsp";
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);
dispatcher.forward(request, response);
} catch (Exception e) { } catch (Exception e) {
throw new ServletException(e); throw new ServletException(e);
} }
writer.flush();
writer.close();
} }
} }

View File

@ -0,0 +1,39 @@
<%--
Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
====================================================================
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.
====================================================================
--%>
<%@ page buffer="20kb"%>
<%@ taglib uri="http://displaytag.sf.net" prefix="display"%>
<html>
<head>
<title>jclouds: anyweight cloudware for java</title>
</head>
<body>
<h2>Bucket List</h2>
<display:table name="buckets">
<display:column property="name" title="Bucket" />
<display:column property="size" title="Size" />
</display:table>
</body>
</html>

View File

@ -1,48 +1,51 @@
<!--
<!--
Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com> Copyright (C) 2009 Global Cloud Specialists, Inc.
<info@globalcloudspecialists.com>
==================================================================== ====================================================================
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one or more
or more contributor license agreements. See the NOTICE file contributor license agreements. See the NOTICE file distributed with
distributed with this work for additional information this work for additional information regarding copyright ownership.
regarding copyright ownership. The ASF licenses this file The ASF licenses this file to you under the Apache License, Version
to you under the Apache License, Version 2.0 (the 2.0 (the "License"); you may not use this file except in compliance
"License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed under the
Unless required by applicable law or agreed to in writing, License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
software distributed under the License is distributed on an CONDITIONS OF ANY KIND, either express or implied. See the License for
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY the specific language governing permissions and limitations under the
KIND, either express or implied. See the License for the License.
specific language governing permissions and limitations ====================================================================
under the License. -->
====================================================================
-->
<!DOCTYPE web-app PUBLIC <!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd"> "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"> <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<display-name>jclouds-s3-example</display-name> <display-name>jclouds-s3-example</display-name>
<!-- Servlets --> <!-- Servlets -->
<filter> <filter>
<filter-name>guiceFilter</filter-name> <filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter> </filter>
<filter-mapping> <filter-mapping>
<filter-name>guiceFilter</filter-name> <filter-name>guiceFilter</filter-name>
<url-pattern>/guice/*</url-pattern> <url-pattern>/guice/*</url-pattern>
</filter-mapping> </filter-mapping>
<listener> <listener>
<listener-class>org.jclouds.samples.googleappengine.config.GuiceServletConfig</listener-class> <listener-class>org.jclouds.samples.googleappengine.config.GuiceServletConfig</listener-class>
</listener> </listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app> </web-app>

View File

@ -24,7 +24,13 @@
--%> --%>
<html> <html>
<head>
<title>jclouds: anyweight cloudware for java</title>
</head>
<body> <body>
<h2>Hello World!</h2> <h2>Welcome!</h2>
Click
<a href="/guice/listbuckets.s3">here</a>
to list my buckets.
</body> </body>
</html> </html>

View File

@ -81,7 +81,7 @@ public class GoogleAppEngineLiveTest {
public void shouldPass() throws InterruptedException, IOException { public void shouldPass() throws InterruptedException, IOException {
InputStream i = url.openStream(); InputStream i = url.openStream();
String string = IOUtils.toString(i); String string = IOUtils.toString(i);
assert string.indexOf("Hello World!") >= 0 : string; assert string.indexOf("Welcome") >= 0 : string;
} }
@Test(invocationCount = 5, enabled = true) @Test(invocationCount = 5, enabled = true)