Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #180 from WindowsAzure/dev

Update to 0.3.3
  • Loading branch information...
commit 4b0a14abd4e5895066009a3d0abe9f3db40b37e3 2 parents 08c0b56 + a757f4c
@joostdenijs joostdenijs authored
Showing with 694 additions and 322 deletions.
  1. +8 −1 ChangeLog.txt
  2. +1 −1  README.md
  3. +252 −252 microsoft-azure-api/pom.xml
  4. +1 −1  ...soft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobDeserializationHelper.java
  5. +54 −23 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlob.java
  6. +13 −3 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlockBlob.java
  7. +12 −3 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudPageBlob.java
  8. +1 −1  microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CopyState.java
  9. +1 −1  microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/Constants.java
  10. +7 −2 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/utils/Utility.java
  11. +4 −1 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/CloudQueue.java
  12. +2 −4 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/QueuePermissions.java
  13. +3 −4 ...osoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/SharedAccessQueuePolicy.java
  14. +2 −2 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/AtomPubParser.java
  15. +3 −4 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/CloudTable.java
  16. +1 −1  microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/QueryTableOperation.java
  17. +173 −0 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java
  18. +9 −7 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/CloudQueueClientTests.java
  19. +109 −2 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/CloudQueueTests.java
  20. +3 −5 ...soft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableBatchOperationTests.java
  21. +14 −2 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableClientTests.java
  22. +2 −2 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableOperationTests.java
  23. +19 −0 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableSerializerTests.java
View
9 ChangeLog.txt
@@ -1,3 +1,10 @@
+2012.10.29 Version 0.3.3
+ * In the blob client, fixed a bug which allows users to call write APIs on a blob snapshot reference
+ * Updated the URL parse method in storage client libraries, to allow users to pass a URL ending with "/"
+ * Updated the parsing response header code in blob client APIs
+ * Updated the storage client library user agent version from 0.1.2 to 0.1.3
+ * Added more test cases in storage client tests
+
2012.10.16 Version 0.3.2
* Implemented a more graceful timeout Exception
* Implemented a better Exception for an empty header returned by the Azure Storage Service
@@ -37,7 +44,7 @@
2012.01.31 Version 0.1.3
* Updated User Agent to v0.1.1
* Updated License Headers
- * Blob Client Mark bug fix
+ * Blob Client Mark update
* Retry Logic updated in Blob and Queue Client to not retry
* Error Response parsing updated for Table compatibility
* MD5 is delay calculated on copy streams
View
2  README.md
@@ -41,7 +41,7 @@ within your project you can also have them installed by the Java package manager
<dependency>
<groupId>com.microsoft.windowsazure</groupId>
<artifactId>microsoft-windowsazure-api</artifactId>
- <version>0.3.1</version>
+ <version>0.3.3</version>
</dependency>
##Minimum Requirements
View
504 microsoft-azure-api/pom.xml
@@ -1,252 +1,252 @@
-<!--
- 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.microsoft.windowsazure</groupId>
- <artifactId>microsoft-windowsazure-api</artifactId>
- <version>0.3.2</version>
- <packaging>jar</packaging>
-
- <name>Microsoft Windows Azure Client API</name>
- <description>API for Microsoft Windows Azure Clients</description>
- <url>https://github.com/WindowsAzure/azure-sdk-for-java</url>
-
- <licenses>
- <license>
- <name>The Apache Software License, Version 2.0</name>
- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
- <distribution>repo</distribution>
- </license>
- </licenses>
-
- <scm>
- <url>scm:git:https://github.com/WindowsAzure/azure-sdk-for-java</url>
- <connection>scm:git:git://github.com/WindowsAzure/azure-sdk-for-java.git</connection>
- </scm>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <legal><![CDATA[[INFO] Any downloads listed may be third party software. Microsoft grants you no rights for third party software.]]></legal>
- </properties>
-
- <developers>
- <developer>
- <id>microsoft</id>
- <name>Microsoft</name>
- </developer>
- </developers>
-
- <dependencies>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-client</artifactId>
- <version>1.10-b02</version>
- </dependency>
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.1</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.8</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <version>1.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- <version>1.9.0-rc1</version>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>1.10-b02</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1.1</version>
- </dependency>
- <dependency>
- <groupId>javax.mail</groupId>
- <artifactId>mail</artifactId>
- <version>1.4</version>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.1</version>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-help-plugin</artifactId>
- <version>2.1.1</version>
- <executions>
- <execution>
- <phase>validate</phase>
- <goals>
- <goal>evaluate</goal>
- </goals>
- <configuration>
- <expression>legal</expression>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.6</source>
- <target>1.6</target>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.jvnet.jaxb2.maven2</groupId>
- <artifactId>maven-jaxb2-plugin</artifactId>
- <version>0.8.0</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>generate</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <extension>true</extension>
- <plugins>
- <plugin>
- <groupId>org.jvnet.jaxb2_commons</groupId>
- <artifactId>jaxb2-basics</artifactId>
- <version>0.6.0</version>
- </plugin>
- <plugin>
- <groupId>org.jvnet.jaxb2_commons</groupId>
- <artifactId>jaxb2-basics-annotate</artifactId>
- <version>0.6.0</version>
- </plugin>
- </plugins>
-
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8</version>
- <configuration>
- <excludePackageNames>*.implementation.*;*.utils.*;com.microsoft.schemas._2003._10.serialization</excludePackageNames>
- <bottom><![CDATA[<code>/**
-<br/>* Copyright 2011 Microsoft Corporation
-<br/>*
-<br/>* Licensed under the Apache License, Version 2.0 (the "License");
-<br/>* you may not use this file except in compliance with the License.
-<br/>* You may obtain a copy of the License at
-<br/>* http://www.apache.org/licenses/LICENSE-2.0
-<br/>*
-<br/>* Unless required by applicable law or agreed to in writing, software
-<br/>* distributed under the License is distributed on an "AS IS" BASIS,
-<br/>* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-<br/>* See the License for the specific language governing permissions and
-<br/>* limitations under the License.
-<br/>*/</code>]]></bottom>
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <xmlOutput>true</xmlOutput>
- <findbugsXmlOutput>true</findbugsXmlOutput>
- <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <version>2.8</version>
- <configuration>
- <configLocation>src/config/checkstyle.xml</configLocation>
- </configuration>
- </plugin>
-
-
- </plugins>
- <pluginManagement>
- <plugins>
- <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
- <plugin>
- <groupId>org.eclipse.m2e</groupId>
- <artifactId>lifecycle-mapping</artifactId>
- <version>1.0.0</version>
- <configuration>
- <lifecycleMappingMetadata>
- <pluginExecutions>
- <pluginExecution>
- <pluginExecutionFilter>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-help-plugin</artifactId>
- <versionRange>[2.1.1,)</versionRange>
- <goals>
- <goal>evaluate</goal>
- </goals>
- </pluginExecutionFilter>
- <action>
- <ignore></ignore>
- </action>
- </pluginExecution>
- </pluginExecutions>
- </lifecycleMappingMetadata>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.4.3</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.12</version>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-</project>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.microsoft.windowsazure</groupId>
+ <artifactId>microsoft-windowsazure-api</artifactId>
+ <version>0.3.3</version>
+ <packaging>jar</packaging>
+
+ <name>Microsoft Windows Azure Client API</name>
+ <description>API for Microsoft Windows Azure Clients</description>
+ <url>https://github.com/WindowsAzure/azure-sdk-for-java</url>
+
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <scm>
+ <url>scm:git:https://github.com/WindowsAzure/azure-sdk-for-java</url>
+ <connection>scm:git:git://github.com/WindowsAzure/azure-sdk-for-java.git</connection>
+ </scm>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <legal><![CDATA[[INFO] Any downloads listed may be third party software. Microsoft grants you no rights for third party software.]]></legal>
+ </properties>
+
+ <developers>
+ <developer>
+ <id>microsoft</id>
+ <name>Microsoft</name>
+ </developer>
+ </developers>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-client</artifactId>
+ <version>1.10-b02</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ <version>2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <version>1.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ <version>1.9.0-rc1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-json</artifactId>
+ <version>1.10-b02</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-help-plugin</artifactId>
+ <version>2.1.1</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>evaluate</goal>
+ </goals>
+ <configuration>
+ <expression>legal</expression>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+ <version>0.8.0</version>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <extension>true</extension>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-basics</artifactId>
+ <version>0.6.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-basics-annotate</artifactId>
+ <version>0.6.0</version>
+ </plugin>
+ </plugins>
+
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.8</version>
+ <configuration>
+ <excludePackageNames>*.implementation.*;*.utils.*;com.microsoft.schemas._2003._10.serialization</excludePackageNames>
+ <bottom><![CDATA[<code>/**
+<br/>* Copyright 2011 Microsoft Corporation
+<br/>*
+<br/>* Licensed under the Apache License, Version 2.0 (the "License");
+<br/>* you may not use this file except in compliance with the License.
+<br/>* You may obtain a copy of the License at
+<br/>* http://www.apache.org/licenses/LICENSE-2.0
+<br/>*
+<br/>* Unless required by applicable law or agreed to in writing, software
+<br/>* distributed under the License is distributed on an "AS IS" BASIS,
+<br/>* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+<br/>* See the License for the specific language governing permissions and
+<br/>* limitations under the License.
+<br/>*/</code>]]></bottom>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <xmlOutput>true</xmlOutput>
+ <findbugsXmlOutput>true</findbugsXmlOutput>
+ <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.8</version>
+ <configuration>
+ <configLocation>src/config/checkstyle.xml</configLocation>
+ </configuration>
+ </plugin>
+
+
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-help-plugin</artifactId>
+ <versionRange>[2.1.1,)</versionRange>
+ <goals>
+ <goal>evaluate</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore></ignore>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4.3</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.12</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
View
2  .../main/java/com/microsoft/windowsazure/services/blob/client/BlobDeserializationHelper.java
@@ -317,7 +317,7 @@ else if (name.equals(Constants.ETAG_ELEMENT)) {
}
else if (name.equals(Constants.LEASE_STATUS_ELEMENT)) {
properties.setLeaseStatus(LeaseStatus.parse(Utility.readElementFromXMLReader(xmlr,
- Constants.COPY_STATUS_ELEMENT)));
+ Constants.LEASE_STATUS_ELEMENT)));
}
else if (name.equals(Constants.LEASE_STATE_ELEMENT)) {
properties.setLeaseState(LeaseState.parse(Utility.readElementFromXMLReader(xmlr,
View
77 ...ft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlob.java
@@ -305,7 +305,6 @@ public String execute(final CloudBlobClient client, final CloudBlob blob, final
return null;
}
- blob.updatePropertiesFromResponse(request);
blob.properties.setLeaseStatus(LeaseStatus.LOCKED);
return BlobResponse.getLeaseID(request, opContext);
@@ -418,7 +417,7 @@ public Long execute(final CloudBlobClient client, final CloudBlob blob, final Op
return -1L;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
final String leaseTime = BlobResponse.getLeaseTime(request, opContext);
blob.properties.setLeaseStatus(LeaseStatus.UNLOCKED);
@@ -552,7 +551,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
blob.copyState = BaseResponse.getCopyState(request);
return null;
@@ -631,8 +630,6 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
-
return null;
}
};
@@ -676,6 +673,8 @@ public final CloudBlob createSnapshot() throws StorageException {
@DoesServiceRequest
public final CloudBlob createSnapshot(final AccessCondition accessCondition, BlobRequestOptions options,
OperationContext opContext) throws StorageException {
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -714,7 +713,7 @@ else if (blob instanceof CloudPageBlob) {
snapshot = new CloudPageBlob(blob.getUri(), snapshotTime, client);
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return snapshot;
}
};
@@ -881,7 +880,6 @@ public Boolean execute(final CloudBlobClient client, final CloudBlob blob, final
this.setResult(ExecutionEngine.processRequest(request, opContext));
- blob.updatePropertiesFromResponse(request);
if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_ACCEPTED) {
return true;
}
@@ -973,7 +971,11 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
final String contentLength = request.getHeaderField(Constants.HeaderConstants.CONTENT_LENGTH);
final long expectedLength = Long.parseLong(contentLength);
- blob.updatePropertiesFromResponse(request);
+ final BlobAttributes retrievedAttributes = BlobResponse.getAttributes(request, blob.getUri(),
+ blob.snapshotID, opContext);
+ blob.properties = retrievedAttributes.getProperties();
+ blob.metadata = retrievedAttributes.getMetadata();
+ blob.copyState = retrievedAttributes.getCopyState();
ExecutionEngine.getResponseCode(this.getResult(), request, opContext);
if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) {
@@ -1326,7 +1328,15 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ // Do not update blob length in downloadRangeInternal API.
+ final long orignalBlobLength = blob.properties.getLength();
+ final BlobAttributes retrievedAttributes = BlobResponse.getAttributes(request, blob.getUri(),
+ blob.snapshotID, opContext);
+ blob.properties = retrievedAttributes.getProperties();
+ blob.metadata = retrievedAttributes.getMetadata();
+ blob.copyState = retrievedAttributes.getCopyState();
+ blob.properties.setLength(orignalBlobLength);
+
final String contentLength = request.getHeaderField(Constants.HeaderConstants.CONTENT_LENGTH);
final long expectedLength = Long.parseLong(contentLength);
if (totalRead != expectedLength) {
@@ -1426,7 +1436,11 @@ public Boolean execute(final CloudBlobClient client, final CloudBlob blob, final
this.setResult(ExecutionEngine.processRequest(request, opContext));
if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_OK) {
- blob.updatePropertiesFromResponse(request);
+ final BlobAttributes retrievedAttributes = BlobResponse.getAttributes(request, blob.getUri(),
+ blob.snapshotID, opContext);
+ blob.properties = retrievedAttributes.getProperties();
+ blob.metadata = retrievedAttributes.getMetadata();
+ blob.copyState = retrievedAttributes.getCopyState();
return Boolean.valueOf(true);
}
else if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
@@ -1746,6 +1760,8 @@ public final BlobInputStream openInputStream(final AccessCondition accessConditi
options = new BlobRequestOptions();
}
+ assertNoWriteOperationForSnapshot();
+
options.applyDefaults(this.blobServiceClient);
return new BlobInputStream(this, accessCondition, options, opContext);
@@ -1820,7 +1836,7 @@ protected void parseURIQueryStringAndVerify(final URI completeUri, final CloudBl
}
}
- void updatePropertiesFromResponse(HttpURLConnection request) {
+ void updateEtagAndLastModifiedFromResponse(HttpURLConnection request) {
String tempStr = request.getHeaderField(Constants.HeaderConstants.ETAG);
// ETag
@@ -1836,12 +1852,12 @@ void updatePropertiesFromResponse(HttpURLConnection request) {
this.getProperties().setLastModified(lastModifiedCalendar.getTime());
}
- // using this instead of the request property since the request
- // property only returns an int.
- tempStr = request.getHeaderField(Constants.HeaderConstants.CONTENT_LENGTH);
+ }
- if (!Utility.isNullOrEmpty(tempStr)) {
- this.getProperties().setLength(Long.parseLong(tempStr));
+ void updateLengthFromResponse(HttpURLConnection request) {
+ final String xContentLengthHeader = request.getHeaderField(BlobConstants.CONTENT_LENGTH_HEADER);
+ if (!Utility.isNullOrEmpty(xContentLengthHeader)) {
+ this.getProperties().setLength(Long.parseLong(xContentLengthHeader));
}
}
@@ -1915,7 +1931,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
blob.properties.setLeaseStatus(LeaseStatus.UNLOCKED);
return null;
}
@@ -1995,7 +2011,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -2084,7 +2100,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -2231,7 +2247,7 @@ public Long execute(final CloudBlobClient client, final CloudBlob blob, final Op
return -1L;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
final String leaseTime = BlobResponse.getLeaseTime(request, opContext);
return Utility.isNullOrEmpty(leaseTime) ? -1L : Long.parseLong(leaseTime);
@@ -2317,6 +2333,8 @@ public abstract void upload(InputStream sourceStream, long length, final AccessC
protected final void uploadFullBlob(final InputStream sourceStream, final long length,
final AccessCondition accessCondition, final BlobRequestOptions options, final OperationContext opContext)
throws StorageException, IOException {
+ assertNoWriteOperationForSnapshot();
+
// Mark sourceStream for current position.
sourceStream.mark(Constants.MAX_MARK_LENGTH);
@@ -2359,7 +2377,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -2400,6 +2418,8 @@ public final void uploadMetadata() throws StorageException {
@DoesServiceRequest
public final void uploadMetadata(final AccessCondition accessCondition, BlobRequestOptions options,
OperationContext opContext) throws StorageException {
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -2431,7 +2451,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -2471,6 +2491,8 @@ public final void uploadProperties() throws StorageException {
@DoesServiceRequest
public final void uploadProperties(final AccessCondition accessCondition, BlobRequestOptions options,
OperationContext opContext) throws StorageException {
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -2503,7 +2525,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -2511,4 +2533,13 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
ExecutionEngine
.executeWithRetry(this.blobServiceClient, this, impl, options.getRetryPolicyFactory(), opContext);
}
+
+ /**
+ * Asserts that write operation is not done for snapshot.
+ */
+ protected void assertNoWriteOperationForSnapshot() {
+ if (isSnapshot()) {
+ throw new IllegalArgumentException("Cannot perform this operation on a blob representing a snapshot.");
+ }
+ }
}
View
16 ...ure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlockBlob.java
@@ -162,6 +162,8 @@ public void commitBlockList(final Iterable<BlockEntry> blockList) throws Storage
@DoesServiceRequest
public void commitBlockList(final Iterable<BlockEntry> blockList, final AccessCondition accessCondition,
BlobRequestOptions options, OperationContext opContext) throws StorageException {
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -209,7 +211,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -298,7 +300,9 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
+ blob.updateLengthFromResponse(request);
+
final GetBlockListResponse response = new GetBlockListResponse(request.getInputStream());
return response.getBlocks();
}
@@ -350,6 +354,8 @@ public BlobOutputStream openOutputStream(final AccessCondition accessCondition,
options = new BlobRequestOptions();
}
+ assertNoWriteOperationForSnapshot();
+
options.applyDefaults(this.blobServiceClient);
return new BlobOutputStream(this, accessCondition, options, opContext);
@@ -406,6 +412,8 @@ public void upload(final InputStream sourceStream, final long length, final Acce
"Invalid stream length, specify -1 for unkown length stream, or a positive number of bytes");
}
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -520,6 +528,8 @@ public void uploadBlock(final String blockId, final InputStream sourceStream, fi
"Invalid stream length, length must be less than or equal to 4 MB in size.");
}
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -621,7 +631,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
View
15 ...zure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudPageBlob.java
@@ -240,6 +240,8 @@ public void create(final long length) throws StorageException {
@DoesServiceRequest
public void create(final long length, final AccessCondition accessCondition, BlobRequestOptions options,
OperationContext opContext) throws StorageException {
+ assertNoWriteOperationForSnapshot();
+
if (length % BlobConstants.PAGE_SIZE != 0) {
throw new IllegalArgumentException("Page blob length must be multiple of 512.");
}
@@ -277,7 +279,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
return null;
}
};
@@ -357,7 +359,7 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
final GetPageRangesResponse response = new GetPageRangesResponse(request.getInputStream());
return response.getPageRanges();
}
@@ -416,6 +418,8 @@ public BlobOutputStream openOutputStream(final long length, final AccessConditio
options = new BlobRequestOptions();
}
+ assertNoWriteOperationForSnapshot();
+
options.applyDefaults(this.blobServiceClient);
if (options.getStoreBlobContentMD5()) {
@@ -485,7 +489,8 @@ public Void execute(final CloudBlobClient client, final CloudBlob blob, final Op
return null;
}
- blob.updatePropertiesFromResponse(request);
+ blob.updateEtagAndLastModifiedFromResponse(request);
+ blob.updateLengthFromResponse(request);
return null;
}
};
@@ -541,6 +546,8 @@ public void upload(final InputStream sourceStream, final long length) throws Sto
@DoesServiceRequest
public void upload(final InputStream sourceStream, final long length, final AccessCondition accessCondition,
BlobRequestOptions options, OperationContext opContext) throws StorageException, IOException {
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -644,6 +651,8 @@ public void uploadPages(final InputStream sourceStream, final long offset, final
throw new IllegalArgumentException("Max write size is 4MB. Please specify a smaller range.");
}
+ assertNoWriteOperationForSnapshot();
+
if (opContext == null) {
opContext = new OperationContext();
}
View
2  ...ft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CopyState.java
@@ -28,7 +28,7 @@
private String copyId;
/**
- * Holds the time the copy operation completed, whether completion was due to a successful copy, abortion, or a
+ * Holds the time the copy operation completed, whether completion was due to a successful copy, an abort, or a
* failure.
*/
private Date completionTime;
View
2  ...t-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/Constants.java
@@ -327,7 +327,7 @@
/**
* Specifies the value to use for UserAgent header.
*/
- public static final String USER_AGENT_VERSION = "Client v0.1.2";
+ public static final String USER_AGENT_VERSION = "Client v0.1.3";
}
/**
View
9 ...ure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/utils/Utility.java
@@ -365,11 +365,16 @@ public static XMLStreamReader createXMLStreamReaderFromReader(final Reader reade
* @return <code>true</code> if the specified URI is path-style; otherwise, <code>false</code>.
*/
public static boolean determinePathStyleFromUri(final URI baseURI, final String knownAccountName) {
+ String path = baseURI.getPath();
+
if (knownAccountName == null) {
- return !Utility.isNullOrEmpty(baseURI.getPath());
+ if (Utility.isNullOrEmpty(path) || path.equals("/")) {
+ return false;
+ }
+
+ return true;
}
- String path = baseURI.getPath();
if (!Utility.isNullOrEmpty(path) && path.startsWith("/")) {
path = path.substring(1);
}
View
5 ...-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/CloudQueue.java
@@ -637,6 +637,9 @@ public void deleteMessage(final CloudQueueMessage message) throws StorageExcepti
public void deleteMessage(final CloudQueueMessage message, QueueRequestOptions options, OperationContext opContext)
throws StorageException {
Utility.assertNotNull("message", message);
+ Utility.assertNotNullOrEmpty("messageId", message.id);
+ Utility.assertNotNullOrEmpty("popReceipt", message.popReceipt);
+
if (opContext == null) {
opContext = new OperationContext();
}
@@ -1072,7 +1075,7 @@ public CloudQueueMessage retrieveMessage() throws StorageException {
@DoesServiceRequest
public CloudQueueMessage retrieveMessage(final int visibilityTimeoutInSeconds, final QueueRequestOptions options,
final OperationContext opContext) throws StorageException {
- return getFirstOrNull(this.retrieveMessages(1, visibilityTimeoutInSeconds, null, null));
+ return getFirstOrNull(this.retrieveMessages(1, visibilityTimeoutInSeconds, options, opContext));
}
/**
View
6 ...-api/src/main/java/com/microsoft/windowsazure/services/queue/client/QueuePermissions.java
@@ -17,8 +17,6 @@
import java.util.HashMap;
-import com.microsoft.windowsazure.services.table.client.SharedAccessTablePolicy;
-
/**
* Represents the permissions for a container.
*/
@@ -51,8 +49,8 @@ public QueuePermissions() {
* Sets the set of shared access policies for the queue.
*
* @param sharedAccessPolicies
- * The set of shared access policies to set for the queue, represented by a <code>HashMap</code> object of
- * {@link SharedAccessQueuePolicy} objects.
+ * The set of shared access policies to set for the queue, represented by a <code>HashMap</code> object
+ * of {@link SharedAccessQueuePolicy} objects.
*/
public void setSharedAccessPolicies(final HashMap<String, SharedAccessQueuePolicy> sharedAccessPolicies) {
this.sharedAccessPolicies = sharedAccessPolicies;
View
7 ...c/main/java/com/microsoft/windowsazure/services/queue/client/SharedAccessQueuePolicy.java
@@ -18,7 +18,6 @@
import java.util.EnumSet;
import com.microsoft.windowsazure.services.core.storage.Constants;
-import com.microsoft.windowsazure.services.table.client.SharedAccessTablePermissions;
/**
* Represents a shared access policy, which specifies the start time, expiry time, and permissions for a shared access
@@ -31,8 +30,8 @@
*
* @param value
* A <code>String</code> that represents the shared access permissions. The string must contain one or
- * more of the following values. Note that they must be lower case, and the order that they are specified must
- * be in the order of "rwdl".
+ * more of the following values. Note that they must be lower case, and the order that they are specified
+ * must be in the order of "rwdl".
* <ul>
* <li><code>d</code>: Delete access.</li>
* <li><code>l</code>: List access.</li>
@@ -159,7 +158,7 @@ public Date getSharedAccessStartTime() {
* Sets the permissions for a shared access signature associated with this shared access policy.
*
* @param permissions
- * The permissions, represented by a <code>java.util.EnumSet</code> object that contains
+ * The permissions, represented by a <code>java.util.EnumSet</code> object that contains
* {@link SharedAccessQueuePermissions} values, to set for the shared access signature.
*/
public void setPermissions(final EnumSet<SharedAccessQueuePermissions> permissions) {
View
4 ...ure-api/src/main/java/com/microsoft/windowsazure/services/table/client/AtomPubParser.java
@@ -416,8 +416,8 @@ protected static void writeEntityToStream(final TableEntity entity, final boolea
}
if (!isTableEntry) {
- Utility.assertNotNullOrEmpty(TableConstants.PARTITION_KEY, entity.getPartitionKey());
- Utility.assertNotNullOrEmpty(TableConstants.ROW_KEY, entity.getRowKey());
+ Utility.assertNotNull(TableConstants.PARTITION_KEY, entity.getPartitionKey());
+ Utility.assertNotNull(TableConstants.ROW_KEY, entity.getRowKey());
Utility.assertNotNull(TableConstants.TIMESTAMP, entity.getTimestamp());
}
View
7 ...-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/CloudTable.java
@@ -21,7 +21,6 @@
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
-import com.microsoft.windowsazure.services.blob.client.BlobContainerPermissions;
import com.microsoft.windowsazure.services.blob.core.storage.SharedAccessSignatureHelper;
import com.microsoft.windowsazure.services.core.storage.DoesServiceRequest;
import com.microsoft.windowsazure.services.core.storage.OperationContext;
@@ -594,11 +593,11 @@ public TablePermissions execute(final CloudTableClient client, final CloudTable
* A table-level access policy.
* @return A <code>String</code> containing the shared access signature for the table.
* @throws InvalidKeyException
- * If an invalid key was passed.
+ * If an invalid key was passed.
* @throws StorageException
- * If a storage service error occurred.
+ * If a storage service error occurred.
* @throws IllegalArgumentException
- * If an unexpected value is passed.
+ * If an unexpected value is passed.
*/
public String generateSharedAccessSignature(final SharedAccessTablePolicy policy,
final String accessPolicyIdentifier, final String startPartitionKey, final String startRowKey,
View
2  ...i/src/main/java/com/microsoft/windowsazure/services/table/client/QueryTableOperation.java
@@ -62,7 +62,7 @@ protected QueryTableOperation() {
*/
QueryTableOperation(final String partitionKey, final String rowKey) {
super(null, TableOperationType.RETRIEVE);
- Utility.assertNotNullOrEmpty("partitionKey", partitionKey);
+ Utility.assertNotNull("partitionKey", partitionKey);
this.partitionKey = partitionKey;
this.rowKey = rowKey;
}
View
173 ...rc/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java
@@ -21,6 +21,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
@@ -36,6 +37,7 @@
import com.microsoft.windowsazure.services.core.storage.AccessCondition;
import com.microsoft.windowsazure.services.core.storage.OperationContext;
+import com.microsoft.windowsazure.services.core.storage.ResultSegment;
import com.microsoft.windowsazure.services.core.storage.StorageCredentialsSharedAccessSignature;
import com.microsoft.windowsazure.services.core.storage.StorageErrorCodeStrings;
import com.microsoft.windowsazure.services.core.storage.StorageException;
@@ -498,4 +500,175 @@ public void testCopyFromBlobAbortTest() throws StorageException, URISyntaxExcept
newContainer.deleteIfExists();
}
}
+
+ @Test
+ public void testBlobSnapshotValidationTest() throws StorageException, URISyntaxException, IOException,
+ InterruptedException {
+ String name = generateRandomContainerName();
+ CloudBlobContainer newContainer = bClient.getContainerReference(name);
+ newContainer.create();
+
+ try {
+ final int length = 1 * 1024;
+ final Random randGenerator = new Random();
+ final byte[] buff = new byte[length];
+ randGenerator.nextBytes(buff);
+
+ String blockBlobName = "testBlockBlob" + Integer.toString(randGenerator.nextInt(50000));
+ blockBlobName = blockBlobName.replace('-', '_');
+
+ final CloudBlob blockBlobRef = newContainer.getBlockBlobReference(blockBlobName);
+ blockBlobRef.upload(new ByteArrayInputStream(buff), -1, null, null, null);
+
+ final CloudBlob blobSnapshot = blockBlobRef.createSnapshot();
+
+ final ByteArrayOutputStream outStream = new ByteArrayOutputStream(length);
+
+ blobSnapshot.download(outStream);
+ final byte[] retrievedBuff = outStream.toByteArray();
+ for (int m = 0; m < length; m++) {
+ Assert.assertEquals(buff[m], retrievedBuff[m]);
+ }
+
+ // Read operation should work fine.
+ blobSnapshot.downloadAttributes();
+
+ // Expect an IllegalArgumentException from upload.
+ try {
+ blobSnapshot.upload(new ByteArrayInputStream(buff), -1);
+ Assert.fail("Expect an IllegalArgumentException from upload");
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals("Cannot perform this operation on a blob representing a snapshot.", e.getMessage());
+ }
+
+ // Expect an IllegalArgumentException from uploadMetadata.
+ try {
+ blobSnapshot.uploadMetadata();
+ Assert.fail("Expect an IllegalArgumentException from uploadMetadata");
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals("Cannot perform this operation on a blob representing a snapshot.", e.getMessage());
+ }
+
+ // Expect an IllegalArgumentException from uploadProperties.
+ try {
+ blobSnapshot.uploadProperties();
+ Assert.fail("Expect an IllegalArgumentException from uploadProperties");
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals("Cannot perform this operation on a blob representing a snapshot.", e.getMessage());
+ }
+
+ // Expect an IllegalArgumentException from createSnapshot.
+ try {
+ blobSnapshot.createSnapshot();
+ Assert.fail("Expect an IllegalArgumentException from createSnapshot");
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals("Cannot perform this operation on a blob representing a snapshot.", e.getMessage());
+ }
+
+ blobSnapshot.delete(DeleteSnapshotsOption.NONE, null, null, null);
+
+ blockBlobRef.downloadAttributes();
+ }
+ finally {
+ // cleanup
+ newContainer.deleteIfExists();
+ }
+ }
+
+ @Test
+ public void testBlobDownloadRangeValidationTest() throws StorageException, URISyntaxException, IOException,
+ InterruptedException {
+ String name = generateRandomContainerName();
+ CloudBlobContainer newContainer = bClient.getContainerReference(name);
+ newContainer.create();
+
+ try {
+
+ final int blockLength = 1024 * 1024;
+ final int length = 3 * blockLength;
+ final Random randGenerator = new Random();
+ final byte[] buff = new byte[length];
+ randGenerator.nextBytes(buff);
+
+ String blockBlobName = "testBlockBlob" + Integer.toString(randGenerator.nextInt(50000));
+ blockBlobName = blockBlobName.replace('-', '_');
+
+ final CloudBlockBlob blockBlobRef = newContainer.getBlockBlobReference(blockBlobName);
+ blockBlobRef.upload(new ByteArrayInputStream(buff), -1, null, null, null);
+ ArrayList<BlockEntry> blockList = new ArrayList<BlockEntry>();
+ for (int i = 1; i <= 3; i++) {
+ randGenerator.nextBytes(buff);
+
+ String blockID = String.format("%08d", i);
+ blockBlobRef.uploadBlock(blockID, new ByteArrayInputStream(buff), blockLength, null, null, null);
+ blockList.add(new BlockEntry(blockID, BlockSearchMode.LATEST));
+ }
+
+ blockBlobRef.commitBlockList(blockList);
+
+ //Download full blob
+ blockBlobRef.download(new ByteArrayOutputStream());
+ Assert.assertEquals(length, blockBlobRef.getProperties().getLength());
+
+ //Download blob range.
+ byte[] downloadBuffer = new byte[100];
+ blockBlobRef.downloadRange(0, 100, downloadBuffer, 0);
+ Assert.assertEquals(length, blockBlobRef.getProperties().getLength());
+
+ //Download block list.
+ blockBlobRef.downloadBlockList();
+ Assert.assertEquals(length, blockBlobRef.getProperties().getLength());
+ }
+ finally {
+ // cleanup
+ newContainer.deleteIfExists();
+ }
+ }
+
+ @Test
+ public void testBlobNamePlusEncodingTest() throws StorageException, URISyntaxException, IOException,
+ InterruptedException {
+ String name = generateRandomContainerName();
+ CloudBlobContainer newContainer = bClient.getContainerReference(name);
+ newContainer.create();
+
+ try {
+
+ final int length = 1 * 1024;
+ final Random randGenerator = new Random();
+ final byte[] buff = new byte[length];
+ randGenerator.nextBytes(buff);
+
+ final CloudBlockBlob originalBlob = newContainer.getBlockBlobReference("a+b.txt");
+ originalBlob.upload(new ByteArrayInputStream(buff), -1, null, null, null);
+
+ CloudBlob copyBlob = newContainer.getBlockBlobReference(originalBlob.getName() + "copyed");
+ copyBlob.copyFromBlob(originalBlob);
+ Thread.sleep(1000);
+ copyBlob.downloadAttributes();
+ }
+ finally {
+ // cleanup
+ newContainer.deleteIfExists();
+ }
+ }
+
+ @Test
+ public void testListContainersTest() throws StorageException, URISyntaxException, IOException, InterruptedException {
+ final ResultSegment<CloudBlobContainer> segment = bClient.listContainersSegmented(null,
+ ContainerListingDetails.ALL, 2, null, null, null);
+
+ for (int i = 0; i < 5 && segment.getHasMoreResults(); i++) {
+ for (final CloudBlobContainer container : segment.getResults()) {
+ container.downloadAttributes();
+ }
+
+ bClient.listContainersSegmented(null, ContainerListingDetails.ALL, 2, segment.getContinuationToken(), null,
+ null);
+ }
+ }
}
View
16 ...src/test/java/com/microsoft/windowsazure/services/queue/client/CloudQueueClientTests.java
@@ -120,18 +120,20 @@ public void testListQueuesAndListQueuesSegmentedLargeNumber() throws URISyntaxEx
NumberFormat myFormat = NumberFormat.getInstance();
myFormat.setMinimumIntegerDigits(4);
- for (int i = 0; i < totalLimit - count; i++) {
- String sub = myFormat.format(i);
+ for (int i = 0, j = 0; i < totalLimit - count; j++) {
+ String sub = myFormat.format(j);
CloudQueue q = new CloudQueue(AppendQueueName(httpAcc.getQueueEndpoint(),
String.format("listqueue" + sub.replace(",", ""))), qClient);
- q.createIfNotExist();
+ if (q.createIfNotExist())
+ i++;
}
- }
- count = 0;
- for (CloudQueue queue : qClient.listQueues()) {
- count++;
+ count = 0;
+ for (CloudQueue queue : qClient.listQueues()) {
+ count++;
+ }
}
+
Assert.assertTrue(count >= totalLimit);
ResultSegment<CloudQueue> segment = qClient.listQueuesSegmented();
View
111 ...e-api/src/test/java/com/microsoft/windowsazure/services/queue/client/CloudQueueTests.java
@@ -19,6 +19,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
@@ -98,8 +99,9 @@ public void testQueueSAS() throws StorageException, URISyntaxException, InvalidK
// Add a policy, check setting and getting.
SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy();
Calendar now = GregorianCalendar.getInstance();
+ now.add(Calendar.MINUTE, -15);
policy1.setSharedAccessStartTime(now.getTime());
- now.add(Calendar.MINUTE, 10);
+ now.add(Calendar.MINUTE, 30);
policy1.setSharedAccessExpiryTime(now.getTime());
String identifier = UUID.randomUUID().toString();
@@ -537,6 +539,76 @@ public void testAddMessage() throws URISyntaxException, StorageException, Unsupp
}
@Test
+ public void testAddMessageUnicode() throws URISyntaxException, StorageException, UnsupportedEncodingException {
+ final String queueName = UUID.randomUUID().toString().toLowerCase();
+ final CloudQueue queue = qClient.getQueueReference(queueName);
+ queue.create();
+
+ ArrayList<String> messages = new ArrayList<String>();
+ messages.add("Le débat sur l'identité nationale, l'idée du président Nicolas Sarkozy de déchoir des personnes d'origine étrangère de la nationalité française ... certains cas et les récentes mesures prises contre les Roms ont choqué les experts, qui rendront leurs conclusions le 27 août.");
+ messages.add("Ваш логин Yahoo! дает доступ к таким мощным инструментам связи, как электронная почта, отправка мгновенных сообщений, функции безопасности, в частности, антивирусные средства и блокировщик всплывающей рекламы, и избранное, например, фото и музыка в сети — все бесплат");
+ messages.add("据新华社8月12日电 8月11日晚,舟曲境内再次出现强降雨天气,使特大山洪泥石流灾情雪上加霜。白龙江水在梨坝子村的交汇地带形成一个新的堰塞湖,水位比平时高出3米。甘肃省国土资源厅副厅长张国华当日22时许在新闻发布会上介绍,截至12日21时50分,舟曲堰塞湖堰塞体已消除,溃坝险情已消除,目前针对堰塞湖的主要工作是疏通河道。");
+ messages.add("ל כולם\", הדהים יעלון, ויישר קו עם העדות שמסר ראש הממשלה, בנימין נתניהו, לוועדת טירקל. לדבריו, אכן השרים דנו רק בהיבטים התקשורתיים של עצירת המשט: \"בשביעייה לא התקיים דיון על האלטרנטיבות. עסקנו בהיבטים ");
+ messages.add("Prozent auf 0,5 Prozent. Im Vergleich zum Vorjahresquartal wuchs die deutsche Wirtschaft von Januar bis März um 2,1 Prozent. Auch das ist eine Korrektur nach oben, ursprünglich waren es hier 1,7 Prozent");
+ messages.add("<?xml version=\"1.0\"?>\n<!DOCTYPE PARTS SYSTEM \"parts.dtd\">\n<?xml-stylesheet type=\"text/css\" href=\"xmlpartsstyle.css\"?>\n<PARTS>\n <TITLE>Computer Parts</TITLE>\n <PART>\n <ITEM>Motherboard</ITEM>\n <MANUFACTURER>ASUS</MANUFACTURER>\n <MODEL>"
+ + "P3B-F</MODEL>\n <COST> 123.00</COST>\n </PART>\n <PART>\n <ITEM>Video Card</ITEM>\n <MANUFACTURER>ATI</MANUFACTURER>\n <MODEL>All-in-Wonder Pro</MODEL>\n <COST> 160.00</COST>\n </PART>\n <PART>\n <ITEM>Sound Card</ITEM>\n <MANUFACTURER>"
+ + "Creative Labs</MANUFACTURER>\n <MODEL>Sound Blaster Live</MODEL>\n <COST> 80.00</COST>\n </PART>\n <PART>\n <ITEM> inch Monitor</ITEM>\n <MANUFACTURER>LG Electronics</MANUFACTURER>\n <MODEL> 995E</MODEL>\n <COST> 290.00</COST>\n </PART>\n</PARTS>");
+
+ for (int i = 0; i < messages.size(); i++) {
+ String msg = messages.get(i);
+ queue.addMessage(new CloudQueueMessage(msg));
+ CloudQueueMessage readBack = queue.retrieveMessage();
+ Assert.assertEquals(msg, readBack.getMessageContentAsString());
+ queue.deleteMessage(readBack);
+ }
+
+ queue.shouldEncodeMessage = false;
+ for (int i = 0; i < messages.size(); i++) {
+ String msg = messages.get(i);
+ queue.addMessage(new CloudQueueMessage(msg));
+ CloudQueueMessage readBack = queue.retrieveMessage();
+ Assert.assertEquals(msg, readBack.getMessageContentAsString());
+ queue.deleteMessage(readBack);
+ }
+
+ queue.delete();
+ }
+
+ @Test
+ public void testAddMessageLargeVisibilityDelay() throws URISyntaxException, StorageException,
+ UnsupportedEncodingException {
+ final String queueName = UUID.randomUUID().toString().toLowerCase();
+ final CloudQueue queue = qClient.getQueueReference(queueName);
+ queue.create();
+
+ String msgContent = UUID.randomUUID().toString();
+ final CloudQueueMessage message = new CloudQueueMessage(msgContent);
+ queue.addMessage(message, 100, 50, null, null);
+ CloudQueueMessage msgFromRetrieve1 = queue.retrieveMessage();
+ Assert.assertNull(msgFromRetrieve1);
+
+ queue.delete();
+ }
+
+ @Test
+ public void testDeleteMessageWithDifferentQueueInstance() throws URISyntaxException, StorageException,
+ UnsupportedEncodingException {
+ final String queueName = UUID.randomUUID().toString().toLowerCase();
+ final CloudQueue queue1 = qClient.getQueueReference(queueName);
+ queue1.create();
+
+ String msgContent = UUID.randomUUID().toString();
+ final CloudQueueMessage message = new CloudQueueMessage(msgContent);
+ queue1.addMessage(message);
+ CloudQueueMessage msgFromRetrieved = queue1.retrieveMessage();
+
+ final CloudQueue queue2 = qClient.getQueueReference(queueName);
+ queue2.deleteMessage(msgFromRetrieved);
+
+ queue1.delete();
+ }
+
+ @Test
public void testAddMessageToNonExistingQueue() throws URISyntaxException, StorageException,
UnsupportedEncodingException {
String queueName = UUID.randomUUID().toString().toLowerCase();
@@ -751,10 +823,14 @@ public void testRetrieveMessage() throws URISyntaxException, StorageException, U
CloudQueue newQueue = qClient.getQueueReference(queueName);
newQueue.create();
newQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null);
- CloudQueueMessage message1 = newQueue.retrieveMessage();
+ OperationContext opContext = new OperationContext();
+ CloudQueueMessage message1 = newQueue.retrieveMessage(10, null /*QueueRequestOptions*/, opContext);
Date expirationTime1 = message1.getExpirationTime();
Date insertionTime1 = message1.getInsertionTime();
Date nextVisibleTime1 = message1.getNextVisibleTime();
+
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, opContext.getLastResult().getStatusCode());
+
newQueue.deleteMessage(message1);
try {
@@ -1270,4 +1346,35 @@ public void testQueueUpdateMetaData() throws URISyntaxException, StorageExceptio
queue.setMetadata(metadata);
queue.uploadMetadata();
}
+
+ @Test
+ public void testSASClientParse() throws StorageException, URISyntaxException, InvalidKeyException {
+
+ // Add a policy, check setting and getting.
+ SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy();
+ Calendar now = GregorianCalendar.getInstance();
+ now.add(Calendar.MINUTE, -15);
+ policy1.setSharedAccessStartTime(now.getTime());
+ now.add(Calendar.MINUTE, 30);
+ policy1.setSharedAccessExpiryTime(now.getTime());
+
+ policy1.setPermissions(EnumSet.of(SharedAccessQueuePermissions.READ,
+ SharedAccessQueuePermissions.PROCESSMESSAGES, SharedAccessQueuePermissions.ADD,
+ SharedAccessQueuePermissions.UPDATE));
+
+ String sasString = queue.generateSharedAccessSignature(policy1, null);
+
+ URI queueUri = new URI("http://myaccount.queue.core.windows.net/myqueue");
+
+ CloudQueueClient queueClient1 = new CloudQueueClient(new URI("http://myaccount.queue.core.windows.net/"),
+ new StorageCredentialsSharedAccessSignature(sasString));
+
+ CloudQueue queue1 = new CloudQueue(queueUri, queueClient1);
+ queue1.getName();
+
+ CloudQueueClient queueClient2 = new CloudQueueClient(new URI("http://myaccount.queue.core.windows.net/"),
+ new StorageCredentialsSharedAccessSignature(sasString));
+ CloudQueue queue2 = new CloudQueue(queueUri, queueClient2);
+ queue2.getName();
+ }
}
View
8 .../test/java/com/microsoft/windowsazure/services/table/client/TableBatchOperationTests.java
@@ -288,11 +288,9 @@ public void batchReplaceFail() throws StorageException {
}
catch (TableServiceException ex) {
Assert.assertEquals(ex.getMessage(), "Precondition Failed");
- String errorAfterSemiColon = ex.getExtendedErrorInformation().getErrorMessage();
- errorAfterSemiColon = errorAfterSemiColon.substring(errorAfterSemiColon.indexOf(":") + 1);
- Assert.assertTrue(errorAfterSemiColon
- .startsWith("The condition specified using HTTP conditional header(s) is not met."));
- Assert.assertEquals(ex.getExtendedErrorInformation().getErrorCode(), "ConditionNotMet");
+ Assert.assertTrue(ex.getExtendedErrorInformation().getErrorMessage()
+ .startsWith("The update condition specified in the request was not satisfied."));
+ Assert.assertEquals(ex.getExtendedErrorInformation().getErrorCode(), "UpdateConditionNotSatisfied");
}
}
View
16 ...-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableClientTests.java
@@ -503,8 +503,9 @@ public void testTableSASFromPermission() throws StorageException, URISyntaxExcep
// Add a policy, check setting and getting.
SharedAccessTablePolicy policy1 = new SharedAccessTablePolicy();
Calendar now = GregorianCalendar.getInstance();
+ now.add(Calendar.MINUTE, -10);
policy1.setSharedAccessStartTime(now.getTime());
- now.add(Calendar.MINUTE, 10);
+ now.add(Calendar.MINUTE, 30);
policy1.setSharedAccessExpiryTime(now.getTime());
policy1.setPermissions(EnumSet.of(SharedAccessTablePermissions.ADD, SharedAccessTablePermissions.QUERY,
@@ -532,6 +533,16 @@ public void testTableSASFromPermission() throws StorageException, URISyntaxExcep
"javatables_batch_0", null, "javatables_batch_9", null);
{
+ TableBatchOperation batchFromSAS = new TableBatchOperation();
+
+ for (int j = 1000; j < 1010; j++) {
+ class1 ent = generateRandomEnitity("javatables_batch_" + Integer.toString(0));
+ ent.setRowKey(String.format("%06d", j));
+ batchFromSAS.insert(ent);
+ }
+
+ tableClientFromPermission.execute(name, batchFromSAS);
+
class1 randEnt = TableTestBase.generateRandomEnitity(null);
TableQuery<class1> query = TableQuery.from(name, class1.class).where(
String.format("(PartitionKey eq '%s') and (RowKey ge '%s')", "javatables_batch_1", "000050"));
@@ -581,10 +592,11 @@ public void testTableSASFromPermission() throws StorageException, URISyntaxExcep
secondEntity.setRowKey(baseEntity.getRowKey());
secondEntity.setEtag(baseEntity.getEtag());
- // Insert or merge Entity - ENTITY DOES NOT EXIST NOW.
TableResult insertResult = tableClientFromPermission.execute(name,
TableOperation.insertOrMerge(baseEntity));
+ // Insert or merge Entity - ENTITY DOES NOT EXIST NOW.
+
Assert.assertEquals(insertResult.getHttpStatusCode(), HttpURLConnection.HTTP_NO_CONTENT);
// Insert or replace Entity - ENTITY EXISTS -> WILL REPLACE
View
4 ...i/src/test/java/com/microsoft/windowsazure/services/table/client/TableOperationTests.java
@@ -517,8 +517,8 @@ public void replaceFail() throws StorageException {
catch (TableServiceException ex) {
Assert.assertEquals(ex.getMessage(), "Precondition Failed");
Assert.assertTrue(ex.getExtendedErrorInformation().getErrorMessage()
- .startsWith("The condition specified using HTTP conditional header(s) is not met."));
- Assert.assertEquals(ex.getExtendedErrorInformation().getErrorCode(), "ConditionNotMet");
+ .startsWith("The update condition specified in the request was not satisfied."));
+ Assert.assertEquals(ex.getExtendedErrorInformation().getErrorCode(), "UpdateConditionNotSatisfied");
}
// delete entity
View
19 .../src/test/java/com/microsoft/windowsazure/services/table/client/TableSerializerTests.java
@@ -249,6 +249,25 @@ public void whitespaceTest() throws StorageException {
}
@Test
+ public void whitespaceOnEmptyKeysTest() throws StorageException {
+ class1 ref = new class1();
+
+ ref.setA("B ");
+ ref.setB(" A ");
+ ref.setC(" ");
+ ref.setD(new byte[] { 0, 1, 2 });
+ ref.setPartitionKey("");
+ ref.setRowKey("");
+
+ tClient.execute(testSuiteTableName, TableOperation.insert(ref));
+
+ TableResult res = tClient.execute(testSuiteTableName,
+ TableOperation.retrieve(ref.getPartitionKey(), ref.getRowKey(), class1.class));
+
+ Assert.assertEquals(((class1) res.getResult()).getA(), ref.getA());
+ }
+
+ @Test
public void newLineTest() throws StorageException {
class1 ref = new class1();
Please sign in to comment.
Something went wrong with that request. Please try again.