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)); } } } } }
/// <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)); } }
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); }
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); }
public void EnsureOverridePropertyIsReturnedWhenAttributeExists() { var uniqueProperties = UniqueAttribute.GetUniqueProperties(typeof(InheritedModelWithOverride)) .ToList(); Assert.AreEqual(1, uniqueProperties.Count); Assert.AreEqual("PropertyWithAttribute", uniqueProperties.First().Name); }
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(); } }
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); }
private bool IsUniqueProperty <T>(string property) { //TODO Cache? var uniqueProperty = UniqueAttribute.GetUniqueProperty(typeof(T)); if (uniqueProperty == null) { return(false); } return(uniqueProperty.Name == property); }
public void Complete(IContainSagaData saga) { Session.Delete(saga); var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga); if (!uniqueProperty.HasValue) { return; } DeleteUniqueProperty(saga, uniqueProperty.Value); }
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); }
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); }
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); }
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); }
public void Ensure_exception_is_thrown_when_multiple_attributes_exists() { Assert.Throws <InvalidOperationException>(() => UniqueAttribute.GetUniqueProperty(typeof(ModelWithMultipleUniqueProperty))); }
public void Ensure_single_property_is_returned_when_attribute_exists() { var uniqueProperty = UniqueAttribute.GetUniqueProperty(typeof(ModelWithUniqueProperty)); Assert.IsNotNull(uniqueProperty); }
public void Ensure_property_is_returned_when_no_attribute_exists() { var uniqueProperties = UniqueAttribute.GetUniqueProperties(typeof(ModelWithNoUniqueProperty)); Assert.IsEmpty(uniqueProperties); }
public void Ensure_null_returned_when_no_attributes_exists() { var uniqueProperty = UniqueAttribute.GetUniqueProperty(typeof(ModelWithNoUniqueProperty)); Assert.IsNull(uniqueProperty); }
static IEnumerable <CorrelationProperty> FindUniqueAttributes(Type sagaEntityType) { return(UniqueAttribute.GetUniqueProperties(sagaEntityType).Select(pt => new CorrelationProperty { Name = pt.Name })); }
protected bool IsUniqueProperty <T>(string property) { return(UniqueAttribute.GetUniqueProperties(typeof(T)).FirstOrDefault(p => p.Name == property) != null); }
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(); } }
private void UpdateUniquePropertyForSaga(ISagaEntity saga, SagaData sagaData) { var uniqueProperty = UniqueAttribute.GetUniqueProperty(saga); sagaData.UniqueProperty = uniqueProperty != null?GetUniqueProperty(saga.GetType(), uniqueProperty.Value) : Guid.NewGuid().ToString(); }
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); } } }