예제 #1
0
            public async Task UsesProvidedMatchETag()
            {
                // Arrange
                AccessCondition  srcAccessCondition  = null;
                AccessCondition  destAccessCondition = null;
                ISimpleCloudBlob srcBlob             = null;

                _destBlobMock
                .Setup(x => x.StartCopyAsync(It.IsAny <ISimpleCloudBlob>(), It.IsAny <AccessCondition>(), It.IsAny <AccessCondition>()))
                .Returns(Task.FromResult(0))
                .Callback <ISimpleCloudBlob, AccessCondition, AccessCondition>((b, s, d) =>
                {
                    srcBlob             = b;
                    srcAccessCondition  = s;
                    destAccessCondition = d;
                    SetDestCopyStatus(CopyStatus.Success);
                });

                // Act
                await _target.CopyFileAsync(
                    _srcFolderName,
                    _srcFileName,
                    _destFolderName,
                    _destFileName,
                    AccessConditionWrapper.GenerateIfMatchCondition("etag!"));

                // Assert
                _destBlobMock.Verify(
                    x => x.StartCopyAsync(It.IsAny <ISimpleCloudBlob>(), It.IsAny <AccessCondition>(), It.IsAny <AccessCondition>()),
                    Times.Once);
                Assert.Equal("etag!", destAccessCondition.IfMatchETag);
                Assert.Null(destAccessCondition.IfNoneMatchETag);
            }
        public async Task <RevalidationState> MaybeUpdateStateAsync(Func <RevalidationState, bool> updateAction)
        {
            var internalState = await GetInternalStateAsync();

            var fileReference = internalState.FileReference;
            var state         = internalState.State;

            // Only update the state if the update action returns true.
            var originalState = new RevalidationState
            {
                IsInitialized           = state.IsInitialized,
                IsKillswitchActive      = state.IsKillswitchActive,
                DesiredPackageEventRate = state.DesiredPackageEventRate,
            };

            if (!updateAction(state))
            {
                return(originalState);
            }

            try
            {
                var accessCondition = AccessConditionWrapper.GenerateIfMatchCondition(fileReference.ContentId);

                using (var stream = new MemoryStream())
                    using (var writer = new StreamWriter(stream))
                        using (var jsonWriter = new JsonTextWriter(writer))
                        {
                            _serializer.Serialize(jsonWriter, state);
                            jsonWriter.Flush();
                            stream.Position = 0;

                            await _storage.SaveFileAsync(CoreConstants.Folders.RevalidationFolderName, StateFileName, stream, accessCondition);
                        }

                return(state);
            }
            catch (StorageException e) when(e.IsPreconditionFailedException())
            {
                throw new InvalidOperationException("Failed to update the state blob since the access condition failed", e);
            }
        }
예제 #3
0
        /// <summary>
        /// Asynchronously sets blob metadata.
        /// </summary>
        /// <param name="folderName">The folder (container) name.</param>
        /// <param name="fileName">The blob file name.</param>
        /// <param name="updateMetadataAsync">A function which updates a metadata dictionary and returns <c>true</c>
        /// for changes to be persisted or <c>false</c> for changes to be discarded.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        public async Task SetMetadataAsync(
            string folderName,
            string fileName,
            Func <Lazy <Task <Stream> >, IDictionary <string, string>, Task <bool> > updateMetadataAsync)
        {
            if (folderName == null)
            {
                throw new ArgumentNullException(nameof(folderName));
            }

            if (fileName == null)
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            if (updateMetadataAsync == null)
            {
                throw new ArgumentNullException(nameof(updateMetadataAsync));
            }

            var container = await GetContainerAsync(folderName);

            var blob = container.GetBlobReference(fileName);

            await blob.FetchAttributesAsync();

            var lazyStream = new Lazy <Task <Stream> >(() => GetFileAsync(folderName, fileName));
            var wasUpdated = await updateMetadataAsync(lazyStream, blob.Metadata);

            if (wasUpdated)
            {
                var accessCondition       = AccessConditionWrapper.GenerateIfMatchCondition(blob.ETag);
                var mappedAccessCondition = new AccessCondition
                {
                    IfNoneMatchETag = accessCondition.IfNoneMatchETag,
                    IfMatchETag     = accessCondition.IfMatchETag
                };

                await blob.SetMetadataAsync(mappedAccessCondition);
            }
        }