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; })); }
/// <summary> /// This is wrapper class that provides generic exception handling support /// and retrieves the standard metadata for each request. /// </summary> /// <param name="rq">The request.</param> /// <param name="rs">The response.</param> /// <param name="action">The async action task.</param> /// <returns>Returns a task with the response.</returns> protected async Task <StorageResponseHolder> CallCloudBlockBlob(StorageRequestHolder rq , Func <StorageRequestHolder, StorageResponseHolder, bool, Task> action) { int start = StatisticsInternal.ActiveIncrement(); var rs = new StorageResponseHolder(); try { var refEntityDirectory = mEntityContainer.GetDirectoryReference(rq.Directory); rq.Blob = refEntityDirectory.GetBlockBlobReference(rq.SafeKey); bool exists = await rq.Blob.ExistsAsync(rq.CancelSet); if (exists) { MetadataGet(rq.Blob, rq); exists ^= rq.IsDeleted; } await action(rq, rs, exists); } catch (StorageException sex) { rs.Ex = sex; rs.IsSuccess = false; rs.StatusCode = sex.RequestInformation.HttpStatusCode; rs.IsTimeout = rs.StatusCode == 500 || rs.StatusCode == 503; } catch (TaskCanceledException tcex) { rs.Ex = tcex; rs.IsTimeout = true; rs.IsSuccess = false; rs.StatusCode = 502; } catch (Exception ex) { rs.Ex = ex; rs.IsSuccess = false; rs.StatusCode = 500; } finally { if (!rs.IsSuccess) { StatisticsInternal.ErrorIncrement(); } StatisticsInternal.ActiveDecrement(start); } return(rs); }
public virtual async Task <StorageResponseHolder> Create(string key , byte[] body , string contentType = null , string contentEncoding = null , string version = null , string directory = null , IEnumerable <KeyValuePair <string, string> > metadata = null , CancellationToken?cancel = null , bool useEncryption = true) { var request = new StorageRequestHolder(key, cancel, directory); return(await CallCloudBlockBlob(request, async (rq, rs, exists) => { if (!exists) { //Check for a soft delete condition. var access = rq.ETag != null ? AccessCondition.GenerateIfMatchCondition(rq.ETag) : AccessCondition.GenerateIfNotExistsCondition(); rq.ContentType = contentType; rq.ContentEncoding = contentEncoding; rq.VersionId = version; if (metadata != null) { rq.Fields = metadata.ToDictionary((k) => k.Key, (k) => k.Value); } 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, access, mOptions, mContext, rq.CancelSet); MetadataGet(rq.Blob, rs); rs.Data = body; } else { rq.CopyTo(rs); } rs.IsSuccess = !exists; rs.StatusCode = exists ? 409 : 201; })); }
public virtual async Task <StorageResponseHolder> Delete(string key, string directory = null, string version = null , CancellationToken?cancel = null , bool createSnapshotBeforeDelete = true, bool hardDelete = false) { var request = new StorageRequestHolder(key, cancel, directory); return(await CallCloudBlockBlob(request, async (rq, rs, exists) => { //Does the entity currently exist? if (!exists) { rq.CopyTo(rs); rs.IsSuccess = false; rs.StatusCode = 404; return; } //OK, do the version match? if (version != null && rq.VersionId != version) { MetadataGet(rq.Blob, rs); rs.IsSuccess = false; rs.StatusCode = 409; return; } if (hardDelete) { //OK, we hard delete the entity and remove any snapshots that may be there. await rq.Blob.DeleteAsync(DeleteSnapshotsOption.IncludeSnapshots, AccessCondition.GenerateIfMatchCondition(rq.ETag), mOptions, mContext, rq.CancelSet); } else { if (createSnapshotBeforeDelete) { await rq.Blob.CreateSnapshotAsync(rq.Fields, AccessCondition.GenerateIfMatchCondition(rq.ETag), mOptions, mContext, rq.CancelSet); } //Ok, we are going to soft delete the entity. MetadataSet(rq.Blob, rq, deleted: true); await rq.Blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(rq.ETag), mOptions, mContext, rq.CancelSet); } MetadataGet(rq.Blob, rs); rs.IsSuccess = true; rs.StatusCode = 200; })); }
public virtual async Task <StorageResponseHolder> Version(string key, string directory = null, CancellationToken?cancel = null) { var request = new StorageRequestHolder(key, cancel, directory); return(await CallCloudBlockBlob(request, async (rq, rs, exists) => { if (exists) { MetadataGet(rq.Blob, rs); } else { rq.CopyTo(rs); } rs.IsSuccess = exists; rs.StatusCode = exists ? 200 : 404; })); }
public virtual async Task <StorageResponseHolder> Read(string key , string directory = null , CancellationToken?cancel = null , bool useEncryption = true) { var request = new StorageRequestHolder(key, cancel, directory); return(await CallCloudBlockBlob(request, async (rq, rs, exists) => { if (exists) { var sData = new MemoryStream(); await rq.Blob.DownloadToStreamAsync(sData, rq.CancelSet); rs.Data = new byte[sData.Length]; sData.Position = 0; sData.Read(rs.Data, 0, rs.Data.Length); // If encryption provided decrypt the blob if (useEncryption && mEncryption != null) { rs.Data = mEncryption.Decrypt(rs.Data); } MetadataGet(rq.Blob, rs); } else { rq.CopyTo(rs); } rs.IsSuccess = exists; rs.StatusCode = exists ? 200 : 404; })); }