Ejemplo n.º 1
0
        public virtual async Task <Stream> OpenWriteAsync(string blobUrl)
        {
            var filePath = GetFilePathFromUrl(blobUrl);

            if (filePath == null)
            {
                throw new ArgumentException(@"Cannot get file path from URL", nameof(blobUrl));
            }

            var container = _blobServiceClient.GetBlobContainerClient(GetContainerNameFromUrl(blobUrl));
            await container.CreateIfNotExistsAsync(PublicAccessType.Blob);

            var blob = container.GetBlockBlobClient(filePath);

            var options = new BlockBlobOpenWriteOptions
            {
                HttpHeaders = new BlobHttpHeaders
                {
                    ContentType = MimeTypeResolver.ResolveContentType(Path.GetFileName(filePath)),
                    // Leverage Browser Caching - 7days
                    // Setting Cache-Control on Azure Blobs can help reduce bandwidth and improve the performance by preventing consumers from having to continuously download resources.
                    // More Info https://developers.google.com/speed/docs/insights/LeverageBrowserCaching
                    CacheControl = BlobCacheControlPropertyValue
                }
            };

            return(await blob.OpenWriteAsync(true, options));
        }
Ejemplo n.º 2
0
        public static async Task <NotifyingBlobStream> BindStreamAsync(BlobWithContainer <BlobBaseClient> blob,
                                                                       ValueBindingContext context, IBlobWrittenWatcher blobWrittenWatcher)
        {
            var blockBlob = blob.BlobClient as BlockBlobClient;

            if (blockBlob == null)
            {
                throw new InvalidOperationException("Cannot bind to page or append blobs using 'out string', 'TextWriter', or writable 'Stream' parameters.");
            }
            var            functionID = context.FunctionInstanceId;
            BlobProperties properties = await blockBlob.FetchPropertiesOrNullIfNotExistAsync().ConfigureAwait(false);

            Dictionary <string, string> metadata = new Dictionary <string, string>();

            if (properties != null && properties.Metadata != null)
            {
                metadata = new Dictionary <string, string>(properties.Metadata);
            }

            BlobCausalityManager.SetWriter(metadata, functionID);
            BlockBlobOpenWriteOptions options = new BlockBlobOpenWriteOptions()
            {
                Metadata = metadata,
            };
            Stream rawStream = await blockBlob.OpenWriteAsync(true, options).ConfigureAwait(false);

            IBlobCommitedAction committedAction = new BlobCommittedAction(blob, blobWrittenWatcher);

            return(await Task.FromResult(new NotifyingBlobStream(rawStream, committedAction)).ConfigureAwait(false));
        }
Ejemplo n.º 3
0
        public override async Task <string> EgressAsync(
            AzureBlobEgressProviderOptions options,
            Func <Stream, CancellationToken, Task> action,
            EgressArtifactSettings artifactSettings,
            CancellationToken token)
        {
            try
            {
                var containerClient = await GetBlobContainerClientAsync(options, token);

                BlockBlobClient blobClient = containerClient.GetBlockBlobClient(GetBlobName(options, artifactSettings));

                // Write blob content

                var bloboptions = new BlockBlobOpenWriteOptions
                {
                    BufferSize = BlobStorageBufferSize,
                };
                using (Stream blobStream = await blobClient.OpenWriteAsync(overwrite: true, options: bloboptions, cancellationToken: token))
                    using (AutoFlushStream flushStream = new AutoFlushStream(blobStream, BlobStorageBufferSize))
                    {
                        //Azure's stream from OpenWriteAsync will do the following
                        //1. Write the data to a local buffer
                        //2. Once that buffer is full, stage the data remotely (this data is not considered valid yet)
                        //3. After 4Gi of data has been staged, the data will be commited. This can be forced earlier by flushing
                        //the stream.
                        // Since we want the data to be readily available, we automatically flush (and therefore commit) every time we fill up the buffer.
                        Logger?.EgressProviderInvokeStreamAction(EgressProviderTypes.AzureBlobStorage);
                        await action(flushStream, token);

                        await flushStream.FlushAsync(token);
                    }

                // Write blob headers
                await blobClient.SetHttpHeadersAsync(CreateHttpHeaders(artifactSettings), cancellationToken : token);

                // Write blob metadata
                await blobClient.SetMetadataAsync(artifactSettings.Metadata, cancellationToken : token);

                string blobUriString = GetBlobUri(blobClient);
                Logger?.EgressProviderSavedStream(EgressProviderTypes.AzureBlobStorage, blobUriString);
                return(blobUriString);
            }
            catch (AggregateException ex) when(ex.InnerException is RequestFailedException innerException)
            {
                throw CreateException(innerException);
            }
            catch (RequestFailedException ex)
            {
                throw CreateException(ex);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates a crypto transform stream to write blob contents to.
        /// </summary>
        /// <param name="blobClient">
        /// BlobClient to open write with.
        /// </param>
        /// <param name="overwrite">
        /// Overwrite parameter to open write.
        /// </param>
        /// <param name="options">
        /// Options parameter to open write.
        /// </param>
        /// <param name="async">
        /// Whether to perform this operation asynchronously.
        /// </param>
        /// <param name="cancellationToken">
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// Content transform write stream and metadata.
        /// </returns>
        public async Task <Stream> ClientSideEncryptionOpenWriteInternal(
            BlockBlobClient blobClient,
            bool overwrite,
            BlockBlobOpenWriteOptions options,
            bool async,
            CancellationToken cancellationToken)
        {
            Stream encryptionWriteStream = await _encryptor.EncryptedOpenWriteInternal(
                async (encryptiondata, funcAsync, funcCancellationToken) =>
            {
                options.Metadata = TransformMetadata(options.Metadata, encryptiondata);

                return(await blobClient.OpenWriteInternal(
                           overwrite,
                           options,
                           funcAsync,
                           funcCancellationToken).ConfigureAwait(false));
            },
                async,
                cancellationToken).ConfigureAwait(false);

            return(encryptionWriteStream);
        }