Пример #1
0
        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));
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Saves the saga entity to the persistence store.
        /// </summary>
        /// <param name="saga">The saga entity to save.</param>
        public void Save(IContainSagaData saga)
        {
            var sagaTypeName = saga.GetType().Name;

            if (!(saga is IHaveDocumentVersion))
            {
                throw new InvalidOperationException(
                          string.Format("Saga type {0} does not implement IHaveDocumentVersion", sagaTypeName));
            }

            var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga);

            if (uniqueProperty.HasValue)
            {
                this.EnsureUniqueIndex(saga, uniqueProperty.Value);
                CheckUniqueProperty(saga, uniqueProperty.Value);
            }

            var collection = this.mongoDatabase.GetCollection(sagaTypeName);
            var result     = collection.Insert(saga);

            if (result.HasLastErrorMessage)
            {
                throw new InvalidOperationException(string.Format("Unable to save with id {0}", saga.Id));
            }
        }
Пример #3
0
        public void Update(IContainSagaData 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);
        }
Пример #4
0
        public void Ensure_property_is_returned_when_attribute_exists()
        {
            var uniqueProperties = UniqueAttribute.GetUniqueProperties(typeof(ModelWithUniqueProperty))
                                   .ToList();

            Assert.AreEqual(1, uniqueProperties.Count);
            Assert.AreEqual("PropertyWithAttribute", uniqueProperties.First().Name);
        }
Пример #5
0
        public void EnsureOverridePropertyIsReturnedWhenAttributeExists()
        {
            var uniqueProperties = UniqueAttribute.GetUniqueProperties(typeof(InheritedModelWithOverride))
                                   .ToList();

            Assert.AreEqual(1, uniqueProperties.Count);
            Assert.AreEqual("PropertyWithAttribute", uniqueProperties.First().Name);
        }
Пример #6
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();
            }
        }
Пример #7
0
        public void Ensure_multiple_properties_are_returned_when_multiple_attributes_exists()
        {
            var uniqueProperties = UniqueAttribute.GetUniqueProperties(typeof(ModelWithMultipleUniqueProperty))
                                   .ToList();

            Assert.AreEqual(2, uniqueProperties.Count);
            Assert.AreEqual("PropertyWithAttribute1", uniqueProperties.First().Name);
            Assert.AreEqual("PropertyWithAttribute2", uniqueProperties.Skip(1).First().Name);
        }
Пример #8
0
        private bool IsUniqueProperty <T>(string property)
        {
            //TODO Cache?
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(typeof(T));

            if (uniqueProperty == null)
            {
                return(false);
            }
            return(uniqueProperty.Name == property);
        }
Пример #9
0
        public void Complete(IContainSagaData saga)
        {
            Session.Delete(saga);

            var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga);

            if (!uniqueProperty.HasValue)
            {
                return;
            }

            DeleteUniqueProperty(saga, uniqueProperty.Value);
        }
Пример #10
0
        bool IsUniqueProperty <T>(string property)
        {
            var  key = typeof(T).FullName + property;
            bool value;

            if (!PropertyCache.TryGetValue(key, out value))
            {
                value = UniqueAttribute.GetUniqueProperties(typeof(T)).Any(p => p.Name == property);
                PropertyCache[key] = value;
            }

            return(value);
        }
Пример #11
0
        private void EnsureUniqueIndex(IContainSagaData saga)
        {
            var sagaDataType   = saga.GetType();
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(sagaDataType);

            if (uniqueProperty == null)
            {
                return;
            }

            var classmap        = BsonClassMap.LookupClassMap(sagaDataType);
            var uniqueFieldName = GetFieldName(classmap, uniqueProperty.Name);

            _repo.EnsureUniqueIndex(sagaDataType, uniqueFieldName);
        }
Пример #12
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);
        }
Пример #13
0
        void StoreUniqueProperty(IContainSagaData 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);
        }
        public bool ActivateFor(Row row)
        {
            if (ReferenceEquals(null, Target))
            {
                return(false);
            }

            if (!Target.Flags.HasFlag(FieldFlags.Unique))
            {
                return(false);
            }

            var attr = Target.GetAttribute <UniqueAttribute>();

            if (attr != null && !attr.CheckBeforeSave)
            {
                return(false);
            }

            this.attr = attr;
            return(true);
        }
Пример #15
0
 public void Ensure_exception_is_thrown_when_multiple_attributes_exists()
 {
     Assert.Throws <InvalidOperationException>(() => UniqueAttribute.GetUniqueProperty(typeof(ModelWithMultipleUniqueProperty)));
 }
Пример #16
0
        public void Ensure_single_property_is_returned_when_attribute_exists()
        {
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(typeof(ModelWithUniqueProperty));

            Assert.IsNotNull(uniqueProperty);
        }
Пример #17
0
        public void Ensure_property_is_returned_when_no_attribute_exists()
        {
            var uniqueProperties = UniqueAttribute.GetUniqueProperties(typeof(ModelWithNoUniqueProperty));

            Assert.IsEmpty(uniqueProperties);
        }
Пример #18
0
        public void Ensure_null_returned_when_no_attributes_exists()
        {
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(typeof(ModelWithNoUniqueProperty));

            Assert.IsNull(uniqueProperty);
        }
Пример #19
0
 static IEnumerable <CorrelationProperty> FindUniqueAttributes(Type sagaEntityType)
 {
     return(UniqueAttribute.GetUniqueProperties(sagaEntityType).Select(pt => new CorrelationProperty {
         Name = pt.Name
     }));
 }
Пример #20
0
 protected bool IsUniqueProperty <T>(string property)
 {
     return(UniqueAttribute.GetUniqueProperties(typeof(T)).FirstOrDefault(p => p.Name == property) != null);
 }
Пример #21
0
        public static void Main(string[] args)
        {
            string directory;
            string op;

            if (TryFetchWithInfo(args, Keys.Directory, out directory) == false ||
                TryFetchWithInfo(args, Keys.Operation, out op) == false)
            {
                return;
            }

            var sagaTypes = FindAllSagaTypes();

            if (sagaTypes.Length == 0)
            {
                Console.WriteLine("No Saga types found! Have you put all the dlls with sagas in the deduplicator directory?");
                return;
            }

            var sagaToProperty     = new Dictionary <string, string>();
            var sagasWithoutUnique = new List <string>();

            foreach (var sagaType in sagaTypes)
            {
                var uniqueProperty = UniqueAttribute.GetUniqueProperty(sagaType);
                if (uniqueProperty == null)
                {
                    sagasWithoutUnique.Add(sagaType.Name);
                }
                else
                {
                    sagaToProperty.Add(sagaType.Name, uniqueProperty.Name);
                }
            }

            PrintReport(sagaToProperty, sagasWithoutUnique);

            var settings = ConfigurationManager.ConnectionStrings[ConnectionStringName];

            string connectionString;

            if (!string.IsNullOrWhiteSpace(settings?.ConnectionString))
            {
                connectionString = settings.ConnectionString;
            }
            else
            {
                // try to parse the last param
                CloudStorageAccount account;
                var possibleConnectionString = args.Last();
                if (CloudStorageAccount.TryParse(possibleConnectionString, out account) == false)
                {
                    Console.WriteLine("Provide one connection string in the standard 'connectionStrings' App.config section with following name: '{0}'", ConnectionStringName);
                    return;
                }

                connectionString = possibleConnectionString;
            }

            var operation = (OperationType)Enum.Parse(typeof(OperationType), op, true);

            var program = new Program(connectionString, directory);

            switch (operation)
            {
            case OperationType.Download:
                foreach (var kvp in sagaToProperty)
                {
                    program.DownloadConflictingSagas(kvp.Key, kvp.Value);
                }
                return;

            case OperationType.Upload:
                foreach (var kvp in sagaToProperty)
                {
                    program.UploadResolvedConflicts(kvp.Key);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #22
0
        private void UpdateUniquePropertyForSaga(ISagaEntity saga, SagaData sagaData)
        {
            var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga);

            sagaData.UniqueProperty = uniqueProperty != null?GetUniqueProperty(saga.GetType(), uniqueProperty.Value) : Guid.NewGuid().ToString();
        }
Пример #23
0
        private static void InitializeRules()
        {
            validationDefinitionsBySchemaObject = new Dictionary <SchemaObject, List <IValidationDefinition> >();

            Type validationDefinitionType = typeof(IValidationDefinition);
            Type objectAttributeDefType   = typeof(ObjectAttributeValidationDefinition);

            foreach (Type type in AppDomain
                     .CurrentDomain
                     .GetAssemblies()
                     .SelectMany(assembly =>
                                 assembly
                                 .GetTypes()
                                 .Where(t =>
                                        validationDefinitionType.IsAssignableFrom(t) && t != validationDefinitionType && t != objectAttributeDefType)))
            {
                IValidationDefinition validationDefinition = (IValidationDefinition)Activator.CreateInstance(type);
                SchemaObject          schemaObject         = Schema.Schema.GetSchemaObject(validationDefinition.Schema, validationDefinition.Object);
                if (!validationDefinitionsBySchemaObject.ContainsKey(schemaObject))
                {
                    validationDefinitionsBySchemaObject.Add(schemaObject, new List <IValidationDefinition>());
                }

                validationDefinitionsBySchemaObject[schemaObject].Add(validationDefinition);
            }

            foreach (SchemaObject schemaObject in Schema.Schema.GetAllSchemaObjects())
            {
                ObjectAttributeValidationDefinition attributeDefinition = new ObjectAttributeValidationDefinition();
                attributeDefinition.Schema = schemaObject.SchemaName;
                attributeDefinition.Object = schemaObject.ObjectName;
                foreach (Field field in schemaObject.GetFields())
                {
                    if (field.DataSize != -1)
                    {
                        ValidationRule validationRule = new ValidationRule()
                        {
                            Field     = field.FieldName,
                            Message   = field.FieldName + " must be less than or equal to " + field.DataSize + " characters",
                            Condition = new MaxLengthCondition(field.FieldName, field.DataSize)
                        };
                        attributeDefinition.InternalValidationRules.Add(validationRule);
                    }

                    if (field.IsRequired)
                    {
                        ValidationRule validationRule = new ValidationRule()
                        {
                            Field     = field.FieldName,
                            Message   = field.FieldName + " is a required field.",
                            Condition = new RequiredFieldCondition(field.FieldName)
                        };
                        attributeDefinition.InternalValidationRules.Add(validationRule);
                    }
                }

                UniqueAttribute uniqueAttribute = schemaObject.DataObjectType.GetCustomAttributes(typeof(UniqueAttribute), true).FirstOrDefault() as UniqueAttribute;
                if (uniqueAttribute != null)
                {
                    StringBuilder builder = new StringBuilder();
                    foreach (string field in uniqueAttribute.UniqueFields)
                    {
                        if (builder.Length > 0)
                        {
                            builder.Append(",");
                        }

                        builder.Append(field);
                    }

                    ValidationRule uniqueRule = new ValidationRule()
                    {
                        Field     = builder.ToString(),
                        Message   = builder.ToString() + " must be unique",
                        Condition = new UniqueCondition(uniqueAttribute.UniqueFields)
                    };
                    attributeDefinition.InternalValidationRules.Add(uniqueRule);
                }

                if (attributeDefinition.InternalValidationRules.Any())
                {
                    if (!validationDefinitionsBySchemaObject.ContainsKey(schemaObject))
                    {
                        validationDefinitionsBySchemaObject.Add(schemaObject, new List <IValidationDefinition>());
                    }

                    validationDefinitionsBySchemaObject[schemaObject].Add(attributeDefinition);
                }
            }
        }