示例#1
0
        private static async Task ShowETag(string containerName, string filename)
        {
            CloudStorageAccount storage            = CloudStorageAccount.Parse(conn_string);
            CloudBlobClient     cloudBlobClient    = storage.CreateCloudBlobClient();
            CloudBlobContainer  cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName);


            var blob = cloudBlobContainer.GetBlockBlobReference(filename);
            await blob.FetchAttributesAsync();

            var orginalETag = blob.Properties.ETag;

            blob.UploadText($"New Content {DateTime.UtcNow}", accessCondition: AccessCondition.GenerateIfMatchCondition(orginalETag));

            try
            {
                blob.UploadText($"New Content 2 - {DateTime.UtcNow}", accessCondition: AccessCondition.GenerateIfMatchCondition(orginalETag));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            await blob.FetchAttributesAsync();

            Console.WriteLine($"{orginalETag} != {blob.Properties.ETag}");
        }
示例#2
0
        public async Task Save(IHaveIdentifier document)
        {
            var json      = JsonConvert.SerializeObject(document);
            var container = await EnsureContainer(document.Identifier);

            var blob =
                container.GetBlockBlobReference(document.Identifier.Split('/')[1]);

            await using var stream       = new MemoryStream();
            await using var streamWriter = new StreamWriter(stream);
            streamWriter.Write(json);
            await streamWriter.FlushAsync();

            stream.Position = 0;
            if (await blob.ExistsAsync())
            {
                var etag = _blobLookup[document.Identifier].Properties.ETag;
                await blob.UploadFromStreamAsync(stream,
                                                 AccessCondition.GenerateIfMatchCondition(etag), null,
                                                 null);
            }
            else
            {
                await blob.UploadFromStreamAsync(stream);
            }
        }
示例#3
0
        /// <summary>
        /// Constructs an access condition such that an operation will be performed only if the resource's current ETag value
        /// matches the specified resource's ETag value.
        /// </summary>
        /// <param name="resource">A resource with an ETag value to check against the resource's ETag.</param>
        /// <returns>An <see cref="Microsoft.Azure.Search.Models.AccessCondition" /> object that represents the If-Match condition.</returns>
        public static AccessCondition IfNotChanged(IResourceWithETag resource)
        {
            Throw.IfArgumentNull(resource, nameof(resource));
            Throw.IfArgumentNullOrEmpty(resource.ETag, $"{nameof(resource)}.{nameof(resource.ETag)}");

            return(AccessCondition.GenerateIfMatchCondition(resource.ETag));
        }
示例#4
0
        /// <summary>
        /// Stores a new entity in the configured blob container
        /// </summary>
        /// <param name="changes"></param>
        /// <returns></returns>
        public async Task Write(IEnumerable <KeyValuePair <string, object> > changes)
        {
            if (changes == null)
            {
                throw new ArgumentNullException(nameof(changes));
            }

            var blobContainer = await this.Container.Value;
            await Task.WhenAll(
                changes.Select(async(keyValuePair) =>
            {
                var newValue  = keyValuePair.Value;
                var storeItem = newValue as IStoreItem;
                // "*" eTag in IStoreItem converts to null condition for AccessCondition
                var calculatedETag = storeItem?.eTag == "*" ? null : storeItem?.eTag;

                var blobName      = GetBlobName(keyValuePair.Key);
                var blobReference = blobContainer.GetBlockBlobReference(blobName);
                using (var blobStream = await blobReference.OpenWriteAsync(
                           AccessCondition.GenerateIfMatchCondition(calculatedETag),
                           new BlobRequestOptions(),
                           new OperationContext()))
                    using (var streamWriter = new StreamWriter(blobStream))
                        using (var jsonWriter = new JsonTextWriter(streamWriter))
                        {
                            JsonSerializer.Serialize(jsonWriter, newValue);
                        }
            }));
        }
        private static void OptimsticConurrency(CloudBlockBlob blockBlob)
        {
            string helloText   = "Hello World";
            string orignalETag = blockBlob.Properties.ETag;

            //explictly changing the ETag
            blockBlob.UploadText(helloText + "v1");

            try
            {
                blockBlob.UploadText(helloText,
                                     accessCondition: AccessCondition.GenerateIfMatchCondition(orignalETag));
            }
            catch (StorageException ex)
            {
                if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
                {
                    Console.WriteLine("Blob's orignal etag no longer matches");
                }
                else
                {
                    throw;
                }
            }
        }
        public async Task SaveMappingAsync(ActionMapping m)
        {
            ActionMappingBlobResults existingResults = await GetActionsAndEtagAsync();

            List <ActionMapping> existingMappings = existingResults.ActionMappings;

            // look for the new mapping
            ActionMapping found = existingMappings.FirstOrDefault(a => a.RuleOutput.ToLower() == m.RuleOutput.ToLower());

            if (found == null)
            {
                // add the new mapping
                existingMappings.Add(m);
            }
            else
            {
                // update the ActionId for the found mapping
                found.ActionId = m.ActionId;
            }

            // now save back to the blob
            string newJsonData = JsonConvert.SerializeObject(existingMappings);

            byte[] newBytes = Encoding.UTF8.GetBytes(newJsonData);

            await _blobStorageManager.UploadFromByteArrayAsync(
                _blobName,
                newBytes,
                0,
                newBytes.Length,
                AccessCondition.GenerateIfMatchCondition(existingResults.ETag),
                null,
                null);
        }
        public async Task ShouldNotModifyABlobIfChange()
        {
            await ModifyABlockOnBlob();

            var cloudBlobContainer = _cloudClient.GetContainerReference(ContainerName);
            var blob = cloudBlobContainer.GetBlockBlobReference("text.txt");

            var isExists = await blob.ExistsAsync();

            isExists.Should().BeTrue();

            var listBlockItems = await blob.DownloadBlockListAsync();

            var blockIds = listBlockItems.Select(block => block.Name);

            var id        = 3;
            var blockId   = Convert.ToBase64String(Encoding.UTF8.GetBytes(id.ToString("d6")));
            var blockData = new MemoryStream(
                Encoding.UTF8.GetBytes($"modification du block avec l'identifiant égale à {id}"));

            blockIds.Contains(blockId).Should().BeTrue();

            var accessCondition = AccessCondition.GenerateIfMatchCondition(_eTag);

            await blob.PutBlockAsync(blockId, blockData, null, accessCondition, null, null);

            await Assert.ThrowsAsync <StorageException>(
                () => blob.PutBlockListAsync(blockIds, accessCondition, null, null));
        }
示例#8
0
        public async Task SaveAsync(Stream stream, long offset, CancellationToken token)
        {
            Require.OffsetMultiple("offset", offset, PageSize);

            if (stream.Length > CommitSizeBytes)
            {
                var message = "Stream can't be longer than " + CommitSizeBytes;
                throw new ArgumentException(message);
            }

            try
            {
                await _blob.WritePagesAsync(stream, offset, null,
                                            AccessCondition.GenerateIfMatchCondition(_etag), null, null, token)
                .ConfigureAwait(false);

                _etag = _blob.Properties.ETag;
            }
            catch (StorageException ex)
            {
                if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
                {
                    throw new NonTransientAppendFailure("ETAG failed, must reboot", ex);
                }
                throw;
            }
        }
 /// <summary>
 /// Uploads the configuration to the cloud
 /// </summary>
 /// <returns></returns>
 internal void UploadConfiguration()
 {
     try
     {
         using (MemoryStream stream = new MemoryStream())
         {
             BinaryFormatter formatter = new BinaryFormatter();
             formatter.Serialize(stream, this.config);
             stream.Position = 0;
             AccessCondition access = (reconfigurationETag != null) ? AccessCondition.GenerateIfMatchCondition(reconfigurationETag) : null;
             configurationBlob.UploadFromStream(stream, access);
         }
     }
     catch (StorageException ex)
     {
         reconfigurationETag = null;
         if (StorageExceptionCode.PreconditionFailed(ex))
         {
             // ETag condition was not met; there must be a concurrent reconfiguration and we lost
             // so do nothing
             Console.WriteLine("Reconfiguration aborted due to concurrent activity");
         }
         else
         {
             throw ex;
         }
     }
 }
        public virtual void StoreElement([NotNull] XElement element, string friendlyName)
        {
            ExceptionDispatchInfo lastException = null;

            // To perform a transactional update of keyring.xml, we first need to get
            // the original contents of the blob.
            var blobRef = GetKeyRingBlockBlobReference();

            for (int i = 0; i < MAX_NUM_UPDATE_ATTEMPTS; i++)
            {
                AccessCondition updateAccessCondition;
                XDocument       document = ReadDocumentFromStorage(blobRef);

                // Inject the new element into the existing <keyRing> root.
                if (document != null)
                {
                    document.Root.Add(element);

                    // only update if the contents haven't changed (prevents overwrite)
                    updateAccessCondition = AccessCondition.GenerateIfMatchCondition(blobRef.Properties.ETag);
                }
                else
                {
                    document = new XDocument(
                        new XElement(KeyRingElementName,
                                     new XAttribute("version", 1),
                                     element));

                    // only update if the file doesn't exist (prevents overwrite)
                    updateAccessCondition = AccessCondition.GenerateIfNoneMatchCondition("*");
                }

                // Write the updated document back out
                MemoryStream memoryStream = new MemoryStream();
                document.Save(memoryStream);
                try
                {
                    blobRef.UploadFromByteArray(memoryStream.GetBuffer(), 0, checked ((int)memoryStream.Length), accessCondition: updateAccessCondition);
                    return; // success!
                }
                catch (StorageException ex)
                {
                    switch ((HttpStatusCode)ex.RequestInformation.HttpStatusCode)
                    {
                    // If we couldn't update the blob due to a conflict on the server, try again.
                    case HttpStatusCode.Conflict:
                    case HttpStatusCode.PreconditionFailed:
                        lastException = ExceptionDispatchInfo.Capture(ex);
                        continue;

                    default:
                        throw;
                    }
                }
            }

            // If we got this far, too many conflicts occurred while trying to update the blob.
            // Just bail.
            lastException.Throw();
        }
示例#11
0
        public async Task Test_27_ModifyBlockBlobIfNotModified()
        {
            await BlockBlobUpload();

            //await ModifyBlockBlobWithoutChecks();

            var container = _Client.GetContainerReference("test-blockblob-blockreference");
            await container.CreateIfNotExistsAsync();

            var  blob       = container.GetBlockBlobReference("myblockblob");
            bool blobExists = await blob.ExistsAsync();

            blobExists.Should().BeTrue();

            var blockItems = await blob.DownloadBlockListAsync();

            var blockIDs = from blockInfo in blockItems
                           select blockInfo.Name;

            var myNewBlock = string.Empty.PadRight(50, '+') + Environment.NewLine;
            var nBlockID   = 3;
            var blockID    = Convert.ToBase64String(Encoding.UTF8.GetBytes(nBlockID.ToString("d6")));
            var blockData  = new MemoryStream(Encoding.UTF8.GetBytes(myNewBlock));

            blockIDs.Should().Contain(s => s == blockID);

            var ac = AccessCondition.GenerateIfMatchCondition(_etag);

            await blob.PutBlockAsync(blockID, blockData, null, ac, null, null);

            await blob.PutBlockListAsync(blockIDs, ac, null, null);
        }
        public async Task WriteStateAsync(string grainType, GrainReference grainId, GrainState grainState)
        {
            try
            {
                var blobName             = GetBlobName(grainType, grainId);
                var grainStateDictionary = grainState.AsDictionary();
                var storedData           = JsonConvert.SerializeObject(grainStateDictionary, settings);
                Log.Verbose("Serialized grain state is: {0}.", storedData);

                var blob = container.GetBlockBlobReference(blobName);
                blob.Properties.ContentType = "application/json";
                await
                blob.UploadTextAsync(
                    storedData,
                    Encoding.UTF8,
                    AccessCondition.GenerateIfMatchCondition(grainState.Etag),
                    null,
                    null);

                grainState.Etag = blob.Properties.ETag;
            }
            catch (Exception ex)
            {
                Log.Error(0, ex.ToString());
            }
        }
示例#13
0
        private static async Task SaveBlobContentAsync(CloudBlockBlob blob, string content)
        {
            if (blob.Properties.ContentEncoding == null)
            {
                Interlocked.Increment(ref writtenUncompressedBlobs);
                await blob.UploadTextAsync(
                    content,
                    Encoding.UTF8,
                    AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag),
                    options : null,
                    operationContext : null);

                return;
            }
            else if ("gzip".Equals(blob.Properties.ContentEncoding, StringComparison.InvariantCultureIgnoreCase))
            {
                Interlocked.Increment(ref writtenGzipBlobs);
                using (var stream = await blob.OpenWriteAsync(AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag), options: null, operationContext: null))
                    using (var gzipStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true))
                        using (var streamWriter = new StreamWriter(gzipStream, Encoding.UTF8, bufferSize: 81920, leaveOpen: true))
                        {
                            await streamWriter.WriteAsync(content);

                            await streamWriter.FlushAsync();

                            return;
                        }
            }

            throw new UnsupportedContentEncodingException(blob.Properties.ContentEncoding);
        }
        public async Task <Tuple <string, string> > MutateAsync(string path, Func <string, Task <Tuple <string, string> > > mutator)
        {
            var blob = _container.GetBlockBlobReference(path);

            if (!blob.Exists())
            {
                return(null);
            }

            // See for concurrency: http://azure.microsoft.com/blog/2014/09/08/managing-concurrency-in-microsoft-azure-storage-2/
Retry:
            // Apply etag and optimistic concurrency
            string contents = blob.DownloadText();
            string etag = blob.Properties.ETag;

            var tuple = await mutator(contents);

            string content = tuple.Item1;

            try
            {
                blob.UploadText(content, accessCondition: AccessCondition.GenerateIfMatchCondition(etag));
            }
            catch (StorageException ex)
            {
                if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
                {
                    // Etag mismatch. Retry!
                    goto Retry;
                }
                throw;
            }

            return(tuple);
        }
示例#15
0
        public async Task SetAsync(IDeviceIdentity identity, ISessionState sessionState)
        {
            var state = sessionState as BlobSessionState;

            if (state == null)
            {
                throw new ArgumentException("Cannot set Session State object that hasn't been acquired from provider.", "sessionState");
            }

            if (state.IsTransient)
            {
                return;
            }

            CloudBlockBlob blob = this.container.GetBlockBlobReference(identity.Id);

            using (var memoryStream = new MemoryStream())
                using (var streamWriter = new StreamWriter(memoryStream))
                {
                    JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
                    serializer.Serialize(streamWriter, state);
                    streamWriter.Flush();

                    memoryStream.Position = 0;
                    AccessCondition accessCondition = state.ETag == null
                    ? AccessCondition.GenerateIfNoneMatchCondition("*")     // create
                    : AccessCondition.GenerateIfMatchCondition(state.ETag); // update

                    await blob.UploadFromStreamAsync(memoryStream, accessCondition, null, null);

                    state.ETag = blob.Properties.ETag;
                }
        }
示例#16
0
        private void AssertAccessCondition(Uri resourceUri, AccessCondition accessCondition)
        {
            Content.TryGetValue(resourceUri, out var existingContent);
            if (IsAccessCondition(AccessCondition.GenerateEmptyCondition(), accessCondition))
            {
                return;
            }

            if (IsAccessCondition(AccessCondition.GenerateIfNotExistsCondition(), accessCondition))
            {
                Assert.Null(existingContent);
                return;
            }

            if (IsAccessCondition(AccessCondition.GenerateIfExistsCondition(), accessCondition))
            {
                Assert.NotNull(existingContent);
                return;
            }

            if (existingContent is StringStorageContentWithETag eTagContent)
            {
                var eTag = eTagContent.ETag;
                if (IsAccessCondition(AccessCondition.GenerateIfMatchCondition(eTag), accessCondition))
                {
                    return;
                }
            }

            throw new InvalidOperationException("Could not validate access condition!");
        }
示例#17
0
        /// <summary>
        /// Uploads the configuration to the cloud
        /// </summary>
        /// <returns></returns>
        internal void UploadConfiguration(string leaseId)
        {
            try
            {
                ICloudBlob blob = GetConfigurationContainer().GetBlockBlobReference(ConstPool.CURRENT_CONFIGURATION_BLOB_NAME);
                blob.FetchAttributes();

                using (MemoryStream stream = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, this);
                    stream.Position = 0;
                    AccessCondition access = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag);
                    if (leaseId != "")
                    {
                        access.LeaseId = leaseId;
                    }
                    blob.UploadFromStream(stream, access);
                }
            }
            catch (StorageException ex)
            {
                Console.WriteLine(ex.ToString());
                throw ex;
            }
        }
        public async Task DeleteLocationsInBatchAsync(IEnumerable <LocationModel> locations)
        {
            if (locations != null)
            {
                LocationJerkBlobResults existingBlobResults = await GetAllLocationJerkInfo();

                List <LocationJerkModel> existingLocationJerks = existingBlobResults.LocationJerkInfo;
                LocationJerkModel        found = null;

                foreach (var location in locations)
                {
                    found = (existingLocationJerks as IEnumerable <LocationJerkModel>).FirstOrDefault(j => j.Latitude == location.Latitude && j.Longitude == location.Longitude);

                    if (found != null)
                    {
                        existingLocationJerks.Remove(found);
                    }

                    found = null;
                }

                string newJsonData = JsonConvert.SerializeObject(existingLocationJerks);
                byte[] newBytes    = Encoding.UTF8.GetBytes(newJsonData);

                await _blobStorageManager.UploadFromByteArrayAsync(
                    _blobName,
                    newBytes,
                    0,
                    newBytes.Length,
                    AccessCondition.GenerateIfMatchCondition(existingBlobResults.ETag),
                    null,
                    null);
            }
        }
示例#19
0
        /// <summary> Clear / Delete state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            var blobName = GetBlobName(grainType, grainId);

            try
            {
                if (this.Log.IsVerbose3)
                {
                    this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_ClearingData, "Clearing: GrainType={0} Grainid={1} ETag={2} BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                }

                var blob = container.GetBlockBlobReference(blobName);
                await blob.DeleteIfExistsAsync(
                    DeleteSnapshotsOption.None,
                    AccessCondition.GenerateIfMatchCondition(grainState.ETag),
                    null,
                    null).ConfigureAwait(false);

                grainState.ETag = blob.Properties.ETag;

                if (this.Log.IsVerbose3)
                {
                    this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Cleared, "Cleared: GrainType={0} Grainid={1} ETag={2} BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                }
            }
            catch (Exception ex)
            {
                Log.Error((int)AzureProviderErrorCode.AzureBlobProvider_ClearError,
                          string.Format("Error clearing: GrainType={0} Grainid={1} ETag={2} BlobName={3} in Container={4} Exception={5}", grainType, grainId, grainState.ETag, blobName, container.Name, ex.Message),
                          ex);
            }
        }
示例#20
0
        public override void ExecuteCommand()
        {
            // Start by fetching the latest log
            var joblogs = JobLog.LoadJobLogs(StorageAccount);

            // Iterate over each log
            foreach (var joblog in joblogs)
            {
                Log.Info("Cleaning {0}", joblog.JobName);
                foreach (var blob in joblog.Blobs.Where(b => (DateTime.UtcNow - b.ArchiveTimestamp) > MaxAge.Value))
                {
                    try
                    {
                        if (!WhatIf)
                        {
                            // Only delete if it matches.
                            blob.Blob.DeleteIfExists(
                                accessCondition: AccessCondition.GenerateIfMatchCondition(blob.Blob.Properties.ETag));
                        }
                        Log.Info("Deleted {0}", blob.Blob.Name);
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorException("Failed to delete " + blob.Blob.Name, ex);
                    }
                }
            }
        }
示例#21
0
        private async Task BackupFileToBlobAsync(Uri sasWrite)
        {
            // replace previous existing blob

            var accessCondition = AccessCondition.GenerateIfMatchCondition("*");

            await WriteBlobAndSnapshotAsync(sasWrite, accessCondition);
        }
示例#22
0
        protected override Task <string> DoStartCopyAsync()
        {
            AccessCondition destAccessCondition = Utils.GenerateConditionWithCustomerCondition(this.TransferJob.Destination.AccessCondition);

            if (null != this.SourceUri)
            {
                return(this.destBlob.StartCopyAsync(
                           this.SourceUri,
                           null,
                           destAccessCondition,
                           Utils.GenerateBlobRequestOptions(this.TransferJob.Destination.BlobRequestOptions),
                           Utils.GenerateOperationContext(this.TransferContext),
                           this.CancellationToken));
            }
            else if (null != this.SourceBlob)
            {
                AccessCondition sourceAccessCondition =
                    AccessCondition.GenerateIfMatchCondition(this.SourceBlob.Properties.ETag);

                return(this.destBlob.StartCopyAsync(
                           this.SourceBlob.GenerateUriWithCredentials(),
                           sourceAccessCondition,
                           destAccessCondition,
                           Utils.GenerateBlobRequestOptions(this.TransferJob.Destination.BlobRequestOptions),
                           Utils.GenerateOperationContext(this.TransferContext),
                           this.CancellationToken));
            }
            else
            {
                if (BlobType.BlockBlob == this.destBlob.BlobType)
                {
                    return((this.destBlob as CloudBlockBlob).StartCopyAsync(
                               this.SourceFile.GenerateCopySourceFile(),
                               null,
                               destAccessCondition,
                               Utils.GenerateBlobRequestOptions(this.TransferJob.Destination.BlobRequestOptions),
                               Utils.GenerateOperationContext(this.TransferContext),
                               this.CancellationToken));
                }
                else if (BlobType.PageBlob == this.destBlob.BlobType)
                {
                    throw new InvalidOperationException(Resources.AsyncCopyFromFileToPageBlobNotSupportException);
                }
                else if (BlobType.AppendBlob == this.destBlob.BlobType)
                {
                    throw new InvalidOperationException(Resources.AsyncCopyFromFileToAppendBlobNotSupportException);
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  CultureInfo.CurrentCulture,
                                  Resources.NotSupportedBlobType,
                                  this.destBlob.BlobType));
                }
            }
        }
示例#23
0
        public void FromContentReturnsMatchIfETag()
        {
            var eTag    = "etag";
            var content = new StringStorageContentWithETag("content", eTag);

            PackageMonitoringStatusTestUtility.AssertAccessCondition(
                AccessCondition.GenerateIfMatchCondition(eTag),
                PackageMonitoringStatusAccessConditionHelper.FromContent(content));
        }
示例#24
0
        /// <summary>
        /// Sets the metadata that is currently set
        /// </summary>
        /// <param name="accessCondition"></param>
        public void SetMetadata()
        {
            Logger.Verbose("Setting metadata for blob [{0}], etag [{1}]", _pageBlob.Uri, _pageBlob.Properties.ETag);

            try
            { _pageBlob.SetMetadata(AccessCondition.GenerateIfMatchCondition(_pageBlob.Properties.ETag)); }
            catch (AzureStorage.StorageException ex)
            { throw HandleAndRemapCommonExceptions(ex); }
        }
        public void GenerateIfMatchConditionReturnsIfMatchAccessCondition()
        {
            string eTag = "IHazETag";

            AccessCondition result = AccessCondition.GenerateIfMatchCondition(eTag);

            Assert.Equal(eTag, result.IfMatch);
            Assert.Null(result.IfNoneMatch);
        }
        public void Update(long position)
        {
            Require.ZeroOrGreater("position", position);

            Throw.OnEtagMismatchDuringAppend(() => {
                _blob.Metadata[CloudSetup.CheckpointMetadataName] = Convert.ToString(position);
                _blob.SetMetadata(AccessCondition.GenerateIfMatchCondition(_etag));
                _etag = _blob.Properties.ETag;
            });
        }
示例#27
0
        /// <summary>
        /// Stores a new entity in the configured blob container.
        /// </summary>
        /// <param name="changes">The changes to write to storage.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        public async Task WriteAsync(IDictionary <string, object> changes, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (changes == null)
            {
                throw new ArgumentNullException(nameof(changes));
            }

            var blobClient    = _storageAccount.CreateCloudBlobClient();
            var blobContainer = blobClient.GetContainerReference(_containerName);

            // this should only happen once - assuming this is a singleton
            if (Interlocked.CompareExchange(ref _checkforContainerExistance, 0, 1) == 1)
            {
                await blobContainer.CreateIfNotExistsAsync(cancellationToken).ConfigureAwait(false);
            }

            var blobRequestOptions = new BlobRequestOptions();
            var operationContext   = new OperationContext();

            foreach (var keyValuePair in changes)
            {
                var newValue  = keyValuePair.Value;
                var storeItem = newValue as IStoreItem;

                // "*" eTag in IStoreItem converts to null condition for AccessCondition
                var accessCondition = storeItem?.ETag != "*"
                    ? AccessCondition.GenerateIfMatchCondition(storeItem?.ETag)
                    : AccessCondition.GenerateEmptyCondition();

                var blobName      = GetBlobName(keyValuePair.Key);
                var blobReference = blobContainer.GetBlockBlobReference(blobName);

                try
                {
                    using (var memoryStream = new MultiBufferMemoryStream(blobReference.ServiceClient.BufferManager))
                        using (var streamWriter = new StreamWriter(memoryStream))
                        {
                            _jsonSerializer.Serialize(streamWriter, newValue);

                            await streamWriter.FlushAsync().ConfigureAwait(false);

                            memoryStream.Seek(0, SeekOrigin.Begin);
                            await blobReference.UploadFromStreamAsync(memoryStream, accessCondition, blobRequestOptions, operationContext, cancellationToken).ConfigureAwait(false);
                        }
                }
                catch (StorageException ex)
                    when(ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.BadRequest &&
                         ex.RequestInformation.ErrorCode == BlobErrorCodeStrings.InvalidBlockList)
                    {
                        throw new InvalidOperationException(
                                  $"An error ocurred while trying to write an object. The underlying '{BlobErrorCodeStrings.InvalidBlockList}' error is commonly caused due to concurrently uploading an object larger than 128MB in size.",
                                  ex);
                    }
            }
        }
        public virtual async Task <StorageResponseHolder> Update(string key, byte[] body,
                                                                 string contentType       = null, string contentEncoding = null,
                                                                 string version           = null, string oldVersion      = null,
                                                                 string directory         = null, IEnumerable <KeyValuePair <string, string> > metadata = null,
                                                                 CancellationToken?cancel = null, bool createSnapshot = false, bool useEncryption = true)
        {
            var request = new StorageRequestHolder(key, cancel, directory);

            return(await CallCloudBlockBlob(request,
                                            async (rq, rs, exists) =>
            {
                if (!exists)
                {
                    rq.CopyTo(rs);
                    rs.StatusCode = 404;
                    rs.IsSuccess = false;
                    return;
                }

                if (oldVersion != null && oldVersion != rq.VersionId)
                {
                    MetadataGet(rq.Blob, rs);
                    rs.StatusCode = 409;
                    rs.IsSuccess = false;
                    return;
                }

                if (createSnapshot)
                {
                    await rq.Blob.CreateSnapshotAsync(rq.Fields,
                                                      AccessCondition.GenerateIfMatchCondition(rq.ETag), mOptions, mContext, rq.CancelSet);
                    MetadataGet(rq.Blob, rq);
                }

                rq.ContentType = contentType ?? rs.ContentType;
                rq.ContentEncoding = contentEncoding ?? rs.ContentEncoding;
                rq.VersionId = version;
                MetadataSet(rq.Blob, rq);

                // If encryption provided encrypt the body
                var uploadBody = body;
                if (useEncryption && mEncryption != null)
                {
                    uploadBody = mEncryption.Encrypt(body);
                }

                await rq.Blob.UploadFromByteArrayAsync(uploadBody, 0, uploadBody.Length,
                                                       AccessCondition.GenerateIfMatchCondition(rq.ETag), mOptions, mContext, rq.CancelSet);

                MetadataGet(rq.Blob, rs);
                rs.Data = body;
                rs.IsSuccess = true;
                rs.StatusCode = 200;
            }));
        }
示例#29
0
        public async Task FetchAsync(string location, Stream targetStream, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNullOrEmpty(location, nameof(location));
            EnsureArg.IsNotNull(targetStream, nameof(targetStream));

            string[] blobLocation = location.Split(':', StringSplitOptions.RemoveEmptyEntries);
            string   blobName     = blobLocation[0];
            string   eTag         = blobLocation.Length > 1 ? blobLocation[1] : null;

            eTag = AddDoubleQuotesIfMissing(eTag);

            CloudBlobClient blobClient = await ConnectAsync(cancellationToken);

            CloudBlobContainer container = blobClient.GetContainerReference(AnonymizationContainer);

            if (!await container.ExistsAsync(cancellationToken))
            {
                throw new FileNotFoundException(message: Resources.AnonymizationContainerNotFound);
            }

            CloudBlob blob = container.GetBlobReference(blobName);

            if (await blob.ExistsAsync(cancellationToken))
            {
                if (CheckConfigurationIsTooLarge(blob))
                {
                    throw new AnonymizationConfigurationFetchException(Resources.AnonymizationConfigurationTooLarge);
                }

                if (string.IsNullOrEmpty(eTag))
                {
                    await blob.DownloadToStreamAsync(targetStream, cancellationToken);
                }
                else
                {
                    AccessCondition condition          = AccessCondition.GenerateIfMatchCondition(eTag);
                    var             blobRequestOptions = new BlobRequestOptions();
                    var             operationContext   = new OperationContext();
                    try
                    {
                        await blob.DownloadToStreamAsync(targetStream, accessCondition : condition, blobRequestOptions, operationContext, cancellationToken);
                    }
                    catch (StorageException ex)
                    {
                        throw new AnonymizationConfigurationFetchException(ex.Message, ex);
                    }
                }
            }
            else
            {
                throw new FileNotFoundException(message: string.Format(CultureInfo.InvariantCulture, Resources.AnonymizationConfigurationNotFound, blobName));
            }
        }
示例#30
0
 /// <summary>
 /// Writes to the page blob
 /// </summary>
 /// <param name="pageData">must be page size</param>
 /// <param name="startOffset">must be page aligned</param>
 /// <param name="accessCondition"></param>
 public void Write(Stream pageData, int startOffset)
 {
     try
     {
         Logger.Verbose("Writing [{0}] bytes for blob [{1}], etag [{2}]", pageData.Length, _pageBlob.Uri, _pageBlob.Properties.ETag);
         _pageBlob.WritePages(pageData, startOffset, null,
                              AccessCondition.GenerateIfMatchCondition(_pageBlob.Properties.ETag));
         Logger.Verbose("Wrote [{0}] bytes for blob [{1}], etag [{2}]", pageData.Length, _pageBlob.Uri, _pageBlob.Properties.ETag);
     }
     catch (AzureStorage.StorageException ex)
     { throw HandleAndRemapCommonExceptions(ex); }
 }