/// <summary>
        /// Carries out the auto-header logic
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();

            var headers = message.Headers;
            var body    = message.Body;

            var messageType = body.GetType();

            var headersToAssign = _headersToAssign.GetOrAdd(messageType, type => messageType
                                                            .GetTypeInfo()
                                                            .GetCustomAttributes(typeof(HeaderAttribute), true)
                                                            .OfType <HeaderAttribute>()
                                                            .ToArray());

            for (var index = 0; index < headersToAssign.Length; index++)
            {
                var autoHeader = headersToAssign[index];

                if (headers.ContainsKey(autoHeader.Key))
                {
                    continue;
                }

                headers[autoHeader.Key] = autoHeader.Value;
            }

            await next().ConfigureAwait(false);
        }
    /// <summary>
    /// Carries out whichever logic it takes to do something good for the outgoing message :)
    /// </summary>
    public async Task Process(OutgoingStepContext context, Func <Task> next)
    {
        var transactionContext = context.Load <ITransactionContext>();
        var items = transactionContext.Items;

        if (items.TryGetValue(HandlerInvoker.CurrentHandlerInvokerItemsKey, out var item))
        {
            if (item is HandlerInvoker handlerInvoker)
            {
                if (handlerInvoker.HasSaga)
                {
                    if (handlerInvoker.GetSagaData() is IIdempotentSagaData idempotentSagaData)
                    {
                        var idempotencyData = idempotentSagaData.IdempotencyData;

                        var transportMessage     = context.Load <TransportMessage>();
                        var destinationAddresses = context.Load <DestinationAddresses>();
                        var incomingStepContext  = items.GetOrThrow <IncomingStepContext>(StepContext.StepContextKey);
                        var messageId            = incomingStepContext.Load <Message>().GetMessageId();

                        idempotencyData.AddOutgoingMessage(messageId, destinationAddresses, transportMessage);
                    }
                }
            }
        }

        await next();
    }
 private static void SendAfterSendEvent(OutgoingStepContext context)
 {
     if (DiagnosticListener.IsEnabled(AfterSendMessage.EventName))
     {
         DiagnosticListener.Write(AfterSendMessage.EventName, new AfterSendMessage(context));
     }
 }
        /// <summary>
        /// Executes the step and sets the default headers
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();
            var headers = message.Headers;

            if (!headers.ContainsKey(Headers.MessageId))
            {
                headers[Headers.MessageId] = Guid.NewGuid().ToString();
            }

            if (_hasOwnAddress && !headers.ContainsKey(Headers.ReturnAddress))
            {
                headers[Headers.ReturnAddress] = _returnAddress;
            }

            headers[Headers.SentTime] = _rebusTime.Now.ToString("O");

            if (_hasOwnAddress)
            {
                headers[Headers.SenderAddress] = _senderAddress;
            }
            else
            {
                headers.Remove(Headers.SenderAddress);
            }

            if (!headers.ContainsKey(Headers.Type))
            {
                var messageType = message.Body.GetType();

                headers[Headers.Type] = _messageTypeNameConvention.GetTypeName(messageType);
            }

            await next();
        }
Beispiel #5
0
        public async Task StartsNoActivityIfThereIsNoCurrentActivity()
        {
            var step = new OutgoingDiagnosticsStep();

            var headers          = GetMessageHeaders("id", Headers.IntentOptions.PublishSubscribe);
            var message          = new Message(headers, new object());
            var transportMessage = new TransportMessage(headers, Array.Empty <byte>());

            var destinations = new DestinationAddresses(new List <string> {
                "MyQueue"
            });

            var context = new OutgoingStepContext(message, AmbientTransactionContext.Current, destinations);

            context.Save(transportMessage);

            var hadActivity        = false;
            var callbackWasInvoked = false;

            await step.Process(context, () =>
            {
                hadActivity        = Activity.Current != null;
                callbackWasInvoked = true;
                return(Task.CompletedTask);
            });

            Assert.That(hadActivity, Is.False);
            Assert.That(headers, Has.No.ContainKey(RebusDiagnosticConstants.TraceStateHeaderName));
            Assert.That(callbackWasInvoked, Is.True);
        }
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();

            foreach (var e in _beforeMessageSent)
            {
                e(_bus, message.Headers, message.Body, context);
            }

            try
            {
                await next();

                foreach (var e in _afterMessageSent)
                {
                    e(_bus, message.Headers, message.Body, context);
                }
            }
            catch (Exception exception)
            {
                context.Save(exception);

                foreach (var e in _afterMessageSent)
                {
                    e(_bus, message.Headers, message.Body, context);
                }

                throw;
            }
        }
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var transportMessage = context.Load <TransportMessage>();

            var body    = transportMessage.Body;
            var headers = transportMessage.Headers;

            var newHeaders = MapTrivialHeaders(headers);

            var allHeaders = newHeaders.Union(headers).ToDictionary(x => x.Key, x => x.Value);

            MapSpecialHeaders(allHeaders);

            AddCustomHeaders(allHeaders);
            AddMulticastHeader(allHeaders);

            if (_propagateAutoCorrelationSagaId)
            {
                PropagateAutoCorrelationSagaIdToHeaders(allHeaders);
            }

            context.Save(new TransportMessage(allHeaders, body));

            await next();
        }
    /// <summary>
    /// Encrypts the outgoing <see cref="TransportMessage"/> and adds appropriate headers
    /// </summary>
    public async Task Process(OutgoingStepContext context, Func <Task> next)
    {
        var transportMessage = context.Load <TransportMessage>();

        if (transportMessage.Headers.ContainsKey(EncryptionHeaders.DisableEncryptionHeader))
        {
            await next();

            return;
        }

        var headers       = transportMessage.Headers.Clone();
        var bodyBytes     = transportMessage.Body;
        var encryptedData = await _encryptor.Encrypt(bodyBytes);

        headers[EncryptionHeaders.ContentEncryption]           = _encryptor.ContentEncryptionValue;
        headers[EncryptionHeaders.ContentInitializationVector] = Convert.ToBase64String(encryptedData.Iv);

        if (!string.IsNullOrEmpty(encryptedData.KeyId))
        {
            headers[EncryptionHeaders.KeyId] = encryptedData.KeyId;
        }

        context.Save(new TransportMessage(headers, encryptedData.Bytes));

        await next();
    }
        /// <summary>
        /// Carries out the auto-header logic
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();

            var headers = message.Headers;
            var body    = message.Body;

            var messageType = body.GetType();

            var headersToAssign = _headersToAssign.GetOrAdd(messageType, type => messageType
                                                            .GetCustomAttributes(typeof(HeaderAttribute), true)
                                                            .OfType <HeaderAttribute>()
                                                            .ToList());

            foreach (var autoHeader in headersToAssign)
            {
                if (headers.ContainsKey(autoHeader.Key))
                {
                    continue;
                }

                headers[autoHeader.Key] = autoHeader.Value;
            }

            await next();
        }
Beispiel #10
0
        public Task Process(OutgoingStepContext context, Func <Task> next)
        {
            Message message = context.Load <Message>();

            if (message.Headers.ContainsKey(Headers.CorrelationId))
            {
                return(next());
            }

            string correlationId = _correlationContextAccessor.CorrelationContext?.CorrelationId ?? _correlationIdFactory.Create();

            message.Headers[Headers.CorrelationId] = correlationId;

            int correlationSequence = 0;
            ITransactionContext transactionContext  = context.Load <ITransactionContext>();
            IncomingStepContext incomingStepContext = transactionContext.GetOrNull <IncomingStepContext>(StepContext.StepContextKey);

            if (incomingStepContext != null)
            {
                correlationSequence = GetCorrelationSequence(incomingStepContext) + 1;
            }

            message.Headers[Headers.CorrelationSequence] = correlationSequence.ToString(CultureInfo.InvariantCulture);

            _logger.Debug("Correlation ID: {CorrelationId}, sequence: {CorrelationSequence}", correlationId, correlationSequence);

            return(next());
        }
Beispiel #11
0
        /// <summary>
        /// Carries out whichever logic it takes to do something good for the outgoing message :)
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            next    = next ?? throw new ArgumentNullException(nameof(next));
            context = context ?? throw new ArgumentNullException(nameof(context));

            var message = context.Load <Messages.Message>();

            var body = message.Body;

            var processor = _snsAttributeMapperFactory.Create(body.GetType());

            if (processor != null)
            {
                var attributes = processor.GetAttributes(body, message.Headers);

                if (attributes.Count > 10)
                {
                    throw new InvalidOperationException($"You can only map up to 10 attributes with an sns message. The number of attributes mapped is {attributes.Count} and the keys are {string.Join(", ", attributes.Keys)}");
                }

                context.Load <ITransactionContext>().Items.AddOrUpdate(SnsAttributeKey, s => attributes, (s, o) => attributes);
            }

            await next();
        }
Beispiel #12
0
        /// <summary>
        /// Executes the step and sets the default headers
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message     = context.Load <Message>();
            var headers     = message.Headers;
            var messageType = message.Body.GetType();

            if (!headers.ContainsKey(Headers.MessageId))
            {
                headers[Headers.MessageId] = Guid.NewGuid().ToString();
            }

            if (_hasOwnAddress && !headers.ContainsKey(Headers.ReturnAddress))
            {
                headers[Headers.ReturnAddress] = _address;
            }

            headers[Headers.SentTime] = RebusTime.Now.ToString("O");

            if (!headers.ContainsKey(Headers.Type))
            {
                headers[Headers.Type] = messageType.GetSimpleAssemblyQualifiedName();
            }

            await next().ConfigureAwait(false);
        }
 private static void SendBeforeSendEvent(OutgoingStepContext context)
 {
     if (DiagnosticListener.IsEnabled(BeforeSendMessage.EventName, context))
     {
         DiagnosticListener.Write(BeforeSendMessage.EventName, new BeforeSendMessage(context));
     }
 }
        private static void InjectHeaders(Activity activity, OutgoingStepContext context)
        {
            var message = context.Load <Message>();
            var headers = message.Headers;

            if (activity.IdFormat == ActivityIdFormat.W3C)
            {
                if (!headers.ContainsKey(TracingConstants.TraceParentHeaderName))
                {
                    headers[TracingConstants.TraceParentHeaderName] = activity.Id;

                    if (activity.TraceStateString != null)
                    {
                        headers[TracingConstants.TraceStateHeaderName] = activity.TraceStateString;
                    }
                }
            }
            else
            {
                if (!headers.ContainsKey(TracingConstants.RequestIdHeaderName))
                {
                    headers[TracingConstants.RequestIdHeaderName] = activity.Id;
                }
            }
        }
        public Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var transportMessage = context.Load <TransportMessage>();

            transportMessage = StandardAdapter.ConvertOutgoingTransportMessage(transportMessage, StandardHeaderOptions);
            context.Save(transportMessage);
            return(next());
        }
        private static Activity StartActivity(OutgoingStepContext context)
        {
            var activity = new Activity(TracingConstants.ProducerActivityName);

            activity.Start();

            return(activity);
        }
Beispiel #17
0
        static OutgoingStepContext GetOutgoingStepContext()
        {
            var message            = new Message(new Dictionary <string, string>(), new byte[] { 1, 2, 3 });
            var transactionContext = new TransactionContext();
            var context            = new OutgoingStepContext(message, transactionContext, new DestinationAddresses(new string[0]));

            context.Save(new List <string>());
            return(context);
        }
        /// <summary>
        /// Sets the <see cref="Headers.SentTime"/> header
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var message = context.Load<Message>();
            var headers = message.Headers;

            headers[Headers.SentTime] = RebusTime.Now.ToString("O");

            await next();
        }
        private static void StopActivity(Activity activity, OutgoingStepContext context)
        {
            if (activity.Duration == TimeSpan.Zero)
            {
                activity.SetEndTime(DateTime.UtcNow);
            }

            activity.Stop();
        }
        /// <summary>
        /// Executes the step
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var message = context.Load<TransportMessage>();
            var headers = message.Headers;

            CheckDeferHeaders(headers);

            await next();
        }
Beispiel #21
0
        /// <summary>
        /// Sets the <see cref="Headers.SentTime"/> header
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();
            var headers = message.Headers;

            headers[Headers.SentTime] = RebusTime.Now.ToString("O");

            await next();
        }
    /// <summary>
    /// Serializes the outgoing message by invoking the currently configured <see cref="ISerializer"/> on the <see cref="Message"/> found in the context,
    /// storing the result as the <see cref="TransportMessage"/> returned by the serializer
    /// </summary>
    public async Task Process(OutgoingStepContext context, Func <Task> next)
    {
        var logicalMessage   = context.Load <Message>();
        var transportMessage = await _serializer.Serialize(logicalMessage);

        context.Save(transportMessage);

        await next();
    }
Beispiel #23
0
    /// <summary>
    /// Executes the step
    /// </summary>
    public async Task Process(OutgoingStepContext context, Func <Task> next)
    {
        var message = context.Load <TransportMessage>();
        var headers = message.Headers;

        CheckDeferHeaders(headers);

        await next();
    }
        /// <summary>
        /// Serializes the outgoing message by invoking the currently configured <see cref="ISerializer"/> on the <see cref="Message"/> found in the context,
        /// storing the result as the <see cref="TransportMessage"/> returned by the serializer
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var logicalMessage = context.Load<Message>();
            var transportMessage = await _serializer.Serialize(logicalMessage);
            
            context.Save(transportMessage);

            await next();
        }
Beispiel #25
0
            public async Task Process(OutgoingStepContext context, Func <Task> next)
            {
                var events = context.Load <List <string> >();

                events.Add($"{_name} before");

                await next();

                events.Add($"{_name} after");
            }
Beispiel #26
0
    /// <summary>
    /// Dehydrates the message, if it's too big
    /// </summary>
    public async Task Process(OutgoingStepContext context, Func <Task> next)
    {
        var transportMessage = context.Load <TransportMessage>();

        if (transportMessage.Body.Length > _messageSizeLimitBytes)
        {
            await DehydrateTransportMessage(context, transportMessage);
        }

        await next();
    }
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message           = context.Load <Message>();
            var headers           = message.Headers;
            var messageBodyToSend = PossiblyConvertBody(headers, message.Body);
            var body = new[] { messageBodyToSend };

            context.Save(new Message(headers, body));

            await next();
        }
    public async Task Process(OutgoingStepContext context, Func <Task> next)
    {
        var message = context.Load <Message>();
        var state   = stateBuilder();

        message.Headers.WriteKeyAndIv(state.keyId, state.algorithm.IV);
        using (factory.GetEncryptSession(state.algorithm))
        {
            await next();
        }
    }
        public Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var transactionContext = context.Load <ITransactionContext>(SafeRebusContextTags.TransactionContextTag);
            var scope            = transactionContext.GetOrAdd(SafeRebusContextTags.ScopeContextTag, () => ServiceProvider.CreateScope());
            var adapter          = scope.ServiceProvider.GetService <ISafeStandardAdapter>();
            var transportMessage = context.Load <TransportMessage>();

            transportMessage = adapter.AppendAdapterSpecificHeaders(transportMessage);
            context.Save(transportMessage);
            return(next());
        }
Beispiel #30
0
        public Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();

            if (message.Body is IMessage m)
            {
                message.Headers[Headers.MessageId] = m.MessageId;
            }

            return(next());
        }
        /// <summary>
        /// If no return address has been added to the message, the sender's input queue address is automatically added as the <see cref="Headers.ReturnAddress"/>
        /// header
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var message = context.Load<Message>();
            var headers = message.Headers;

            if (_hasOwnAddress && !headers.ContainsKey(Headers.ReturnAddress))
            {
                headers[Headers.ReturnAddress] = _address;
            }

            await next();
        }
Beispiel #32
0
        /// <summary>
        /// Sets the <see cref="Headers.MessageId"/>. The message ID is a new <see cref="Guid"/>
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();
            var headers = message.Headers;

            if (!headers.ContainsKey(Headers.MessageId))
            {
                headers[Headers.MessageId] = Guid.NewGuid().ToString();
            }

            await next();
        }
Beispiel #33
0
        /// <summary>
        /// If no return address has been added to the message, the sender's input queue address is automatically added as the <see cref="Headers.ReturnAddress"/>
        /// header
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message = context.Load <Message>();
            var headers = message.Headers;

            if (_hasOwnAddress && !headers.ContainsKey(Headers.ReturnAddress))
            {
                headers[Headers.ReturnAddress] = _address;
            }

            await next();
        }
        /// <summary>
        /// Sets the <see cref="Headers.MessageId"/>. The message ID is a new <see cref="Guid"/>
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var message = context.Load<Message>();
            var headers = message.Headers;

            if (!headers.ContainsKey(Headers.MessageId))
            {
                headers[Headers.MessageId] = Guid.NewGuid().ToString();
            }

            await next();
        }
        /// <summary>
        /// Sets the <see cref="Headers.Type"/> to the simple assembly-qualified type name of the sent object, unless
        /// the header has not already been added
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func <Task> next)
        {
            var message     = context.Load <Message>();
            var headers     = message.Headers;
            var messageType = message.Body.GetType();

            if (!headers.ContainsKey(Headers.Type))
            {
                headers[Headers.Type] = messageType.GetSimpleAssemblyQualifiedName();
            }

            await next().ConfigureAwait(false);
        }
        /// <summary>
        /// Sets the <see cref="Headers.Type"/> to the simple assembly-qualified type name of the sent object, unless
        /// the header has not already been added
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var message = context.Load<Message>();
            var headers = message.Headers;
            var messageType = message.Body.GetType();

            if (!headers.ContainsKey(Headers.Type))
            {
                headers[Headers.Type] = messageType.GetSimpleAssemblyQualifiedName();
            }

            await next();
        }
Beispiel #37
0
        /// <summary>
        /// Flows the correlation ID like it should
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var outgoingMessage = context.Load<Message>();

            var transactionContext = context.Load<ITransactionContext>();
            var incomingStepContext = transactionContext.GetOrNull<IncomingStepContext>(StepContext.StepContextKey);

            if (!outgoingMessage.Headers.ContainsKey(Headers.CorrelationId))
            {
                var correlationId = GetCorrelationIdToAssign(incomingStepContext, outgoingMessage);

                outgoingMessage.Headers[Headers.CorrelationId] = correlationId;
            }

            await next();
        }
        /// <summary>
        /// Sends the outgoing message using the configured <see cref="ITransport"/>, sending to the <see cref="DestinationAddresses"/>
        /// found in the <see cref="OutgoingStepContext"/>.
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var logicalMessage = context.Load<Message>();
            var transportMessage = context.Load<TransportMessage>();
            var currentTransactionContext = context.Load<ITransactionContext>();
            var destinationAddressesList = context.Load<DestinationAddresses>().ToList();

            var hasOneOrMoreDestinations = destinationAddressesList.Any();

            _log.Debug("Sending {0} -> {1}",
                logicalMessage.Body ?? "<empty message>",
                hasOneOrMoreDestinations ? string.Join(";", destinationAddressesList) : "<no destinations>");

            await Send(destinationAddressesList, transportMessage, currentTransactionContext);

            await next();
        }
        /// <summary>
        /// Carries out the auto-header logic
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var message = context.Load<Message>();

            var headers = message.Headers;
            var body = message.Body;

            var messageType = body.GetType();

            var headersToAssign = _headersToAssign.GetOrAdd(messageType, type => messageType
                .GetCustomAttributes(typeof (HeaderAttribute), true)
                .OfType<HeaderAttribute>()
                .ToList());

            foreach (var autoHeader in headersToAssign)
            {
                if (headers.ContainsKey(autoHeader.Key)) continue;

                headers[autoHeader.Key] = autoHeader.Value;
            }

            await next();
        }