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