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/19 00:16:14 UTC
svn commit: r998560 - in /incubator/libcloud/sandbox/java/trunk: ./ lib/
src/base/connection/ src/simplecloud/storage/
src/simplecloud/storage/interfaces/ src/simplecloud/storage/providers/amazon/
src/simplecloud/storage/providers/nirvanix/
Author: woodser
Date: Sat Sep 18 22:16:13 2010
New Revision: 998560
URL: http://svn.apache.org/viewvc?rev=998560&view=rev
Log:
*Nirvanix adapter added to SimpleCloud*
simplecloud > storage > Example.java illustrates how to interact with SimpleCloud APIs
In support of this driver, some structural changes were made:
- NirvanixAdapter, NirvanixConnection, and NirvanixHandler classes added
- HttpClient libraries updated to 4.1-alpha2 to support multipart-form posts for Nirvanix storeItem()
- IStorageAdapter interface changed to support generic Map<Object, Object> options parameter
Note: Cleanup work in ConnectionKey will soon follow to better support data posts and generic encodeData(Object)
Added:
incubator/libcloud/sandbox/java/trunk/lib/httpclient-4.1-alpha2.jar (with props)
incubator/libcloud/sandbox/java/trunk/lib/httpclient-cache-4.1-alpha2.jar (with props)
incubator/libcloud/sandbox/java/trunk/lib/httpcore-4.1-beta2.jar (with props)
incubator/libcloud/sandbox/java/trunk/lib/httpcore-nio-4.1-beta2.jar (with props)
incubator/libcloud/sandbox/java/trunk/lib/httpmime-4.1-alpha2.jar (with props)
incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixAdapter.java
incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixConnection.java
incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixHandler.java
Removed:
incubator/libcloud/sandbox/java/trunk/lib/httpclient-4.0.1.jar
incubator/libcloud/sandbox/java/trunk/lib/httpcore-4.0.1.jar
incubator/libcloud/sandbox/java/trunk/lib/httpmime-4.0.1.jar
Modified:
incubator/libcloud/sandbox/java/trunk/.classpath
incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java
incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java
incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java
incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java
Modified: incubator/libcloud/sandbox/java/trunk/.classpath
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/.classpath?rev=998560&r1=998559&r2=998560&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/.classpath (original)
+++ incubator/libcloud/sandbox/java/trunk/.classpath Sat Sep 18 22:16:13 2010
@@ -3,15 +3,17 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/apache-mime4j-0.6.jar"/>
+ <classpathentry kind="lib" path="lib/commons-codec-1.4.jar"/>
<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
- <classpathentry kind="lib" path="lib/httpclient-4.0.1.jar"/>
- <classpathentry kind="lib" path="lib/httpcore-4.0.1.jar"/>
- <classpathentry kind="lib" path="lib/httpmime-4.0.1.jar"/>
+ <classpathentry kind="lib" path="lib/httpclient-4.1-alpha2.jar"/>
+ <classpathentry kind="lib" path="lib/httpclient-cache-4.1-alpha2.jar"/>
+ <classpathentry kind="lib" path="lib/httpcore-4.1-beta2.jar"/>
+ <classpathentry kind="lib" path="lib/httpcore-nio-4.1-beta2.jar"/>
+ <classpathentry kind="lib" path="lib/httpmime-4.1-alpha2.jar"/>
<classpathentry kind="lib" path="lib/resolver.jar"/>
<classpathentry kind="lib" path="lib/serializer.jar"/>
<classpathentry kind="lib" path="lib/xercesImpl.jar"/>
<classpathentry kind="lib" path="lib/xercesSamples.jar"/>
<classpathentry kind="lib" path="lib/xml-apis.jar"/>
- <classpathentry kind="lib" path="lib/commons-codec-1.4.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Added: incubator/libcloud/sandbox/java/trunk/lib/httpclient-4.1-alpha2.jar
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/lib/httpclient-4.1-alpha2.jar?rev=998560&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/libcloud/sandbox/java/trunk/lib/httpclient-4.1-alpha2.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/libcloud/sandbox/java/trunk/lib/httpclient-cache-4.1-alpha2.jar
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/lib/httpclient-cache-4.1-alpha2.jar?rev=998560&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/libcloud/sandbox/java/trunk/lib/httpclient-cache-4.1-alpha2.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/libcloud/sandbox/java/trunk/lib/httpcore-4.1-beta2.jar
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/lib/httpcore-4.1-beta2.jar?rev=998560&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/libcloud/sandbox/java/trunk/lib/httpcore-4.1-beta2.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/libcloud/sandbox/java/trunk/lib/httpcore-nio-4.1-beta2.jar
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/lib/httpcore-nio-4.1-beta2.jar?rev=998560&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/libcloud/sandbox/java/trunk/lib/httpcore-nio-4.1-beta2.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/libcloud/sandbox/java/trunk/lib/httpmime-4.1-alpha2.jar
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/lib/httpmime-4.1-alpha2.jar?rev=998560&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/libcloud/sandbox/java/trunk/lib/httpmime-4.1-alpha2.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java?rev=998560&r1=998559&r2=998560&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java Sat Sep 18 22:16:13 2010
@@ -34,7 +34,7 @@ import base.interfaces.IItem;
/*
* Manages a connection with a secret access key.
*/
-public abstract class ConnectionKey implements IConnection {
+public class ConnectionKey implements IConnection {
protected String host;
@@ -99,6 +99,19 @@ public abstract class ConnectionKey impl
}
}
+ /*
+ * TODO: I think some drivers could be simplified if request() was
+ * overloaded to take in a full URL, including host & action. This is
+ * especially true for drivers that require multiple requests to retrieve
+ * e.g. a session token or DownloadNode for downloading content. This
+ * would prevent need to re-connect() for each of these requests.
+ *
+ * TODO: Rewrite in support of:
+ * string body content
+ * inputstream body content (use Item?)
+ * multipart form posts
+ * change to encodeData(Object data) for generic processing
+ */
public Response request(String method, String path,
Map<String, String> headers, Map<String, String> params, Object data) {
this.method = method;
Modified: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java?rev=998560&r1=998559&r2=998560&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java Sat Sep 18 22:16:13 2010
@@ -9,31 +9,57 @@ import java.util.HashMap;
import java.util.Map;
import simplecloud.storage.providers.amazon.S3Adapter;
+import simplecloud.storage.providers.nirvanix.NirvanixAdapter;
import base.types.Item;
public class Example {
-
- public static void main(String [] args) {
- S3Adapter adapter = new S3Adapter("your access key id", "your access key", "s3.amazonaws.com");
- Map<String, String> options = new HashMap<String, String>();
-
- // Upload something
+
+ public static void main(String[] args) {
+ // Nirvanix
try {
- String localPath = "/Users/Eric/libcloud_demo.jpg";
+ NirvanixAdapter nirvanix = new NirvanixAdapter("your application name", "your application key", "your username", "your password");
+ Map<Object, Object> options = new HashMap<Object, Object>();
+ String localPath = "/Users/Eric/Desktop/frozen.jpg";
String contentType = "image/jpeg";
File file = new File(localPath);
InputStream stream = new BufferedInputStream(new FileInputStream(file));
Item item = new Item(stream, contentType, null, file.length());
- options.put(S3Adapter.Type.SRC_BUCKET.toString(), "ericlibcloud");
- adapter.storeItem("/libcloud_demo_stored.jpg", item, options);
+ if (nirvanix.storeItem("/toby.jpg", item, options)) {
+ System.out.println("Upload succeeded");
+ } else {
+ System.out.println("Upload failed");
+ }
+ System.out.println("Nirvanix root: ");
+ options.put(NirvanixAdapter.Type.PAGE_NUMBER, "1");
+ options.put(NirvanixAdapter.Type.PAGE_SIZE, "10");
+ for (String name : nirvanix.listItems("/", options)) {
+ System.out.println('\t' + name);
+ }
} catch (FileNotFoundException e) {
e.printStackTrace();
}
-// options.put(S3Adapter.Type.SRC_BUCKET.toString(), "ericlibcloud");
-// for (String item : adapter.listItems("/", options)) {
-// System.out.println(item);
-// }
-// adapter.renameItem("/libcloud_demo.jpg", "libcloud_demo2.jpg", options);
+ // Amazon
+ try {
+ S3Adapter amazon = new S3Adapter("your access key id", "your access key", "s3.amazonaws.com");
+ Map<Object, Object> options = new HashMap<Object, Object>();
+ String localPath = "/Users/Eric/Desktop/frozen.jpg";
+ String contentType = "image/jpeg";
+ File file = new File(localPath);
+ InputStream stream = new BufferedInputStream(new FileInputStream(file));
+ Item item = new Item(stream, contentType, null, file.length());
+ options.put(S3Adapter.Type.SRC_BUCKET, "ericlibcloud");
+ if (amazon.storeItem("/toby.jpg", item, options)) {
+ System.out.println("Upload succeeded");
+ } else {
+ System.out.println("Upload failed");
+ }
+ System.out.println("Amazon root:");
+ for (String name : amazon.listItems("/", options)) {
+ System.out.println('\t' + name);
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
}
}
Modified: 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=998560&r1=998559&r2=998560&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java Sat Sep 18 22:16:13 2010
@@ -10,26 +10,27 @@ import base.interfaces.IItem;
*
* TODO: Comments
* TODO: For every return void, why not return status? PHP doesn't.
+ * TODO: listItems() return List<Map<String, Object>> for attributes instead of names?
*/
public interface IStorageAdapter {
- public IItem fetchItem(String path, Map<String, String> options);
+ public IItem fetchItem(String path, Map<Object, Object> options);
- public boolean storeItem(String destinationPath, IItem item, Map<String, String> options);
+ public boolean storeItem(String destinationPath, IItem item, Map<Object, Object> options);
- public void deleteItem(String path, Map<String, String> options);
+ public void deleteItem(String path, Map<Object, Object> options);
- public void copyItem(String sourcePath, String destinationPath, Map<String, String> options);
+ public void copyItem(String sourcePath, String destinationPath, Map<Object, Object> options);
- public void moveItem(String sourcePath, String destinationPath, Map<String, String> options);
+ public void moveItem(String sourcePath, String destinationPath, Map<Object, Object> options);
- public void renameItem(String path, String name, Map<String, String> options);
+ public void renameItem(String path, String name, Map<Object, Object> options);
- public List<String> listItems(String path, Map<String, String> options);
+ public List<String> listItems(String path, Map<Object, Object> options);
- public Map<String, String> fetchMetadata(String path, Map<String, String> options);
+ public Map<String, String> fetchMetadata(String path, Map<Object, Object> options);
- public void storeMetadata(String destinationPath, Map<String, String> metadata, Map<String, String> options);
+ public void storeMetadata(String destinationPath, Map<String, String> metadata, Map<Object, Object> options);
- public void deleteMetadata(String path, Map<String, String> options);
+ public void deleteMetadata(String path, Map<Object, Object> options);
}
Modified: 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=998560&r1=998559&r2=998560&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java Sat Sep 18 22:16:13 2010
@@ -25,25 +25,21 @@ import base.interfaces.IResponse;
/*
* Adapter for interacting with Amazon S3.
+ *
+ * TODO: different locations
+ * TODO: comment required option parameters
+ * TODO: general comments
*/
public class S3Adapter extends StorageAdapter {
private final String HOST;
/*
- * TEMP TODO: see if this is of value.
+ * Constant keys for options.
*/
public enum Type {
- SRC_BUCKET("srcBucket"),
- DEST_BUCKET("destBucket");
-
- private String value;
- private Type(String value) {
- this.value = value;
- }
- public String toString() {
- return this.value;
- }
+ SRC_BUCKET,
+ DEST_BUCKET;
}
/*
@@ -58,32 +54,32 @@ public class S3Adapter extends StorageAd
connection = new S3Connection(accessId, accessKey, host, this);
}
- public IItem fetchItem(String path, Map<String, String> options) {
- String bucket = options.get(Type.SRC_BUCKET.toString());
+ public IItem fetchItem(String path, Map<Object, Object> options) {
+ String bucket = (String)options.get(Type.SRC_BUCKET);
connection.connect(bucket + '.' + HOST);
IResponse response = connection.request("GET", path, null, null, null);
S3Handler rh = new S3Handler(response);
return (IItem)rh.getParsedObject();
}
- public boolean storeItem(String destinationPath, IItem item, Map<String, String> options) {
- String bucket = options.get(Type.SRC_BUCKET.toString());
+ public boolean storeItem(String destinationPath, IItem item, Map<Object, Object> options) {
+ String bucket = (String)options.get(Type.SRC_BUCKET);
connection.connect(bucket + '.' + HOST);
IResponse response = connection.request("PUT", destinationPath, null, null, item);
new S3Handler(response);
return response.getStatus() == 200;
}
- public void deleteItem(String path, Map<String, String> options) {
- String bucket = options.get(Type.SRC_BUCKET.toString());
+ public void deleteItem(String path, Map<Object, Object> options) {
+ String bucket = (String)options.get(Type.SRC_BUCKET);
connection.connect(bucket + '.' + HOST);
IResponse response = connection.request("DELETE", path, null, null, null);
new S3Handler(response);
}
- public void copyItem(String sourcePath, String destinationPath, Map<String, String> options) {
- String srcBucket = options.get(Type.SRC_BUCKET.toString());
- String destBucket = options.get(Type.DEST_BUCKET.toString());
+ public void copyItem(String sourcePath, String destinationPath, Map<Object, Object> options) {
+ String srcBucket = (String)options.get(Type.SRC_BUCKET);
+ String destBucket = (String)options.get(Type.DEST_BUCKET);
connection.connect(destBucket + '.' + HOST);
Map<String, String> headers = new HashMap<String, String>();
headers.put("x-amz-copy-source", '/' + srcBucket + sourcePath);
@@ -91,11 +87,10 @@ public class S3Adapter extends StorageAd
new S3Handler(response);
}
- public void moveItem(String sourcePath, String destinationPath,
- Map<String, String> options) {
+ public void moveItem(String sourcePath, String destinationPath, Map<Object, Object> options) {
// Copy the item
- String srcBucket = options.get(Type.SRC_BUCKET.toString());
- String destBucket = options.get(Type.DEST_BUCKET.toString());
+ String srcBucket = (String)options.get(Type.SRC_BUCKET);
+ String destBucket = (String)options.get(Type.DEST_BUCKET);
connection.connect(destBucket + '.' + HOST);
Map<String, String> headers = new HashMap<String, String>();
headers.put("x-amz-copy-source", '/' + srcBucket + sourcePath);
@@ -108,14 +103,14 @@ public class S3Adapter extends StorageAd
new S3Handler(response);
}
- public void renameItem(String path, String name, Map<String, String> options) {
+ public void renameItem(String path, String name, Map<Object, Object> options) {
String destPath = path.substring(0, path.lastIndexOf('/') + 1) + name;
- options.put(Type.DEST_BUCKET.toString(), options.get(Type.SRC_BUCKET.toString()));
+ options.put(Type.DEST_BUCKET, options.get(Type.SRC_BUCKET));
moveItem(path, destPath, options);
}
- public List<String> listItems(String path, Map<String, String> options) {
- String bucket = options.get(Type.SRC_BUCKET.toString());
+ public List<String> listItems(String path, Map<Object, Object> options) {
+ String bucket = (String)options.get(Type.SRC_BUCKET);
connection.connect(bucket + '.' + HOST);
IResponse response = connection.request("GET", path, null, null, null);
S3Handler rh = new S3Handler(response);
@@ -136,21 +131,19 @@ public class S3Adapter extends StorageAd
}
@Override
- public Map<String, String> fetchMetadata(String path,
- Map<String, String> options) {
+ public Map<String, String> fetchMetadata(String path, Map<Object, Object> options) {
// TODO Auto-generated method stub
return null;
}
@Override
- public void storeMetadata(String destinationPath,
- Map<String, String> metadata, Map<String, String> options) {
+ public void storeMetadata(String destinationPath, Map<String, String> metadata, Map<Object, Object> options) {
// TODO Auto-generated method stub
}
@Override
- public void deleteMetadata(String path, Map<String, String> options) {
+ public void deleteMetadata(String path, Map<Object, Object> options) {
// TODO Auto-generated method stub
}
Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixAdapter.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixAdapter.java?rev=998560&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixAdapter.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixAdapter.java Sat Sep 18 22:16:13 2010
@@ -0,0 +1,312 @@
+package simplecloud.storage.providers.nirvanix;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+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 org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIUtils;
+import org.apache.http.entity.mime.MultipartEntity;
+import org.apache.http.entity.mime.content.InputStreamBody;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import simplecloud.storage.interfaces.IStorageAdapter;
+import base.Driver;
+import base.connection.ConnectionKey;
+import base.connection.Response;
+import base.interfaces.IItem;
+import base.interfaces.IResponse;
+
+/*
+ * TODO: comment required option parameters
+ * TODO: general comments
+ * TODO: test url encoding of paths
+ */
+public class NirvanixAdapter extends Driver implements IStorageAdapter {
+
+ private static final String HOST = "services.nirvanix.com";
+
+ private String sessionToken;
+
+ private String appName;
+
+ private String account;
+
+ /*
+ * Constant keys for option parameters.
+ */
+ public enum Type {
+ PAGE_NUMBER,
+ PAGE_SIZE,
+ ITEM_TYPE,
+ FILE,
+ FOLDER;
+ }
+
+ public NirvanixAdapter(String appName, String appKey, String username, String password) {
+ this.connection = new NirvanixConnection(appKey, username, password, HOST, this);
+ this.sessionToken = ((NirvanixConnection)connection).getSessionToken();
+ this.appName = appName;
+ this.account = username;
+ }
+
+ public IItem fetchItem(String path, Map<Object, Object> options) {
+ // First get the DownloadNode
+ Map<String, String> nodeParams = new HashMap<String, String>();
+ nodeParams.put("sessionToken", sessionToken);
+ nodeParams.put("filePath", path);
+ IResponse nodeResponse = connection.request("GET", "/ws/IMFS/GetDownloadNodes.ashx", null, nodeParams, null);
+ NirvanixHandler handler = new NirvanixHandler(nodeResponse);
+ String node = parseDownloadNodes((Document)handler.getParsedObject()).get(0);
+
+ // Download content from node
+ Map<String, String> downloadParams = new HashMap<String, String>();
+ downloadParams.put("sessionToken", sessionToken);
+ ConnectionKey downloadConnection = new ConnectionKey(null, true, node, this);
+ String action;
+ try {
+ action = '/' + appName + '/' + account + URLEncoder.encode(path, "UTF-8");
+ IResponse downloadResponse = downloadConnection.request("GET", action, null, downloadParams, null);
+ if (downloadResponse.getStatus() == 200) return downloadResponse.getItem();
+ new NirvanixHandler(downloadResponse);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return null; // Error
+ }
+
+ /*
+ * TODO: This was hacked together because of lacking multipart-form posts in ConnectionKey.
+ */
+ public boolean storeItem(String destinationPath, IItem item, Map<Object, Object> options) {
+ // First get the StorageNode
+ Map<String, String> nodeParams = new HashMap<String, String>();
+ nodeParams.put("sessionToken", sessionToken);
+ nodeParams.put("sizeBytes", String.valueOf(item.getContentLength()));
+ IResponse nodeResponse = connection.request("GET", "/ws/IMFS/GetStorageNode.ashx", null, nodeParams, null);
+ NirvanixHandler handler = new NirvanixHandler(nodeResponse);
+ String uploadHost = parseUploadHost((Document)handler.getParsedObject());
+ String uploadToken = parseUploadToken((Document)handler.getParsedObject());
+
+ // Parse directory & filename
+ String directory = destinationPath.substring(0, destinationPath.lastIndexOf('/') + 1);
+ String filename = destinationPath.substring(destinationPath.lastIndexOf('/'), destinationPath.length());
+
+ // Create URI endpoint
+ Map<String, String> uploadParams = new HashMap<String, String>();
+ uploadParams.put("uploadToken", uploadToken);
+ uploadParams.put("destFolderPath", directory);
+ URI uri = null;
+ try {
+ uri = URIUtils.createURI("http", uploadHost, -1, "/Upload.ashx", ConnectionKey.urlEncodeMap(uploadParams), null);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ return false;
+ }
+ HttpPost httppost = new HttpPost(uri);
+
+ // Build request entity
+ MultipartEntity entity = new MultipartEntity();
+ InputStreamBodyLength isbl = new InputStreamBodyLength(item.getContent(), item.getContentType(), filename, item.getContentLength());
+ entity.addPart("fileContent", isbl);
+ httppost.setEntity(entity);
+
+ // POST file to the server
+ HttpClient httpclient = new DefaultHttpClient();
+ try {
+ IResponse response = new Response(httpclient.execute(httppost));
+ new NirvanixHandler(response);
+ return true;
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false; // Error
+ }
+
+ public void deleteItem(String path, Map<Object, Object> options) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("sessionToken", sessionToken);
+ Type itemType = (Type)options.get(Type.ITEM_TYPE);
+ IResponse response = null;
+ if (itemType == Type.FOLDER) {
+ params.put("folderPath", path);
+ response = connection.request("GET", "/ws/IMFS/DeleteFolders.ashx", null, params, null);
+ } else {
+ params.put("filePath", path);
+ response = connection.request("GET", "/ws/IMFS/DeleteFiles.ashx", null, params, null);
+ }
+ new NirvanixHandler(response);
+ }
+
+ public void copyItem(String sourcePath, String destinationPath, Map<Object, Object> options) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("sessionToken", sessionToken);
+ Type itemType = (Type)options.get(Type.ITEM_TYPE);
+ IResponse response = null;
+ if (itemType == Type.FOLDER) {
+ params.put("srcFolderPath", sourcePath);
+ params.put("destFolderPath", destinationPath);
+ response = connection.request("GET", "/ws/IMFS/CopyFolders.ashx", null, params, null);
+ } else {
+ params.put("srcFilePath", sourcePath);
+ params.put("destFolderPath", destinationPath);
+ response = connection.request("GET", "/ws/IMFS/CopyFiles.ashx", null, params, null);
+ }
+ new NirvanixHandler(response);
+ }
+
+ public void moveItem(String sourcePath, String destinationPath, Map<Object, Object> options) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("sessionToken", sessionToken);
+ Type itemType = (Type)options.get(Type.ITEM_TYPE);
+ IResponse response = null;
+ if (itemType == Type.FOLDER) {
+ params.put("srcFolderPath", sourcePath);
+ params.put("destFolderPath", destinationPath);
+ response = connection.request("GET", "/ws/IMFS/MoveFolders.ashx", null, params, null);
+ } else {
+ params.put("srcFilePath", sourcePath);
+ params.put("destFolderPath", destinationPath);
+ response = connection.request("GET", "/ws/IMFS/MoveFiles.ashx", null, params, null);
+ }
+ new NirvanixHandler(response);
+ }
+
+ public void renameItem(String path, String name, Map<Object, Object> options) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("sessionToken", sessionToken);
+ Type itemType = (Type)options.get(Type.ITEM_TYPE);
+ IResponse response = null;
+ if (itemType == Type.FOLDER) {
+ params.put("folderPath", path);
+ params.put("newFolderName", name);
+ response = connection.request("GET", "/ws/IMFS/RenameFolder.ashx", null, params, null);
+ } else {
+ params.put("filePath", path);
+ params.put("newFileName", name);
+ response = connection.request("GET", "/ws/IMFS/RenameFile.ashx", null, params, null);
+ }
+ new NirvanixHandler(response);
+ }
+
+ public List<String> listItems(String path, Map<Object, Object> options) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("sessionToken", sessionToken);
+ params.put("folderPath", path);
+ params.put("pageNumber", (String)options.get(Type.PAGE_NUMBER));
+ params.put("pageSize", (String)options.get(Type.PAGE_SIZE));
+ IResponse response = connection.request("GET", "/ws/IMFS/ListFolder.ashx" + path, null, params, null);
+ NirvanixHandler rh = new NirvanixHandler(response);
+ return parseItems((Document)rh.getParsedObject());
+ }
+
+ @Override
+ public Map<String, String> fetchMetadata(String path, Map<Object, Object> options) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void storeMetadata(String destinationPath, Map<String, String> metadata, Map<Object, Object> options) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void deleteMetadata(String path, Map<Object, Object> options) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private List<String> parseDownloadNodes(Document doc) {
+ try {
+ Element elem = doc.getDocumentElement();
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ List<String> nodes = new ArrayList<String>();
+ NodeList downloadNodes = (NodeList)xpath.evaluate("/Response/DownloadNode", elem, XPathConstants.NODESET);
+ for (int i = 0; i < downloadNodes.getLength(); i++) {
+ nodes.add(downloadNodes.item(i).getTextContent());
+ }
+ return nodes;
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return null; // Error
+ }
+
+ private String parseUploadHost(Document doc) {
+ try {
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ return xpath.evaluate("/Response/GetStorageNode/UploadHost", doc.getDocumentElement());
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return null; // Error
+ }
+
+ private String parseUploadToken(Document doc) {
+ try {
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ return xpath.evaluate("/Response/GetStorageNode/UploadToken", doc.getDocumentElement());
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return null; // Error
+ }
+
+ private List<String> parseItems(Document doc) {
+ try {
+ Element elem = doc.getDocumentElement();
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ List<String> items = new ArrayList<String>();
+ NodeList folders = (NodeList)xpath.evaluate("/Response/ListFolder/Folder/Name", elem, XPathConstants.NODESET);
+ for (int i = 0; i < folders.getLength(); i++) {
+ items.add(folders.item(i).getTextContent());
+ }
+ NodeList files = (NodeList)xpath.evaluate("/Response/ListFolder/File/Name", elem, XPathConstants.NODESET);
+ for (int i = 0; i < files.getLength(); i++) {
+ items.add(files.item(i).getTextContent());
+ }
+ return items;
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return null; // Error
+ }
+
+ /*
+ * Simple extension of InputStreamBody to support length.
+ *
+ * TODO: this is simply a hack until HttpClient-alpha2 matures
+ */
+ private class InputStreamBodyLength extends InputStreamBody {
+ private long length;
+ public InputStreamBodyLength(InputStream in, String mimeType,
+ String filename, long length) {
+ super(in, mimeType, filename);
+ this.length = length;
+ }
+ public long getContentLength() {
+ return length;
+ }
+ }
+}
Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixConnection.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixConnection.java?rev=998560&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixConnection.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixConnection.java Sat Sep 18 22:16:13 2010
@@ -0,0 +1,76 @@
+package simplecloud.storage.providers.nirvanix;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.xml.sax.InputSource;
+
+import base.Driver;
+import base.connection.ConnectionUserAndKey;
+import base.interfaces.IResponse;
+
+/*
+ * Manages a connection to the Nirvanix storage cloud.
+ */
+public class NirvanixConnection extends ConnectionUserAndKey {
+
+ private String appKey;
+
+ private String sessionToken;
+
+ private static final boolean SECURE = true;
+
+ /*
+ * Constructs the Nirvanix connection.
+ *
+ * @param appKey is necessary to authenticate with the API
+ * @param accessId identifies the user connecting to Nirvanix
+ * @param accessKey is the user's secret key
+ * @param host defines Nirvanix's host server
+ * @param driver references the driver that owns this connection
+ */
+ public NirvanixConnection(String appKey, String accessId, String accessKey,
+ String host, Driver driver) {
+ super(accessId, accessKey, SECURE, host, driver);
+ this.appKey = appKey;
+ this.sessionToken = null;
+ refreshSessionToken();
+ }
+
+ /*
+ * Returns the session token that authenticates calls to the Nirvanix API.
+ * If this token expires, a new token must be issued using
+ * refreshSessionToken().
+ *
+ * @return String is the session token to authenticate API calls
+ */
+ public String getSessionToken() {
+ if (sessionToken == null) refreshSessionToken();
+ return sessionToken;
+ }
+
+ /*
+ * Refreshes the session token.
+ */
+ public void refreshSessionToken() {
+ // Request authentication
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("appKey", appKey);
+ params.put("username", accessId);
+ params.put("password", accessKey);
+ IResponse response = request("GET", "/ws/Authentication/Login.ashx", null, params, null);
+
+ // Parse response
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ try {
+ InputSource input = new InputSource(response.getItem().getContent());
+ sessionToken = xpath.evaluate("Response/SessionToken", input);
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+}
Added: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixHandler.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixHandler.java?rev=998560&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixHandler.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/nirvanix/NirvanixHandler.java Sat Sep 18 22:16:13 2010
@@ -0,0 +1,74 @@
+package simplecloud.storage.providers.nirvanix;
+
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import base.connection.ResponseHandler;
+import base.interfaces.IResponse;
+
+public class NirvanixHandler extends ResponseHandler {
+
+ private Document document;
+ private String responseCode;
+ private String phrase;
+
+ public NirvanixHandler(IResponse response) {
+ super(response);
+ this.responseCode = null;
+ this.phrase = null;
+ }
+
+ protected void parseBody() {
+ this.object = document;
+ }
+
+ protected String parseError() {
+ if (responseCode == null || phrase == null) {
+ return super.parseError();
+ }
+ return responseCode + ": " + phrase;
+ }
+
+ protected boolean success() {
+ // Simple error occurred
+ if (response.getStatus() != 200) {
+ return super.success();
+ }
+
+ // Further investigation needed; look at the body... bum bum bum.
+ try {
+ // Parse out document for future consumption
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ document = db.parse(response.getItem().getContent());
+
+ // Parse response for status
+ Element elem = document.getDocumentElement();
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ responseCode = xpath.evaluate("/Response/ResponseCode", elem);
+ if (!responseCode.equals("0")) {
+ phrase = xpath.evaluate("/Response/ErrorMessage", elem);
+ return false;
+ }
+ } catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ } catch (SAXException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return true; // Not guilty!
+ }
+}