You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by wo...@apache.org on 2010/09/14 23:57:03 UTC

svn commit: r997113 [2/2] - in /incubator/libcloud/sandbox/java/trunk/src: ./ base/ base/connection/ base/interfaces/ libcloud/ libcloud/data/ libcloud/exceptions/ libcloud/interfaces/ libcloud/providers/ libcloud/providers/amazon/ libcloud/providers/i...

Added: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,82 @@
+package libcloud.providers.rackspace;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import libcloud.NodeDriver;
+import base.connection.ConnectionUserAndKey;
+import base.connection.Response;
+import base.interfaces.IResponse;
+
+public class RackspaceConnection extends ConnectionUserAndKey {
+	
+	private static final String AUTH_HOST = "auth.api.rackspacecloud.com";
+	private static final int DEFAULT_PORT = 443;
+	private static final boolean DEFAULT_SECURE = true;
+	private static final int SUCCESSFUL_AUTH = 204;
+	
+	private String authToken;
+	private String serversUrl;
+	private String serversBasePath;
+	
+	public RackspaceConnection(String username, String apiKey, boolean secure,
+			String host, int port, NodeDriver driver) {
+		super(username, apiKey, DEFAULT_SECURE, AUTH_HOST, DEFAULT_PORT, driver);
+		serversBasePath = "";
+	}
+	
+	public RackspaceConnection(String username, String apiKey, NodeDriver driver) {
+		super(username, apiKey, DEFAULT_SECURE, AUTH_HOST, DEFAULT_PORT, driver);
+		
+		// we need to authenticate to get the server host
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put("X-Auth-User", username);
+		headers.put("X-Auth-Key", apiKey);
+		
+		RackspaceConnection connection = new RackspaceConnection(username, apiKey, DEFAULT_SECURE, 
+				AUTH_HOST, DEFAULT_PORT, null);
+		IResponse response = connection.request("GET", "v1.0", headers, null, null);
+		
+		if (response.getStatus() == SUCCESSFUL_AUTH) {
+			Map<String, String> responseHeaders = response.getHeaders();
+			authToken = responseHeaders.get("X-Auth-Token");
+			serversUrl = responseHeaders.get("X-Server-Management-Url");
+							
+			try {
+				URI uri = new URI(serversUrl);
+				serversBasePath = uri.getPath();
+			} catch (URISyntaxException e) {
+				serversBasePath = "";
+			}
+
+			host = "servers.api.rackspacecloud.com";
+			serversBasePath = serversUrl.replace("https://servers.api.rackspacecloud.com", "");
+			
+		}
+	}
+
+	public Response request(String method, String action,
+			Map<String, String> headers, Map<String, String> params, String data) {
+		return super.request(method, serversBasePath + action, headers, params, data);
+	}
+	
+	public Map<String, String> addDefaultHeaders(Map<String, String> headers) {
+		headers.put("Accept", "application/xml");
+		headers.put("X-Auth-Token", authToken);
+		if (!headers.containsKey("Content-Type")) {
+			headers.put("Content-Type", "application/xml");
+		}
+		return headers;
+	}
+	
+	public void connect(String host, int port) {
+		super.connect(host, port);
+
+		// Rackspace blows up if an Expect header is sent
+		httpClient.removeRequestInterceptorByClass(org.apache.http.protocol.RequestExpectContinue.class);		
+	}
+
+	
+}

Propchange: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceDriver.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceDriver.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceDriver.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceDriver.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,179 @@
+package libcloud.providers.rackspace;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import libcloud.NodeDriver;
+import libcloud.data.Node;
+import libcloud.data.NodeAuth;
+import libcloud.data.NodeImage;
+import libcloud.data.NodeLocation;
+import libcloud.data.NodeSize;
+import libcloud.data.NodeState;
+import libcloud.interfaces.INode;
+import libcloud.interfaces.INodeDriver;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import base.interfaces.IResponse;
+
+public class RackspaceDriver extends NodeDriver {
+
+	private XPath xpath;
+	
+	private static final String NAME = "Rackspace Cloud";
+
+	private static final Map<String, NodeState> NODE_STATE_MAP = new HashMap<String, NodeState>();
+
+	public RackspaceDriver(String username, String apiKey) {
+		connection = new RackspaceConnection(username, apiKey, this);
+		xpath = XPathFactory.newInstance().newXPath();
+		
+		NODE_STATE_MAP.put("BUILD", NodeState.PENDING);
+		NODE_STATE_MAP.put("REBUILD", NodeState.PENDING);
+		NODE_STATE_MAP.put("ACTIVE", NodeState.RUNNING);
+		NODE_STATE_MAP.put("SUSPENDED", NodeState.TERMINATED);
+		NODE_STATE_MAP.put("QUEUE_RESIZE", NodeState.PENDING);
+		NODE_STATE_MAP.put("PREP_RESIZE", NodeState.PENDING);
+		NODE_STATE_MAP.put("VERIFY_RESIZE", NodeState.RUNNING);
+		NODE_STATE_MAP.put("PASSWORD", NodeState.PENDING);
+		NODE_STATE_MAP.put("RESCUE", NodeState.PENDING);
+		NODE_STATE_MAP.put("REBUILD", NodeState.PENDING);
+		NODE_STATE_MAP.put("REBOOT", NodeState.REBOOTING);
+		NODE_STATE_MAP.put("HARD_REBOOT", NodeState.REBOOTING);
+		NODE_STATE_MAP.put("SHARE_IP", NodeState.PENDING);
+		NODE_STATE_MAP.put("SHARE_IP_NO_CONFIG", NodeState.PENDING);
+		NODE_STATE_MAP.put("DELETE_IP", NodeState.PENDING);
+		NODE_STATE_MAP.put("UNKNOWN", NodeState.UNKNOWN);
+	}
+
+	public String getName() {
+		return NAME;
+	}
+
+	public INode createNode(String name, NodeSize size, NodeImage image,
+			NodeLocation location, NodeAuth auth, Map<String, Object> extra) {
+
+		String xml = "<server xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" name=\"" + name
+				+ "\" imageId=\"" + image.id
+				+ "\" flavorId=\"" + size.id + "\" />";
+		
+		IResponse response = connection.request("POST", "/servers.xml", null, null, xml);
+		RackspaceHandler rh = new RackspaceHandler(response);
+		Document document = (Document) rh.getParsedObject();
+		try {
+			return parseNode(document.getDocumentElement());
+		} catch (XPathExpressionException e) {
+			e.printStackTrace();
+		}
+		return null;	// Error
+	}
+
+	public boolean rebootNode(INode node) {
+		String body = "<reboot xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" type=\"SOFT\"/>";
+		IResponse response = connection.request("POST",
+						"/servers/" + node.getId() + "/action.xml",
+				null, null, body);
+		return response.getStatus() == 202;
+	}
+
+	public boolean destroyNode(INode node) {
+		IResponse response = connection.request("DELETE",
+						"/servers/" + node.getId() + ".xml",
+				null, null, null);
+		return response.getStatus() == 202;
+	}
+
+	public List<NodeImage> listImages() {
+		IResponse response = connection.request("GET", "/images/detail.xml", null, null, null);
+		RackspaceHandler rh = new RackspaceHandler(response);
+		return parseImages((Document) rh.getParsedObject());
+	}
+
+	public List<NodeLocation> listLocations() {
+		List<NodeLocation> locations = new ArrayList<NodeLocation>();
+		locations.add(new NodeLocation("0", "Rackspace DFW1", "US", this));
+		locations.add(new NodeLocation("1", "Rackspace ORD1", "US", this));
+		return locations;
+	}
+
+	public List<INode> listNodes() {
+		IResponse response = connection.request("GET", "/servers/detail.xml", null, null, null);
+		RackspaceHandler rh = new RackspaceHandler(response);
+		return parseNodes((Document) rh.getParsedObject());
+	}
+
+	public List<NodeSize> listSizes() {
+		IResponse response = connection.request("GET", "/flavors/detail.xml", null, null, null);
+		RackspaceHandler rh = new RackspaceHandler(response);
+		return parseSizes((Document) rh.getParsedObject());
+	}
+
+	// ----------------------------- PRIVATE HELPERS ---------------------------
+
+	private List<NodeImage> parseImages(Document doc) {
+		List<NodeImage> images = new ArrayList<NodeImage>();
+		try {
+			NodeList set = (NodeList) xpath.evaluate("image", doc.getDocumentElement(), XPathConstants.NODESET);
+			for (int i = 0; i < set.getLength(); i++) {
+				images.add(parseImage((Element) set.item(i)));
+			}
+			return images;
+		} catch (XPathExpressionException e) {
+			e.printStackTrace();
+		}
+		return null;	// Error
+	}
+	
+	private NodeImage parseImage(Element elem) throws XPathExpressionException {
+		return new NodeImage(xpath.evaluate("@id", elem), xpath.evaluate("@name", elem), null, this);
+	}
+	
+	private List<NodeSize> parseSizes(Document doc) {
+		List<NodeSize> sizes = new ArrayList<NodeSize>();
+		try {
+			NodeList set = (NodeList) xpath.evaluate("flavor", doc.getDocumentElement(), XPathConstants.NODESET);
+			for (int i = 0; i < set.getLength(); i++) {
+				sizes.add(parseSize((Element) set.item(i)));
+			}
+			return sizes;
+		} catch (XPathExpressionException e) {
+			e.printStackTrace();
+		}
+		return null;	// Error
+	}
+	
+	private NodeSize parseSize(Element elem) throws XPathExpressionException {
+		return new NodeSize(xpath.evaluate("@id", elem), xpath.evaluate("@name", elem), Integer.parseInt(xpath.evaluate("@ram", elem)), 
+				Integer.parseInt(xpath.evaluate("@disk", elem)), 0, 0.0f, (INodeDriver)this);
+	}
+		
+	private Node parseNode(Element elem) throws XPathExpressionException {
+		return new Node(xpath.evaluate("@id", elem), xpath.evaluate("@name", elem), NODE_STATE_MAP.get(xpath.evaluate("@status", elem)),
+				xpath.evaluate("addresses/public/ip/@addr", elem), xpath.evaluate("addresses/private/ip/@addr", elem), null, this);
+	}
+	
+	private List<INode> parseNodes(Document doc) {
+		List<INode> servers = new ArrayList<INode>();
+		try {
+			NodeList set = (NodeList) xpath.evaluate("server", doc.getDocumentElement(), XPathConstants.NODESET);
+			for (int i = 0; i < set.getLength(); i++) {
+				servers.add(parseNode((Element) set.item(i)));
+			}
+			return servers;
+		} catch (XPathExpressionException e) {
+			e.printStackTrace();
+		}
+		return null;	// Error
+	}
+
+}

Propchange: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceDriver.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceHandler.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceHandler.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceHandler.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceHandler.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,51 @@
+package libcloud.providers.rackspace;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import libcloud.exceptions.InvalidCredsException;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import base.connection.ResponseHandler;
+import base.interfaces.IResponse;
+
+public class RackspaceHandler extends ResponseHandler {
+
+	public RackspaceHandler(IResponse response) {
+		super(response);
+	}
+
+	protected void parseBody() {
+		object = null;
+		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+		try {
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			object = db.parse(new InputSource(new StringReader(response.getBody())));
+		} catch (ParserConfigurationException e) {
+			e.printStackTrace();
+		} catch (SAXException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	protected String parseError() {
+		if (response.getStatus() == 401) {
+			if (response.getBody().equals("")) {
+				throw new InvalidCredsException(response.getStatus() + ": "
+						+ response.getPhrase());
+			} else {
+				throw new InvalidCredsException(response.getBody());
+			}
+		} else {
+			return response.getBody();
+		}
+	}
+}

Propchange: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceHandler.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageAdapter.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageAdapter.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageAdapter.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageAdapter.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,8 @@
+package simplecloud.storage;
+
+import simplecloud.storage.interfaces.IStorageAdapter;
+import base.Driver;
+
+public abstract class StorageAdapter extends Driver implements IStorageAdapter {
+	
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageFactory.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageFactory.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageFactory.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/StorageFactory.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,6 @@
+package simplecloud.storage;
+
+// TODO: implement this & extend from SimpleCloudFactory
+public class StorageFactory {
+
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/File.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/File.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/File.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/File.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,8 @@
+package simplecloud.storage.data;
+
+public class File extends Item {
+
+	public File(String name) {
+		super(name);
+	}
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Folder.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Folder.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Folder.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Folder.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,9 @@
+package simplecloud.storage.data;
+
+public class Folder extends Item {
+
+	public Folder(String name) {
+		super(name);
+	}
+
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Item.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Item.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Item.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/Item.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,14 @@
+package simplecloud.storage.data;
+
+public class Item {
+
+	private String name;
+	
+	public Item(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/exceptions/StorageException.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/exceptions/StorageException.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/exceptions/StorageException.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/exceptions/StorageException.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,10 @@
+package simplecloud.storage.exceptions;
+
+/*
+ * Represents an exception when interacting with SimpleCloud's storage service.
+ */
+public class StorageException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,35 @@
+package simplecloud.storage.interfaces;
+
+import java.util.List;
+import java.util.Map;
+
+import simplecloud.storage.data.Item;
+
+/*
+ * Common interface for unstructured cloud storage.
+ * 
+ * TODO: Comments
+ * TODO: For every return void, why not return status? PHP doesn't.
+ */
+public interface IStorageAdapter {
+	
+	public Item fetchItem(String path, Map<String, String> options);
+	
+	public boolean storeItem(String destinationPath, Item item, Map<String, String> options);
+	
+	public void deleteItem(String path, Map<String, String> options);
+	
+	public void copyItem(String sourcePath, String destinationPath, Map<String, String> options);
+	
+	public void moveItem(String sourcePath, String destinationPath, Map<String, String> options);
+	
+	public void renameItem(String path, String name, Map<String, String> options);
+
+	public List<String> listItems(String path, Map<String, String> options);
+	
+	public Map<String, String> fetchMetadata(String path, Map<String, String> options);
+	
+	public void storeMetadata(String destinationPath, Map<String, String> metadata, Map<String, String> options);
+	
+	public void deleteMetadata(String path, Map<String, String> options);
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,14 @@
+package simplecloud.storage.providers.amazon;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Main {
+
+	public static void main(String [] args) {
+		S3Adapter adapter = new S3Adapter("access key id", "access key", "s3.amazonaws.com");
+		Map<String, String> options = new HashMap<String, String>();
+		options.put(S3Adapter.Type.BUCKET.toString(), "ericlibcloud");
+		adapter.fetchItem("/hello.jpg", options);
+	}
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,110 @@
+package simplecloud.storage.providers.amazon;
+
+import java.util.List;
+import java.util.Map;
+
+import simplecloud.storage.StorageAdapter;
+import simplecloud.storage.data.Item;
+import base.interfaces.IResponse;
+
+/*
+ * Adapter for interacting with Amazon S3.
+ */
+public class S3Adapter extends StorageAdapter {
+	
+	private final String HOST;
+	
+	public enum Type {
+		BUCKET("bucket");
+		
+		private String value;
+		private Type(String value) {
+			this.value = value;
+		}
+		public String toString() {
+			return this.value;
+		}
+	}
+	
+	/*
+	 * Constructs the adapter.
+	 * 
+	 * @param accessId is the Amazon account access ID
+	 * @param accessKey is the corresponding key to the Amazon account
+	 * @param host identifies the endpoint for the S3 services
+	 */
+	public S3Adapter(String accessId, String accessKey, String host) {
+		HOST = host;
+		connection = new S3Connection(accessId, accessKey, host, this);
+	}
+
+	@Override
+	public Item fetchItem(String path, Map<String, String> options) {
+		String bucket = options.get(Type.BUCKET.toString());
+		connection.connect(bucket + '.' + HOST, -1);	// TODO: connect to port only (add method)
+		IResponse response = connection.request("GET", path, null, null, null);
+		System.out.println("Response: " + response.toString());
+		//S3Handler handler = new S3Handler(response);
+		return null;
+	}
+
+	@Override
+	public boolean storeItem(String destinationPath, Item item,
+			Map<String, String> options) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public void deleteItem(String path, Map<String, String> options) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void copyItem(String sourcePath, String destinationPath,
+			Map<String, String> options) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void moveItem(String sourcePath, String destinationPath,
+			Map<String, String> options) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void renameItem(String path, String name, Map<String, String> options) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public List<String> listItems(String path, Map<String, String> options) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Map<String, String> fetchMetadata(String path,
+			Map<String, String> options) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void storeMetadata(String destinationPath,
+			Map<String, String> metadata, Map<String, String> options) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void deleteMetadata(String path, Map<String, String> options) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Connection.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Connection.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Connection.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Connection.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,160 @@
+package simplecloud.storage.providers.amazon;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.SimpleTimeZone;
+import java.util.TreeMap;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+
+import base.Driver;
+import base.connection.ConnectionUserAndKey;
+
+public class S3Connection extends ConnectionUserAndKey {
+	
+	private static final boolean DEFAULT_SECURE = true;
+	
+	private static List<String> subResources;
+
+	public S3Connection(String accessId, String accessKey, String host,
+			Driver driver) {
+		super(accessId, accessKey, DEFAULT_SECURE, host, driver);
+		subResources = new ArrayList<String>();
+		subResources.add("?versioning");
+		subResources.add("?location");
+		subResources.add("?acl");
+		subResources.add("?torret");
+		subResources.add("?logging");
+	}
+	
+	protected Map<String, String> addDefaultHeaders(Map<String, String> headers) {
+		headers.put("Host", this.host);
+		SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
+		sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
+		headers.put("Date", sdf.format(new Date()));
+		String signature = getSignature(headers);
+		headers.put("Authorization", "AWS " + accessId + ':' + signature);
+		return headers;
+	}
+	
+	protected Map<String, String> addDefaultParams(Map<String, String> params) {
+		return null;
+	}
+	
+	/*
+	 * Generates the request signature as documented at:
+	 * http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/index.html
+	 * 
+	 * @param headers are the headers used to generate the signature
+	 * 
+	 * @return the signature that signs (authenticates) the request
+	 */
+	private String getSignature(Map<String, String> headers) {
+		String stringToSign = getStringToSign(headers);
+		
+		// Calculate HMAC of stringToSign
+		byte[] hmac = null;
+		try {
+			Mac mac = Mac.getInstance("HmacSHA1");
+			SecretKeySpec key = new SecretKeySpec(accessKey.getBytes(), "UTF-8");
+			mac.init(key);
+			hmac = mac.doFinal(stringToSign.getBytes());
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		} catch (InvalidKeyException e) {
+			e.printStackTrace();
+		}
+		
+		// Base 64 encode HMAC
+		return new String(Base64.encodeBase64(hmac));
+	}
+	
+	private String getStringToSign(Map<String, String> headers) {
+		StringBuilder sb = new StringBuilder();
+		sb.append(this.method).append('\n');
+		if (headers.containsKey("Content-MD5")) sb.append(headers.get("Content-MD5"));
+		sb.append('\n');
+		if (headers.containsKey("Content-Type")) sb.append(headers.get("Content-Type"));
+		sb.append('\n');
+		if (containsKeyIgnoreCase(headers, "x-amz-date")) {
+			sb.append('\n');
+		} else {
+			sb.append(headers.get("Date")).append('\n');
+		}
+		sb.append(getCanonicalizedAmzHeaders(headers));
+		sb.append(getCanonicalizedResource(headers));
+		return sb.toString();
+	}
+	
+	private String getCanonicalizedAmzHeaders(Map<String, String> headers) {
+		// 1 & 2, Compose lowercase, sorted map of x-amz headers
+		TreeMap<String, String> xamzMap = new TreeMap<String, String>();
+		for (String key : headers.keySet()) {
+			if (key.toLowerCase().startsWith("x-amz-")) {
+				xamzMap.put(key.toLowerCase(), headers.get(key));
+			}
+		}
+		
+		// 3: Combine like headers (e.g. x-amz-common: val1,val2)
+		// No. Map<String, List<String>> isn't happening.
+		
+		// 4: Unfold long headers that span multiple lines
+		// No. Don't send in long header lines.
+		
+		// 5 & 6: Construct final string
+		StringBuilder sb = new StringBuilder();
+		for (String key : xamzMap.keySet()) {
+			sb.append(key).append(':').append(xamzMap.get(key)).append('\n');	// TODO: include newline on last header?
+		}
+		return sb.toString();
+	}
+	
+	private String getCanonicalizedResource(Map<String, String> headers) {
+		// 1: Start with empty string
+		StringBuilder sb = new StringBuilder();
+		
+		// 2: Add bucket if present
+		if (headers.containsKey("Host")) {
+			String host = headers.get("Host");
+			if (!host.startsWith("s3.")) {
+				sb.append('/').append(host.substring(0, host.indexOf('.')));
+			}
+		}
+		
+		// 3: Add HTTP Request URI up to but not including query
+		int queryIdx = path.indexOf('?');
+		if (queryIdx == -1) {
+			sb.append(this.path);
+		} else {
+			sb.append(path.substring(0, queryIdx));
+			
+			// 4: Add sub-resources if present
+			String queryString = path.substring(queryIdx, path.length());
+			for (String subResource : subResources) {
+				if (queryString.startsWith(subResource)) {
+					sb.append(subResource);
+					break;
+				}
+			}
+		}
+		return sb.toString();
+	}
+	
+	/*
+	 * Case-agnostic function that determines if a key is contained within a
+	 * map.
+	 */
+	private boolean containsKeyIgnoreCase(Map<String, String> map, String aKey) {
+		for (String key : map.keySet())
+			if (key.equalsIgnoreCase(aKey)) return true;
+		return false;
+	}
+}

Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java?rev=997113&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java Tue Sep 14 21:57:01 2010
@@ -0,0 +1,20 @@
+package simplecloud.storage.providers.amazon;
+
+import base.connection.ResponseHandler;
+import base.interfaces.IResponse;
+
+/*
+ * Custom handles responses from S3.
+ * 
+ * TODO: override parseError()
+ */
+public class S3Handler extends ResponseHandler {
+
+	public S3Handler(IResponse response) {
+		super(response);
+	}
+	
+	protected void parseBody() {
+		object = null;
+	}
+}