public Task StoreSnapshotAsync <TSnapshot>(
            ThingyId thingyId,
            int aggregateSequenceNumber,
            TSnapshot snapshot)
            where TSnapshot : ISnapshot
        {
            var snapshotDefinition = SnapshotDefinitionService.GetDefinition(typeof(TSnapshot));
            var snapshotMetadata   = new SnapshotMetadata
            {
                AggregateId             = thingyId.Value,
                AggregateName           = "ThingyAggregate",
                AggregateSequenceNumber = aggregateSequenceNumber,
                SnapshotName            = snapshotDefinition.Name,
                SnapshotVersion         = snapshotDefinition.Version,
            };

            return(SnapshotPersistence.SetSnapshotAsync(
                       typeof(ThingyAggregate),
                       thingyId,
                       new SerializedSnapshot(
                           JsonConvert.SerializeObject(snapshotMetadata),
                           JsonConvert.SerializeObject(snapshot),
                           snapshotMetadata),
                       CancellationToken.None));
        }
Exemple #2
0
        public async Task <IActionResult> Ping(ThingyId id)
        {
            var pingCommand = new ThingyPingCommand(id, PingId.New);
            await _commandBus.PublishAsync(pingCommand, CancellationToken.None).ConfigureAwait(false);

            return(Ok());
        }
 protected async Task PublishPingCommandAsync(ThingyId thingyId, int count = 1)
 {
     for (var i = 0; i < count; i++)
     {
         await CommandBus.PublishAsync(new ThingyPingCommand(thingyId, PingId.New), CancellationToken.None).ConfigureAwait(false);
     }
 }
Exemple #4
0
 protected async Task PublishPingCommandAsync(ThingyId thingyId, int count = 1)
 {
     for (var i = 0; i < count; i++)
     {
         await CommandBus.PublishAsync(new ThingyPingCommand(thingyId, PingId.New), CancellationToken.None).ConfigureAwait(false);
     }
 }
Exemple #5
0
        public void NewDeterministic_IsValid()
        {
            // Arrange
            var testId = ThingyId.NewDeterministic(Guid.NewGuid(), Guid.NewGuid().ToString());

            // Assert
            ThingyId.IsValid(testId.Value).Should().BeTrue(testId.Value);
        }
Exemple #6
0
        public void New_IsValid()
        {
            // Arrange
            var testId = ThingyId.New;

            // Assert
            ThingyId.IsValid(testId.Value).Should().BeTrue(testId.Value);
        }
        public async Task <IHttpActionResult> Ping(string id)
        {
            var testId      = ThingyId.With(id);
            var pingCommand = new ThingyPingCommand(testId, PingId.New);
            await _commandBus.PublishAsync(pingCommand, CancellationToken.None).ConfigureAwait(false);

            return(Ok());
        }
        protected async Task <PingId> PublishPingCommandAsync(
            ThingyId thingyId,
            CancellationToken cancellationToken = default)
        {
            var pingIds = await PublishPingCommandsAsync(thingyId, 1, cancellationToken).ConfigureAwait(false);

            return(pingIds.Single());
        }
Exemple #9
0
        private Task <ThingySaga> LoadSagaAsync(ThingyId thingyId)
        {
            // This is specified in the ThingySagaLocator
            var expectedThingySagaId = new ThingySagaId($"saga-{thingyId.Value}");

            return(AggregateStore.LoadAsync <ThingySaga, ThingySagaId>(
                       expectedThingySagaId,
                       CancellationToken.None));
        }
        protected async Task <ThingySnapshot> LoadSnapshotAsync(ThingyId thingyId)
        {
            var snapshotContainer = await SnapshotStore.LoadSnapshotAsync <ThingyAggregate, ThingyId, ThingySnapshot>(
                thingyId,
                CancellationToken.None)
                                    .ConfigureAwait(false);

            return((ThingySnapshot)snapshotContainer?.Snapshot);
        }
Exemple #11
0
        public void DifferentAreNotEqual()
        {
            // Arrange
            var id1 = ThingyId.With("thingy-7ddc487f-02ad-4be3-a6ef-71203d333c61");
            var id2 = ThingyId.With("thingy-d15b1562-11f2-4645-8b1a-f8b946b566d3");

            // Assert
            id1.Equals(id2).Should().BeFalse();
            (id1 == id2).Should().BeFalse();
        }
Exemple #12
0
        public void InputOutput()
        {
            // Arrange
            var guid = Guid.NewGuid();

            // Act
            var thingyId = ThingyId.With(guid);

            // Assert
            thingyId.GetGuid().Should().Be(guid);
        }
Exemple #13
0
        public void ManuallyCreatedIsOk()
        {
            // Arrange
            const string value = "thingy-d15b1562-11f2-4645-8b1a-f8b946b566d3";

            // Act
            var testId = ThingyId.With(value);

            // Test
            testId.Value.Should().Be(value);
        }
Exemple #14
0
        public void SameIdsAreEqual()
        {
            // Arrange
            const string value = "thingy-d15b1562-11f2-4645-8b1a-f8b946b566d3";
            var          id1   = ThingyId.With(value);
            var          id2   = ThingyId.With(value);

            // Assert
            id1.Equals(id2).Should().BeTrue();
            (id1 == id2).Should().BeTrue();
        }
Exemple #15
0
        public void Arguments(string aggregateId, int magicNumber, string expectedSouceId)
        {
            // Arrange
            var testId  = ThingyId.With(aggregateId);
            var command = new MyDistinctCommand(testId, magicNumber);

            // Act
            var sourceId = command.SourceId;

            // Assert
            sourceId.Value.Should().Be(expectedSouceId);
        }
Exemple #16
0
        public void NewDeterministic_ReturnsKnownResult()
        {
            // Arrange
            var          namespaceId = Guid.Parse("769077C6-F84D-46E3-AD2E-828A576AAAF3");
            const string name        = "fantastic 4";

            // Arrange
            var testId = ThingyId.NewDeterministic(namespaceId, name);

            // Assert
            testId.Value.Should().Be("thingy-da7ab6b1-c513-581f-a1a0-7cdf17109deb");
            ThingyId.IsValid(testId.Value).Should().BeTrue();
        }
Exemple #17
0
        public void WithValidValue(string value, string expectedGuidValue)
        {
            // Arrange
            ThingyId thingyId     = null;
            var      expectedGuid = Guid.Parse(expectedGuidValue);

            // Act
            Assert.DoesNotThrow(() => thingyId = ThingyId.With(value));

            // Assert
            thingyId.Should().NotBeNull();
            thingyId.Value.Should().Be(value);
            thingyId.GetGuid().Should().Be(expectedGuid);
        }
        protected async Task <IReadOnlyCollection <PingId> > PublishPingCommandsAsync(
            ThingyId thingyId,
            int count,
            CancellationToken cancellationToken = default)
        {
            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            var pingIds = new List <PingId>();

            for (var i = 0; i < count; i++)
            {
                var pingId = PingId.New;
                await CommandBus.PublishAsync(new ThingyPingCommand(thingyId, pingId), cancellationToken).ConfigureAwait(false);

                pingIds.Add(pingId);
            }

            return(pingIds);
        }
        public async Task EventsContainMetadata()
        {
            ThingyId id = ThingyId.New;

            // Arrange + Act
            await GetAsync($"thingy/ping?id={id}").ConfigureAwait(false);

            // Assert
            var events = await EventStore.LoadEventsAsync <ThingyAggregate, ThingyId>(id, CancellationToken.None);

            IMetadata metadata = events.Single().Metadata;

            metadata.Should().Contain(new[]
            {
                new KeyValuePair <string, string>("user_claim[sid]", "test-sid"),
                new KeyValuePair <string, string>("user_claim[role]", "test-role-1;test-role-2")
            }
                                      );

            metadata.Should().NotContain(
                new KeyValuePair <string, string>("user_claim[name]", "test-name"));
        }
        private List <IStep> CreateSteps(ThingyId id)
        {
            var steps = new List <IStep>
            {
                new Step <bool>(
                    CancellationBoundary.BeforeUpdatingAggregate,
                    _eventPersistence.LoadCompletionSource),

                new Step <bool>(
                    CancellationBoundary.BeforeCommittingEvents,
                    _commandHandler.ExecuteCompletionSource,
                    () => Task.FromResult(_commandHandler.HasBeenCalled),
                    v => v.Should().BeTrue(),
                    v => v.Should().BeFalse()),

                new Step <IReadOnlyCollection <ICommittedDomainEvent> >(
                    CancellationBoundary.BeforeUpdatingReadStores,
                    _eventPersistence.CommitCompletionSource,
                    () => _eventPersistence.LoadCommittedEventsAsync(id, 0, CancellationToken.None),
                    v => v.Should().NotBeEmpty(),
                    v => v.Should().BeEmpty()),

                new Step <ReadModelEnvelope <InMemoryThingyReadModel> >(
                    CancellationBoundary.BeforeNotifyingSubscribers,
                    _readStore.UpdateCompletionSource,
                    () => _readStore.GetAsync(id.ToString(), CancellationToken.None),
                    v => v.ReadModel.Should().NotBeNull(),
                    v => v.ReadModel.Should().BeNull()),

                new Step <bool>(
                    CancellationBoundary.CancelAlways,
                    _subscriber.HandleCompletionSource,
                    () => Task.FromResult(_subscriber.HasHandled),
                    v => v.Should().BeTrue(),
                    v => v.Should().BeFalse())
            };

            return(steps);
        }
Exemple #21
0
        protected IDomainEvent <ThingyAggregate, ThingyId> ToDomainEvent <TAggregateEvent>(
            ThingyId thingyId,
            TAggregateEvent aggregateEvent,
            int aggregateSequenceNumber = 0)
            where TAggregateEvent : IAggregateEvent
        {
            var metadata = new Metadata
            {
                Timestamp = A <DateTimeOffset>(),
                SourceId  = A <SourceId>(),
            };

            if (aggregateSequenceNumber == 0)
            {
                aggregateSequenceNumber = A <int>();
            }

            return(DomainEventFactory.Create <ThingyAggregate, ThingyId>(
                       aggregateEvent,
                       metadata,
                       thingyId,
                       aggregateSequenceNumber));
        }
Exemple #22
0
        public void UncomittedEventIdsShouldBeDeterministic()
        {
            // Arrange
            Inject(ThingyId.With("thingy-75e925aa-9b01-4615-89ee-2a2ecf91d7e8"));

            // Act
            Sut.Ping(A <PingId>());
            Sut.Ping(A <PingId>());

            // Assert
            var eventIdGuids = Sut.UncommittedEvents
                               .Select(e => e.Metadata.EventId.Value)
                               .ToList();

            // GuidFactories.Deterministic.Namespaces.Events, $"{thingyId.Value}-v1"
            eventIdGuids[0]
            .Should()
            .Be("event-3dde5ccb-b594-59b4-ad0a-4d432ffce026");
            // GuidFactories.Deterministic.Namespaces.Events, $"{thingyId.Value}-v2"
            eventIdGuids[1]
            .Should()
            .Be("event-2e79868f-6ef7-5c88-a941-12ae7ae801c7");
        }
 public ThingySagaStartedEvent(ThingyId thingyId)
 {
     ThingyId = thingyId;
 }
 private async Task<IReadOnlyCollection<ThingyMessage>> CreateAndPublishThingyMessagesAsync(ThingyId thingyId, int count)
 {
     var thingyMessages = Fixture.CreateMany<ThingyMessage>(count).ToList();
     await Task.WhenAll(thingyMessages.Select(m => CommandBus.PublishAsync(new ThingyAddMessageCommand(thingyId, m)))).ConfigureAwait(false);
     return thingyMessages;
 }
Exemple #25
0
 public ThingyGetMessagesQuery(
     ThingyId thingyId)
 {
     ThingyId = thingyId;
 }
 public ThingyGetQuery(
     ThingyId thingyId)
 {
     ThingyId = thingyId;
 }
 public void Apply(ThingySagaStartedEvent aggregateEvent)
 {
     _thingyId = aggregateEvent.ThingyId;
 }
 public LocalTestAggregate(ThingyId id) : base(id)
 {
 }
Exemple #29
0
 public void CannotCreateBadIds(string badIdValue)
 {
     // Act
     Assert.Throws <ArgumentException>(() => ThingyId.With(badIdValue)).Message.Should().Contain("Identity is invalid:");
 }
        private async Task <IReadOnlyCollection <ThingyMessage> > CreateAndPublishThingyMessagesAsync(ThingyId thingyId, int count)
        {
            var thingyMessages = Fixture.CreateMany <ThingyMessage>(count).ToList();
            await Task.WhenAll(thingyMessages.Select(m => CommandBus.PublishAsync(new ThingyAddMessageCommand(thingyId, m)))).ConfigureAwait(false);

            return(thingyMessages);
        }
 public ThingyGetVersionQuery(
     ThingyId thingyId)
 {
     ThingyId = thingyId;
 }
 protected Task <ThingyAggregate> LoadAggregateAsync(ThingyId thingyId)
 {
     return(AggregateStore.LoadAsync <ThingyAggregate, ThingyId>(thingyId));
 }