public async Task OnPoll_WhenPendingNotificationListIsNotEmpty_ReturnsTrue(
            [Frozen] PollingJobStub jobStub,
            PendingNotificationsChaser chaser)
        {
            var pollResult = await jobStub.Poll();

            Assert.True(pollResult);
        }
        public async Task OnPoll_WhenLockWasNotAcquired_ReturnsFalse(
            [Frozen] PollingJobStub jobStub,
            PendingNotificationsChaser chaser)
        {
            var pollResult = await jobStub.Poll();

            Assert.False(pollResult);
        }
        public async Task OnPoll_WhenLockWasAcquired_LoadsPendingNotifications(
            [Frozen] PollingJobStub jobStub,
            [Frozen] Mock <IPendingNotifications> pendingNotificationsMock,
            PendingNotificationsChaser chaser)
        {
            await jobStub.Poll();

            pendingNotificationsMock.Verify(self => self.LoadAsync());
        }
        public async Task OnPoll_WhenPendingNotificationListIsNotEmpty_ReleasesAcquiredLock(
            [Frozen] PollingJobStub jobStub,
            [Frozen] Mock <ICloudBlockBlob> blobLock,
            PendingNotificationsChaser chaser)
        {
            await jobStub.Poll();

            blobLock.Verify(self => self.ReleaseLeaseAsync(It.IsAny <string>()));
        }
        public async Task OnPoll_WhenPendingNotificationListIsNotEmpty_SendNotificationToTheHub(
            [Frozen] PollingJobStub jobStub,
            [Frozen] Mock <INotificationHub> hubMock,
            [Frozen] EventStreamUpdated[] pendingNotifications,
            PendingNotificationsChaser chaser)
        {
            await jobStub.Poll();

            foreach (var pendingNotification in pendingNotifications)
            {
                hubMock.Verify(self => self.NotifyAsync(pendingNotification));
            }
        }
        public async Task OnPoll_WhenExceptionHappensOnProcessing_ReturnsFalse(
            [Frozen] PollingJobStub jobStub,
            [Frozen] Mock <IPendingNotifications> pendingNotificationsMock,
            PendingNotificationsChaser chaser)
        {
            pendingNotificationsMock
            .Setup(self => self.DeleteAsync(It.IsAny <string>(), It.IsAny <StreamVersion[]>()))
            .Throws <Exception>();

            var pollResult = await jobStub.Poll();

            Assert.False(pollResult);
        }
        public async Task OnPoll_WhenExceptionHappensOnProcessing_ReleasesAcquiredLock(
            [Frozen] PollingJobStub jobStub,
            [Frozen] Mock <IPendingNotifications> pendingNotificationsMock,
            [Frozen] Mock <ICloudBlockBlob> blobLock,
            PendingNotificationsChaser chaser)
        {
            pendingNotificationsMock
            .Setup(self => self.DeleteAsync(It.IsAny <string>(), It.IsAny <StreamVersion>()))
            .Throws <Exception>();

            await jobStub.Poll();

            blobLock.Verify(self => self.ReleaseLeaseAsync(It.IsAny <string>()));
        }
        public async Task OnPoll_WhenPendingNotificationListIsNotEmpty_DeletesNotification(
            [Frozen] PollingJobStub jobStub,
            [Frozen] Mock <IPendingNotifications> pendingNotificationsMock,
            [Frozen] EventStreamUpdated[] pendingNotifications,
            PendingNotificationsChaser chaser)
        {
            await jobStub.Poll();


            foreach (var pendingNotification in pendingNotifications)
            {
                pendingNotificationsMock.Verify(self => self.DeleteAsync(
                                                    pendingNotification.StreamName,
                                                    It.Is <StreamVersion[]>(versions => versions.Contains(pendingNotification.FromVersion))));
            }
        }
Exemple #9
0
        public IEventStoreConnection Build()
        {
            if (m_configuration == null)
            {
                m_configuration = new EventStoreConnectionConfiguration();
                m_configure(m_configuration);

                m_configuration.AssertConfigurationCompleted();
                m_factory = new StorageFactory();
            }

            var connectivityState = new EventStoreConnectionState();

            var journalTable = new EventJournalTable(m_factory.CreateTable(
                                                         m_configuration.StorageConnectionString,
                                                         m_configuration.JournalTableName));

            var deploymentTable = m_factory.CreateTable(
                m_configuration.StorageConnectionString,
                m_configuration.EventStoreDeploymentTableName);

            var sessionFactory = new EventStreamConsumingSessionFactory(
                m_factory.CreateBlobContainer(
                    m_configuration.StorageConnectionString,
                    m_configuration.StreamConsumerSessionsBlobContainerName));

            var pipelineFactory = new EventMutationPipelineFactory(
                m_configuration.IncomingMessageMutators,
                m_configuration.OutgoingMessageMutators);

            var queues = Enumerable
                         .Range(0, m_configuration.NotificationQueuePartitionCount)
                         .Select(index => m_factory.CreateQueue(
                                     m_configuration.StorageConnectionString,
                                     m_configuration.NotificationQueueName + "-" + index.ToString("D3")))
                         .ToArray();

            var eventJournal = new EventJournal(journalTable);

            var consumersRegistry = new EventStreamConsumers(deploymentTable);
            var consumersService  = new ConsumersService(consumersRegistry, eventJournal);

            var notificationHub = new NotificationHub(
                new PollingJob("NotificationHubPollingJob", new PollingTimeout()),
                new NotificationsChannel(queues, new NotificationFormatter()),
                new ReceivedNotificationProcessor());

            var pendingNotificationTable          = m_factory.CreateTable(m_configuration.StorageConnectionString, m_configuration.PendingNotificationsTableName);
            var pendingNotifications              = new PendingNotifications(pendingNotificationTable);
            var pendingNotificationsChaserTimeout = new PollingTimeout(
                TimeSpan.FromMinutes(Constants.Settings.PENDING_NOTIFICATIONS_CHASER_INITIAL_TIMEOUT_IN_MINUTES),
                Constants.Settings.PENDING_NOTIFICATIONS_CHASER_TIMEOUT_MULTIPLIER,
                Constants.Settings.PENDING_NOTIFICATIONS_CHASER_TIMEOUT_INCREASING_THRESHOLD,
                TimeSpan.FromMinutes(Constants.Settings.PENDING_NOTIFICATIONS_CHASER_MAX_TIMEOUT_IN_MINUTES));

            var pendingNotificationsChaser = new PendingNotificationsChaser(
                pendingNotifications,
                notificationHub,
                new PollingJob("PendingNotificationsChaserPollingJob", pendingNotificationsChaserTimeout),
                m_factory.CreateBlobContainer(
                    m_configuration.StorageConnectionString,
                    m_configuration.PendingNotificationsChaserExclusiveAccessLockBlobContainerName).CreateBlockBlob(
                    m_configuration.PendingNotificationsChaserExclusiveAccessLockBlobName));

            connectivityState.ConnectionCreated += (sender, args) =>
            {
                if (m_configuration.BackgroundProcessingEnabled)
                {
                    foreach (var notificationListener in m_configuration.NotificationListeners)
                    {
                        notificationHub.Subscribe(notificationListener);
                    }

                    notificationHub.StartNotificationProcessing(args.Connection);
                    pendingNotificationsChaser.Start();
                }
            };

            connectivityState.ConnectionClosing += (sender, args) =>
            {
                if (m_configuration.BackgroundProcessingEnabled)
                {
                    notificationHub.StopNotificationProcessing();
                    pendingNotificationsChaser.Stop();
                }
            };

            connectivityState.ConnectionClosed += (sender, args) =>
            {
                if (m_configuration.BackgroundProcessingEnabled)
                {
                    foreach (var notificationListener in m_configuration.NotificationListeners)
                    {
                        notificationHub.Unsubscribe(notificationListener);
                    }
                }
            };

            return(new EventStoreConnection(
                       connectivityState,
                       eventJournal,
                       notificationHub,
                       pendingNotifications,
                       consumersRegistry,
                       sessionFactory,
                       pipelineFactory,
                       consumersService));
        }