/// <summary> /// Gets the page ranges impl. /// </summary> /// <param name="offset">The start offset. Must be multiples of 512.</param> /// <param name="length">Length of the data range to be cleared. Must be multiples of 512.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param> /// <returns>A <see cref="RESTCommand{T}"/> for getting the page ranges.</returns> private RESTCommand<IEnumerable<PageRange>> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) { RESTCommand<IEnumerable<PageRange>> getCmd = new RESTCommand<IEnumerable<PageRange>>(this.ServiceClient.Credentials, this.Uri); getCmd.ApplyRequestOptions(options); getCmd.RetrieveResponseStream = true; getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetPageRanges(uri, serverTimeout, this.SnapshotTime, offset, length, accessCondition, ctx); getCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata); getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx); getCmd.PostProcessResponse = (cmd, resp, ex, ctx) => { CloudBlobSharedImpl.ParseSizeAndLastModified(this.attributes, resp); GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream); IEnumerable<PageRange> pageRanges = new List<PageRange>(getPageRangesResponse.PageRanges); return pageRanges; }; return getCmd; }
/// <summary> /// Implementation for get page ranges. /// </summary> /// <param name="offset">The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param> /// <param name="length">The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param> /// <returns>A <see cref="RESTCommand"/> for getting the page ranges.</returns> private RESTCommand<IEnumerable<PageRange>> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) { RESTCommand<IEnumerable<PageRange>> getCmd = new RESTCommand<IEnumerable<PageRange>>(this.ServiceClient.Credentials, this.attributes.StorageUri); options.ApplyToStorageCommand(getCmd); getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary; getCmd.RetrieveResponseStream = true; getCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => { StorageRequestMessage msg = BlobHttpRequestMessageFactory.GetPageRanges(uri, serverTimeout, this.SnapshotTime, offset, length, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials); return msg; }; getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); getCmd.PostProcessResponse = (cmd, resp, ctx) => { CloudBlob.UpdateETagLMTLengthAndSequenceNumber(this.attributes, resp, true); return Task.Factory.StartNew(() => { GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream); IEnumerable<PageRange> pageRanges = new List<PageRange>(getPageRangesResponse.PageRanges); return pageRanges; }); }; return getCmd; }
/// <summary> /// Gets the page ranges impl. /// </summary> /// <param name="offset">The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param> /// <param name="length">The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param> /// <returns>A <see cref="RESTCommand"/> for getting the page ranges.</returns> private RESTCommand<IEnumerable<PageRange>> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) { RESTCommand<IEnumerable<PageRange>> getCmd = new RESTCommand<IEnumerable<PageRange>>(this.ServiceClient.Credentials, this.Uri); getCmd.ApplyRequestOptions(options); getCmd.RetrieveResponseStream = true; getCmd.Handler = this.ServiceClient.AuthenticationHandler; getCmd.BuildClient = HttpClientFactory.BuildHttpClient; getCmd.BuildRequest = (cmd, cnt, ctx) => { HttpRequestMessage msg = BlobHttpRequestMessageFactory.GetPageRanges(cmd.Uri, cmd.ServerTimeoutInSeconds, this.SnapshotTime, offset, length, accessCondition, cnt, ctx); BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); return msg; }; getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx); getCmd.PostProcessResponse = (cmd, resp, ex, ctx) => { CloudBlobSharedImpl.ParseSizeAndLastModified(this.attributes, resp); return Task.Factory.StartNew(() => { GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream); IEnumerable<PageRange> pageRanges = new List<PageRange>(getPageRangesResponse.PageRanges); return pageRanges; }); }; return getCmd; }
/// <summary> /// Gets the page ranges impl. /// </summary> /// <param name="offset">The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param> /// <param name="length">The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param> /// <returns>A <see cref="RESTCommand{T}"/> for getting the page ranges.</returns> private RESTCommand<IEnumerable<PageRange>> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) { RESTCommand<IEnumerable<PageRange>> getCmd = new RESTCommand<IEnumerable<PageRange>>(this.ServiceClient.Credentials, this.attributes.StorageUri); options.ApplyToStorageCommand(getCmd); getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary; getCmd.RetrieveResponseStream = true; getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, useVersionHeader, ctx) => BlobHttpWebRequestFactory.GetPageRanges(uri, serverTimeout, this.SnapshotTime, offset, length, accessCondition, useVersionHeader, ctx); getCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata); getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); getCmd.PostProcessResponse = (cmd, resp, ctx) => { CloudBlob.UpdateETagLMTLengthAndSequenceNumber(this.attributes, resp, true); GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream); IEnumerable<PageRange> pageRanges = new List<PageRange>(getPageRangesResponse.PageRanges); return pageRanges; }; return getCmd; }
public void ClearPageRangeScenarioTest(string containerName, string blobName, HttpStatusCode? expectedError) { // 1. Create Sparse Page Blob int blobSize = 128 * 1024; BlobProperties properties = new BlobProperties() { BlobType = BlobType.PageBlob }; Uri uri = BlobTests.ConstructPutUri(BlobContext.Address, containerName, blobName); OperationContext opContext = new OperationContext(); HttpWebRequest webRequest = BlobHttpWebRequestFactory.Put(uri, BlobContext.Timeout, properties, BlobType.PageBlob, blobSize, null, opContext); BlobTests.SignRequest(webRequest, BlobContext); using (HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse) { BlobTests.PutBlobResponse(response, BlobContext, expectedError); } // 2. Now upload some page ranges for (int m = 0; m * 512 * 4 < blobSize; m++) { int startOffset = 512 * 4 * m; int length = 512; PageRange range = new PageRange(startOffset, startOffset + length - 1); opContext = new OperationContext(); HttpWebRequest pageRequest = BlobHttpWebRequestFactory.PutPage(uri, BlobContext.Timeout, range, PageWrite.Update, null, opContext); pageRequest.ContentLength = 512; BlobTests.SignRequest(pageRequest, BlobContext); Stream outStream = pageRequest.GetRequestStream(); for (int n = 0; n < 512; n++) { outStream.WriteByte((byte)m); } outStream.Close(); using (HttpWebResponse pageResponse = pageRequest.GetResponse() as HttpWebResponse) { } } // 3. Now do a Get Page Ranges List<PageRange> pageRanges = new List<PageRange>(); opContext = new OperationContext(); HttpWebRequest pageRangeRequest = BlobHttpWebRequestFactory.GetPageRanges(uri, BlobContext.Timeout, null, null, null, null, opContext); BlobTests.SignRequest(pageRangeRequest, BlobContext); using (HttpWebResponse pageRangeResponse = pageRangeRequest.GetResponse() as HttpWebResponse) { GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(pageRangeResponse.GetResponseStream()); pageRanges.AddRange(getPageRangesResponse.PageRanges.ToList()); } // 4. Now Clear some pages bool skipFlag = false; foreach (PageRange pRange in pageRanges) { skipFlag = !skipFlag; if (skipFlag) { continue; } opContext = new OperationContext(); HttpWebRequest clearPageRequest = BlobHttpWebRequestFactory.PutPage(uri, BlobContext.Timeout, pRange, PageWrite.Clear, null, opContext); clearPageRequest.ContentLength = 0; BlobTests.SignRequest(clearPageRequest, BlobContext); using (HttpWebResponse clearResponse = clearPageRequest.GetResponse() as HttpWebResponse) { } } // 5. Get New Page ranges and verify List<PageRange> newPageRanges = new List<PageRange>(); opContext = new OperationContext(); HttpWebRequest newPageRangeRequest = BlobHttpWebRequestFactory.GetPageRanges(uri, BlobContext.Timeout, null, null, null, null, opContext); BlobTests.SignRequest(newPageRangeRequest, BlobContext); using (HttpWebResponse newPageRangeResponse = newPageRangeRequest.GetResponse() as HttpWebResponse) { GetPageRangesResponse getNewPageRangesResponse = new GetPageRangesResponse(newPageRangeResponse.GetResponseStream()); newPageRanges.AddRange(getNewPageRangesResponse.PageRanges.ToList()); } Assert.AreEqual(pageRanges.Count(), newPageRanges.Count() * 2); for (int l = 0; l < newPageRanges.Count(); l++) { Assert.AreEqual(pageRanges[2 * l].StartOffset, newPageRanges[l].StartOffset); Assert.AreEqual(pageRanges[2 * l].EndOffset, newPageRanges[l].EndOffset); } }