public static ValidateResponse ValidateRelationships(ServiceKey key)
        {
            var response = new ValidateResponse(true, key)
            {
                Errors = new List <IValidationError>()
            };
            var serviceName = ServiceDefinition.Get(key.Id).Name;

            try
            {
                var svcRelationships = Get(key);
                //got applicable relations
                var svcRel = svcRelationships.Select(def => def.GetDefinition(key)).Where(pd => pd != null).ToList();
                if (svcRel?.Count > 0)
                {
                    response.Errors.AddRange(from rel in svcRel
                                             where Convert.ToInt32(rel.Minimum) > 0
                                             where !(key.Relationships.Any(x => x.Key == rel.Name))
                                             select new ValidationError(string.Format("Required Related {0} is missing on service {1}", rel.Name, serviceName), ValidationError.RELATIONSHIP, key.GetIdentifier(null), ValidationError.MISSING, rel.Name + " is missing.", rel.Name));
                }
                if (key.Relationships != null)
                {
                    foreach (var pair in key.Relationships)
                    {
                        var relExists = svcRel.Any(x => x.Name == pair.Key);
                        if (!relExists)
                        {
                            response.AddError(string.Format("{0} is an unknown relationship for service {1}.", pair.Key,
                                                            serviceName), ValidationError.RELATIONSHIP, key.GetIdentifier(null), ValidationError.UNKNOWN, pair.Key + " is unknown for this service.", null);
                        }
                        else
                        {
                            var rel = svcRel.Find(x => x.Name == pair.Key);

                            if (key.Relationships[pair.Key].Count() < Convert.ToInt32(rel.Minimum))
                            {
                                response.AddError(
                                    string.Format(
                                        "Service relationship {0} for Service {1} does not meet the minimum of {2}.",
                                        pair.Key,
                                        serviceName, rel.Minimum), ValidationError.RELATIONSHIP, key.GetIdentifier(null), ValidationError.MINIMUM, pair.Value.Count + "<" + rel.Minimum);
                            }
                            if (key.Relationships[pair.Key].Count() > Convert.ToInt32(rel.Maximum) && Convert.ToInt32(rel.Maximum) != -1)
                            {
                                response.AddError(
                                    string.Format("Service relationship {0} for Service {1} exceeds the maximum of {2}.",
                                                  pair.Key, serviceName, rel.Maximum), ValidationError.RELATIONSHIP, key.GetIdentifier(null), ValidationError.MAXIMUM, pair.Value.Count + ">" + rel.Maximum, rel.Name);
                            }
                            foreach (var k in pair.Value.Where(k => !rel.Services.Contains(k.Id)))
                            {
                                response.AddError(
                                    string.Format(
                                        "Service relationship {0} for Service {1} does not support service of type {2}.",
                                        pair.Key, serviceName, ServiceDefinition.Get(k.Id).Name), ValidationError.RELATIONSHIP, k.GetIdentifier(null), ValidationError.INVALID_VALUE, k.Id.ToString(), rel.Name);
                            }
                        }
                    }
                }
                if (response.Errors.Count() > 0)
                {
                    response.IsValid = false;
                }
            }
            catch (Exception e)
            {
                response.AddError(e.Message, ValidationError.SERVICE, key.GetIdentifier(null), ValidationError.MISSING_CONFIG, e.Message);
                response.IsValid = false;
                return(response);
            }

            return(response);
        }
        public static ValidateResponse Validate(ServiceKey key)
        {
            var response = new ValidateResponse(true, key);
            var kids     = Get(key);

            // validate min/max
            foreach (var kid in kids)
            {
                if (kid.MinQuantity > 0 &&
                    (key.Children == null || !key.Children.ContainsKey(kid.Name) || key.Children[kid.Name].Count < kid.MinQuantity))
                {
                    response.AddError($"Minimum quanity not met for child '{kid.Name}'", ValidationError.SERVICE, key.GetIdentifier(null), ValidationError.MINIMUM, "Minimum quantity not met");
                }
                else if (kid.MaxQuantity >= 0 &&
                         key.Children != null &&
                         key.Children.ContainsKey(kid.Name) &&
                         key.Children[kid.Name].Count > kid.MaxQuantity)
                {
                    response.AddError($"Too many instances of child '{kid.Name}'", ValidationError.SERVICE, key.GetIdentifier(null), ValidationError.MAXIMUM, "Maximum quantity exceeded");
                }
            }
            // make sure we don't have any extras
            if (key.Children != null)
            {
                foreach (var child in key.Children)
                {
                    var allowedIds = kids.Where(k => k.Name.Equals(child.Key)).Select(k => k.Id);
                    if (allowedIds.Count() == 0)
                    {
                        response.AddError($"Child '{child.Key}' is not allowed on this service", ValidationError.SERVICE, key.GetIdentifier(null), ValidationError.MAXIMUM, $"Child '{child.Key}' is not allowed");
                    }
                    else
                    {
                        foreach (var v in child.Value)
                        {
                            if (!allowedIds.Contains(v.Id))
                            {
                                response.AddError($"Service #{v.Id} is not allowed for child '{child.Key}'", ValidationError.SERVICE, key.GetIdentifier(null), ValidationError.MAXIMUM, $"Service #{v.Id} is not allowed");
                            }
                        }
                    }
                }
            }

            return(response);
        }
Example #3
0
        public ValidateServiceResponse Validate(ServiceKey key)
        {
            var response = new ValidateServiceResponse(true, key)
            {
                Errors = new List <IValidationError>()
            };
            var vr = new ValidateResponse(true, key)
            {
                Errors = new List <IValidationError>()
            };

            // let's make sure all required attributes are there
            vr.Errors.AddRange(from ad in Attributes.Values
                               where !IsOptional(ad.Name, key)
                               //checking if the attribute is supposed to have defaults
                               where !HasDefault(ad.Name)
                               where !ad.Type.Equals(AttributeType.Complex)
                               let value = key.GetAttributeValue(ad.Name, SearchOptions.ALL_TRUE)
                                           where string.IsNullOrEmpty(value)
                                           select new ValidationServiceError(string.Format("{0}: {1} is required.", key.ServiceInstanceId, ad.Label), ValidationError.SERVICE, ad.Name, ValidationError.MISSING, ad.Label, null, key.ServiceInstanceId));

            // if attributes are missing, let's stop there
            if (vr.Errors.Count == 0)
            {
                // valid value check
                var validValueRules = ValidValueRuleParser.GetRules(ValidValueRule);

                foreach (IValidValueRule rule in validValueRules)
                {
                    var v = key.GetAttributeValue(rule.GetAttributeName(), SearchOptions.NO_DEFAULTS);
                    //checking if attribute is applicable and is required
                    if (IsConfigurableAttribute(rule.GetAttributeName(), key) && !IsOptional(rule.GetAttributeName(), key))
                    {
                        vr.AddResponse(rule.ValidateAttributes(key));
                    }
                }

                // DataConstraints
                foreach (var a in key.Values)
                {
                    vr.AddResponse(IsValid(a.Key, a.Value.Value, key));
                }


                // service relationships
                vr.AddResponse(ServiceRelationships.ValidateRelationships(key));


                // children
                vr.AddResponse(ServiceHierarchy.Validate(key));



                //Since we have all of the needed values, we can now make sure that it meets all of the business rules.
                var           attributes = ServiceAttributes.Get(key, false);
                AttributeInfo attributeInfo;
                foreach (var attributeName in Attributes.Keys)
                {
                    attributeInfo = attributes.FirstOrDefault(a => a.Name.Equals(attributeName));
                    if (attributeInfo != null)
                    {
                        if (attributeInfo.GetValue() == null && !IsOptional(attributeName, key) && !HasDefault(attributeName))
                        {
                            vr.AddError(attributeInfo.Label + " does not have a valid value.", ValidationError.ATTRIBUTE, key.GetIdentifier(null), ValidationError.INVALID_VALUE, attributeName);
                        }
                        //If the value returned by the GetAttributes doesn't match the one returned by the key, we are not valid.
                        if (attributeInfo.Type.Equals(AttributeType.List))
                        {
                            string value = null;
                            if (!string.IsNullOrEmpty(attributeInfo.GetValue()))
                            {
                                value = attributeInfo.GetValue();
                            }
                            else if (!string.IsNullOrEmpty(attributeInfo.DefaultValue))
                            {
                                value = attributeInfo.DefaultValue;
                            }

                            var keyValue = key.GetAttributeValue(attributeName, SearchOptions.ALL_TRUE);
                            if (value != null && keyValue != null && !value.Equals(keyValue))
                            {
                                vr.AddError(string.Format("{0} ({1}) does not have a valid value. Should be ({2}).",
                                                          attributeInfo.Label, keyValue, value), ValidationError.ATTRIBUTE, key.GetIdentifier(null), ValidationError.INVALID_VALUE, attributeName);
                            }
                        }
                    }
                    else if (!HasDefault(attributeName) && !IsOptional(attributeName, key))
                    {
                        vr.AddError(
                            string.Format("{0} is required, does not have a default value, and '{1}' is not returned by GetAttributes.",
                                          attributeInfo.Label, key.GetAttributeValue(attributeName, SearchOptions.ALL_TRUE)),
                            ValidationError.ATTRIBUTE, key.GetIdentifier(null), ValidationError.INVALID_VALUE, attributeName);
                    }
                }
            }
            response.AddResponse(response.ToServiceResponse(FixAttributeNameToLabel(key, vr)));

            if (response.Errors.Count > 0)
            {
                response.IsValid = false;
                List <ValidationServiceError> vErrors = new List <ValidationServiceError>();

                foreach (var error in response.Errors)
                {
                    if (error is ValidationError)
                    {
                        vErrors.Add(new ValidationServiceError(error.Description, error.Category,
                                                               error.Entity, error.Type, error.Reason, error.ErrorCode, key.ServiceInstanceId));
                    }
                    else
                    {
                        if ((error as ValidationServiceError)?.InstanceId == null || (error as ValidationServiceError)?.InstanceId == 0)
                        {
                            vErrors.Add(new ValidationServiceError(error.Description, error.Category,
                                                                   error.Entity, error.Type, error.Reason, error.ErrorCode, key.ServiceInstanceId));
                        }
                        else
                        {
                            vErrors.Add(error as ValidationServiceError);
                        }
                    }
                }
                if (vErrors.Count > 0)
                {
                    response.Errors = null;
                    response.AddErrors(new List <ValidationServiceError>(vErrors));
                }
            }

            return(response);
        }