public async Task <IReadOnlyCollection <ICommittedDomainEvent> > CommitEventsAsync(IIdentity id, IReadOnlyCollection <SerializedEvent> serializedEvents, CancellationToken cancellationToken)
        {
            var eventFlowEvents = serializedEvents
                                  .Select(e => new EventFlowEvent
            {
                AggregateSequenceNumber = e.AggregateSequenceNumber,
                Metadata    = e.SerializedMetadata,
                AggregateId = id.Value,
                Data        = e.SerializedData
            })
                                  .ToList();

            var expectedVersion = serializedEvents.Min(e => e.AggregateSequenceNumber) - 1;

            var streamsDbMessages = serializedEvents
                                    .Select(e =>
            {
                var eventId   = e.Metadata.EventId.Value;
                var eventType = string.Format("{0}.{1}.{2}", e.Metadata[MetadataKeys.AggregateName], e.Metadata.EventName, e.Metadata.EventVersion);
                var data      = Encoding.UTF8.GetBytes(e.SerializedData);
                var header    = Encoding.UTF8.GetBytes(e.SerializedMetadata);

                return(new MessageInput
                {
                    ID = eventId,
                    Type = eventType,
                    Header = header,
                    Value = data
                });
            })
                                    .ToList();

            try
            {
                await _client.DB().AppendStream(id.Value, ConcurrencyCheck.ExpectStreamVersion(expectedVersion), streamsDbMessages).ConfigureAwait(false);
            }
            catch (OperationCanceledException e)
            {
                throw new OptimisticConcurrencyException(e.Message, e);
            }

            return(eventFlowEvents);
        }
Esempio n. 2
0
        public ActionResult Edit(
            string entityName,
            string key,
            [Bind(Prefix = "__ConcurrencyCheck")] string concurrencyCheck,
            FormCollection collection)
        {
            var entity = _admin.GetEntity(entityName);

            if (entity == null)
            {
                return(RedirectToAction("NotFound", new { entityName }));
            }

            var concurrencyCheckValue = ConcurrencyCheck.Convert(concurrencyCheck, entity);

            var isSuccess = _entityService.Edit(entity, key, collection, Request.Files, concurrencyCheckValue);

            if (isSuccess)
            {
                _notificator.Success(IlaroAdminResources.EditSuccess, entity.Verbose.Singular);

                return(SaveOrUpdateSucceed(entityName, key));
            }

            var entityRecord = entity.CreateRecord(key, collection, Request.Files);

            var model = new EntityEditModel
            {
                Entity           = entity,
                Record           = entityRecord,
                PropertiesGroups = _entityService.PrepareGroups(entityRecord, getKey: false, key: key),
                ConcurrencyCheck = concurrencyCheckValue
            };

            return(View(model));
        }
Esempio n. 3
0
        private async Task UpdateReadModelAsync(
            IReadModelContextFactory readModelContextFactory,
            Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelUpdateResult <TReadModel> > > updateReadModel,
            CancellationToken cancellationToken,
            ReadModelUpdate readModelUpdate)
        {
            var readModelId       = readModelUpdate.ReadModelId;
            var readModelEnvelope = await GetAsync(readModelId, cancellationToken).ConfigureAwait(false);

            var readModel = readModelEnvelope.ReadModel;
            var isNew     = readModel == null;

            if (readModel == null)
            {
                readModel = await _readModelFactory.CreateAsync(readModelId, cancellationToken).ConfigureAwait(false);

                readModelEnvelope = ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, readModel);
            }

            var readModelContext = readModelContextFactory.Create(readModelId, isNew);

            var originalVersion = readModelEnvelope.Version;

            var readModelUpdateResult = await updateReadModel(
                readModelContext,
                readModelUpdate.DomainEvents,
                readModelEnvelope,
                cancellationToken)
                                        .ConfigureAwait(false);

            if (!readModelUpdateResult.IsModified)
            {
                return;
            }

            readModelEnvelope = readModelUpdateResult.Envelope;

            if (readModelContext.IsMarkedForDeletion)
            {
                await DeleteAsync(readModelId, cancellationToken).ConfigureAwait(false);

                return;
            }

            var readModelType = typeof(TReadModel);

            var stream = readModelId == "null"
               ? readModelType.Name.ToLowerInvariant()
               : $"{readModelType.Name.ToLowerInvariant()}-{readModelId}";

            var messageInput = new MessageInput
            {
                ID    = Guid.NewGuid().ToString(),
                Type  = $"{readModelType.Name}.{readModelEnvelope.Version}",
                Value = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(readModelEnvelope.ReadModel))
            };

            try
            {
                if (readModelUpdate is CursorBasedReadModelUpdate cursorBasedReadModelUpdate)
                {
                    var cursorsMessageInput = new MessageInput
                    {
                        ID    = Guid.NewGuid().ToString(),
                        Type  = "cursors",
                        Value = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(cursorBasedReadModelUpdate.Cursors))
                    };

                    await _client.DB().AppendStreams(
                        new StreamInput(cursorBasedReadModelUpdate.CursorsStream, new List <MessageInput> {
                        cursorsMessageInput
                    }),
                        new StreamInput(stream, ConcurrencyCheck.ExpectStreamVersion(originalVersion.GetValueOrDefault()), new List <MessageInput> {
                        messageInput
                    })
                        ).ConfigureAwait(false);
                }
                else
                {
                    await _client.DB().AppendStream(stream, ConcurrencyCheck.ExpectStreamVersion(originalVersion.GetValueOrDefault()), messageInput).ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                throw new OptimisticConcurrencyException($"Read model '{readModelEnvelope.ReadModelId}' updated by another", e);
            }

            Log.Verbose(() => $"Updated StreamsDB read model {typeof(TReadModel).PrettyPrint()} with ID '{readModelId}' to version '{readModelEnvelope.Version}'");
        }