예제 #1
0
        public void LeaseOperation(CloudBlob blob, string leaseId, LeaseAction action, int timeout)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
            var request        = BlobRequest.Lease(transformedUri, timeout, action, leaseId);

            creds.SignRequest(request);
            request.GetResponse().Close();
        }
예제 #2
0
        private static void DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action)
        {
            var credentials = blob.ServiceClient.Credentials;
            var request     = BlobRequest.Lease(new Uri(credentials.TransformUri(blob.Uri.AbsoluteUri)), 90,
                                                action, leaseId);

            credentials.SignRequest(request);
            request.GetResponse().Close();
        }
        private static void DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
            var req            = BlobRequest.Lease(transformedUri, 60, action, leaseId);

            creds.SignRequest(req);
            req.GetResponse().Close();
        }
        protected override void DoSave(IConcurrencyControlContext context, T obj)
        {
            if (string.IsNullOrWhiteSpace(context.ObjectId))
            {
                throw new ArgumentNullException("context.ObjectId", "ObjectId cannot be null or empty");
            }

            if (context is OptimisticConcurrencyContext)
            {
                CloudBlob blob = this.Container.GetBlobReference(context.ObjectId);
                blob.Properties.ContentType = "application/json";

                var blobRequestOptions = new BlobRequestOptions()
                {
                    AccessCondition = (context as OptimisticConcurrencyContext).AccessCondition
                };

                blob.UploadText(new JavaScriptSerializer().Serialize(obj), Encoding.Default, blobRequestOptions);
            }
            else if (context is PessimisticConcurrencyContext)
            {
                if (string.IsNullOrWhiteSpace((context as PessimisticConcurrencyContext).LockId))
                {
                    throw new ArgumentNullException("context.LockId", "LockId cannot be null or empty");
                }

                var blobProperties = new BlobProperties();
                blobProperties.ContentType = "application/json";

                var updateText = BlobRequest.Put(
                    this.GetUri(context.ObjectId),
                    BlobRequestTimeout,
                    blobProperties,
                    BlobType.BlockBlob,
                    (context as PessimisticConcurrencyContext).LockId,
                    0);
                using (var stream = new StreamWriter(updateText.GetRequestStream(), Encoding.Default))
                {
                    stream.Write(new JavaScriptSerializer().Serialize(obj));
                }
                this.Account.Credentials.SignRequest(updateText);

                using (var response = updateText.GetResponse())
                {
                    if (response is HttpWebResponse &&
                        !HttpStatusCode.Created.Equals((response as HttpWebResponse).StatusCode))
                    {
                        TraceHelper.TraceError("Error writing leased blob '{0}': {1}", context.ObjectId, (response as HttpWebResponse).StatusDescription);
                        throw new InvalidOperationException((response as HttpWebResponse).StatusDescription);
                    }
                }
            }
            else
            {
                throw new InvalidOperationException("IConcurrencyControlContext implementation cannot be handled");
            }
        }
        /// <summary>
        /// Uploads the block list.
        /// </summary>
        /// <param name="blocks">The blocks to upload.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="TaskSequence"/> that uploads the block list.</returns>
        internal TaskSequence UploadBlockList(List <PutBlockListItem> blocks, BlobRequestOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("modifers");
            }

            var request = ProtocolHelper.GetWebRequest(this.ServiceClient, options, (timeout) => BlobRequest.PutBlockList(this.TransformedAddress, timeout, this.Properties, null));

            options.AccessCondition.ApplyCondition(request);
            BlobRequest.AddMetadata(request, this.Metadata);

            using (var memoryStream = new SmallBlockMemoryStream(Constants.DefaultBufferSize))
            {
                BlobRequest.WriteBlockListBody(blocks, memoryStream);

                CommonUtils.ApplyRequestOptimizations(request, memoryStream.Length);

                memoryStream.Seek(0, SeekOrigin.Begin);

                // Compute the MD5
                var md5 = System.Security.Cryptography.MD5.Create();

                request.Headers[HttpRequestHeader.ContentMd5] = Convert.ToBase64String(md5.ComputeHash(memoryStream));

                this.ServiceClient.Credentials.SignRequest(request);

                memoryStream.Seek(0, SeekOrigin.Begin);

                // Retrieve the stream
                var requestStreamTask = request.GetRequestStreamAsync();
                yield return(requestStreamTask);

                using (Stream requestStream = requestStreamTask.Result)
                {
                    // Copy the data
                    var copyTask = new InvokeTaskSequenceTask(() => { return(memoryStream.WriteTo(requestStream)); });
                    yield return(copyTask);

                    // Materialize any exceptions
                    var scratch = copyTask.Result;
                    Console.WriteLine(scratch);
                }
            }

            // Get the response
            var responseTask = request.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout);

            yield return(responseTask);

            using (var response = responseTask.Result as HttpWebResponse)
            {
                ParseSizeAndLastModified(response);
                this.Properties.Length = 0;
            }
        }
예제 #6
0
        public static void SetMetadata(this CloudBlob blob, string leaseId)
        {
            var req = BlobRequest.SetMetadata(new Uri(blob.ServiceClient.Credentials.TransformUri(blob.Uri.AbsoluteUri)), 90, leaseId);

            foreach (string key in blob.Metadata.Keys)
            {
                req.Headers.Add("x-ms-meta-" + key, blob.Metadata[key]);
            }
            blob.ServiceClient.Credentials.SignRequest(req);
            req.GetResponse().Close();
        }
예제 #7
0
        public static string AcquireLease(this CloudBlob blob)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.AbsoluteUri));
            var req            = BlobRequest.Lease(transformedUri, 90, LeaseAction.Acquire, null);

            blob.ServiceClient.Credentials.SignRequest(req);
            using (var response = req.GetResponse()) {
                return(response.Headers["x-ms-lease-id"]);
            }
        }
        public static void ReleaseLease(this CloudBlob blob, string leaseId)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
            var req            = BlobRequest.Lease(transformedUri, 0, LeaseAction.Release, leaseId);

            blob.ServiceClient.Credentials.SignRequest(req);
            using (var response = req.GetResponse())
            {
            }
        }
예제 #9
0
        public bool AcquireLock(PessimisticConcurrencyContext lockContext)
        {
            var request = BlobRequest.Lease(this.GetUri(lockContext.ObjectId), BlobRequestTimeout, LeaseAction.Acquire, null);

            this.Account.Credentials.SignRequest(request);

            // add extra headers not supported by SDK - not supported by emulator yet (SDK 1.7)
            ////request.Headers["x-ms-version"] = "2012-02-12";
            ////request.Headers.Add("x-ms-lease-duration", lockContext.Duration.TotalSeconds.ToString());

            try
            {
                using (var response = request.GetResponse())
                {
                    if (response is HttpWebResponse &&
                        HttpStatusCode.Created.Equals((response as HttpWebResponse).StatusCode))
                    {
                        lockContext.LockId = response.Headers["x-ms-lease-id"];
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            catch (WebException e)
            {
                this._logger.LogWarning("Warning acquiring blob '{0}' lease: {1}", lockContext.ObjectId, e.Message);
                if (WebExceptionStatus.ProtocolError.Equals(e.Status))
                {
                    if (e.Response is HttpWebResponse)
                    {
                        if (HttpStatusCode.NotFound.Equals((e.Response as HttpWebResponse).StatusCode))
                        {
                            lockContext.LockId = null;
                            return(true);
                        }
                        else if (HttpStatusCode.Conflict.Equals((e.Response as HttpWebResponse).StatusCode))
                        {
                            lockContext.LockId = null;
                            return(false);
                        }
                    }
                    throw;
                }
                return(false);
            }
            catch (Exception e)
            {
                this._logger.LogError("Error acquiring blob '{0}' lease: {1}", lockContext.ObjectId, e.Message);
                throw;
            }
        }
예제 #10
0
        public string AcquireLease(CloudBlob blob, int timeout)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
            var request        = BlobRequest.Lease(transformedUri, timeout, LeaseAction.Acquire, null);

            blob.ServiceClient.Credentials.SignRequest(request);
            using (var response = request.GetResponse())
            {
                return(response.Headers["x-ms-lease-id"]);
            }
        }
        /// <summary>
        /// Converts the source blob of a copy operation to an appropriate access URI, taking Shared Access Signature credentials into account.
        /// </summary>
        /// <param name="source">The source blob.</param>
        /// <returns>A URI addressing the source blob, using SAS if appropriate.</returns>
        internal static Uri SourceBlobToUri(ICloudBlob source)
        {
            Uri sourceUri = source.ServiceClient.Credentials.TransformUri(source.Uri);

            if (source.SnapshotTime.HasValue)
            {
                UriQueryBuilder builder = new UriQueryBuilder();
                builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(source.SnapshotTime.Value));
                sourceUri = builder.AddToUri(sourceUri);
            }

            return(sourceUri);
        }
        public static string AcquireLease(this CloudBlob blob)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
            var req            = BlobRequest.Lease(transformedUri,
                                                   60,                  // timeout (in seconds)
                                                   LeaseAction.Acquire, // as opposed to "break" "release" or "renew"
                                                   null);               // name of the existing lease, if any

            blob.ServiceClient.Credentials.SignRequest(req);
            using (var response = req.GetResponse())
            {
                return(response.Headers["x-ms-lease-id"]);
            }
        }
        /// <summary>
        /// Gets the canonical name of the blob, formatted as /&lt;account-name&gt;/&lt;container-name&gt;/&lt;blob-name&gt;.
        /// If <c>ignoreSnapshotTime</c> is <c>false</c> and this blob is a snapshot, the canonical name is augmented with a
        /// query of the form ?snapshot=&lt;snapshot-time&gt;.
        /// <para>This is used by both Shared Access and Copy blob operations.</para>
        /// </summary>
        /// <param name="ignoreSnapshotTime">Indicates if the snapshot time is ignored.</param>
        /// <returns>The canonical name of the blob.</returns>
        private string GetCanonicalName(bool ignoreSnapshotTime)
        {
            string accountName   = this.ServiceClient.Credentials.AccountName;
            string containerName = this.Container.Name;
            string blobName      = this.Name;

            string canonicalName = string.Format("/{0}/{1}/{2}", accountName, containerName, blobName);

            if (!ignoreSnapshotTime && this.SnapshotTime != null)
            {
                canonicalName += "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value);
            }

            return(canonicalName);
        }
        /// <summary>
        /// Gets the canonical name of the blob, formatted as /&lt;account-name&gt;/&lt;container-name&gt;/&lt;blob-name&gt;.
        /// If <c>ignoreSnapshotTime</c> is <c>false</c> and this blob is a snapshot, the canonical name is augmented with a
        /// query of the form ?snapshot=&lt;snapshot-time&gt;.
        /// <para>This is used by both Shared Access and Copy blob operations.</para>
        /// </summary>
        /// <param name="ignoreSnapshotTime">Indicates if the snapshot time is ignored.</param>
        /// <returns>The canonical name of the blob.</returns>
        private string GetCanonicalName(bool ignoreSnapshotTime)
        {
            string accountName   = this.ServiceClient.Credentials.AccountName;
            string containerName = this.Container.Name;

            // Replace \ with / for uri compatibility when running under .net 4.5.
            string blobName = this.Name.Replace('\\', '/');

            string canonicalName = string.Format(CultureInfo.InvariantCulture, "/{0}/{1}/{2}", accountName, containerName, blobName);

            if (!ignoreSnapshotTime && this.SnapshotTime != null)
            {
                canonicalName += "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value);
            }

            return(canonicalName);
        }
        // NOTE: This method doesn't do everything that the regular UploadText does.
        // Notably, it doesn't update the BlobProperties of the blob (with the new
        // ETag and LastModifiedTimeUtc). It also, like all the methods in this file,
        // doesn't apply any retry logic. Use this at your own risk!
        public static void UploadText(this CloudBlob blob, string text, string leaseId)
        {
            string url = blob.Uri.ToString();

            if (blob.ServiceClient.Credentials.NeedsTransformUri)
            {
                url = blob.ServiceClient.Credentials.TransformUri(url);
            }
            var req = BlobRequest.Put(new Uri(url), 60, new BlobProperties(), BlobType.BlockBlob, leaseId, 0);

            using (var writer = new StreamWriter(req.GetRequestStream()))
            {
                writer.Write(text);
            }
            blob.ServiceClient.Credentials.SignRequest(req);
            req.GetResponse().Close();
        }
        static void SetLength(CloudPageBlob blob, long newLength, int timeout = 10000)
        {
            var credentials = blob.ServiceClient.Credentials;

            var requestUri = blob.Uri;

            if (credentials.NeedsTransformUri)
            {
                requestUri = new Uri(credentials.TransformUri(requestUri.ToString()));
            }

            var request = BlobRequest.SetProperties(requestUri, timeout, blob.Properties, null, newLength);

            request.Timeout = timeout;

            credentials.SignRequest(request);

            using (request.GetResponse()) { }
        }
        public void Resize_Blob(CloudPageBlob pageBlob, CloudBlobClient blobStorage, long newBlobSize)
        {
            Uri requestUri = pageBlob.Uri;

            if (blobStorage.Credentials.NeedsTransformUri)
            {
                requestUri = new Uri(blobStorage.Credentials.TransformUri(requestUri.ToString()));
            }

            HttpWebRequest request = BlobRequest.SetProperties(requestUri, timeout,
                                                               pageBlob.Properties, null, newBlobSize);

            request.Timeout = timeout;
            blobStorage.Credentials.SignRequest(request);
            using (WebResponse response = request.GetResponse())
            {
                // call succeeded
            };
        }
예제 #18
0
 public static void DoLeaseOperation(VLogger logger, CloudBlob blob, string leaseId, LeaseAction action, int AzureBlobLeaseTimeout)
 {
     try
     {
         if (blob == null || leaseId == null)
         {
             return;
         }
         var creds          = blob.ServiceClient.Credentials;
         var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
         var req            = BlobRequest.Lease(transformedUri, AzureBlobLeaseTimeout, action, leaseId);
         creds.SignRequest(req);
         req.GetResponse().Close();
     }
     catch (WebException e)
     {
         Utils.structuredLog(logger, "WebException", e.Message + ". DoLeaseOperation, blob: " + blob.Name + ", leaseId: " + leaseId + ", action " + action);
     }
 }
        /// <summary>
        /// Cast out blob instance and bind it's metadata to metadata repeater
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnBlobDataBound(object sender, ListViewItemEventArgs e)
        {
            if (e.Item.ItemType == ListViewItemType.DataItem)
            {
                var metadataRepeater = e.Item.FindControl("blobMetadata") as Repeater;
                var blob             = ((ListViewDataItem)e.Item).DataItem as CloudBlob;

                // If this blob is a snapshot, rename button to "Delete Snapshot"
                if (blob != null)
                {
                    if (blob.SnapshotTime.HasValue)
                    {
                        var delBtn = e.Item.FindControl("deleteBlob") as LinkButton;

                        if (delBtn != null)
                        {
                            delBtn.Text = "Delete Snapshot";
                            var snapshotRequest = BlobRequest.Get(new Uri(delBtn.CommandArgument), 0, blob.SnapshotTime.Value, null);
                            delBtn.CommandArgument = snapshotRequest.RequestUri.AbsoluteUri;
                        }

                        var snapshotBtn = e.Item.FindControl("SnapshotBlob") as LinkButton;
                        if (snapshotBtn != null)
                        {
                            snapshotBtn.Visible = false;
                        }
                    }

                    if (metadataRepeater != null)
                    {
                        // bind to metadata
                        metadataRepeater.DataSource = from key in blob.Metadata.AllKeys
                                                      select new
                        {
                            Name  = key,
                            Value = blob.Metadata[key]
                        };
                        metadataRepeater.DataBind();
                    }
                }
            }
        }
        static string AcquireLease(CloudBlob blob)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.AbsoluteUri));
            var req            = BlobRequest.Lease(transformedUri, 10, LeaseAction.Acquire, null);

            req.Headers.Add("x-ms-lease-duration", "60");
            creds.SignRequest(req);

            HttpWebResponse response;

            try
            {
                response = (HttpWebResponse)req.GetResponse();
            }
            catch (WebException we)
            {
                var statusCode = ((HttpWebResponse)we.Response).StatusCode;
                switch (statusCode)
                {
                case HttpStatusCode.Conflict:
                case HttpStatusCode.NotFound:
                case HttpStatusCode.RequestTimeout:
                case HttpStatusCode.InternalServerError:
                    return(null);

                default:
                    throw;
                }
            }

            try
            {
                return(response.StatusCode == HttpStatusCode.Created
                    ? response.Headers["x-ms-lease-id"]
                    : null);
            }
            finally
            {
                response.Close();
            }
        }
예제 #21
0
        /// <summary>
        /// Implementation method for the ClearPage methods.
        /// </summary>
        /// <param name="startOffset">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="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="TaskSequence"/> that writes the pages.</returns>
        private TaskSequence ClearPageImpl(long startOffset, long length, BlobRequestOptions options)
        {
            CommonUtils.AssertNotNull("options", options);

            if (startOffset < 0 || startOffset % Protocol.Constants.PageSize != 0)
            {
                CommonUtils.ArgumentOutOfRange("startOffset", startOffset);
            }

            if (length <= 0 || length % Protocol.Constants.PageSize != 0)
            {
                CommonUtils.ArgumentOutOfRange("length", length);
            }

            PutPageProperties properties = new PutPageProperties()
            {
                Range     = new PageRange(startOffset, startOffset + length - 1),
                PageWrite = PageWrite.Clear,
            };

            var webRequest = ProtocolHelper.GetWebRequest(
                this.ServiceClient,
                options,
                (timeout) => BlobRequest.PutPage(this.TransformedAddress, timeout, properties, null));

            webRequest.ContentLength = 0;

            // signing request needs Size to be set
            this.ServiceClient.Credentials.SignRequest(webRequest);

            // Get the response
            var responseTask = webRequest.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout);

            yield return(responseTask);

            // Parse the response
            using (HttpWebResponse webResponse = responseTask.Result as HttpWebResponse)
            {
                this.ParseSizeAndLastModified(webResponse);
            }
        }
예제 #22
0
        public void ReleaseLock(PessimisticConcurrencyContext lockContext)
        {
            if (string.IsNullOrWhiteSpace(lockContext.LockId))
            {
                throw new ArgumentNullException("lockContext.LockId", "LockId cannot be null or empty");
            }

            var request = BlobRequest.Lease(this.GetUri(lockContext.ObjectId), BlobRequestTimeout, LeaseAction.Release, lockContext.LockId);

            this.Account.Credentials.SignRequest(request);

            using (var response = request.GetResponse())
            {
                if (response is HttpWebResponse &&
                    !HttpStatusCode.OK.Equals((response as HttpWebResponse).StatusCode))
                {
                    this._logger.LogError("Error releasing blob '{0}' lease: {1}", lockContext.ObjectId, (response as HttpWebResponse).StatusDescription);
                    throw new InvalidOperationException((response as HttpWebResponse).StatusDescription);
                }
            }
        }
        static bool DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action)
        {
            var creds          = blob.ServiceClient.Credentials;
            var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
            var req            = BlobRequest.Lease(transformedUri, 10, action, leaseId);

            creds.SignRequest(req);

            HttpWebResponse response;

            try
            {
                response = (HttpWebResponse)req.GetResponse();
            }
            catch (WebException we)
            {
                var statusCode = ((HttpWebResponse)we.Response).StatusCode;
                switch (statusCode)
                {
                case HttpStatusCode.Conflict:
                case HttpStatusCode.NotFound:
                case HttpStatusCode.RequestTimeout:
                case HttpStatusCode.InternalServerError:
                    return(false);

                default:
                    throw;
                }
            }

            try
            {
                var expectedCode = action == LeaseAction.Break ? HttpStatusCode.Accepted : HttpStatusCode.OK;
                return(response.StatusCode == expectedCode);
            }
            finally
            {
                response.Close();
            }
        }
예제 #24
0
        public static string AcquireLease(VLogger logger, CloudBlockBlob blob, int AzureBlobLeaseTimeout)
        {
            try
            {
                var creds          = blob.ServiceClient.Credentials;
                var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
                var req            = BlobRequest.Lease(transformedUri, AzureBlobLeaseTimeout, // timeout (in seconds)
                                                       LeaseAction.Acquire,                   // as opposed to "break" "release" or "renew"
                                                       null);                                 // name of the existing lease, if any
                blob.ServiceClient.Credentials.SignRequest(req);
                using (var response = req.GetResponse())
                {
                    return(response.Headers["x-ms-lease-id"]);
                }
            }

            catch (WebException e)
            {
                Utils.structuredLog(logger, "WebException", e.Message + ". AcquireLease, blob: " + blob);
                return(null);
            }
        }
예제 #25
0
 private static void DoLeaseOperation(CloudBlob blob, string leaseId, Microsoft.WindowsAzure.StorageClient.Protocol.LeaseAction action, NLog.Logger logger)
 {
     try
     {
         if (blob == null || leaseId == null)
         {
             return;
         }
         var creds          = blob.ServiceClient.Credentials;
         var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
         var req            = BlobRequest.Lease(transformedUri, AzureBlobLeaseTimeout, action, leaseId);
         creds.SignRequest(req);
         req.GetResponse().Close();
     }
     catch (WebException e)
     {
         if (null != logger)
         {
             logger.ErrorException("DoLeaseOperation, blob: " + blob.Name + ", leaseId: " + leaseId + ", action " + action, e);
         }
     }
 }
예제 #26
0
        private Stream DownloadBlockFromBlob(CloudBlob blob, Block block, Queue <Block> blocksToDownload)
        {
            try
            {
                var blobGetRequest = BlobRequest.Get(blob.Uri, 60, null, null);
                blobGetRequest.Headers.Add("x-ms-range", string.Format(CultureInfo.InvariantCulture, "bytes={0}-{1}", block.Offset, block.Offset + block.Length - 1));
                var credentials = blob.ServiceClient.Credentials;
                credentials.SignRequest(blobGetRequest);
                var response = blobGetRequest.GetResponse() as HttpWebResponse;
                return(response != null?response.GetResponseStream() : null);
            }
            catch
            {
                if (++block.Attempt > MaxRetries)
                {
                    throw;
                }

                lock (blocksToDownload) blocksToDownload.Enqueue(block);
            }
            return(null);
        }
예제 #27
0
        protected virtual void PessimisticControlContextWriteStrategy(IConcurrencyControlContext context, T obj)
        {
            if (string.IsNullOrWhiteSpace((context as PessimisticConcurrencyContext).LockId))
            {
                throw new ArgumentNullException("context.LockId", "LockId cannot be null or empty");
            }

            var blobProperties = new BlobProperties();

            var binarizedObject = this.BinarizeObjectForStreaming(blobProperties, obj);

            var updateRequest = BlobRequest.Put(
                this.GetUri(context.ObjectId),
                BlobRequestTimeout,
                blobProperties,
                BlobType.BlockBlob,
                (context as PessimisticConcurrencyContext).LockId,
                0);

            using (var writer = new BinaryWriter(updateRequest.GetRequestStream(), Encoding.Default))
            {
                writer.Write(binarizedObject);
            }

            this.Account.Credentials.SignRequest(updateRequest);

            using (var response = updateRequest.GetResponse())
            {
                if (response is HttpWebResponse &&
                    !HttpStatusCode.Created.Equals((response as HttpWebResponse).StatusCode))
                {
                    this._logger.LogError("Error writing leased blob '{0}': {1}", context.ObjectId, (response as HttpWebResponse).StatusDescription);
                    throw new InvalidOperationException((response as HttpWebResponse).StatusDescription);
                }
            }
        }
예제 #28
0
        /// <summary>
        /// Gets the page ranges impl.
        /// </summary>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <param name="setResult">The set result.</param>
        /// <returns>A <see cref="TaskSequence"/> for getting the page ranges.</returns>
        private TaskSequence GetPageRangesImpl(BlobRequestOptions options, Action <IEnumerable <PageRange> > setResult)
        {
            CommonUtils.AssertNotNull("options", options);

            var webRequest = ProtocolHelper.GetWebRequest(this.ServiceClient, options, (timeout) => BlobRequest.GetPageRanges(this.TransformedAddress, timeout, this.SnapshotTime, null));

            BlobRequest.AddMetadata(webRequest, this.Metadata);
            this.ServiceClient.Credentials.SignRequest(webRequest);
            var task = webRequest.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout);

            yield return(task);

            using (var webResponse = task.Result as HttpWebResponse)
            {
                var getPageRangesResponse   = BlobResponse.GetPageRanges(webResponse);
                List <PageRange> pageRanges = new List <PageRange>();

                // materialize response as we need to close the webResponse
                pageRanges.AddRange(getPageRangesResponse.PageRanges.ToList());

                setResult(pageRanges);

                this.ParseSizeAndLastModified(webResponse);
            }
        }
예제 #29
0
        /// <summary>
        /// Gets the download block list.
        /// </summary>
        /// <param name="typesOfBlocks">The types of blocks.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <param name="setResult">The result report delegate.</param>
        /// <returns>A <see cref="TaskSequence"/> that gets the download block list.</returns>
        internal TaskSequence GetDownloadBlockList(BlockListingFilter typesOfBlocks, BlobRequestOptions options, Action <IEnumerable <ListBlockItem> > setResult)
        {
            var request = ProtocolHelper.GetWebRequest(this.ServiceClient, options, (timeout) => BlobRequest.GetBlockList(this.TransformedAddress, timeout, this.SnapshotTime, typesOfBlocks, null));

            this.ServiceClient.Credentials.SignRequest(request);

            // Retrieve the stream
            var requestStreamTask = request.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout);

            yield return(requestStreamTask);

            // Copy the data
            using (var response = requestStreamTask.Result as HttpWebResponse)
            {
                using (var responseStream = response.GetResponseStream())
                {
                    var blockListResponse = new GetBlockListResponse(responseStream);

                    setResult(ParseResponse(blockListResponse));
                }

                this.ParseSizeAndLastModified(response);
            }
        }
예제 #30
0
        /// <summary>
        /// Implementation method for the WritePage methods.
        /// </summary>
        /// <param name="pageData">The page data.</param>
        /// <param name="startOffset">The start offset.</param>
        /// <param name="sourceStreamPosition">The beginning position of the source stream prior to execution, negative if stream is unseekable.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="TaskSequence"/> that writes the pages.</returns>
        private TaskSequence WritePageImpl(Stream pageData, long startOffset, long sourceStreamPosition, BlobRequestOptions options)
        {
            CommonUtils.AssertNotNull("options", options);

            long length = pageData.Length;

            // Logic to rewind stream on a retry
            // For non seekable streams we need a way to detect the retry iteration so as to only attempt to execute once.
            // The first attempt will have SourceStreamPosition = -1, which means the first iteration on a non seekable stream.
            // The second attempt will have SourceStreamPosition = -2, anything below -1 is considered an abort. Since the Impl method
            // does not have an execution context to be aware of what iteration is used the SourceStreamPosition is utilized as counter to
            // differentiate between the first attempt and a retry.
            if (sourceStreamPosition >= 0 && pageData.CanSeek)
            {
                if (sourceStreamPosition != pageData.Position)
                {
                    pageData.Seek(sourceStreamPosition, 0);
                }
            }
            else if (sourceStreamPosition < -1)
            {
                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.CannotRetryNonSeekableStreamError));
            }

            if (startOffset % Protocol.Constants.PageSize != 0)
            {
                CommonUtils.ArgumentOutOfRange("startOffset", startOffset);
            }

            long rangeStreamOffset = pageData.CanSeek ? pageData.Position : 0;

            PutPageProperties properties = new PutPageProperties()
            {
                Range     = new PageRange(startOffset, startOffset + length - rangeStreamOffset - 1),
                PageWrite = PageWrite.Update,
            };

            if ((1 + properties.Range.EndOffset - properties.Range.StartOffset) % Protocol.Constants.PageSize != 0 ||
                (1 + properties.Range.EndOffset - properties.Range.StartOffset) == 0)
            {
                CommonUtils.ArgumentOutOfRange("pageData", pageData);
            }

            var webRequest = ProtocolHelper.GetWebRequest(
                this.ServiceClient,
                options,
                (timeout) => BlobRequest.PutPage(this.TransformedAddress, timeout, properties, null));

            ////BlobRequest.AddMetadata(webRequest, this.Metadata);

            // Retrieve the stream
            var requestStreamTask = webRequest.GetRequestStreamAsync();

            yield return(requestStreamTask);

            // Copy the data
            using (var outputStream = requestStreamTask.Result)
            {
                var copyTask = new InvokeTaskSequenceTask(() => { return(pageData.WriteTo(outputStream)); });
                yield return(copyTask);

                // Materialize any exceptions
                var scratch = copyTask.Result;
            }

            // signing request needs Size to be set
            this.ServiceClient.Credentials.SignRequest(webRequest);

            // Get the response
            var responseTask = webRequest.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout);

            yield return(responseTask);

            // Parse the response
            using (HttpWebResponse webResponse = responseTask.Result as HttpWebResponse)
            {
                this.ParseSizeAndLastModified(webResponse);
            }
        }