예제 #1
0
            public When_an_event_is_mapped_as_a_delete()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder
                    .Map <ProductDiscontinuedEvent>()
                    .AsDeleteOf(e => e.ProductKey)
                    .ThrowingIfMissing();

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Delete = (key, context) =>
                        {
                            isDeleted = true;
                            return(Task.FromResult(true));
                        }
                    });
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
예제 #2
0
            public When_deleting_a_non_existing_event_should_be_handled_manually()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder
                    .Map <ProductDiscontinuedEvent>()
                    .AsDeleteOf(e => e.ProductKey)
                    .HandlingMissesUsing((key, context) =>
                    {
                        missedKey = key;
                    });

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Delete = (key, context) => Task.FromResult(false)
                    });
                });

                WhenLater(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
예제 #3
0
            public When_an_event_is_mapped_as_a_custom_action()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <object>();
                    mapBuilder.Map <ProductDiscontinuedEvent>().As((@event, context) =>
                    {
                        involvedKey = @event.ProductKey;

                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build(new ProjectorMap <object>
                    {
                        Custom = (context, projector) => projector()
                    });
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new object());
                });
            }
예제 #4
0
            public When_deleting_a_non_existing_event_should_be_handled_manually_from_context()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder
                    .Map <ProductDiscontinuedEvent>()
                    .AsDeleteOf((e, context) => context.EventHeaders["ProductId"] as string)
                    .HandlingMissesUsing((key, context) =>
                    {
                        missedKey = key;
                    });

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Delete = (key, context) => Task.FromResult(false)
                    });
                });

                WhenLater(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext()
                    {
                        EventHeaders = new Dictionary <string, object>(1)
                        {
                            { "ProductId", "1234" }
                        }
                    });
                });
            }
예제 #5
0
            public When_a_condition_is_met()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <object>();
                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .When(e => e.Category == "Hybrids")
                    .As((e, ctx) =>
                    {
                        involvedKey = e.ProductKey;
                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build(new ProjectorMap <object>
                    {
                        Custom = (context, projector) => projector()
                    });
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new object());
                });
            }
            public When_a_condition_is_not_met()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <object>();
                    mapBuilder.Map <ProductAddedToCatalogEvent>()
                    .When(e => e.Category == "Electric")
                    .As((e, ctx) =>
                    {
                        projection.Category = e.Category;

                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new object());
                });
            }
예제 #7
0
 public DomainProjector(IEventMap <ProjectionContext> map, IEnumerable <Projector>?children = null)
 {
     Projector = new Projector(map, children)
     {
         ShouldRetry = ShouldRetry
     };
 }
예제 #8
0
        public void RunAggregateProjection(IActorRef repository)
        {
            EventMap = EventMapBuilder.Build(ProjectorMap);
            var projector = ActorSystem.ActorOf(Props.Create(() => new ProjectorManager <TJournal, TProjectionContext, TProjection, TProjectionId>(repository, EventMap, Journal)), "PersistentIdStream");

            projector.Tell(new BeginProjection());
        }
예제 #9
0
            public When_an_updating_event_should_ignore_missing_projections()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .AsUpdateOf(e => e.ProductKey)
                    .IgnoringMisses()
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;
                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Update = (key, context, projector, createIfMissing) => Task.FromResult(false)
                    });
                });

                WhenLater(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
 public EntityFrameworkEventMapConfigurator(
     IEventMapBuilder <TProjection, TKey, EntityFrameworkProjectionContext> eventMapBuilder,
     Action <TProjection, TKey> setIdentity)
 {
     _setIdentity     = setIdentity ?? throw new ArgumentNullException(nameof(setIdentity));
     _eventMapBuilder = eventMapBuilder ?? throw new ArgumentNullException(nameof(eventMapBuilder));
     _eventMap        = BuildEventMap(eventMapBuilder);
 }
예제 #11
0
        public PaymentProjection(IEventSourcing eventSourcing)
        {
            _eventSourcing = eventSourcing;
            _events        = new Dictionary <Guid, PaymentModel>();

            _map = CreatePaymentEventMap()
                   .BuildBalanceMap();
        }
예제 #12
0
        public InnerProjector(IEventMap <ProjectionContext> map, IEnumerable <InnerProjector> children = null)
        {
            _map = map;

            _children = children?.ToList() ?? new List <InnerProjector>();
            if (_children.Contains(null))
            {
                throw new ArgumentException("There is null child projector.", nameof(children));
            }
        }
예제 #13
0
        public AggregateEventStream(
            IActorRef repository,
            IEventMap <TProjectionContext> eventMap,
            TJournal journal)
        {
            _journal    = journal;
            _eventMap   = eventMap;
            _repository = repository;

            Receive <BeginAggregateEventStream>(Handle);
        }
예제 #14
0
        public void SetUp()
        {
            var dispatcher = new EventDispatcherWithCommandProcessing(new CommandBinder());
            var provider   = new EventMapProvider
            {
                Dispatcher = dispatcher
            };

            _dispatcher = dispatcher;
            _map        = provider.TakeInstance(this, null);
        }
예제 #15
0
        public ProjectorManager(
            IActorRef repository,
            IEventMap <TProjectionContext> eventMap,
            TJournal journal)
        {
            _journal    = journal;
            _repository = repository;
            _eventMap   = eventMap;

            Receive <BeginProjection>(Handle);
            Receive <ReportAggregateId>(Handle);
        }
예제 #16
0
        public NHibernateEventMapConfigurator(
            IEventMapBuilder <TProjection, TKey, NHibernateProjectionContext> mapBuilder,
            IEnumerable <INHibernateChildProjector> children = null)
        {
            if (mapBuilder == null)
            {
                throw new ArgumentNullException(nameof(mapBuilder));
            }

            map           = BuildMap(mapBuilder);
            this.children = children?.ToList() ?? new List <INHibernateChildProjector>();
        }
        public RavenEventMapConfigurator(
            IEventMapBuilder <TProjection, string, RavenProjectionContext> mapBuilder,
            IEnumerable <IRavenChildProjector> children = null)
        {
            if (mapBuilder == null)
            {
                throw new ArgumentNullException(nameof(mapBuilder));
            }

            map           = BuildMap(mapBuilder);
            this.children = children?.ToList() ?? new List <IRavenChildProjector>();
        }
            public When_a_condition_is_not_met_on_a_projection()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder.HandleProjectionModificationsAs(async(key, context, projector, options) =>
                    {
                        projection = new ProductCatalogEntry
                        {
                            Id = key,
                        };

                        await projector(projection);
                    });

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .When(e => e.Category == "Electric")
                    .AsUpdateOf(e => e.ProductKey)
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;

                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        throw new InvalidOperationException("Deletion should not be called.");
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
            public When_an_event_is_mapped_as_a_create_if_does_not_exist()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .AsCreateIfDoesNotExistOf(e => e.ProductKey)
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;
                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleProjectionModificationsAs(async(key, context, projector, options) =>
                    {
                        projection = new ProductCatalogEntry
                        {
                            Id = key,
                        };

                        this.options = options;
                        await projector(projection);
                    });

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        throw new InvalidOperationException("Deletion should not be called.");
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
예제 #20
0
        //protected Source<EventEnvelope, NotUsed> EventStream { get; set; }

        public Projector(
            string id,
            IActorRef repositoryRef,
            IEventMap <TProjectionContext> eventMap)
        {
            Id       = id;
            EventMap = eventMap;
            //this probably needs to be sent the stream reference so that this actor can sink the stream and start processing the messages
            // from the journal, the wierd thing here is the stream can be either from tags or from actual persistence ids (aggregate or saga Ids)
            Receive <CreateProjectorSchema>(Handle);
            Receive <BeginProjectorStream>(Handle);
            Receive <ClearProjectorSchema>(Handle);
            Receive <DropProjectorSchema>(Handle);
            ReceiveAsync <ProjectEvent <TProjectionContext> >(Handle);
        }
예제 #21
0
            public When_a_creating_event_should_allow_manual_handling_of_duplicates()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .AsCreateOf(e => e.ProductKey)
                    .HandlingDuplicatesUsing((duplicate, @event, context) =>
                    {
                        duplicateProjection = existingProjection;
                        return(true);
                    })
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;
                        return(Task.FromResult(0));
                    });

                    existingProjection = new ProductCatalogEntry
                    {
                        Id       = "c350E",
                        Category = "OldCategory",
                    };

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Create = async(key, context, projector, shouldOverwrite) =>
                        {
                            if (shouldOverwrite(existingProjection))
                            {
                                await projector(existingProjection);
                            }
                        }
                    });
                });

                When(async() =>
                {
                    await map.Handle(new ProductAddedToCatalogEvent
                    {
                        Category   = "NewCategory",
                        ProductKey = "c350E"
                    },
                                     new ProjectionContext());
                });
            }
예제 #22
0
        public Projector(IEventMapBuilder <ProjectionContext> eventMapBuilder, IEnumerable <Projector> children = null)
        {
            if (eventMapBuilder == null)
            {
                throw new ArgumentNullException(nameof(eventMapBuilder));
            }

            SetupHandlers(eventMapBuilder);
            map           = eventMapBuilder.Build();
            this.children = children?.ToList() ?? new List <Projector>();

            if (this.children.Contains(null))
            {
                throw new ArgumentException("There is null child projector.", nameof(children));
            }
        }
예제 #23
0
            public When_a_creating_event_must_ignore_an_existing_projection()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .AsCreateOf(e => e.ProductKey).IgnoringDuplicates()
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;
                        return(Task.FromResult(0));
                    });

                    existingProjection = new ProductCatalogEntry
                    {
                        Id       = "c350E",
                        Category = "Fosile",
                    };

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Create = async(key, context, projector, shouldOverwrite) =>
                        {
                            if (shouldOverwrite(existingProjection))
                            {
                                await projector(existingProjection);
                            }
                        }
                    });
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
예제 #24
0
            public When_an_updating_event_should_create_a_missing_projection_from_context()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .AsUpdateOf((e, context) => context.EventHeaders["ProductId"] as string)
                    .CreatingIfMissing()
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;
                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Update = (key, context, projector, createIfMissing) =>
                        {
                            shouldCreate = true;

                            return(Task.FromResult(0));
                        }
                    });
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext()
                    {
                        EventHeaders = new Dictionary <string, object>(1)
                        {
                            { "ProductId", "1234" }
                        }
                    });
                });
            }
            public When_an_event_is_mapped_as_a_custom_action_on_a_projection()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        customActionDecoratorExecuted = true;
                        return(projector());
                    });

                    mapBuilder.HandleProjectionModificationsAs((key, context, projector, options) =>
                    {
                        throw new InvalidOperationException("Modification should not be called.");
                    });

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        throw new InvalidOperationException("Deletion should not be called.");
                    });

                    mapBuilder.Map <ProductDiscontinuedEvent>().As((@event, context) =>
                    {
                        involvedKey = @event.ProductKey;

                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
            public When_an_event_is_mapped_as_a_delete_if_exists()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder.Map <ProductDiscontinuedEvent>().AsDeleteIfExistsOf(e => e.ProductKey);

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        projection = new ProductCatalogEntry
                        {
                            Id      = key,
                            Deleted = true
                        };

                        this.options = options;
                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleProjectionModificationsAs((key, context, projector, options) =>
                    {
                        throw new InvalidOperationException("Modification should not be called.");
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
예제 #27
0
            public When_a_global_filter_is_not_met()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <object>()
                                     .Where((@event, context) =>
                    {
                        if (@event is ProductAddedToCatalogEvent addedEvent)
                        {
                            return(Task.FromResult(addedEvent.Category == "Electric"));
                        }

                        return(Task.FromResult(true));
                    });

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .As((e, ctx) =>
                    {
                        involvedKey = e.ProductKey;

                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build(new ProjectorMap <object>
                    {
                        Custom = (context, projector) => projector()
                    });
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new object());
                });
            }
예제 #28
0
            public When_event_should_create_a_new_projection_from_context()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder.Map <ProductAddedToCatalogEvent>().AsCreateOf((e, context) => context.EventHeaders["ProductId"] as string).Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;

                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Create = async(key, context, projector, shouldOverwrite) =>
                        {
                            projection = new ProductCatalogEntry
                            {
                                Id = key,
                            };

                            await projector(projection);
                        }
                    });
                });

                When(async() =>
                {
                    await map.Handle(new ProductAddedToCatalogEvent
                    {
                        Category = "Hybrids"
                    },
                                     new ProjectionContext()
                    {
                        EventHeaders = new Dictionary <string, object>(1)
                        {
                            { "ProductId", "1234" }
                        }
                    });
                });
            }
예제 #29
0
            public When_an_updating_event_should_throw_on_misses()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder.Map <ProductAddedToCatalogEvent>().AsUpdateOf(e => e.ProductKey).Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;

                        return(Task.FromResult(0));
                    });

                    existingProjection = new ProductCatalogEntry
                    {
                        Id       = "c350E",
                        Category = "OldCategory",
                    };

                    map = mapBuilder.Build(new ProjectorMap <ProductCatalogEntry, string, ProjectionContext>
                    {
                        Update = async(key, context, projector, createIfMissing) =>
                        {
                            if (createIfMissing())
                            {
                                await projector(existingProjection);
                            }
                        }
                    });
                });

                WhenLater(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        ProductKey = "c350E",
                        Category   = "NewCategory"
                    },
                        new ProjectionContext());
                });
            }
예제 #30
0
        public BalanceProjection(IStreamStore streamStore, StreamId streamId)
        {
            var mapBuilder = new EventMapBuilder <Balance>();

            mapBuilder.Map <Deposited>().As((deposited, balance) =>
            {
                balance.Add(deposited.Amount);
            });

            mapBuilder.Map <Withdrawn>().As((withdrawn, balance) =>
            {
                balance.Subtract(withdrawn.Amount);
            });

            _map = mapBuilder.Build(new ProjectorMap <Balance>()
            {
                Custom = (context, projector) => projector()
            });

            streamStore.SubscribeToStream(streamId, null, StreamMessageReceived);
        }
		public void runBeforeEachTest()
		{
			eventDispatcher = new EventDispatcher();
			eventMap = new EventMap();
		}