internal async Task <TResult> MarkInviteRedeemedAsync <TResult>(Guid inviteToken, Guid loginId, Func <Guid, TResult> onFound, Func <TResult> onNotFound, Func <Guid, TResult> onAlreadyRedeemed, Func <TResult> onAlreadyInUse, Func <TResult> onAlreadyConnected) { var lookupResults = await await repository.FindByIdAsync(inviteToken, async (Documents.InviteTokenDocument tokenDocument) => { var rollback = new RollbackAsync <TResult>(); rollback.AddTaskUpdate(tokenDocument.InviteId, (Documents.InviteDocument inviteDoc) => { inviteDoc.LoginId = loginId; }, (inviteDoc) => { inviteDoc.LoginId = default(Guid?); }, onNotFound, this.repository); var loginLookup = new Documents.LoginActorLookupDocument() { ActorId = tokenDocument.ActorId, }; rollback.AddTaskCreate(loginId, loginLookup, onAlreadyInUse, this.repository); return(await rollback.ExecuteAsync(() => onFound(tokenDocument.ActorId))); }, () => onNotFound().ToTask()); return(lookupResults); }
public static void AddTaskDeleteJoin <TRollback, TDocument>(this RollbackAsync <Guid?, TRollback> rollback, Guid docId, Func <TDocument, Guid?> removeLink, Action <Guid, TDocument> rollbackLink, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTaskUpdate(docId, (TDocument doc) => { var joinId = removeLink(doc); return(joinId); }, (joinId, doc) => { if (joinId.HasValue) { rollbackLink(joinId.Value, doc); return(true); } return(false); }, () => default(Guid?), repo); }
public async Task <TResult> CreateOrUpdateAsync <TResult>(Guid actorId, Guid claimId, string type, string value, Func <TResult> onSuccess, Func <TResult> onFailure, Func <TResult> onActorNotFound) { return(await await repository.FindLinkedDocumentsAsync <ActorMappingsDocument, ClaimDocument, Task <TResult> >(actorId, (ActorMappingsDocument actorMappingsDocument) => actorMappingsDocument.Claims.ToGuidsFromByteArray(), async (ActorMappingsDocument actorMappingsDocument, ClaimDocument[] claimDocuments) => { var claimDocs = claimDocuments.Where( doc => string.Compare(doc.Type, type, StringComparison.OrdinalIgnoreCase) == 0) .ToArray(); if (claimDocs.Length >= 1) { var claimDoc = claimDocs[0]; return await repository.UpdateAsync <ClaimDocument, TResult>(claimDoc.ClaimId, async(currentDoc, saveAsync) => { currentDoc.Value = value; await saveAsync(currentDoc); return onSuccess(); }, () => onFailure()); } var rollback = new RollbackAsync <TResult>(); var newClaimDoc = new ClaimDocument() { ClaimId = claimId, Issuer = actorId.ToString("N"), //TODO - Is this is the correct issuer data??? Type = type, Value = value }; rollback.AddTaskCreate(claimId, newClaimDoc, onFailure, repository); rollback.AddTaskUpdate(actorId, (ActorMappingsDocument actorMapDocument) => actorMapDocument.AddClaim(claimId), (actorMapDocument) => actorMapDocument.RemoveClaim(claimId), onActorNotFound, repository); return await rollback.ExecuteAsync(onSuccess); }, () => onActorNotFound().ToTask())); }
public static void AddTaskUpdate <T, TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, Func < TDocument, Func <T, UpdateCallback <T> >, // Save + Success Func <UpdateCallback <T> >, // No Save + Success UpdateCallback <T> > mutateUpdate, Func <T, TDocument, bool> mutateRollback, Func <TRollback> onNotFound, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTaskUpdate(docId, (doc, save, successNoSave, fail) => mutateUpdate(doc, save, successNoSave), mutateRollback, "This version of update does not support a failure case".AsFunctionException <TRollback>(), // should never happen onNotFound, repo); }
public static void AddTaskUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, Func < TDocument, Func <UpdateCallback <bool> >, // Save + Success Func <UpdateCallback <bool> >, // No Save + Success Func <UpdateCallback <bool> >, // Reject UpdateCallback <bool> > mutateUpdate, Func <TDocument, bool> mutateRollback, Func <TRollback> onMutateRejected, Func <TRollback> onNotFound, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTaskUpdate <bool, TRollback, TDocument>(docId, (doc, save, successNoSave, reject) => mutateUpdate(doc, () => save(true), () => successNoSave(), () => reject()), (throwAway, doc) => { mutateRollback(doc); return(true); }, onMutateRejected, onNotFound, repo); }
public static async Task <TResult> AddJoinAsync <TJoin, TDocJoin, TDoc1, TDoc2, TResult>(this AzureStorageRepository repo, Guid id, Guid id1, Guid id2, TDocJoin document, Func <TDoc1, TJoin[]> getJoins1, Func <TDoc2, TJoin[]> getJoins2, Func <TJoin, Guid> id1FromJoin, Func <TJoin, Guid> id2FromJoin, Action <TDoc1> mutateUpdate1, Action <TDoc1> mutateRollback1, Action <TDoc2> mutateUpdate2, Action <TDoc2> mutateRollback2, Func <TResult> onSuccess, Func <TResult> joinIdAlreadyExist, Func <TJoin, TResult> joinAlreadyExist, Func <TResult> doc1DoesNotExist, Func <TResult> doc2DoesNotExist) where TDocJoin : class, ITableEntity where TDoc1 : class, ITableEntity where TDoc2 : class, ITableEntity { var parallel = new RollbackAsync <TResult>(); var duplicateJoin1 = default(TJoin); parallel.AddTaskUpdate <Guid, TResult, TDoc1>(id1, (doc, successSave, successNoSave, reject) => { var matches = getJoins1(doc).Where(join => id2FromJoin(join) == id2).ToArray(); if (matches.Length > 0) { duplicateJoin1 = matches[0]; return(reject()); } mutateUpdate1(doc); return(successSave(id1)); }, (id1Again, doc) => { mutateRollback1(doc); return(true); }, () => joinAlreadyExist(duplicateJoin1), doc1DoesNotExist, repo); var duplicateJoin2 = default(TJoin); parallel.AddTaskUpdate <Guid, TResult, TDoc2>(id2, (doc, successSave, successNoSave, reject) => { var matches = getJoins2(doc).Where(join => id1FromJoin(join) == id1).ToArray(); if (matches.Length > 0) { duplicateJoin2 = matches[0]; return(reject()); } mutateUpdate2(doc); return(successSave(id2)); }, (id1Again, doc) => { mutateRollback2(doc); return(true); }, () => joinAlreadyExist(duplicateJoin2), doc2DoesNotExist, repo); //parallel.AddTaskUpdate(id2, // mutateUpdate2, // mutateRollback2, // doc2DoesNotExist, // repo); parallel.AddTaskCreate(id, document, () => joinIdAlreadyExist(), repo); var result = await parallel.ExecuteAsync( () => onSuccess(), (failureResult) => failureResult); return(result); }