public virtual void Save_ValidEvent_EventCanBeRetreived()
        {
            // Arrange
            var correlationIdHelper = new CorrelationIdHelper(new ContextItemCollectionFactory());

            correlationIdHelper.SetCorrelationId(Guid.NewGuid());
            var logger     = new ConsoleLogger(new LoggerSettingsConfigurationSection(), correlationIdHelper);
            var eventStore = CreateEventStore(new DefaultEventBuilder <Guid>(), new EventDeserialiser <Guid>(), logger, new TableStorageEventStoreConnectionStringFactory(new ConfigurationManager(), logger));

            var event1 = new TestEvent
            {
                Rsn           = Guid.NewGuid(),
                Id            = Guid.NewGuid(),
                CorrelationId = correlationIdHelper.GetCorrelationId(),
                Frameworks    = new List <string> {
                    "Test 1"
                },
                TimeStamp = DateTimeOffset.UtcNow
            };
            var event2 = new TestEvent
            {
                Rsn           = Guid.NewGuid(),
                Id            = Guid.NewGuid(),
                CorrelationId = correlationIdHelper.GetCorrelationId(),
                Frameworks    = new List <string> {
                    "Test 2"
                },
                TimeStamp = DateTimeOffset.UtcNow
            };

            // Act
            eventStore.Save <TestEvent>(event1);
            eventStore.Save <TestEvent>(event2);

            // Assert
            var timer = new Stopwatch();
            IList <IEvent <Guid> > events = eventStore.Get <TestEvent>(event1.Id).ToList();

            timer.Stop();
            Console.WriteLine("Load one operation took {0}", timer.Elapsed);
            Assert.AreEqual(1, events.Count);
            Assert.AreEqual(event1.Id, events.Single().Id);
            Assert.AreEqual(event1.Frameworks.Single(), events.Single().Frameworks.Single());

            timer.Restart();
            events = eventStore.Get <TestEvent>(event2.Id).ToList();
            timer.Stop();
            Console.WriteLine("Load one operation took {0}", timer.Elapsed);
            Assert.AreEqual(1, events.Count);
            Assert.AreEqual(event2.Id, events.Single().Id);
            Assert.AreEqual(event2.Frameworks.Single(), events.Single().Frameworks.Single());

            timer.Restart();
            IList <EventData> correlatedEvents = eventStore.Get(event1.CorrelationId).ToList();

            timer.Stop();
            Console.WriteLine("Load several correlated operation took {0}", timer.Elapsed);
            Assert.AreEqual(2, correlatedEvents.Count);
        }
        public void Send <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            ICommandValidator <TAuthenticationToken, TCommand> commandValidator = null;

            try
            {
                commandValidator = DependencyResolver.Resolve <ICommandValidator <TAuthenticationToken, TCommand> >();
            }
            catch (Exception exception)
            {
                Logger.LogDebug("Locating an ICommandValidator failed.", string.Format("{0}\\Handle({1})", GetType().FullName, command.GetType().FullName), exception);
            }

            if (commandValidator != null && !commandValidator.IsCommandValid(command))
            {
                Logger.LogInfo("The provided command is not valid.", string.Format("{0}\\Handle({1})", GetType().FullName, command.GetType().FullName));
                return;
            }

            if (command.AuthenticationToken == null)
            {
                command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            command.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            ServiceBusPublisher.Send(new BrokeredMessage(MessageSerialiser.SerialiseCommand(command)));
            Logger.LogInfo(string.Format("A command was sent of type {0}.", command.GetType().FullName));
        }
Exemple #3
0
        protected virtual void StartSettingsChecking()
        {
            Guid currentCorrelationId;

            try
            {
                currentCorrelationId = CorrelationIdHelper.GetCorrelationId();
            }
            catch (Exception)
            {
                currentCorrelationId = Guid.NewGuid();
            }
            Task.Factory.StartNew(() =>
            {
                // New thread remember
                CorrelationIdHelper.SetCorrelationId(currentCorrelationId);

                SpinWait.SpinUntil(ValidateSettingsHaveChanged, sleepInMilliseconds: 1000);

                Logger.LogInfo("Connecting string settings for the Azure Service Bus changed and will now refresh.");

                // Update the connection string and trigger a restart;
                if (ValidateSettingsHaveChanged())
                {
                    TriggerSettingsChecking();
                }
            });
        }
        public virtual void Save_ValidProjectionView_ProjectionViewCanBeRetreived()
        {
            // Arrange
            var correlationIdHelper = new CorrelationIdHelper(new ThreadedContextItemCollectionFactory());

            correlationIdHelper.SetCorrelationId(Guid.NewGuid());
            var logger    = new ConsoleLogger(new LoggerSettingsConfigurationSection(), correlationIdHelper);
            var dataStore = new BlobStorageDataStore <TestEvent>(logger, new BlobStorageDataStoreConnectionStringFactory(new ConfigurationManager(), logger));

            var event1 = new TestEvent
            {
                Rsn           = Guid.NewGuid(),
                Id            = Guid.NewGuid(),
                CorrelationId = correlationIdHelper.GetCorrelationId(),
                Frameworks    = new List <string> {
                    "Test 1"
                },
                TimeStamp = DateTimeOffset.UtcNow
            };

            // Act
            dataStore.Add(event1);

            // Assert
            var timer = new Stopwatch();

            timer.Start();
            TestEvent view = dataStore.GetByName(event1.Rsn);

            timer.Stop();
            Console.WriteLine("Load operation took {0}", timer.Elapsed);
            Assert.IsNotNull(view);
            Assert.AreEqual(event1.Id, view.Id);
        }
Exemple #5
0
        public virtual void Add_ValidProjectionView_ProjectionViewCanBeRetreived()
        {
            // Arrange
            var correlationIdHelper = new CorrelationIdHelper(new ContextItemCollectionFactory());

            correlationIdHelper.SetCorrelationId(Guid.NewGuid());
            var logger = new ConsoleLogger(new LoggerSettingsConfigurationSection(), correlationIdHelper);
            TableStorageDataStore <TestEvent> dataStore = CreateDataStore <TestEvent>(logger, new ConfigurationManager());

            var event1 = new TestEvent
            {
                Rsn           = Guid.NewGuid(),
                Id            = Guid.NewGuid(),
                CorrelationId = correlationIdHelper.GetCorrelationId(),
                Frameworks    = new List <string> {
                    "Test 1"
                },
                TimeStamp = DateTimeOffset.UtcNow
            };

            // Act
            dataStore.Add(event1);

            // Assert
            var timer      = new Stopwatch();
            var repository = new TableStorageRepository <TestQueryStrategy, TestQueryBuilder <TestEvent>, TestEvent>(() => dataStore, null);

            timer.Start();
            TestEvent view = repository.Load(event1.Rsn);

            timer.Stop();
            Console.WriteLine("Load operation took {0}", timer.Elapsed);
            Assert.IsNotNull(view);
            Assert.AreEqual(event1.Id, view.Id);
        }
Exemple #6
0
        public virtual void Publish <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            DateTimeOffset startedAt      = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch  = Stopwatch.StartNew();
            bool           wasSuccessfull = false;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/Servicebus" }
            };
            string telemetryName    = string.Format("{0}/{1}", command.GetType().FullName, command.Id);
            var    telemeteredEvent = command as ITelemeteredMessage;

            if (telemeteredEvent != null)
            {
                telemetryName = telemeteredEvent.TelemetryName;
            }
            telemetryName = string.Format("Command/{0}", telemetryName);

            try
            {
                if (!AzureBusHelper.PrepareAndValidateCommand(command, "Azure-ServiceBus"))
                {
                    return;
                }

                try
                {
                    var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseCommand(command))
                    {
                        CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                    };
                    brokeredMessage.Properties.Add("Type", command.GetType().FullName);
                    PrivateServiceBusPublisher.Send(brokeredMessage);
                }
                catch (QuotaExceededException exception)
                {
                    Logger.LogError("The size of the command being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Command", command }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Command", command }
                    });
                    throw;
                }

                Logger.LogInfo(string.Format("A command was sent of type {0}.", command.GetType().FullName));
                wasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency(telemetryName, telemetryName, startedAt, mainStopWatch.Elapsed, wasSuccessfull, telemetryProperties);
            }
        }
 /// <summary>
 /// Create a <see cref="IServiceRequest{TAuthenticationToken}"/> setting header information.
 /// </summary>
 protected virtual IServiceRequest <TSingleSignOnToken> CreateRequest <TSingleSignOnToken>()
 {
     return(new ServiceRequest <TSingleSignOnToken>
     {
         AuthenticationToken = CreateAuthenticationToken <TSingleSignOnToken>(),
         CorrelationId = CorrelationIdHelper.GetCorrelationId()
     });
 }
Exemple #8
0
 protected virtual void PrepareCommand <TCommand>(TCommand command)
     where TCommand : ICommand <TAuthenticationToken>
 {
     if (command.AuthenticationToken == null)
     {
         command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
     }
     command.CorrelationId = CorrelationIdHelper.GetCorrelationId();
 }
Exemple #9
0
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            Type eventType = @event.GetType();

            if (@event.Frameworks != null && @event.Frameworks.Contains("Built-In"))
            {
                Logger.LogInfo("The provided event has already been processed by the Built-In bus.", string.Format("{0}\\PrepareAndValidateEvent({1})", GetType().FullName, eventType.FullName));
                return;
            }

            if (@event.AuthenticationToken == null || @event.AuthenticationToken.Equals(default(TAuthenticationToken)))
            {
                @event.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            @event.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            if (string.IsNullOrWhiteSpace(@event.OriginatingFramework))
            {
                @event.TimeStamp            = DateTimeOffset.UtcNow;
                @event.OriginatingFramework = "Built-In";
            }

            var frameworks = new List <string>();

            if (@event.Frameworks != null)
            {
                frameworks.AddRange(@event.Frameworks);
            }
            frameworks.Add("Built-In");
            @event.Frameworks = frameworks;

            bool isRequired;

            if (!ConfigurationManager.TryGetSetting(string.Format("{0}.IsRequired", eventType.FullName), out isRequired))
            {
                isRequired = true;
            }

            IEnumerable <Action <IMessage> > handlers = Routes.GetHandlers(@event, isRequired).Select(x => x.Delegate).ToList();

            // This check doesn't require an isRequired check as there will be an exception raised above and handled below.
            if (!handlers.Any())
            {
                Logger.LogDebug(string.Format("An event handler for '{0}' is not required.", eventType.FullName));
            }

            foreach (Action <IMessage> handler in handlers)
            {
                IList <IEvent <TAuthenticationToken> > events;
                if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                {
                    events.Add(@event);
                }
                handler(@event);
            }
        }
Exemple #10
0
 /// <summary>
 /// Create a <see cref="IServiceRequestWithData{TAuthenticationToken,TData}"/> setting header information.
 /// If <paramref name="createParameterDelegate"/> is not null, it is used to populate <see cref="IServiceRequestWithData{TAuthenticationToken,TData}.Data"/> otherwise <see cref="CreateParameter{TParameters}"/> is used.
 /// </summary>
 protected virtual IServiceRequestWithData <TSingleSignOnToken, TParameters> CreateRequestWithData <TSingleSignOnToken, TParameters>(Func <TParameters> createParameterDelegate = null)
     where TParameters : new()
 {
     return(new ServiceRequestWithData <TSingleSignOnToken, TParameters>
     {
         AuthenticationToken = CreateAuthenticationToken <TSingleSignOnToken>(),
         CorrelationId = CorrelationIdHelper.GetCorrelationId(),
         Data = createParameterDelegate == null?CreateParameter <TParameters>() : createParameterDelegate()
     });
 }
Exemple #11
0
        public virtual void Send <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            Type commandType = command.GetType();

            switch (command.Framework)
            {
            case FrameworkType.Akka:
                Logger.LogInfo(string.Format("A command arrived of the type '{0}' but was marked as coming from the '{1}' framework, so it was dropped.", commandType.FullName, command.Framework));
                return;
            }

            ICommandValidator <TAuthenticationToken, TCommand> commandValidator = null;

            try
            {
                commandValidator = DependencyResolver.Resolve <ICommandValidator <TAuthenticationToken, TCommand> >();
            }
            catch (Exception exception)
            {
                Logger.LogDebug("Locating an ICommandValidator failed.", string.Format("{0}\\Handle({1})", GetType().FullName, commandType.FullName), exception);
            }

            if (commandValidator != null && !commandValidator.IsCommandValid(command))
            {
                Logger.LogInfo("The provided command is not valid.", string.Format("{0}\\Handle({1})", GetType().FullName, commandType.FullName));
                return;
            }

            if (command.AuthenticationToken == null)
            {
                command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            command.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            bool isRequired;

            if (!ConfigurationManager.TryGetSetting(string.Format("{0}.IsRequired", commandType.FullName), out isRequired))
            {
                isRequired = true;
            }

            RouteHandlerDelegate commandHandler = Routes.GetSingleHandler(command, isRequired);

            // This check doesn't require an isRequired check as there will be an exception raised above and handled below.
            if (commandHandler == null)
            {
                Logger.LogDebug(string.Format("The command handler for '{0}' is not required.", commandType.FullName));
                return;
            }

            Action <IMessage> handler = commandHandler.Delegate;

            handler(command);
        }
        /// <summary>
        /// Publishes the provided <paramref name="event"/> on the event bus.
        /// </summary>
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            // We only set these two properties as they are not going to be available across the thread/task
            if (@event.AuthenticationToken == null || @event.AuthenticationToken.Equals(default(TAuthenticationToken)))
            {
                @event.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            @event.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            bool result = EventHandlerResolver.Ask <bool>(@event).Result;
        }
Exemple #13
0
        public virtual void Publish <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            // We only set these two properties as they are not going to be available across the thread/task
            if (command.AuthenticationToken == null || command.AuthenticationToken.Equals(default(TAuthenticationToken)))
            {
                command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            command.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            bool result = CommandHandlerResolver.Ask <bool>(command).Result;
        }
Exemple #14
0
        /// <summary>
        /// Sends the provided <paramref name="command"></paramref> and waits for an event of <typeparamref name="TEvent"/> or exits if the specified timeout is expired.
        /// </summary>
        /// <param name="command">The <typeparamref name="TCommand"/> to send.</param>
        /// <param name="condition">A delegate to be executed over and over until it returns the <typeparamref name="TEvent"/> that is desired, return null to keep trying.</param>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="F:System.Threading.Timeout.Infinite"/> (-1) to wait indefinitely.</param>
        /// <param name="eventReceiver">If provided, is the <see cref="IEventReceiver{TAuthenticationToken}" /> that the event is expected to be returned on.</param>
        public virtual TEvent SendAndWait <TCommand, TEvent>(TCommand command, Func <IEnumerable <IEvent <TAuthenticationToken> >, TEvent> condition, int millisecondsTimeout,
                                                             IEventReceiver <TAuthenticationToken> eventReceiver = null) where TCommand : ICommand <TAuthenticationToken>
        {
            if (eventReceiver != null)
            {
                throw new NotSupportedException("Specifying a different event receiver is not yet supported.");
            }
            if (!AzureBusHelper.PrepareAndValidateCommand(command, "Azure-ServiceBus"))
            {
                return((TEvent)(object)null);
            }

            TEvent result = (TEvent)(object)null;

            EventWaits.Add(command.CorrelationId, new List <IEvent <TAuthenticationToken> >());

            try
            {
                var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseCommand(command))
                {
                    CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                };
                brokeredMessage.Properties.Add("Type", command.GetType().FullName);
                PrivateServiceBusPublisher.Send(brokeredMessage);
            }
            catch (QuotaExceededException exception)
            {
                Logger.LogError("The size of the command being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                    { "Command", command }
                });
                throw;
            }
            catch (Exception exception)
            {
                Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                    { "Command", command }
                });
                throw;
            }
            Logger.LogInfo(string.Format("A command was sent of type {0}.", command.GetType().FullName));

            SpinWait.SpinUntil(() =>
            {
                IList <IEvent <TAuthenticationToken> > events = EventWaits[command.CorrelationId];

                result = condition(events);

                return(result != null);
            }, millisecondsTimeout, sleepInMilliseconds: 1000);

            return(result);
        }
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            if (@event.AuthenticationToken == null)
            {
                @event.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            @event.CorrelationId = CorrelationIdHelper.GetCorrelationId();
            @event.TimeStamp     = DateTimeOffset.UtcNow;

            ServiceBusPublisher.Send(new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event)));
            Logger.LogInfo(string.Format("An event was published with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
        }
        public void Add_ValidProjectionView_ProjectionViewCanBeRetreived()
        {
            // Arrange
            var correlationIdHelper = new CorrelationIdHelper(new ThreadedContextItemCollectionFactory());

            correlationIdHelper.SetCorrelationId(Guid.NewGuid());
            var logger = new ConsoleLogger(new LoggerSettings(), correlationIdHelper);

            var connectionStringFactory = new TestMongoDataStoreConnectionStringFactory();

            TestMongoDataStoreConnectionStringFactory.DatabaseName = string.Format("Test-{0}", new Random().Next(0, 9999));

            var factory = new TestMongoDbDataStoreFactory(logger, connectionStringFactory);
            IMongoCollection <TestEvent> collection = factory.GetTestEventCollection();

            try
            {
                // Arrange
                var dataStore = new MongoDbDataStore <TestEvent>(logger, collection);

                var event1 = new TestEvent
                {
                    Rsn           = Guid.NewGuid(),
                    Id            = Guid.NewGuid(),
                    CorrelationId = correlationIdHelper.GetCorrelationId(),
                    Frameworks    = new List <string> {
                        "Test 1"
                    },
                    TimeStamp = DateTimeOffset.UtcNow
                };

                // Act
                dataStore.Add(event1);

                // Assert
                var timer = new Stopwatch();
                timer.Start();
                TestEvent view = dataStore.SingleOrDefault(e => e.Rsn == event1.Rsn);
                timer.Stop();
                Console.WriteLine("Load operation took {0}", timer.Elapsed);
                Assert.IsNotNull(view);
                Assert.AreEqual(event1.Id, view.Id);
            }
            finally
            {
                // Clean-up
                collection.Database.Client.DropDatabase(TestMongoDataStoreConnectionStringFactory.DatabaseName);
            }
        }
Exemple #17
0
        /// <summary>
        /// Completes the provided <paramref name="response"/> by setting the appropriate <see cref="HttpResponseMessage.StatusCode"/> and populating <see cref="HttpResponseMessage.Content"/> with <paramref name="serviceResponse"/>.
        /// </summary>
        protected virtual HttpResponseMessage CompleteResponse <TServiceResponse>(HttpResponseMessage response, TServiceResponse serviceResponse)
            where TServiceResponse : IServiceResponse
        {
            serviceResponse.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            HttpConfiguration configuration            = Request.GetConfiguration();
            var contentNegotiator                      = configuration.Services.GetContentNegotiator();
            ContentNegotiationResult negotiationResult = contentNegotiator.Negotiate(typeof(IServiceResponse), Request, configuration.Formatters);

            response.Content = new ObjectContent <IServiceResponse>(serviceResponse, negotiationResult.Formatter, negotiationResult.MediaType);

            switch (serviceResponse.State)
            {
            case ServiceResponseStateType.Succeeded:
                response.StatusCode = HttpStatusCode.Accepted;

                break;

            case ServiceResponseStateType.FailedAuthentication:
                response.StatusCode = HttpStatusCode.Forbidden;
                break;

            case ServiceResponseStateType.FailedAuthorisation:
                response.StatusCode = HttpStatusCode.Unauthorized;
                break;

            case ServiceResponseStateType.FailedValidation:
                response.StatusCode = HttpStatusCode.PreconditionFailed;
                break;

            case ServiceResponseStateType.FailedWithAFatalException:
                response.StatusCode = HttpStatusCode.InternalServerError;
                break;

            case ServiceResponseStateType.FailedWithAnUnexpectedException:
                response.StatusCode = HttpStatusCode.InternalServerError;
                break;

            case ServiceResponseStateType.Unknown:
                response.StatusCode = HttpStatusCode.BadRequest;
                break;

            default:
                response.StatusCode = HttpStatusCode.Ambiguous;
                break;
            }

            return(response);
        }
Exemple #18
0
        /// <summary>
        /// Raises notifications to the system advising what time it is in different <see cref="TimeZoneInfo">time-zones</see>.
        /// </summary>
        public virtual void WhatTimeIsIt()
        {
            Guid      correlationId    = CorrelationIdHelper.GetCorrelationId();
            Stopwatch mainStopWatch    = Stopwatch.StartNew();
            var       requestTelemetry = new RequestTelemetry
            {
                Name         = "Scheduler/WhatTimeIsIt",
                Timestamp    = DateTimeOffset.UtcNow,
                ResponseCode = "200",
                Success      = true,
                Id           = correlationId.ToString("N"),
                Sequence     = correlationId.ToString("N")
            };

            try
            {
                var actualDateTime = DateTime.UtcNow;

                DateTimeOffset processDate = GetNowToTheNearestPrevious15Minutes();

                Logger.LogInfo(string.Format("The calculated time is: '{0}' and the actual time is: '{1}'", processDate, actualDateTime));
                // We Console.WriteLine as this is a WebJob and that will send output to the diagnostic Azure WebJob portal.
                Console.WriteLine("The calculated time is: '{0}' and the actual time is: '{1}'", processDate, actualDateTime);

                var eventPublisher = DependencyResolver.Current.Resolve <IEventPublisher <Guid> >();
                FindAndPublishTimeZones(eventPublisher, requestTelemetry, null, processDate);
                FindAndPublishTimeZones(eventPublisher, requestTelemetry, 0, processDate);
                FindAndPublishTimeZones(eventPublisher, requestTelemetry, 15, processDate);
                FindAndPublishTimeZones(eventPublisher, requestTelemetry, 30, processDate);
                FindAndPublishTimeZones(eventPublisher, requestTelemetry, 45, processDate);
            }
            catch
            {
                requestTelemetry.ResponseCode = "500";
                requestTelemetry.Success      = false;
                throw;
            }
            finally
            {
                Logger.LogInfo("Done... Shutting down.");

                mainStopWatch.Stop();
                requestTelemetry.Duration = mainStopWatch.Elapsed;
                TelemetryClient.TrackRequest(requestTelemetry);

                // We need to do this, otherwise if the app exits the telemetry data won't be sent
                TelemetryClient.Flush();
            }
        }
        /// <summary>
        /// Query for all the events that match the provided CorrelationId.
        /// </summary>
        /// <param name="serviceRequest">A <see cref="IServiceRequestWithData{TAuthenticationToken,TData}">service-request</see> that contains the CorrelationId.</param>
        /// <returns>A collection of <see cref="EventData">event data</see></returns>
        protected virtual IServiceResponseWithResultData <IEnumerable <EventData> > GetEventData(IServiceRequestWithData <TSingleSignOnToken, Guid> serviceRequest)
        {
            AuthenticationTokenHelper.SetAuthenticationToken(serviceRequest.AuthenticationToken);
            CorrelationIdHelper.SetCorrelationId(serviceRequest.CorrelationId);

            OnGetEventData(serviceRequest);
            IEnumerable <EventData> results = EventStore.Get(serviceRequest.Data);

            results = OnGotEventData(serviceRequest, results);

            return(new ServiceResponseWithResultData <IEnumerable <EventData> >
            {
                State = ServiceResponseStateType.Succeeded,
                ResultData = results,
                CorrelationId = CorrelationIdHelper.GetCorrelationId()
            });
        }
Exemple #20
0
        protected virtual void PrepareCommand <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            if (command.AuthenticationToken == null)
            {
                command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            command.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            if (string.IsNullOrWhiteSpace(command.OriginatingFramework))
            {
                command.OriginatingFramework = "Akka";
            }
            IList <string> frameworks = new List <string>(command.Frameworks);

            frameworks.Add("Akka");
            command.Frameworks = frameworks;
        }
Exemple #21
0
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            switch (@event.Framework)
            {
            case FrameworkType.Akka:
                Logger.LogInfo(string.Format("An event arrived of the type '{0}' but was marked as coming from the '{1}' framework, so it was dropped.", @event.GetType().FullName, @event.Framework));
                return;
            }

            if (@event.AuthenticationToken == null)
            {
                @event.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            @event.CorrelationId = CorrelationIdHelper.GetCorrelationId();
            @event.TimeStamp     = DateTimeOffset.UtcNow;

            Type eventType = @event.GetType();
            bool isRequired;

            if (!ConfigurationManager.TryGetSetting(string.Format("{0}.IsRequired", eventType.FullName), out isRequired))
            {
                isRequired = true;
            }

            IEnumerable <Action <IMessage> > handlers = Routes.GetHandlers(@event, isRequired).Select(x => x.Delegate).ToList();

            // This check doesn't require an isRequired check as there will be an exception raised above and handled below.
            if (!handlers.Any())
            {
                Logger.LogDebug(string.Format("The event handler for '{0}' is not required.", eventType.FullName));
            }

            foreach (Action <IMessage> handler in handlers)
            {
                IList <IEvent <TAuthenticationToken> > events;
                if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                {
                    events.Add(@event);
                }
                handler(@event);
            }
        }
Exemple #22
0
        public virtual void PrepareCommand <TCommand>(TCommand command, string framework)
            where TCommand : ICommand <TAuthenticationToken>
        {
            if (command.AuthenticationToken == null)
            {
                command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            command.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            if (string.IsNullOrWhiteSpace(command.OriginatingFramework))
            {
                command.OriginatingFramework = framework;
            }
            var frameworks = new List <string>();

            if (command.Frameworks != null)
            {
                frameworks.AddRange(command.Frameworks);
            }
            frameworks.Add("Azure-EventHub");
            command.Frameworks = frameworks;
        }
Exemple #23
0
        public virtual void PrepareEvent <TEvent>(TEvent @event, string framework)
            where TEvent : IEvent <TAuthenticationToken>
        {
            if (@event.AuthenticationToken == null)
            {
                @event.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            @event.CorrelationId = CorrelationIdHelper.GetCorrelationId();
            @event.TimeStamp     = DateTimeOffset.UtcNow;

            if (string.IsNullOrWhiteSpace(@event.OriginatingFramework))
            {
                @event.OriginatingFramework = framework;
            }
            var frameworks = new List <string>();

            if (@event.Frameworks != null)
            {
                frameworks.AddRange(@event.Frameworks);
            }
            frameworks.Add("Azure-EventHub");
            @event.Frameworks = frameworks;
        }
Exemple #24
0
        protected virtual void PrepareCommand <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            if (command.AuthenticationToken == null || command.AuthenticationToken.Equals(default(TAuthenticationToken)))
            {
                command.AuthenticationToken = AuthenticationTokenHelper.GetAuthenticationToken();
            }
            command.CorrelationId = CorrelationIdHelper.GetCorrelationId();

            if (string.IsNullOrWhiteSpace(command.OriginatingFramework))
            {
                command.OriginatingFramework = "Built-In";
            }

            var frameworks = new List <string>();

            if (command.Frameworks != null)
            {
                frameworks.AddRange(command.Frameworks);
            }
            frameworks.Add("Built-In");
            command.Frameworks = frameworks;
        }
Exemple #25
0
        protected virtual TServiceResponse CompleteResponse <TServiceResponse>(TServiceResponse serviceResponse)
            where TServiceResponse : IServiceResponse
        {
            serviceResponse.CorrelationId = CorrelationIdHelper.GetCorrelationId();
            switch (serviceResponse.State)
            {
            case ServiceResponseStateType.Succeeded:
                StatusCode(HttpStatusCode.OK);
                break;

            case ServiceResponseStateType.FailedAuthentication:
                StatusCode(HttpStatusCode.Forbidden);
                break;

            case ServiceResponseStateType.FailedAuthorisation:
                StatusCode(HttpStatusCode.Unauthorized);
                break;

            case ServiceResponseStateType.FailedValidation:
                StatusCode(HttpStatusCode.PreconditionFailed);
                break;

            case ServiceResponseStateType.FailedWithAFatalException:
                StatusCode(HttpStatusCode.InternalServerError);
                break;

            case ServiceResponseStateType.FailedWithAnUnexpectedException:
                StatusCode(HttpStatusCode.InternalServerError);
                break;

            case ServiceResponseStateType.Unknown:
                StatusCode(HttpStatusCode.BadRequest);
                break;
            }
            return(serviceResponse);
        }
Exemple #26
0
        /// <summary>
        /// Publishes the provided <paramref name="event"/> on the event bus.
        /// </summary>
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            DateTimeOffset startedAt          = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch      = Stopwatch.StartNew();
            string         responseCode       = null;
            bool           mainWasSuccessfull = false;
            bool           telemeterOverall   = false;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/Servicebus" }
            };
            string telemetryName    = string.Format("{0}/{1}/{2}", @event.GetType().FullName, @event.GetIdentity(), @event.Id);
            var    telemeteredEvent = @event as ITelemeteredMessage;

            if (telemeteredEvent != null)
            {
                telemetryName = telemeteredEvent.TelemetryName;
            }
            else
            {
                telemetryName = string.Format("Event/{0}", telemetryName);
            }

            try
            {
                if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-ServiceBus"))
                {
                    return;
                }

                Type eventType            = typeof(TEvent);
                bool?isPublicBusRequired  = BusHelper.IsPublicBusRequired(eventType);
                bool?isPrivateBusRequired = BusHelper.IsPrivateBusRequired(eventType);

                // We only add telemetry for overall operations if two occured
                telemeterOverall = isPublicBusRequired != null && isPublicBusRequired.Value && isPrivateBusRequired != null && isPrivateBusRequired.Value;

                // Backwards compatibility and simplicity
                bool      wasSuccessfull;
                Stopwatch stopWatch = Stopwatch.StartNew();
                if ((isPublicBusRequired == null || !isPublicBusRequired.Value) && (isPrivateBusRequired == null || !isPrivateBusRequired.Value))
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                        {
                            CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                        };
                        brokeredMessage.Properties.Add("Type", @event.GetType().FullName);
                        PublicServiceBusPublisher.Send(brokeredMessage);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the event being sent was too large or the topic has reached it's limit.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Default Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }
                    Logger.LogDebug(string.Format("An event was published on the public bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                }
                if ((isPublicBusRequired != null && isPublicBusRequired.Value))
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                        {
                            CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                        };
                        brokeredMessage.Properties.Add("Type", @event.GetType().FullName);
                        PublicServiceBusPublisher.Send(brokeredMessage);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Public Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }
                    Logger.LogDebug(string.Format("An event was published on the public bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                }
                if (isPrivateBusRequired != null && isPrivateBusRequired.Value)
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                        {
                            CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                        };
                        brokeredMessage.Properties.Add("Type", @event.GetType().FullName);
                        PrivateServiceBusPublisher.Send(brokeredMessage);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Private Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }

                    Logger.LogDebug(string.Format("An event was published on the private bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                }
                mainWasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                if (telemeterOverall)
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, mainWasSuccessfull, telemetryProperties);
                }
            }
        }
Exemple #27
0
        /// <summary>
        /// Publishes the provided <paramref name="events"/> on the event bus.
        /// </summary>
        public virtual void Publish <TEvent>(IEnumerable <TEvent> events)
            where TEvent : IEvent <TAuthenticationToken>
        {
            IList <TEvent> sourceEvents = events.ToList();

            DateTimeOffset startedAt          = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch      = Stopwatch.StartNew();
            string         responseCode       = null;
            bool           mainWasSuccessfull = false;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/Servicebus" }
            };
            string telemetryName  = "Events";
            string telemetryNames = string.Empty;

            foreach (TEvent @event in sourceEvents)
            {
                string subTelemetryName = string.Format("{0}/{1}/{2}", @event.GetType().FullName, @event.GetIdentity(), @event.Id);
                var    telemeteredEvent = @event as ITelemeteredMessage;
                if (telemeteredEvent != null)
                {
                    subTelemetryName = telemeteredEvent.TelemetryName;
                }
                telemetryNames = string.Format("{0}{1},", telemetryNames, subTelemetryName);
            }
            if (telemetryNames.Length > 0)
            {
                telemetryNames = telemetryNames.Substring(0, telemetryNames.Length - 1);
            }
            telemetryProperties.Add("Events", telemetryNames);

            try
            {
                IList <string>          sourceEventMessages     = new List <string>();
                IList <BrokeredMessage> privateBrokeredMessages = new List <BrokeredMessage>(sourceEvents.Count);
                IList <BrokeredMessage> publicBrokeredMessages  = new List <BrokeredMessage>(sourceEvents.Count);
                foreach (TEvent @event in sourceEvents)
                {
                    if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-ServiceBus"))
                    {
                        continue;
                    }

                    var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                    {
                        CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                    };
                    brokeredMessage.Properties.Add("Type", @event.GetType().FullName);

                    var privateEventAttribute = Attribute.GetCustomAttribute(typeof(TEvent), typeof(PrivateEventAttribute)) as PrivateEventAttribute;
                    var publicEventAttribute  = Attribute.GetCustomAttribute(typeof(TEvent), typeof(PrivateEventAttribute)) as PublicEventAttribute;

                    if
                    (
                        // Backwards compatibility and simplicity
                        (publicEventAttribute == null && privateEventAttribute == null)
                        ||
                        publicEventAttribute != null
                    )
                    {
                        publicBrokeredMessages.Add(brokeredMessage);
                        sourceEventMessages.Add(string.Format("An event was published on the public bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                    }
                    if (privateEventAttribute != null)
                    {
                        privateBrokeredMessages.Add(brokeredMessage);
                        sourceEventMessages.Add(string.Format("An event was published on the private bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                    }
                }

                bool      wasSuccessfull;
                Stopwatch stopWatch = Stopwatch.StartNew();

                // Backwards compatibility and simplicity
                stopWatch.Restart();
                responseCode   = "200";
                wasSuccessfull = false;
                try
                {
                    PublicServiceBusPublisher.SendBatch(publicBrokeredMessages);
                    wasSuccessfull = true;
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", publicBrokeredMessages }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", publicBrokeredMessages }
                    });
                    throw;
                }
                finally
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Public Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                }

                stopWatch.Restart();
                responseCode   = "200";
                wasSuccessfull = false;
                try
                {
                    PrivateServiceBusPublisher.SendBatch(privateBrokeredMessages);
                    wasSuccessfull = true;
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", privateBrokeredMessages }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", privateBrokeredMessages }
                    });
                    throw;
                }
                finally
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Private Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                }

                foreach (string message in sourceEventMessages)
                {
                    Logger.LogInfo(message);
                }

                mainWasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, mainWasSuccessfull, telemetryProperties);
            }
        }
Exemple #28
0
        /// <summary>
        /// Send out an event to all users
        /// </summary>
        void INotificationHub.SendAllUsersEvent <TSingleSignOnToken>(IEvent <TSingleSignOnToken> eventData)
        {
            Logger.LogDebug("Sending a message on the hub to all users.");

            try
            {
                var tokenSource = new CancellationTokenSource();
                Task.Factory.StartNewSafely
                (
                    () =>
                {
                    try
                    {
                        CurrentHub
                        .Clients
                        .All
                        .notifyEvent(new { Type = eventData.GetType().FullName, Data = eventData, CorrelationId = CorrelationIdHelper.GetCorrelationId() });
                    }
                    catch (TimeoutException exception)
                    {
                        Logger.LogWarning("Sending a message on the hub to all users timed-out.", exception: exception);
                    }
                    catch (Exception exception)
                    {
                        Logger.LogError("Sending a message on the hub to all users resulted in an error.", exception: exception);
                    }
                }, tokenSource.Token
                );

                tokenSource.CancelAfter(15 * 1000);
            }
            catch (Exception exception)
            {
                Logger.LogError("Queueing a message on the hub to all users resulted in an error.", exception: exception);
            }
        }
Exemple #29
0
        /// <summary>
        /// Send out an event to specific user token
        /// </summary>
        void INotificationHub.SendUserEvent <TSingleSignOnToken>(IEvent <TSingleSignOnToken> eventData, string userToken)
        {
            Logger.LogDebug(string.Format("Sending a message on the hub for user [{0}].", userToken));

            try
            {
                var tokenSource = new CancellationTokenSource();
                Task.Factory.StartNewSafely
                (
                    () =>
                {
                    IDictionary <string, object> metaData = GetAdditionalDataForLogging(userToken);

                    try
                    {
                        CurrentHub
                        .Clients
                        .Group(string.Format("User-{0}", userToken))
                        .notifyEvent(new { Type = eventData.GetType().FullName, Data = eventData, CorrelationId = CorrelationIdHelper.GetCorrelationId() });
                    }
                    catch (TimeoutException exception)
                    {
                        Logger.LogWarning("Sending a message on the hub timed-out.", exception: exception, metaData: metaData);
                    }
                    catch (Exception exception)
                    {
                        Logger.LogError("Sending a message on the hub resulted in an error.", exception: exception, metaData: metaData);
                    }
                }, tokenSource.Token
                );

                tokenSource.CancelAfter(15 * 1000);
            }
            catch (Exception exception)
            {
                Logger.LogError("Queueing a message on the hub resulted in an error.", exception: exception, metaData: GetAdditionalDataForLogging(userToken));
            }
        }
Exemple #30
0
        /// <summary>
        /// Send out an event to specific user RSNs
        /// </summary>
        void INotificationHub.SendUsersEvent <TSingleSignOnToken>(IEvent <TSingleSignOnToken> eventData, params Guid[] userRsnCollection)
        {
            IList <Guid> optimisedUserRsnCollection = (userRsnCollection ?? Enumerable.Empty <Guid>()).ToList();

            Logger.LogDebug(string.Format("Sending a message on the hub for user RSNs [{0}].", string.Join(", ", optimisedUserRsnCollection)));

            try
            {
                var tokenSource = new CancellationTokenSource();
                Task.Factory.StartNewSafely
                (
                    () =>
                {
                    foreach (Guid userRsn in optimisedUserRsnCollection)
                    {
                        var metaData = GetAdditionalDataForLogging(userRsn);
                        try
                        {
                            Clients
                            .Group(string.Format("UserRsn-{0}", userRsn))
                            .notifyEvent(new { Type = eventData.GetType().FullName, Data = eventData, CorrelationId = CorrelationIdHelper.GetCorrelationId() });
                        }
                        catch (TimeoutException exception)
                        {
                            Logger.LogWarning("Sending a message on the hub timed-out.", exception: exception, metaData: metaData);
                        }
                        catch (Exception exception)
                        {
                            Logger.LogError("Sending a message on the hub resulted in an error.", exception: exception, metaData: metaData);
                        }
                    }
                }, tokenSource.Token
                );

                tokenSource.CancelAfter(15 * 1000);
            }
            catch (Exception exception)
            {
                foreach (Guid userRsn in optimisedUserRsnCollection)
                {
                    Logger.LogError("Queueing a message on the hub resulted in an error.", exception: exception, metaData: GetAdditionalDataForLogging(userRsn));
                }
            }
        }