public async Task Execute <TIdent>(IEventStoreAsync eventStorage, TIdent id, Action <TAggregateRoot> execute) where TIdent : IIdentity
        {
            if (eventStorage == null)
            {
                throw new ArgumentNullException("eventStorage");
            }

            if (id == null || id.Equals(default(TIdent)))
            {
                throw new ArgumentException("id is null or default value", "id");
            }

            // Load event stream from the store
            var stream = await eventStorage.LoadEventStream(id);

            // create new Customer aggregate from the history
            var aggregate = new TAggregateRoot();

            aggregate.LoadsFromHistory(stream.Events);

            // execute delegated action
            Logger.DebugFormat("Executing Update on aggregate {0}", aggregate);
            execute(aggregate);

            // append resulting changes to the stream, expect the same version loaded before applying ddd logic
            if (aggregate.Changes.Any())
            {
                Logger.DebugFormat("Saving {0} uncommited events on aggregate {1}", aggregate.Changes.Count, aggregate);
                await eventStorage.AppendToStream(id, stream.Version, aggregate.Changes);
            }

            Logger.DebugFormat("Finished Update on {0}", aggregate);
        }
Beispiel #2
0
        public EventStream LoadEventStream(IIdentity id)
        {
            EventStream loadEventStream = this.LoadEventStream(id, 0, int.MaxValue);

            Logger.DebugFormat("Loaded stream {0} on rev {1}", id, loadEventStream.Version);
            return(loadEventStream);
        }
Beispiel #3
0
        public void Update <TIdent>(TIdent id, Action <TSagaAggregate> execute) where TIdent : IIdentity
        {
            // Load event stream from the store
            EventStream stream = this.eventStore.LoadEventStream(id);

            // create new Customer aggregate from the history
            var      aggregate = new TSagaAggregate();
            QueueBus queueBus  = new QueueBus();

            aggregate.Bus = queueBus;
            aggregate.LoadsFromHistory(stream.Events);

            // execute delegated action
            Logger.DebugFormat("Executing Update on aggregate {0}", aggregate);
            execute(aggregate);

            // append resulting changes to the stream, expect the same version loaded before applying ddd logic
            if (aggregate.Changes.Any())
            {
                Logger.DebugFormat("Saving {0} uncommited events on aggregate {1}", aggregate.Changes.Count, aggregate);
                this.eventStore.AppendToStream(id, stream.Version, aggregate.Changes);
            }

            queueBus.EmptyQueue(this.bus);

            Logger.DebugFormat("Finished Update on {0}", aggregate);
        }
Beispiel #4
0
        public async Task AppendToStream(IIdentity id, long expectedVersion, ICollection <IEvent> events)
        {
            if (events.Count == 0)
            {
                return;
            }

            var name = id.ToString();
            var data = this.serializer.SerializeEvent(events.ToArray());

            try
            {
                await this.appender.Append(name, data, expectedVersion);
            }
            catch (AppendOnlyStoreConcurrencyException e)
            {
                // load server events
                var server = await this.LoadEventStream(id, 0, int.MaxValue);

                // throw a real problem
                throw OptimisticConcurrencyException.Create(server.Version, e.ExpectedStreamVersion, id, server.Events);
            }

            foreach (var @event in events)
            {
                Logger.DebugFormat("{0} r{1} Event: {2}", id, expectedVersion, @event);
            }
        }
Beispiel #5
0
        public async Task Execute <TIdent, TResult, TIdentCreated>(IEventStoreAsync eventStorage, TIdent id, Func <TResult, TAggregateRoot> execute, TIdentCreated createId)
            where TIdent : IIdentity
            where TResult : IAggregate, new()
            where TIdentCreated : IIdentity
        {
            if (eventStorage == null)
            {
                throw new ArgumentNullException("eventStorage");
            }

            if (id == null || id.Equals(default(TIdent)))
            {
                throw new ArgumentException("id is null or default value", "id");
            }

            if (createId == null || createId.Equals(default(TIdentCreated)))
            {
                throw new ArgumentException("createid is null or default value", "createId");
            }

            EventStream stream = await eventStorage.LoadEventStream(id);

            // create new Customer aggregate from the history
            var aggregate = new TResult();

            aggregate.LoadsFromHistory(stream.Events);

            // execute delegated action
            Logger.DebugFormat("Executing UpdateAndCreateAggregate on aggregate {0}", aggregate);
            TAggregateRoot res = execute(aggregate);

            if (aggregate.Changes.Any())
            {
                throw new Exception("You cannot modify more than one aggregate per command!");
            }

            if (res != null && res.Changes.Any())
            {
                Logger.DebugFormat("Saving {0} uncommited events on result aggregate {1}", res.Changes.Count, res);
                await eventStorage.AppendToStream(createId, 0, res.Changes);

                Logger.DebugFormat("Finished Create on {0}", aggregate);
                return;
            }

            throw new InvalidOperationException("No aggregate created on execute");
        }
Beispiel #6
0
        public void AquireLease()
        {
            //var blobReference = this.container.GetBlobReferenceFromServer("lock");

            Logger.Debug("Requesting lease....");
            this.lease = this.container.AcquireLease(TimeSpan.FromSeconds(15), this.instanceId);

            if (string.IsNullOrEmpty(lease))
            {
                this.Exception = new Exception("Could not aquire lease.");
                Logger.Info("Got exception on lease: ", this.Exception);
            }
            else
            {
                this.Exception = null;
                Logger.DebugFormat("Got lease.... {0}", this.lease);
            }
        }
        public void Dispatch(ICommand cmd)
        {
            if (cmd.Timestamp == DateTime.MinValue)
            {
                throw new ArgumentException("Command must have a timestamp: " + cmd.GetType());
            }

            if (this.services.ContainsKey(cmd.GetType()))
            {
                foreach (var handler in this.services[cmd.GetType()])
                {
                    lock (onecommand)
                    {
                        Logger.DebugFormat("Dispatching Command: {0}", cmd.ToString());
                        handler.Execute(cmd);
                    }
                }
            }
            else
            {
                throw new InvalidOperationException(string.Format("No service to execute command {0}", cmd));
            }
        }
Beispiel #8
0
        public async Task <bool> Initialize()
        {
            try
            {
                await this.projections.CreateIfNotExistsAsync();

                await this.table.CreateIfNotExistsAsync();
            }
            catch (StorageException ex)
            {
                Logger.DebugFormat("Failed to initialize, best guess is bad naming of table. Check azure naming guidelines.");
                Logger.InfoFormat("Error: {0} with status code: {1}. Extended info: {2} ({3})", ex.RequestInformation.HttpStatusMessage, ex.RequestInformation.HttpStatusCode, ex.RequestInformation.ExtendedErrorInformation.ErrorMessage, ex.RequestInformation.ExtendedErrorInformation.ErrorCode);
                Logger.Debug(ex.ToString());
                return(false);
            }

            return(true);
        }