/// <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); }
/// <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; } } }
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); }
/// <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); }
/// <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); }
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); }
/// <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); }
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); } }
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); }
/// <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); }