diff --git a/ChangeLog.txt b/ChangeLog.txt
index f42d57277e0f6..79bfc2dca7940 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,4 +1,11 @@
-2012.01.31. Version 0.1.3
+2012.02.28 Version 0.2.0
+ * Added Support for Azure Table in com.microsoft.windowsazure.services.table
+ * Added Client Tests for Table
+ * Added a dependency on apache commons-lang3 3.1
+ * ResultsSegment exposes an ArrayList instead of an Iterable
+ * UserAgent updated to v1.1.2
+
+2012.01.31 Version 0.1.3
* Updated User Agent to v0.1.1
* Updated License Headers
* Blob Client Mark bug fix
@@ -8,7 +15,7 @@
* Date parsing support for various number of fractional decimals
* StorageErrorResponse updated to support lower case xml for tables
-2011.12.22. Version 0.1.2
+2011.12.22 Version 0.1.2
* Fixed CloudBlob.download to lock to ETag during a resume
* Ensured that Client Side Exceptions are not resumed
diff --git a/README.md b/README.md
index 4e942bcd59b5f..dbca6ec9f918c 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ Windows Azure Java Developer Center
Option 1: Via Git
To get the source code of the SDK via git just type:
git clone git://github.com/WindowsAzure/azure-sdk-for-java.git
-cd ./azure-sdk-for-java
+cd ./azure-sdk-for-java/microsoft-azure-api
mvn compile
Option 2: Via Maven
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/implementation/QueueRestProxy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/implementation/QueueRestProxy.java
index 4677d0431b818..5816a1bec264d 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/implementation/QueueRestProxy.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/implementation/QueueRestProxy.java
@@ -152,6 +152,9 @@ public void createQueue(String queue) throws ServiceException {
}
public void createQueue(String queue, CreateQueueOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue);
WebResource.Builder builder = webResource.header("x-ms-version", API_VERSION);
@@ -165,6 +168,9 @@ public void deleteQueue(String queue) throws ServiceException {
}
public void deleteQueue(String queue, QueueServiceOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue);
WebResource.Builder builder = webResource.header("x-ms-version", API_VERSION);
@@ -195,6 +201,9 @@ public GetQueueMetadataResult getQueueMetadata(String queue) throws ServiceExcep
}
public GetQueueMetadataResult getQueueMetadata(String queue, QueueServiceOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).queryParam("comp", "metadata");
Builder builder = webResource.header("x-ms-version", API_VERSION);
@@ -216,6 +225,9 @@ public void setQueueMetadata(String queue, HashMap metadata) thr
public void setQueueMetadata(String queue, HashMap metadata, QueueServiceOptions options)
throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).queryParam("comp", "metadata");
WebResource.Builder builder = webResource.header("x-ms-version", API_VERSION);
@@ -229,6 +241,9 @@ public void createMessage(String queue, String messageText) throws ServiceExcept
}
public void createMessage(String queue, String messageText, CreateMessageOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).path("messages");
webResource = addOptionalQueryParam(webResource, "visibilitytimeout", options.getVisibilityTimeoutInSeconds());
webResource = addOptionalQueryParam(webResource, "messagettl", options.getTimeToLiveInSeconds());
@@ -249,6 +264,11 @@ public UpdateMessageResult updateMessage(String queue, String messageId, String
public UpdateMessageResult updateMessage(String queue, String messageId, String popReceipt, String messageText,
int visibilityTimeoutInSeconds, QueueServiceOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+ if (messageId == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).path("messages").path(messageId);
webResource = addOptionalQueryParam(webResource, "popreceipt", popReceipt);
webResource = addOptionalQueryParam(webResource, "visibilitytimeout", visibilityTimeoutInSeconds);
@@ -272,6 +292,9 @@ public ListMessagesResult listMessages(String queue) throws ServiceException {
}
public ListMessagesResult listMessages(String queue, ListMessagesOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).path("messages");
webResource = addOptionalQueryParam(webResource, "visibilitytimeout", options.getVisibilityTimeoutInSeconds());
webResource = addOptionalQueryParam(webResource, "numofmessages", options.getNumberOfMessages());
@@ -286,6 +309,9 @@ public PeekMessagesResult peekMessages(String queue) throws ServiceException {
}
public PeekMessagesResult peekMessages(String queue, PeekMessagesOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).path("messages").queryParam("peekonly", "true");
webResource = addOptionalQueryParam(webResource, "numofmessages", options.getNumberOfMessages());
@@ -300,6 +326,11 @@ public void deleteMessage(String queue, String messageId, String popReceipt) thr
public void deleteMessage(String queue, String messageId, String popReceipt, QueueServiceOptions options)
throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+ if (messageId == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).path("messages").path(messageId);
webResource = addOptionalQueryParam(webResource, "popreceipt", popReceipt);
@@ -313,6 +344,9 @@ public void clearMessages(String queue) throws ServiceException {
}
public void clearMessages(String queue, QueueServiceOptions options) throws ServiceException {
+ if (queue == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(queue).path("messages");
Builder builder = webResource.header("x-ms-version", API_VERSION);
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/DefaultEdmValueConterter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/DefaultEdmValueConterter.java
index f7df91f533f51..41b38735afa51 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/DefaultEdmValueConterter.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/DefaultEdmValueConterter.java
@@ -22,6 +22,7 @@
import com.microsoft.windowsazure.services.blob.implementation.ISO8601DateConverter;
import com.microsoft.windowsazure.services.table.EdmValueConverter;
import com.microsoft.windowsazure.services.table.models.EdmType;
+import com.sun.jersey.core.util.Base64;
public class DefaultEdmValueConterter implements EdmValueConverter {
@@ -41,6 +42,9 @@ public String serialize(String edmType, Object value) {
if (value instanceof Date) {
serializedValue = iso8601DateConverter.shortFormat((Date) value);
}
+ else if (value instanceof byte[]) {
+ serializedValue = new String(Base64.encode((byte[]) value));
+ }
else {
serializedValue = value.toString();
}
@@ -73,6 +77,9 @@ else if (EdmType.INT32.equals(edmType)) {
else if (EdmType.INT64.equals(edmType)) {
return Long.parseLong(value);
}
+ else if (EdmType.BINARY.equals(edmType)) {
+ return Base64.decode(value);
+ }
return value;
}
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/TableRestProxy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/TableRestProxy.java
index bfeddfdb5c807..42cd3154bb240 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/TableRestProxy.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/TableRestProxy.java
@@ -249,7 +249,6 @@ private WebResource.Builder addIfMatchHeader(WebResource.Builder builder, String
private WebResource getResource(TableServiceOptions options) {
WebResource webResource = channel.resource(url).path("/");
- webResource = addOptionalQueryParam(webResource, "timeout", options.getTimeout());
for (ServiceFilter filter : filters) {
webResource.addFilter(new ClientFilterAdapter(filter));
}
@@ -282,6 +281,9 @@ public void setServiceProperties(ServiceProperties serviceProperties) throws Ser
@Override
public void setServiceProperties(ServiceProperties serviceProperties, TableServiceOptions options)
throws ServiceException {
+ if (serviceProperties == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path("/").queryParam("resType", "service")
.queryParam("comp", "properties");
@@ -297,6 +299,9 @@ public GetTableResult getTable(String table) throws ServiceException {
@Override
public GetTableResult getTable(String table, TableServiceOptions options) throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path("Tables" + "('" + table + "')");
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -369,6 +374,9 @@ public void createTable(String table) throws ServiceException {
@Override
public void createTable(String table, TableServiceOptions options) throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path("Tables");
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -387,6 +395,9 @@ public void deleteTable(String table) throws ServiceException {
@Override
public void deleteTable(String table, TableServiceOptions options) throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path("Tables" + "('" + table + "')");
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -405,6 +416,9 @@ public InsertEntityResult insertEntity(String table, Entity entity) throws Servi
@Override
public InsertEntityResult insertEntity(String table, Entity entity, TableServiceOptions options)
throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(table);
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -434,7 +448,7 @@ public UpdateEntityResult updateEntity(String table, Entity entity, TableService
@Override
public UpdateEntityResult mergeEntity(String table, Entity entity) throws ServiceException {
- return updateEntity(table, entity, new TableServiceOptions());
+ return mergeEntity(table, entity, new TableServiceOptions());
}
@Override
@@ -456,7 +470,7 @@ public UpdateEntityResult insertOrReplaceEntity(String table, Entity entity, Tab
@Override
public UpdateEntityResult insertOrMergeEntity(String table, Entity entity) throws ServiceException {
- return insertOrReplaceEntity(table, entity, new TableServiceOptions());
+ return insertOrMergeEntity(table, entity, new TableServiceOptions());
}
@Override
@@ -467,6 +481,9 @@ public UpdateEntityResult insertOrMergeEntity(String table, Entity entity, Table
private UpdateEntityResult putOrMergeEntityCore(String table, Entity entity, String verb, boolean includeEtag,
TableServiceOptions options) throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(
getEntityPath(table, entity.getPartitionKey(), entity.getRowKey()));
@@ -499,6 +516,9 @@ public void deleteEntity(String table, String partitionKey, String rowKey) throw
@Override
public void deleteEntity(String table, String partitionKey, String rowKey, DeleteEntityOptions options)
throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(getEntityPath(table, partitionKey, rowKey));
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -517,6 +537,9 @@ public GetEntityResult getEntity(String table, String partitionKey, String rowKe
@Override
public GetEntityResult getEntity(String table, String partitionKey, String rowKey, TableServiceOptions options)
throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+
WebResource webResource = getResource(options).path(getEntityPath(table, partitionKey, rowKey));
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -538,6 +561,11 @@ public QueryEntitiesResult queryEntities(String table) throws ServiceException {
@Override
public QueryEntitiesResult queryEntities(String table, QueryEntitiesOptions options) throws ServiceException {
+ if (table == null)
+ throw new NullPointerException();
+ if (options == null)
+ options = new QueryEntitiesOptions();
+
WebResource webResource = getResource(options).path(table);
webResource = addOptionalQuery(webResource, options.getQuery());
webResource = addOptionalQueryParam(webResource, "NextPartitionKey",
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/DeleteEntityOptions.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/DeleteEntityOptions.java
index 161087d46834a..4cce1e14a24a9 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/DeleteEntityOptions.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/DeleteEntityOptions.java
@@ -17,12 +17,6 @@
public class DeleteEntityOptions extends TableServiceOptions {
private String etag;
- @Override
- public DeleteEntityOptions setTimeout(Integer timeout) {
- super.setTimeout(timeout);
- return this;
- }
-
public String getEtag() {
return etag;
}
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryEntitiesOptions.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryEntitiesOptions.java
index fe6842b62082d..31c7d05652bc7 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryEntitiesOptions.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryEntitiesOptions.java
@@ -19,12 +19,6 @@ public class QueryEntitiesOptions extends TableServiceOptions {
public String nextPartitionKey;
public String nextRowKey;
- @Override
- public QueryEntitiesOptions setTimeout(Integer timeout) {
- super.setTimeout(timeout);
- return this;
- }
-
public Query getQuery() {
return query;
}
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryTablesOptions.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryTablesOptions.java
index 13cc7fcf70024..36b975d7a6900 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryTablesOptions.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/QueryTablesOptions.java
@@ -19,12 +19,6 @@ public class QueryTablesOptions extends TableServiceOptions {
private Query query;
private String prefix;
- @Override
- public QueryTablesOptions setTimeout(Integer timeout) {
- super.setTimeout(timeout);
- return this;
- }
-
public Query getQuery() {
return query;
}
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/ServiceProperties.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/ServiceProperties.java
index 73bffc9e03b67..01a18543864b1 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/ServiceProperties.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/ServiceProperties.java
@@ -42,9 +42,9 @@ public void setMetrics(Metrics metrics) {
public static class Logging {
private String version;
- private Boolean delete;
- private Boolean read;
- private Boolean write;
+ private boolean delete;
+ private boolean read;
+ private boolean write;
private RetentionPolicy retentionPolicy;
@XmlElement(name = "RetentionPolicy")
diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/TableServiceOptions.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/TableServiceOptions.java
index 69c19ecba5547..c4a733a6e3a6b 100644
--- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/TableServiceOptions.java
+++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/models/TableServiceOptions.java
@@ -15,15 +15,4 @@
package com.microsoft.windowsazure.services.table.models;
public class TableServiceOptions {
- // Nullable because it is optional
- private Integer timeout;
-
- public Integer getTimeout() {
- return timeout;
- }
-
- public TableServiceOptions setTimeout(Integer timeout) {
- this.timeout = timeout;
- return this;
- }
}
diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java
index 4a4146a5055db..5f14d2d82a1f7 100644
--- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java
+++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java
@@ -300,10 +300,11 @@ public void insertEntityWorks() throws Exception {
// Arrange
Configuration config = createConfiguration();
TableContract service = TableService.create(config);
+ byte[] binaryData = new byte[] { 1, 2, 3, 4 };
Entity entity = new Entity().setPartitionKey("001").setRowKey("insertEntityWorks")
.setProperty("test", EdmType.BOOLEAN, true).setProperty("test2", EdmType.STRING, "value")
.setProperty("test3", EdmType.INT32, 3).setProperty("test4", EdmType.INT64, 12345678901L)
- .setProperty("test5", EdmType.DATETIME, new Date());
+ .setProperty("test5", EdmType.DATETIME, new Date()).setProperty("test6", EdmType.BINARY, binaryData);
// Act
InsertEntityResult result = service.insertEntity(TEST_TABLE_2, entity);
@@ -331,6 +332,14 @@ public void insertEntityWorks() throws Exception {
assertNotNull(result.getEntity().getProperty("test5"));
assertTrue(result.getEntity().getProperty("test5").getValue() instanceof Date);
+
+ assertNotNull(result.getEntity().getProperty("test6"));
+ assertTrue(result.getEntity().getProperty("test6").getValue() instanceof byte[]);
+ byte[] returnedBinaryData = (byte[]) result.getEntity().getProperty("test6").getValue();
+ assertEquals(binaryData.length, returnedBinaryData.length);
+ for (int i = 0; i < binaryData.length; i++) {
+ assertEquals(binaryData[i], returnedBinaryData[i]);
+ }
}
@Test
@@ -465,10 +474,11 @@ public void getEntityWorks() throws Exception {
// Arrange
Configuration config = createConfiguration();
TableContract service = TableService.create(config);
+ byte[] binaryData = new byte[] { 1, 2, 3, 4 };
Entity entity = new Entity().setPartitionKey("001").setRowKey("getEntityWorks")
.setProperty("test", EdmType.BOOLEAN, true).setProperty("test2", EdmType.STRING, "value")
.setProperty("test3", EdmType.INT32, 3).setProperty("test4", EdmType.INT64, 12345678901L)
- .setProperty("test5", EdmType.DATETIME, new Date());
+ .setProperty("test5", EdmType.DATETIME, new Date()).setProperty("test6", EdmType.BINARY, binaryData);
// Act
InsertEntityResult insertResult = service.insertEntity(TEST_TABLE_2, entity);
@@ -498,6 +508,14 @@ public void getEntityWorks() throws Exception {
assertNotNull(result.getEntity().getProperty("test5"));
assertTrue(result.getEntity().getProperty("test5").getValue() instanceof Date);
+
+ assertNotNull(result.getEntity().getProperty("test6"));
+ assertTrue(result.getEntity().getProperty("test6").getValue() instanceof byte[]);
+ byte[] returnedBinaryData = (byte[]) result.getEntity().getProperty("test6").getValue();
+ assertEquals(binaryData.length, returnedBinaryData.length);
+ for (int i = 0; i < binaryData.length; i++) {
+ assertEquals(binaryData[i], returnedBinaryData[i]);
+ }
}
@Test