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)); }
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)); }
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); } }
/// <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); }