示例#1
0
        /// <summary>
        /// Initializes a security token service based on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The message queue configuration</param>
        /// <returns>Returns a task whose result is the initialized security token service</returns>
        public async Task <ISecurityTokenService> InitSecurityTokenService(SecurityTokensElement configuration)
        {
            var myConfig = configuration ?? new SecurityTokensElement();
            var provider = GetProvider(myConfig.Provider);

            if (provider == null)
            {
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationDefault)
                {
                    Detail = "Message journal disabled"
                }.Build());

                return(null);
            }

            var securityTokenService = await provider.CreateSecurityTokenService(myConfig);

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = $"Security token service {securityTokenService?.GetType().FullName} initialized"
            }.Build());

            return(securityTokenService);
        }
示例#2
0
        /// <summary>
        /// Performs final initialization of the transport service
        /// </summary>
        /// <param name="cancellationToken">A cancellation token that can be used by the caller
        /// can use to cancel the initialization process</param>
        /// <returns>Returns a task that completes when initialization is complete</returns>
        public async Task Init(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (Interlocked.Exchange(ref _initialized, 1) == 0)
            {
                try
                {
                    await _messageQueueingService.CreateQueue(_outboundQueueName, this,
                                                              cancellationToken : cancellationToken);

                    await _diagnosticService.EmitAsync(
                        new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
                    {
                        Detail = "HTTP transport service initialized"
                    }.Build(), cancellationToken);
                }
                catch (Exception ex)
                {
                    _diagnosticService.Emit(
                        new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitializationError)
                    {
                        Detail    = "Error initializating outbound transport queue",
                        Exception = ex
                    }.Build());
                    throw;
                }
            }
        }
示例#3
0
        private async Task HandlePlatibusRequest(HttpContext context)
        {
            await _diagnosticService.EmitAsync(
                new HttpEventBuilder(this, HttpEventType.HttpRequestReceived)
            {
                Remote = context.Connection.RemoteIpAddress?.ToString(),
                Uri    = context.Request.GetUri(),
                Method = context.Request.Method
            }.Build());

            var resourceRequest  = new HttpRequestAdapter(context.Request);
            var resourceResponse = new HttpResponseAdapter(context.Response);

            try
            {
                await _resourceRouter.Route(resourceRequest, resourceResponse);
            }
            catch (Exception ex)
            {
                var exceptionHandler = new HttpExceptionHandler(resourceRequest, resourceResponse, _diagnosticService);
                exceptionHandler.HandleException(ex);
            }

            await _diagnosticService.EmitAsync(
                new HttpEventBuilder(this, HttpEventType.HttpResponseSent)
            {
                Remote = context.Connection.RemoteIpAddress?.ToString(),
                Uri    = context.Request.GetUri(),
                Method = context.Request.Method,
                Status = context.Response.StatusCode
            }.Build());
        }
        /// <summary>
        /// Initializes a message encryption service based on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The message queue configuration</param>
        /// <returns>Returns a task whose result is the initialized message encryption service</returns>
        public async Task <IMessageEncryptionService> InitMessageEncryptionService(EncryptionElement configuration)
        {
            var myConfig = configuration ?? new EncryptionElement();
            var provider = GetProvider(myConfig.Provider);

            if (provider == null || !myConfig.Enabled)
            {
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationDefault)
                {
                    Detail = "Message encryption disabled"
                }.Build());

                return(null);
            }

            var messageEncryptionService = await provider.CreateMessageEncryptionService(myConfig);

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = $"Message encryption service {messageEncryptionService?.GetType().FullName} initialized"
            }.Build());

            return(messageEncryptionService);
        }
示例#5
0
        /// <summary>
        /// Initializes a message journal on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The journal configuration</param>
        /// <returns>Returns a task whose result is the initialized message journal</returns>
        public async Task <IMessageJournal> InitMessageJournal(JournalingElement configuration)
        {
            var myConfig = configuration ?? new JournalingElement();

            if (string.IsNullOrWhiteSpace(myConfig.Provider))
            {
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationDefault)
                {
                    Detail = "Message journal disabled"
                }.Build());

                return(null);
            }

            var provider       = GetProvider(myConfig.Provider);
            var messageJournal = await provider.CreateMessageJournal(myConfig);

            if (messageJournal == null)
            {
                return(null);
            }

            var messageJournalType = messageJournal.GetType().FullName;

            var categories = new List <MessageJournalCategory>();

            if (myConfig.JournalSentMessages)
            {
                categories.Add(MessageJournalCategory.Sent);
            }
            if (myConfig.JournalReceivedMessages)
            {
                categories.Add(MessageJournalCategory.Received);
            }
            if (myConfig.JournalPublishedMessages)
            {
                categories.Add(MessageJournalCategory.Published);
            }

            var filteredMessageJournalingService = new FilteredMessageJournal(messageJournal, categories);

            messageJournal = filteredMessageJournalingService;

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = $"Message journal {messageJournalType} initialized"
            }.Build());

            return(new SanitizedMessageJournal(messageJournal));
        }
        /// <summary>
        /// Initializes a message queueing service based on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The message queue configuration</param>
        /// <returns>Returns a task whose result is the initialized message queueing service</returns>
        public async Task <IMessageQueueingService> InitMessageQueueingService(QueueingElement configuration)
        {
            var myConfig = configuration ?? new QueueingElement();
            var provider = await GetProvider(myConfig.Provider);

            var messageQueueingService = await provider.CreateMessageQueueingService(myConfig);

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = $"Message queueing service {messageQueueingService.GetType().FullName} initialized"
            }.Build());

            return(messageQueueingService);
        }
示例#7
0
        /// <summary>
        /// Enqueues a message
        /// </summary>
        /// <param name="message">The message to enqueue</param>
        /// <param name="principal">The sender principal</param>
        /// <returns>Returns a task that completes when the message has been enqueued</returns>
        public async Task Enqueue(Message message, IPrincipal principal)
        {
            CheckDisposed();
            var expires       = message.Headers.Expires;
            var securityToken = await _securityTokenService.NullSafeIssue(principal, expires);

            var persistedMessage = message.WithSecurityToken(securityToken);

            if (_messageEncryptionService != null)
            {
                persistedMessage = await _messageEncryptionService.Encrypt(persistedMessage);
            }

            using (var channel = _connection.CreateModel())
            {
                await RabbitMQHelper.PublishMessage(persistedMessage, principal, channel, null, _queueExchange, _encoding);

                await _diagnosticService.EmitAsync(
                    new RabbitMQEventBuilder(this, DiagnosticEventType.MessageEnqueued)
                {
                    Queue         = _queueName,
                    Message       = message,
                    ChannelNumber = channel.ChannelNumber
                }.Build());
            }
        }
        private async Task Listen(CancellationToken cancellationToken)
        {
            var cancelation = new TaskCompletionSource <bool>();

            cancellationToken.Register(() => cancelation.TrySetCanceled());
            var canceled = cancelation.Task;

            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    var received = _listenerClient.ReceiveAsync();
                    await Task.WhenAny(received, canceled);

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    var receiveResult = await received;
                    var bytesReceived = receiveResult.Buffer?.Length ?? 0;
                    await _diagnosticService.EmitAsync(new MulticastEventBuilder(this, MulticastEventType.DatagramReceived)
                    {
                        Detail = bytesReceived + " byte(s) received",
                        Node   = _nodeId.ToString(),
                        Host   = receiveResult.RemoteEndPoint.Address.ToString(),
                        Port   = receiveResult.RemoteEndPoint.Port
                    }.Build(), cancellationToken);

                    await _receiveResultQueue.SendAsync(receiveResult, cancellationToken);
                }
            }
            catch (OperationCanceledException)
            {
            }

            var listenerBinding = (IPEndPoint)_listenerClient.Client.LocalEndPoint;
            await _diagnosticService.EmitAsync(new MulticastEventBuilder(this, MulticastEventType.ListenerStopped)
            {
                Node = _nodeId.ToString(),
                Host = listenerBinding.Address.ToString(),
                Port = listenerBinding.Port
            }.Build(), cancellationToken);
        }
示例#9
0
        private async Task <bool> HandlePlatibusRequest(IOwinContext context, IDiagnosticService diagnosticService)
        {
            if (!_resourceRouter.IsRoutable(context.Request.Uri))
            {
                return(false);
            }

            await diagnosticService.EmitAsync(
                new HttpEventBuilder(this, HttpEventType.HttpRequestReceived)
            {
                Remote = context.Request.RemoteIpAddress,
                Uri    = context.Request.Uri,
                Method = context.Request.Method
            }.Build());

            var resourceRequest  = new OwinRequestAdapter(context.Request);
            var resourceResponse = new OwinResponseAdapter(context.Response);

            try
            {
                await _resourceRouter.Route(resourceRequest, resourceResponse);
            }
            catch (Exception ex)
            {
                var exceptionHandler = new HttpExceptionHandler(resourceRequest, resourceResponse, diagnosticService);
                exceptionHandler.HandleException(ex);
            }

            await diagnosticService.EmitAsync(
                new HttpEventBuilder(this, HttpEventType.HttpResponseSent)
            {
                Remote = context.Request.RemoteIpAddress,
                Uri    = context.Request.Uri,
                Method = context.Request.Method,
                Status = context.Response.StatusCode
            }.Build());

            return(true);
        }
示例#10
0
        /// <summary>
        /// Initializes a subscription tracking service based on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The subscription tracking configuration</param>
        /// <returns>Returns a task whose result is the initialized subscription tracking service</returns>
        public async Task <IDiagnosticEventSink> InitDiagnosticEventSink(DiagnosticEventSinkElement configuration)
        {
            var myConfig = configuration ?? new DiagnosticEventSinkElement();

            if (string.IsNullOrWhiteSpace(myConfig.Provider))
            {
                var message = "Provider not specified for diagnostic event sink '" + myConfig.Name + "'";
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationError)
                {
                    Detail = message
                }.Build());

                throw new ConfigurationErrorsException(message);
            }

            var provider = GetProvider(myConfig.Provider);

            if (provider == null)
            {
                var message = "Unknown provider '" + myConfig.Provider + "' specified for diagnostic event sink '" + myConfig.Name + "'";
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationError)
                {
                    Detail = message
                }.Build());

                throw new ConfigurationErrorsException(message);
            }

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = "Initializing diagnostic event sink '" + myConfig.Name + "'"
            }.Build());

            var sink = await provider.CreateDiagnosticEventSink(myConfig);

            var filterSpec = new DiagnosticEventLevelSpecification(myConfig.MinLevel, myConfig.MaxLevel);
            var filterSink = new FilteringSink(sink, filterSpec);

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = "Diagnostic event sink '" + myConfig.Name + "' initialized"
            }.Build());

            return(filterSink);
        }
示例#11
0
        private async Task Init(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (_httpListener.IsListening)
            {
                return;
            }

            await TransportService.Init(cancellationToken);

            await _bus.Init(cancellationToken);

            _httpListener.Start();

            await _diagnosticService.EmitAsync(
                new HttpEventBuilder(this, HttpEventType.HttpServerStarted)
            {
                Detail = "HTTP listener started",
                Uri    = _baseUri
            }.Build(), cancellationToken);

            // Create a new async task but do not wait for it to complete.
            _listenTask = Listen(_cancellationTokenSource.Token);
        }
        /// <summary>
        /// Read existing messages from the persistent store and
        /// </summary>
        /// <param name="cancellationToken">A cancellation token that can be used by the caller
        /// to cancel the enqueueing operation</param>
        /// <returns></returns>
        protected async Task EnqueueExistingMessages(CancellationToken cancellationToken = default(CancellationToken))
        {
            var pendingMessages = await GetPendingMessages(cancellationToken);

            foreach (var pendingMessage in pendingMessages)
            {
                await _queuedMessages.SendAsync(pendingMessage, cancellationToken);

                await DiagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.MessageRequeued)
                {
                    Detail  = "Persistent message requeued (recovery)",
                    Message = pendingMessage.Message,
                    Queue   = QueueName
                }.Build(), cancellationToken);
            }
        }
示例#13
0
        public async Task HandleMessage(IEnumerable <IMessageHandler> messageHandlers, Message message,
                                        IMessageContext messageContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (message.Headers.Expires < DateTime.UtcNow)
            {
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.MessageExpired)
                {
                    Detail  = "Discarding message that expired " + message.Headers.Expires,
                    Message = message
                }.Build(), cancellationToken);

                messageContext.Acknowledge();
                return;
            }

            var messageContent = _messageMarshaller.Unmarshal(message);

            var handlingTasks = messageHandlers.Select(handler =>
                                                       handler.HandleMessage(messageContent, messageContext, cancellationToken));

            await Task.WhenAll(handlingTasks);
        }
示例#14
0
        /// <summary>
        /// Initializes the bus instance
        /// </summary>
        /// <param name="cancellationToken">(Optional) A cancellation token provided by the
        /// caller that can be used to indicate that initialization should be canceled</param>
        /// <returns>Returns a task that will complete when bus initialization is complete</returns>
        /// <remarks>
        /// During initialization all handler queues are initialized and listeners are started.
        /// Additionally, subscriptions are initiated through the <see cref="ITransportService"/>.
        /// </remarks>
        public async Task Init(CancellationToken cancellationToken = default(CancellationToken))
        {
            var handlingRulesGroupedByQueueName = _handlingRules
                                                  .GroupBy(r => r.QueueName)
                                                  .ToDictionary(grp => grp.Key, grp => grp);

            foreach (var ruleGroup in handlingRulesGroupedByQueueName)
            {
                var queueName = ruleGroup.Key;
                var rules     = ruleGroup.Value;
                var handlers  = rules.Select(r => r.MessageHandler);

                var queueOptions = rules
                                   .OrderBy(r => QueueOptionPrecedence(r.QueueOptions))
                                   .Select(r => r.QueueOptions)
                                   .FirstOrDefault();

                var queueListener = new MessageHandlingListener(this, _messageHandler, handlers);

                await _messageQueueingService.CreateQueue(queueName, queueListener, queueOptions, cancellationToken);
            }

            foreach (var subscription in _subscriptions)
            {
                var endpoint = _endpoints[subscription.Endpoint];

                // The returned task will no complete until the subscription is
                // canceled via the supplied cancelation token, so we shouldn't
                // await it.

                var subscriptionTask = _transportService.Subscribe(endpoint, subscription.Topic, subscription.TTL,
                                                                   _cancellationTokenSource.Token);

                _subscriptionTasks.Add(subscriptionTask);
            }

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.BusInitialized).Build(),
                cancellationToken);
        }