Permalink
Browse files

Merge branch 'dev' of https://github.com/WindowsAzure/azure-sdk-for-java

 into dev
  • Loading branch information...
2 parents 63a6eff + f8a5aee commit 290d22a67385601308d9444e98af84bfc3db164d @adashcolinr committed May 9, 2012
View
@@ -1,3 +1,8 @@
+2012.05.02 Version 0.2.2
+ * Added Javadoc comments to Azure Blob Service Layer
+ * Fixed a URL encoding issue in Table Client Layer
+ * Made CloudTableClient use Iterator instead of Iterable
+
2012.04.11 Version 0.2.1
* Added Service Layer support for Azure Table
* Added Javadoc comments to Azure Queue Service Layer
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.microsoft.windowsazure</groupId>
<artifactId>microsoft-windowsazure-api</artifactId>
- <version>0.2.1</version>
+ <version>0.2.2</version>
<packaging>jar</packaging>
<name>Microsoft Windows Azure Client API</name>
@@ -36,7 +36,7 @@
import com.microsoft.windowsazure.services.core.storage.utils.PathUtility;
import com.microsoft.windowsazure.services.core.storage.utils.Utility;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.ExecutionEngine;
-import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterator;
+import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterable;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.ListingContext;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.SegmentedStorageOperation;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.StorageOperation;
@@ -534,7 +534,7 @@ public int getWriteBlockSizeInBytes() {
}
};
- return new LazySegmentedIterator<CloudBlobClient, Void, CloudBlobContainer>(impl, this, null,
+ return new LazySegmentedIterable<CloudBlobClient, Void, CloudBlobContainer>(impl, this, null,
options.getRetryPolicyFactory(), opContext);
}
@@ -42,7 +42,7 @@
import com.microsoft.windowsazure.services.core.storage.utils.UriQueryBuilder;
import com.microsoft.windowsazure.services.core.storage.utils.Utility;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.ExecutionEngine;
-import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterator;
+import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterable;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.SegmentedStorageOperation;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.StorageOperation;
@@ -1273,7 +1273,7 @@ public URI getUri() {
}
};
- return new LazySegmentedIterator<CloudBlobClient, CloudBlobContainer, ListBlobItem>(impl,
+ return new LazySegmentedIterable<CloudBlobClient, CloudBlobContainer, ListBlobItem>(impl,
this.blobServiceClient, this, options.getRetryPolicyFactory(), opContext);
}
@@ -0,0 +1,76 @@
+/**
+ * Copyright 2011 Microsoft Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.microsoft.windowsazure.services.core.storage.utils.implementation;
+
+import java.util.Iterator;
+
+import com.microsoft.windowsazure.services.core.storage.OperationContext;
+import com.microsoft.windowsazure.services.core.storage.ResultSegment;
+import com.microsoft.windowsazure.services.core.storage.RetryPolicyFactory;
+
+/**
+ * RESERVED FOR INTERNAL USE. Provides a lazy iterator which will retrieve the next segment of a result as the iterator
+ * is consumed
+ *
+ * @param <CLIENT_TYPE>
+ * The service client type
+ * @param <PARENT_TYPE>
+ * The type of the parent object, i.e. CloudBlobClient for ListContainers etc.
+ * @param <ENTITY_TYPE>
+ * The type of the objects the resulting iterable objects
+ */
+public final class LazySegmentedIterable<CLIENT_TYPE, PARENT_TYPE, ENTITY_TYPE> implements Iterable<ENTITY_TYPE> {
+ /**
+ * Holds the service client associated with the operations.
+ */
+ private final CLIENT_TYPE client;
+
+ /**
+ * Holds a reference to the parent object, i.e. CloudBlobContainer for list blobs.
+ */
+ private final PARENT_TYPE parentObject;
+
+ /**
+ * Holds the reference to the RetryPolicyFactory object.
+ */
+ private final RetryPolicyFactory policyFactory;
+
+ /**
+ * Holds the SegmentedStorageOperation which is used to retrieve the next segment of results.
+ */
+ private final SegmentedStorageOperation<CLIENT_TYPE, PARENT_TYPE, ResultSegment<ENTITY_TYPE>> segmentGenerator;
+
+ /**
+ * Holds an object used to track the execution of the operation
+ */
+ private final OperationContext opContext;
+
+ public LazySegmentedIterable(
+ final SegmentedStorageOperation<CLIENT_TYPE, PARENT_TYPE, ResultSegment<ENTITY_TYPE>> segmentGenerator,
+ final CLIENT_TYPE client, final PARENT_TYPE parent, final RetryPolicyFactory policyFactory,
+ final OperationContext opContext) {
+ this.segmentGenerator = segmentGenerator;
+ this.parentObject = parent;
+ this.opContext = opContext;
+ this.policyFactory = policyFactory;
+ this.client = client;
+ }
+
+ @Override
+ public Iterator<ENTITY_TYPE> iterator() {
+ return new LazySegmentedIterator<CLIENT_TYPE, PARENT_TYPE, ENTITY_TYPE>(this.segmentGenerator, this.client,
+ this.parentObject, this.policyFactory, this.opContext);
+ }
+}
@@ -34,8 +34,7 @@
* @param <ENTITY_TYPE>
* The type of the objects the resulting iterable objects
*/
-public final class LazySegmentedIterator<CLIENT_TYPE, PARENT_TYPE, ENTITY_TYPE> implements Iterator<ENTITY_TYPE>,
- Iterable<ENTITY_TYPE> {
+public final class LazySegmentedIterator<CLIENT_TYPE, PARENT_TYPE, ENTITY_TYPE> implements Iterator<ENTITY_TYPE> {
/**
* Holds the current segment of results.
@@ -126,14 +125,6 @@ public boolean hasNext() {
return this.currentSegmentIterator.hasNext();
}
- /**
- * Gets a reference to the iterator.
- */
- @Override
- public Iterator<ENTITY_TYPE> iterator() {
- return this;
- }
-
/**
* Returns the next element.
*/
@@ -36,7 +36,7 @@
import com.microsoft.windowsazure.services.core.storage.StorageException;
import com.microsoft.windowsazure.services.core.storage.utils.Utility;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.ExecutionEngine;
-import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterator;
+import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterable;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.ListingContext;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.SegmentedStorageOperation;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.StorageOperation;
@@ -164,7 +164,7 @@ public CloudQueue getQueueReference(final String queueAddress) throws URISyntaxE
}
};
- return new LazySegmentedIterator<CloudQueueClient, Void, CloudQueue>(impl, this, null,
+ return new LazySegmentedIterable<CloudQueueClient, Void, CloudQueue>(impl, this, null,
options.getRetryPolicyFactory(), opContext);
}
@@ -39,7 +39,7 @@
import com.microsoft.windowsazure.services.core.storage.StorageException;
import com.microsoft.windowsazure.services.core.storage.utils.Utility;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.ExecutionEngine;
-import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterator;
+import com.microsoft.windowsazure.services.core.storage.utils.implementation.LazySegmentedIterable;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.SegmentedStorageOperation;
import com.microsoft.windowsazure.services.core.storage.utils.implementation.StorageOperation;
@@ -1325,7 +1325,7 @@ public TableResult execute(final String tableName, final TableOperation operatio
}
};
- return new LazySegmentedIterator<CloudTableClient, TableQuery<T>, T>(impl, this, queryRef,
+ return new LazySegmentedIterable<CloudTableClient, TableQuery<T>, T>(impl, this, queryRef,
options.getRetryPolicyFactory(), opContext);
}
else {
@@ -1349,7 +1349,7 @@ public TableResult execute(final String tableName, final TableOperation operatio
return result;
}
};
- return new LazySegmentedIterator<CloudTableClient, TableQuery<T>, R>(impl, this, queryRef,
+ return new LazySegmentedIterable<CloudTableClient, TableQuery<T>, R>(impl, this, queryRef,
options.getRetryPolicyFactory(), opContext);
}
}
@@ -142,17 +142,35 @@ public void listTablesWithIterator() throws IOException, URISyntaxException, Sto
try {
// With prefix
int currTable = 0;
- for (String s : tClient.listTables(tableBaseName, null, null)) {
+ Iterable<String> listTables = tClient.listTables(tableBaseName, null, null);
+ for (String s : listTables) {
Assert.assertEquals(s,
String.format("%s%s", tableBaseName, new DecimalFormat("#0000").format(currTable)));
currTable++;
}
+ Assert.assertEquals(20, currTable);
+ // Second Iteration
+ currTable = 0;
+ for (String s : listTables) {
+ Assert.assertEquals(s,
+ String.format("%s%s", tableBaseName, new DecimalFormat("#0000").format(currTable)));
+ currTable++;
+ }
Assert.assertEquals(20, currTable);
// Without prefix
currTable = 0;
- for (String s : tClient.listTables()) {
+ Iterable<String> listTablesNoPrefix = tClient.listTables();
+ for (String s : listTablesNoPrefix) {
+ if (s.startsWith(tableBaseName)) {
+ currTable++;
+ }
+ }
+
+ Assert.assertEquals(20, currTable);
+ currTable = 0;
+ for (String s : listTablesNoPrefix) {
if (s.startsWith(tableBaseName)) {
currTable++;
}
@@ -20,6 +20,7 @@
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
@@ -59,6 +60,54 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK
}
}
+ @Test
+ public void tableQueryIterateTwice() {
+ // Create entity to check against
+ class1 randEnt = TableTestBase.generateRandomEnitity(null);
+
+ final Iterable<DynamicTableEntity> result = tClient.execute(TableQuery.from(testSuiteTableName,
+ DynamicTableEntity.class).take(50));
+
+ ArrayList<DynamicTableEntity> firstIteration = new ArrayList<DynamicTableEntity>();
+ ArrayList<DynamicTableEntity> secondIteration = new ArrayList<DynamicTableEntity>();
+
+ // Validate results
+ for (DynamicTableEntity ent : result) {
+ Assert.assertEquals(ent.getProperties().size(), 4);
+ Assert.assertEquals(ent.getProperties().get("A").getValueAsString(), randEnt.getA());
+ Assert.assertEquals(ent.getProperties().get("B").getValueAsString(), randEnt.getB());
+ Assert.assertEquals(ent.getProperties().get("C").getValueAsString(), randEnt.getC());
+ Assert.assertTrue(Arrays.equals(ent.getProperties().get("D").getValueAsByteArray(), randEnt.getD()));
+ firstIteration.add(ent);
+ }
+
+ // Validate results
+ for (DynamicTableEntity ent : result) {
+ Assert.assertEquals(ent.getProperties().size(), 4);
+ Assert.assertEquals(ent.getProperties().get("A").getValueAsString(), randEnt.getA());
+ Assert.assertEquals(ent.getProperties().get("B").getValueAsString(), randEnt.getB());
+ Assert.assertEquals(ent.getProperties().get("C").getValueAsString(), randEnt.getC());
+ Assert.assertTrue(Arrays.equals(ent.getProperties().get("D").getValueAsByteArray(), randEnt.getD()));
+ secondIteration.add(ent);
+ }
+
+ Assert.assertEquals(firstIteration.size(), secondIteration.size());
+ for (int m = 0; m < firstIteration.size(); m++) {
+ Assert.assertEquals(firstIteration.get(m).getPartitionKey(), secondIteration.get(m).getPartitionKey());
+ Assert.assertEquals(firstIteration.get(m).getRowKey(), secondIteration.get(m).getRowKey());
+ Assert.assertEquals(firstIteration.get(m).getProperties().size(), secondIteration.get(m).getProperties()
+ .size());
+ Assert.assertEquals(firstIteration.get(m).getProperties().get("A").getValueAsString(),
+ secondIteration.get(m).getProperties().get("A").getValueAsString());
+ Assert.assertEquals(firstIteration.get(m).getProperties().get("B").getValueAsString(),
+ secondIteration.get(m).getProperties().get("B").getValueAsString());
+ Assert.assertEquals(firstIteration.get(m).getProperties().get("C").getValueAsString(),
+ secondIteration.get(m).getProperties().get("C").getValueAsString());
+ Assert.assertTrue(Arrays.equals(firstIteration.get(m).getProperties().get("D").getValueAsByteArray(),
+ secondIteration.get(m).getProperties().get("D").getValueAsByteArray()));
+ }
+ }
+
@Test
public void tableQueryWithDynamicEntity() {
// Create entity to check against

0 comments on commit 290d22a

Please sign in to comment.