public IExpectBuilder <T> Or(Type type, Func <object, bool> filter) { WaitIsOver = WaitIsOver.Or(c => c != null && c.Any(filter)); Waiter.Subscribe(type, filter, WaitIsOver.Compile()); Waiter.Subscribe(MessageMetadataEnvelop.GenericForType(type), filter, WaitIsOver.Compile()); return(this); }
public async Task Execute(ICommand command, IMessageMetadata metadata = null, CommandConfirmationMode confirmationMode = CommandConfirmationMode.Projected) { var envelopedCommand = new MessageMetadataEnvelop(command, metadata ?? CreateEmptyCommandMetadata(command)); if (confirmationMode == CommandConfirmationMode.None) { _commandExecutorActor.Tell(envelopedCommand); return; } var inbox = Inbox.Create(_system); _commandExecutorActor.Tell(envelopedCommand, inbox.Receiver); var msg = await inbox.ReceiveAsync(_defaultTimeout); if (CheckMessage(confirmationMode, msg)) { return; } msg = await inbox.ReceiveAsync(_defaultTimeout); if (CheckMessage(confirmationMode, msg)) { return; } throw new TimeoutException("Command execution took to long"); }
public void Publish(object msg, IMessageMetadata metadata) { _local.Publish(msg); var messageMetadataEnvelop = MessageMetadataEnvelop.NewGeneric(msg, metadata); _remoteSubscriber.Ask <PublishAck>(new Publish(messageMetadataEnvelop), _timeout).Wait(); }
public void All_sync_handlers_performs_one_after_one() { Sys.InitLocalTransportExtension(); var delayActor = Sys.ActorOf(Props.Create(() => new EchoSleepActor(TimeSpan.FromMilliseconds(50), TestActor))); var catalog = new HandlersDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProjectionProcessor(delayActor)); catalog.Add <BalloonTitleChanged>(new SyncProjectionProcessor(delayActor)); catalog.Add <BalloonTitleChanged>(new SyncProjectionProcessor(delayActor)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); actor.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString()))); //in sync process we should wait for handlers execution //in same order as they were sent to handlers process actor ExpectMsg <MarkedHandlerExecutedMessage>(); ExpectMsg <IMessageMetadataEnvelop <DomainEvent> >(); //HandlersProcessActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); actor.Tell(MessageMetadataEnvelop.New(new BalloonTitleChanged("2", Guid.NewGuid().ToString()))); ExpectMsg <MarkedHandlerExecutedMessage>(); ExpectMsg <MarkedHandlerExecutedMessage>(); //HandlersProcessActor should notify next step - process actor that work is done ExpectMsg <IMessageMetadataEnvelop <DomainEvent> >(); ExpectMsg <AllHandlersCompleted>(); }
public AggregatePersistedHub_Infrastructure(ActorSystem system) { ChildId = Guid.NewGuid(); ChildCreateMessage = new MessageMetadataEnvelop <ICommand>(new CreateSampleAggregateCommand(42, ChildId), new MessageMetadata(ChildId)); ChildActivateMessage = new MessageMetadataEnvelop <ICommand>(new ChangeSampleAggregateCommand(100, ChildId), new MessageMetadata(ChildId)); HubProps = system.DI().Props <AggregateHubActor <SampleAggregate> >(); }
public AggregatePersistedHubInfrastructure() { ChildId = Guid.NewGuid().ToString(); ChildCreateMessage = new MessageMetadataEnvelop <ICommand>(new InflateNewBallonCommand(42, ChildId), MessageMetadata.New(ChildId, null, null)); ChildActivateMessage = new MessageMetadataEnvelop <ICommand>(new WriteTitleCommand(100, ChildId), MessageMetadata.New(ChildId, null, null)); }
public void Process_change_state_after_transitions() { var domainEventA = new BalloonCreated("1", Guid.NewGuid().ToString(), DateTime.Now, _processId); _processActor.Ref.Tell(MessageMetadataEnvelop.New(domainEventA)); var msg = ExpectMsg <ProcessTransited>(); Assert.Equal(domainEventA.SourceId, ((TestState)msg.NewProcessState).ProcessingId); }
public void Condition_wait_end_should_be_true_on_B_and_C() { var sampleObjectsReceived = new object[] { MessageMetadataEnvelop.New(_messageB), MessageMetadataEnvelop.New(_messageC) }; Assert.True(Waiter.ConditionBuilder.StopCondition(sampleObjectsReceived)); }
public void Process_transition_raises_state_events() { _processActor.Ref.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString(), DateTime.Now, _processId), MessageMetadata.Empty)); _localAkkaEventBusTransport.Subscribe(typeof(IMessageMetadataEnvelop), TestActor); FishForMessage <MessageMetadataEnvelop>(m => m.Message is ProcessManagerCreated <TestState>); FishForMessage <MessageMetadataEnvelop>(m => m.Message is ProcessReceivedMessage <TestState>); }
public static CreateActorRouteMessage ForAggregate(string name, IAggregateCommandsHandlerDesriptor descriptor) { var messageRoutes = descriptor.RegisteredCommands.Select(c => new MessageRoute ( MessageMetadataEnvelop.GenericForType(c.CommandType), c.Property )).ToArray(); var hubType = typeof(AggregateHubActor <>).MakeGenericType(descriptor.AggregateType); return(new CreateActorRouteMessage(hubType, name, PoolKind.None, messageRoutes)); }
public ProcessHubInfrastructure() { var processId = Guid.NewGuid().ToString(); ChildId = processId; var gotTired = new GotTiredEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), processId); var coffeMadeEvent = new CoffeMadeEvent(gotTired.FavoriteCoffeMachineId, gotTired.PersonId, null, processId); ChildCreateMessage = new MessageMetadataEnvelop <DomainEvent>(gotTired, MessageMetadata.New(gotTired.SourceId, null, null)); //TODO: second message will not hit same process as created by previos, //think how to change it. ChildActivateMessage = new MessageMetadataEnvelop <DomainEvent>(coffeMadeEvent, MessageMetadata.New(coffeMadeEvent.SourceId, null, null)); }
public void Message_Envelop_should_be_serializable() { var evt = new BalloonTitleChanged("123", Guid.NewGuid().ToString()); var fault = new Fault <BalloonTitleChanged>(evt, new Exception(), typeof(object), Guid.NewGuid().ToString(), DateTime.Now); //Fault //ballonTitleChanged var msg = new MessageMetadataEnvelop <Fault <BalloonTitleChanged> >(fault, MessageMetadata.Empty); var serializer = new DebugHyperionSerializer((ExtendedActorSystem)TestActorSystem.Create()); var bytes = serializer.ToBinary(msg); var restored = serializer.FromBinary(bytes, typeof(MessageMetadataEnvelop <Fault <BalloonTitleChanged> >)); Assert.NotNull(restored); }
public void CommandExecutor_does_not_support_command_inheritance() { var catalog = new TypeCatalog <IActorRef, object>(); catalog.Add <InflateNewBallonCommand>(TestActor); var actor = Sys.ActorOf(Props.Create(() => new AggregatesPipeActor(catalog))); var msg = new MessageMetadataEnvelop <CreateCommand>(new CreateCommand(1, Guid.NewGuid().ToString()), MessageMetadata.Empty); actor.Tell(msg); ExpectNoMsg(); }
public static CreateActorRouteMessage ForSaga(ISagaDescriptor descriptor, string name = null) { name = name ?? $"SagaHub_{descriptor.SagaType.BeautyName()}"; var messageRoutes = descriptor.AcceptMessages .Select(messageBinder => new MessageRoute( MessageMetadataEnvelop.GenericForType(messageBinder.MessageType), messageBinder.CorrelationField)) .ToArray(); var hubType = typeof(SagaHubActor <,>).MakeGenericType(descriptor.SagaType, descriptor.StateType); return(new CreateActorRouteMessage(hubType, name, PoolKind.None, messageRoutes)); }
public void CommandExecutor_routes_command_by_its_type() { var catalog = new TypeCatalog <IActorRef, object>(); catalog.Add <InflateNewBallonCommand>(TestActor); var actor = Sys.ActorOf(Props.Create(() => new AggregatesPipeActor(catalog))); var msg = new MessageMetadataEnvelop <ICommand>(new InflateNewBallonCommand(1, Guid.NewGuid().ToString()), MessageMetadata.Empty); actor.Tell(msg); ExpectMsg <MessageMetadataEnvelop <ICommand> >(); }
public void Given_no_processors_pipe_still_reply_with_completed_messages() { var catalog = new HandlersDefaultProcessor(); Sys.InitLocalTransportExtension(); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); var sampleAggregateCreatedEvent = new BalloonCreated("1", Guid.NewGuid().ToString()); actor.Tell(MessageMetadataEnvelop.New(sampleAggregateCreatedEvent, MessageMetadata.Empty)); //HandlersPipeActor should notify next step - process actor that work is done ExpectMsg <IMessageMetadataEnvelop <DomainEvent> >(); //HandlersPipeActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); }
public StateSagaPersistedHub_Infrastructure(ActorSystem system) { var sagaId = Guid.NewGuid(); ChildId = sagaId; var gotTired = new GotTiredEvent(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), sagaId); var coffeMadeEvent = new CoffeMadeEvent(gotTired.FavoriteCoffeMachineId, gotTired.PersonId, null, sagaId); ChildCreateMessage = new MessageMetadataEnvelop <DomainEvent>(gotTired, new MessageMetadata(gotTired.SourceId)); ChildActivateMessage = new MessageMetadataEnvelop <DomainEvent>(coffeMadeEvent, new MessageMetadata(coffeMadeEvent.SourceId)); HubProps = system.DI().Props <SagaHubActor <SoftwareProgrammingSaga, SoftwareProgrammingSagaState> >(); }
public void Process_actor_process_one_message_in_time() { var domainEventA = new BalloonCreated("1", Guid.NewGuid().ToString(), DateTime.Now, _processId); var domainEventB = new BalloonTitleChanged("2", Guid.NewGuid().ToString(), DateTime.Now, _processId); _processActor.Tell(MessageMetadataEnvelop.New(domainEventA, MessageMetadata.Empty)); _processActor.Tell(MessageMetadataEnvelop.New(domainEventB, MessageMetadata.Empty)); //A was received first and should be processed first var msg = ExpectMsg <ProcessTransited>(); Assert.Equal(domainEventA.SourceId, ((TestState)msg.NewProcessState).ProcessingId); //B should not be processed after A is completed var msgB = ExpectMsg <ProcessTransited>(); Assert.Equal(domainEventB.SourceId, ((TestState)msgB.NewProcessState).ProcessingId); }
public async Task <IWaitResults> Execute(params ICommand[] commands) { foreach (var command in commands) { _waiter.ExpectBuilder.Or(MessageMetadataEnvelop.GenericForType(Fault.TypeFor(command)), f => (((f as IMessageMetadataEnvelop)?.Message as IFault)?.Message as ICommand)?.Id == command.Id); } var task = _waiter.Start(); foreach (var command in commands) { Executor.Execute(command); } var res = await task; if (!_failOnFaults) { return(res); } var faults = new List <IFault>(); foreach (var m in res.All) { var fault = m as IFault; if (fault != null) { faults.Add(fault); } var envelopedFault = m as IMessageMetadataEnvelop <IFault>; if (envelopedFault != null) { faults.Add(envelopedFault.Message); } } if (faults.Any()) { throw new AggregateException(faults.Select(f => f.Exception)); } return(res); }
public void CustomHandlerExecutor_does_not_support_domain_event_inheritance() { Sys.InitLocalTransportExtension(); var catalog = new HandlersDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProjectionProcessor(TestActor)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); var msg = MessageMetadataEnvelop.New(new Inherited()); actor.Tell(msg); //processor did not run, but we pass message to process after ExpectMsg <MessageMetadataEnvelop <Inherited> >(); //processor did not run, but we received processing complete message ExpectMsg <AllHandlersCompleted>(); }
public async Task ProcessManagerPipeActor_does_not_support_domain_event_inheritance() { var testProcessActor = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, Guid.NewGuid().ToString(), null))); var catalog = new ProcessesDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProcessManagerProcessor(testProcessActor)); var processPipeActor = Sys.ActorOf(Props.Create(() => new ProcessesPipeActor(catalog))); await processPipeActor.Ask <Initialized>(new Initialize(TestActor)); var msg = MessageMetadataEnvelop.New <DomainEvent>(new Inherited()); processPipeActor.Tell(msg); ExpectMsg <ProcessesTransitComplete>(); //process processor did not run due to error, but we received processing complete message ExpectNoMsg(TimeSpan.FromSeconds(1)); }
public void CustomHandlerProcessor_routes_events_by_type() { Sys.InitLocalTransportExtension(); var catalog = new HandlersDefaultProcessor(); catalog.Add <BalloonCreated>(new FireAndForgetActorMessageProcessor(TestActor)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); actor.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString()))); //TestActor as processor receives message for work ExpectMsg <MessageMetadataEnvelop <BalloonCreated> >(); //HandlersProcessActor should resend domain event to next step - process actor - for processing ExpectMsg <MessageMetadataEnvelop <BalloonCreated> >(); //HandlersProcessActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); }
private void CreatingProcessBehavior() { Receive <CreateNewProcess>(c => { _log.Debug("Creating new process instance from {@message}", c); var pendingState = _processStateFactory.Create(c.Message.Message); ExecutionContext.StartNewExecution(pendingState, c.Message, Sender); var cmd = new CreateNewStateCommand <TState>(ExecutionContext.PendingState.Id, ExecutionContext.PendingState); //will reply with CommandExecuted _stateAggregateActor.Tell(new MessageMetadataEnvelop <ICommand>(cmd, ExecutionContext.ProcessingMessage.Metadata)); Behavior.Become(AwaitingCreationConfirmationBehavior, nameof(AwaitingCreationConfirmationBehavior)); }); void AwaitingCreationConfirmationBehavior() { Receive <Status.Failure>(f => FinishWithError(ExecutionContext.ProcessingMessage, ExecutionContext.ProcessingMessageSender, f.Cause)); //from state aggregate actor after persist Receive <AggregateActor.CommandExecuted>(c => { _log.Debug("Process instance created by message {@processResult}", ExecutionContext.ProcessingMessage); var pendingStateId = ExecutionContext.PendingState.Id; if (Id != pendingStateId) { _log.Debug("Redirecting message to newly created process state instance, {id}", pendingStateId); var redirect = new MessageMetadataEnvelop(new ProcessRedirect(pendingStateId, ExecutionContext.ProcessingMessage), ExecutionContext.ProcessingMessage.Metadata); //requesting redirect from parent - persistence hub Context.Parent.Tell(redirect, ExecutionContext.ProcessingMessageSender); Behavior.Become(AwaitingMessageBehavior, nameof(AwaitingMessageBehavior)); ExecutionContext.Clear(); return; } State = ExecutionContext.PendingState; Self.Tell(ExecutionContext.ProcessingMessage, ExecutionContext.ProcessingMessageSender); Behavior.Become(TransitingProcessBehavior, nameof(TransitingProcessBehavior)); ExecutionContext.Clear(); }); StashingMessagesToProcessBehavior("process is waiting for process instance creation"); } }
public async Task ProcessPipeActor_routes_events_by_type() { var testProcessActor = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, Guid.NewGuid().ToString(), null))); var catalog = new ProcessesDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProcessManagerProcessor(testProcessActor)); var processPipeActor = Sys.ActorOf(Props.Create(() => new ProcessesPipeActor(catalog))); await processPipeActor.Ask <Initialized>(new Initialize(TestActor)); var msg = new MessageMetadataEnvelop <DomainEvent>(new BalloonCreated("1", Guid.NewGuid().ToString()), MessageMetadata.Empty); processPipeActor.Tell(msg); //TestActor from test process processor receives message after work is done ExpectMsg <ProcessTransited>(); //process pipe should send next step - command execution actor that new commands should be executed ExpectMsg <IMessageMetadataEnvelop <ICommand> >(); }
public void Sync_and_async_handlers_performs_independent() { Sys.InitLocalTransportExtension(); var fastHandler = Sys.ActorOf(Props.Create(() => new EchoSleepActor(TimeSpan.FromMilliseconds(1), TestActor))); var slowHandler = Sys.ActorOf(Props.Create(() => new EchoSleepActor(TimeSpan.FromMilliseconds(500), TestActor))); var catalog = new HandlersDefaultProcessor(); //Slow handler will receive messages first. //Due to it is registered with async process policy //second handler (fast) will not wait for slow one and it will finish execution before slow handler catalog.Add <BalloonCreated>(new FireAndForgetActorMessageProcessor(slowHandler)); catalog.Add <BalloonCreated>(new SyncProjectionProcessor(fastHandler)); catalog.Add <BalloonTitleChanged>(new FireAndForgetActorMessageProcessor(slowHandler)); catalog.Add <BalloonTitleChanged>(new SyncProjectionProcessor(fastHandler)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); actor.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString()))); actor.Tell(MessageMetadataEnvelop.New(new BalloonTitleChanged("1", Guid.NewGuid().ToString()))); ExpectMsg <MarkedHandlerExecutedMessage>((e, s) => e.ProcessingMessage.Message is BalloonCreated && s == fastHandler); ExpectMsg <IMessageMetadataEnvelop <BalloonCreated> >(); ExpectMsg <AllHandlersCompleted>(); //for balloon created ExpectMsg <MarkedHandlerExecutedMessage>((e, s) => e.ProcessingMessage.Message is BalloonTitleChanged && s == fastHandler); //HandlersProcessActor should notify next step - process actor that work is done ExpectMsg <IMessageMetadataEnvelop <BalloonTitleChanged> >(); //HandlersProcessActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); //slow fire and handlers will finish execution in undetermined order ExpectMsg <MarkedHandlerExecutedMessage>(); ExpectMsg <MarkedHandlerExecutedMessage>(); }
public async Task <object> Execute(CommandPlan plan) { var waiter = new AkkaCommandLocalWaiter(this, _system, _transport, plan.Timeout, true); var expectBuilder = waiter.ExpectBuilder; //All expected messages should be received foreach (var expectedMessage in plan.ExpectedMessages.Where(e => !typeof(IFault).IsAssignableFrom(e.MessageType))) { expectBuilder.And(MessageMetadataEnvelop.GenericForType(expectedMessage.MessageType), o => expectedMessage.Match((o as IMessageMetadataEnvelop)?.Message)); } //All expected faults should end waiting foreach (var expectedMessage in plan.ExpectedMessages.Where(e => typeof(IFault).IsAssignableFrom(e.MessageType))) { expectBuilder.Or(MessageMetadataEnvelop.GenericForType(expectedMessage.MessageType), o => expectedMessage.Match((o as IMessageMetadataEnvelop)?.Message) && (!expectedMessage.Sources.Any() || expectedMessage.Sources.Contains(((o as IMessageMetadataEnvelop)?.Message as IFault)?.Processor))); } //Command fault should always end waiting var commandFaultType = typeof(IFault <>).MakeGenericType(plan.Command.GetType()); expectBuilder.Or(MessageMetadataEnvelop.GenericForType(commandFaultType), o => (((o as IMessageMetadataEnvelop)?.Message as IFault)?.Message as ICommand)?.Id == plan.Command.Id); var res = await expectBuilder.Create(plan.Timeout) .Execute(plan.Command) .ConfigureAwait(false); return(res.All.Count > 1 ? res.All.ToArray() : res.All.FirstOrDefault()); }
public void When_child_revives_monitor_should_be_created_even_on_collision() { var ChildId = "testChild"; var create = new MessageMetadataEnvelop <ICommand>(new InflateNewBallonCommand(42, ChildId), MessageMetadata.New(ChildId, null, null)); _hubRef.Tell(create); Task.Run(async() => { while (true) { var activate = new MessageMetadataEnvelop <ICommand>(new WriteTitleCommand(100, ChildId), MessageMetadata.New(ChildId, null, null)); _hubRef.Tell(activate); await Task.Delay(150); } }); EventFilter.Exception <InvalidActorNameException>() .Expect(0, TimeSpan.FromSeconds(10), () => { }); }
public void Publish(object msg, IMessageMetadata metadata) { _log.Trace("Publishing {@Message} to transport with metadata {@metadata}", msg, metadata); _bus.Publish(MessageMetadataEnvelop.NewGeneric(msg, metadata)); }
public async Task All_Processes_performs_linear_and_results_from_all_processes_are_gathered() { var processAId = Guid.NewGuid().ToString(); _output.WriteLine("Process A:" + processAId); var testProcessActorA = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, processAId, TimeSpan.FromMilliseconds(1000)))); var processBId = Guid.NewGuid().ToString(); _output.WriteLine("Process B:" + processBId); var testProcessActorB = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, processBId, TimeSpan.FromMilliseconds(50)))); var processCId = Guid.NewGuid().ToString(); _output.WriteLine("Process C:" + processCId); var testProcessActorC = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, processCId, TimeSpan.FromMilliseconds(50)))); var catalog = new ProcessesDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProcessManagerProcessor(testProcessActorA)); catalog.Add <BalloonTitleChanged>(new SyncProcessManagerProcessor(testProcessActorB)); catalog.Add <BalloonTitleChanged>(new SyncProcessManagerProcessor(testProcessActorC)); var balloonCreated = new BalloonCreated("1", Guid.NewGuid().ToString()); var balloonTitleChanged = new BalloonTitleChanged("2", Guid.NewGuid().ToString()); //var resultA = await catalog.Process(MessageMetadataEnvelop.New<DomainEvent>(balloonCreated)); //var resultB = await catalog.Process(MessageMetadataEnvelop.New<DomainEvent>(balloonTitleChanged)); var processPipeActor = Sys.ActorOf(Props.Create(() => new ProcessesPipeActor(catalog))); await processPipeActor.Ask <Initialized>(new Initialize(TestActor)); processPipeActor.Tell(MessageMetadataEnvelop.New <DomainEvent>(balloonCreated)); processPipeActor.Tell(MessageMetadataEnvelop.New <DomainEvent>(balloonTitleChanged)); //process pipe will process domain event linear on each message //but for don't wait for each message execution end, so first will complete process of second message - balloonTitleChanged //after process pipe will proceed with balloonTitleChanged event, pass it linear to two left process managers var transited = ExpectMsg <ProcessTransited>(TimeSpan.FromSeconds(600)); var testCommand = transited.ProducedCommands.OfType <TestCommand>().First(); Assert.Equal(processBId, testCommand.ProcessId); transited = ExpectMsg <ProcessTransited>(); testCommand = transited.ProducedCommands.OfType <TestCommand>().First(); Assert.Equal(processCId, testCommand.ProcessId); //after it process pipe is finished with ballon created message processing, gathering results //and sending it to commandPipe (testActor) var cmdB = ExpectMsg <MessageMetadataEnvelop <ICommand> >(); Assert.Equal(processBId, cmdB.Message.ProcessId); var cmdC = ExpectMsg <MessageMetadataEnvelop <ICommand> >(); Assert.Equal(processCId, cmdC.Message.ProcessId); //than it will report end of domain event processing ExpectMsg <ProcessesTransitComplete>(); //than slow processing of first message will finish //test process actors sends to us messages on complete //wait for test process actor transit on first event transited = ExpectMsg <ProcessTransited>(); testCommand = transited.ProducedCommands.OfType <TestCommand>().First(); Assert.Equal(processAId, testCommand.ProcessId); var cmdA = ExpectMsg <MessageMetadataEnvelop <ICommand> >(); Assert.Equal(processAId, cmdA.Message.ProcessId); //process pipe has only one handler for balloonCreated, so it will finish processing //and send us a message ExpectMsg <ProcessesTransitComplete>(); }
public void Publish(object msg, IMessageMetadata metadata) { Publish(MessageMetadataEnvelop.NewGeneric(msg, metadata)); }