Beispiel #1
0
        public void Prepare_InsertsEvents(
            [Frozen] Mock <IBatchOperation> operationMock,
            [Frozen] string streamName,
            [Frozen] EventStreamHeader header,
            JournaledEvent[] events,
            AppendOperation operation)
        {
            operation.Prepare(events);

            var version = header.Version;

            foreach (var journaledEvent in events)
            {
                var e = journaledEvent;
                version = version.Increment();

                VerifyInsertOperation(
                    operationMock: operationMock,
                    partitionKey: streamName,
                    rowKey: version.ToString(),
                    verifyColumns: columns =>
                    columns["EventId"].Equals(e.EventId) &&
                    columns["EventType"].Equals(e.EventTypeName));
            }
        }
        private EntityCreatedEvent EventStreamRoundTripEvent(EntityCreatedEvent evt)
        {
            EventStreamHeader header = new EventStreamHeader(new VectorClock(), new Infrastructure.VectorClock(), Guid.NewGuid(), Guid.NewGuid());

            MemoryStream stream = new MemoryStream();

            using (EventStreamWriter writer = new EventStreamWriter(stream, header, false))
            {
                writer.WriteEvent(evt);
            }

            stream.Seek(0, SeekOrigin.Begin);

            using (stream)
                using (EventStreamReader reader = new EventStreamReader(stream))
                {
                    while (reader.Read())
                    {
                        if (reader.ItemType == ItemType.Event)
                        {
                            return((EntityCreatedEvent)reader.CurrentEvent);
                        }
                    }
                }

            throw new InvalidOperationException("The event could not be round tripped");
        }
        public InitialCursorState(EventStreamHeader streamHeader, StreamVersion fromVersion, FetchEvents fetch)
            : base(streamHeader)
        {
            Require.NotNull(fetch, "fetch");

            m_version = fromVersion;
            m_fetch   = fetch;
        }
        private EventStreamCursor(EventStreamHeader streamHeader, StreamVersion fromVersion, FetchEvents fetch)
        {
            Require.NotNull(fetch, "fetch");

            m_state = new InitialCursorState(streamHeader, fromVersion, fetch);
            m_slice = EventStreamSlice.Empty;
            m_cursorStreamVersion = fromVersion;
        }
        public void TwoEqualsHeader_AreSame(EventStreamHeader header)
        {
            var header1 = header;
            var header2 = new EventStreamHeader(header1.ETag, header1.Version);

            Assert.Equal(header1, header2);
            Assert.True(header1 == header2);
        }
        public void TwoHeadersWithDifferentETagValue_AreNotSame(string etag1, string etag2, StreamVersion version)
        {
            var header1 = new EventStreamHeader(etag1, version);
            var header2 = new EventStreamHeader(etag2, version);

            Assert.NotEqual(header1, header2);
            Assert.False(header1 == header2);
        }
        public void TwoHeadersWithDifferentVersionValue_AreNotSame(string etag, StreamVersion version1, StreamVersion version2)
        {
            var header1 = new EventStreamHeader(etag, version1);
            var header2 = new EventStreamHeader(etag, version2);

            Assert.NotEqual(header1, header2);
            Assert.False(header1 == header2);
        }
Beispiel #8
0
        public FetchingCursorState(
            EventStreamHeader streamHeader,
            StreamVersion sliceSteamVersion,
            FetchEvents fetch) : base(streamHeader)
        {
            Require.NotNull(fetch, "fetch");

            m_sliceSteamVersion = sliceSteamVersion;
            m_fetch             = fetch;
        }
        public async Task AppendEvents_AppendEventsToJournal(
            [Frozen] EventStreamHeader header,
            [Frozen] Mock<IEventJournal> journalMock,
            EventStreamWriter writer,
            JournaledEvent[] events)
        {
            await writer.AppendEventsAsync(events);

            journalMock.Verify(journal => journal.AppendEventsAsync(
                writer.StreamName,
                header,
                It.Is<IReadOnlyCollection<JournaledEvent>>(e => e.Count == events.Length)));
        }
Beispiel #10
0
        private async Task <EventStreamHeader> AppendEventsAsync(
            string streamName,
            EventStreamHeader header,
            int batchSize   = EVENTS_COUNT,
            int batchNumber = BATCH_NUMBER)
        {
            var batches = PrepareBatch(batchSize, batchNumber);

            var currentPosition = header;

            while (batches.Any())
            {
                currentPosition = await Journal.AppendEventsAsync(streamName, currentPosition, batches.Dequeue());
            }

            return(currentPosition);
        }
        public async Task StreamPosition_AfterWriteAsyncCall_UpdatedStreamVersionValue(
            [Frozen] Mock<IEventJournal> journalMock,
            EventStreamHeader header,
            EventStreamWriter writer,
            JournaledEvent[] events)
        {
            journalMock
                .Setup(self => self.AppendEventsAsync(
                    It.IsAny<string>(),
                    It.IsAny<EventStreamHeader>(),
                    It.IsAny<IReadOnlyCollection<JournaledEvent>>()))
                .Returns(header.YieldTask());

            await writer.AppendEventsAsync(events);

            Assert.Equal(header.Version, writer.StreamVersion);
        }
Beispiel #12
0
        public void Prepare_ForUnknownHeader_InsertsHeaderRow(
            [Frozen] Mock <IBatchOperation> operationMock,
            [Frozen] string streamName,
            [Frozen] EventStreamHeader header,
            JournaledEvent[] events,
            AppendOperation operation)
        {
            var targetVersion = (int)header.Version.Increment(events.Count());

            operation.Prepare(events);

            VerifyInsertOperation(
                operationMock,
                streamName,
                "HEAD",
                name => name.Equals("Version"),
                value => value.Equals(targetVersion));
        }
        public async Task AppendEvents_DeletesPendingNotification(
            [Frozen] Mock<IEventJournal> journalMock,
            [Frozen] Mock<IPendingNotifications> pendingNotificationMock,
            [Frozen] EventStreamHeader header,
            EventStreamWriter writer,
            JournaledEvent[] events)
        {
            journalMock
                .Setup(self => self.AppendEventsAsync(
                    It.IsAny<string>(),
                    It.IsAny<EventStreamHeader>(),
                    It.IsAny<IReadOnlyCollection<JournaledEvent>>()))
                .Returns(header.YieldTask());

            await writer.AppendEventsAsync(events);

            pendingNotificationMock.Verify(notifications => notifications.DeleteAsync(
                writer.StreamName,
                header.Version));
        }
        public EventStreamWriter(
            string streamName,
            IEventStoreConnectionState connectionState,
            EventStreamHeader endOfStream,
            IEventJournal journal,
            IEventMutationPipeline mutationPipeline,
            INotificationHub notificationHub,
            IPendingNotifications pendingNotification) : base(streamName, connectionState)
        {
            Require.NotEmpty(streamName, "streamName");
            Require.NotNull(journal, "journal");
            Require.NotNull(mutationPipeline, "mutationPipeline");
            Require.NotNull(notificationHub, "notificationHub");
            Require.NotNull(pendingNotification, "pendingNotification");

            m_endOfStream         = endOfStream;
            m_journal             = journal;
            m_mutationPipeline    = mutationPipeline;
            m_notificationHub     = notificationHub;
            m_pendingNotification = pendingNotification;
        }
Beispiel #15
0
        public async Task <FetchEventsResult> FetchStreamEvents(string stream, EventStreamHeader header, StreamVersion fromVersion, int sliceSize)
        {
            // fromVersion already in slice
            var isFetchingCompleted = false;
            var nextSliceVersion    = fromVersion.Increment(sliceSize - 1);

            if (nextSliceVersion >= header.Version)
            {
                nextSliceVersion    = header.Version;
                isFetchingCompleted = true;
            }

            const string queryTemplate =
                "((PartitionKey eq '{0}') and (RowKey eq 'HEAD')) or " +
                "((PartitionKey eq '{0}') and (RowKey ge '{1}' and RowKey le '{2}'))";

            var query = m_table.PrepareEntityFilterRangeQuery(
                queryTemplate.FormatString(
                    stream,
                    fromVersion.ToString(),
                    nextSliceVersion.ToString()));

            var queryResult = await query.ExecuteAsync();

            var events = new SortedList <StreamVersion, JournaledEvent>(sliceSize);

            foreach (var properties in queryResult)
            {
                var rowKey = (string)properties[KnownProperties.RowKey];
                if (!rowKey.EqualsCi("HEAD"))
                {
                    events.Add(StreamVersion.Parse((string)properties[KnownProperties.RowKey]), JournaledEvent.Create(properties));
                }
            }

            return(new FetchEventsResult(isFetchingCompleted, events));
        }
        public void PublishEvents(IEnumerable <ModelEvent> events)
        {
            UpdateEventCache();

            var eventsToPublish = events.Where(e => !_publishedEvents.Contains(e.EventID)).OrderBy(e => e.EventVector).ToList();

            if (eventsToPublish.Count == 0)
            {
                return;
            }

            var streamId             = Guid.NewGuid();
            EventStreamHeader header = new EventStreamHeader(eventsToPublish[0].EventVector, eventsToPublish.Last().EventVector, _deviceId, streamId);

            string filePath = Path.Combine(_deviceDirectory, streamId.ToString() + ".eventstream");

            using (Stream file = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write))
                using (EventStreamWriter writer = new EventStreamWriter(file, header, true))
                {
                    writer.WriteEvents(eventsToPublish);
                }

            FileEventStream stream = new FileEventStream(filePath);

            _cachedEventStreams.Add(filePath, stream);

            var streamEventIDs = eventsToPublish.Select(e => e.EventID).ToList();

            foreach (var eventId in streamEventIDs)
            {
                if (!_publishedEvents.Add(eventId))
                {
                    throw new InvalidOperationException("This eventID already exists!");
                }
            }
            _eventsInStreams.Add(filePath, streamEventIDs);
        }
        public async Task AppendEventsAsync(IReadOnlyCollection <JournaledEvent> events)
        {
            Require.NotNull(events, "events");

            ConnectionState.EnsureConnectionIsActive();

            if (events.Count == 0)
            {
                return;
            }

            var fromVersion   = m_endOfStream.Version;
            var mutatedEvents = new List <JournaledEvent>(events.Count);

            mutatedEvents.AddRange(events.Select(journaledEvent => m_mutationPipeline.Mutate(journaledEvent)));

            await m_pendingNotification.AddAsync(StreamName, fromVersion, mutatedEvents.Count);

            m_endOfStream = await m_journal.AppendEventsAsync(StreamName, m_endOfStream, mutatedEvents);

            await m_notificationHub.NotifyAsync(new EventStreamUpdated(StreamName, fromVersion, m_endOfStream.Version));

            await m_pendingNotification.DeleteAsync(StreamName, fromVersion);
        }
        public void TestPositiveEncode()
        {
            foreach (var entry in _positiveDecodedTestCases)
            {
                byte[] payload     = null;
                var    headersList = new List <IEventStreamHeader>();

                //read the data to encode, then add it to payload and headers list.
                var decodedDoc = entry.Value;
                var jsonStr    = Encoding.UTF8.GetString(decodedDoc);
                var data       = JsonMapper.ToObject(jsonStr);

                if (data[PayloadField] != null)
                {
                    var base64Payload = (String)data[PayloadField];
                    payload = Convert.FromBase64String(base64Payload);
                }

                if (data[HeaderField] != null)
                {
                    var headersCollection = data[HeaderField];

                    foreach (var header in headersCollection.OfType <JsonData>())
                    {
                        var headerName  = (string)header[HeaderNameField];
                        var headerValue = new EventStreamHeader(headerName);

                        var type = (EventStreamHeaderType)(int)header[HeaderTypeField];

                        switch (type)
                        {
                        case EventStreamHeaderType.String:
                            var strVal = Encoding.UTF8.GetString(Convert.FromBase64String((string)header[HeaderValueField]));
                            headerValue.SetString(strVal);
                            break;

                        case EventStreamHeaderType.UUID:
                            var uuidVal = Convert.FromBase64String((string)header[HeaderValueField]);
                            headerValue.SetUUID(new Guid(uuidVal));
                            break;

                        case EventStreamHeaderType.ByteBuf:
                            var byteBuf = Convert.FromBase64String((string)header[HeaderValueField]);
                            headerValue.SetByteBuf(byteBuf);
                            break;

                        case EventStreamHeaderType.BoolFalse:
                        case EventStreamHeaderType.BoolTrue:
                            var boolVal = (bool)header[HeaderValueField];
                            headerValue.SetBool(boolVal);
                            break;

                        case EventStreamHeaderType.Byte:
                            var byteVal = (byte)(int)header[HeaderValueField];
                            headerValue.SetByte(byteVal);
                            break;

                        case EventStreamHeaderType.Int16:
                            var int16Val = (short)header[HeaderValueField];
                            headerValue.SetInt16(int16Val);
                            break;

                        case EventStreamHeaderType.Int32:
                            var int32Val = (int)header[HeaderValueField];
                            headerValue.SetInt32(int32Val);
                            break;

                        case EventStreamHeaderType.Int64:
                            var intVal = (long)header[HeaderValueField];
                            headerValue.SetInt64(intVal);
                            break;

                        case EventStreamHeaderType.Timestamp:
                            var dateVal = (long)header[HeaderValueField];

                            /* we only do this in this spot because we're setting it from the unix epoch directly.
                             * normal API usage, you can use DateTime as a first class citizen. */
                            headerValue.SetTimestamp(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(dateVal));
                            break;

                        default:
                            break;
                        }

                        headersList.Add(headerValue);
                    }
                }

                //create the message, and serialize it, it should equal the original encoded data.
                var message = new EventStreamMessage(headersList, payload);
                CollectionAssert.Equals(_positiveEncodedTestCases[entry.Key], message.ToByteArray());
            }
        }
 public void IsNewStream_ForNotUnknownHeader_ReturnsFalse(EventStreamHeader header)
 {
     Assert.False(EventStreamHeader.IsNewStream(header));
 }
 public void IsNewStream_ForUnknownHeader_ReturnsTrue()
 {
     Assert.True(EventStreamHeader.IsNewStream(EventStreamHeader.Unknown));
 }
        public async Task MoveToEndOfStreamAsync()
        {
            ConnectionState.EnsureConnectionIsActive();

            m_endOfStream = await m_journal.ReadStreamHeaderAsync(StreamName);
        }
Beispiel #22
0
 public AppendOperation CreateAppendOperation(string streamName, EventStreamHeader header)
 {
     return(new AppendOperation(m_table, streamName, header));
 }
 public void TwoNotEqualsHeader_AreNotSame(EventStreamHeader header1, EventStreamHeader header2)
 {
     Assert.NotEqual(header1, header2);
     Assert.False(header1 == header2);
 }
 public static IEventStreamCursor CreateEmptyCursor(EventStreamHeader streamHeader, StreamVersion fromVersion)
 {
     return(new EventStreamCursor(streamHeader, fromVersion));
 }
 public static IEventStreamCursor CreateActiveCursor(EventStreamHeader streamHeader, StreamVersion fromVersion, FetchEvents fetch)
 {
     return(new EventStreamCursor(streamHeader, fromVersion, fetch));
 }
 private EventStreamCursor(EventStreamHeader streamHeader, StreamVersion fromVersion)
 {
     m_state = new EndOfStreamCursorState(streamHeader);
     m_slice = EventStreamSlice.Empty;
     m_cursorStreamVersion = fromVersion;
 }
Beispiel #27
0
 protected CursorState(EventStreamHeader streamHeader)
 {
     StreamHeader = streamHeader;
 }
Beispiel #28
0
 public MemoryEventStream(Func <IEnumerable <ModelEvent> > intializeEventIterator, EventStreamHeader header)
 {
     _intializeEventIterator = intializeEventIterator;
     _header = header;
 }
Beispiel #29
0
 public EndOfStreamCursorState(EventStreamHeader streamHeader) : base(streamHeader)
 {
 }
 public void StreamPosition_ReturnsStreamVersionValue([Frozen] EventStreamHeader header, EventStreamWriter writer)
 {
     Assert.Equal(header.Version, writer.StreamVersion);
 }