Example #1
0
    public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
    {
        if (!(context.Message.Instance is IOrderMessage orderMessage))
        {
            await next();

            return;
        }

        var order = await orderRepository.Load(orderMessage.OrderId);

        context.Extensions.Set(order);

        if (!order.OutgoingMessages.ContainsKey(context.MessageId))
        {
            var outboxState = new OutboxState();
            order.OutgoingMessages.Add(context.MessageId, outboxState);
            context.Extensions.Set(outboxState);

            await next();

            await orderRepository.Store(order);
        }

        if (order.OutgoingMessages[context.MessageId] != null)
        {
            foreach (var kvp in order.OutgoingMessages[context.MessageId].OutgoingMessages)
            {
                await context.PublishWithId(kvp.Payload, kvp.Id);
            }

            order.OutgoingMessages[context.MessageId] = null;
            await orderRepository.Store(order);
        }
    }
Example #2
0
        /// <summary>
        /// Sends a mail synchronously
        /// </summary>
        /// <param name="mail">Mail Message to send</param>
        /// <param name="inReplyTo">The unique id of the mail to which this is a reply</param>
        /// <returns>The unique id of the mail just sent</returns>
        public string Send(MailSoap12TransportBinding mail, string inReplyTo)
        {
            if (_serverConfiguration == null)
            {
                throw new MailServerConfigurationMissingException();
            }

            _state = OutboxState.Sending;

            // If we have a In-Reply-To id, set it
            if (inReplyTo != null)
            {
                mail.InReplyTo = inReplyTo;
            }

            lock (MailServerLockingToken) {
                LogOn();
                SendViaServer(mail);
                LogOff();
            }

            _state = OutboxState.Idle;

            return(mail.MessageId);
        }
Example #3
0
 public Task Put(string transactionId, OutboxState state)
 {
     return(Put(new OutboxItem
     {
         OutboxState = state,
         Id = transactionId
     }, null));
 }
    public async Task Store(string key, OutboxState outgoingMessages)
    {
        lock (store)
        {
            if (store.ContainsKey(key))
            {
                throw new InvalidOperationException("Outbox entry already exists");
            }

            store[key] = outgoingMessages;
        }
    }
Example #5
0
    async Task <string> FinishTransaction(IMessageProcessingContext context, OutboxState outboxState, T entity, string version)
    {
        if (outboxState != null)
        {
            var toDispatch = outboxState.OutgoingMessages.Deserialize();
            await Dispatch(toDispatch, context);

            await outboxStore.Delete(entity.TransactionId);
        }

        await inboxStore.MarkProcessed(context.MessageId);

        entity.TransactionId = null;
        return(await repository.Put(entity, version));
    }
Example #6
0
    public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
    {
        var id = getId(context.Message.Instance);

        if (id == null)
        {
            await next();

            return;
        }

        var(entity, version) = await repository.Get(id);

        var hasBeenProcessed = await tokenStore.HasBeenProcessed(context.MessageId);

        if (hasBeenProcessed)
        {
            if (entity.OutboxState.ContainsKey(context.MessageId))
            {
                entity.OutboxState.Remove(context.MessageId);
                await repository.Put(entity, version);
            }
            return; //Duplicate
        }

        if (!entity.OutboxState.TryGetValue(context.MessageId, out var outboxState))
        {
            context.Extensions.Set(entity);
            var messages = await InvokeMessageHandler(context, next);

            outboxState = new OutboxState {
                OutgoingMessages = messages.Serialize()
            };
            entity.OutboxState[context.MessageId] = outboxState;

            version = await repository.Put(entity, version);
        }

        var toDispatch = outboxState.OutgoingMessages.Deserialize();

        await Dispatch(toDispatch, context);

        await tokenStore.MarkProcessed(context.MessageId);

        entity.OutboxState.Remove(context.MessageId);
        await repository.Put(entity, version);
    }
Example #7
0
    public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
    {
        var id = getId(context.Message.Instance);

        if (id == null)
        {
            await next();

            return;
        }

        OutboxState outboxState;

        var(entity, version) = await repository.Get(id);

        if (entity.TransactionId != null)
        {
            outboxState = await outboxStore.Get(entity.TransactionId);

            version = await FinishTransaction(context, outboxState, entity, version);
        }

        var hasBeenProcessed = await inboxStore.HasBeenProcessed(context.MessageId);

        if (hasBeenProcessed)
        {
            return;
        }

        var transactionId = Guid.NewGuid().ToString();

        context.Extensions.Set(entity);
        var messages = await InvokeMessageHandler(context, next);

        outboxState = new OutboxState {
            OutgoingMessages = messages.Serialize()
        };

        await outboxStore.Put(transactionId, outboxState);

        entity.TransactionId = transactionId;
        version = await repository.Put(entity, version);

        await FinishTransaction(context, outboxState, entity, version);
    }
Example #8
0
    public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
    {
        if (!(context.Message.Instance is IOrderMessage orderMessage))
        {
            await next();

            return;
        }

        var order = await orderRepository.Load(orderMessage.OrderId)
                    ?? new Order
        {
            Id = orderMessage.OrderId
        };

        if (!order.OutboxState.TryGetValue(context.MessageId, out var outboxState))
        {
            context.Extensions.Set(order);
            var messages = await InvokeMessageHandler(context, next);

            outboxState = new OutboxState {
                OutgoingMessages = messages.Serialize()
            };
            order.OutboxState[context.MessageId] = outboxState;
            await orderRepository.Store(order);
        }

        if (outboxState != null)
        {
            var toDispatch = outboxState.OutgoingMessages.Deserialize();
            await Dispatch(toDispatch, context);

            order.OutboxState[context.MessageId] = null;
            await orderRepository.Store(order);
        }
    }
Example #9
0
    public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
    {
        var id = getId(context.Message.Instance);

        if (id == null)
        {
            await next();

            return;
        }

        context.Headers.TryGetValue("TokenId", out var tokenId);

        var(entity, version) = await repository.Get(id);

        string tokenVersion = null;

        if (tokenId != null)
        {
            bool tokenExists;
            (tokenExists, tokenVersion) = await tokenStore.Exists(tokenId);

            if (!tokenExists)
            {
                //Cleanup
                if (entity.OutboxState.ContainsKey(context.MessageId))
                {
                    entity.OutboxState.Remove(context.MessageId);
                    await repository.Put(entity, version);
                }

                return; //Duplicate
            }
        }

        if (!entity.OutboxState.TryGetValue(context.MessageId, out var outboxState))
        {
            context.Extensions.Set(entity);
            var messages = await InvokeMessageHandler(context, next);

            outboxState = new OutboxState {
                OutgoingMessages = messages.Serialize()
            };
            entity.OutboxState[context.MessageId] = outboxState;

            version = await repository.Put(entity, version);
        }

        if (!outboxState.TokensGenerated)
        {
            foreach (var message in outboxState.OutgoingMessages)
            {
                message.Headers["TokenId"] = Guid.NewGuid().ToString();
                await tokenStore.Create(message.Headers["TokenId"]);
            }

            outboxState.TokensGenerated = true;
            version = await repository.Put(entity, version);
        }

        var toDispatch = outboxState.OutgoingMessages.Deserialize();

        await Dispatch(toDispatch, context);

        if (tokenId != null)
        {
            await tokenStore.Delete(tokenId, tokenVersion);
        }

        entity.OutboxState.Remove(context.MessageId);
        await repository.Put(entity, version);
    }
Example #10
0
    public async Task Store(Guid transactionId, string messageId, OutboxState outgoingMessages)
    {
        await barrier("Outbox.Store").ConfigureAwait(false);

        await impl.Store(transactionId, messageId, outgoingMessages).ConfigureAwait(false);
    }
Example #11
0
    public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
    {
        var id = getId(context.Message.Instance);

        if (id == null)
        {
            await next();

            return;
        }

        OutboxState outboxState;

        var(entity, version) = await repository.Get(id);

        var hasBeenProcessed = await inboxStore.HasBeenProcessed(context.MessageId);

        if (hasBeenProcessed)
        {
            if (entity.TransactionIds.ContainsKey(context.MessageId))
            {
                entity.TransactionIds.Remove(context.MessageId);
                await repository.Put(entity, version);
            }
            return;
        }

        if (!entity.TransactionIds.TryGetValue(context.MessageId, out var transactionId))
        {
            transactionId = Guid.NewGuid().ToString();

            context.Extensions.Set(entity);
            var messages = await InvokeMessageHandler(context, next);

            outboxState = new OutboxState {
                OutgoingMessages = messages.Serialize()
            };

            await outboxStore.Put(transactionId, outboxState);

            entity.TransactionIds[context.MessageId] = transactionId;
            version = await repository.Put(entity, version);
        }
        else
        {
            outboxState = await outboxStore.Get(transactionId);
        }

        if (outboxState != null)
        {
            var toDispatch = outboxState.OutgoingMessages.Deserialize();
            await Dispatch(toDispatch, context);

            await outboxStore.Delete(transactionId);
        }

        await inboxStore.MarkProcessed(context.MessageId);

        entity.TransactionIds.Remove(context.MessageId);
        await repository.Put(entity, version);
    }
    public async Task Store(string key, OutboxState outgoingMessages)
    {
        await impl.Store(key, outgoingMessages).ConfigureAwait(false);

        await barrier("Outbox.Store").ConfigureAwait(false);
    }