[jbosscache-commits] JBoss Cache SVN: r5450 - in amazon-s3/trunk: src/main/java/com/amazon/s3 and 3 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Mar 19 18:46:38 EDT 2008


Author: genman
Date: 2008-03-19 18:46:38 -0400 (Wed, 19 Mar 2008)
New Revision: 5450

Added:
   amazon-s3/trunk/src/main/java/com/amazon/s3/ISO801DateFormat.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/
   amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Server.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Writer.java
   amazon-s3/trunk/src/test/java/com/amazon/s3/S3EmulatorTest.java
Modified:
   amazon-s3/trunk/pom.xml
   amazon-s3/trunk/src/main/java/com/amazon/s3/CallingFormat.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/Connection.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/Entry.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/ListAllBucketsResponse.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/ListResponse.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/Owner.java
   amazon-s3/trunk/src/main/java/com/amazon/s3/S3Object.java
   amazon-s3/trunk/src/test/java/com/amazon/s3/S3Test.java
   amazon-s3/trunk/src/test/resources/log4j.xml
Log:
Initial emulator; minor changes in client to support emulator

Modified: amazon-s3/trunk/pom.xml
===================================================================
--- amazon-s3/trunk/pom.xml	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/pom.xml	2008-03-19 22:46:38 UTC (rev 5450)
@@ -49,6 +49,18 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>net.noderunner</groupId>
+      <artifactId>http</artifactId>
+      <version>1.0</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.3</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
       <groupId>commons-httpclient</groupId>
       <artifactId>commons-httpclient</artifactId>
       <version>3.0.1</version>

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/CallingFormat.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/CallingFormat.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/CallingFormat.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -139,6 +139,7 @@
 	}
 
 	static private class VanityCallingFormat extends SubdomainCallingFormat {
+		@Override
 		public String getServer(String server, Bucket bucket) {
 			return bucket.getName();
 		}

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/Connection.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/Connection.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/Connection.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -128,7 +128,7 @@
                              String server, CallingFormat format) {
         this(awsAccessKeyId, awsSecretAccessKey, isSecure, server, 
              isSecure ? SECURE_PORT : INSECURE_PORT, 
-             CallingFormat.SUBDOMAIN);
+             format);
     }
 
     /**

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/Entry.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/Entry.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/Entry.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -14,7 +14,7 @@
 /**
  * A structure representing a single object stored in S3.
  */
-public class Entry {
+public class Entry implements Comparable<Entry> {
 	
     private String key;
 
@@ -35,9 +35,16 @@
     }
 
     /**
+     * Constructs a new Entry.
+     */
+    public Entry(String key) {
+    	setKey(key);
+    }
+
+    /**
 	 * Sets lastModified.
 	 */
-	void setLastModified(Date lastModified) {
+	public void setLastModified(Date lastModified) {
 		this.lastModified = lastModified;
 	}
 
@@ -87,7 +94,7 @@
 	/**
 	 * Sets owner.
 	 */
-	void setOwner(Owner owner) {
+	public void setOwner(Owner owner) {
 		this.owner = owner;
 	}
 
@@ -101,7 +108,7 @@
 	/**
 	 * Sets size.
 	 */
-	void setSize(long size) {
+	public void setSize(long size) {
 		this.size = size;
 	}
 
@@ -125,4 +132,28 @@
 	public String getStorageClass() {
 		return storageClass;
 	}
+	
+	/**
+	 * Returns true if other is an entry with the same key.
+	 */
+	@Override
+	public boolean equals(Object other) {
+		Entry entry = (Entry)other;
+		return key.equals(entry.key);
+	}
+	
+	/**
+	 * Calculates hash using the key.
+	 */
+	@Override
+	public int hashCode() {
+		return key.hashCode();
+	}
+
+	/**
+	 * Compares by key name.
+	 */
+	public int compareTo(Entry other) {
+		return key.compareTo(other.key);
+	}
 }

Added: amazon-s3/trunk/src/main/java/com/amazon/s3/ISO801DateFormat.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/ISO801DateFormat.java	                        (rev 0)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/ISO801DateFormat.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -0,0 +1,18 @@
+package com.amazon.s3;
+
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+/**
+ * Date format used by Amazon S3.
+ * @author Elias Ross
+ */
+ at SuppressWarnings("serial")
+public class ISO801DateFormat extends SimpleDateFormat {
+
+	public ISO801DateFormat() {
+		super("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+		setTimeZone(TimeZone.getTimeZone("UTC"));
+	}
+	
+}

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/ListAllBucketsResponse.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/ListAllBucketsResponse.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/ListAllBucketsResponse.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -15,7 +15,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.TimeZone;
 
 import org.apache.commons.httpclient.HttpMethod;
 import org.xml.sax.Attributes;
@@ -51,9 +50,7 @@
 
 		public ListAllMyBucketsHandler() {
 			super();
-			this.iso8601Parser = new SimpleDateFormat(
-					"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
-			this.iso8601Parser.setTimeZone(TimeZone.getTimeZone("UTC"));
+			this.iso8601Parser = new ISO801DateFormat();
 			this.currText = new StringBuilder();
 		}
 
@@ -68,6 +65,8 @@
 			if (name.equals("Bucket")) {
 				entries.add(this.currBucket);
 			} else if (name.equals("Name")) {
+				if (currBucket == null)
+					throw new IllegalStateException();
 				this.currBucket.setName(this.currText.toString());
 			} else if (name.equals("CreationDate")) {
 				try {

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/ListResponse.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/ListResponse.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/ListResponse.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -14,7 +14,6 @@
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.TimeZone;
 
 import org.apache.commons.httpclient.HttpMethod;
 import org.xml.sax.Attributes;
@@ -113,8 +112,7 @@
             super();
             entries = new ArrayList<Entry>();
             commonPrefixEntries = new ArrayList<CommonPrefixEntry>();
-            this.iso8601Parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
-            this.iso8601Parser.setTimeZone(TimeZone.getTimeZone("UTC"));
+            this.iso8601Parser = new ISO801DateFormat();
             this.currText = new StringBuilder();
         }
 

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/Owner.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/Owner.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/Owner.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -21,6 +21,14 @@
     }
 
 	/**
+	 * Constructs a new Owner.
+	 */
+	public Owner(String id, String displayName) {
+		this.id = id;
+		this.displayName = displayName;
+	}
+
+	/**
 	 * Sets displayName.
 	 */
 	void setDisplayName(String displayName) {

Modified: amazon-s3/trunk/src/main/java/com/amazon/s3/S3Object.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/S3Object.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/S3Object.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -70,6 +70,13 @@
 	}
 
 	/**
+	 * Sets the metadata.
+	 */
+	public void setMetadata(Headers metadata) {
+		this.metadata = metadata;
+	}
+
+	/**
 	 * Returns a debug string.
 	 */
 	@Override

Added: amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Server.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Server.java	                        (rev 0)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Server.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -0,0 +1,229 @@
+package com.amazon.s3.emulator;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.noderunner.http.servlet.ServletServer;
+
+import com.amazon.s3.Entry;
+import com.amazon.s3.Headers;
+import com.amazon.s3.Owner;
+import com.amazon.s3.S3Object;
+
+public class Server extends HttpServlet {
+
+	private static final long serialVersionUID = 1L;
+
+	private ServletServer ss;
+	private boolean bucket = false;
+	private SortedMap<Entry, S3Object> map = new TreeMap<Entry, S3Object>();
+
+	public Server() throws IOException {
+		ss = new ServletServer(this);
+	}
+
+	/**
+	 * Closes socket, stops accepting requests.
+	 */
+	public void close() throws IOException {
+		ss.close();
+	}
+
+	@Override
+	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		URI uri;
+		try {
+			uri = new URI(req.getRequestURI());
+		} catch (URISyntaxException e1) {
+			throw new RuntimeException(e1);
+		}
+		String key = uri.getPath().substring(1);
+		Entry e = new Entry(key);
+		S3Object remove = map.remove(e);
+		if (remove == null) {
+			resp.sendError(404, "Not found " + key);
+		} else {
+			resp.sendError(HttpURLConnection.HTTP_NO_CONTENT, "Deleted");
+		}
+
+	}
+
+	/**
+	 * Listening port.
+	 */
+	public int getPort() {
+		return ss.getPort();
+	}
+
+	/**
+	 * Starts accepting requests.
+	 */
+	public void start() {
+		ss.start();
+	}
+
+	@Override
+	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		URI uri;
+		try {
+			uri = new URI(req.getRequestURI());
+		} catch (URISyntaxException e1) {
+			throw new RuntimeException(e1);
+		}
+		if ("/".equals(uri.getPath())) {
+			list(req, resp);
+		} else {
+			String key = uri.getPath().substring(1);
+			Entry e = new Entry(key);
+			S3Object obj = map.get(e);
+			if (obj == null) {
+				resp.sendError(404, "Not here: " + e);
+				return;
+			}
+			Headers h = new Headers();
+			h = h.mergeMetadata(obj.getMetadata());
+			log("Headers " + obj);
+			log("Headers " + h);
+			for (Map.Entry<String, List<String>> me : h.getHeaders().entrySet()) {
+				for (String v : me.getValue()) {
+					resp.setHeader(me.getKey(), v);
+				}
+			}
+			resp.getOutputStream().write(obj.getData());
+		}
+
+	}
+
+	private void list(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+		String prefix = req.getParameter("prefix");
+		String marker = req.getParameter("marker");
+		String delimiter = req.getParameter("delimiter");
+		String maxKeysStr = req.getParameter("max-keys");
+		int maxKeys = Integer.MAX_VALUE;
+		if (maxKeysStr != null)
+			maxKeys = Integer.parseInt(maxKeysStr);
+		Writer w = new Writer();
+		Map<Entry, S3Object> submap = map;
+		if (prefix != null)
+			submap = map.tailMap(new Entry(prefix));
+		int keyCount = 0;
+		boolean truncated = false;
+		for (Entry e : submap.keySet()) {
+			if (++keyCount > maxKeys) {
+				truncated = true;
+				break;
+			}
+			String key = e.getKey();
+			if (prefix != null && !key.startsWith(prefix))
+				break;
+			if (delimiter != null && key.indexOf(delimiter) != -1)
+				continue;
+			w.start("Contents");
+			w.start("Key").write(key).end();
+			w.start("LastModified").write(e.getLastModified()).end();
+			w.start("Size").write(e.getSize()).end();
+			w.start("Owner");
+			w.start("ID").write(e.getOwner().getId()).end()
+					.start("DisplayName").write(e.getOwner().getDisplayName())
+					.end();
+			w.end();
+			w.end();
+		}
+
+		Writer hw = new Writer();
+		hw.start("ListBucketResult");
+		hw.start("Name").write("localhost").end();
+		hw.start("Prefix").write(s(prefix)).end();
+		hw.start("Marker").write(s(marker)).end();
+		if (delimiter != null)
+			hw.start("Delimiter").write(delimiter).end();
+		hw.start("IsTruncated").write(String.valueOf(truncated)).end();
+		if (maxKeysStr != null)
+			hw.start("MaxKeys").write(maxKeysStr).end();
+		hw.write(w);
+		hw.end();
+
+		PrintWriter pw = resp.getWriter();
+		pw.write(hw.toString());
+		log(hw.toString());
+		pw.flush();
+		bucket = true;
+	}
+
+	private String s(String s) {
+		if (s == null)
+			return "";
+		return s;
+	}
+
+	@Override
+	protected void doHead(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		System.out.println(req);
+	}
+
+	@Override
+	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		URI uri;
+		try {
+			uri = new URI(req.getRequestURI());
+		} catch (URISyntaxException e1) {
+			throw new RuntimeException(e1);
+		}
+		if ("/".equals(uri.getPath())) {
+			log("create bucket");
+			bucket = true;
+		} else {
+			log("URI " + uri.getPath());
+			String key = uri.getPath().substring(1);
+			Entry e = new Entry(key);
+			e.setLastModified(new Date());
+			e.setSize(req.getContentLength());
+			e.setOwner(new Owner("id", "name"));
+			ByteArrayOutputStream os = new ByteArrayOutputStream();
+			ServletInputStream is = req.getInputStream();
+			byte b[] = new byte[128];
+			while (true) {
+				int len = is.read(b);
+				if (len == -1)
+					break;
+				os.write(b, 0, len);
+			}
+			S3Object s3 = new S3Object(os.toByteArray());
+			map.put(e, s3);
+			Headers h = new Headers();
+			@SuppressWarnings("unchecked")
+			Enumeration<String> names = req.getHeaderNames();
+			for (String n : Collections.list(names))
+				h.put(n, req.getHeader(n));
+			s3.setMetadata(h.extractMetadata());
+			log("PUT '" + e + "' as: " + s3);
+		}
+		System.out.println(req);
+	}
+
+	public void log(String log) {
+		System.err.println(log);
+	}
+
+}

Added: amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Writer.java
===================================================================
--- amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Writer.java	                        (rev 0)
+++ amazon-s3/trunk/src/main/java/com/amazon/s3/emulator/Writer.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -0,0 +1,50 @@
+package com.amazon.s3.emulator;
+
+import java.util.Date;
+import java.util.Stack;
+
+import com.amazon.s3.ISO801DateFormat;
+
+public class Writer {
+
+	Stack<String> tags = new Stack<String>();
+	
+	StringBuilder sb = new StringBuilder();
+	
+	public Writer start(String tag) {
+		sb.append("<").append(tag).append(">");
+		tags.push(tag);
+		return this;
+	}
+	
+	public Writer end() {
+		String tag = tags.pop();
+		sb.append("</").append(tag).append(">");
+		return this;
+	}
+	
+	public Writer write(String s) {
+		s = s.replaceAll("&", "&amp;");
+		s = s.replaceAll("<", "&lt;");
+		sb.append(s);
+		return this;
+	}
+	
+	public Writer write(Writer w) {
+		sb.append(w.toString());
+		return this;
+	}
+	
+	public String toString() {
+		return sb.toString();
+	}
+
+	public Writer write(Date lastModified) {
+		return write(new ISO801DateFormat().format(lastModified));
+	}
+
+	public Writer write(long size) {
+		return write(String.valueOf(size));
+	}
+	
+}

Added: amazon-s3/trunk/src/test/java/com/amazon/s3/S3EmulatorTest.java
===================================================================
--- amazon-s3/trunk/src/test/java/com/amazon/s3/S3EmulatorTest.java	                        (rev 0)
+++ amazon-s3/trunk/src/test/java/com/amazon/s3/S3EmulatorTest.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -0,0 +1,363 @@
+package com.amazon.s3;
+//  This software code is made available "AS IS" without warranties of any
+//  kind.  You may copy, display, modify and redistribute the software
+//  code either by itself or as incorporated into your code; provided that
+//  you do not remove any proprietary notices.  Your use of this software
+//  code is at your own risk and you waive any claim against Amazon
+//  Digital Services, Inc. or its affiliates with respect to your use of
+//  this software code. (c) 2006-2007 Amazon Digital Services, Inc. or its
+//  affiliates.
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.URI;
+import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.amazon.s3.emulator.Server;
+
+public class S3EmulatorTest {
+	
+    private static final int UnspecifiedMaxKeys = -1;
+
+	private Server s;
+
+	private Bucket bucket;
+	
+	private int port;
+
+    @Before
+    public void setUp() throws Exception {
+        s = new Server();
+        s.start();
+        bucket = new Bucket("localhost");
+        port = s.getPort();
+    }
+    
+    @After
+    public void tearDown() throws Exception {
+    	s.close();
+    }
+    
+    @Test
+    public void testMe() throws Exception {
+        String awsAccessKeyId = "512341324124";
+        String awsSecretAccessKey = "512351234123";
+		CallingFormat format = CallingFormat.VANITY;
+		String location = null;
+		Connection conn = new Connection(awsAccessKeyId, awsSecretAccessKey, false, "localhost", port, format);
+        
+        Response response = conn.create(bucket, location, null);
+        response.assertOk();
+
+        ListResponse listBucketResponse = conn.list(bucket);
+        listBucketResponse.assertOk();
+        assertEquals("list wasn't empty " + listBucketResponse, 0, listBucketResponse.getEntries().size());
+        verifyBucketResponseParameters(listBucketResponse, bucket, "", "", UnspecifiedMaxKeys, null, false, null);
+
+        // start delimiter tests
+
+        final String text = "this is a test";
+        final String key = "example.txt";
+        final String innerKey = "test/inner.txt";
+        final String lastKey = "z-last-key.txt";
+
+        response = conn.put(bucket, key, new S3Object(text));
+        response.assertOk();
+
+        response = conn.put(bucket, innerKey, new S3Object(text));
+        response.assertOk();
+
+        response = conn.put(bucket, lastKey, new S3Object(text));
+        response.assertOk();
+
+        // plain list
+        listBucketResponse = conn.list(bucket);
+        listBucketResponse.assertOk();
+        assertEquals("Unexpected list size", 3, listBucketResponse.getEntries().size());
+        assertEquals("Unexpected common prefix size", 0, listBucketResponse.getCommonPrefixEntries().size());
+        verifyBucketResponseParameters(listBucketResponse, bucket, "", "", UnspecifiedMaxKeys, null, false, null);
+        
+        System.out.println("LIST " + listBucketResponse.getEntries());
+
+        // root "directory"
+        listBucketResponse = conn.list(bucket, null, null, null, "/", null);
+        listBucketResponse.assertOk();
+        assertEquals("Unexpected list size " + listBucketResponse, 2, listBucketResponse.getEntries().size());
+        // TODO
+        // assertEquals("Unexpected common prefix size", 1, listBucketResponse.getCommonPrefixEntries().size());
+        verifyBucketResponseParameters(listBucketResponse, bucket, "", "", UnspecifiedMaxKeys, "/", false, null);
+
+        // root "directory" with a max-keys of "1"
+        listBucketResponse = conn.list(bucket, null, null, 1, "/", null);
+        listBucketResponse.assertOk();
+        assertEquals("Unexpected list size", 1, listBucketResponse.getEntries().size());
+        assertEquals("Unexpected common prefix size", 0, listBucketResponse.getCommonPrefixEntries().size());
+        // TODO
+        // verifyBucketResponseParameters(listBucketResponse, bucket, "", "", 1, "/", true, "example.txt");
+
+        // root "directory" with a max-keys of "2"
+        listBucketResponse = conn.list(bucket, null, null, 2, "/", null);
+        listBucketResponse.assertOk();
+        assertEquals("Unexpected list size", 1, listBucketResponse.getEntries().size());
+        // TODO
+        // assertEquals("Unexpected common prefix size", 1, listBucketResponse.getCommonPrefixEntries().size());
+        // TODO
+        // verifyBucketResponseParameters(listBucketResponse, bucket, "", "", 2, "/", true, "test/");
+        String marker = listBucketResponse.getNextMarker();
+        listBucketResponse = conn.list(bucket, null, marker, 2, "/", null);
+        listBucketResponse.assertOk();
+        assertEquals("Unexpected list size", 1, listBucketResponse.getEntries().size());
+        assertEquals("Unexpected common prefix size", 0, listBucketResponse.getCommonPrefixEntries().size());
+        // TODO
+        // verifyBucketResponseParameters(listBucketResponse, bucket, "", marker, 2, "/", false, null);
+
+        // test "directory"
+        listBucketResponse = conn.list(bucket, "test/", null, null, "/", null);
+        listBucketResponse.assertOk();
+        // TODO
+        // assertEquals("Unexpected list size", 1, listBucketResponse.getEntries().size());
+        assertEquals("Unexpected common prefix size", 0, listBucketResponse.getCommonPrefixEntries().size());
+        verifyBucketResponseParameters(listBucketResponse, bucket, "test/", "", UnspecifiedMaxKeys, "/", false, null);
+
+        // remove innerkey
+        response = conn.delete(bucket, innerKey, null);
+        assertEquals(
+                "couldn't delete entry",
+                HttpURLConnection.HTTP_NO_CONTENT,
+                response.getResponseCode());
+
+        // remove last key
+        response = conn.delete(bucket, lastKey, null);
+        assertEquals(
+                "couldn't delete entry",
+                HttpURLConnection.HTTP_NO_CONTENT,
+                response.getResponseCode());
+
+
+        // end delimiter tests
+
+        response = conn.put(bucket, key, new S3Object(text.getBytes(), null), null);
+        response.assertOk();
+
+        Headers metadata = new Headers();
+        metadata.put("title", "title");
+        response = conn.put(bucket, key, new S3Object(text.getBytes(), metadata), null);
+        response.assertOk();
+
+        GetResponse getResponse = conn.get(bucket, key, null);
+        getResponse.assertOk();
+        assertEquals("didn't get the right data back", text.getBytes(), getResponse.getObject().getData());
+        assertEquals("didn't get the right metadata back", 1, getResponse.getObject().getMetadata().size());
+        assertEquals(
+                "didn't get the right metadata back",
+                "title",
+                getResponse.getObject().getMetadata().getValue("title"));
+        assertEquals(
+                "didn't get the right content-length",
+                ""+text.length(),
+                getResponse.getHeaderField("Content-Length"));
+        
+        GetStreamResponse streamResponse = conn.getStream(bucket, key);
+        InputStream is = streamResponse.getInputStream();
+        byte b[] = new byte[text.length()];
+        int len = is.read(b);
+        assertEquals("didn't get the right data back " + len, text.getBytes(), b);
+        streamResponse.release();
+
+        String titleWithSpaces = " \t  title with leading and trailing spaces    ";
+        Headers h = new Headers();
+        h.put("title", titleWithSpaces);
+        response = conn.put(bucket, key, new S3Object(text.getBytes(), h), null);
+        assertEquals(
+                "couldn't put metadata with leading and trailing spaces",
+                HttpURLConnection.HTTP_OK,
+                response.getResponseCode());
+
+        getResponse = conn.get(bucket, key, null);
+        assertEquals(
+                "couldn't get object",
+                HttpURLConnection.HTTP_OK,
+                getResponse.getResponseCode());
+        assertEquals("didn't get the right metadata back", getResponse.getObject().getMetadata().size(), 1);
+        assertEquals(
+                "didn't get the right metadata back",
+                titleWithSpaces.trim(),
+                getResponse.getObject().getMetadata().getValue("title"));
+
+        String weirdKey = "&weird+%";
+        response = conn.put(bucket, weirdKey, new S3Object(text.getBytes()));
+        assertEquals(
+                "couldn't put weird key",
+                HttpURLConnection.HTTP_OK,
+                response.getResponseCode());
+
+        getResponse = conn.get(bucket, weirdKey, null);
+        assertEquals(
+                "couldn't get weird key",
+                HttpURLConnection.HTTP_OK,
+                getResponse.getResponseCode());
+
+        // start acl test
+
+        getResponse = conn.getACL(bucket, key, null);
+        assertEquals(
+                "couldn't get acl",
+                HttpURLConnection.HTTP_OK,
+                getResponse.getResponseCode());
+
+        byte[] acl = getResponse.getObject().getData();
+
+        response = conn.putACL(bucket, key, new String(acl), null);
+        assertEquals(
+                "couldn't put acl",
+                HttpURLConnection.HTTP_OK,
+                response.getResponseCode());
+
+        getResponse = conn.getACL(bucket, null);
+        assertEquals(
+                "couldn't get bucket acl",
+                HttpURLConnection.HTTP_OK,
+                getResponse.getResponseCode());
+
+        byte[] bucketACL = getResponse.getObject().getData();
+
+        response = conn.putACL(bucket, new String(bucketACL), null);
+        assertEquals(
+                "couldn't put bucket acl",
+                HttpURLConnection.HTTP_OK,
+                response.getResponseCode());
+
+        // end acl test
+
+        // bucket logging tests
+        getResponse = conn.getBucketLogging(bucket, null);
+        assertEquals(
+                "couldn't get bucket logging config",
+                HttpURLConnection.HTTP_OK, 
+                getResponse.getResponseCode());
+
+        byte[] bucketLogging = getResponse.getObject().getData();
+
+        response = conn.putBucketLogging(bucket, new String(bucketLogging), null);
+        assertEquals(
+                "couldn't put bucket logging config",
+                HttpURLConnection.HTTP_OK,
+                response.getResponseCode());
+
+        // end bucket logging tests
+
+        listBucketResponse = conn.list(bucket, null, null, null, null);
+        assertEquals(
+                "couldn't list bucket",
+                HttpURLConnection.HTTP_OK,
+                listBucketResponse.getResponseCode());
+        List<Entry> entries = listBucketResponse.getEntries();
+        assertEquals("didn't get back the right number of entries", 2, entries.size());
+        // depends on weirdKey < $key
+        assertEquals("first key isn't right", weirdKey, ((Entry)entries.get(0)).getKey());
+        assertEquals("second key isn't right", key, ((Entry)entries.get(1)).getKey());
+        verifyBucketResponseParameters(listBucketResponse, bucket, "", "", UnspecifiedMaxKeys, null, false, null);
+
+        listBucketResponse = conn.list(bucket, null, null, new Integer(1), null);
+        assertEquals(
+                "couldn't list bucket",
+                HttpURLConnection.HTTP_OK,
+                listBucketResponse.getResponseCode());
+        assertEquals(
+                "didn't get back the right number of entries",
+                1,
+                listBucketResponse.getEntries().size());
+        verifyBucketResponseParameters(listBucketResponse, bucket, "", "", 1, null, true, null);
+
+        for (Entry entry : entries) {
+            response = conn.delete(bucket, entry.getKey(), null);
+            assertEquals(
+                    "couldn't delete entry",
+                    HttpURLConnection.HTTP_NO_CONTENT,
+                    response.getResponseCode());
+        }
+
+        /* TODO
+        ListAllBucketsResponse listAllMyBucketsResponse = conn.listAllBuckets();
+        assertEquals(
+                "couldn't list all my buckets",
+                HttpURLConnection.HTTP_OK,
+                listAllMyBucketsResponse.getResponseCode());
+        List<Bucket> buckets = listAllMyBucketsResponse.getEntries();
+
+        response = conn.delete(bucket);
+        assertEquals(
+                "couldn't delete bucket",
+                HttpURLConnection.HTTP_NO_CONTENT,
+                response.getResponseCode());
+
+        listAllMyBucketsResponse = conn.listAllBuckets();
+        assertEquals(
+                "couldn't list all my buckets",
+                HttpURLConnection.HTTP_OK,
+                listAllMyBucketsResponse.getResponseCode());
+        assertEquals(
+                "bucket count is incorrect",
+                buckets.size() - 1,
+                listAllMyBucketsResponse.getEntries().size());
+        */
+
+    }
+
+    private static void verifyBucketResponseParameters( ListResponse listBucketResponse,
+                                                           Bucket bucket, String prefix, String marker,
+                                                           int maxKeys, String delimiter, boolean isTruncated,
+                                                           String nextMarker ) {
+        assertEquals("Bucket name should match.", bucket.getName(), listBucketResponse.getName());
+        assertEquals("Bucket prefix should match.", prefix, listBucketResponse.getPrefix());
+        assertEquals("Bucket marker should match.", marker, listBucketResponse.getMarker());
+        assertEquals("Bucket delimiter should match.", delimiter, listBucketResponse.getDelimiter());
+        if ( UnspecifiedMaxKeys != maxKeys ) {
+            assertEquals("Bucket max-keys should match.", maxKeys, listBucketResponse.getMaxKeys());
+        }
+        assertEquals("Bucket should not be truncated.", isTruncated, listBucketResponse.isTruncated());
+        assertEquals("Bucket nextMarker should match.", nextMarker, listBucketResponse.getNextMarker());
+    }
+
+
+    private static void assertEquals(String message, int expected, int actual) {
+        if (expected != actual) {
+            throw new RuntimeException(message + ": expected " + expected + " but got " + actual);
+        }
+    }
+    
+    private static void assertEquals(String message, byte[] expected, byte[] actual) {
+        if (! Arrays.equals(expected, actual)) {
+            throw new RuntimeException(
+                    message +
+                    ": expected " +
+                    new String(expected) +
+                    " but got " +
+                    new String(actual));
+        }
+    }
+
+    private static void assertEquals(String message, Object expected, Object actual) {
+        if (expected != actual && (actual == null || ! actual.equals(expected))) {
+            throw new RuntimeException(message + ": expected " + expected + " but got " + actual);
+        }
+    }
+
+    private static void assertEquals(String message, boolean expected, boolean actual) {
+        if (expected != actual) {
+            throw new RuntimeException(message + ": expected " + expected + " but got " + actual);
+        }
+    }
+
+}

Modified: amazon-s3/trunk/src/test/java/com/amazon/s3/S3Test.java
===================================================================
--- amazon-s3/trunk/src/test/java/com/amazon/s3/S3Test.java	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/test/java/com/amazon/s3/S3Test.java	2008-03-19 22:46:38 UTC (rev 5450)
@@ -27,6 +27,7 @@
 	
     String awsAccessKeyId = System.getProperty("accessKey");
     String awsSecretAccessKey = System.getProperty("secretKey");
+    boolean emulated = Boolean.valueOf(System.getProperty("emulated", "true"));
     Bucket bucket;
 
     static final int UnspecifiedMaxKeys = -1;
@@ -45,6 +46,8 @@
     
     @Test
     public void testMe() throws Exception {
+    	if (emulated)
+    		return;
         // test all operation for both regular and vanity domains
         // regular: http://s3.amazonaws.com/key
         // subdomain: http://bucket.s3.amazonaws.com/key
@@ -466,6 +469,8 @@
     
     @Test
     public void testDriver() throws Exception {
+    	if (emulated)
+    		return;
         Bucket bucket = new Bucket(awsAccessKeyId.toLowerCase() + "-test-bucket");
         String keyName = "KEY";
 

Modified: amazon-s3/trunk/src/test/resources/log4j.xml
===================================================================
--- amazon-s3/trunk/src/test/resources/log4j.xml	2008-03-19 10:24:18 UTC (rev 5449)
+++ amazon-s3/trunk/src/test/resources/log4j.xml	2008-03-19 22:46:38 UTC (rev 5450)
@@ -28,7 +28,7 @@
       <level value="INFO"/>
   </logger>
   <logger name="httpclient.wire">
-      <level value="INFO"/>
+      <level value="ALL"/>
   </logger>
   <logger name="org.apache.commons.httpclient">
       <level value="INFO"/>




More information about the jbosscache-commits mailing list