From 9e3341bfc7d4b59e863228339b644aabd3011aa9 Mon Sep 17 00:00:00 2001 From: "adrian.f.cole" Date: Fri, 1 May 2009 19:40:36 +0000 Subject: [PATCH] Issue 7: Map git-svn-id: http://jclouds.googlecode.com/svn/trunk@139 3d8758e0-26b5-11de-8745-db77d3ebf521 --- .../aws/s3/nio/NioS3InputStreamMapTest.java | 61 +++ .../aws/s3/nio/NioS3ObjectMapTest.java | 4 +- .../org/jclouds/aws/s3/S3InputStreamMap.java | 43 +++ .../main/java/org/jclouds/aws/s3/S3Map.java | 32 ++ .../java/org/jclouds/aws/s3/S3ObjectMap.java | 24 +- .../jclouds/aws/s3/internal/BaseS3Map.java | 217 +++++++++++ .../aws/s3/internal/LiveS3InputStreamMap.java | 251 ++++++++++++ .../aws/s3/internal/LiveS3ObjectMap.java | 364 ++---------------- .../org/jclouds/aws/s3/BaseS3MapTest.java | 156 ++++++++ .../jclouds/aws/s3/S3InputStreamMapTest.java | 213 ++++++++++ .../org/jclouds/aws/s3/S3ObjectMapTest.java | 312 ++++----------- 11 files changed, 1089 insertions(+), 588 deletions(-) create mode 100644 extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3InputStreamMapTest.java create mode 100644 s3/src/main/java/org/jclouds/aws/s3/S3InputStreamMap.java create mode 100644 s3/src/main/java/org/jclouds/aws/s3/S3Map.java create mode 100644 s3/src/main/java/org/jclouds/aws/s3/internal/BaseS3Map.java create mode 100644 s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3InputStreamMap.java create mode 100644 s3/src/test/java/org/jclouds/aws/s3/BaseS3MapTest.java create mode 100644 s3/src/test/java/org/jclouds/aws/s3/S3InputStreamMapTest.java diff --git a/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3InputStreamMapTest.java b/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3InputStreamMapTest.java new file mode 100644 index 0000000000..d596475b65 --- /dev/null +++ b/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3InputStreamMapTest.java @@ -0,0 +1,61 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.nio; + +import java.util.Properties; + +import org.jclouds.aws.s3.S3InputStreamMapTest; +import org.jclouds.aws.s3.nio.config.S3HttpNioConnectionPoolClientModule; +import org.testng.annotations.Test; + +import com.google.inject.Module; + +/** + * // TODO: Adrian: Document this! + * + * @author Adrian Cole + */ +@Test(groups = "unit", sequential = true, testName = "s3.NioS3InputStreamMapTest") +public class NioS3InputStreamMapTest extends S3InputStreamMapTest { + + @Override + protected Properties buildS3Properties(String AWSAccessKeyId, + String AWSSecretAccessKey) { + Properties properties = super.buildS3Properties(AWSAccessKeyId, + AWSSecretAccessKey); + properties.setProperty("jclouds.http.pool.max_connection_reuse", "75"); + properties.setProperty("jclouds.http.pool.max_session_failures", "2"); + properties + .setProperty("jclouds.http.pool.request_invoker_threads", "1"); + properties.setProperty("jclouds.http.pool.io_worker_threads", "2"); + properties.setProperty("jclouds.pool.max_connections", "12"); + return properties; + } + + @Override + protected Module createHttpModule() { + return new S3HttpNioConnectionPoolClientModule(); + } + +} diff --git a/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3ObjectMapTest.java b/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3ObjectMapTest.java index edebe44425..c9ca16a8df 100644 --- a/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3ObjectMapTest.java +++ b/extensions/s3nio/src/test/java/org/jclouds/aws/s3/nio/NioS3ObjectMapTest.java @@ -36,9 +36,9 @@ import com.google.inject.Module; * * @author Adrian Cole */ -@Test(groups = "unit", sequential = true, testName = "s3.S3ObjectMapTest") +@Test(groups = "unit", sequential = true, testName = "s3.NioS3ObjectMapTest") public class NioS3ObjectMapTest extends S3ObjectMapTest { - + @Override protected Properties buildS3Properties(String AWSAccessKeyId, String AWSSecretAccessKey) { diff --git a/s3/src/main/java/org/jclouds/aws/s3/S3InputStreamMap.java b/s3/src/main/java/org/jclouds/aws/s3/S3InputStreamMap.java new file mode 100644 index 0000000000..a2dd8afecc --- /dev/null +++ b/s3/src/main/java/org/jclouds/aws/s3/S3InputStreamMap.java @@ -0,0 +1,43 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.s3; + +import java.io.File; +import java.io.InputStream; +import java.util.Map; + +public interface S3InputStreamMap extends Map, S3Map { + InputStream putString(String key, String value); + + InputStream putFile(String key, File value); + + InputStream putBytes(String key, byte[] value); + + void putAllStrings(Map map); + + void putAllBytes(Map map); + + void putAllFiles(Map map); + +} \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/S3Map.java b/s3/src/main/java/org/jclouds/aws/s3/S3Map.java new file mode 100644 index 0000000000..740022cd28 --- /dev/null +++ b/s3/src/main/java/org/jclouds/aws/s3/S3Map.java @@ -0,0 +1,32 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.s3; + +import org.jclouds.aws.s3.domain.S3Bucket; + +public interface S3Map { + + S3Bucket getBucket(); + +} \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/S3ObjectMap.java b/s3/src/main/java/org/jclouds/aws/s3/S3ObjectMap.java index 529ba95e05..7ebe7bb2b1 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/S3ObjectMap.java +++ b/s3/src/main/java/org/jclouds/aws/s3/S3ObjectMap.java @@ -23,32 +23,10 @@ */ package org.jclouds.aws.s3; -import java.io.File; -import java.io.InputStream; import java.util.Map; -import java.util.Set; -import org.jclouds.aws.s3.domain.S3Bucket; import org.jclouds.aws.s3.domain.S3Object; -public interface S3ObjectMap extends Map { - - InputStream putString(String key, String value); - - InputStream putFile(String key, File value); - - InputStream putBytes(String key, byte[] value); - - void putAllStrings(Map map); - - void putAllBytes(Map map); - - void putAllFiles(Map map); - - InputStream put(S3Object object); - - void putAll(Set objects); - - S3Bucket getBucket(); +public interface S3ObjectMap extends Map, S3Map { } \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/internal/BaseS3Map.java b/s3/src/main/java/org/jclouds/aws/s3/internal/BaseS3Map.java new file mode 100644 index 0000000000..2e1d05bc0e --- /dev/null +++ b/s3/src/main/java/org/jclouds/aws/s3/internal/BaseS3Map.java @@ -0,0 +1,217 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.jclouds.Utils; +import org.jclouds.aws.s3.S3Connection; +import org.jclouds.aws.s3.S3Map; +import org.jclouds.aws.s3.S3Utils; +import org.jclouds.aws.s3.domain.S3Bucket; +import org.jclouds.aws.s3.domain.S3Object; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + +public abstract class BaseS3Map implements Map, S3Map { + + protected final S3Connection connection; + protected final S3Bucket bucket; + + @Inject + public BaseS3Map(S3Connection connection, @Assisted S3Bucket bucket) { + this.connection = checkNotNull(connection, "connection"); + this.bucket = checkNotNull(bucket, "bucket"); + } + + public int size() { + try { + S3Bucket bucket = refreshBucket(); + Set contents = bucket.getContents(); + return contents.size(); + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException("Error getting size of bucket" + + bucket, e); + } + } + + protected boolean containsETag(String eTagOfValue) + throws InterruptedException, ExecutionException { + for (S3Object object : refreshBucket().getContents()) { + if (object.getETag().equals(eTagOfValue)) + return true; + } + return false; + } + + protected byte[] getMd5(Object value) throws IOException, + FileNotFoundException, InterruptedException, ExecutionException { + byte[] md5; + + if (value instanceof InputStream) { + md5 = S3Utils.md5((InputStream) value); + } else if (value instanceof byte[]) { + md5 = S3Utils.md5((byte[]) value); + } else if (value instanceof String) { + md5 = S3Utils.md5(((String) value).getBytes()); + } else if (value instanceof File) { + md5 = S3Utils.md5(new FileInputStream((File) value)); + } else if (value instanceof S3Object) { + S3Object object = (S3Object) value; + object = connection.headObject(bucket, object.getKey()).get(); + if (S3Object.NOT_FOUND.equals(object)) + throw new FileNotFoundException("not found: " + object.getKey()); + md5 = S3Utils.fromHexString(object.getETag()); + } else { + throw new IllegalArgumentException("unsupported value type: " + + value.getClass()); + } + return md5; + } + + protected Set getAllObjects() { + Set objects = new HashSet(); + Set> futureObjects = new HashSet>(); + for (String key : keySet()) { + futureObjects.add(connection.getObject(bucket, key)); + } + for (Future futureObject : futureObjects) { + S3Object object = null; + try { + object = futureObject.get(); + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error getting value from bucket %1s:%2s", bucket, + object != null ? object.getKey() : "unknown"), e); + } + objects.add(object); + } + return objects; + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMapi#containsValue(java.lang.Object) + */ + public boolean containsValue(Object value) { + + try { + byte[] md5 = getMd5(value); + String eTagOfValue = S3Utils.toHexString(md5); + return containsETag(eTagOfValue); + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error searching for ETAG of value: [%2s] in bucket:%1s", + bucket, value), e); + } + } + + public static class S3RuntimeException extends RuntimeException { + private static final long serialVersionUID = 1L; + + S3RuntimeException(String s) { + super(s); + } + + public S3RuntimeException(String s, Throwable throwable) { + super(s, throwable); + } + } + + public void clear() { + try { + List> deletes = new ArrayList>(); + for (String key : keySet()) { + deletes.add(connection.deleteObject(bucket, key)); + } + for (Future isdeleted : deletes) + if (!isdeleted.get()) { + throw new S3RuntimeException("failed to delete entry"); + } + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException("Error clearing bucket" + bucket, e); + } + } + + protected S3Bucket refreshBucket() throws InterruptedException, + ExecutionException { + S3Bucket currentBucket = connection.getBucket(bucket).get(); + if (currentBucket == S3Bucket.NOT_FOUND) + throw new S3RuntimeException("bucket not found: " + + bucket.getName()); + else + return currentBucket; + } + + public Set keySet() { + try { + Set keys = new HashSet(); + for (S3Object object : refreshBucket().getContents()) + keys.add(object.getKey()); + return keys; + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException("Error getting keys in bucket: " + + bucket, e); + } + } + + public boolean containsKey(Object key) { + try { + return connection.headObject(bucket, key.toString()).get() != S3Object.NOT_FOUND; + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error searching for %1s:%2s", bucket, key), e); + } + } + + public boolean isEmpty() { + return keySet().size() == 0; + } + + public S3Bucket getBucket() { + return bucket; + } + +} \ No newline at end of file diff --git a/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3InputStreamMap.java b/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3InputStreamMap.java new file mode 100644 index 0000000000..d5a18361da --- /dev/null +++ b/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3InputStreamMap.java @@ -0,0 +1,251 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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.internal; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Future; + +import org.apache.commons.io.IOUtils; +import org.jclouds.Utils; +import org.jclouds.aws.s3.S3Connection; +import org.jclouds.aws.s3.S3InputStreamMap; +import org.jclouds.aws.s3.domain.S3Bucket; +import org.jclouds.aws.s3.domain.S3Object; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + +/** + * Map representation of a live connection to S3. + * + * @author Adrian Cole + */ +public class LiveS3InputStreamMap extends BaseS3Map implements + S3InputStreamMap { + + @Inject + public LiveS3InputStreamMap(S3Connection connection, + @Assisted S3Bucket bucket) { + super(connection, bucket); + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMapi#get(java.lang.Object) + */ + public InputStream get(Object o) { + try { + return (InputStream) (connection.getObject(bucket, o.toString()) + .get()).getContent(); + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error geting object %1s:%2s", bucket, o), e); + } + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMapi#remove(java.lang.Object) + */ + public InputStream remove(Object o) { + InputStream old = get(o); + try { + connection.deleteObject(bucket, o.toString()).get(); + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error removing object %1s:%2s", bucket, o), e); + } + return old; + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMapi#values() + */ + public Collection values() { + Collection values = new LinkedList(); + Set objects = getAllObjects(); + for (S3Object object : objects) { + values.add((InputStream) object.getContent()); + } + return values; + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMapi#entrySet() + */ + public Set> entrySet() { + Set> entrySet = new HashSet>(); + for (String key : keySet()) { + Map.Entry entry = new Entry(key, get(key)); + entrySet.add(entry); + } + return entrySet; + } + + public class Entry implements java.util.Map.Entry { + + private InputStream value; + private String key; + + Entry(String key, InputStream value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public InputStream getValue() { + return value; + } + + public InputStream setValue(InputStream value) { + return put(key, value); + } + + } + + private InputStream putInternal(String s, Object o) { + S3Object object = new S3Object(s); + try { + InputStream returnVal = containsKey(s) ? get(s) : null; + object.setContent(o); + setSizeIfContentIsInputStream(object); + connection.addObject(bucket, object).get(); + return returnVal; + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error adding object %1s:%2s", bucket, object), e); + } + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMap#putAll(java.util.Map) + */ + public void putAll(Map map) { + putAllInternal(map); + } + + public void putAllBytes(Map map) { + putAllInternal(map); + } + + public void putAllFiles(Map map) { + putAllInternal(map); + } + + public void putAllStrings(Map map) { + putAllInternal(map); + } + + private void putAllInternal(Map map) { + try { + List> puts = new ArrayList>(); + for (String key : map.keySet()) { + S3Object object = new S3Object(key); + object.setContent(map.get(key)); + setSizeIfContentIsInputStream(object); + puts.add(connection.addObject(bucket, object)); + } + for (Future put : puts) + put.get();// this will throw an exception if there was a problem + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException("Error putting into bucket" + bucket, + e); + } + } + + private void setSizeIfContentIsInputStream(S3Object object) + throws IOException { + if (object.getContent() instanceof InputStream) { + byte[] buffer = IOUtils.toByteArray((InputStream) object + .getContent()); + object.setSize(buffer.length); + object.setContent(new ByteArrayInputStream(buffer)); + } + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMap#putString(java.lang.String, + * java.lang.String) + */ + public InputStream putString(String key, String value) { + return putInternal(key, value); + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMap#putFile(java.lang.String, + * java.io.File) + */ + public InputStream putFile(String key, File value) { + return putInternal(key, value); + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMap#putBytes(java.lang.String, byte[]) + */ + public InputStream putBytes(String key, byte[] value) { + return putInternal(key, value); + } + + /* + * (non-Javadoc) + * + * @see org.jclouds.aws.s3.S3ObjectMap#put(java.lang.String, + * java.io.InputStream) + */ + public InputStream put(String key, InputStream value) { + return putInternal(key, value); + } + +} diff --git a/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3ObjectMap.java b/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3ObjectMap.java index 59cc90aaf1..277c65dac4 100644 --- a/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3ObjectMap.java +++ b/s3/src/main/java/org/jclouds/aws/s3/internal/LiveS3ObjectMap.java @@ -23,26 +23,17 @@ */ package org.jclouds.aws.s3.internal; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import org.apache.commons.io.IOUtils; import org.jclouds.Utils; import org.jclouds.aws.s3.S3Connection; import org.jclouds.aws.s3.S3ObjectMap; -import org.jclouds.aws.s3.S3Utils; import org.jclouds.aws.s3.domain.S3Bucket; import org.jclouds.aws.s3.domain.S3Object; @@ -54,166 +45,28 @@ import com.google.inject.assistedinject.Assisted; * * @author Adrian Cole */ -public class LiveS3ObjectMap implements S3ObjectMap { - - private final S3Connection connection; - private final S3Bucket bucket; +public class LiveS3ObjectMap extends BaseS3Map implements S3ObjectMap { @Inject public LiveS3ObjectMap(S3Connection connection, @Assisted S3Bucket bucket) { - this.connection = connection; - this.bucket = bucket; + super(connection, bucket); } - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#size() - */ - public int size() { - try { - return refreshBucket().getContents().size(); - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException("Error clearing bucket" + bucket, e); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#get(java.lang.Object) - */ - public InputStream get(Object o) { - try { - return (InputStream) (connection.getObject(bucket, o.toString()) - .get()).getContent(); - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException(String.format( - "Error geting object %1s:%2s", bucket, o), e); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#remove(java.lang.Object) - */ - public InputStream remove(Object o) { - InputStream old = get(o); - try { - connection.deleteObject(bucket, o.toString()).get(); - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException(String.format( - "Error removing object %1s:%2s", bucket, o), e); - } - return old; - } - - public class S3RuntimeException extends RuntimeException { - S3RuntimeException(String s) { - super(s); - } - - public S3RuntimeException(String s, Throwable throwable) { - super(s, throwable); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#clear() - */ - public void clear() { - try { - List> deletes = new ArrayList>(); - for (String key : keySet()) { - deletes.add(connection.deleteObject(bucket, key)); - } - for (Future isdeleted : deletes) - if (!isdeleted.get()) { - throw new S3RuntimeException("failed to delete entry"); - } - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException("Error clearing bucket" + bucket, e); - } - } - - private S3Bucket refreshBucket() throws InterruptedException, - ExecutionException { - return connection.getBucket(bucket).get(); - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#keySet() - */ - public Set keySet() { - try { - Set keys = new HashSet(); - for (S3Object object : refreshBucket().getContents()) - keys.add(object.getKey()); - return keys; - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException("Error getting keys in bucket: " - + bucket, e); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#values() - */ - public Collection values() { - Collection values = new LinkedList(); - Set> futureObjects = new HashSet>(); - for (String key : keySet()) { - futureObjects.add(connection.getObject(bucket, key)); - } - for (Future futureObject : futureObjects) { - S3Object object = null; - try { - object = futureObject.get(); - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException(String.format( - "Error getting value from bucket %1s:%2s", bucket, - object != null ? object.getKey() : "unknown"), e); - } - System.err.printf("key: %1s, MD5: %2s", object.getKey(), object - .getContentMD5()); - values.add((InputStream) object.getContent()); - } - return values; - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#entrySet() - */ - public Set> entrySet() { - Set> entrySet = new HashSet>(); - for (String key : keySet()) { - Map.Entry entry = new Entry(key, get(key)); + public Set> entrySet() { + Set> entrySet = new HashSet>(); + for (S3Object value : values()) { + Map.Entry entry = new Entry(value.getKey(), value); entrySet.add(entry); } return entrySet; } - public class Entry implements java.util.Map.Entry { + public class Entry implements java.util.Map.Entry { - private InputStream value; + private S3Object value; private String key; - Entry(String key, InputStream value) { + Entry(String key, S3Object value) { this.key = key; this.value = value; } @@ -222,203 +75,42 @@ public class LiveS3ObjectMap implements S3ObjectMap { return key; } - public InputStream getValue() { + public S3Object getValue() { return value; } - public InputStream setValue(InputStream value) { + public S3Object setValue(S3Object value) { return put(key, value); } } - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#containsKey(java.lang.Object) - */ - public boolean containsKey(Object key) { + public S3Object get(Object key) { try { - return connection.headObject(bucket, key.toString()).get() != S3Object.NOT_FOUND; + return connection.getObject(bucket, key.toString()).get(); } catch (Exception e) { Utils. rethrowIfRuntimeOrSameType(e); throw new S3RuntimeException(String.format( - "Error searching for %1s:%2s", bucket, key), e); + "Error geting object %1s:%2s", bucket, key), e); } } - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#containsValue(java.lang.Object) - */ - public boolean containsValue(Object value) { - + public S3Object put(String key, S3Object value) { + S3Object returnVal = get(key); try { - byte[] md5; - - if (value instanceof InputStream) { - md5 = S3Utils.md5((InputStream) value); - } else if (value instanceof byte[]) { - md5 = S3Utils.md5((byte[]) value); - } else if (value instanceof String) { - md5 = S3Utils.md5(((String) value).getBytes()); - } else if (value instanceof File) { - md5 = S3Utils.md5(new FileInputStream((File) value)); - } else { - throw new IllegalArgumentException("unsupported value type: " - + value.getClass()); - } - String eTagOfValue = S3Utils.getHexString(md5); - - for (S3Object object : refreshBucket().getContents()) { - if (object.getETag().equals(eTagOfValue)) - return true; - } - return false; + connection.addObject(bucket, value).get(); } catch (Exception e) { Utils. rethrowIfRuntimeOrSameType(e); throw new S3RuntimeException(String.format( - "Error searching for ETAG of value: [%2s] in bucket:%1s", - bucket, value), e); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMapi#isEmpty() - */ - public boolean isEmpty() { - return keySet().size() == 0; - } - - private InputStream putInternal(String s, Object o) { - S3Object object = new S3Object(); - try { - - InputStream returnVal = containsKey(s) ? get(s) : null; - object.setKey(s); - object.setContent(o); - setSizeIfContentIsInputStream(object); - connection.addObject(bucket, object).get(); - return returnVal; - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException(String.format( - "Error adding object %1s:%2s", bucket, object), e); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMap#putAll(java.util.Map) - */ - public void putAll(Map map) { - putAllInternal(map); - } - - public void putAllBytes(Map map) { - putAllInternal(map); - } - - public void putAllFiles(Map map) { - putAllInternal(map); - } - - public void putAllStrings(Map map) { - putAllInternal(map); - } - - private void putAllInternal(Map map) { - try { - List> puts = new ArrayList>(); - for (String key : map.keySet()) { - S3Object object = new S3Object(); - object.setKey(key); - object.setContent(map.get(key)); - setSizeIfContentIsInputStream(object); - puts.add(connection.addObject(bucket, object)); - } - for (Future put : puts) - put.get();// this will throw an exception if there was a problem - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException("Error putting into bucket" + bucket, - e); - } - } - - private void setSizeIfContentIsInputStream(S3Object object) - throws IOException { - if (object.getContent() instanceof InputStream) { - byte[] buffer = IOUtils.toByteArray((InputStream) object - .getContent()); - object.setSize(buffer.length); - object.setContent(new ByteArrayInputStream(buffer)); - } - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMap#putString(java.lang.String, - * java.lang.String) - */ - public InputStream putString(String key, String value) { - return putInternal(key, value); - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMap#putFile(java.lang.String, - * java.io.File) - */ - public InputStream putFile(String key, File value) { - return putInternal(key, value); - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMap#putBytes(java.lang.String, byte[]) - */ - public InputStream putBytes(String key, byte[] value) { - return putInternal(key, value); - } - - /* - * (non-Javadoc) - * - * @see org.jclouds.aws.s3.S3ObjectMap#put(java.lang.String, - * java.io.InputStream) - */ - public InputStream put(String key, InputStream value) { - return putInternal(key, value); - } - - public S3Bucket getBucket() { - return bucket; - } - - public InputStream put(S3Object object) { - InputStream returnVal = get(object.getKey()); - try { - connection.addObject(bucket, object).get(); - } catch (Exception e) { - Utils. rethrowIfRuntimeOrSameType(e); - throw new S3RuntimeException(String.format( - "Error putting object %1s:%2s", bucket, object.getKey()), e); + "Error putting object %1s:%2s%n%1s", bucket, key, value), e); } return returnVal; } - public void putAll(Set objects) { + public void putAll(Map map) { try { List> puts = new ArrayList>(); - for (S3Object object : objects) { + for (S3Object object : map.values()) { puts.add(connection.addObject(bucket, object)); } for (Future put : puts) @@ -430,4 +122,20 @@ public class LiveS3ObjectMap implements S3ObjectMap { } } + public S3Object remove(Object key) { + S3Object old = get(key); + try { + connection.deleteObject(bucket, key.toString()).get(); + } catch (Exception e) { + Utils. rethrowIfRuntimeOrSameType(e); + throw new S3RuntimeException(String.format( + "Error removing object %1s:%2s", bucket, key), e); + } + return old; + } + + public Collection values() { + return getAllObjects(); + } + } diff --git a/s3/src/test/java/org/jclouds/aws/s3/BaseS3MapTest.java b/s3/src/test/java/org/jclouds/aws/s3/BaseS3MapTest.java new file mode 100644 index 0000000000..4f298010b6 --- /dev/null +++ b/s3/src/test/java/org/jclouds/aws/s3/BaseS3MapTest.java @@ -0,0 +1,156 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.s3; + +import static org.testng.Assert.assertEquals; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.TreeSet; +import java.util.concurrent.ExecutionException; + +import org.apache.commons.io.IOUtils; +import org.jclouds.aws.s3.domain.S3Bucket; +import org.jclouds.aws.s3.internal.BaseS3Map; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +public abstract class BaseS3MapTest extends S3IntegrationTest { + + private S3Bucket bucket; + + public abstract void testPutAll(); + + public abstract void testEntrySet() throws IOException; + + public abstract void testValues() throws IOException; + + protected BaseS3Map map; + protected Map fiveStrings = ImmutableMap.of("one", "apple", + "two", "bear", "three", "candy", "four", "dogma", "five", "emma"); + protected Map fiveBytes = ImmutableMap.of("one", "apple" + .getBytes(), "two", "bear".getBytes(), "three", "candy".getBytes(), + "four", "dogma".getBytes(), "five", "emma".getBytes()); + protected Map fiveInputs; + protected Map fiveFiles; + String tmpDirectory; + + @BeforeMethod + @Parameters( { "basedir" }) + protected void setUpTempDir(String basedir) throws InterruptedException, + ExecutionException, FileNotFoundException, IOException { + tmpDirectory = basedir + File.separator + "target" + File.separator + + "testFiles" + File.separator + getClass().getSimpleName(); + new File(tmpDirectory).mkdirs(); + + fiveFiles = ImmutableMap.of("one", new File(tmpDirectory, "apple"), + "two", new File(tmpDirectory, "bear"), "three", new File( + tmpDirectory, "candy"), "four", new File(tmpDirectory, + "dogma"), "five", new File(tmpDirectory, "emma")); + + for (File file : fiveFiles.values()) { + IOUtils.write(file.getName(), new FileOutputStream(file)); + } + + fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"), + "two", IOUtils.toInputStream("bear"), "three", IOUtils + .toInputStream("candy"), "four", IOUtils + .toInputStream("dogma"), "five", IOUtils + .toInputStream("emma")); + bucket = new S3Bucket(bucketPrefix + ".mimi"); + client.createBucketIfNotExists(bucket).get(); + map = createMap(context, bucket); + map.clear(); + } + + protected abstract BaseS3Map createMap(S3Context context, S3Bucket bucket); + + @AfterMethod + public void tearDown() { + map.clear(); + map = null; + bucket = null; + } + + @Test + public void testClear() { + map.clear(); + assertEquals(map.size(),0); + putString("one", "apple"); + assertEquals(map.size(),1); + map.clear(); + assertEquals(map.size(),0); + } + + @Test() + public abstract void testRemove() throws IOException; + + @Test() + public void testKeySet() { + assertEquals(map.keySet().size(), 0); + putString("one", "two"); + assertEquals(map.keySet(), ImmutableSet.of("one")); + } + + @Test() + public void testContainsKey() { + assert !map.containsKey("one"); + putString("one", "apple"); + assert map.containsKey("one"); + } + + @Test() + public void testIsEmpty() { + assert map.isEmpty(); + putString("one", "apple"); + assert !map.isEmpty(); + } + + abstract protected void putString(String key, String value); + + protected void fourLeftRemovingOne() { + map.remove("one"); + assertEquals(map.size(), 4); + assertEquals(new TreeSet(map.keySet()), new TreeSet( + ImmutableSet.of("two", "three", "four", "five"))); + } + + @Test + public abstract void testPut() throws IOException; + + @Test() + public void testGetBucket() { + assertEquals(map.getBucket().getName(), bucket.getName()); + } + +} \ No newline at end of file diff --git a/s3/src/test/java/org/jclouds/aws/s3/S3InputStreamMapTest.java b/s3/src/test/java/org/jclouds/aws/s3/S3InputStreamMapTest.java new file mode 100644 index 0000000000..fe0fd0b7fd --- /dev/null +++ b/s3/src/test/java/org/jclouds/aws/s3/S3InputStreamMapTest.java @@ -0,0 +1,213 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.s3; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; +import java.util.Map.Entry; + +import org.apache.commons.io.IOUtils; +import org.jclouds.Utils; +import org.jclouds.aws.s3.domain.S3Bucket; +import org.jclouds.aws.s3.internal.BaseS3Map; +import org.testng.annotations.Test; + +/** + * Tests to cover @{link LiveS3ObjectMap} + * + * @author Adrian Cole + */ +@Test(groups = "unit", sequential = true, testName = "s3.S3InputStreamMapTest") +public class S3InputStreamMapTest extends BaseS3MapTest { + S3InputStreamMap map = null; + + @SuppressWarnings("unchecked") + protected BaseS3Map createMap(S3Context context, + S3Bucket bucket) { + map = context.createS3InputStreamMap(bucket); + return (BaseS3Map) map; + } + + @Override + @Test() + public void testValues() throws IOException { + map.putAll(this.fiveInputs); + Collection values = map.values(); + assertEquals(values.size(), 5); + Set valuesAsString = new HashSet(); + for (InputStream stream : values) { + valuesAsString.add(Utils.toStringAndClose(stream)); + } + valuesAsString.removeAll(fiveStrings.values()); + assert valuesAsString.size() == 0; + } + + @Test() + public void testRemove() throws IOException { + putString("one", "two"); + InputStream old = map.remove("one"); + assertEquals(Utils.toStringAndClose(old), "two"); + old = map.remove("one"); + assert old == null; + old = map.get("one"); + assert old == null; + assertEquals(map.keySet().size(), 0); + } + + @Override + @Test() + public void testEntrySet() throws IOException { + map.putAllStrings(this.fiveStrings); + Set> entries = map.entrySet(); + assertEquals(entries.size(), 5); + for (Entry entry : entries) { + assertEquals(IOUtils.toString(entry.getValue()), fiveStrings + .get(entry.getKey())); + entry.setValue(IOUtils.toInputStream("")); + } + assertEquals(map.size(), 5); + for (InputStream value : map.values()) { + assertEquals(IOUtils.toString(value), ""); + } + } + + @Test() + public void testContainsStringValue() { + map.putString("one", "apple"); + assert map.containsValue(fiveStrings.get("one")); + } + + @Test() + public void testContainsFileValue() { + map.putString("one", "apple"); + assert map.containsValue(fiveFiles.get("one")); + } + + @Test() + public void testContainsInputStreamValue() { + map.putString("one", "apple"); + assert map.containsValue(this.fiveInputs.get("one")); + } + + @Test() + public void testContainsBytesValue() { + map.putString("one", "apple"); + assert map.containsValue(this.fiveBytes.get("one")); + } + + @Override + @Test() + public void testPutAll() { + map.putAll(this.fiveInputs); + assertEquals(map.size(), 5); + assertEquals(new TreeSet(map.keySet()), new TreeSet( + fiveInputs.keySet())); + fourLeftRemovingOne(); + } + + @Test() + public void testPutAllBytes() { + map.putAllBytes(this.fiveBytes); + assertEquals(map.size(), 5); + assertEquals(new TreeSet(map.keySet()), new TreeSet( + fiveBytes.keySet())); + fourLeftRemovingOne(); + } + + @Test + public void testPutAllFiles() { + map.putAllFiles(this.fiveFiles); + assertEquals(map.size(), 5); + assertEquals(new TreeSet(map.keySet()), new TreeSet( + fiveFiles.keySet())); + fourLeftRemovingOne(); + } + + @Test() + public void testPutAllStrings() { + map.putAllStrings(this.fiveStrings); + assertEquals(map.size(), 5); + assertEquals(new TreeSet(map.keySet()), new TreeSet( + fiveStrings.keySet())); + fourLeftRemovingOne(); + } + + @Test() + public void testPutString() throws IOException { + InputStream old = map.putString("one", "apple"); + getOneReturnsAppleAndOldValueIsNull(old); + InputStream apple = map.putString("one", "bear"); + getOneReturnsBearAndOldValueIsApple(apple); + } + + void getOneReturnsAppleAndOldValueIsNull(InputStream old) + throws IOException { + assert old == null; + assertEquals(Utils.toStringAndClose(map.get("one")), "apple"); + assertEquals(map.size(), 1); + } + + void getOneReturnsBearAndOldValueIsApple(InputStream oldValue) + throws IOException { + assertEquals(Utils.toStringAndClose(map.get("one")), "bear"); + assertEquals(Utils.toStringAndClose(oldValue), "apple"); + assertEquals(map.size(), 1); + } + + @Test() + public void testPutFile() throws IOException { + InputStream old = map.putFile("one", fiveFiles.get("one")); + getOneReturnsAppleAndOldValueIsNull(old); + InputStream apple = map.putFile("one", fiveFiles.get("two")); + getOneReturnsBearAndOldValueIsApple(apple); + } + + @Test() + public void testPutBytes() throws IOException { + InputStream old = map.putBytes("one", "apple".getBytes()); + getOneReturnsAppleAndOldValueIsNull(old); + InputStream apple = map.putBytes("one", "bear".getBytes()); + getOneReturnsBearAndOldValueIsApple(apple); + } + + @Test() + public void testPut() throws IOException { + InputStream old = map.put("one", IOUtils.toInputStream("apple")); + getOneReturnsAppleAndOldValueIsNull(old); + InputStream apple = map.put("one", IOUtils.toInputStream("bear")); + getOneReturnsBearAndOldValueIsApple(apple); + } + + @Override + protected void putString(String key, String value) { + map.putString(key, value); + } + +} diff --git a/s3/src/test/java/org/jclouds/aws/s3/S3ObjectMapTest.java b/s3/src/test/java/org/jclouds/aws/s3/S3ObjectMapTest.java index 259c38d6e6..012f1df938 100644 --- a/s3/src/test/java/org/jclouds/aws/s3/S3ObjectMapTest.java +++ b/s3/src/test/java/org/jclouds/aws/s3/S3ObjectMapTest.java @@ -25,305 +25,147 @@ package org.jclouds.aws.s3; import static org.testng.Assert.assertEquals; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.Map.Entry; -import java.util.concurrent.ExecutionException; import org.apache.commons.io.IOUtils; -import org.jclouds.Utils; import org.jclouds.aws.s3.domain.S3Bucket; import org.jclouds.aws.s3.domain.S3Object; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Parameters; +import org.jclouds.aws.s3.internal.BaseS3Map; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - /** * Tests to cover @{link LiveS3ObjectMap} * * @author Adrian Cole */ @Test(groups = "unit", sequential = true, testName = "s3.S3ObjectMapTest") -public class S3ObjectMapTest extends S3IntegrationTest { +public class S3ObjectMapTest extends BaseS3MapTest { + S3ObjectMap map = null; - private S3Bucket bucket; - private S3ObjectMap map; - - private Map fiveStrings = ImmutableMap.of("one", "apple", - "two", "bear", "three", "candy", "four", "dogma", "five", "emma"); - private Map fiveBytes = ImmutableMap.of("one", "apple" - .getBytes(), "two", "bear".getBytes(), "three", "candy".getBytes(), - "four", "dogma".getBytes(), "five", "emma".getBytes()); - private Map fiveInputs; - private Map fiveFiles; - - String tmpDirectory; - - @BeforeMethod - @Parameters( { "basedir" }) - protected void setUpTempDir(String basedir) throws InterruptedException, - ExecutionException, FileNotFoundException, IOException { - tmpDirectory = basedir + File.separator + "target" + File.separator - + "testFiles" + File.separator + getClass().getSimpleName(); - new File(tmpDirectory).mkdirs(); - - fiveFiles = ImmutableMap.of("one", new File(tmpDirectory, "apple"), - "two", new File(tmpDirectory, "bear"), "three", new File( - tmpDirectory, "candy"), "four", new File(tmpDirectory, - "dogma"), "five", new File(tmpDirectory, "emma")); - - for (File file : fiveFiles.values()) { - IOUtils.write(file.getName(), new FileOutputStream(file)); - } - - fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"), - "two", IOUtils.toInputStream("bear"), "three", IOUtils - .toInputStream("candy"), "four", IOUtils - .toInputStream("dogma"), "five", IOUtils - .toInputStream("emma")); - bucket = new S3Bucket(); - bucket.setName(bucketPrefix + ".mimi"); - client.createBucketIfNotExists(bucket).get(); - map = context.createMapView(bucket); - map.clear(); - } - - @AfterMethod - public void tearDown() { - map.clear(); - map = null; - bucket = null; - } - - @Test - public void testClear() { - map.clear(); - assert map.size() == 0; - map.putString("one", "apple"); - map.clear(); - assert map.size() == 0; - } - - @Test() - public void testRemove() throws IOException { - map.putString("one", "two"); - InputStream old = map.remove("one"); - assertEquals(Utils.toStringAndClose(old), "two"); - old = map.remove("one"); - assert old == null; - old = map.get("one"); - assert old == null; - assertEquals(map.keySet().size(), 0); - } - - @Test() - public void testKeySet() { - assertEquals(map.keySet().size(), 0); - map.putString("one", "two"); - assertEquals(map.keySet(), ImmutableSet.of("one")); + @SuppressWarnings("unchecked") + protected BaseS3Map createMap(S3Context context, S3Bucket bucket) { + map = context.createS3ObjectMap(bucket); + return (BaseS3Map) map; } + @Override @Test() public void testValues() throws IOException { - map.putAll(this.fiveInputs); - Collection values = map.values(); + putFiveStrings(); + Collection values = map.values(); assertEquals(values.size(), 5); Set valuesAsString = new HashSet(); - for (InputStream stream : values) { - valuesAsString.add(Utils.toStringAndClose(stream)); + for (S3Object object : values) { + valuesAsString.add(S3Utils.getContentAsStringAndClose(object)); } valuesAsString.removeAll(fiveStrings.values()); assert valuesAsString.size() == 0; } + @Test() + public void testRemove() throws IOException { + putString("one", "two"); + S3Object old = map.remove("one"); + assertEquals(S3Utils.getContentAsStringAndClose(old), "two"); + old = map.remove("one"); + assert old == S3Object.NOT_FOUND; + old = map.get("one"); + assert old == S3Object.NOT_FOUND; + assertEquals(map.keySet().size(), 0); + } + + @Override @Test() public void testEntrySet() throws IOException { - map.putAllStrings(this.fiveStrings); - Set> entries = map.entrySet(); + putFiveStrings(); + Set> entries = map.entrySet(); assertEquals(entries.size(), 5); - for (Entry entry : entries) { - assertEquals(IOUtils.toString(entry.getValue()), fiveStrings - .get(entry.getKey())); - entry.setValue(IOUtils.toInputStream("")); + for (Entry entry : entries) { + assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()), + fiveStrings.get(entry.getKey())); + S3Object value = entry.getValue(); + value.setContent(""); + entry.setValue(value); } assertEquals(map.size(), 5); - for (InputStream value : map.values()) { - assertEquals(IOUtils.toString(value), ""); + for (S3Object value : map.values()) { + assertEquals(S3Utils.getContentAsStringAndClose(value), ""); } } @Test() - public void testContainsKey() { - assert !map.containsKey("one"); - map.putString("one", "apple"); - assert map.containsKey("one"); + public void testContains() { + putString("one", "apple"); + S3Object object = new S3Object("one"); + object.setContent("apple"); + assert map.containsValue(object); } - @Test() - public void testContainsStringValue() { - map.putString("one", "apple"); - assert map.containsValue(fiveStrings.get("one")); + void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException { + assert old == S3Object.NOT_FOUND; + assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), + "apple"); + assert map.size() == 1; } - @Test() - public void testContainsFileValue() { - map.putString("one", "apple"); - assert map.containsValue(fiveFiles.get("one")); - } - - @Test() - public void testContainsInputStreamValue() { - map.putString("one", "apple"); - assert map.containsValue(this.fiveInputs.get("one")); - } - - @Test() - public void testContainsBytesValue() { - map.putString("one", "apple"); - assert map.containsValue(this.fiveBytes.get("one")); - } - - @Test() - public void testIsEmpty() { - assert map.isEmpty(); - map.putString("one", "apple"); - assert !map.isEmpty(); - } - - @Test() - public void testPutAll() { - map.putAll(this.fiveInputs); - assertEquals(map.size(), 5); - assertEquals(new TreeSet(map.keySet()), new TreeSet( - fiveInputs.keySet())); - fourLeftRemovingOne(); - } - - @Test() - public void testPutAllBytes() { - map.putAllBytes(this.fiveBytes); - assertEquals(map.size(), 5); - assertEquals(new TreeSet(map.keySet()), new TreeSet( - fiveBytes.keySet())); - fourLeftRemovingOne(); + void getOneReturnsBearAndOldValueIsApple(S3Object oldValue) + throws IOException { + assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear"); + assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple"); + assert map.size() == 1; } @Test - public void testPutAllFiles() { - map.putAllFiles(this.fiveFiles); - assertEquals(map.size(), 5); - assertEquals(new TreeSet(map.keySet()), new TreeSet( - fiveFiles.keySet())); - fourLeftRemovingOne(); - } - - void fourLeftRemovingOne() { - map.remove("one"); - assertEquals(map.size(), 4); - assertEquals(new TreeSet(map.keySet()), new TreeSet( - ImmutableSet.of("two", "three", "four", "five"))); - } - - @Test() - public void testPutAllStrings() { - map.putAllStrings(this.fiveStrings); - assertEquals(map.size(), 5); - assertEquals(new TreeSet(map.keySet()), new TreeSet( - fiveStrings.keySet())); - fourLeftRemovingOne(); - } - - @Test() - public void testPutString() throws IOException { - InputStream old = map.putString("one", "apple"); - getOneReturnsAppleAndOldValueIsNull(old); - InputStream apple = map.putString("one", "bear"); - getOneReturnsBearAndOldValueIsApple(apple); - } - - private void getOneReturnsAppleAndOldValueIsNull(InputStream old) - throws IOException { - assert old == null; - assertEquals(Utils.toStringAndClose(map.get("one")), "apple"); - assert map.size() == 1; - } - - private void getOneReturnsBearAndOldValueIsApple(InputStream oldValue) - throws IOException { - assertEquals(Utils.toStringAndClose(map.get("one")), "bear"); - assertEquals(Utils.toStringAndClose(oldValue), "apple"); - assert map.size() == 1; - } - - @Test() - public void testPutFile() throws IOException { - InputStream old = map.putFile("one", fiveFiles.get("one")); - getOneReturnsAppleAndOldValueIsNull(old); - InputStream apple = map.putFile("one", fiveFiles.get("two")); - getOneReturnsBearAndOldValueIsApple(apple); - } - - @Test() - public void testPutBytes() throws IOException { - InputStream old = map.putBytes("one", "apple".getBytes()); - getOneReturnsAppleAndOldValueIsNull(old); - InputStream apple = map.putBytes("one", "bear".getBytes()); - getOneReturnsBearAndOldValueIsApple(apple); - } - - @Test() public void testPut() throws IOException { - InputStream old = map.put("one", IOUtils.toInputStream("apple")); - getOneReturnsAppleAndOldValueIsNull(old); - InputStream apple = map.put("one", IOUtils.toInputStream("bear")); - getOneReturnsBearAndOldValueIsApple(apple); - } - - @Test() - public void testGetBucket() { - assertEquals(map.getBucket().getName(), bucket.getName()); - } - - @Test - void testPutS3Object() throws IOException { - S3Object object = new S3Object(); - object.setKey("one"); + S3Object object = new S3Object("one"); object.setContent(IOUtils.toInputStream("apple")); object.setSize("apple".getBytes().length); - InputStream old = map.put(object); + S3Object old = map.put(object.getKey(), object); getOneReturnsAppleAndOldValueIsNull(old); object.setContent(IOUtils.toInputStream("bear")); object.setSize("bear".getBytes().length); - InputStream apple = map.put(object); + S3Object apple = map.put(object.getKey(), object); getOneReturnsBearAndOldValueIsApple(apple); } @Test - void testPutAllS3Objects() { - Set set = new HashSet(); + public void testPutAll() { + Map newMap = new HashMap(); for (String key : fiveInputs.keySet()) { - S3Object object = new S3Object(); - object.setKey(key); + S3Object object = new S3Object(key); object.setContent(fiveInputs.get(key)); object.setSize(fiveBytes.get(key).length); - set.add(object); + newMap.put(key, object); } - map.putAll(set); + map.putAll(newMap); assertEquals(map.size(), 5); assertEquals(new TreeSet(map.keySet()), new TreeSet( fiveInputs.keySet())); fourLeftRemovingOne(); } + + @Override + protected void putString(String key, String value) { + S3Object object = new S3Object(key); + object.setContent(value); + map.put(key, object); + } + + protected void putFiveStrings() { + Map newMap = new HashMap(); + for (Map.Entry entry : fiveStrings.entrySet()) { + S3Object object = new S3Object(entry.getKey()); + object.setContent(entry.getValue()); + newMap.put(entry.getKey(), object); + } + map.putAll(newMap); + } + }