/// <summary>
        /// Finds an already-existing instance of the given saga data type that has a property with the given <paramref name="propertyName"/>
        /// whose value matches <paramref name="propertyValue"/>. Returns null if no such instance could be found
        /// </summary>
        public async Task <ISagaData> Find(Type sagaDataType, string propertyName, object propertyValue)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                string sagaDataDocumentId;

                if (propertyName == _sagaDataIdPropertyName)
                {
                    sagaDataDocumentId = SagaDataDocument.GetIdFromGuid((Guid)propertyValue);
                }
                else
                {
                    var sagaCorrelationPropertyDocumentId =
                        SagaCorrelationPropertyDocument.GetIdForCorrelationProperty(sagaDataType, propertyName,
                                                                                    propertyValue);

                    var existingSagaCorrelationPropertyDocument =
                        await session.LoadAsync <SagaCorrelationPropertyDocument>(sagaCorrelationPropertyDocumentId);

                    sagaDataDocumentId = existingSagaCorrelationPropertyDocument?.SagaDataDocumentId;
                }

                if (sagaDataDocumentId == null)
                {
                    return(null);
                }

                var existingSagaDataDocument = await session.LoadAsync <SagaDataDocument>(sagaDataDocumentId);

                return(existingSagaDataDocument?.SagaData);
            }
        }
Example #2
0
        /// <inheritdoc />
        public async Task Insert(ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties)
        {
            if (sagaData.Id == Guid.Empty)
            {
                throw new InvalidOperationException($"Saga data {sagaData.GetType()} has an uninitialized Id property!");
            }

            if (sagaData.Revision != 0)
            {
                throw new InvalidOperationException($"Attempted to insert saga data with ID {sagaData.Id} and revision {sagaData.Revision}, but revision must be 0 on first insert!");
            }

            using (var session = _documentStore.OpenAsyncSession())
            {
                session.Advanced.UseOptimisticConcurrency = true;

                try
                {
                    var sagaDataDocumentId = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                    var sagaDataDocument   = new SagaDataDocument(sagaData);

                    await session.StoreAsync(sagaDataDocument, sagaDataDocumentId);

                    var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, sagaDataDocumentId);

                    sagaDataDocument.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                    await session.SaveChangesAsync();
                }
                catch (Raven.Abstractions.Exceptions.ConcurrencyException ravenDbConcurrencyException)
                {
                    throw new ConcurrencyException(ravenDbConcurrencyException, $"Could not insert saga data with ID {sagaData.Id}");
                }
            }
        }
Example #3
0
        static async Task DeleteCorrelationPropertyDataForSaga(SagaDataDocument sagaDataDocument, IAsyncDocumentSession session)
        {
            var correlationPropertyDocumentIds = sagaDataDocument.SagaCorrelationPropertyDocumentIds;
            var documentId = sagaDataDocument.Id;

            await DeleteCorrelationProperties(correlationPropertyDocumentIds, session, documentId);
        }
Example #4
0
        public async Task Insert(ISagaData sagaData, IEnumerable<ISagaCorrelationProperty> correlationProperties)
        {
            if (sagaData.Id == Guid.Empty)
            {
                throw new InvalidOperationException($"Saga data {sagaData.GetType()} has an uninitialized Id property!");
            }

            if (sagaData.Revision != 0)
            {
                throw new InvalidOperationException($"Attempted to insert saga data with ID {sagaData.Id} and revision {sagaData.Revision}, but revision must be 0 on first insert!");
            }

            using (var session = _documentStore.OpenAsyncSession())
            {
                var sagaDataDocumentId = SagaDataDocument.GetIdFromGuid(sagaData.Id);

                var existingSagaDataDocument = await session.LoadAsync<SagaDataDocument>(sagaDataDocumentId);

                if (existingSagaDataDocument != null)
                {
                    throw new ConcurrencyException("Cannot insert document with an id that already exists");
                }

                var sagaDataDocument = new SagaDataDocument(sagaData);
                await session.StoreAsync(sagaDataDocument, sagaDataDocumentId);

                var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, sagaDataDocumentId);
                sagaDataDocument.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                await session.SaveChangesAsync();
            }
        }
Example #5
0
        /// <inheritdoc />
        public async Task Delete(ISagaData sagaData)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                session.Advanced.UseOptimisticConcurrency = true;

                var documentId       = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var existingSagaData = await session.LoadAsync <SagaDataDocument>(documentId);

                if (existingSagaData == null)
                {
                    throw new ConcurrencyException("Cannot delete saga that does not exist");
                }

                try
                {
                    await DeleteCorrelationPropertyDataForSaga(existingSagaData, session);

                    session.Delete(existingSagaData);

                    await session.SaveChangesAsync();
                }
                catch (Raven.Abstractions.Exceptions.ConcurrencyException ravenDbConcurrencyException)
                {
                    throw new ConcurrencyException(ravenDbConcurrencyException, $"Could not delete saga data with ID {sagaData.Id}");
                }
            }

            sagaData.Revision++;
        }
        public async Task Insert(ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties)
        {
            if (sagaData.Id == Guid.Empty)
            {
                throw new InvalidOperationException($"Saga data {sagaData.GetType()} has an uninitialized Id property!");
            }

            if (sagaData.Revision != 0)
            {
                throw new InvalidOperationException($"Attempted to insert saga data with ID {sagaData.Id} and revision {sagaData.Revision}, but revision must be 0 on first insert!");
            }

            using (var session = _documentStore.OpenAsyncSession())
            {
                session.Advanced.UseOptimisticConcurrency = true;

                var sagaDataDocumentId = SagaDataDocument.GetIdFromGuid(sagaData.Id);

                var existingSagaDataDocument = await session.LoadAsync <SagaDataDocument>(sagaDataDocumentId);

                if (existingSagaDataDocument != null)
                {
                    throw new ConcurrencyException("Cannot insert document with an id that already exists");
                }

                var sagaDataDocument = new SagaDataDocument(sagaData);
                await session.StoreAsync(sagaDataDocument, sagaDataDocumentId);

                var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, sagaDataDocumentId);

                sagaDataDocument.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                await session.SaveChangesAsync();
            }
        }
        public async Task Update(ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                session.Advanced.UseOptimisticConcurrency = true;

                var documentId       = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var existingSagaData = await session.LoadAsync <SagaDataDocument>(documentId);

                if (existingSagaData == null)
                {
                    throw new ConcurrencyException("Cannot update saga that does not exist");
                }

                sagaData.Revision++;
                existingSagaData.SagaData = sagaData;

                //add the new saga correlation documents
                var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, existingSagaData.Id);

                var oldCorrelationPropertyDocumentIdsNotPresentInNew = existingSagaData
                                                                       .SagaCorrelationPropertyDocumentIds
                                                                       .Where(sc => !correlationPropertyDocumentIds.Contains(sc));

                await DeleteCorrelationProperties(oldCorrelationPropertyDocumentIdsNotPresentInNew, session);

                existingSagaData.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                await session.SaveChangesAsync();
            }
        }
Example #8
0
        private async Task DeleteCorrelationPropertyDataForSaga(SagaDataDocument sagaDataDocument,
                                                                IAsyncDocumentSession session)
        {
            var existingSagaCorrelationPropertyDocuments =
                await session.LoadAsync <SagaCorrelationPropertyDocument>(
                    sagaDataDocument.SagaCorrelationPropertyDocumentIds);

            //delete the existing saga correlation documents
            foreach (var existingSagaCorrelationPropertyDocument in existingSagaCorrelationPropertyDocuments)
            {
                session.Delete(existingSagaCorrelationPropertyDocument);
            }
        }
Example #9
0
        public async Task Delete(ISagaData sagaData)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                var documentId       = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var existingSagaData = await session.LoadAsync <SagaDataDocument>(documentId);
                await DeleteCorrelationPropertyDataForSaga(existingSagaData, session);

                session.Delete(existingSagaData);

                await session.SaveChangesAsync();
            }
        }
Example #10
0
        /// <inheritdoc />
        public async Task Update(ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                session.Advanced.UseOptimisticConcurrency = true;

                var documentId       = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var existingSagaData = await session.LoadAsync <SagaDataDocument>(documentId);

                if (existingSagaData == null)
                {
                    throw new ConcurrencyException($"Tried to update saga data with ID {sagaData.Id} but it did not exist (could have been deleted by someone else while we were workingS)");
                }

                if (existingSagaData.SagaData.Revision != sagaData.Revision)
                {
                    throw new ConcurrencyException($"Tried to update saga data with ID {sagaData.Id} to revision {sagaData.Revision + 1} but it was already updated to that revision while we were working");
                }

                sagaData.Revision++;
                existingSagaData.SagaData = sagaData;

                try
                {
                    //add the new saga correlation documents
                    var correlationPropertyDocumentIds =
                        (await SaveCorrelationProperties(session, sagaData, correlationProperties, existingSagaData.Id))
                        .ToList();

                    var oldCorrelationPropertyDocumentIdsNotPresentInNew = existingSagaData
                                                                           .SagaCorrelationPropertyDocumentIds
                                                                           .Except(correlationPropertyDocumentIds);

                    await DeleteCorrelationProperties(oldCorrelationPropertyDocumentIdsNotPresentInNew, session, documentId);

                    existingSagaData.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                    await session.SaveChangesAsync();
                }
                catch (Raven.Abstractions.Exceptions.ConcurrencyException ravenDbConcurrencyException)
                {
                    throw new ConcurrencyException(ravenDbConcurrencyException, $"Could not update saga data with ID {sagaData.Id} to revision {sagaData.Revision}");
                }
            }
        }
Example #11
0
        public async Task Delete(ISagaData sagaData)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                var documentId       = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var existingSagaData = await session.LoadAsync <SagaDataDocument>(documentId);

                if (existingSagaData == null)
                {
                    throw new ConcurrencyException("Cannot delete saga that does not exist");
                }

                await DeleteCorrelationPropertyDataForSaga(existingSagaData, session);

                session.Delete(existingSagaData);

                await session.SaveChangesAsync();
            }
        }
Example #12
0
        public async Task Insert(ISagaData sagaData, IEnumerable<ISagaCorrelationProperty> correlationProperties)
        {
            if (sagaData.Id == Guid.Empty)
            {
                throw new InvalidOperationException($"Saga data {sagaData.GetType()} has an uninitialized Id property!");
            }

            using (var session = _documentStore.OpenAsyncSession())
            {
                var sagaDataDocumentId = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var sagaDataDocument = new SagaDataDocument(sagaData);
                await session.StoreAsync(sagaDataDocument, sagaDataDocumentId);

                var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, sagaDataDocumentId);
                sagaDataDocument.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                await session.SaveChangesAsync();
            }
        }
Example #13
0
        public async Task Update(ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                var documentId       = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var existingSagaData = await session.LoadAsync <SagaDataDocument>(documentId);

                sagaData.Revision++;
                existingSagaData.SagaData = sagaData;

                await DeleteCorrelationPropertyDataForSaga(existingSagaData, session);

                //add the new saga correlation documents
                var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, existingSagaData.Id);

                existingSagaData.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                await session.SaveChangesAsync();
            }
        }
Example #14
0
        public async Task Insert(ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties)
        {
            if (sagaData.Id == Guid.Empty)
            {
                throw new InvalidOperationException($"Saga data {sagaData.GetType()} has an uninitialized Id property!");
            }

            using (var session = _documentStore.OpenAsyncSession())
            {
                var sagaDataDocumentId = SagaDataDocument.GetIdFromGuid(sagaData.Id);
                var sagaDataDocument   = new SagaDataDocument(sagaData);
                await session.StoreAsync(sagaDataDocument, sagaDataDocumentId);

                var correlationPropertyDocumentIds = await SaveCorrelationProperties(session, sagaData, correlationProperties, sagaDataDocumentId);

                sagaDataDocument.SagaCorrelationPropertyDocumentIds = correlationPropertyDocumentIds;

                await session.SaveChangesAsync();
            }
        }
Example #15
0
 async Task DeleteCorrelationPropertyDataForSaga(SagaDataDocument sagaDataDocument, IAsyncDocumentSession session)
 {
     await DeleteCorrelationProperties(sagaDataDocument.SagaCorrelationPropertyDocumentIds, session);
 }
Example #16
0
        private async Task DeleteCorrelationPropertyDataForSaga(SagaDataDocument sagaDataDocument,
            IAsyncDocumentSession session)
        {
            var existingSagaCorrelationPropertyDocuments =
                await session.LoadAsync<SagaCorrelationPropertyDocument>(
                    sagaDataDocument.SagaCorrelationPropertyDocumentIds);

            //delete the existing saga correlation documents
            foreach (var existingSagaCorrelationPropertyDocument in existingSagaCorrelationPropertyDocuments)
            {
                session.Delete(existingSagaCorrelationPropertyDocument);
            }
        }
Example #17
0
 async Task DeleteCorrelationPropertyDataForSaga(SagaDataDocument sagaDataDocument, IAsyncDocumentSession session)
 {
     await DeleteCorrelationProperties(sagaDataDocument.SagaCorrelationPropertyDocumentIds, session);
 }