/** * Reserved for internal use. Populates the blob from an XMLStreamReader, reader must be at Start * element of Blob * * @param xmlr the XMLStreamReader to read from * @param serviceClient the CloudBlobClient associated with the objects. * @throws XMLStreamException if there is an error parsing the stream * @throws ParseException if there is an error in parsing a date * @throws URISyntaxException if the uri is invalid * @throws StorageException */ protected static CloudBlob readBlob( final XMLStreamReader xmlr, final CloudBlobClient serviceClient, final CloudBlobContainer container) throws XMLStreamException, ParseException, URISyntaxException, StorageException { xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.BLOB_ELEMENT); String blobName = Constants.EMPTY_STRING; String snapshotID = null; String urlString = null; HashMap<String, String> metadata = null; BlobProperties properties = null; CopyState copyState = null; int eventType = xmlr.getEventType(); // check if there are more events in the input stream while (xmlr.hasNext()) { eventType = xmlr.next(); final String name = xmlr.getName().toString(); if (eventType == XMLStreamConstants.START_ELEMENT) { if (name.equals(Constants.URL_ELEMENT)) { urlString = Utility.readElementFromXMLReader(xmlr, Constants.URL_ELEMENT); } else if (name.equals(BlobConstants.SNAPSHOT_ELEMENT)) { snapshotID = Utility.readElementFromXMLReader(xmlr, BlobConstants.SNAPSHOT_ELEMENT); } else if (name.equals(Constants.NAME_ELEMENT)) { blobName = Utility.readElementFromXMLReader(xmlr, Constants.NAME_ELEMENT); } else if (name.equals(BlobConstants.PROPERTIES)) { properties = BlobDeserializationHelper.readBlobProperties(xmlr); xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.PROPERTIES); } else if (name.equals(Constants.METADATA_ELEMENT)) { metadata = DeserializationHelper.parseMetadateFromXML(xmlr); xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.METADATA_ELEMENT); } else if (name.equals(Constants.COPY_ID_ELEMENT)) { if (copyState == null) { copyState = new CopyState(); } copyState.setCopyId(Utility.readElementFromXMLReader(xmlr, Constants.COPY_ID_ELEMENT)); } else if (name.equals(Constants.COPY_COMPLETION_TIME_ELEMENT)) { if (copyState == null) { copyState = new CopyState(); } copyState.setCompletionTime( Utility.parseRFC1123DateFromStringInGMT( Utility.readElementFromXMLReader(xmlr, Constants.COPY_COMPLETION_TIME_ELEMENT))); } else if (name.equals(Constants.COPY_STATUS_ELEMENT)) { if (copyState == null) { copyState = new CopyState(); } copyState.setStatus( CopyStatus.parse( Utility.readElementFromXMLReader(xmlr, Constants.COPY_STATUS_ELEMENT))); } else if (name.equals(Constants.COPY_SOURCE_ELEMENT)) { if (copyState == null) { copyState = new CopyState(); } copyState.setSource( new URI(Utility.readElementFromXMLReader(xmlr, Constants.COPY_SOURCE_ELEMENT))); } else if (name.equals(Constants.COPY_PROGRESS_ELEMENT)) { if (copyState == null) { copyState = new CopyState(); } final String tempString = Utility.readElementFromXMLReader(xmlr, Constants.COPY_PROGRESS_ELEMENT); String[] progressSequence = tempString.split("/"); copyState.setBytesCopied(Long.parseLong(progressSequence[0])); copyState.setTotalBytes(Long.parseLong(progressSequence[1])); } else if (name.equals(Constants.COPY_STATUS_DESCRIPTION_ELEMENT)) { if (copyState == null) { copyState = new CopyState(); } copyState.setStatusDescription( Utility.readElementFromXMLReader(xmlr, Constants.COPY_STATUS_DESCRIPTION_ELEMENT)); } } else if (eventType == XMLStreamConstants.END_ELEMENT && name.equals(BlobConstants.BLOB_ELEMENT)) { break; } } xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.BLOB_ELEMENT); // Assemble and return if (properties != null) { CloudBlob retBlob = null; final int blobNameSectionIndex = urlString.lastIndexOf("/".concat(blobName)); final URI baseUri = new URI(urlString.substring(0, blobNameSectionIndex + 1)); String query = null; if (blobNameSectionIndex + 1 + blobName.length() < urlString.length()) { // Snapshot blob URI // example:http://<yourstorageaccount>.blob.core.windows.net/<yourcontainer>/<yourblobname>?snapshot=2009-12-03T15%3a26%3a19.4466877Z query = urlString.substring(blobNameSectionIndex + 1 + blobName.length() + 1); } final URI blobURI = new URI( baseUri.getScheme(), baseUri.getAuthority(), baseUri.getRawPath().concat(blobName), query, null); if (properties.getBlobType() == BlobType.BLOCK_BLOB) { retBlob = new CloudBlockBlob(blobURI, serviceClient, container); } else if (properties.getBlobType() == BlobType.PAGE_BLOB) { retBlob = new CloudPageBlob(blobURI, serviceClient, container); } else { throw new StorageException( StorageErrorCodeStrings.INVALID_XML_DOCUMENT, "The response received is invalid or improperly formatted.", Constants.HeaderConstants.HTTP_UNUSED_306, null, null); } retBlob.uri = blobURI; retBlob.snapshotID = snapshotID; retBlob.properties = properties; retBlob.metadata = metadata; retBlob.copyState = copyState; return retBlob; } else { throw new StorageException( StorageErrorCodeStrings.INVALID_XML_DOCUMENT, "The response received is invalid or improperly formatted.", Constants.HeaderConstants.HTTP_UNUSED_306, null, null); } }
/** * Create a snapshot * * @throws StorageException * @throws URISyntaxException * @throws IOException * @throws InterruptedException */ @Test public void testPageBlobSnapshotValidationTest() throws StorageException, URISyntaxException, IOException { final int length = 1024; CloudPageBlob blockBlobRef = (CloudPageBlob) BlobTestHelper.uploadNewBlob( this.container, BlobType.PAGE_BLOB, "originalBlob", length, null); final CloudBlob blobSnapshot = blockBlobRef.createSnapshot(); for (ListBlobItem blob : this.container.listBlobs(null, true, EnumSet.allOf(BlobListingDetails.class), null, null)) { final ByteArrayOutputStream outStream = new ByteArrayOutputStream(length); ((CloudBlob) blob).download(outStream); } ByteArrayOutputStream outStream = new ByteArrayOutputStream(length); blobSnapshot.download(outStream); byte[] retrievedBuff = outStream.toByteArray(); assertEquals(length, retrievedBuff.length); // Read operation should work fine. blobSnapshot.downloadAttributes(); final CloudPageBlob blobSnapshotUsingRootUri = this.container.getPageBlobReference(blockBlobRef.getName(), blobSnapshot.getSnapshotID()); outStream = new ByteArrayOutputStream(length); blobSnapshotUsingRootUri.download(outStream); retrievedBuff = outStream.toByteArray(); assertEquals(length, retrievedBuff.length); assertEquals(blobSnapshot.getSnapshotID(), blobSnapshotUsingRootUri.getSnapshotID()); // Expect an IllegalArgumentException from upload. try { final Random randGenerator = new Random(); final byte[] buff = new byte[length]; randGenerator.nextBytes(buff); blobSnapshot.upload(new ByteArrayInputStream(buff), -1); fail("Expect an IllegalArgumentException from upload"); } catch (IllegalArgumentException e) { assertEquals( "Cannot perform this operation on a blob representing a snapshot.", e.getMessage()); } // Expect an IllegalArgumentException from uploadMetadata. try { blobSnapshot.uploadMetadata(); fail("Expect an IllegalArgumentException from uploadMetadata"); } catch (IllegalArgumentException e) { assertEquals( "Cannot perform this operation on a blob representing a snapshot.", e.getMessage()); } // Expect an IllegalArgumentException from uploadProperties. try { blobSnapshot.uploadProperties(); fail("Expect an IllegalArgumentException from uploadProperties"); } catch (IllegalArgumentException e) { assertEquals( "Cannot perform this operation on a blob representing a snapshot.", e.getMessage()); } // Expect an IllegalArgumentException from createSnapshot. try { blobSnapshot.createSnapshot(); fail("Expect an IllegalArgumentException from createSnapshot"); } catch (IllegalArgumentException e) { assertEquals( "Cannot perform this operation on a blob representing a snapshot.", e.getMessage()); } }