public async Task ProcessAsyncReturnsInternalServerErrorWhenInvalidMessageContentTypeSent() { // Act var result = await processor .ProcessAsync(BaseMessage, SequenceNumber, (MessageContentType)InvalidEnumValue, MessageAction.Published) .ConfigureAwait(false); // Assert Assert.Equal(HttpStatusCode.InternalServerError, result); }
public async Task ProcessAsync<T>(IMessageStateHandler<T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { //Is this a saga var processor = messageStateHandler.MessageScope.GetInstance<IProcessMessage<T>>(pipelineInformation.ProcessorInterfaceType); if (processor is ISaga saga) { var sagaType = ReflectionHelper.GetAllInterfacesImplementingOpenGenericInterface(processor.GetType(), typeof(ISaga<>)).Single(); var sagaDataType = sagaType.GenericTypeArguments[0]; var sagaHandlerType = typeof(SagaHandler<,>).MakeGenericType(sagaDataType, typeof(T)); var message = await messageStateHandler.GetMessageAsync().ConfigureAwait(false); var sagaHandler = (ISagaHandler)Activator.CreateInstance(sagaHandlerType, _sagaStore, processor, message); try { await sagaHandler.Initialize().ConfigureAwait(false); } catch (SagaAlreadyStartedException e) { // If the processor is ISagaDuplicateDetected, let the processor process the duplicate message before completing the saga if (processor is ISagaDuplicateDetected<T> sagaDetectedHandler) { await sagaDetectedHandler.ProcessDuplicateAsync(message, cancellationToken).ConfigureAwait(false); } else { pipelineInformation.HostConfiguration.Log.Information(e, "Saga already started"); } await messageStateHandler.CompleteAsync().ConfigureAwait(false); return; } try { await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } catch (Exception) { if (saga.MessageMapper.IsStartMessage(typeof(T))) { //If we have started a saga but the start message fails then we must make sure the message can be retried await _sagaStore.Complete(saga.PartitionKey, saga.Id).ConfigureAwait(false); } throw; } } else { await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } }
public async Task Should_process_message() { //arrange _stateHandler.Setup(x => x.DeliveryCount).Returns(1); _stateHandler.Setup(x => x.DeadLetterDeliveryLimit).Returns(1); _stateHandler.Setup(x => x.GetMessageAsync()).ReturnsAsync(new TestCommandOne()); //act await _messageProcessor.ProcessAsync(_stateHandler.Object, CancellationToken.None); //assert _stateHandler.Verify(x => x.CompleteAsync(), Times.Once); _countable.Verify(x => x.Count(), Times.Once); }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { using (_serviceProvider.CreateScope()) { await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } }
public async Task StartAsync(CancellationToken cancellationToken = default) { await foreach (var message in _reader.ReadAllAsync(cancellationToken)) { await _messageProcessor.ProcessAsync(message, cancellationToken); } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { if (messageStateHandler.DeliveryCount > messageStateHandler.DeadLetterDeliveryLimit) { var processor = pipelineInformation.HostConfiguration.DependencyInjection.GetInstance <IProcessMessage <T> >(pipelineInformation.ProcessorInterfaceType); if (processor is IProcessBeforeDeadLetter <T> deadletterProcessor) { var message = await messageStateHandler.GetMessageAsync().ConfigureAwait(false); try { await deadletterProcessor.BeforeDeadLetterAsync(message, cancellationToken).ConfigureAwait(false); } catch (Exception e) { pipelineInformation.HostConfiguration.Log.Error(e, "Failed before deadletter processing {@" + typeof(T).Name + "}", message); } } await messageStateHandler.DeadLetterAsync(messageStateHandler.DeadLetterDeliveryLimit).ConfigureAwait(false); return; } await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); }
public static async Task Run( [ServiceBusTrigger("%cms-messages-topic%", "%cms-messages-subscription%", Connection = "service-bus-connection-string")] Message sitefinityMessage, [Inject] IMessageProcessor messageProcessor, [Inject] IMessagePropertiesService messagePropertiesService, ILogger log) { if (sitefinityMessage == null) { throw new ArgumentNullException(nameof(sitefinityMessage)); } sitefinityMessage.UserProperties.TryGetValue("ActionType", out var actionType); sitefinityMessage.UserProperties.TryGetValue("CType", out var contentType); sitefinityMessage.UserProperties.TryGetValue("Id", out var messageContentId); // logger should allow setting up correlation id and should be picked up from message log.LogInformation($"{nameof(SitefinityMessageHandler)}: Received message action '{actionType}' for type '{contentType}' with Id: '{messageContentId}': Correlation id {sitefinityMessage.CorrelationId}"); var message = Encoding.UTF8.GetString(sitefinityMessage?.Body); if (string.IsNullOrWhiteSpace(message)) { throw new ArgumentException("Message cannot be null or empty.", nameof(sitefinityMessage)); } if (!Enum.IsDefined(typeof(MessageAction), actionType?.ToString())) { throw new ArgumentOutOfRangeException(nameof(actionType), $"Invalid message action '{actionType}' received, should be one of '{string.Join(",", Enum.GetNames(typeof(MessageAction)))}'"); } if (!Enum.IsDefined(typeof(MessageContentType), contentType?.ToString())) { throw new ArgumentOutOfRangeException(nameof(contentType), $"Invalid message content type '{contentType}' received, should be one of '{string.Join(",", Enum.GetNames(typeof(MessageContentType)))}'"); } var messageAction = Enum.Parse <MessageAction>(actionType?.ToString()); var messageContentType = Enum.Parse <MessageContentType>(contentType?.ToString()); var sequenceNumber = messagePropertiesService.GetSequenceNumber(sitefinityMessage); var result = await messageProcessor.ProcessAsync(message, sequenceNumber, messageContentType, messageAction).ConfigureAwait(false); switch (result) { case HttpStatusCode.OK: log.LogInformation($"{ClassFullName}: Content Page Id: {messageContentId}: Updated Content Page"); break; case HttpStatusCode.Created: log.LogInformation($"{ClassFullName}: Content Page Id: {messageContentId}: Created Content Page"); break; case HttpStatusCode.AlreadyReported: log.LogInformation($"{ClassFullName}: Content Page Id: {messageContentId}: Content Page previously updated"); break; default: log.LogWarning($"{ClassFullName}: Content Page Id: {messageContentId}: Content Page not Posted: Status: {result}"); break; } }
private async Task MessageHandler(ProcessMessageEventArgs args) { try { _logger.LogInformation($"client '{_systemInfo.ClientId}' received message '{args.Message.MessageId}'. Processing..."); var message = await _messageParser.DeserializeAsync <TM>(args.Message.Body); await _messageProcessor.ProcessAsync((dynamic)message, args.CancellationToken); await args.CompleteMessageAsync(args.Message).ConfigureAwait(false); } catch (Exception ex) { _logger.LogError(ex, $"an error has occurred while processing message '{args.Message.MessageId}': {ex.Message}"); if (args.Message.DeliveryCount > 3) { await args.DeadLetterMessageAsync(args.Message).ConfigureAwait(false); } else { await args.AbandonMessageAsync(args.Message).ConfigureAwait(false); } } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { using (AsyncScopedLifestyle.BeginScope(_container)) { await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { IMessageAttachment attachment = null; var queueName = AutoMessageMapper.GetQueueName <T>(); try { string attachmentId = null; if (typeof(ICommandWithAttachment).IsAssignableFrom(typeof(T))) { attachmentId = AttachmentUtility.GetAttachmentIds(messageStateHandler.MessageProperties).FirstOrDefault(); if (!string.IsNullOrEmpty(attachmentId)) { attachment = await _attachmentProvider.GetAttachmentAsync(queueName, attachmentId, cancellationToken).ConfigureAwait(false); var message = (ICommandWithAttachment)await messageStateHandler.GetMessageAsync().ConfigureAwait(false); message.Attachment = attachment; } } await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); if (attachment != null) { attachment.Stream?.Dispose(); await _attachmentProvider.DeleteAttachmentAsync(queueName, attachmentId, cancellationToken).ConfigureAwait(false); } } finally { attachment?.Stream?.Dispose(); } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { if (messageStateHandler is IMessageLockHandler <T> lockHandler && pipelineInformation.ProcessingSettings is IExtendMessageLockTimeout extendLock) { var token = cts.Token; #pragma warning disable 4014 Task.Run(async() => { await RenewLock(extendLock.ExtensionInterval, extendLock.ExtensionDuration, token, lockHandler, pipelineInformation.HostConfiguration.Log).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false); #pragma warning restore 4014 } try { await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } finally { //Stop the lock renewal cts.Cancel(); } } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { var messageName = typeof(T).FullName; using (var operation = _client.StartOperation <RequestTelemetry>(messageName)) { try { await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); // Add the message properties to the telemetry log foreach (var property in messageStateHandler.MessageProperties) { operation.Telemetry.Properties[property.Key] = property.Value; } operation.Telemetry.Success = true; } catch (Exception e) { operation.Telemetry.Success = false; _client.TrackException(e); throw; } } }
public void Setup(IMessageProcessor messagesProcessor) { var factory = new ConnectionFactory() { HostName = _brokerOptions.Value.Hostname }; _connection = factory.CreateConnection(); _channel = _connection.CreateModel(); _channel.QueueDeclare(queue: QueueName, durable: false, exclusive: false, autoDelete: false, arguments: null); //_channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false); var consumer = new EventingBasicConsumer(_channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); // ToDo add deserializing messagesProcessor.ProcessAsync(new CreateAlgorithmMessage()); Console.WriteLine(" [x] Received {0}", message); var eventRecieved = model as EventingBasicConsumer; eventRecieved?.Model?.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); }; _channel.BasicConsume(queue: QueueName, noAck: false, consumer: consumer); }
public void Setup(IMessageProcessor messageProcessor) { if (!_bus.IsConnected) { _logger.LogDebug("Trying to communicate with bus that is not connected to RabbitMq server!"); //throw new ArgumentException("Trying to communite with disconnected bus"); } else { _logger.LogInformation("Connected to RabbitMq server and setting respond"); } _bus.RespondAsync <CreateAlgorithmMessage, RunResultMessage>(async(request) => { _logger.LogInformation("Received request!"); try { var result = await messageProcessor.ProcessAsync(request); _logger.LogInformation("Sending respond!"); return(result); } catch (Exception ex) { _logger.LogCritical(ex.ToString()); throw; } }); }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { using (var scope = messageStateHandler.MessageScope.GetScope()) { messageStateHandler.MessageScope = scope; await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } }
public static Task <HandlerResponse <TResult> > ProcessAsync <TResult>(this IMessageProcessor processor, ICommand command) { if (processor == null) { throw Error.ArgumentNull("processor"); } return(processor.ProcessAsync <TResult>(command, default(CancellationToken))); }
private async Task Handler(Message message, CancellationToken cancellationToken) { var stateHandler = new ServiceBusMessageStateHandler <T>(_messageReceiver, message, _configuration.MessageSerializer, _deadLetterLimit, _hostConfiguration.DependencyInjection); using (var cts = CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, cancellationToken)) { await _processor.ProcessAsync(stateHandler, cts.Token).ConfigureAwait(false); } }
private async Task ClientOnProcessMessageAsync(ProcessMessageEventArgs arg) { var stateHandler = new ServiceBusMessageStateHandler <TTopic>(arg, _serializer, _deadLetterLimit, _hostConfiguration.DependencyInjection); using (var cts = CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, arg.CancellationToken)) { await _processor.ProcessAsync(stateHandler, cts.Token).ConfigureAwait(false); } }
/// <summary> /// Invokes message processing with the provided processor. /// </summary> /// <param name="message">The message that should be processed.</param> /// <param name="processor">The processor instance capable of processing the message.</param> /// <returns>A task representing the message processing operation.</returns> private async Task InvokeAsync(BotMessage message, IMessageProcessor processor) { var processingResult = await processor.ProcessAsync(message).ConfigureAwait(false); if (!processingResult.IsFinal) { _processorStorage.StoreProcessor(processor); } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { if (messageStateHandler.DeliveryCount > messageStateHandler.DeadLetterDeliveryLimit) { await messageStateHandler.DeadLetterAsync(messageStateHandler.DeadLetterDeliveryLimit).ConfigureAwait(false); return; } await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); }
public async Task ProcessAsyncJobProfileCreatePublishedTestReturnsOk() { // arrange const HttpStatusCode expectedResult = HttpStatusCode.Created; const string message = "{}"; const long sequenceNumber = 1; const MessageContentType messageContentType = MessageContentType.Pages; A.CallTo(() => mappingService.MapToContentPageModel(message, sequenceNumber)).Returns(A.Fake <ContentPageModel>()); A.CallTo(() => httpClientService.PutAsync(A <ContentPageModel> .Ignored)).Returns(expectedResult); // act var result = await messageProcessor.ProcessAsync(message, sequenceNumber, messageContentType, MessageAction.Published).ConfigureAwait(false); // assert A.CallTo(() => mappingService.MapToContentPageModel(message, sequenceNumber)).MustHaveHappenedOnceExactly(); A.CallTo(() => httpClientService.PutAsync(A <ContentPageModel> .Ignored)).MustHaveHappenedOnceExactly(); Assert.Equal(expectedResult, result); }
public async Task Process(Message sitefinityMessage) { if (sitefinityMessage == null) { throw new ArgumentNullException(nameof(sitefinityMessage)); } sitefinityMessage.UserProperties.TryGetValue(MessageProperty.Action, out var messagePropertyActionType); sitefinityMessage.UserProperties.TryGetValue(MessageProperty.ContentType, out var messagePropertyContentType); sitefinityMessage.UserProperties.TryGetValue(MessageProperty.JobProfileId, out var messageContentId); var messageBody = Encoding.UTF8.GetString(sitefinityMessage?.Body); if (string.IsNullOrWhiteSpace(messageBody)) { throw new ArgumentException("Message cannot be null or empty.", nameof(sitefinityMessage)); } if (!Enum.IsDefined(typeof(MessageActionType), messagePropertyActionType?.ToString())) { throw new ArgumentOutOfRangeException(nameof(messagePropertyActionType), $"Invalid message action '{messagePropertyActionType}' received, should be one of '{string.Join(",", Enum.GetNames(typeof(MessageActionType)))}'"); } if (!Enum.IsDefined(typeof(MessageContentType), messagePropertyContentType?.ToString())) { throw new ArgumentOutOfRangeException(nameof(messagePropertyContentType), $"Invalid message content type '{messagePropertyContentType}' received, should be one of '{string.Join(",", Enum.GetNames(typeof(MessageContentType)))}'"); } var messageAction = Enum.Parse <MessageActionType>(messagePropertyActionType?.ToString()); var messageContentType = Enum.Parse <MessageContentType>(messagePropertyContentType?.ToString()); var sequenceNumber = messagePropertiesService.GetSequenceNumber(sitefinityMessage); var result = await messageProcessor.ProcessAsync(messageBody, sequenceNumber, messageContentType, messageAction).ConfigureAwait(false); switch (result) { case HttpStatusCode.OK: logger.LogInformation($"{ClassFullName}: JobProfile Id: {messageContentId}: Updated segment"); break; case HttpStatusCode.Created: logger.LogInformation($"{ClassFullName}: JobProfile Id: {messageContentId}: Created segment"); break; case HttpStatusCode.AlreadyReported: logger.LogInformation($"{ClassFullName}: JobProfile Id: {messageContentId}: Segment previously updated"); break; default: logger.LogWarning($"{ClassFullName}: JobProfile Id: {messageContentId}: Segment not Posted: Status: {result}"); break; } }
public static async Task <HandlerResponse <TResult> > ProcessAsync <TResult>(this IMessageProcessor processor, ICommand command, CancellationToken cancellationToken) { if (processor == null) { throw Error.ArgumentNull("processor"); } var response = await processor.ProcessAsync(command, cancellationToken); return(new HandlerResponse <TResult>(response)); }
public async Task ProcessAsyncWorkingPatternTestReturnsOk() { // arrange const HttpStatusCode expectedResult = HttpStatusCode.OK; const string message = "{}"; const long sequenceNumber = 1; A.CallTo(() => mapper.Map <PatchWorkingPatternModel>(A <PatchWorkingPatternServiceBusModel> .Ignored)).Returns(A.Fake <PatchWorkingPatternModel>()); A.CallTo(() => httpClientService.PatchAsync(A <PatchWorkingPatternModel> .Ignored, A <string> .Ignored)).Returns(expectedResult); // act var result = await messageProcessor.ProcessAsync(message, sequenceNumber, MessageContentType.WorkingPattern, MessageAction.Published).ConfigureAwait(false); // assert A.CallTo(() => mapper.Map <PatchWorkingPatternModel>(A <PatchWorkingPatternServiceBusModel> .Ignored)).MustHaveHappenedOnceExactly(); A.CallTo(() => httpClientService.PatchAsync(A <PatchWorkingPatternModel> .Ignored, A <string> .Ignored)).MustHaveHappenedOnceExactly(); Assert.Equal(expectedResult, result); }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { if (!_stopwatch.IsRunning) { _stopwatch.Start(); } await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); if (++_count % 1000 == 0) { Console.WriteLine($"Processed {_count} messages in {_stopwatch.Elapsed} {_count / _stopwatch.Elapsed.TotalSeconds} m/s"); } }
public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage { try { await _semaphoreQueue.WaitAsync().ConfigureAwait(false); await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false); } finally { _semaphoreQueue.Release(); } }
private async Task Process(IMessage message, QueueReferences queueReferences, CancellationToken cancellationToken) { _logger.LogInformation("client {ClientGroup}/{ClientId} received message '{MessageId}' from Topic '{Topic}'. Processing...", _systemInfo.ClientGroup, _systemInfo.ClientId, message.Id, queueReferences.TopicName); try { await _messageProcessor.ProcessAsync((dynamic)message, cancellationToken); } catch (Exception ex) { await HandleProcessErrors(message, queueReferences, ex, cancellationToken); } }
public async Task StartAsync(CancellationToken cancellationToken = default) { await foreach (var message in _reader.ReadAllAsync(cancellationToken)) { try { await _messageProcessor.ProcessAsync(message, cancellationToken); } catch (Exception e) { _logger.LogError(e, $"an exception has occurred while processing '{message.GetType().FullName}' message '{message.Id}': {e.Message}"); } } }
public async Task MessagingProcessor(IMessageProcessor processor) { var messageHandler = await messageQueueIn.GetMessage <PlatformMessage>(); MessageRoute messageRoute = new MessageRoute(pricipal); this.platformMessage = messageHandler.MessageObject; await processor.ProcessAsync(platformMessage); messageRoute.Complete(); await messageHandler.Complete(); this.platformMessage.Routes.Add(messageRoute); await messageQueueQut.SendQueueMessage(this.platformMessage); }
public async Task MessageHandlerReturnsSuccessForSegmentUpdated(HttpStatusCode expectedResult) { // arrange const MessageAction messageAction = MessageAction.Published; const MessageContentType messageContentType = MessageContentType.Pages; const long sequenceNumber = 123; var model = A.Fake <ContentPageMessage>(); var message = JsonConvert.SerializeObject(model); var serviceBusMessage = new Message(Encoding.ASCII.GetBytes(message)); serviceBusMessage.UserProperties.Add("ActionType", messageAction); serviceBusMessage.UserProperties.Add("CType", messageContentType); serviceBusMessage.UserProperties.Add("Id", Guid.NewGuid()); A.CallTo(() => messagePropertiesService.GetSequenceNumber(serviceBusMessage)).Returns(sequenceNumber); A.CallTo(() => messageProcessor.ProcessAsync(message, sequenceNumber, messageContentType, messageAction)).Returns(expectedResult); // act await MessageHandler.Run(serviceBusMessage, messageProcessor, messagePropertiesService, logger).ConfigureAwait(false); // assert A.CallTo(() => messagePropertiesService.GetSequenceNumber(serviceBusMessage)).MustHaveHappenedOnceExactly(); A.CallTo(() => messageProcessor.ProcessAsync(message, sequenceNumber, messageContentType, messageAction)).MustHaveHappenedOnceExactly(); }