/// <inheritdoc/> public async Task <ITenant> CreateWellKnownChildTenantAsync( string parentTenantId, Guid wellKnownChildTenantGuid, string name) { ArgumentNullException.ThrowIfNull(parentTenantId); try { (ITenant parentTenant, CloudBlobContainer cloudBlobContainer) = await this.GetContainerAndTenantForChildTenantsOf(parentTenantId).ConfigureAwait(false); // We need to copy blob storage settings for the Tenancy container definition from the parent to the new child // to support the tenant blob store provider. We would expect this to be overridden by clients that wanted to // establish their own settings. BlobStorageConfiguration tenancyStorageConfiguration = parentTenant.GetBlobStorageConfiguration(ContainerDefinition); IPropertyBag childProperties = this.propertyBagFactory.Create(values => values.AddBlobStorageConfiguration(ContainerDefinition, tenancyStorageConfiguration)); var child = new Tenant( parentTenantId.CreateChildId(wellKnownChildTenantGuid), name, childProperties); // As we create the new blob, we need to ensure there isn't already a tenant with the same Id. We do this by // providing an If-None-Match header passing a "*", which will cause a storage exception with a 409 status // code if a blob with the same Id already exists. CloudBlockBlob blob = GetLiveTenantBlockBlobReference(child.Id, cloudBlobContainer); string text = JsonConvert.SerializeObject(child, this.serializerSettings); await blob.UploadTextAsync( text, null, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null).ConfigureAwait(false); child.ETag = blob.Properties.ETag; return(child); } catch (FormatException fex) { throw new TenantNotFoundException("Unsupported tenant ID", fex); } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) { throw new TenantNotFoundException(); } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) { // This exception is thrown because there's already a tenant with the same Id. This should never happen when // this method has been called from CreateChildTenantAsync as the Guid will have been generated and the // chances of it matching one previously generated are miniscule. However, it could happen when calling this // method directly with a wellKnownChildTenantGuid that's already in use. In this case, the fault is with // the client code - creating tenants with well known Ids is something one would expect to happen under // controlled conditions, so it's only likely that a conflict will occur when either the client code has made // a mistake or someone is actively trying to cause problems. throw new ArgumentException( $"A child tenant of '{parentTenantId}' with a well known Guid of '{wellKnownChildTenantGuid}' already exists.", nameof(wellKnownChildTenantGuid)); } }
private byte[] EstablishAndRetrieveSyncronizedKey() { var keyBlob = GetKeyBlobReference(); if (keyBlob.Exists()) { return(GetBlobContents(keyBlob)); } else { var newKey = CreateNewKey(); try { var base64 = Convert.ToBase64String(newKey); keyBlob.UploadText(base64, encoding: Encoding.UTF8, accessCondition: AccessCondition.GenerateIfNoneMatchCondition("*")); } catch (StorageException) { return(GetBlobContents(keyBlob)); } return(newKey); } }
public async Task OpenReadAsyncReturnsContentWhenIfNoneMatchSucceeds() { // Arrange var folderName = CoreConstants.Folders.ValidationFolderName; var fileName = _prefixA; var expectedContent = "Hello, world."; await _targetA.SaveFileAsync( folderName, fileName, new MemoryStream(Encoding.ASCII.GetBytes(expectedContent)), overwrite : false); var container = _clientA.GetContainerReference(folderName); var file = container.GetBlobReference(fileName); // Act using (var stream = await file.OpenReadAsync(accessCondition: AccessCondition.GenerateIfNoneMatchCondition("WON'T MATCH"))) using (var streamReader = new StreamReader(stream)) { var actualContent = await streamReader.ReadToEndAsync(); // Assert Assert.Equal(expectedContent, actualContent); Assert.Equal(expectedContent.Length, file.Properties.Length); Assert.NotNull(file.ETag); } }
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; } }
private CloudBlockBlob InitializeBlobReference(string blockName) { var blobReference = blobContainer.GetBlockBlobReference(blockName); try { blobReference.DownloadText(); } catch (StorageException downloadException) { if (downloadException.RequestInformation.HttpStatusCode != (int)HttpStatusCode.NotFound) { throw; } try { blobReference.UploadText(SeedValue, AccessCondition.GenerateIfNoneMatchCondition("*")); } catch (StorageException uploadException) { if (uploadException.RequestInformation.HttpStatusCode != (int)HttpStatusCode.Conflict) { throw; } } } return(blobReference); }
private async Task EnsureBlobExistsAsync() { if (await m_blob.ExistsAsync()) { return; } try { await m_blob.UploadFromByteArrayAsync( EmptyArray.Get <byte>(), 0, 0, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null); } catch (StorageException exception) { // 412 from trying to modify a blob that's leased var blobLeased = exception.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed; var blobExists = exception.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict && exception.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.BlobAlreadyExists; if (!blobExists && !blobLeased) { throw; } } }
/// <summary> /// Connect to Azure storage and get a reference to the container object, /// creating it if it does not exist. /// </summary> public void Initialize() { // we want to increase the connection limit used to communicate with via HTTP rest // calls otherwise we will feel significant performance degradation. This can also // be modified via configuration but that would be a very leaky concern to the // application developer. if (Interlocked.Increment(ref _connectionLimitSet) < 2) { Uri uri = new Uri(_primaryContainer.Uri.AbsoluteUri); var sp = ServicePointManager.FindServicePoint(uri); sp.ConnectionLimit = _options.ParallelConnectionLimit; // make sure we have a checkpoint aggregate var blobContainer = _blobClient.GetContainerReference(_rootContainerName); blobContainer.CreateIfNotExists(); var pageBlobReference = blobContainer.GetPageBlobReference(_checkpointBlobName); try { pageBlobReference.Create(512, accessCondition: AccessCondition.GenerateIfNoneMatchCondition("*")); } catch (Microsoft.WindowsAzure.Storage.StorageException ex) { // 409 means it was already there if (!ex.Message.Contains("409")) { throw; } } } if (Interlocked.Increment(ref _initialized) < 2) { _primaryContainer.CreateIfNotExists(); } }
private static async Task WriteBlob(string auditData, string fullPath, CloudBlockBlob blob) { try { var strm = await Task.Factory.FromAsync( (cb, s) => blob.BeginOpenWrite( AccessCondition.GenerateIfNoneMatchCondition("*"), new BlobRequestOptions(), new OperationContext(), cb, s), ar => blob.EndOpenWrite(ar), null); using (var writer = new StreamWriter(strm)) { await writer.WriteAsync(auditData); } } catch (StorageException ex) { if (ex.RequestInformation != null && ex.RequestInformation.HttpStatusCode == 409) { // Blob already existed! throw new InvalidOperationException(String.Format( CultureInfo.CurrentCulture, Strings.CloudAuditingService_DuplicateAuditRecord, fullPath)); } throw; } }
public async Task StartAuditAsync(Guid validationId, string[] validators, DateTimeOffset started, string packageId, string packageVersion, NuGetPackage package) { _logger.LogInformation("Start writing Start PackageValidationAudit for " + $"validation {{{TraceConstant.ValidationId}}} " + $"- package {{{TraceConstant.PackageId}}} " + $"v. {{{TraceConstant.PackageVersion}}}...", validationId, package.Id, packageVersion); var packageValidationAudit = new PackageValidationAudit(); packageValidationAudit.ValidationId = validationId; packageValidationAudit.PackageId = packageId; packageValidationAudit.PackageVersion = packageVersion; packageValidationAudit.Package = package; packageValidationAudit.Started = started; packageValidationAudit.Validators = validators; await StoreAuditAsync( validationId, packageValidationAudit.PackageId, packageValidationAudit.PackageVersion, _ => packageValidationAudit, uploadAccessCondition : AccessCondition.GenerateIfNoneMatchCondition("*")); _logger.LogInformation("Finished writing Start PackageValidationAudit for " + $"validation {{{TraceConstant.ValidationId}}} " + $"- package {{{TraceConstant.PackageId}}} " + $"v. {{{TraceConstant.PackageVersion}}}.", validationId, package.Id, packageVersion); }
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(); }
private async Task WriteBlockAsync(string Id, byte[] bytes, int startIndex, int length, CancellationToken cancellationToken) { using (var ms = new MemoryStream(bytes, startIndex, length)) { // These should be new blocks - use the appropropriate condition await _currentBlob.PutBlockAsync(Id, ms, null, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null, cancellationToken).ConfigureAwait(false); } }
public void GenerateIfMatchConditionReturnsIfNoneMatchAccessCondition() { string eTag = "IHazETag"; AccessCondition result = AccessCondition.GenerateIfNoneMatchCondition(eTag); Assert.Equal(eTag, result.IfNoneMatch); Assert.Null(result.IfMatch); }
public AutoRenewLease(CloudBlockBlob blob) { this.blob = blob; if (blob.Exists() == false) { blob.UploadFromStream(new MemoryStream(new byte[0]), AccessCondition.GenerateIfNoneMatchCondition("*")); } leaseId = blob.TryAcquireLease(); }
public async Task UploadFromStreamAsync(Stream source, bool overwrite) { if (overwrite) { await _blob.UploadFromStreamAsync(source); } else { await UploadFromStreamAsync(source, AccessCondition.GenerateIfNoneMatchCondition("*")); } }
public override void ExecuteCommand() { using (var sqlConnection = new SqlConnection(ConnectionString.ConnectionString)) using (var dbExecutor = new SqlExecutor(sqlConnection)) { sqlConnection.Open(); var externalPackages = dbExecutor.Query <Package>(@" SELECT pr.Id, p.Version, p.ExternalPackageUrl FROM Packages p JOIN PackageRegistrations pr ON pr.[Key] = p.PackageRegistrationKey WHERE p.ExternalPackageUrl IS NOT NULL ORDER BY Id, Version"); foreach (Package pkg in externalPackages) { Console.WriteLine(); HttpClient client = new HttpClient(); var responseTask = client.GetAsync(pkg.ExternalPackageUrl); var response = responseTask.Result; if (!response.IsSuccessStatusCode) { Console.WriteLine("Found broken package: " + response.StatusCode + " " + pkg.ExternalPackageUrl); Console.WriteLine("You should ask the package owner to unlist the package " + pkg.Id + " " + pkg.Version); } var bytesTask = response.Content.ReadAsByteArrayAsync(); byte[] bytes = bytesTask.Result; var blobClient = CreateBlobClient(); var packagesBlobContainer = Util.GetPackagesBlobContainer(blobClient); var packageFileBlob = Util.GetPackageFileBlob( packagesBlobContainer, pkg.Id, pkg.Version); var fileName = Util.GetPackageFileName( pkg.Id, pkg.Version); if (packageFileBlob.Exists()) { Console.WriteLine("SKIPPED! Package file blob " + fileName + " already exists"); } else { Console.WriteLine("Saving the package file " + pkg.ExternalPackageUrl + " to blob storage as " + fileName); if (!WhatIf) { packageFileBlob.UploadFromStream( new MemoryStream(bytes), AccessCondition.GenerateIfNoneMatchCondition("*")); } } } } }
public void Init() { if (!_blob.Exists()) { //var nextSize = NextSize(0); _blob.Create(0, AccessCondition.GenerateIfNoneMatchCondition("*")); } _size = _blob.Properties.Length; _etag = _blob.Properties.ETag; }
public async Task CreateLeaseIfNotExistAsync(string partitionId) { CloudBlockBlob leaseBlob = this.consumerGroupDirectory.GetBlockBlobReference(partitionId); BlobLease lease = new BlobLease(leaseBlob) { PartitionId = partitionId }; string serializedLease = JsonConvert.SerializeObject(lease); try { this.settings.Logger.PartitionManagerInfo( this.storageAccountName, this.taskHubName, this.workerName, partitionId, string.Format( CultureInfo.InvariantCulture, "CreateLeaseIfNotExistAsync - leaseContainerName: {0}, consumerGroupName: {1}, partitionId: {2}. blobPrefix: {3}", this.leaseContainerName, this.consumerGroupName, partitionId, this.blobPrefix ?? string.Empty)); await leaseBlob.UploadTextAsync(serializedLease, null, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null); } catch (StorageException se) { // eat any storage exception related to conflict // this means the blob already exist if (se.RequestInformation.HttpStatusCode != 409) { this.settings.Logger.PartitionManagerInfo( this.storageAccountName, this.taskHubName, this.workerName, partitionId, string.Format( CultureInfo.InvariantCulture, "CreateLeaseIfNotExistAsync - leaseContainerName: {0}, consumerGroupName: {1}, partitionId: {2}, blobPrefix: {3}, exception: {4}", this.leaseContainerName, this.consumerGroupName, partitionId, this.blobPrefix ?? string.Empty, se.Message)); } } finally { this.stats.StorageRequests.Increment(); } }
public Task UploadVideoAsync(Guid roomId, string sessionId, Stream stream, CancellationToken token) { var blobName = BuildBlobName(roomId, sessionId); var blob = GetBlob(blobName); if (stream.CanSeek) { stream.Seek(0, SeekOrigin.Begin); } blob.Properties.ContentType = "video/webm"; return(blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfNoneMatchCondition("*"), new BlobRequestOptions(), new OperationContext(), token)); }
public async Task WriteToBlob(ICloudFactory storage) { var blob = GetBlob(storage); var exists = await blob.ExistsAsync(); if (!exists) { blob.Create(0, AccessCondition.GenerateIfNoneMatchCondition("*")); } blob.Metadata["endpoint"] = this._endpoint; await blob.SetMetadataAsync(); }
public async Task <StreamWriter> CreateWriter(CancellationToken cancellation) { if (await blob.ExistsAsync() && !overwrite) { throw Errors.BlobAlreadyExists(blob.Uri.ToString()); } await blob.Container.CreateIfNotExistsAsync(cancellation); return(new BlobStreamWriter( await blob.OpenWriteAsync( overwrite ? null : AccessCondition.GenerateIfNoneMatchCondition("*"), null, null, cancellation), blob.Uri.ToString())); }
private async Task <StorageResult> GetBlobContentAsync(string folderName, string fileName, string ifNoneMatch = null) { ICloudBlobContainer container = await GetContainerAsync(folderName); var blob = container.GetBlobReference(fileName); var stream = new MemoryStream(); try { await blob.DownloadToStreamAsync( stream, accessCondition : ifNoneMatch == null? null : AccessCondition.GenerateIfNoneMatchCondition(ifNoneMatch)); } catch (StorageException ex) { stream.Dispose(); if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotModified) { return(new StorageResult(HttpStatusCode.NotModified, null)); } else if (ex.RequestInformation.ExtendedErrorInformation?.ErrorCode == BlobErrorCodeStrings.BlobNotFound) { return(new StorageResult(HttpStatusCode.NotFound, null)); } throw; } catch (TestableStorageClientException ex) { // This is for unit test only, because we can't construct an // StorageException object with the required ErrorCode stream.Dispose(); if (ex.ErrorCode == BlobErrorCodeStrings.BlobNotFound) { return(new StorageResult(HttpStatusCode.NotFound, null)); } throw; } stream.Position = 0; return(new StorageResult(HttpStatusCode.OK, stream)); }
private async Task <BlobData> GetLatestDataAsync(ICloudBlob blobRef) { // Set the appropriate AccessCondition based on what we believe the latest // file contents to be, then make the request. var latestCachedData = Volatile.Read(ref _cachedBlobData); // local ref so field isn't mutated under our feet var accessCondition = (latestCachedData != null) ? AccessCondition.GenerateIfNoneMatchCondition(latestCachedData.ETag) : null; try { using (var memoryStream = new MemoryStream()) { await blobRef.DownloadToStreamAsync( target : memoryStream, accessCondition : accessCondition, options : null, operationContext : null); // At this point, our original cache either didn't exist or was outdated. // We'll update it now and return the updated value; latestCachedData = new BlobData() { BlobContents = memoryStream.ToArray(), ETag = blobRef.Properties.ETag }; } Volatile.Write(ref _cachedBlobData, latestCachedData); } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == 304) { // 304 Not Modified // Thrown when we already have the latest cached data. // This isn't an error; we'll return our cached copy of the data. } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == 404) { // 404 Not Found // Thrown when no file exists in storage. // This isn't an error; we'll delete our cached copy of data. latestCachedData = null; Volatile.Write(ref _cachedBlobData, latestCachedData); } return(latestCachedData); }
public async Task UploadFromStreamAsync(Stream packageFile, bool overwrite) { if (overwrite) { await _blob.UploadFromStreamAsync(packageFile); } else { await _blob.UploadFromStreamAsync( packageFile, AccessCondition.GenerateIfNoneMatchCondition("*"), new BlobRequestOptions(), new OperationContext()); } }
// see https://stackoverflow.com/questions/27756853/forcing-etag-check-on-blob-creation public override async Task UploadFromStreamAsync(Stream source, string etag) { if (String.IsNullOrEmpty(etag)) { // For those Cloud Provider that doesn't support etag, etag should always be null. // https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.accesscondition.generateifnonematchcondition?view=azure-dotnet // Check if the azure blob doesn't exist await _blob.UploadFromStreamAsync(source, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null);; } else { await _blob.UploadFromStreamAsync(source, AccessCondition.GenerateIfMatchCondition(etag), null, null); } return; }
public async Task <Lease> CreateLeaseIfNotExistsAsync(string partitionId) // throws URISyntaxException, IOException, StorageException { AzureBlobLease returnLease; try { CloudBlockBlob leaseBlob = GetBlockBlobReference(partitionId); returnLease = new AzureBlobLease(partitionId, leaseBlob); string jsonLease = JsonConvert.SerializeObject(returnLease); ProcessorEventSource.Log.AzureStorageManagerInfo( this.host.HostName, partitionId, "CreateLeaseIfNotExist - leaseContainerName: " + this.leaseContainerName + " consumerGroupName: " + this.host.ConsumerGroupName + " storageBlobPrefix: " + this.storageBlobPrefix); // Don't provide default request options for upload call. // This request will respect client's default options. await leaseBlob.UploadTextAsync( jsonLease, null, AccessCondition.GenerateIfNoneMatchCondition("*"), null, this.operationContext).ConfigureAwait(false); } catch (StorageException se) { if (se.RequestInformation.ErrorCode == BlobErrorCodeStrings.BlobAlreadyExists || se.RequestInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) // occurs when somebody else already has leased the blob { // The blob already exists. ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, partitionId, "Lease already exists"); returnLease = (AzureBlobLease) await GetLeaseAsync(partitionId).ConfigureAwait(false); } else { ProcessorEventSource.Log.AzureStorageManagerError( this.host.HostName, partitionId, "CreateLeaseIfNotExist StorageException - leaseContainerName: " + this.leaseContainerName + " consumerGroupName: " + this.host.ConsumerGroupName + " storageBlobPrefix: " + this.storageBlobPrefix, se.ToString()); throw; } } return(returnLease); }
public async Task Test_21_UploadBlobIfNotExists() { CloudBlobContainer container = _Client.GetContainerReference("photos"); await container.CreateIfNotExistsAsync(); CloudBlockBlob blob = container.GetBlockBlobReference("monah.jpg"); //await blob.DeleteIfExistsAsync(); var ac = AccessCondition.GenerateIfNoneMatchCondition("*"); var localFileName = @"d:\monah.jpg"; File.Exists(localFileName).Should().BeTrue(); await blob.UploadFromFileAsync(localFileName, ac, null, null); }
async Task CreateAppLeaseInfoIfNotExistsAsync() { try { await this.appLeaseInfoBlob.UploadTextAsync("{}", null, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null); } catch (StorageException) { // eat any storage exception related to conflict // this means the blob already exist } finally { this.stats.StorageRequests.Increment(); } }
public async Task SaveAsync() { if (_dataAccounts != null) { _namespaceBlob.Metadata[MetadataNameAccount] = String.Join(AccountDelimiter, _dataAccounts); } if (!_blobExists) { await _namespaceBlob.UploadTextAsync("", Encoding.UTF8, AccessCondition.GenerateIfNoneMatchCondition("*"), null, null); } else { await _namespaceBlob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(_namespaceBlob.Properties.ETag), null, null); } _blobExists = true; }
public AutoRenewLease(CloudBlockBlob blob) { this.blob = blob; blob.Container.CreateIfNotExists(); try { if (!blob.Exists()) { blob.UploadFromByteArray(new byte[0], 0, 0, AccessCondition.GenerateIfNoneMatchCondition("*")); // new BlobRequestOptions { AccessCondition = AccessCondition.IfNoneMatch("*") }); } } catch (StorageException e) { if (e.RequestInformation.HttpStatusCode != (int)HttpStatusCode.PreconditionFailed && // 412 from trying to modify a blob that's leased e.RequestInformation.ExtendedErrorInformation.ErrorCode != BlobErrorCodeStrings.BlobAlreadyExists ) { throw; } } try { leaseId = blob.AcquireLease(TimeSpan.FromSeconds(60), null); _accessCondition = new AccessCondition { LeaseId = leaseId }; } catch (Exception) { Trace.WriteLine("==========> Lease rejected! <=========="); } if (HasLease) { renewalThread = new Thread(() => { while (true) { Thread.Sleep(TimeSpan.FromSeconds(40)); var ac = new AccessCondition(); ac.LeaseId = leaseId; blob.RenewLease(ac); //.RenewLease(leaseId); } }); renewalThread.Start(); } }
public async Task UploadTextAsync(string content, string?leaseId = null, bool ifDoesntExist = false) { AccessCondition?accessCondition = null; if (ifDoesntExist) { accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); } else if (leaseId != null) { accessCondition = AccessCondition.GenerateLeaseCondition(leaseId); } await this.azureStorageClient.MakeBlobStorageRequest( (context, cancellationToken) => this.cloudBlockBlob.UploadTextAsync(content, null, accessCondition, null, context, cancellationToken), "Blob UploadText"); }