public async Task RenewLeaseAsync(string jobId, string leaseId)
        {
            var blockBlob = await GetLeaseBlobForJob(jobId);

            await blockBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId));
        }
Esempio n. 2
0
        public async Task <bool> ReleaseAsync(BlobLease lease)
        {
            CloudBlockBlob leaseBlob = lease.Blob;

            try
            {
                string leaseId = lease.Token;

                BlobLease copy = new BlobLease(lease);
                copy.Token = null;
                copy.Owner = null;
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(copy), null, AccessCondition.GenerateLeaseCondition(leaseId), null, null);

                this.stats.StorageRequests.Increment();
                await leaseBlob.ReleaseLeaseAsync(accessCondition : AccessCondition.GenerateLeaseCondition(leaseId));

                this.stats.StorageRequests.Increment();
            }
            catch (StorageException storageException)
            {
                this.stats.StorageRequests.Increment();
                throw HandleStorageException(lease, storageException);
            }

            return(true);
        }
 public static void ReleaseLease(this CloudBlockBlob blob, string leaseId)
 {
     blob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId));
 }
Esempio n. 4
0
        public void PutBlockListScenarioTest(string containerName, string blobName, List <PutBlockListItem> blocks, BlobProperties blobProperties, string leaseId, HttpStatusCode?expectedError)
        {
            HttpWebRequest request = BlobTests.PutBlockListRequest(BlobContext, containerName, blobName, blobProperties, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpWebRequest");
            byte[] content;
            using (MemoryStream stream = new MemoryStream())
            {
                BlobRequest.WriteBlockListBody(blocks, stream);
                stream.Seek(0, SeekOrigin.Begin);
                content = new byte[stream.Length];
                stream.Read(content, 0, content.Length);
            }
            request.ContentLength = content.Length;
            if (BlobContext.Credentials != null)
            {
                BlobTests.SignRequest(request, BlobContext);
            }
            BlobTestUtils.SetRequest(request, BlobContext, content);
            HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext);

            try
            {
                BlobTests.PutBlockListResponse(response, BlobContext, expectedError);
            }
            finally
            {
                response.Close();
            }
        }
Esempio n. 5
0
        public void UploadBigFileWithCommits()
        {
            StorageCredentials  creds   = new StorageCredentials(AcctName, AcctKey);
            CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
            CloudBlobClient     client  = account.CreateCloudBlobClient();
            CloudBlockBlob      blob    = new CloudBlockBlob(Uri, client);

            var blockList = new List <string>();

            byte[] bytesRead    = new byte[FOURMB];
            int    numBytesRead = 0;

            MemoryStream ms = new MemoryStream();

            ms.Capacity = FOURMB;
            Boolean DoneSending = false;

            string acquiredLeaseId = null;
            string proposedLeaseId = Guid.NewGuid().ToString();

            using (FileStream fs = File.OpenRead(Filename))
            {
                AccessCondition accessCondition = AccessCondition.GenerateEmptyCondition();
                do
                {
                    Console.Write(".");
                    NewBlockId blockId = new NewBlockId();

                    try
                    {
                        if (blockList.Count > 0)
                        {
                            acquiredLeaseId = ((ICloudBlob)blob).AcquireLeaseAsync(TimeSpan.FromMinutes(1), proposedLeaseId).Result;
                            accessCondition = AccessCondition.GenerateLeaseCondition(acquiredLeaseId);
                        }

                        ms.Position  = 0;
                        numBytesRead = fs.Read(bytesRead, 0, FOURMB);

                        if (numBytesRead == FOURMB)
                        {
                            ms.Write(bytesRead, 0, FOURMB);
                            Send4mbBlockAsyncWithAccessCondition(blob, ms, blockId, accessCondition).Wait();
                        }
                        else
                        {
                            MemoryStream msLast = new MemoryStream();
                            msLast.Capacity = numBytesRead;

                            msLast.Write(bytesRead, 0, numBytesRead);
                            Send4mbBlockAsyncWithAccessCondition(blob, msLast, blockId, accessCondition).Wait();

                            DoneSending = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine();
                        Console.WriteLine($"Error: {ex.Message} :sending block to storage.");
                        continue;
                    }

                    try
                    {
                        blockList.Add(blockId.Base64BlockId);
                        blob.PutBlockListAsync(
                            blockList,
                            accessCondition,
                            options: new BlobRequestOptions
                        {
                            StoreBlobContentMD5 = true,
                            UseTransactionalMD5 = true
                        },
                            operationContext: new OperationContext()).Wait();
                    } catch (Exception ex)
                    {
                        Console.WriteLine();
                        Console.WriteLine($"Error: {ex.Message} :commiting block list.");
                    } finally
                    {
                        if (acquiredLeaseId != null)
                        {
                            ((ICloudBlob)blob).ReleaseLeaseAsync(accessCondition).Wait();
                            acquiredLeaseId = null;
                        }
                    }
                } while (!DoneSending);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Scenario test for changing a lease.
        /// </summary>
        /// <param name="containerName">The name of the container.</param>
        /// <param name="blobName">The name of the blob, if any.</param>
        /// <param name="leaseId">The lease ID.</param>
        /// <param name="proposedLeaseId">The proposed lease ID.</param>
        /// <param name="expectedError">The error status code to expect.</param>
        /// <returns>The lease ID.</returns>
        public string ChangeLeaseScenarioTest(string containerName, string blobName, string leaseId, string proposedLeaseId, HttpStatusCode?expectedError)
        {
            // Create and validate the web request
            HttpWebRequest request = BlobTests.ChangeLeaseRequest(BlobContext, containerName, blobName, proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId));

            if (BlobContext.Credentials != null)
            {
                BlobTests.SignRequest(request, BlobContext);
            }

            using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.ChangeLeaseResponse(response, proposedLeaseId, expectedError);

                return(BlobHttpResponseParsers.GetLeaseId(response));
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Sends a get blob range request with the given parameters and validates both request and response.
        /// </summary>
        /// <param name="containerName">The blob's container's name.</param>
        /// <param name="blobName">The blob's name.</param>
        /// <param name="leaseId">The lease ID, or null if there is no lease.</param>
        /// <param name="content">The total contents of the blob.</param>
        /// <param name="offset">The offset of the contents we will get.</param>
        /// <param name="count">The number of bytes we will get, or null to get the rest of the blob.</param>
        /// <param name="expectedError">The error code we expect from this operation, or null if we expect it to succeed.</param>
        public void GetBlobRangeScenarioTest(string containerName, string blobName, string leaseId, byte[] content, long offset, long?count, HttpStatusCode?expectedError)
        {
            HttpWebRequest request = BlobTests.GetBlobRangeRequest(BlobContext, containerName, blobName, offset, count, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpWebRequest");

            if (BlobContext.Credentials != null)
            {
                BlobTests.SignRequest(request, BlobContext);
            }

            HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext);

            try
            {
                long   endRange        = count.HasValue ? count.Value + offset - 1 : content.Length - 1;
                byte[] selectedContent = null;

                // Compute expected content only if call is expected to succeed.
                if (expectedError == null)
                {
                    selectedContent = new byte[endRange - offset + 1];
                    Array.Copy(content, offset, selectedContent, 0, selectedContent.Length);
                }

                BlobTests.CheckBlobRangeResponse(response, BlobContext, selectedContent, offset, endRange, content.Length, expectedError);
            }
            finally
            {
                response.Close();
            }
        }
Esempio n. 8
0
        /// <summary>Ensures that 1 machine will execute an operation periodically.</summary>
        /// <param name="startTime">The base time; all machines should use the same exact base time.</param>
        /// <param name="period">Indicates how frequently you want the operation performed.</param>
        /// <param name="timeBetweenLeaseRetries">Indicates how frequently a machine that is not elected to perform the work should retry the work in case the elected machine crashes while performing the work.</param>
        /// <param name="blob">The blob that all the machines should be using to acquire a lease.</param>
        /// <param name="cancellationToken">Indicates when the operation should no longer be performed in the future.</param>
        /// <param name="winnerWorker">A method that is called periodically by whatever machine wins the election.</param>
        /// <returns>A Task which you can  use to catch an exception or known then this method has been canceled.</returns>
        public static async Task RunAsync(DateTimeOffset startTime, TimeSpan period,
                                          TimeSpan timeBetweenLeaseRetries, ICloudBlob blob,
                                          CancellationToken cancellationToken, Func <Task> winnerWorker)
        {
            var bro = new BlobRequestOptions {
                RetryPolicy = new ExponentialRetry()
            };
            const Int32    leaseDurationSeconds = 60; // 15-60 seconds
            DateTimeOffset nextElectionTime     = NextElectionTime(startTime, period);

            while (true)
            {
                TimeSpan timeToWait = nextElectionTime - DateTimeOffset.UtcNow;
                timeToWait = (timeToWait < TimeSpan.Zero) ? TimeSpan.Zero : timeToWait;
                await Task.Delay(timeToWait, cancellationToken).ConfigureAwait(false); // Wait until time to check

                ElectionError electionError = ElectionError.Unknown;
                try {
                    // Try to acquire lease & check metadata to see if this period has been processed
                    String leaseId = await blob.AcquireLeaseAsync(TimeSpan.FromSeconds(leaseDurationSeconds), null,
                                                                  AccessCondition.GenerateIfNotModifiedSinceCondition(nextElectionTime), bro, null, CancellationToken.None).ConfigureAwait(false);

                    try {
                        // Got lease: do elected work (periodically renew lease)
                        Task winnerWork = Task.Run(winnerWorker);
                        while (true)
                        {
                            // Verify if winnerWork throws, we exit this loop & release the lease to try again
                            Task wakeUp = await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(leaseDurationSeconds - 15)), winnerWork).ConfigureAwait(false);

                            if (wakeUp == winnerWork) // Winner work is done
                            {
                                if (winnerWork.IsFaulted)
                                {
                                    throw winnerWork.Exception;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            await blob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).ConfigureAwait(false);
                        }
                        // After work done, write to blob to indicate elected winner sucessfully did work
                        blob.UploadFromByteArray(new Byte[1], 0, 1, AccessCondition.GenerateLeaseCondition(leaseId), bro, null);
                        nextElectionTime = NextElectionTime(nextElectionTime + period, period);
                    }
                    finally {
                        blob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId));
                    }
                }
                catch (StorageException ex) {
                    if (ex.Matches(HttpStatusCode.Conflict, BlobErrorCodeStrings.LeaseAlreadyPresent))
                    {
                        electionError = ElectionError.LeaseAlreadyPresent;
                    }
                    else if (ex.Matches(HttpStatusCode.PreconditionFailed))
                    {
                        electionError = ElectionError.ElectionOver;
                    }
                    else
                    {
                        throw;
                    }
                }
                switch (electionError)
                {
                case ElectionError.ElectionOver:
                    // If access condition failed, the election is over, wait until next election time
                    nextElectionTime = NextElectionTime(nextElectionTime + period, period);
                    break;

                case ElectionError.LeaseAlreadyPresent:
                    // if failed to get lease, wait a bit and retry again
                    await Task.Delay(timeBetweenLeaseRetries).ConfigureAwait(false);

                    break;
                }
            }
            // We never get here
        }
        private Task Release(string category, AcquiredLease acquiredLease)
        {
            var blob = this.container.GetBlobReference(GetBlobName(category, acquiredLease.ResourceKey));

            return(blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(acquiredLease.Token)));
        }
        public void ReleaseLease(FileNode fileNode, string leaseId)
        {
            var blob = this.GetCloudBlobReference(fileNode);

            blob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), options: HelperConst.DefaultBlobOptions);
        }
Esempio n. 11
0
        static void AcquireLeaseSample(string connectionString)
        {
            const string        blobName       = "rating.txt";
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudBlobClient     client         = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer  container      = client.GetContainerReference("myfiles");
            CloudBlockBlob      blob           = container.GetBlockBlobReference(blobName);

            blob.UploadText("0", Encoding.UTF8);

            Parallel.For(0, 20, new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount * 2
            }, i =>
            {
                CloudStorageAccount sAccount  = CloudStorageAccount.Parse(connectionString);
                CloudBlobClient bClient       = storageAccount.CreateCloudBlobClient();
                CloudBlobContainer bContainer = client.GetContainerReference("myfiles");
                CloudBlockBlob blobRef        = container.GetBlockBlobReference(blobName);

                bool isOk = false;
                while (isOk == false)
                {
                    try
                    {
                        // The Lease Blob operation establishes and manages a lock on a blob for write and delete operations.
                        // The lock duration can be 15 to 60 seconds, or can be infinite.
                        string leaseId = blobRef.AcquireLease(TimeSpan.FromSeconds(15), Guid.NewGuid().ToString());
                        using (Stream stream = blobRef.OpenRead())
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                int raitingCount     = int.Parse(reader.ReadToEnd());
                                byte[] bytesToUpload = Encoding.UTF8.GetBytes((raitingCount + 1).ToString(CultureInfo.InvariantCulture));
                                blobRef.UploadFromByteArray(bytesToUpload, 0, bytesToUpload.Length, AccessCondition.GenerateLeaseCondition(leaseId));
                            }

                        blobRef.BreakLease(breakPeriod: TimeSpan.Zero, accessCondition: AccessCondition.GenerateLeaseCondition(leaseId));
                        isOk = true;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            });
        }
Esempio n. 12
0
 public async Task ReleaseLeaseAsync(string leaseId)
 {
     await this.azureStorageClient.MakeBlobStorageRequest(
         (context, cancellationToken) => this.cloudBlockBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, context, cancellationToken),
         "Blob ReleaseLease");
 }
Esempio n. 13
0
 public async Task <string> ChangeLeaseAsync(string proposedLeaseId, string currentLeaseId)
 {
     return(await this.azureStorageClient.MakeBlobStorageRequest <string>(
                (context, cancellationToken) => this.cloudBlockBlob.ChangeLeaseAsync(proposedLeaseId, accessCondition: AccessCondition.GenerateLeaseCondition(currentLeaseId), null, context, cancellationToken),
                "Blob ChangeLease"));
 }
Esempio n. 14
0
 /// <summary>
 /// Renews active lease
 /// </summary>
 /// <returns></returns>
 public async Task RenewLeaseAsync()
 {
     await _blob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(LeaseId));
 }
        async Task <bool> AcquireLeaseCoreAsync(AzureBlobLease lease)
        {
            CloudBlockBlob leaseBlob   = lease.Blob;
            bool           retval      = true;
            string         newLeaseId  = Guid.NewGuid().ToString();
            string         partitionId = lease.PartitionId;

            try
            {
                string newToken;
                await leaseBlob.FetchAttributesAsync().ConfigureAwait(false);

                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.Id, lease.PartitionId, "Need to ChangeLease");
                    newToken = await leaseBlob.ChangeLeaseAsync(newLeaseId, AccessCondition.GenerateLeaseCondition(lease.Token)).ConfigureAwait(false);
                }
                else
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.Id, lease.PartitionId, "Need to AcquireLease");
                    newToken = await leaseBlob.AcquireLeaseAsync(leaseDuration, newLeaseId).ConfigureAwait(false);
                }

                lease.Token = newToken;
                lease.Owner = this.host.HostName;
                lease.IncrementEpoch(); // Increment epoch each time lease is acquired or stolen by a new host
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null).ConfigureAwait(false);
            }
            catch (StorageException se)
            {
                if (WasLeaseLost(partitionId, se))
                {
                    retval = false;
                }
                else
                {
                    throw;
                }
            }

            return(retval);
        }
Esempio n. 16
0
        /// <summary>
        /// Scenario test for changing a lease.
        /// </summary>
        /// <param name="containerName">The name of the container.</param>
        /// <param name="blobName">The name of the blob, if any.</param>
        /// <param name="leaseId">The lease ID.</param>
        /// <param name="proposedLeaseId">The proposed lease ID.</param>
        /// <param name="expectedError">The error status code to expect.</param>
        /// <returns>The lease ID.</returns>
        public async Task <string> ChangeLeaseScenarioTest(string containerName, string blobName, string leaseId, string proposedLeaseId, HttpStatusCode?expectedError)
        {
            // Create and validate the web request
            HttpRequestMessage request = BlobTests.ChangeLeaseRequest(BlobContext, containerName, blobName, proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId));

            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.ChangeLeaseResponse(response, proposedLeaseId, expectedError);

                return(BlobHttpResponseParsers.GetLeaseId(response));
            }
        }
        async Task <bool> ReleaseLeaseCoreAsync(AzureBlobLease lease)
        {
            ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.Id, lease.PartitionId, "Releasing lease");

            CloudBlockBlob leaseBlob   = lease.Blob;
            bool           retval      = true;
            string         partitionId = lease.PartitionId;

            try
            {
                string         leaseId      = lease.Token;
                AzureBlobLease releasedCopy = new AzureBlobLease(lease)
                {
                    Token = string.Empty,
                    Owner = string.Empty
                };
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(releasedCopy), null, AccessCondition.GenerateLeaseCondition(leaseId), null, null).ConfigureAwait(false);

                await leaseBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).ConfigureAwait(false);
            }
            catch (StorageException se)
            {
                if (WasLeaseLost(partitionId, se))
                {
                    retval = false;
                }
                else
                {
                    throw;
                }
            }

            return(retval);
        }
Esempio n. 18
0
        /// <summary>
        /// Scenario test for releasing a lease.
        /// </summary>
        /// <param name="containerName">The name of the container.</param>
        /// <param name="blobName">The name of the blob, if any.</param>
        /// <param name="leaseId">The lease ID.</param>
        /// <param name="expectedError">The error status code to expect.</param>
        public async Task ReleaseLeaseScenarioTest(string containerName, string blobName, string leaseId, HttpStatusCode?expectedError)
        {
            // Create and validate the web request
            HttpRequestMessage request = BlobTests.ReleaseLeaseRequest(BlobContext, containerName, blobName, AccessCondition.GenerateLeaseCondition(leaseId));

            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.ReleaseLeaseResponse(response, expectedError);
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Scenario test for releasing a lease.
        /// </summary>
        /// <param name="containerName">The name of the container.</param>
        /// <param name="blobName">The name of the blob, if any.</param>
        /// <param name="leaseId">The lease ID.</param>
        /// <param name="expectedError">The error status code to expect.</param>
        public void ReleaseLeaseScenarioTest(string containerName, string blobName, string leaseId, HttpStatusCode?expectedError)
        {
            // Create and validate the web request
            HttpWebRequest request = BlobTests.ReleaseLeaseRequest(BlobContext, containerName, blobName, AccessCondition.GenerateLeaseCondition(leaseId));

            if (BlobContext.Credentials != null)
            {
                BlobTests.SignRequest(request, BlobContext);
            }

            using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.ReleaseLeaseResponse(response, expectedError);
            }
        }
Esempio n. 20
0
        public async Task GetBlobScenarioTest(string containerName, string blobName, BlobProperties properties, string leaseId,
                                              byte[] content, HttpStatusCode?expectedError)
        {
            HttpRequestMessage request = BlobTests.GetBlobRequest(BlobContext, containerName, blobName, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");

            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.GetBlobResponse(response, BlobContext, properties, content, expectedError);
            }
        }
Esempio n. 21
0
        public void PutBlockScenarioTest(string containerName, string blobName, string blockId, string leaseId, byte[] content, HttpStatusCode?expectedError)
        {
            HttpWebRequest request = BlobTests.PutBlockRequest(BlobContext, containerName, blobName, blockId, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpWebRequest");
            request.ContentLength = content.Length;
            if (BlobContext.Credentials != null)
            {
                BlobTests.SignRequest(request, BlobContext);
            }
            BlobTestUtils.SetRequest(request, BlobContext, content);
            HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext);

            try
            {
                BlobTests.PutBlockResponse(response, BlobContext, expectedError);
            }
            finally
            {
                response.Close();
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Sends a get blob range request with the given parameters and validates both request and response.
        /// </summary>
        /// <param name="containerName">The blob's container's name.</param>
        /// <param name="blobName">The blob's name.</param>
        /// <param name="leaseId">The lease ID, or null if there is no lease.</param>
        /// <param name="content">The total contents of the blob.</param>
        /// <param name="offset">The offset of the contents we will get.</param>
        /// <param name="count">The number of bytes we will get, or null to get the rest of the blob.</param>
        /// <param name="expectedError">The error code we expect from this operation, or null if we expect it to succeed.</param>
        public async Task GetBlobRangeScenarioTest(string containerName, string blobName, string leaseId, byte[] content, long offset, long?count, HttpStatusCode?expectedError)
        {
            HttpRequestMessage request = BlobTests.GetBlobRangeRequest(BlobContext, containerName, blobName, offset, count, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");

            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                long   endRange        = count.HasValue ? count.Value + offset - 1 : content.Length - 1;
                byte[] selectedContent = null;

                // Compute expected content only if call is expected to succeed.
                if (expectedError == null)
                {
                    selectedContent = new byte[endRange - offset + 1];
                    Array.Copy(content, offset, selectedContent, 0, selectedContent.Length);
                }

                BlobTests.CheckBlobRangeResponse(response, BlobContext, selectedContent, offset, endRange, content.Length, expectedError);
            }
        }
Esempio n. 23
0
        public void GetBlockListScenarioTest(string containerName, string blobName, BlockListingFilter typesOfBlocks, string leaseId, HttpStatusCode?expectedError, params string[] expectedBlocks)
        {
            HttpWebRequest request = BlobTests.GetBlockListRequest(BlobContext, containerName, blobName, typesOfBlocks, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpWebRequest");
            if (BlobContext.Credentials != null)
            {
                BlobTests.SignRequest(request, BlobContext);
            }
            HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext);

            try
            {
                BlobTests.GetBlockListResponse(response, BlobContext, expectedError);
                GetBlockListResponse getBlockListResponse = new GetBlockListResponse(response.GetResponseStream());
                int i = 0;
                foreach (ListBlockItem item in getBlockListResponse.Blocks)
                {
                    if (expectedBlocks == null)
                    {
                        Assert.Fail("Should not have blocks.");
                    }
                    Assert.IsTrue(i < expectedBlocks.Length, "Unexpected block: " + item.Name);
                    Assert.AreEqual <string>(expectedBlocks[i++], item.Name, "Incorrect block.");
                }
                if (expectedBlocks != null && i < expectedBlocks.Length)
                {
                    Assert.Fail("Missing block: " + expectedBlocks[i] + "(and " + (expectedBlocks.Length - i - 1) + " more).");
                }
            }
            finally
            {
                response.Close();
            }
        }
Esempio n. 24
0
        public async Task PutBlockScenarioTest(string containerName, string blobName, string blockId, string leaseId, byte[] content, HttpStatusCode?expectedError)
        {
            HttpRequestMessage request = BlobTests.PutBlockRequest(BlobContext, containerName, blobName, blockId, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");
            //HttpRequestHandler.SetContentLength(request, content.Length);
            request.Content = new ByteArrayContent(content);
            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.PutBlockResponse(response, BlobContext, expectedError);
            }
        }
Esempio n. 25
0
        public async Task <bool> AcquireAsync(BlobLease lease, string owner)
        {
            CloudBlockBlob leaseBlob = lease.Blob;

            try
            {
                await leaseBlob.FetchAttributesAsync();

                string newLeaseId = Guid.NewGuid().ToString("N");
                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    lease.Token = await leaseBlob.ChangeLeaseAsync(newLeaseId, accessCondition : AccessCondition.GenerateLeaseCondition(lease.Token));
                }
                else
                {
                    lease.Token = await leaseBlob.AcquireLeaseAsync(this.leaseInterval, newLeaseId);
                }

                this.stats.StorageRequests.Increment();
                lease.Owner = owner;
                // Increment Epoch each time lease is acquired or stolen by new host
                lease.Epoch += 1;
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null);

                this.stats.StorageRequests.Increment();
            }
            catch (StorageException storageException)
            {
                this.stats.StorageRequests.Increment();
                throw HandleStorageException(lease, storageException);
            }

            return(true);
        }
Esempio n. 26
0
        public async Task PutBlockListScenarioTest(string containerName, string blobName, List <PutBlockListItem> blocks, BlobProperties blobProperties, string leaseId, HttpStatusCode?expectedError)
        {
            HttpRequestMessage request = BlobTests.PutBlockListRequest(BlobContext, containerName, blobName, blobProperties, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");
            byte[] content;
            using (MemoryStream stream = new MemoryStream())
            {
                BlobRequest.WriteBlockListBody(blocks, stream);
                stream.Seek(0, SeekOrigin.Begin);
                content = new byte[stream.Length];
                stream.Read(content, 0, content.Length);
            }
            //HttpRequestHandler.SetContentLength(request, content.Length);
            request.Content = new ByteArrayContent(content);
            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.PutBlockListResponse(response, BlobContext, expectedError);
            }
        }
Esempio n. 27
0
        public async Task <bool> UpdateAsync(BlobLease lease)
        {
            if (lease == null || string.IsNullOrWhiteSpace(lease.Token))
            {
                return(false);
            }

            CloudBlockBlob leaseBlob = lease.Blob;

            try
            {
                // First renew the lease to make sure checkpoint will go through
                await leaseBlob.RenewLeaseAsync(accessCondition : AccessCondition.GenerateLeaseCondition(lease.Token));
            }
            catch (StorageException storageException)
            {
                throw HandleStorageException(lease, storageException);
            }
            finally
            {
                this.stats.StorageRequests.Increment();
            }

            try
            {
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null);
            }
            catch (StorageException storageException)
            {
                throw HandleStorageException(lease, storageException, true);
            }
            finally
            {
                this.stats.StorageRequests.Increment();
            }

            return(true);
        }
Esempio n. 28
0
        public async Task GetBlockListScenarioTest(string containerName, string blobName, BlockListingFilter typesOfBlocks, string leaseId, HttpStatusCode?expectedError, params string[] expectedBlocks)
        {
            HttpRequestMessage request = BlobTests.GetBlockListRequest(BlobContext, containerName, blobName, typesOfBlocks, AccessCondition.GenerateLeaseCondition(leaseId));

            Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");
            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
            {
                BlobTests.GetBlockListResponse(response, BlobContext, expectedError);
                IEnumerable <ListBlockItem> getBlockListResponse = await GetBlockListResponse.ParseAsync(HttpResponseParsers.GetResponseStream(response), CancellationToken.None);

                int i = 0;
                foreach (ListBlockItem item in getBlockListResponse)
                {
                    if (expectedBlocks == null)
                    {
                        Assert.Fail("Should not have blocks.");
                    }
                    Assert.IsTrue(i < expectedBlocks.Length, "Unexpected block: " + item.Name);
                    Assert.AreEqual <string>(expectedBlocks[i++], item.Name, "Incorrect block.");
                }
                if (expectedBlocks != null && i < expectedBlocks.Length)
                {
                    Assert.Fail("Missing block: " + expectedBlocks[i] + "(and " + (expectedBlocks.Length - i - 1) + " more).");
                }
            }
        }
 public static bool TryRenewLease(this CloudBlockBlob blob, string leaseId)
 {
     try { blob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); return(true); }
     catch { return(false); }
 }
Esempio n. 30
0
        async Task <bool> AcquireLeaseCoreAsync(AzureBlobLease lease)
        {
            CloudBlockBlob leaseBlob   = lease.Blob;
            bool           retval      = true;
            string         newLeaseId  = Guid.NewGuid().ToString();
            string         partitionId = lease.PartitionId;

            try
            {
                string newToken;
                await leaseBlob.FetchAttributesAsync().ConfigureAwait(false);

                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    if (string.IsNullOrEmpty(lease.Token))
                    {
                        // We reach here in a race condition: when this instance of EventProcessorHost scanned the
                        // lease blobs, this partition was unowned (token is empty) but between then and now, another
                        // instance of EPH has established a lease (getLeaseState() is LEASED). We normally enforce
                        // that we only steal the lease if it is still owned by the instance which owned it when we
                        // scanned, but we can't do that when we don't know who owns it. The safest thing to do is just
                        // fail the acquisition. If that means that one EPH instance gets more partitions than it should,
                        // rebalancing will take care of that quickly enough.
                        return(false);
                    }

                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, lease.PartitionId, "Need to ChangeLease");
                    newToken = await leaseBlob.ChangeLeaseAsync(newLeaseId, AccessCondition.GenerateLeaseCondition(lease.Token)).ConfigureAwait(false);
                }
                else
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, lease.PartitionId, "Need to AcquireLease");

                    try
                    {
                        newToken = await leaseBlob.AcquireLeaseAsync(leaseDuration, newLeaseId).ConfigureAwait(false);
                    }
                    catch (StorageException se)
                        when(se.RequestInformation != null &&
                             se.RequestInformation.ErrorCode.Equals(BlobErrorCodeStrings.LeaseAlreadyPresent, StringComparison.OrdinalIgnoreCase))
                        {
                            // Either some other host grabbed the lease or checkpoint call renewed it.
                            return(false);
                        }
                }

                lease.Token = newToken;
                lease.Owner = this.host.HostName;
                lease.IncrementEpoch(); // Increment epoch each time lease is acquired or stolen by a new host
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null).ConfigureAwait(false);
            }
            catch (StorageException se)
            {
                throw HandleStorageException(partitionId, se);
            }

            return(retval);
        }