public async Task InsertAsync(SagaData entity) { var sagaID = entity.PartitionKey + entity.RowKey; var lockID = string.Empty; if (this.lockSagas) { lockID = await sagaLock.CreateLock(sagaID).ConfigureAwait(false); } entity.CreationTimeStamp = DateTime.UtcNow; // Create the table client. CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); CloudTable table = tableClient.GetTableReference(TABLE_NAME); // Create the TableOperation object that inserts the customer entity. TableOperation insertOperation = TableOperation.Insert(entity as ITableEntity); // Execute the insert operation. await table.ExecuteAsync(insertOperation).ConfigureAwait(false); if (this.lockSagas) { await sagaLock.ReleaseLock(sagaID, lockID).ConfigureAwait(false); } }
public async Task UpdateAsync(SagaData entity) { if (entity.IsDeleted) { return; } CloudStorageAccount storageAccount = CloudStorageAccount.Parse(SettingsUtil.GetSettings <string>(SETTINGS.AZURE_STORAGE)); // Create the table client. CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); CloudTable table = tableClient.GetTableReference(TABLE_NAME); // Create the TableOperation object that inserts the customer entity. TableOperation replaceOperation = TableOperation.Replace(entity as ITableEntity); // Execute the insert operation. await table.ExecuteAsync(replaceOperation).ConfigureAwait(false); var sagaID = entity.PartitionKey + entity.RowKey; if (this.lockSagas && !entity.IsDeleted) { await sagaLock.ReleaseLock(sagaID, entity.LockID).ConfigureAwait(false); } }
public async Task DeleteAsync(SagaData entity) { entity.IsDeleted = true; entity.FinishingTimeStamp = DateTime.UtcNow; var sagaID = entity.PartitionKey + entity.RowKey; if (this.lockSagas) { await sagaLock.DeleteLock(sagaID, entity.LockID).ConfigureAwait(false); } // Create the table client. CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); CloudTable table = tableClient.GetTableReference(TABLE_NAME); // Create the TableOperation object that inserts the customer entity. TableOperation replaceOperation = TableOperation.Delete(entity); // Execute the insert operation. await table.ExecuteAsync(replaceOperation); /* * entity.IsDeleted = true; * entity.FinishingTimeStamp = DateTime.UtcNow; * * var sagaID = entity.PartitionKey + entity.RowKey; * * if (this.lockSagas) * { * await sagaLock.DeleteLock(sagaID, entity.LockID); * }*/ }
private async Task <bool> LookForEventsProcessedBySagas <T>(T message, AFBusMessageContext messageContext, ILogger log) where T : class { var instantiated = false; foreach (var sagaInfo in messageToSagaDictionary[message.GetType()]) { var saga = CreateInstance(sagaInfo.SagaType); dynamic sagaDynamic = saga; var sagaMessageToMethod = sagaInfo?.EventsThatCorrelatesSagas?.FirstOrDefault(m => m.Message == message.GetType()); //try to load saga from repository if (sagaMessageToMethod != null) { var locker = new SagaAzureStorageLocker(); object[] lookForInstanceParametersArray = new object[] { message }; sagaDynamic.SagaPersistence = new SagaAzureStoragePersistence(locker, this.lockSaga); var sagasData = await((Task <List <SagaData> >)sagaMessageToMethod.CorrelatingMethod.Invoke(saga, lookForInstanceParametersArray)).ConfigureAwait(false); if (sagasData != null) { //process each saga data independently foreach (var sagaData in sagasData) { try { dynamic finalSagaData = sagaData; SagaData lockedSagaData = await sagaDynamic.SagaPersistence.GetSagaDataAsync <SagaData>(sagaData.PartitionKey, sagaData.RowKey).ConfigureAwait(false); finalSagaData.Timestamp = lockedSagaData.Timestamp; finalSagaData.ETag = lockedSagaData.ETag; finalSagaData.LockID = lockedSagaData.LockID; sagaDynamic.Data = finalSagaData; var bus = new Bus(serializer, SolveDependency <ISendMessages>(), SolveDependency <IPublishEvents>()) { Context = messageContext }; object[] parametersArray = new object[] { bus, message, log }; SagaData typedSagaData = (SagaData)sagaData; log?.LogInformation("Invoke event saga handler " + sagaMessageToMethod.HandlingMethod.ToString() + " for transaction " + messageContext.TransactionID); await((Task)sagaMessageToMethod.HandlingMethod.Invoke(saga, parametersArray)).ConfigureAwait(false); await sagaPersistence.UpdateAsync(sagaDynamic.Data).ConfigureAwait(false); instantiated = true; } catch (Exception ex) { //if there is an error release the lock. log?.LogError(ex.Message, ex); var sagaID = sagaData.PartitionKey + sagaData.RowKey; await locker.ReleaseLock(sagaID, sagaData.LockID); throw; } } } } } return(instantiated); }
private async Task <bool> LookForCommandsProcessedByASaga <T>(T message, AFBusMessageContext messageContext, ILogger log) where T : class { var instantiated = false; foreach (var sagaInfo in messageToSagaDictionary[message.GetType()]) { var saga = CreateInstance(sagaInfo.SagaType);//Activator.CreateInstance(sagaInfo.SagaType); dynamic sagaDynamic = saga; var sagaMessageToMethod = sagaInfo.CommandsThatAreCorrelatedByTheSaga.FirstOrDefault(m => m.Message == message.GetType()); //try to load saga from repository if (sagaMessageToMethod != null) { var locker = new SagaAzureStorageLocker(); object[] lookForInstanceParametersArray = new object[] { message }; sagaDynamic.SagaPersistence = new SagaAzureStoragePersistence(locker, this.lockSaga); dynamic sagaData = await((Task <SagaData>)sagaMessageToMethod.CorrelatingMethod.Invoke(saga, lookForInstanceParametersArray)).ConfigureAwait(false); if (sagaData != null) { try { sagaDynamic.Data = sagaData; var bus = new Bus(serializer, SolveDependency <ISendMessages>(), SolveDependency <IPublishEvents>()) { Context = messageContext }; object[] parametersArray = new object[] { bus, message, log }; SagaData typedSagaData = (SagaData)sagaData; log?.LogInformation("Invoke saga handler " + sagaMessageToMethod.HandlingMethod.ToString() + " for transaction " + messageContext.TransactionID + " with key (" + typedSagaData.PartitionKey.ToString() + "," + typedSagaData.RowKey + ")"); await((Task)sagaMessageToMethod.HandlingMethod.Invoke(saga, parametersArray)).ConfigureAwait(false); await sagaPersistence.UpdateAsync(sagaDynamic.Data).ConfigureAwait(false); instantiated = true; } catch (Exception ex) { //if there is an error release the lock. log?.LogError(ex.Message, ex); var sagaID = sagaData.PartitionKey + sagaData.RowKey; await locker.ReleaseLock(sagaID, sagaData.LockID); throw; } } } sagaMessageToMethod = sagaInfo.CommandsThatActivateTheSaga.FirstOrDefault(m => m.Message == message.GetType()); //if not => create the saga if (!instantiated && sagaMessageToMethod != null) { var bus = new Bus(serializer, SolveDependency <ISendMessages>(), SolveDependency <IPublishEvents>()) { Context = messageContext }; object[] parametersArray = new object[] { bus, message, log }; log?.LogInformation("Invoke saga handler " + sagaMessageToMethod.HandlingMethod.ToString() + " for transaction " + messageContext.TransactionID + " creating new saga"); await((Task)sagaMessageToMethod.HandlingMethod.Invoke(saga, parametersArray)).ConfigureAwait(false); await sagaPersistence.InsertAsync(sagaDynamic.Data).ConfigureAwait(false); SagaData typedSagaData = (SagaData)sagaDynamic.Data; log?.LogInformation("Saga data inserted " + sagaMessageToMethod.HandlingMethod.ToString() + " for transaction " + messageContext.TransactionID + " with key (" + typedSagaData.PartitionKey.ToString() + "," + typedSagaData.RowKey.ToString() + ")"); instantiated = true; } } return(instantiated); }