Esempio n. 1
0
 public UniqueProperty(ISagaEntity saga, string name, object value)
 {
     _type  = saga.GetType();
     Name   = name;
     Value  = value;
     SagaId = saga.Id;
 }
Esempio n. 2
0
 void ISagaPersister.Save(ISagaEntity saga)
 {
     lock (syncRoot)
     {
         data[saga.Id] = saga;
     }
 }
Esempio n. 3
0
        public void Update(ISagaEntity saga)
        {
            var p = UniqueAttribute.GetUniqueProperty(saga);

            if (!p.HasValue)
            {
                return;
            }

            var uniqueProperty = p.Value;

            var metadata = Session.Advanced.GetMetadataFor(saga);

            //if the user just added the unique property to a saga with existing data we need to set it
            if (!metadata.ContainsKey(UniqueValueMetadataKey))
            {
                StoreUniqueProperty(saga);
                return;
            }

            var storedvalue = metadata[UniqueValueMetadataKey].ToString();

            var currentValue = uniqueProperty.Value.ToString();

            if (currentValue == storedvalue)
            {
                return;
            }

            DeleteUniqueProperty(saga, new KeyValuePair <string, object>(uniqueProperty.Key, storedvalue));
            StoreUniqueProperty(saga);
        }
 public UniqueProperty(ISagaEntity saga, string name, object value)
 {
     _type = saga.GetType();
     Name = name;
     Value = value;
     SagaId = saga.Id;
 }
        private void ValidateUniqueProperties(ISagaEntity saga)
        {
            var uniqueProperties = UniqueAttribute.GetUniqueProperties(saga.GetType());

            if (!uniqueProperties.Any())
            {
                return;
            }

            var sagasFromSameType = from s in data
                                    where
                                    ((s.Value as ISagaEntity).GetType() == saga.GetType() && (s.Key != saga.Id))
                                    select s.Value;

            foreach (var storedSaga in sagasFromSameType)
            {
                foreach (var uniqueProperty in uniqueProperties)
                {
                    if (uniqueProperty.CanRead)
                    {
                        var inComingSagaPropertyValue = uniqueProperty.GetValue(saga, null);
                        var storedSagaPropertyValue   = uniqueProperty.GetValue(storedSaga, null);
                        if (inComingSagaPropertyValue.Equals(storedSagaPropertyValue))
                        {
                            throw new
                                  InvalidOperationException(
                                      string.Format("Cannot store a saga. The saga with id '{0}' already has property '{1}' with value '{2}'.", storedSaga.Id, uniqueProperty.ToString(), storedSagaPropertyValue));
                        }
                    }
                }
            }
        }
        public void Complete(ISagaEntity saga)
        {
            var ctx = _sessionFactory.GetSession();

            ctx.DeleteObject(saga as T);
            ctx.SaveChanges();
        }
Esempio n. 7
0
        public void Update(ISagaEntity saga)
        {
            long currentVersion = GetSagaVersion(saga);
            var  sagaKey        = GetSagaKey(saga);
            var  sagaVersionKey = GetSagaVersionKey(saga);

            using (var client = GetClient())
            {
                var versionString = client.Get <string>(sagaVersionKey);
                if (versionString != null)
                {
                    long storageVersion = long.Parse(versionString);

                    if (storageVersion != currentVersion)
                    {
                        throw new ConcurrencyException("The saga " + saga.Id + " has changed since it was last loaded");
                    }
                }
                else
                {
                    throw new ConcurrencyException("The saga " + saga.Id + " has been deleted since it was last loaded");
                }
            }

            Save(saga);
        }
        public void Save(ISagaEntity saga)
        {
            var ctx = _sessionFactory.GetSession();

            ctx.AddObject(typeof(T).Name, saga as T);
            ctx.SaveChanges();
        }
Esempio n. 9
0
 public void Complete(ISagaEntity saga)
 {
     using (var session = Store.OpenSession())
     {
         session.Delete(saga);
     }
 }
 void ISagaPersister.Complete(ISagaEntity saga)
 {
     lock (syncRoot)
     {
         data.Remove(saga.Id);
     }
 }
Esempio n. 11
0
 public void Save(Guid sagaId, ISagaEntity saga)
 {
     _data[sagaId] = new ProfileSagaEntity
     {
         SagaEntity = BlobSerializer.Serialize(saga), ProfileName = _pluginContext.ProfileName
     };
 }
Esempio n. 12
0
 protected string GetSagaKey(ISagaEntity saga)
 {
     if (saga == null)
     {
         throw new ArgumentNullException("saga");
     }
     return(KeyPrefix + "saga:" + saga.GetType().FullName + ":" + saga.Id.ToString("N"));
 }
Esempio n. 13
0
        /// <summary>
        /// Gets a single property that is marked with the UniqueAttribute for a saga entity
        /// </summary>
        /// <param name="entity">A saga entity</param>
        /// <returns>A PropertyInfo of the property marked with a UniqAttribute or null if not used</returns>
        public static KeyValuePair <string, object>?GetUniqueProperty(ISagaEntity entity)
        {
            var prop = GetUniqueProperty(entity.GetType());

            return(prop != null ?
                   new KeyValuePair <string, object>(prop.Name, prop.GetValue(entity, null)) :
                   (KeyValuePair <string, object>?)null);
        }
Esempio n. 14
0
 public void SetUp()
 {
     _sagaEntityA = new SagaEntityA {
         Id = Guid.NewGuid(), SomeIdentifier = IDENTIFIER
     };
     SagaPersister.Save(_sagaEntityA);
     SagaPersister.DocumentSessionFactory.Current.SaveChanges();
 }
Esempio n. 15
0
 public void Complete(ISagaEntity saga)
 {
     using (var session = OpenSession())
     {
         session.Advanced.DatabaseCommands.Delete(Store.Conventions.FindTypeTagName(saga.GetType()) + "/" + saga.Id, null);
         session.SaveChanges();
     }
 }
Esempio n. 16
0
        private string GetXmlForSaga(ISagaEntity saga)
        {
            var serializer   = new XmlSerializer(saga.GetType());
            var stringWriter = new StringWriter();

            serializer.Serialize(stringWriter, saga);
            return(stringWriter.ToString());
        }
Esempio n. 17
0
 public void Save(ISagaEntity saga)
 {
     using (var session = Store.OpenSession())
     {
         session.Store(saga);
         session.SaveChanges();
     }
 }
Esempio n. 18
0
        /// <summary>
        /// Gets a single property that is marked with the UniqueAttribute for a saga entity
        /// </summary>
        /// <param name="entity">A saga entity</param>
        /// <returns>A PropertyInfo of the property marked with a UniqAttribute or null if not used</returns>
        public static KeyValuePair<string, object>? GetUniqueProperty(ISagaEntity entity)
        {
            var prop = GetUniqueProperty(entity.GetType());

            return prop != null ?
                new KeyValuePair<string, object>(prop.Name, prop.GetValue(entity, null)) :
                (KeyValuePair<string, object>?) null;
        }
 void ISagaPersister.Save(ISagaEntity saga)
 {
     lock (syncRoot)
     {
         ValidateUniqueProperties(saga);
         data[saga.Id] = saga;
     }
 }
Esempio n. 20
0
        public void Save(ISagaEntity saga)
        {
            Action saveSagaAction = () =>
            {
                var stringId           = saga.Id.ToString("N");
                var sagaKey            = GetSagaKey(saga);
                var sagaPropertyMapKey = GetSagaPropertyMapKey(saga);
                var sagaVersionKey     = GetSagaVersionKey(saga);
                var uniqueProperties   = UniqueAttribute.GetUniqueProperties(saga);

                using (var client = GetClient())
                {
                    using (var rlock = client.AcquireLock(stringId, TimeSpan.FromSeconds(30)))
                    {
                        long version = client.Increment(sagaVersionKey, 1);

                        SetSagaVersion(saga, version);

                        var sagaString = Serialize(saga);

                        //Check that unique properties don't already exist for a different saga
                        foreach (var prop in uniqueProperties)
                        {
                            var propertyKey = GetPropertyKey(saga.GetType(), prop.Key, prop.Value);
                            var sagaId      = client.Get <string>(propertyKey);
                            if (sagaId != null)
                            {
                                if (saga.Id != Guid.Parse(sagaId))
                                {
                                    throw new UniquePropertyException("Unique property " + prop.Key + " already exists with value " + prop.Value);
                                }
                            }
                        }

                        using (var tran = client.CreateTransaction())
                        {
                            tran.QueueCommand(c => c.Set(sagaKey, sagaString));
                            foreach (var prop in uniqueProperties)
                            {
                                var propertyKey = GetPropertyKey(saga.GetType(), prop.Key, prop.Value);
                                tran.QueueCommand(c => c.Lists[sagaPropertyMapKey].Add(propertyKey));                       //Link from saga ID to property key
                                tran.QueueCommand(c => client.Set(propertyKey, stringId));                                  //Link from property key to saga
                            }
                            tran.Commit();
                        }
                    }
                }
            };

            if (Transaction.Current != null)
            {
                Transaction.Current.EnlistVolatile(new ActionResourceManager(saveSagaAction, null), EnlistmentOptions.None);
            }
            else
            {
                saveSagaAction();
            }
        }
        private void StoreUniqueProperty(ISagaEntity saga)
        {
            var uniqueProperty = GetUniqueProperty(saga);

            if (uniqueProperty != null)
            {
                DocumentSessionFactory.Current.Store(uniqueProperty);
            }
        }
 private static UniqueProperty GetUniqueProperty(ISagaEntity saga)
 {
     return((from propertyInfo in saga.GetType().GetProperties()
             let customAttributes = propertyInfo.GetCustomAttributes(typeof(UniqueAttribute), false)
                                    where customAttributes.Length > 0
                                    where propertyInfo.CanRead
                                    select new UniqueProperty(saga, propertyInfo.Name, propertyInfo.GetValue(saga, null))
             ).FirstOrDefault());
 }
        public void SetUp()
        {
            _sagaEntityA = new SagaEntityA { Id = Guid.NewGuid(), SomeIdentifier = IDENTIFIER };
            _sagaEntityB = new SagaEntityB { Id = Guid.NewGuid(), SomeIdentifier = IDENTIFIER };

            SagaPersister.Save(_sagaEntityA);
            SagaPersister.Save(_sagaEntityB);

            SagaPersister.DocumentSessionFactory.Current.SaveChanges();
        }
Esempio n. 24
0
        public void Complete(ISagaEntity saga)
        {
            var sagaData = Context.SagaData.FirstOrDefault(s => s.Id == saga.Id);

            if (sagaData == null)
            {
                return;
            }

            Context.SagaData.Remove(sagaData);
        }
Esempio n. 25
0
        protected void SetSagaVersion(ISagaEntity saga, long version)
        {
            var versionProp = saga.GetType().GetProperties().FirstOrDefault(o => o.Name == "Version");

            if (versionProp == null)
            {
                throw new MissingMemberException("'Version' property must be defined");
            }

            versionProp.SetValue(saga, version, null);
        }
Esempio n. 26
0
        protected long GetSagaVersion(ISagaEntity saga)
        {
            //TODO: Use an attribute instead of fixed property name?
            var versionProp = saga.GetType().GetProperties().FirstOrDefault(o => o.Name == "Version");

            if (versionProp == null)
            {
                throw new MissingMemberException("'Version' property must be defined on saga data");
            }

            return(Convert.ToInt64(versionProp.GetValue(saga, null)));
        }
Esempio n. 27
0
        public void Update(ISagaEntity saga)
        {
            var sagaData = Context.SagaData.FirstOrDefault(s => s.Id == saga.Id);

            if (sagaData == null)
            {
                return;
            }

            sagaData.Data = GetXmlForSaga(saga);
            sagaData.Version++;
            UpdateUniquePropertyForSaga(saga, sagaData);
        }
Esempio n. 28
0
        public void Complete(ISagaEntity saga)
        {
            Session.Delete(saga);

            var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga);

            if (!uniqueProperty.HasValue)
            {
                return;
            }

            DeleteUniqueProperty(saga, uniqueProperty.Value);
        }
Esempio n. 29
0
        public void Save(ISagaEntity saga)
        {
            var sagaData = new SagaData
            {
                Id      = saga.Id,
                Data    = GetXmlForSaga(saga),
                Version = 1
            };

            UpdateUniquePropertyForSaga(saga, sagaData);

            Context.SagaData.Add(sagaData);
        }
Esempio n. 30
0
        void StoreUniqueProperty(ISagaEntity saga)
        {
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga);

            if (!uniqueProperty.HasValue)
            {
                return;
            }

            var id = SagaUniqueIdentity.FormatId(saga.GetType(), uniqueProperty.Value);

            Session.Store(new SagaUniqueIdentity {
                Id = id, SagaId = saga.Id, UniqueValue = uniqueProperty.Value.Value
            });

            SetUniqueValueMetadata(saga, uniqueProperty.Value);
        }
        private void DeleteUniquePropertyEntityIfExists(ISagaEntity saga)
        {
            var session        = DocumentSessionFactory.Current;
            var uniqueProperty = GetUniqueProperty(saga);

            if (uniqueProperty == null)
            {
                return;
            }

            var persistedUniqueProperty = session.Query <UniqueProperty>()
                                          .Customize(x => x.WaitForNonStaleResults())
                                          .Where(p => p.SagaId == saga.Id)
                                          .SingleOrDefault();

            if (persistedUniqueProperty != null)
            {
                session.Delete(persistedUniqueProperty);
            }
        }
Esempio n. 32
0
        void StoreUniqueProperty(ISagaEntity saga)
        {
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga);

            if (!uniqueProperty.HasValue)
            {
                return;
            }

            var id        = SagaUniqueIdentity.FormatId(saga.GetType(), uniqueProperty.Value);
            var sagaDocId = sessionFactory.Store.Conventions.FindFullDocumentKeyFromNonStringIdentifier(saga.Id, saga.GetType(), false);

            Session.Store(new SagaUniqueIdentity
            {
                Id          = id,
                SagaId      = saga.Id,
                UniqueValue = uniqueProperty.Value.Value,
                SagaDocId   = sagaDocId
            });

            SetUniqueValueMetadata(saga, uniqueProperty.Value);
        }
Esempio n. 33
0
        protected void DeleteSaga(ISagaEntity saga)
        {
            var stringId = saga.Id.ToString("N");

            var sagaKey            = GetSagaKey(saga);
            var sagaPropertyMapKey = GetSagaPropertyMapKey(saga);
            var sagaVersionKey     = GetSagaVersionKey(saga);

            Action deleteSagaAction = () =>
            {
                using (var client = GetClient())
                {
                    var propertyKeys = client.Lists[sagaPropertyMapKey].GetAll();

                    using (var tran = client.CreateTransaction())
                    {
                        if (propertyKeys != null)
                        {
                            tran.QueueCommand(c => c.RemoveAll(propertyKeys.ToArray()));
                        }
                        tran.QueueCommand(c => c.Remove(sagaKey));
                        tran.QueueCommand(c => c.Remove(sagaPropertyMapKey));
                        tran.QueueCommand(c => c.Remove(sagaVersionKey));
                        tran.Commit();
                    }
                }
            };

            if (Transaction.Current != null)
            {
                Transaction.Current.EnlistVolatile(new ActionResourceManager(deleteSagaAction, null), EnlistmentOptions.None);
            }
            else
            {
                deleteSagaAction();
            }
        }
Esempio n. 34
0
 /// <summary>
 /// Indicate a timeout at the expiration time for the given saga maintaining the given state.
 /// </summary>
 /// <param name="expiration"></param>
 /// <param name="saga"></param>
 /// <param name="state"></param>
 public TimeoutMessage(DateTime expiration, ISagaEntity saga, object state)
 {
     expires = DateTime.SpecifyKind(expiration, DateTimeKind.Utc);
     SagaId = saga.Id;
     State = state;
 }
Esempio n. 35
0
 /// <summary>
 /// Indicate a timeout within the given time for the given saga maintaing the given state.
 /// </summary>
 /// <param name="expireIn"></param>
 /// <param name="saga"></param>
 /// <param name="state"></param>
 public TimeoutMessage(TimeSpan expireIn, ISagaEntity saga, object state)
     : this(DateTime.Now + expireIn, saga, state)
 {
 }
Esempio n. 36
0
 /// <summary>
 /// Signal to the timeout manager that all other <see cref="TimeoutMessage"/>
 /// objects can be cleared for the given <see cref="Saga"/>.
 /// </summary>
 /// <param name="saga"></param>
 /// <param name="clear"></param>
 public TimeoutMessage(ISagaEntity saga, bool clear)
 {
     SagaId = saga.Id;
     ClearTimeout = clear;
 }
Esempio n. 37
0
 /// <summary>
 /// Gets all the properties that are marked with the UniqueAttribute for a saga entity
 /// </summary>
 /// <param name="entity">A saga entity</param>
 /// <returns>A dictionary of property names and their values</returns>
 public static IDictionary<string, object> GetUniqueProperties(ISagaEntity entity)
 {
     return GetUniqueProperties(entity.GetType()).ToDictionary(p => p.Name, p => p.GetValue(entity, null));
 }