Пример #1
0
        static void Main()
        {
            var ordersView = new MongoDbViewManager<OrdersView>(MongoConnectionString);
            var orderedItemsView = new MongoDbViewManager<OrderedItemsView>(MongoConnectionString);
            var regrettableItemsView = new MongoDbViewManager<RegrettableItemsView>(MongoConnectionString);

            var commandProcessor = CommandProcessor.With()
                .Logging(l => l.UseConsole())
                .EventStore(e => e.UseSqlServer(SqlConnectionString, "Events"))
                .EventDispatcher(e => e.UseViewManagerEventDispatcher(ordersView, orderedItemsView, regrettableItemsView))
                .Create();

            using (commandProcessor)
            {
                const string orderId = "order/5";

                commandProcessor.ProcessCommand(new CreateNewOrder(orderId));
                commandProcessor.ProcessCommand(new AddItem(orderId, "Beer", 6));
                commandProcessor.ProcessCommand(new AddItem(orderId, "Nuts", 3));
                commandProcessor.ProcessCommand(new RemoveItem(orderId, "Beer", 6));
                commandProcessor.ProcessCommand(new AddShipmentAddress(orderId, new Address("Torsmark", "4", "8700", "Horsens")));

                Console.WriteLine("Press ENTER to quit");
                Console.ReadLine();
            }
        }
Пример #2
0
        public void AutomaticallyReplaysEventsIfViewIsPurged(int numberOfCommands)
        {
            var allPotatoesView = new MongoDbViewManager <AllPotatoesView>(_mongoDatabase);

            _dispatcher.AddViewManager(allPotatoesView);

            Console.WriteLine("Processing {0} commands....", numberOfCommands);
            Enumerable.Range(0, numberOfCommands - 1)
            .ToList()
            .ForEach(i => _commandProcessor.ProcessCommand(new BitePotato("someid1", .01m)));

            var lastResult = _commandProcessor.ProcessCommand(new BitePotato("someid2", .01m));

            Console.WriteLine("Waiting until {0} has been dispatched to the view...", lastResult.GetNewPosition());
            allPotatoesView.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(2)).Wait();

            var viewOnFirstLoad = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId());

            Assert.That(viewOnFirstLoad, Is.Not.Null);

            Console.WriteLine("Purging the view!");
            allPotatoesView.Purge();

            Console.WriteLine("Waiting until {0} has been dispatched to the view...", lastResult.GetNewPosition());
            allPotatoesView.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(4)).Wait();

            var viewOnNextLoad = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId());

            Assert.That(viewOnNextLoad, Is.Not.Null);

            Assert.That(viewOnNextLoad.LastGlobalSequenceNumber, Is.EqualTo(viewOnFirstLoad.LastGlobalSequenceNumber));
        }
        public void AutomaticallyReplaysEventsIfViewIsPurged(int numberOfCommands)
        {
            var allPotatoesView = new MongoDbViewManager<AllPotatoesView>(_mongoDatabase);
            _dispatcher.AddViewManager(allPotatoesView);

            Console.WriteLine("Processing {0} commands....", numberOfCommands);
            Enumerable.Range(0, numberOfCommands - 1)
                .ToList()
                .ForEach(i => _commandProcessor.ProcessCommand(new BitePotato("someid1", .01m)));

            var lastResult = _commandProcessor.ProcessCommand(new BitePotato("someid2", .01m));

            Console.WriteLine("Waiting until {0} has been dispatched to the view...", lastResult.GetNewPosition());
            allPotatoesView.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(2)).Wait();

            var viewOnFirstLoad = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId());
            Assert.That(viewOnFirstLoad, Is.Not.Null);

            Console.WriteLine("Purging the view!");
            allPotatoesView.Purge();

            Console.WriteLine("Waiting until {0} has been dispatched to the view...", lastResult.GetNewPosition());
            allPotatoesView.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(4)).Wait();

            var viewOnNextLoad = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId());
            Assert.That(viewOnNextLoad, Is.Not.Null);

            Assert.That(viewOnNextLoad.LastGlobalSequenceNumber, Is.EqualTo(viewOnFirstLoad.LastGlobalSequenceNumber));
        }
Пример #4
0
        public void BasicDispatchOfSomeEvents()
        {
            var allPotatoesView            = new MongoDbViewManager <AllPotatoesView>(_mongoDatabase);
            var potatoTimeToBeConsumedView = new MongoDbViewManager <PotatoTimeToBeConsumedView>(_mongoDatabase);

            _dispatcher.AddViewManager(allPotatoesView);
            _dispatcher.AddViewManager(potatoTimeToBeConsumedView);

            // act
            var firstPointInTime = new DateTime(1979, 3, 1, 12, 0, 0, DateTimeKind.Utc);

            TimeMachine.FixCurrentTimeTo(firstPointInTime);
            _commandProcessor.ProcessCommand(new BitePotato("potato1", 0.5m));
            _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.3m));
            _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.3m));
            _commandProcessor.ProcessCommand(new BitePotato("potato3", 0.3m));

            var nextPointInTime = new DateTime(1981, 6, 9, 12, 0, 0, DateTimeKind.Utc);

            TimeMachine.FixCurrentTimeTo(nextPointInTime);
            _commandProcessor.ProcessCommand(new BitePotato("potato1", 0.5m));
            _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.5m));

            var lastPointInTime = new DateTime(1981, 6, 9, 12, 0, 0, DateTimeKind.Utc);

            _commandProcessor.ProcessCommand(new BitePotato("potato3", 0.8m));

            Thread.Sleep(1000);

            // assert
            var allPotatoes = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId());

            Assert.That(allPotatoes, Is.Not.Null);

            var potato1View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato1"));
            var potato2View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato2"));
            var potato3View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato3"));

            Assert.That(potato1View, Is.Not.Null);
            Assert.That(potato2View, Is.Not.Null);
            Assert.That(potato3View, Is.Not.Null);

            Assert.That(allPotatoes.NamesOfPotatoes.Count, Is.EqualTo(3));
            Assert.That(allPotatoes.NamesOfPotatoes["potato1"], Is.EqualTo("Jeff"));
            Assert.That(allPotatoes.NamesOfPotatoes["potato2"], Is.EqualTo("Bunny"));
            Assert.That(allPotatoes.NamesOfPotatoes["potato3"], Is.EqualTo("Walter"));

            Assert.That(potato1View.Name, Is.EqualTo("Jeff"));
            Assert.That(potato1View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime));
            Assert.That(potato1View.TimeToBeEaten, Is.EqualTo(nextPointInTime - firstPointInTime));

            Assert.That(potato2View.Name, Is.EqualTo("Bunny"));
            Assert.That(potato2View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime));
            Assert.That(potato2View.TimeToBeEaten, Is.EqualTo(nextPointInTime - firstPointInTime));

            Assert.That(potato3View.Name, Is.EqualTo("Walter"));
            Assert.That(potato3View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime));
            Assert.That(potato3View.TimeToBeEaten, Is.EqualTo(lastPointInTime - firstPointInTime));
        }
        protected override IViewManager <TViewInstance> CreateViewManager <TViewInstance>(bool enableBatchDispatch = false)
        {
            var viewManager = new MongoDbViewManager <TViewInstance>(_database)
            {
                BatchDispatchEnabled = enableBatchDispatch
            };

            return(viewManager);
        }
        protected override void DoSetUp()
        {
            CirqusLoggerFactory.Current = new ConsoleLoggerFactory(Logger.Level.Warn);

            var mongoDatabase = MongoHelper.InitializeTestDatabase();

            var aalborgEventStore = new MongoDbEventStore(mongoDatabase, "AalborgEvents");
            var hongKongEventStore = new MongoDbEventStore(mongoDatabase, "HongKongEvents");

            CreateCommandProcessor(aalborgEventStore, aalborgEventStore);

            _hongKongViewManager = new MongoDbViewManager<CountingRootView>(mongoDatabase);
            _hongKongCommandProcessor = CreateCommandProcessor(aalborgEventStore, hongKongEventStore, _hongKongViewManager);

            var replicationDelay = TimeSpan.FromSeconds(5);

            CreateAndStartReplication(aalborgEventStore, hongKongEventStore, replicationDelay);
        }
Пример #7
0
        protected override void DoSetUp()
        {
            CirqusLoggerFactory.Current = new ConsoleLoggerFactory(Logger.Level.Warn);

            var mongoDatabase = MongoHelper.InitializeTestDatabase();

            var aalborgEventStore  = new MongoDbEventStore(mongoDatabase, "AalborgEvents");
            var hongKongEventStore = new MongoDbEventStore(mongoDatabase, "HongKongEvents");

            CreateCommandProcessor(aalborgEventStore, aalborgEventStore);

            _hongKongViewManager      = new MongoDbViewManager <CountingRootView>(mongoDatabase);
            _hongKongCommandProcessor = CreateCommandProcessor(aalborgEventStore, hongKongEventStore, _hongKongViewManager);

            var replicationDelay = TimeSpan.FromSeconds(5);

            CreateAndStartReplication(aalborgEventStore, hongKongEventStore, replicationDelay);
        }
Пример #8
0
        public void CanBlockUntilViewIsUpdated(BlockOption blockOption)
        {
            // arrange
            var slowView = new MongoDbViewManager <SlowView>(_mongoDatabase);

            _dispatcher.AddViewManager(slowView);

            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));
            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));
            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));
            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));

            var result = _commandProcessor.ProcessCommand(new BitePotato("potato1", 1));

            // act
            switch (blockOption)
            {
            case BlockOption.BlockOnViewManager:
                Console.WriteLine("Waiting for {0} on the view...", result.GetNewPosition());
                slowView.WaitUntilProcessed(result, TimeSpan.FromSeconds(2)).Wait();
                break;

            case BlockOption.BlockOnEventDispatcher:
                Console.WriteLine("Waiting for {0} on the dispatcher...", result.GetNewPosition());
                _dispatcher.WaitUntilProcessed <SlowView>(result, TimeSpan.FromSeconds(2)).Wait();
                break;
            }

            // assert
            var instance = slowView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato1"));

            if (blockOption == BlockOption.NoBlock)
            {
                Assert.That(instance, Is.Null);
                Console.WriteLine("View instance was null, just as expected");
            }
            else
            {
                Assert.That(instance, Is.Not.Null);
                Console.WriteLine("View instance was properly updated, just as expected");
            }
        }
Пример #9
0
        public async Task YeyItWorks()
        {
            CirqusLoggerFactory.Current = new ConsoleLoggerFactory();

            var mongoDatabase = MongoHelper.InitializeTestDatabase();

            var firstView  = new MongoDbViewManager <HeyCounter>(mongoDatabase);
            var secondView = new MongoDbViewManager <WordCounter>(mongoDatabase);

            /*         ________.......------=====^^!^^=====------.......________             */
            var dependentView = new MongoDbViewManager <HeyPercentageCalculator>(mongoDatabase);
            /*         ________.......------=====^^!^^=====------.......________             */

            var waitHandle        = new ViewManagerWaitHandle();
            var specialWaitHandle = new ViewManagerWaitHandle();

            //Brett
            var commandProcessor = CreateCommandProcessor(config => config
                                                          .EventStore(e => e.UseInMemoryEventStore())
                                                          .EventDispatcher(e => {
                e.UseViewManagerEventDispatcher(firstView)
                .WithWaitHandle(waitHandle);

                e.UseViewManagerEventDispatcher(secondView)
                .WithWaitHandle(waitHandle);

                e.UseDependentViewManagerEventDispatcher(dependentView)
                .WithWaitHandle(specialWaitHandle)
                .DependentOn(firstView, secondView)
                .WithViewContext(new Dictionary <string, object>
                {
                    { "heys", mongoDatabase.GetCollection <HeyCounter>(typeof(HeyCounter).Name).AsQueryable() },
                    { "words", mongoDatabase.GetCollection <WordCounter>(typeof(WordCounter).Name).AsQueryable() },
                });
            }));

            //Orig
            //var commandProcessor = CommandProcessor.With()
            //    .EventStore(e => e.UseInMemoryEventStore())
            //    .EventDispatcher(e =>
            //    {
            //        e.UseViewManagerEventDispatcher(firstView)
            //            .WithWaitHandle(waitHandle);

            //        e.UseViewManagerEventDispatcher(secondView)
            //            .WithWaitHandle(waitHandle);

            //        e.UseDependentViewManagerEventDispatcher(dependentView)
            //            .WithWaitHandle(specialWaitHandle)
            //            .DependentOn(firstView, secondView)
            //            .WithViewContext(new Dictionary<string, object>
            //            {
            //                {"heys", mongoDatabase.GetCollection<HeyCounter>(typeof (HeyCounter).Name).AsQueryable()},
            //                {"words", mongoDatabase.GetCollection<WordCounter>(typeof (WordCounter).Name).AsQueryable()},
            //            });
            //    })
            //    .Create();

            RegisterForDisposal(commandProcessor);

            //Brett
            CommandProcessingResult result = null;

            Enumerable.Range(0, 100).ToList().ForEach(i => result = commandProcessor.ProcessCommand(new DoStuff("test", "hej meddig min ven " + i)));

            //orig
            //result = Enumerable.Range(0, 100)
            //    .Select(i => commandProcessor.ProcessCommand(new DoStuff("test", "hej meddig min ven " + i)))
            //    .Last();

            await waitHandle.WaitForAll(result, TimeSpan.FromSeconds(5));

            var viewId = InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("test");

            var firstViewInstance  = firstView.Load(viewId);
            var secondViewInstance = secondView.Load(viewId);

            Assert.That(firstViewInstance.Count, Is.EqualTo(100));
            Assert.That(secondViewInstance.Count, Is.EqualTo(500));

            Console.WriteLine("Waiting for dependent views to catch up...");
            await specialWaitHandle.WaitForAll(result, TimeSpan.FromSeconds(5));

            Console.WriteLine("DOne!");

            var heyPercentageCalculator = dependentView.Load(viewId);

            Assert.That(heyPercentageCalculator.HeyPercentage, Is.EqualTo(20));
        }
        public void CanBlockUntilViewIsUpdated(BlockOption blockOption)
        {
            // arrange
            var slowView = new MongoDbViewManager<SlowView>(_mongoDatabase);
            _dispatcher.AddViewManager(slowView);

            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));
            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));
            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));
            _commandProcessor.ProcessCommand(new BitePotato("potato1", .1m));

            var result = _commandProcessor.ProcessCommand(new BitePotato("potato1", 1));

            // act
            switch (blockOption)
            {
                case BlockOption.BlockOnViewManager:
                    Console.WriteLine("Waiting for {0} on the view...", result.GetNewPosition());
                    slowView.WaitUntilProcessed(result, TimeSpan.FromSeconds(2)).Wait();
                    break;

                case BlockOption.BlockOnEventDispatcher:
                    Console.WriteLine("Waiting for {0} on the dispatcher...", result.GetNewPosition());
                    _dispatcher.WaitUntilProcessed<SlowView>(result, TimeSpan.FromSeconds(2)).Wait();
                    break;
            }

            // assert
            var instance = slowView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato1"));

            if (blockOption == BlockOption.NoBlock)
            {
                Assert.That(instance, Is.Null);
                Console.WriteLine("View instance was null, just as expected");
            }
            else
            {
                Assert.That(instance, Is.Not.Null);
                Console.WriteLine("View instance was properly updated, just as expected");
            }
        }
        public void BasicDispatchOfSomeEvents()
        {
            var allPotatoesView = new MongoDbViewManager<AllPotatoesView>(_mongoDatabase);
            var potatoTimeToBeConsumedView = new MongoDbViewManager<PotatoTimeToBeConsumedView>(_mongoDatabase);

            _dispatcher.AddViewManager(allPotatoesView);
            _dispatcher.AddViewManager(potatoTimeToBeConsumedView);

            // act
            var firstPointInTime = new DateTime(1979, 3, 1, 12, 0, 0, DateTimeKind.Utc);
            TimeMachine.FixCurrentTimeTo(firstPointInTime);
            _commandProcessor.ProcessCommand(new BitePotato("potato1", 0.5m));
            _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.3m));
            _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.3m));
            _commandProcessor.ProcessCommand(new BitePotato("potato3", 0.3m));

            var nextPointInTime = new DateTime(1981, 6, 9, 12, 0, 0, DateTimeKind.Utc);
            TimeMachine.FixCurrentTimeTo(nextPointInTime);
            _commandProcessor.ProcessCommand(new BitePotato("potato1", 0.5m));
            _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.5m));

            var lastPointInTime = new DateTime(1981, 6, 9, 12, 0, 0, DateTimeKind.Utc);
            _commandProcessor.ProcessCommand(new BitePotato("potato3", 0.8m));

            Thread.Sleep(1000);

            // assert
            var allPotatoes = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId());

            Assert.That(allPotatoes, Is.Not.Null);

            var potato1View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato1"));
            var potato2View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato2"));
            var potato3View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato3"));

            Assert.That(potato1View, Is.Not.Null);
            Assert.That(potato2View, Is.Not.Null);
            Assert.That(potato3View, Is.Not.Null);

            Assert.That(allPotatoes.NamesOfPotatoes.Count, Is.EqualTo(3));
            Assert.That(allPotatoes.NamesOfPotatoes["potato1"], Is.EqualTo("Jeff"));
            Assert.That(allPotatoes.NamesOfPotatoes["potato2"], Is.EqualTo("Bunny"));
            Assert.That(allPotatoes.NamesOfPotatoes["potato3"], Is.EqualTo("Walter"));

            Assert.That(potato1View.Name, Is.EqualTo("Jeff"));
            Assert.That(potato1View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime));
            Assert.That(potato1View.TimeToBeEaten, Is.EqualTo(nextPointInTime - firstPointInTime));

            Assert.That(potato2View.Name, Is.EqualTo("Bunny"));
            Assert.That(potato2View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime));
            Assert.That(potato2View.TimeToBeEaten, Is.EqualTo(nextPointInTime - firstPointInTime));

            Assert.That(potato3View.Name, Is.EqualTo("Walter"));
            Assert.That(potato3View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime));
            Assert.That(potato3View.TimeToBeEaten, Is.EqualTo(lastPointInTime - firstPointInTime));
        }
Пример #12
0
        protected override IViewManager <TViewInstance> CreateViewManager <TViewInstance>()
        {
            var viewManager = new MongoDbViewManager <TViewInstance>(_database);

            return(viewManager);
        }
Пример #13
0
        private static void Main()
        {
            // Cirqus configuration
            var viewManagers = new List<IViewManager>();

            var bookingViewManager =
                new EntityFrameworkViewManager<BookingView>(
                    ConfigurationManager.ConnectionStrings["CirqusDemo"].ConnectionString);
            var bookings = bookingViewManager.CreateContext().Views;

            var customerViewManager =
                new EntityFrameworkViewManager<CustomerView>(
                    ConfigurationManager.ConnectionStrings["CirqusDemo"].ConnectionString);
            var customers = customerViewManager.CreateContext().Views;

            var roomViewManager =
                new EntityFrameworkViewManager<RoomView>(
                    ConfigurationManager.ConnectionStrings["CirqusDemo"].ConnectionString);
            var rooms = roomViewManager.CreateContext().Views;

            var roomStatisticsViewManager =
                new MongoDbViewManager<RoomStatisticsView>(
                    ConfigurationManager.ConnectionStrings["CirqusMongoDemo"].ConnectionString);

            viewManagers.Add(bookingViewManager);
            viewManagers.Add(customerViewManager);
            viewManagers.Add(roomStatisticsViewManager);
            viewManagers.Add(roomViewManager);

            var processor =
                CommandProcessor.With()
            #if DEBUG
                    .Logging(l => l.UseConsole(Logger.Level.Debug))
            #endif
                    .EventStore(e => e.UseSqlServer("CirqusDemo", "Events"))
                    .EventDispatcher(conf => conf.UseViewManagerEventDispatcher(viewManagers.ToArray()))
                    //.EventDispatcher(conf => viewManagers.ForEach(vm => conf.UseViewManagerEventDispatcher(vm)))
                    .Options(opt => opt.PurgeExistingViews(true))
                    .Create();

            IBookingService bookingService = new BookingService(processor, bookings);
            IRoomService roomService = new RoomService(processor, rooms);
            ICustomerService customerService = new CustomerService(processor, customers);

            Thread.Sleep(SleepTimeout);

            // Create rooms
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var room1 = roomService.AddRoom(true, false,
                new Bathroom(new Dimensions(10, 10, 10), true, true, false, true), new Dimensions(20, 20, 20),
                new Bed(Bed.Size.King));
            PrintDebug($"Created room with ID {room1}.");

            var room2 = roomService.AddRoom(true, false,
                new Bathroom(new Dimensions(9, 9, 9), true, false, true, true), new Dimensions(15, 15, 15),
                new Bed(Bed.Size.Queen));
            PrintDebug($"Created room with ID {room2}.");

            var room3 = roomService.AddRoom(true, false,
                new Bathroom(new Dimensions(8, 8, 8), true, true, false, true), new Dimensions(10, 10, 10),
                new Bed(Bed.Size.Full));
            PrintDebug($"Created room with ID {room3}.");

            var room4 = roomService.AddRoom(true, true,
                new Bathroom(new Dimensions(7, 7, 7), false, true, false, true), new Dimensions(5, 5, 5),
                new Bed(Bed.Size.Single));
            PrintDebug($"Created room with ID {room4}.");

            Thread.Sleep(SleepTimeout);

            // Get all rooms
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var allRooms = roomService.GetAllRooms();
            PrintDebug($"Found {allRooms.Count} rooms!");
            foreach (var room in allRooms)
            {
                PrintDebug($"Found room: {room}");
            }

            // Create customers
            Debugger.Break();

            var customer1 = customerService.AddCustomer("Jan Janssens", "*****@*****.**",
                new Address("Straat Zonder Naam 1", null, "1000", "Brussels", Address.ECountry.Belgium));
            PrintDebug($"Created customer with ID {customer1}.");

            var customer2 = customerService.AddCustomer("Peter Peeters", "*****@*****.**",
                new Address("Straat Zonder Naam 2", null, "2000", "Antwerp", Address.ECountry.Belgium));
            PrintDebug($"Created customer with ID {customer2}.");

            Thread.Sleep(SleepTimeout);

            // Get all customers
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var allCustomers = customerService.GetAllCustomers();
            PrintDebug($"Found {allCustomers.Count} customers!");
            foreach (var customer in allCustomers)
            {
                PrintDebug($"Found customer: {customer}");
            }

            // Create booking
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var booking1 = bookingService.AddBooking(DateTimeOffset.UtcNow.AddDays(7), DateTimeOffset.UtcNow.AddDays(14),
                true, customer1, room1, room2);
            PrintDebug($"Created booking with ID {booking1}.");

            Thread.Sleep(SleepTimeout);

            // Retrieve booking
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var booking1FromService = bookingService.GetBookingById(booking1);
            PrintDebug($"Found booking: {booking1FromService}");

            // Remove booking
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var removedBooking1 = bookingService.RemoveBooking(booking1);
            PrintDebug($"Booking removed? {removedBooking1}");

            Thread.Sleep(SleepTimeout);

            // Retrieve bookings
            #if DEBUG
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
            #endif

            var allBookings = bookingService.GetAllBookings();
            PrintDebug($"Found {allBookings.Count} bookings!");

            System.Console.ReadKey();
            processor.Dispose();
        }