public async Task When_a_duplicate_messages_starting_a_saga_arrive_simultanously_one_of_them_fails()
        {
            var context      = CreateMessageContext();
            var transaction1 = await outboxPersister.BeginTransaction(context);

            var session1 = new OutboxEventStoreSynchronizedStorageSession(connection, (EventStoreOutboxTransaction)transaction1);

            var sagaData = CreateNewSagaData();
            await persister.Save(sagaData, new SagaCorrelationProperty(CorrelationPropName, sagaData.StringProperty), session1, context);

            var transaction2 = await outboxPersister.BeginTransaction(context);

            var session2 = new OutboxEventStoreSynchronizedStorageSession(connection, (EventStoreOutboxTransaction)transaction2);

            try
            {
                await persister.Save(sagaData, new SagaCorrelationProperty(CorrelationPropName, sagaData.StringProperty), session2, context);

                Assert.Fail("Expected exception");
            }
            catch (Exception ex)
            {
                StringAssert.StartsWith("Append failed due to WrongExpectedVersion.", ex.Message);
            }
        }
コード例 #2
0
    static async Task Store(int i, OutboxPersister persister, CancellationToken cancellationToken = default)
    {
        var operations = new[]
        {
            new TransportOperation(
                messageId: "OperationId" + i,
                properties: new DispatchProperties(new Dictionary <string, string>
            {
                {
                    "OptionKey1", "OptionValue1"
                }
            }),
                body: new byte[]
            {
                0x20
            },
                headers: new Dictionary <string, string>
            {
                {
                    "HeaderKey1", "HeaderValue1"
                }
            }
                )
        };
        var messageId  = "MessageId" + i;
        var contextBag = CreateContextBag(messageId);

        using (var transaction = await persister.BeginTransaction(contextBag, cancellationToken))
        {
            await persister.Store(new OutboxMessage(messageId, operations), transaction, contextBag, cancellationToken).ConfigureAwait(false);

            await transaction.Commit(cancellationToken);
        }
        await persister.SetAsDispatched(messageId, contextBag, cancellationToken).ConfigureAwait(false);
    }
コード例 #3
0
        public async Task Should_update_dispatched_flag()
        {
            var persister = new OutboxPersister(store, testEndpointName, CreateTestSessionOpener());

            var id      = Guid.NewGuid().ToString("N");
            var message = new OutboxMessage(id, new []
            {
                new TransportOperation(id, new Dictionary <string, string>(), new byte[1024 * 5], new Dictionary <string, string>())
            });

            using (var transaction = await persister.BeginTransaction(new ContextBag()))
            {
                await persister.Store(message, transaction, new ContextBag());

                await transaction.Commit();
            }
            await persister.SetAsDispatched(id, new ContextBag());

            WaitForIndexing();

            using (var s = store.OpenAsyncSession())
            {
                var result = await s.Query <OutboxRecord>()
                             .SingleOrDefaultAsync(o => o.MessageId == id);

                Assert.NotNull(result);
                Assert.True(result.Dispatched);
            }
        }
コード例 #4
0
    async Task <OutboxMessage> StoreAndGetAsync(OutboxPersister persister)
    {
        var operations = new[]
        {
            new TransportOperation(
                messageId: "Id1",
                options: new Dictionary <string, string>
            {
                {
                    "OptionKey1", "OptionValue1"
                }
            },
                body: new byte[] { 0x20, 0x21 },
                headers: new Dictionary <string, string>
            {
                {
                    "HeaderKey1", "HeaderValue1"
                }
            }
                )
        };

        var messageId = "a";

        var contextBag = CreateContextBag(messageId);

        using (var transaction = await persister.BeginTransaction(contextBag))
        {
            await persister.Store(new OutboxMessage(messageId, operations), transaction, contextBag).ConfigureAwait(false);

            await transaction.Commit();
        }
        return(await persister.Get(messageId, contextBag).ConfigureAwait(false));
    }
コード例 #5
0
        public async Task Should_delete_all_OutboxRecords_that_have_been_dispatched()
        {
            var id      = Guid.NewGuid().ToString("N");
            var context = new ContextBag();

            var persister = new OutboxPersister(store, "TestEndpoint", CreateTestSessionOpener());

            using (var transaction = await persister.BeginTransaction(context))
            {
                await persister.Store(new OutboxMessage("NotDispatched", new TransportOperation[0]), transaction, context);

                await transaction.Commit();
            }

            var outboxMessage = new OutboxMessage(id, new []
            {
                new TransportOperation(id, new Dictionary <string, string>(), new byte[1024 * 5], new Dictionary <string, string>())
            });


            using (var transaction = await persister.BeginTransaction(context))
            {
                await persister.Store(outboxMessage, transaction, context);

                await transaction.Commit();
            }


            await persister.SetAsDispatched(id, context);

            await Task.Delay(TimeSpan.FromSeconds(1)); //Need to wait for dispatch logic to finish

            //WaitForUserToContinueTheTest(store);
            WaitForIndexing();

            var cleaner = new OutboxRecordsCleaner(store);

            await cleaner.RemoveEntriesOlderThan(DateTime.UtcNow.AddMinutes(1));

            using (var s = store.OpenAsyncSession())
            {
                var result = await s.Query <OutboxRecord>().ToListAsync();

                Assert.AreEqual(1, result.Count);
                Assert.AreEqual("NotDispatched", result[0].MessageId);
            }
        }
コード例 #6
0
        public async Task Should_throw_if__trying_to_insert_same_messageid()
        {
            var persister = new OutboxPersister(store, testEndpointName, CreateTestSessionOpener());

            using (var transaction = await persister.BeginTransaction(new ContextBag()))
            {
                await persister.Store(new OutboxMessage("MySpecialId", new TransportOperation[0]), transaction, new ContextBag());

                await transaction.Commit();
            }

            var exception = await Catch <ConcurrencyException>(async() =>
            {
                using (var transaction = await persister.BeginTransaction(new ContextBag()))
                {
                    await persister.Store(new OutboxMessage("MySpecialId", new TransportOperation[0]), transaction, new ContextBag());

                    await transaction.Commit();
                }
            });

            Assert.NotNull(exception);
        }
コード例 #7
0
        public async Task Should_be_deleted()
        {
            await store.Maintenance.SendAsync(
                new ConfigureExpirationOperation(
                    new ExpirationConfiguration {
                Disabled = false, DeleteFrequencyInSec = 1,
            }));

            // arrange
            var persister                  = new OutboxPersister("TestEndpoint", CreateTestSessionOpener(), TimeSpan.FromSeconds(1));
            var context                    = new ContextBag();
            var incomingMessageId          = SimulateIncomingMessage(context).MessageId;
            var dispatchedOutboxMessage    = new OutboxMessage(incomingMessageId, new TransportOperation[0]);
            var notDispatchedOutboxMessage = new OutboxMessage("NotDispatched", new TransportOperation[0]);

            using (var transaction = await persister.BeginTransaction(context))
            {
                await persister.Store(dispatchedOutboxMessage, transaction, context);

                await persister.Store(notDispatchedOutboxMessage, transaction, context);

                await transaction.Commit();
            }

            await persister.SetAsDispatched(dispatchedOutboxMessage.MessageId, context);

            // act
            // wait for dispatch logic and expiry to finish, not ideal but polling on BASE index is also not great
            await Task.Delay(TimeSpan.FromSeconds(3));

            WaitForIndexing();

            // assert
            using (var session = store.OpenAsyncSession())
            {
                var outboxRecords = await session.Query <OutboxRecord>().ToListAsync();

                Assert.AreEqual(1, outboxRecords.Count);
                Assert.AreEqual(notDispatchedOutboxMessage.MessageId, outboxRecords.Single().MessageId);
            }
        }
コード例 #8
0
    static async Task <Tuple <OutboxMessage, OutboxMessage> > StoreDispatchAndGetAsync(OutboxPersister persister, CancellationToken cancellationToken = default)
    {
        var operations = new List <TransportOperation>
        {
            new TransportOperation(
                messageId: "Id1",
                properties: new DispatchProperties(new Dictionary <string, string>
            {
                {
                    "OptionKey1", "OptionValue1"
                }
            }),
                body: new byte[] { 0x20, 0x21 },
                headers: new Dictionary <string, string>
            {
                {
                    "HeaderKey1", "HeaderValue1"
                }
            }
                )
        };
        var messageId = "a";

        var contextBag = CreateContextBag(messageId);

        using (var transaction = await persister.BeginTransaction(contextBag, cancellationToken))
        {
            await persister.Store(new OutboxMessage(messageId, operations.ToArray()), transaction, contextBag, cancellationToken).ConfigureAwait(false);

            await transaction.Commit(cancellationToken);
        }

        var beforeDispatch = await persister.Get(messageId, contextBag, cancellationToken).ConfigureAwait(false);

        await persister.SetAsDispatched(messageId, contextBag, cancellationToken).ConfigureAwait(false);

        var afterDispatch = await persister.Get(messageId, contextBag, cancellationToken).ConfigureAwait(false);

        return(Tuple.Create(beforeDispatch, afterDispatch));
    }
コード例 #9
0
        public async Task Should_save_with_not_dispatched()
        {
            var persister = new OutboxPersister(store, testEndpointName, CreateTestSessionOpener());

            var id      = Guid.NewGuid().ToString("N");
            var message = new OutboxMessage(id, new[]
            {
                new TransportOperation(id, new Dictionary <string, string>(), new byte[1024 * 5], new Dictionary <string, string>())
            });

            using (var transaction = await persister.BeginTransaction(new ContextBag()))
            {
                await persister.Store(message, transaction, new ContextBag());

                await transaction.Commit();
            }

            var result = await persister.Get(id, new ContextBag());

            var operation = result.TransportOperations.Single();

            Assert.AreEqual(id, operation.MessageId);
        }
コード例 #10
0
        public async Task Should_filter_invalid_docid_character()
        {
            var persister = new OutboxPersister(store, testEndpointName, CreateTestSessionOpener());

            var guid                = Guid.NewGuid();
            var messageId           = $@"{guid}\12345";
            var emptyDictionary     = new Dictionary <string, string>();
            var operation           = new TransportOperation("test", emptyDictionary, new byte[0], emptyDictionary);
            var transportOperations = new [] { operation };

            using (var transaction = await persister.BeginTransaction(new ContextBag()))
            {
                await persister.Store(new OutboxMessage(messageId, transportOperations), transaction, new ContextBag());

                await transaction.Commit();
            }

            var outboxMessage = await persister.Get(messageId, new ContextBag());

            Assert.AreEqual(messageId, outboxMessage.MessageId);
            Assert.AreEqual(1, outboxMessage.TransportOperations.Length);
            Assert.AreEqual("test", outboxMessage.TransportOperations[0].MessageId);
        }