コード例 #1
0
        public async Task ProjectionStore_Trace_default_behavior_can_be_overridden()
        {
            var receivedGetKey        = "";
            var receivedGetProjection = 0;
            var receivedPutKey        = "";
            var receivedPutProjection = 0;

            var store = ProjectionStore
                        .Create <string, int>(
                get: async key => 41,
                put: async(key, count) => { })
                        .Trace(
                get: (key, count) =>
            {
                receivedGetKey        = key;
                receivedGetProjection = count;
            },
                put: (key, count) =>
            {
                receivedPutKey        = key;
                receivedPutProjection = count;
            }
                );

            await store.Get("any key");

            receivedGetKey.Should().Be("any key");
            receivedGetProjection.Should().Be(41);

            await store.Put("some other key", 57);

            receivedPutKey.Should().Be("some other key");
            receivedPutProjection.Should().Be(57);
        }
コード例 #2
0
        protected void GivenThereAreNoProjections()
        {
            ProjectId = DataFixture.Create <Guid>();
            ToggleKey = DataFixture.Create <string>();

            ProjectionStore.WhenForAnyArgs(ps => ps.Get(Arg.Any <string>()))
            .Do(ci => throw new Evelyn.Core.ReadModel.ProjectionNotFoundException());
        }
コード例 #3
0
        protected async Task ThenTheStoredProjectionIsUnchanged()
        {
            await ProjectionStore.DidNotReceiveWithAnyArgs().Create(Arg.Any <string>(), Arg.Any <TProjection>());

            await ProjectionStore.DidNotReceiveWithAnyArgs().Update(Arg.Any <string>(), Arg.Any <TProjection>());

            await ProjectionStore.DidNotReceiveWithAnyArgs().Delete(Arg.Any <string>());
        }
コード例 #4
0
        private void ThenTheProjectionContainsTheToggleDetails()
        {
            // TODO: move
            ProjectionStore.Received().Create(Core.ReadModel.Projections.ToggleDetails.Projection.StoreKey(ProjectId, ToggleKey), UpdatedProjection);

            UpdatedProjection.Toggle.Key.Should().Be(Event.Key);
            UpdatedProjection.Toggle.Name.Should().Be(Event.Name);
        }
コード例 #5
0
        private void ThenTheProjectionContainsTheProjectDetails()
        {
            ProjectionStore.Received().Create(Projection.StoreKey(ProjectId), UpdatedProjection);

            var project = UpdatedProjection.Project;

            project.Name.Should().Be(Event.Name);
            project.Environments.Should().BeEmpty();
            project.Toggles.Should().BeEmpty();
        }
コード例 #6
0
        public async Task By_default_ProjectionStore_Trace_writes_projection_store_misses_during_Get_to_trace_output()
        {
            var store = ProjectionStore.Create <string, BalanceProjection>(
                get: async key => null,
                put: async(key, p) => { });

            await store.Trace().Get("the-stream-id");

            traceListener.Messages
            .Should()
            .Contain("[Get] no projection for stream the-stream-id");
        }
コード例 #7
0
        public async Task The_same_projection_is_not_queried_more_than_once_during_a_batch()
        {
            var streamId   = "hello";
            var projection = new BalanceProjection
            {
                CursorPosition = 1
            };

            var getCount        = 0;
            var projectionStore = ProjectionStore.Create <string, BalanceProjection>(
                get: async key =>
            {
                if (key.Contains(streamId))
                {
                    Console.WriteLine("Get");
                    Interlocked.Increment(ref getCount);
                }
                return(projection);
            },
                put: async(key, p) =>
            {
                if (streamId == key)
                {
                    Console.WriteLine("Put");
                }
                projection = p;
            });

            var catchup = StreamCatchup.All(streamSource.StreamPerAggregate());

            catchup.Subscribe(new BalanceProjector(), projectionStore);

            store.WriteEvents(streamId);
            store.WriteEvents(streamId);
            store.WriteEvents(streamId);

            await catchup.RunSingleBatch();

            getCount.Should().Be(1);
        }
コード例 #8
0
        protected ProjectionBuilderHarness()
        {
            DataFixture     = new Fixture();
            StoppingToken   = default;
            ProjectionStore = Substitute.For <IProjectionStore <TProjection> >();

            _deserializeWithPrivateSetters = new JsonSerializerSettings
            {
                ContractResolver = new JsonPrivateResolver()
            };

            ProjectionStore.Get(Arg.Any <string>())
            .Returns(ps => CopyOf(OriginalProjection));

            ProjectionStore.WhenForAnyArgs(ps => ps.Create(Arg.Any <string>(), Arg.Any <TProjection>()))
            .Do(ci => UpdatedProjection = ci.ArgAt <TProjection>(1));

            ProjectionStore.WhenForAnyArgs(ps => ps.Update(Arg.Any <string>(), Arg.Any <TProjection>()))
            .Do(ci => UpdatedProjection = ci.ArgAt <TProjection>(1));

            StreamPosition = long.MinValue;
        }
コード例 #9
0
 private void ThenTheProjectionIsDeleted()
 {
     ProjectionStore.Received().Delete(Projection.StoreKey(ProjectId, ToggleKey));
 }
コード例 #10
0
 private void ThenTheProjectionIsDeleted()
 {
     ProjectionStore.Received().Delete(Projection.StoreKey(ProjectId, EnvironmentKey));
 }
コード例 #11
0
 protected void ThenTheProjectionIsCreated()
 {
     ProjectionStore.Received().Create(Core.ReadModel.Projections.AccountProjects.Projection.StoreKey(AccountId), UpdatedProjection);
 }
コード例 #12
0
        private void ThenTheProjectionContainsTheEnvironmentState()
        {
            ProjectionStore.Received().Create(Projection.StoreKey(ProjectId, EnvironmentKey), UpdatedProjection);

            UpdatedProjection.EnvironmentState.ToggleStates.Should().BeEquivalentTo(Event.ToggleStates);
        }
コード例 #13
0
        public async Task AllChanges_doesnt_miss_aggregates()
        {
            var AggregateId1 = Guid.NewGuid();
            var AggregateId2 = Guid.NewGuid();
            var AggregateId3 = Guid.NewGuid();
            var AggregateId4 = Guid.NewGuid();

            var storableEvents = new[]
            {
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType1).Name, AggregateId = AggregateId1, SequenceNumber = 1, Id = 7, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType2).Name, AggregateId = AggregateId1, SequenceNumber = 2, Id = 8, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType3).Name, AggregateId = AggregateId1, SequenceNumber = 3, Id = 9, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType4).Name, AggregateId = AggregateId1, SequenceNumber = 4, Id = 10, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType5).Name, AggregateId = AggregateId1, SequenceNumber = 5, Id = 11, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 6, Id = 12, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 7, Id = 13, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId1, SequenceNumber = 8, Id = 14, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 9, Id = 15, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 10, Id = 16, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId1, SequenceNumber = 11, Id = 18, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 12, Id = 19, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 13, Id = 20, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId1, SequenceNumber = 14, Id = 21, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 15, Id = 22, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 16, Id = 23, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType1).Name, AggregateId = AggregateId2, SequenceNumber = 1, Id = 24, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType9).Name, AggregateId = AggregateId2, SequenceNumber = 2, Id = 25, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType10).Name, AggregateId = AggregateId2, SequenceNumber = 3, Id = 26, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType11).Name, AggregateId = AggregateId2, SequenceNumber = 4, Id = 27, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType12).Name, AggregateId = AggregateId2, SequenceNumber = 5, Id = 28, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType13).Name, AggregateId = AggregateId2, SequenceNumber = 6, Id = 29, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType14).Name, AggregateId = AggregateId2, SequenceNumber = 7, Id = 40, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType1).Name, AggregateId = AggregateId3, SequenceNumber = 1, Id = 1, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType9).Name, AggregateId = AggregateId3, SequenceNumber = 2, Id = 2, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType10).Name, AggregateId = AggregateId3, SequenceNumber = 3, Id = 3, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType11).Name, AggregateId = AggregateId3, SequenceNumber = 4, Id = 4, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType12).Name, AggregateId = AggregateId3, SequenceNumber = 5, Id = 5, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType13).Name, AggregateId = AggregateId3, SequenceNumber = 6, Id = 6, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType14).Name, AggregateId = AggregateId3, SequenceNumber = 7, Id = 17, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType1).Name, AggregateId = AggregateId4, SequenceNumber = 1, Id = 30, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType2).Name, AggregateId = AggregateId4, SequenceNumber = 2, Id = 31, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType3).Name, AggregateId = AggregateId4, SequenceNumber = 3, Id = 32, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType4).Name, AggregateId = AggregateId4, SequenceNumber = 4, Id = 33, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType5).Name, AggregateId = AggregateId4, SequenceNumber = 5, Id = 34, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 6, Id = 35, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 7, Id = 36, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId4, SequenceNumber = 8, Id = 37, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 9, Id = 38, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 10, Id = 39, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId4, SequenceNumber = 11, Id = 41, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 12, Id = 42, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 13, Id = 43, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId4, SequenceNumber = 14, Id = 44, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 15, Id = 45, Body = "{}"
                },
                new StorableEvent {
                    StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 16, Id = 46, Body = "{}"
                },
            }.AsQueryable();


            {
                var allChanges = EventStream.PerAggregate("Snarf", () => new DisposableQueryable <StorableEvent>(
                                                              () => { }, storableEvents));

                var aggregator = Aggregator.Create <int, IEvent>((oldCount, batch) =>
                {
                    var eventType14s = batch.OfType <AggregateB.EventType14>();
                    var newCount     = eventType14s.Count();
                    return(oldCount + newCount);
                }).Trace();

                var catchup = StreamCatchup.All(allChanges);

                var count = 0;
                var store = ProjectionStore.Create <string, int>(async _ =>
                {
                    //await Task.Delay(TimeSpan.FromMilliseconds(1));
                    return(count);
                }, async(_, newCount) => count = newCount);
                catchup.Subscribe(aggregator, store);
                catchup.RunUntilCaughtUp().Wait();
                count.Should().Be(2);
            }
        }