public async Task Process(IncomingStepContext context, Func<Task> next) { var message = context.Load<Message>(); var headers = message.Headers; if (headers.ContainsKey(MapLegacyHeadersIncomingStep.LegacyMessageHeader)) { var body = message.Body; var array = body as object[]; if (array == null) { throw new FormatException( $"Incoming message has the '{MapLegacyHeadersIncomingStep.LegacyMessageHeader}' header, but the message body {body} is not an object[] as expected"); } foreach (var bodyToDispatch in array) { var messageBodyToDispatch = PossiblyConvertBody(bodyToDispatch, headers); context.Save(new Message(headers, messageBodyToDispatch)); await next(); } return; } await next(); }
void PossiblyDecompressTransportMessage(IncomingStepContext context) { var transportMessage = context.Load<TransportMessage>(); string contentEncoding; if (!transportMessage.Headers.TryGetValue(Headers.ContentEncoding, out contentEncoding)) return; if (contentEncoding != ZipMessagesOutgoingStep.GzipEncodingHeader) { var message = $"The message {transportMessage.GetMessageLabel()} has a '{Headers.ContentEncoding}' with the" + $" value '{contentEncoding}', but this middleware only knows how to decompress" + $" '{ZipMessagesOutgoingStep.GzipEncodingHeader}'"; throw new ArgumentException(message); } var headers = transportMessage.Headers.Clone(); var compressedBody = transportMessage.Body; headers.Remove(Headers.ContentEncoding); var body = _zipper.Unzip(compressedBody); context.Save(new TransportMessage(headers, body)); }
void MutateLegacyTransportMessage(IncomingStepContext context, Dictionary<string, string> headers, TransportMessage transportMessage) { var newHeaders = MapTrivialHeaders(headers); MapSpecialHeaders(newHeaders); newHeaders[LegacyMessageHeader] = ""; context.Save(new TransportMessage(newHeaders, transportMessage.Body)); }
/// <summary> /// Reorders the handler invokers if necessary /// </summary> public async Task Process(IncomingStepContext context, Func<Task> next) { var handlerInvokers = context.Load<HandlerInvokers>(); var orderedHandlerInvokers = handlerInvokers.OrderBy(i => _configuration.GetIndex(i.Handler)); var newHandlerInvokers = new HandlerInvokers(handlerInvokers.Message, orderedHandlerInvokers); context.Save(newHandlerInvokers); await next(); }
public async Task Process(IncomingStepContext context, Func<Task> next) { var statsContext = new StatsContext(); // save stats context for all the ProfilerSteps to find context.Save(statsContext); await next(); _profilerStats.Register(statsContext); }
public async Task CanRestoreIdentity() { var step = new RestorePrincipalFromIncomingMessage(new DummySerializer()); var instance = new Message(new Dictionary<string, string>(), new object()); var context = new IncomingStepContext(new TransportMessage(new Dictionary<string, string>(), new byte[0] ), new DefaultTransactionContext() ); instance.Headers[CapturePrincipalInOutgoingMessage.PrincipalCaptureKey] = "Larry"; context.Save(instance); await step.Process(context, async () => { Assert.AreEqual(ClaimsPrincipal.Current.Identity.Name, "Larry"); }); }
/// <summary> /// Descrypts the incoming <see cref="TransportMessage"/> if it has the <see cref="EncryptionHeaders.ContentEncryption"/> header /// </summary> public async Task Process(IncomingStepContext context, Func<Task> next) { var transportMessage = context.Load<TransportMessage>(); if (transportMessage.Headers.ContainsKey(EncryptionHeaders.ContentEncryption)) { var headers = transportMessage.Headers.Clone(); var encryptedBodyBytes = transportMessage.Body; var iv = GetIv(headers); var bodyBytes = _encryptor.Decrypt(encryptedBodyBytes, iv); context.Save(new TransportMessage(headers, bodyBytes)); } await next(); }
/// <summary> /// Descrypts the incoming <see cref="TransportMessage"/> if it has the <see cref="EncryptionHeaders.ContentEncryption"/> header /// </summary> public async Task Process(IncomingStepContext context, Func<Task> next) { var transportMessage = context.Load<TransportMessage>(); string contentEncryptionValue; if (transportMessage.Headers.TryGetValue(EncryptionHeaders.ContentEncryption, out contentEncryptionValue) && contentEncryptionValue == _encryptor.ContentEncryptionValue) { var headers = transportMessage.Headers.Clone(); var encryptedBodyBytes = transportMessage.Body; var iv = GetIv(headers); var bodyBytes = _encryptor.Decrypt(new EncryptedData(encryptedBodyBytes, iv)); context.Save(new TransportMessage(headers, bodyBytes)); } await next(); }
/// <summary> /// Executes the entire message processing pipeline in an exception handler, tracking the number of failed delivery attempts. /// Forwards the message to the error queue when the max number of delivery attempts has been exceeded. /// </summary> public async Task Process(IncomingStepContext context, Func<Task> next) { var transportMessage = context.Load<TransportMessage>(); var transactionContext = context.Load<ITransactionContext>(); var messageId = transportMessage.Headers.GetValueOrNull(Headers.MessageId); if (string.IsNullOrWhiteSpace(messageId)) { await MoveMessageToErrorQueue(transportMessage, transactionContext, $"Received message with empty or absent '{Headers.MessageId}' header! All messages must be" + " supplied with an ID . If no ID is present, the message cannot be tracked" + " between delivery attempts, and other stuff would also be much harder to" + " do - therefore, it is a requirement that messages be supplied with an ID."); return; } if (_errorTracker.HasFailedTooManyTimes(messageId)) { var errorDescriptionFor = GetErrorDescriptionFor(messageId); // if we don't have 2nd level retries, just get the message out of the way if (!_simpleRetryStrategySettings.SecondLevelRetriesEnabled) { await MoveMessageToErrorQueue(transportMessage, transactionContext, errorDescriptionFor); _errorTracker.CleanUp(messageId); return; } // change the identifier to track by to perform this 2nd level of delivery attempts var secondLevelMessageId = GetSecondLevelMessageId(messageId); if (_errorTracker.HasFailedTooManyTimes(secondLevelMessageId)) { await MoveMessageToErrorQueue(transportMessage, transactionContext, errorDescriptionFor); _errorTracker.CleanUp(messageId); _errorTracker.CleanUp(secondLevelMessageId); return; } context.Save(DispatchAsFailedMessageKey, true); await DispatchWithTrackerIdentifier(next, secondLevelMessageId, transactionContext, new[] { messageId, secondLevelMessageId }); return; } await DispatchWithTrackerIdentifier(next, messageId, transactionContext, new[] { messageId }); }
public async Task Process(IncomingStepContext context, Func<Task> next) { context.Save(DataBusStorageKey, _dataBusStorage); await next(); }