public void setting_empty_metadata_works()
        {
            _connection.SetStreamMetadataAsync(_stream, ExpectedVersion.EmptyStream, (byte[])null).Wait();

            var meta = _connection.GetStreamMetadataAsRawBytesAsync(_stream).Result;

            Assert.AreEqual(_stream, meta.Stream);
            Assert.AreEqual(false, meta.IsStreamDeleted);
            Assert.AreEqual(0, meta.MetastreamVersion);
            Assert.AreEqual(new byte[0], meta.StreamMetadata);
        }
예제 #2
0
 protected Task WriteMeta(string streamId, string login, string password, string metawriteRole)
 {
     return(Connection.SetStreamMetadataAsync(streamId, ExpectedVersion.Any,
                                              metawriteRole == null
                                 ? StreamMetadata.Build()
                                 : StreamMetadata.Build().SetReadRole(metawriteRole)
                                              .SetWriteRole(metawriteRole)
                                              .SetMetadataReadRole(metawriteRole)
                                              .SetMetadataWriteRole(metawriteRole),
                                              login == null && password == null ? null : new UserCredentials(login, password)));
 }
예제 #3
0
        public async Task setting_empty_metadata_works()
        {
            const string stream = "setting_empty_metadata_works";

            await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, (byte[])null);

            var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream);

            Assert.AreEqual(stream, meta.Stream);
            Assert.AreEqual(false, meta.IsStreamDeleted);
            Assert.AreEqual(0, meta.MetastreamVersion);
            Assert.AreEqual(new byte[0], meta.StreamMetadata);
        }
 public void TearDown()
 {
     _conn.SetStreamMetadataAsync("$all", ExpectedVersion.Any,
                                  StreamMetadata.Build(),
                                  new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)).Wait();
     _conn.Close();
 }
        public override async Task SetUp()
        {
            await base.SetUp();

            _node = new MiniNode <TLogFormat, TStreamId>(PathName);
            await _node.Start();

            _conn = BuildConnection(_node);
            await _conn.ConnectAsync();

            await _conn.SetStreamMetadataAsync("$all", -1,
                                               StreamMetadata.Build().SetReadRole(SystemRoles.All),
                                               new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword));

            _testEvents = Enumerable
                          .Range(0, 5)
                          .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent"))
                          .ToList();

            _testEvents.AddRange(
                Enumerable
                .Range(0, 5)
                .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList());

            _fakeSystemEvents = Enumerable
                                .Range(0, 5)
                                .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "$systemEvent"))
                                .ToList();
        }
        public static async Task SetEventMaxAgeIfNull(this IEventStoreConnection connection, string streamName, TimeSpan maxAge)
        {
            for (int i = 0; i < 3; ++i)
            {
                var readRes = await connection.GetStreamMetadataAsync(streamName);

                if (readRes.IsStreamDeleted || readRes.StreamMetadata.MaxAge != null)
                {
                    return;
                }

                var metadata = StreamMetadata.Create(maxAge: maxAge);

                try
                {
                    await connection.SetStreamMetadataAsync(streamName, readRes.MetastreamVersion, metadata);

                    return;
                }
                catch (WrongExpectedVersionException)
                {
                }

                await Task.Delay((i + 1) * 100);
            }
        }
예제 #7
0
 /// <inheritdoc />
 protected override async Task UpdateStreamMetadata(IStream stream)
 {
     var metaVersion = (await _connection.GetStreamMetadataAsync(stream.Key)).MetastreamVersion;
     await _connection.SetStreamMetadataAsync(
         stream.Key,
         metaVersion,
         Encoding.UTF8.GetBytes(EncodeStreamMetadata(stream))); // JExtensions.JStreamMetadata(stream));
 }
        public void after_setting_less_strict_max_count_read_stream_forward_reads_more_events()
        {
            var res = _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false).Result;

            Assert.AreEqual(SliceReadStatus.Success, res.Status);
            Assert.AreEqual(3, res.Events.Length);
            Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(),
                            res.Events.Select(x => x.Event.EventId).ToArray());

            _connection.SetStreamMetadataAsync(Stream, ExpectedVersion.Any, StreamMetadata.Build().SetMaxCount(4)).Wait();

            res = _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false).Result;
            Assert.AreEqual(SliceReadStatus.Success, res.Status);
            Assert.AreEqual(4, res.Events.Length);
            Assert.AreEqual(_testEvents.Skip(1).Select(x => x.EventId).ToArray(),
                            res.Events.Select(x => x.Event.EventId).ToArray());
        }
 public void SetUp()
 {
     _conn = BuildConnection();
     _conn.ConnectAsync().Wait();
     _conn.SetStreamMetadataAsync("$all", ExpectedVersion.Any,
                                  StreamMetadata.Build().SetReadRole(SystemRoles.All),
                                  new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)).Wait();
 }
        /// <summary>
        /// Truncates the stream TCP.
        /// </summary>
        /// <param name="eventStoreConnection">The event store connection.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="truncateBefore">The truncate before.</param>
        private static async Task TruncateStreamTcp(IEventStoreConnection eventStoreConnection,
                                                    String stream,
                                                    Int32 truncateBefore)
        {
            await eventStoreConnection.SetStreamMetadataAsync(stream, -2, StreamMetadata.Create(truncateBefore: truncateBefore));

            Console.WriteLine($"truncate stream tcp {stream}");
        }
예제 #11
0
 private async Task SetStreamMetadataAsync(string stream)
 {
     using (_logger.OperationAt(LogEventLevel.Debug).Time("Setting TTL on stream {StreamName}", stream))
         using (DittoMetrics.IODuration.WithIOLabels("eventstore", "ditto-destination", "set_stream_metadata").NewTimer())
         {
             await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.Any, _streamMetadata);
         }
 }
예제 #12
0
 private void SaveMetadata(string streamName)
 {
     if (_metadata != null)
     {
         // Setting metadata for that specific stream asynchronously to avoid a blocking call
         _connection.SetStreamMetadataAsync(streamName, _expectedVersion, _metadata);
     }
 }
예제 #13
0
        public async Task StoreStreamMetadata <T>(string id, string key, T data)
        {
            var streamMetadata = await _connection.GetStreamMetadataAsync(id);

            var updatedStream = streamMetadata.StreamMetadata.Copy().SetCustomProperty(key, data.ToJson());
            await _connection.SetStreamMetadataAsync(id, streamMetadata.MetastreamVersion,
                                                     updatedStream.Build());
        }
예제 #14
0
        public void Save(Position position)
        {
            _connection.SetStreamMetadataAsync(StreamId, ExpectedVersion.Any, StreamMetadata.Build().SetMaxCount(1)).Wait();
            var evtId      = Guid.NewGuid();
            var evt        = new PositionChanged(evtId.ToString(), position.CommitPosition, position.PreparePosition);
            var dataToPost = CreateEventData(evt);

            _connection.AppendToStreamAsync(StreamId, ExpectedVersion.StreamExists, dataToPost).Wait();
        }
예제 #15
0
        protected override async Task DeleteMessagesToAsync(string persistenceId, long toSequenceNr)
        {
            if (toSequenceNr == long.MaxValue)
            {
                var slice = await _eventStoreConnection.ReadStreamEventsBackwardAsync(persistenceId, StreamPosition.End, 1, false);

                if (slice.Events.Any())
                {
                    var @event = slice.Events.First();
                    var highestEventPosition = @event.OriginalEventNumber;
                    await _eventStoreConnection.SetStreamMetadataAsync(persistenceId, ExpectedVersion.Any, StreamMetadata.Create(truncateBefore: highestEventPosition + 1));
                }
            }
            else
            {
                await _eventStoreConnection.SetStreamMetadataAsync(persistenceId, ExpectedVersion.Any, StreamMetadata.Create(truncateBefore: toSequenceNr));
            }
        }
        public void SetUp()
        {
            _connection = TestConnection.Create(TcpType.Normal);
            _connection.ConnectAsync().Wait();

            _connection.SetStreamMetadataAsync(Stream, ExpectedVersion.Any, StreamMetadata.Build().SetMaxCount(3)).Wait();

            _testEvents = Enumerable.Range(0, 5).Select(x => TestEvent.NewTestEvent(data: x.ToString())).ToArray();
            _connection.AppendToStreamAsync(Stream, ExpectedVersion.Any, _testEvents).Wait();
        }
        public override void SetUp()
        {
            base.SetUp();
            _node = new MiniNode(PathName, skipInitializeStandardUsersCheck: false);
            _node.Start();

            _conn = TestConnection.Create(_node.TcpEndPoint);
            _conn.ConnectAsync().Wait();
            _conn.SetStreamMetadataAsync("$all", -1,
                                    StreamMetadata.Build().SetReadRole(SystemRoles.All),
                                    new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)).Wait();
        }
        public override void SetUp()
        {
            base.SetUp();
            _node = new MiniNode(PathName, skipInitializeStandardUsersCheck: false);
            _node.Start();

            _conn = BuildConnection(_node);
            _conn.ConnectAsync().Wait();
            _conn.SetStreamMetadataAsync("$all", -1,
                                         StreamMetadata.Build().SetReadRole(SystemRoles.All),
                                         new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)).Wait();
        }
예제 #19
0
        public async Task soft_deleted_stream_when_recreated_preserves_metadata_except_truncatebefore()
        {
            const string stream = "soft_deleted_stream_when_recreated_preserves_metadata_except_truncatebefore";

            Assert.AreEqual(1,
                            (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(),
                                                             TestEvent.NewTestEvent())).NextExpectedVersion);

            Assert.AreEqual(0, (await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream,
                                                                   StreamMetadata.Build().SetTruncateBefore(long.MaxValue)
                                                                   .SetMaxCount(100)
                                                                   .SetDeleteRole("some-role")
                                                                   .SetCustomProperty("key1", true)
                                                                   .SetCustomProperty("key2", 17)
                                                                   .SetCustomProperty("key3", "some value"))).NextExpectedVersion);

            var events = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() };

            Assert.AreEqual(4, (await _conn.AppendToStreamAsync(stream, 1, events)).NextExpectedVersion);
            await Task.Delay(50);             //TODO: This is a workaround until github issue #1744 is fixed

            var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false);

            Assert.AreEqual(SliceReadStatus.Success, res.Status);
            Assert.AreEqual(4, res.LastEventNumber);
            Assert.AreEqual(3, res.Events.Length);
            Assert.AreEqual(events.Select(x => x.EventId), res.Events.Select(x => x.OriginalEvent.EventId));
            Assert.AreEqual(new[] { 2, 3, 4 }, res.Events.Select(x => x.OriginalEvent.EventNumber));

            var meta = await _conn.GetStreamMetadataAsync(stream);

            Assert.AreEqual(1, meta.MetastreamVersion);
            Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore);
            Assert.AreEqual(100, meta.StreamMetadata.MaxCount);
            Assert.AreEqual("some-role", meta.StreamMetadata.Acl.DeleteRole);
            Assert.AreEqual(true, meta.StreamMetadata.GetValue <bool>("key1"));
            Assert.AreEqual(17, meta.StreamMetadata.GetValue <int>("key2"));
            Assert.AreEqual("some value", meta.StreamMetadata.GetValue <string>("key3"));
        }
        public override void SetUp()
        {
            base.SetUp();
            _node = new MiniNode(PathName);
            _node.Start();

            _connection = TestConnection.Create(_node.TcpEndPoint);
            _connection.ConnectAsync().Wait();

            _connection.SetStreamMetadataAsync(Stream, ExpectedVersion.EmptyStream, StreamMetadata.Build().SetMaxCount(3)).Wait();

            _testEvents = Enumerable.Range(0, 5).Select(x => TestEvent.NewTestEvent(data: x.ToString())).ToArray();
            _connection.AppendToStreamAsync(Stream, ExpectedVersion.EmptyStream, _testEvents).Wait();
        }
 private void InitStream()
 {
     try
     {
         _connection?.SetStreamMetadataAsync(_positionStreamName, ExpectedVersion.Any,
                                             SerializeObject(new Dictionary <string, int> {
             { "$maxCount", 1 }
         }));
     }
     catch (Exception ex)
     {
         _log.Error("Error while initializing stream", ex);
     }
 }
        public override void SetUp()
        {
            base.SetUp();
            _node = new MiniNode(PathName);
            _node.Start();

            _connection = TestConnection.Create(_node.TcpEndPoint);
            _connection.ConnectAsync().Wait();

            _connection.SetStreamMetadataAsync(Stream, ExpectedVersion.EmptyStream, StreamMetadata.Build().SetMaxCount(3)).Wait();

            _testEvents = Enumerable.Range(0, 5).Select(x => TestEvent.NewTestEvent(data: x.ToString())).ToArray();
            _connection.AppendToStreamAsync(Stream, ExpectedVersion.EmptyStream, _testEvents).Wait();
        }
        public override async Task SetUp()
        {
            await base.SetUp();

            _node = new MiniNode <TLogFormat, TStreamId>(PathName);
            await _node.Start();

            _conn = BuildConnection(_node);
            await _conn.ConnectAsync();

            await _conn.SetStreamMetadataAsync("$all", -1,
                                               StreamMetadata.Build().SetReadRole(SystemRoles.All),
                                               new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword));
        }
        protected override async Task DeleteAsync(SnapshotMetadata metadata)
        {
            var streamName = GetStreamName(metadata.PersistenceId);
            var m          = await _conn.GetStreamMetadataAsync(streamName);

            if (m.IsStreamDeleted)
            {
                return;
            }

            var streamMetadata = m.StreamMetadata.Copy();
            var timestamp      = metadata.Timestamp != DateTime.MinValue ? metadata.Timestamp : default(DateTime?);

            var result = await FindSnapshot(streamName, metadata.SequenceNr, timestamp);

            if (result.Snapshot == null)
            {
                return;
            }


            streamMetadata = streamMetadata.SetTruncateBefore(result.EventNumber + 1);
            await _conn.SetStreamMetadataAsync(streamName, ExpectedVersion.Any, streamMetadata.Build());
        }
예제 #25
0
        public static async Task SetDefaultStreamMetaData(this IEventStoreConnection conn, string stream)
        {
            try
            {
                var acl      = new StreamAcl("$admins", "$admins", "$admins", "$admins", "$admins");
                var metaData = StreamMetadata.Create(acl: acl);
                var result   = await conn.SetStreamMetadataAsync(stream, ExpectedVersion.Any, metaData);

                return;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
        }
예제 #26
0
        public override async Task SetUp()
        {
            await base.SetUp();

            _node = new MiniNode <TLogFormat, TStreamId>(PathName);
            await _node.Start();

            _connection = TestConnection.Create(_node.TcpEndPoint);
            await _connection.ConnectAsync();

            await _connection.SetStreamMetadataAsync(Stream, ExpectedVersion.NoStream,
                                                     StreamMetadata.Build().SetMaxCount(3));

            _testEvents = Enumerable.Range(0, 5).Select(x => TestEvent.NewTestEvent(data: x.ToString())).ToArray();
            await _connection.AppendToStreamAsync(Stream, ExpectedVersion.NoStream, _testEvents);
        }
        public void SetPermisions()
        {
            string stream = String.Format(streamName);
            // metadane jakie mają być ustawione dla danego streama
            string metadata = @"{
  ""$acl"": {
	""$r"": ""userReader"",
    ""$w"": ""userWriter"",
    ""$d"": ""$admins"",
    ""$mr"": ""$admins"",
    ""$mw"": ""$admins""
  },
  ""$maxAge"": 7948800
}";

            byte[] metadatabytes = Encoding.ASCII.GetBytes(metadata);
            _connectionES.SetStreamMetadataAsync(stream, ExpectedVersion.Any, metadatabytes).Wait();
        }
예제 #28
0
        public async Task <HttpResponseMessage> Post(OuroSearchRequest request)
        {
            var id           = Guid.NewGuid();
            var resultStream = string.Format("searchresult-{0}", id.ToString("N"));
            var responseUri  = string.Format("search-result/{0}", id.ToString("N"));

            //This will set the stream ACL to allow reads from all but only writes from
            //the admins group. With more secure data you may limit reads only to the user
            //that made the request and likely a backenduser who is likely not a member
            //of the $admins group for security purposes.
            //
            //await _eventStoreConnection.SetStreamMetadataAsync(resultStream,
            //                                       ExpectedVersion.EmptyStream,
            //                                       StreamMetadata.Build()
            //                                                    .SetMaxAge(TimeSpan.FromDays(90))
            //                                                    .SetWriteRole("backenduser")
            //                                                    .SetReadRole(Request.User),
            //                                       new UserCredentials("backenduser", "password"));
            //
            //This code also sets an expiration on the stream of 5 minutes. More than
            //likely in a production system you would not want such a short expiration
            //this is more so to be able to show the functionality of expiring the
            //results over time in a way that can actually be demoed. In most such
            //systems this would likely be months or possibly even never due to
            //operational needs of being able to see what happened with a given
            //request.
            await _eventStoreConnection.SetStreamMetadataAsync(resultStream,
                                                               ExpectedVersion.EmptyStream,
                                                               StreamMetadata.Build()
                                                               .SetMaxAge(TimeSpan.FromMinutes(5))
                                                               .SetWriteRole("$admins")
                                                               .SetReadRole("$all"),
                                                               new UserCredentials("admin", "changeit"));

            await _eventStoreConnection.AppendToStreamAsync("incoming", ExpectedVersion.Any,
                                                            request.ToEvent(resultStream).ToEventData("searchRequested"));

            var response = new HttpResponseMessage(HttpStatusCode.Accepted);

            response.Headers.Location = new Uri(responseUri, UriKind.Relative);
            return(response);
        }
        /// <summary>
        /// Start the subscriber.
        /// </summary>
        /// <param name="restart">Starting from a restart.</param>
        public void Start(bool restart = false)
        {
            if (_usingHeartbeats)
            {
                SendHeartbeat();
                _heartbeatTimer.Start();
            }

            lock (_subscriptionLock)
            {
                KillSubscription();

                if (_liveOnly)
                {
                    _subscription = _connection.SubscribeToStreamAsync(_streamName, true, (s, e) => EventAppeared(e), SubscriptionDropped).Result;
                }
                else
                {
                    var catchUpSettings = new CatchUpSubscriptionSettings(_maxLiveQueueSize, _catchupPageSize, true, true);
                    _subscription = _connection.SubscribeToStreamFrom(_streamName, _startingPosition, catchUpSettings, (s, e) => EventAppeared(e), LiveProcessingStarted, SubscriptionDropped);
                }
            }

            if (restart)
            {
                return;
            }

            if (_usingHeartbeats)
            {
                _connection.SetStreamMetadataAsync(_heartbeatStreamName, ExpectedVersion.Any, StreamMetadata.Create(2));
            }

            var processor = new Thread(ProcessEvents)
            {
                IsBackground = true
            };

            processor.Start();
        }
        public override async Task SetUp()
        {
            await base.SetUp();

            _node = new MiniNode <TLogFormat, TStreamId>(PathName);
            await _node.Start();

            _conn = BuildConnection(_node);
            await _conn.ConnectAsync();

            _conn.SetStreamMetadataAsync(SystemStreams.AllStream, -1,
                                         StreamMetadata.Build().SetReadRole(SystemRoles.All),
                                         new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)).Wait();

            _testEvents = Enumerable
                          .Range(0, 10)
                          .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent"))
                          .ToList();

            _testEvents.AddRange(
                Enumerable
                .Range(0, 10)
                .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList());

            _testEventsAfter = Enumerable
                               .Range(0, 10)
                               .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent"))
                               .ToList();

            _testEventsAfter.AddRange(
                Enumerable
                .Range(0, 10)
                .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList());

            await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.EvenEvents());

            await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.OddEvents());
        }
        public async Task setting_empty_metadata_works()
        {
            const string stream = "setting_empty_metadata_works";

            await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, StreamMetadata.Create());

            var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream);

            Assert.AreEqual(stream, meta.Stream);
            Assert.AreEqual(false, meta.IsStreamDeleted);
            Assert.AreEqual(0, meta.MetastreamVersion);
            Assert.AreEqual(Helper.UTF8NoBom.GetBytes("{}"), meta.StreamMetadata);
        }
예제 #32
0
        private static void SetStreamMetadata(IEventStoreConnection connection)
        {
            StreamMetadataBuilder builder = StreamMetadata.Build();
            builder.SetCacheControl(TimeSpan.FromHours(1));
            builder.SetCustomProperty("key", "value");
            builder.SetMaxAge(TimeSpan.FromHours(1));
            builder.SetMaxCount(100);

            StreamMetadata metadata = builder.Build();
            connection.SetStreamMetadataAsync("test-stream", ExpectedVersion.Any, metadata);
        }
예제 #33
0
        public async Task WriteMetadata(string stream, int?maxCount = null, int?truncateBefore = null, TimeSpan?maxAge = null,
                                        TimeSpan?cacheControl       = null, bool?frozen = null, Guid?owner = null)
        {
            Logger.Write(LogLevel.Debug, () => $"Writing metadata to stream [{stream}] [ {nameof(maxCount)}: {maxCount}, {nameof(maxAge)}: {maxAge}, {nameof(cacheControl)}: {cacheControl}, {nameof(frozen)}: {frozen} ]");

            var existing = await _client.GetStreamMetadataAsync(stream).ConfigureAwait(false);

            if ((existing.StreamMetadata?.CustomKeys.Contains("frozen") ?? false) &&
                existing.StreamMetadata?.GetValue <string>("owner") != Defaults.Instance.ToString())
            {
                FrozenExceptions.Mark();
                throw new VersionException("Stream is frozen - we are not the owner");
            }
            if (frozen.HasValue && frozen == false && (
                    existing.StreamMetadata == null ||
                    (existing.StreamMetadata?.CustomKeys.Contains("frozen") ?? false) == false ||
                    existing.StreamMetadata?.GetValue <string>("owner") != Defaults.Instance.ToString()))
            {
                FrozenExceptions.Mark();
                throw new FrozenException();
            }

            // If we are trying to freeze the stream that we've already frozen (to prevent multiple threads from attempting to process the same frozen data)
            if (frozen.HasValue && frozen == true && (existing.StreamMetadata?.CustomKeys.Contains("frozen") ?? false) &&
                existing.StreamMetadata?.GetValue <string>("owner") == Defaults.Instance.ToString())
            {
                FrozenExceptions.Mark();
                throw new FrozenException();
            }

            var metadata = StreamMetadata.Build();

            if ((maxCount ?? existing.StreamMetadata?.MaxCount).HasValue)
            {
                metadata.SetMaxCount((maxCount ?? existing.StreamMetadata?.MaxCount).Value);
            }
            if ((truncateBefore ?? existing.StreamMetadata?.TruncateBefore).HasValue)
            {
                metadata.SetTruncateBefore((truncateBefore ?? existing.StreamMetadata?.TruncateBefore).Value);
            }
            if ((maxAge ?? existing.StreamMetadata?.MaxAge).HasValue)
            {
                metadata.SetMaxAge((maxAge ?? existing.StreamMetadata?.MaxAge).Value);
            }
            if ((cacheControl ?? existing.StreamMetadata?.CacheControl).HasValue)
            {
                metadata.SetCacheControl((cacheControl ?? existing.StreamMetadata?.CacheControl).Value);
            }

            if (frozen.HasValue && frozen == true)
            {
                metadata.SetCustomProperty("frozen", DateTime.UtcNow.ToUnixTime());
            }
            if (owner.HasValue)
            {
                metadata.SetCustomProperty("owner", Defaults.Instance.ToString());
            }

            try
            {
                await _client.SetStreamMetadataAsync(stream, existing.MetastreamVersion, metadata).ConfigureAwait(false);
            }
            catch (WrongExpectedVersionException e)
            {
                throw new VersionException(e.Message, e);
            }
            catch (CannotEstablishConnectionException e)
            {
                throw new PersistenceException(e.Message, e);
            }
            catch (OperationTimedOutException e)
            {
                throw new PersistenceException(e.Message, e);
            }
            catch (EventStoreConnectionException e)
            {
                throw new PersistenceException(e.Message, e);
            }
        }