public async Task <IActionResult> Invoke(HttpRequest request, string messageType, ILogger logger, IAsyncCollector <string> collector, ExecutionContext executionContext)
        {
            var messageId = Guid.NewGuid().ToString("N");
            var headers   = new Dictionary <string, string> {
                [Headers.EnclosedMessageTypes] = messageType
            };

            foreach (var httpHeader in request.Headers)
            {
                headers[httpHeader.Key] = httpHeader.Value;
            }

            var memoryStream = new MemoryStream();

            await request.Body.CopyToAsync(memoryStream);

            var body = memoryStream.ToArray(); //JsonConvert.DeserializeObject(memoryStream.ToArray(), typeof(PlaceOrder)); // TODO: hardcoded, needs to be determined

            var rootContext = new ContextBag();

            if (collector == null)
            {
                collector = new FakeCollector <string>();
            }
            rootContext.Set(collector);

            var messageContext = new MessageContext(messageId, headers, body, new TransportTransaction(), new CancellationTokenSource(), rootContext);

            var instance = await GetEndpoint(logger, executionContext);

            try
            {
                await instance.PushMessage(messageContext);
            }
            catch (Exception ex)
            {
                if (moveFailedMessagesToError)
                {
                    var errorContext = new ErrorContext(ex, headers, messageId, body, new TransportTransaction(), 0);

                    var result = await instance.PushError(errorContext);

                    if (result == ErrorHandleResult.RetryRequired)
                    {
                        throw;
                    }

                    return(new AcceptedResult());
                }

                throw;
            }

            return(new OkResult());
        }
Ejemplo n.º 2
0
        public async Task Invoke(HttpRequest request, ILogger logger, IAsyncCollector <string> collector, ExecutionContext executionContext)
        {
            var messageId    = Guid.NewGuid().ToString("N");
            var headers      = new Dictionary <string, string>();
            var memoryStream = new MemoryStream();

            await request.Body.CopyToAsync(memoryStream);

            var body = memoryStream.ToArray(); //JsonConvert.DeserializeObject(memoryStream.ToArray(), typeof(PlaceOrder)); // TODO: hardcoded, needs to be determined

            var rootContext = new ContextBag();

            if (collector == null)
            {
                collector = new FakeCollector <string>();
            }
            rootContext.Set(collector);

            var messageContext = new MessageContext(messageId, headers, body, new TransportTransaction(), new CancellationTokenSource(), rootContext);

            var instance = await GetEndpoint(logger, executionContext);

            await instance.PushMessage(messageContext);
        }
        public async Task Invoke(Message message, ILogger logger, IAsyncCollector <string> collector, ExecutionContext executionContext, MessageReceiver messageReceiver = null)
        {
            var messageId = message.GetMessageId();
            var headers   = message.GetNServiceBusHeaders();
            var body      = message.GetBody();

            if (!headers.ContainsKey(Headers.ConversationId))
            {
                headers[Headers.ConversationId] = messageId;
            }


            var rootContext = new ContextBag();

            if (collector == null)
            {
                collector = new FakeCollector <string>();
            }
            rootContext.Set(collector);

            var instance = await GetEndpoint(logger, executionContext);

            try
            {
                // TODO: only should be done if in sends atomic with receive mode and message receiver is provided
                var useTransaction = messageReceiver != null;

                using (var scope = useTransaction ? new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled) : null)
                {
                    var transportTransaction = CreateTransportTransaction(useTransaction, messageReceiver, message.PartitionKey);
                    var messageContext       = new MessageContext(messageId, headers, body, transportTransaction, new CancellationTokenSource(), rootContext);

                    await instance.PushMessage(messageContext);

                    // Azure Function auto-completion would be disabled if we try to run in SendsAtomicWithReceive, need to complete message manually
                    if (useTransaction)
                    {
                        await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
                    }

                    scope?.Complete();
                }
            }
            catch (Exception ex)
            {
                // TODO: is 4 the right value?
                // TODO: Should we provide delayed retries as well?
                // TODO: when using transaction, complete the incoming message along with sending the error message
                if (moveFailedMessagesToError && message.SystemProperties.DeliveryCount > 4)
                {
                    var errorContext = new ErrorContext(ex, headers, messageId, body, new TransportTransaction(), 0);

                    var result = await instance.PushError(errorContext);

                    if (result == ErrorHandleResult.RetryRequired)
                    {
                        throw;
                    }

                    return;
                }

                throw;
            }
        }