コード例 #1
0
    async Task <OutboxMessage> StoreDispatchAndGetAsync()
    {
        var operations = new List <TransportOperation>
        {
            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";

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

                transaction.Commit();
            }
        await persister.SetAsDispatched(messageId, null).ConfigureAwait(false);

        return(await persister.Get(messageId, null).ConfigureAwait(false));
    }
コード例 #2
0
        public void Should_delete_all_OutboxRecords_that_have_been_dispatched()
        {
            var id = Guid.NewGuid().ToString("N");

            var sessionFactory = new RavenSessionFactory(store);

            var persister = new OutboxPersister(sessionFactory) { DocumentStore = store, EndpointName = "TestEndpoint" };
            persister.Store("NotDispatched", Enumerable.Empty<TransportOperation>());
            persister.Store(id, new List<TransportOperation>
            {
                new TransportOperation(id, new Dictionary<string, string>(), new byte[1024*5], new Dictionary<string, string>()),
            });

            sessionFactory.SaveChanges();
            sessionFactory.ReleaseSession();

            persister.SetAsDispatched(id);
            Thread.Sleep(TimeSpan.FromSeconds(1)); //Need to wait for dispatch logic to finish

            WaitForIndexing(store);

            var cleaner = new OutboxRecordsCleaner { DocumentStore = store };
            cleaner.RemoveEntriesOlderThan(DateTime.UtcNow.AddMinutes(1));

            using (var session = store.OpenSession())
            {
                var result = session.Query<OutboxRecord>().ToList();

                Assert.AreEqual(1, result.Count);
                Assert.AreEqual("NotDispatched", result[0].MessageId);
            }
        }
コード例 #3
0
        public void Should_throw_if__trying_to_insert_same_messageid2()
        {
            var sessionFactory = new RavenSessionFactory(store);
            var persister = new OutboxPersister(sessionFactory) { EndpointName = "TestEndpoint" };

            persister.Store("MySpecialId", Enumerable.Empty<TransportOperation>());
            sessionFactory.SaveChanges();
            sessionFactory.ReleaseSession();

            persister.Store("MySpecialId", Enumerable.Empty<TransportOperation>());
            Assert.Throws<ConcurrencyException>(sessionFactory.SaveChanges);
        }
コード例 #4
0
        public void Should_throw_if__trying_to_insert_same_messageid()
        {
            var sessionFactory = new RavenSessionFactory(store);
            var persister = new OutboxPersister(sessionFactory) { EndpointName = "TestEndpoint" };
            persister.EndpointName = "TestEndpoint";

            using (sessionFactory.Session)
            {
                persister.Store("MySpecialId", Enumerable.Empty<TransportOperation>());
                Assert.Throws<NonUniqueObjectException>(() => persister.Store("MySpecialId", Enumerable.Empty<TransportOperation>()));

                sessionFactory.SaveChanges();
            }
        }
コード例 #5
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);
            }
        }
コード例 #6
0
        public async Task Should_throw_if__trying_to_insert_same_messageid_concurrently()
        {
            var persister = new OutboxPersister(store, testEndpointName, CreateTestSessionOpener());

            var exception = await Catch <NonUniqueObjectException>(async() =>
            {
                using (var transaction = await persister.BeginTransaction(new ContextBag()))
                {
                    await persister.Store(new OutboxMessage("MySpecialId", new TransportOperation[0]), transaction, 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_throw_if__trying_to_insert_same_messageid_concurrently()
        {
            var persister = new OutboxPersister(store, testEndpointName);

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

            Assert.NotNull(exception);
        }
コード例 #8
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";

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

                transaction.Commit();
            }
        return(await persister.Get(messageId, null).ConfigureAwait(false));
    }
コード例 #9
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);
    }
コード例 #10
0
    async Task Store(int i, DbConnection connection, OutboxPersister persister)
    {
        var operations = new[]
        {
            new TransportOperation(
                messageId: "OperationId" + i,
                options: new Dictionary <string, string>
            {
                {
                    "OptionKey1", "OptionValue1"
                }
            },
                body: new byte[]
            {
                0x20
            },
                headers: new Dictionary <string, string>
            {
                {
                    "HeaderKey1", "HeaderValue1"
                }
            }
                )
        };
        var messageId     = "MessageId" + i;
        var outboxMessage = new OutboxMessage(messageId, operations);

        using (var transaction = connection.BeginTransaction())
        {
            await persister.Store(outboxMessage, transaction, connection).ConfigureAwait(false);

            transaction.Commit();
        }
        await persister.SetAsDispatched(messageId, null).ConfigureAwait(false);
    }
コード例 #11
0
        public void Should_update_dispatched_flag()
        {
            var id = Guid.NewGuid().ToString("N");

            var sessionFactory = new RavenSessionFactory(store);
            var persister = new OutboxPersister(sessionFactory) { DocumentStore = store, EndpointName = "TestEndpoint" };
            persister.Store(id, new List<TransportOperation>
            {
                new TransportOperation(id, new Dictionary<string, string>(), new byte[1024*5], new Dictionary<string, string>()),
            });

            sessionFactory.SaveChanges();
            sessionFactory.ReleaseSession();

            persister.SetAsDispatched(id);

            WaitForIndexing(store);

            using (var session = store.OpenSession())
            {
                var result = session.Query<OutboxRecord>().Where(o => o.MessageId == id)
                    .SingleOrDefault();

                Assert.NotNull(result);
                Assert.True(result.Dispatched);
            }
        }
コード例 #12
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);
            }
        }
コード例 #13
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");

            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(store);

            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);
            }
        }
コード例 #14
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);
            }
        }
コード例 #15
0
        public void Should_save_with_not_dispatched()
        {
            var id = Guid.NewGuid().ToString("N");
            var sessionFactory = new RavenSessionFactory(store);

            var persister = new OutboxPersister(sessionFactory) { DocumentStore = store, EndpointName = "TestEndpoint" };
            persister.Store(id, new List<TransportOperation>
            {
                new TransportOperation(id, new Dictionary<string, string>(), new byte[1024*5], new Dictionary<string, string>()),
            });

            sessionFactory.SaveChanges();
            sessionFactory.ReleaseSession();

            OutboxMessage result;
            persister.TryGet(id, out result);

            var operation = result.TransportOperations.Single();

            Assert.AreEqual(id, operation.MessageId);
        }
コード例 #16
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));
    }
コード例 #17
0
    async Task <Tuple <OutboxMessage, OutboxMessage> > StoreDispatchAndGetAsync(OutboxPersister persister)
    {
        var operations = new List <TransportOperation>
        {
            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";

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

                transaction.Commit();
            }
        var beforeDispatch = await persister.Get(messageId, null).ConfigureAwait(false);

        await persister.SetAsDispatched(messageId, null).ConfigureAwait(false);

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

        return(Tuple.Create(beforeDispatch, afterDispatch));
    }
コード例 #18
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);
        }
コード例 #19
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);
        }
コード例 #20
0
        public async Task Should_save_with_not_dispatched()
        {
            var persister = new OutboxPersister(store, testEndpointName);

            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);
        }
コード例 #21
0
    public async Task It_stores_messages_in_tables_based_on_sequence_number()
    {
        using (var conn = CreateConnection())
        {
            await conn.OpenAsync().ConfigureAwait(false);

            using (var trans = conn.BeginTransaction())
            {
                for (var i = 1; i <= 6; i++)
                {
                    var operation = CreateMessages(Guid.NewGuid().ToString());
                    await persister.Store(operation, () => {}, conn, trans).ConfigureAwait(false);
                }

                trans.Commit();
            }
        }
    }
コード例 #22
0
        public async Task Should_update_dispatched_flag()
        {
            var persister = new OutboxPersister(store, testEndpointName);

            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(store);

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

                Assert.NotNull(result);
                Assert.True(result.Dispatched);
            }
        }