コード例 #1
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            ExtensionRuleResultDetail detail = null;

            List <string> entitySetURLs = MetadataHelper.GetEntitySetURLs();

            passed = false;
            string entityTypeShortName = string.Empty;

            foreach (string entitySetUrl in entitySetURLs)
            {
                try
                {
                    entityTypeShortName = entitySetUrl.MapEntitySetNameToEntityTypeShortName();
                }
                catch (ArgumentNullException)
                { continue; }

                Tuple <string, string> key = MetadataHelper.GetKeyProperty(entityTypeShortName);

                List <XElement> properties = MetadataHelper.GetAllPropertiesOfEntity(ServiceStatus.GetInstance().MetadataDocument, entityTypeShortName, MatchPropertyType.Navigations);

                Response resp = WebHelper.Get(new Uri(context.ServiceBaseUri + "/" + entitySetUrl), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    continue;
                }

                JObject feed;
                resp.ResponsePayload.TryToJObject(out feed);

                if (feed == null || JTokenType.Object != feed.Type)
                {
                    continue;
                }

                JArray entities = JsonParserHelper.GetEntries(feed);
                foreach (JToken entity in entities)
                {
                    string identity = entity[key.Item1].ToString();
                    foreach (XElement property in properties)
                    {
                        if (String.IsNullOrEmpty(property.Attribute("Name").Value))
                        {
                            continue;
                        }

                        string url = context.ServiceBaseUri + "/" + entitySetUrl + "(" + (key.Item2.Equals("Edm.String") ? "\'" + identity + "\'" : identity) + ")/" + property.Attribute("Name").Value;

                        resp   = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                        detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, "");

                        if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                        {
                            continue;
                        }

                        resp.ResponsePayload.TryToJObject(out feed);

                        if (feed == null || JTokenType.Object == feed.Type)
                        {
                            passed = true; break;
                        }
                    }
                    if (passed.Value)
                    {
                        break;
                    }
                }

                if (passed.Value)
                {
                    break;
                }
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
コード例 #2
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    props = MetadataHelper.GetProperties("Edm.GeographyPoint", 1, out entityTypeShortName);

            if (null == props || !props.Any())
            {
                return(passed);
            }

            string propName     = props[0].PropertyName;
            string srid         = props[0].SRID;
            var    entitySetUrl = entityTypeShortName.GetAccessEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                return(passed);
            }

            string url  = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl;
            var    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);

            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                JObject jObj    = JObject.Parse(resp.ResponsePayload);
                JArray  jArr    = jObj.GetValue(Constants.Value) as JArray;
                var     entity  = jArr.First as JObject;
                var     propVal = entity[propName]["coordinates"] as JArray;
                var     pt      = new Point(Convert.ToDouble(propVal[0]), Convert.ToDouble(propVal[1]));
                var     pts     = new Point[4]
                {
                    pt + new Point(1.0, 0.0),
                    pt + new Point(-1.0, 0.0),
                    pt + new Point(0.0, 1.0),
                    pt + new Point(0.0, -1.0)
                };
                url  = string.Format("{0}?$filter=geo.intersects({1}, SRID={2};POLYGON({3}, {4}, {5}, {6}))", url, propName, srid, pts[0], pts[1], pts[2], pts[3]);
                resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);
                info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                if (null != resp && HttpStatusCode.OK == resp.StatusCode)
                {
                    jObj = JObject.Parse(resp.ResponsePayload);
                    jArr = jObj.GetValue(Constants.Value) as JArray;
                    foreach (JObject et in jArr)
                    {
                        passed = this.IsIntersects(propName, new Polygon(pts), et);
                    }
                }
                else
                {
                    passed = false;
                }
            }

            return(passed);
        }
コード例 #3
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    propNames = MetadataHelper.GetPropertyNames(
                "Edm.String",
                out entityTypeShortName,
                2,
                (elem) => {
                return(!(null != elem.Attribute("MaxLength") && elem.GetAttributeValue("MaxLength") == "max"));
            });

            if (null == propNames || propNames.Count < 2)
            {
                return(passed);
            }

            string propName1    = propNames[0];
            string propName2    = propNames[1];
            var    entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL();
            string url          = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl;
            var    resp         = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);

            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                JObject jObj     = JObject.Parse(resp.ResponsePayload);
                JArray  jArr     = jObj.GetValue(Constants.Value) as JArray;
                var     entity   = jArr.First as JObject;
                var     propVal1 = entity[propName1].ToString();
                var     propVal2 = entity[propName2].ToString();
                url  = string.Format("{0}?$filter=concat(concat({1}, ': '), {2}) eq '{3}: {4}'", url, propName1, propName2, propVal1, propVal2);
                resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, resp.ResponseHeaders, resp);
                detail.URI                = url;
                detail.ResponsePayload    = resp.ResponsePayload;
                detail.ResponseHeaders    = resp.ResponseHeaders;
                detail.HTTPMethod         = "GET";
                detail.ResponseStatusCode = resp.StatusCode.ToString();

                info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                if (null != resp && HttpStatusCode.OK == resp.StatusCode)
                {
                    jObj = JObject.Parse(resp.ResponsePayload);
                    jArr = jObj.GetValue(Constants.Value) as JArray;
                    bool passtest = false;
                    foreach (JObject et in jArr)
                    {
                        string test1 = string.Format("{0}: {1}", et[propName1].ToString(), et[propName2].ToString());
                        string test2 = string.Format("{0}: {1}", propVal1, propVal2);

                        passtest = (string.Format("{0}: {1}", et[propName1].ToString(), et[propName2].ToString()) == string.Format("{0}: {1}", propVal1, propVal2));
                        if (!passtest)
                        {
                            var errordetail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, resp.ResponseHeaders, resp, "The concatination did not match: " + test1 + " not equal to " + test2);
                            info.AddDetail(errordetail);
                            passed = false;
                        }
                    }
                }
                else
                {
                    detail.ErrorMessage = "The server returned an error response:  " + detail.ResponseStatusCode;
                    passed = false;
                }
            }

            return(passed);
        }
コード例 #4
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    propTypes = new string[2] {
                "Edm.Double", "Edm.Decimal"
            };
            var props = MetadataHelper.GetProperties(propTypes, out entityTypeShortName);

            if (null == props || !props.Any())
            {
                return(passed);
            }

            string propName     = props[0].Item1;
            string propType     = props[0].Item2;
            var    entitySetUrl = entityTypeShortName.GetAccessEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                return(passed);
            }

            string url  = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl;
            var    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);

            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                JObject jObj   = JObject.Parse(resp.ResponsePayload);
                JArray  jArr   = jObj.GetValue(Constants.Value) as JArray;
                var     entity = jArr.First as JObject;
                if ("Edm.Double" == propType)
                {
                    var propVal = Math.Floor(Convert.ToDouble(entity[propName]));
                    url  = string.Format("{0}?$filter=floor({1}) eq {2}", url, propName, propVal);
                    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                    var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);
                    info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                    if (null != resp && HttpStatusCode.OK == resp.StatusCode)
                    {
                        jObj = JObject.Parse(resp.ResponsePayload);
                        jArr = jObj.GetValue(Constants.Value) as JArray;
                        foreach (JObject et in jArr)
                        {
                            if (Math.Floor(Convert.ToDouble(et[propName])) == propVal)
                            {
                                passed = true;
                            }
                            else
                            {
                                passed = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        passed = false;
                    }
                }
                else // The property type is Edm.Decimal.
                {
                    var propVal = Math.Floor(Convert.ToDecimal(entity[propName]));
                    url  = string.Format("{0}?$filter=floor({1}) eq {2}", url, propName, propVal);
                    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                    var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);
                    info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                    if (null != resp && HttpStatusCode.OK == resp.StatusCode)
                    {
                        jObj = JObject.Parse(resp.ResponsePayload);
                        jArr = jObj.GetValue(Constants.Value) as JArray;
                        foreach (JObject et in jArr)
                        {
                            if (Math.Floor(Convert.ToDecimal(et[propName])) == propVal)
                            {
                                passed = true;
                            }
                            else
                            {
                                passed = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        passed = false;
                    }
                }
            }

            return(passed);
        }
コード例 #5
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name);

            var restrictions = AnnotationsHelper.GetChangeTracking(context.MetadataDocument, context.VocCapabilities);

            if (string.IsNullOrEmpty(restrictions.Item1) ||
                null == restrictions.Item2 || !restrictions.Item2.Any() ||
                null == restrictions.Item3 || !restrictions.Item3.Any())
            {
                detail.ErrorMessage = "Cannot find an entity-container or any entity-sets which support the change tracking function.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            string url = string.Format("{0}/{1}", context.ServiceBaseUri, restrictions.Item1);
            List <KeyValuePair <string, string> > requestHeaders = new List <KeyValuePair <string, string> >();

            foreach (KeyValuePair <string, string> kvp in context.RequestHeaders)
            {
                requestHeaders.Add(new KeyValuePair <string, string>(kvp.Key, kvp.Value));
            }

            // Add odata.track-changes preference in request header.
            KeyValuePair <string, string> prefer = new KeyValuePair <string, string>("Prefer", "odata.track-changes");

            requestHeaders.Add(prefer);
            Response response = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, requestHeaders);

            detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, requestHeaders), response);

            if (response != null && !string.IsNullOrEmpty(response.ResponseHeaders))
            {
                string preferHeader = response.ResponseHeaders.GetHeaderValue("Preference-Applied");

                if (string.IsNullOrEmpty(preferHeader))
                {
                    passed = false;
                    detail.ErrorMessage = "The response header returned by the service does not contain 'odata.track-changes', when request with the header 'Prefer:odata.track-changes'.";
                }
                else if (preferHeader.Contains("odata.track-changes"))
                {
                    passed = true;
                }
            }
            else
            {
                passed = false;
                detail.ErrorMessage = "The service does not support Delta change tracking.";
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
コード例 #6
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            ServiceStatus serviceStatus    = ServiceStatus.GetInstance();
            TermDocuments termDocs         = TermDocuments.GetInstance();
            DataFactory   dFactory         = DataFactory.Instance();
            var           detail1          = new ExtensionRuleResultDetail(this.Name);
            var           detail2          = new ExtensionRuleResultDetail(this.Name);
            var           detail3          = new ExtensionRuleResultDetail(this.Name);
            var           detail4          = new ExtensionRuleResultDetail(this.Name);
            List <string> keyPropertyTypes = new List <string>()
            {
                "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String"
            };
            List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, null, NavigationRoughType.SingleValued).ToList();

            if (null == entityTypeElements || 0 == entityTypeElements.Count())
            {
                detail1.ErrorMessage = "To verify this rule it expects an entity type with Int32/Int64/Int16/Guid/String key property, but there is no this entity type in metadata so can not verify this rule. ";
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            EntityTypeElement entityType = null;

            foreach (var en in entityTypeElements)
            {
                var matchEntity = en.EntitySetName.GetRestrictions(serviceStatus.MetadataDocument, termDocs.VocCapabilitiesDoc,
                                                                   new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >()
                {
                    AnnotationsHelper.GetDeleteRestrictions, AnnotationsHelper.GetInsertRestrictions
                });

                if (!string.IsNullOrEmpty(matchEntity.Item1) &&
                    matchEntity.Item2 != null && matchEntity.Item2.Any() &&
                    matchEntity.Item3 != null && matchEntity.Item3.Any())
                {
                    entityType = en;
                    break;
                }
            }

            string entitySetUrl = entityType.EntitySetName.MapEntitySetNameToEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                detail1.ErrorMessage = string.Format("Cannot find the entity-set URL which is matched with {0}", entityType.EntityTypeShortName);
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            // Create a entity
            string url             = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl;
            var    keyNames        = entityType.KeyProperties;
            string keyName         = keyNames.First().PropertyName;
            var    additionalInfos = new List <AdditionalInfo>();
            var    reqData         = dFactory.ConstructInsertedEntityData(entityType.EntitySetName, entityType.EntityTypeShortName, null, out additionalInfos);
            string reqDataStr      = reqData.ToString();
            bool   isMediaType     = !string.IsNullOrEmpty(additionalInfos.Last().ODataMediaEtag);
            var    resp            = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos);

            detail1 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr);
            if (resp.StatusCode == HttpStatusCode.Created)
            {
                var entityId = additionalInfos.Last().EntityId;
                var hasEtag  = additionalInfos.Last().HasEtag;

                // Get a individual property except key property
                string        toDeletePropertyName = string.Empty;
                List <string> properties           = MetadataHelper.GetNormalPropertiesNames(serviceStatus.MetadataDocument, entityType.EntityTypeShortName);

                foreach (string name in properties)
                {
                    if (!string.Equals(name, keyName))
                    {
                        toDeletePropertyName = name;
                        break;
                    }
                }

                string individualProUrl = entityId + @"/" + toDeletePropertyName;
                resp                       = WebHelper.Get(new Uri(individualProUrl), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, serviceStatus.DefaultHeaders);
                detail2                    = new ExtensionRuleResultDetail(this.Name, individualProUrl, HttpMethod.Get, StringHelper.MergeHeaders(Constants.AcceptHeaderJson, serviceStatus.DefaultHeaders), resp);
                detail2.URI                = individualProUrl;
                detail2.ResponsePayload    = resp.ResponsePayload;
                detail2.ResponseHeaders    = resp.ResponseHeaders;
                detail2.HTTPMethod         = "PATCH";
                detail2.ResponseStatusCode = resp.StatusCode.ToString();

                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    // Delete the individual property
                    resp    = WebHelper.DeleteEntity(individualProUrl, context.RequestHeaders, hasEtag);
                    detail3 = new ExtensionRuleResultDetail(this.Name, individualProUrl, HttpMethod.Delete, string.Empty, resp);
                    if (resp.StatusCode == HttpStatusCode.NoContent)
                    {
                        // Check whether the deleted property is set to null
                        if (WebHelper.GetContent(individualProUrl, context.RequestHeaders, out resp))
                        {
                            detail4 = new ExtensionRuleResultDetail(this.Name, individualProUrl, HttpMethod.Get, string.Empty, resp);
                            JObject jo;
                            resp.ResponsePayload.TryToJObject(out jo);
                            if (jo != null && jo[Constants.Value].Type == JTokenType.Null)
                            {
                                passed = true;
                            }
                            else if (jo == null)
                            {
                                passed = false;
                                detail4.ErrorMessage = "Can not get individual property after deleting it. ";
                            }
                            else if (jo != null && jo[Constants.Value].Type != JTokenType.Null)
                            {
                                passed = false;
                                detail4.ErrorMessage = "The individual property is not set to null after deleting it. ";
                            }
                        }
                    }
                    else
                    {
                        passed = false;
                        detail3.ErrorMessage = "Delete individual property from the created entity failed. ";
                    }
                }
                else
                {
                    passed = false;
                    detail2.ErrorMessage = "Get individual property from the created entity failed. ";
                }

                // Delete the entity
                var resps = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos);
            }
            else
            {
                passed = false;
                detail1.ErrorMessage = "Created the new entity failed for above URI. ";
            }

            var details = new List <ExtensionRuleResultDetail>()
            {
                detail1, detail2, detail3, detail4
            }.RemoveNullableDetails();

            info = new ExtensionRuleViolationInfo(this.ErrorMessage, new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, details);

            return(passed);
        }
コード例 #7
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            List <ExtensionRuleResultDetail> details = new List <ExtensionRuleResultDetail>();
            List <string> entitySetURLs = null;

            try
            {
                entitySetURLs = MetadataHelper.GetEntitySetURLs();
            }
            catch
            {
                details.Add(new ExtensionRuleResultDetail(this.Name, string.Empty, HttpMethod.Get, "Please check the Service Document.  One of the attributes are missing for EntitySet.  Required url and kind"));
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, details);
                return(false);
            }
            foreach (string entitySetUrl in entitySetURLs)
            {
                string entityTypeShortName;
                try
                {
                    entityTypeShortName = entitySetUrl.MapEntitySetNameToEntityTypeShortName();
                }
                catch (ArgumentException)
                { continue; }

                Tuple <string, string> key = MetadataHelper.GetKeyProperty(entityTypeShortName);
                if (key == null)
                {
                    continue;
                }

                Response resp = WebHelper.Get(new Uri(context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + entitySetUrl), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    continue;
                }

                JObject feed;
                resp.ResponsePayload.TryToJObject(out feed);

                if (feed == null || JTokenType.Object != feed.Type)
                {
                    continue;
                }

                JArray entities = JsonParserHelper.GetEntries(feed);
                if (entities.Count == 0)
                {
                    continue;
                }
                string identity = entities[0][key.Item1].ToString();

                string url = context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + entitySetUrl + "(" + (key.Item2.Equals("Edm.String") ? "\'" + identity + "\'" : identity) + ")";

                resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                details.Add(new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, resp.ResponseHeaders, resp));

                if (resp.ResponseHeaders.Contains("ETag:"))
                {
                    passed = true;
                    break;
                }
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, details);
            return(passed);
        }
コード例 #8
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            List <ExtensionRuleResultDetail> details = new List <ExtensionRuleResultDetail>();
            ExtensionRuleResultDetail        detail1 = new ExtensionRuleResultDetail(this.Name);
            var filterRestrictions = AnnotationsHelper.GetFilterRestrictions(context.MetadataDocument, context.VocCapabilities);

            if (string.IsNullOrEmpty(filterRestrictions.Item1) ||
                null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any())
            {
                detail1.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1);

                return(passed);
            }

            string entitySet         = filterRestrictions.Item1;
            string primitivePropName = filterRestrictions.Item2.First().PropertyName;
            string primitivePropType = filterRestrictions.Item2.First().PropertyType;

            string url  = string.Format("{0}/{1}", context.ServiceBaseUri, entitySet);
            var    resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                detail1.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1);

                return(passed);
            }

            JObject feed;

            resp.ResponsePayload.TryToJObject(out feed);

            if (feed != null && JTokenType.Object == feed.Type)
            {
                var    entities = JsonParserHelper.GetEntries(feed);
                string propVal  = entities[0][primitivePropName].ToString();

                #region Equal operation on filter.
                bool?  isEqualOpValidation = null;
                string pattern             = "Edm.String" == primitivePropType ? "{0}/{1}?$filter={2} eq '{3}'" : "{0}/{1}?$filter={2} eq {3}";
                url     = string.Format(pattern, context.ServiceBaseUri, entitySet, primitivePropName, propVal);
                resp    = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                detail1 = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp);

                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    JObject feed1;
                    resp.ResponsePayload.TryToJObject(out feed1);

                    if (feed1 != null && JTokenType.Object == feed1.Type)
                    {
                        var entities1 = JsonParserHelper.GetEntries(feed1).ToList();
                        var temp      = entities1.FindAll(en => propVal == en[primitivePropName].ToString()).Select(en => en);

                        if (entities1.Count() == temp.Count())
                        {
                            isEqualOpValidation = true;
                        }
                        else
                        {
                            isEqualOpValidation  = false;
                            detail1.ErrorMessage = "The service does not execute an accurate result with system query option $filter eq.";
                            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1);

                            return(isEqualOpValidation);
                        }
                    }
                }
                else
                {
                    passed = false;
                    detail1.ErrorMessage = "Request failed with system query option $filter eq.";
                    info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1);

                    return(passed);
                }
                #endregion

                #region NotEqual operation on filter.
                bool?isNotEqualOpValidation = null;
                pattern = "Edm.String" == primitivePropType ? "{0}/{1}?$filter={2} ne '{3}'" : "{0}/{1}?$filter={2} ne {3}";
                url     = string.Format(pattern, context.ServiceBaseUri, entitySet, primitivePropName, propVal);
                resp    = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                ExtensionRuleResultDetail detail2 = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp);

                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    JObject feed2;
                    resp.ResponsePayload.TryToJObject(out feed2);

                    if (feed2 != null && JTokenType.Object == feed2.Type)
                    {
                        var entities2 = JsonParserHelper.GetEntries(feed2).ToList();
                        var temp      = entities2.FindAll(en => propVal != en[primitivePropName].ToString()).Select(en => en);

                        if (entities2.Count() == temp.Count())
                        {
                            isNotEqualOpValidation = true;
                        }
                        else
                        {
                            isNotEqualOpValidation = false;
                            detail2.ErrorMessage   = "The service does not execute an accurate result with system query option $filter ne.";
                        }
                    }
                }
                else
                {
                    passed = false;
                    detail2.ErrorMessage = "Request failed with system query option $filter ne.";
                }
                #endregion

                if (true == isEqualOpValidation && true == isNotEqualOpValidation)
                {
                    passed = true;
                }

                details.Add(detail2);
            }

            details.Insert(0, detail1);
            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, details);

            return(passed);
        }
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name);
            var filterRestrictions           = AnnotationsHelper.GetFilterRestrictions(context.MetadataDocument, context.VocCapabilities);

            if (string.IsNullOrEmpty(filterRestrictions.Item1) ||
                null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any())
            {
                detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            string entitySet         = filterRestrictions.Item1;
            string primitivePropName = filterRestrictions.Item2.First().PropertyName;
            string primitivePropType = filterRestrictions.Item2.First().PropertyType;

            string url  = string.Format("{0}/{1}", context.ServiceBaseUri, entitySet);
            var    resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            JObject feed;

            resp.ResponsePayload.TryToJObject(out feed);

            if (feed != null && JTokenType.Object == feed.Type)
            {
                var    entities = JsonParserHelper.GetEntries(feed);
                string propVal  = "Edm.String" == primitivePropType?string.Format("'{0}'", entities[0][primitivePropName].ToString()) : entities[0][primitivePropName].ToString();

                var req = WebRequest.Create(string.Format("{0}?$filter={1} eq @test1&@test1={2}", url, primitivePropName, propVal)) as HttpWebRequest;;
                resp   = WebHelper.Get(req, RuleEngineSetting.Instance().DefaultMaximumPayloadSize);
                detail = new ExtensionRuleResultDetail(this.Name, req.RequestUri.ToString(), "GET", string.Empty, resp);

                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    JObject feed1;
                    resp.ResponsePayload.TryToJObject(out feed1);

                    if (feed1 != null && JTokenType.Object == feed1.Type)
                    {
                        var entities1 = JsonParserHelper.GetEntries(feed1).ToList();
                        var temp      = entities1.FindAll(en => propVal == en[primitivePropName].ToString()).Select(en => en);

                        if (entities1.Count() == temp.Count())
                        {
                            passed = true;
                        }
                        else
                        {
                            passed = false;
                            detail.ErrorMessage = "The service does not execute an accurate result on aliases in $filter expressions.";
                        }
                    }
                }
                else
                {
                    passed = false;
                    detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                }
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
コード例 #10
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            ExtensionRuleResultDetail detail = null;

            List <string> entitySetURLs = MetadataHelper.GetEntitySetURLs();

            foreach (string entitySetUrl in entitySetURLs)
            {
                string entityTypeShortName = entitySetUrl.MapEntitySetNameToEntityTypeShortName();
                Tuple <string, string> key = MetadataHelper.GetKeyProperty(entityTypeShortName);
                Response resp = WebHelper.Get(new Uri(context.ServiceBaseUri + "/" + entitySetUrl), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    continue;
                }

                JObject feed;
                resp.ResponsePayload.TryToJObject(out feed);

                if (feed == null || JTokenType.Object != feed.Type)
                {
                    continue;
                }

                JArray entities = JsonParserHelper.GetEntries(feed);
                string identity = entities[0][key.Item1].ToString();

                string url = context.ServiceBaseUri + "/" + entitySetUrl + "(" + (key.Item2.Equals("Edm.String") ? "\'" + identity + "\'" : identity) + ")/" + key.Item1;

                resp   = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, "");

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    passed = false; break;
                }

                resp.ResponsePayload.TryToJObject(out feed);

                if (feed == null || JTokenType.Object != feed.Type)
                {
                    passed = false; break;
                }


                if (feed["value"] != null && feed["value"].ToString().Equals(identity))
                {
                    passed = true; break;
                }
                passed = false; break;
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
コード例 #11
0
        /// <summary>
        /// Verify extension rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool passed = false;

            info = null;

            if (context.DestinationBasePath.Contains("$links"))
            {
                // Load Payload into XMLDOM
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(context.ResponsePayload);
                XmlNode node = xmlDoc.SelectSingleNode("//*[local-name()='links']");

                if (node == null)
                {
                    node = xmlDoc.SelectSingleNode("//*[local-name()='uri']");

                    Response response = WebHelper.Get(new Uri(node.InnerText), Constants.AcceptHeaderAtom, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        XmlDocument xmlDoc2 = new XmlDocument();
                        xmlDoc2.LoadXml(response.ResponsePayload);
                        XmlNode node2 = xmlDoc2.SelectSingleNode("//*[local-name()='entry']");

                        if (node2 != null)
                        {
                            passed = true;
                        }
                    }
                }
                else
                {
                    // Rule is skipped
                    passed = true;
                }
            }
            else
            {
                // Rule is skipped
                passed = true;
            }

            info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);

            return(passed);
        }
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    keyProp = MetadataHelper.GetKeyProperty(out entityTypeShortName);

            if (null == keyProp)
            {
                return(passed);
            }

            string keyPropName = keyProp.Item1;
            string keyPropType = keyProp.Item2;

            if (string.IsNullOrEmpty(entityTypeShortName) || string.IsNullOrEmpty(keyPropName) || string.IsNullOrEmpty(keyPropType))
            {
                return(passed);
            }

            string entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL();
            string url          = string.Format("{0}/{1}?$orderby={2} desc", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, keyPropName);
            var    resp         = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
            var    detail       = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionOrderBy", url, HttpMethod.Get, string.Empty);

            info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                var jObj = JObject.Parse(resp.ResponsePayload);
                var jArr = jObj.GetValue("value") as JArray;
                passed = true;
                for (int i = 0; i < jArr.Count - 1; i++)
                {
                    if (!CompareOperationHelper.Compare(jArr[i][keyPropName], jArr[i + 1][keyPropName], keyPropType, ComparerType.Equal | ComparerType.GreaterThan))
                    {
                        passed = false;
                        break;
                    }
                }
            }

            return(passed);
        }
コード例 #13
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    propTypes = new string[1] {
                "Edm.DateTimeOffset"
            };
            var propNames = MetadataHelper.GetPropertyNames(propTypes, out entityTypeShortName);

            if (null == propNames || !propNames.Any())
            {
                return(passed);
            }

            string propName     = propNames[0];
            var    entitySetUrl = entityTypeShortName.GetAccessEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                return(passed);
            }

            string url  = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl;
            var    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);

            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                var settings = new JsonSerializerSettings();
                settings.DateParseHandling = DateParseHandling.None;
                JObject jObj    = JsonConvert.DeserializeObject(resp.ResponsePayload, settings) as JObject;
                JArray  jArr    = jObj.GetValue(Constants.Value) as JArray;
                var     entity  = jArr.First as JObject;
                var     propVal = string.Empty;

                for (int i = 0; i < propNames.Count - 1; i++)
                {
                    try
                    {
                        propVal = entity[propNames[i].ToString()].ToString();
                    }
                    catch
                    {
                    }
                    if (!string.IsNullOrEmpty(propVal))
                    {
                        propName = propNames[i].ToString();
                        break;
                    }
                }

                int index = propVal.IndexOf('T');
                if (index < 0)
                {
                    passed = false;
                }
                else
                {
                    propVal = propVal.Substring(0, index);
                    url     = string.Format("{0}?$filter=date({1}) eq {2}", url, propName, propVal);
                    resp    = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                    var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);
                    info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                    if (null != resp && HttpStatusCode.OK == resp.StatusCode)
                    {
                        jObj = JsonConvert.DeserializeObject(resp.ResponsePayload, settings) as JObject;
                        jArr = jObj.GetValue(Constants.Value) as JArray;
                        foreach (JObject et in jArr)
                        {
                            var actualVal = et[propName].ToString();
                            index     = actualVal.IndexOf('T');
                            actualVal = actualVal.Substring(0, index);
                            passed    = actualVal == propVal;
                        }
                    }
                    else
                    {
                        passed = false;
                    }
                }
            }

            return(passed);
        }
コード例 #14
0
        /// <summary>
        /// Verify Error.Core.4601
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            string   AcceptAtomXml = Constants.ContentTypeAtom;
            Response response      = WebHelper.Get(context.Destination, AcceptAtomXml, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
            var      payloadFormat = response.ResponsePayload.GetFormatFromPayload();
            var      payloadType   = ContextHelper.GetPayloadType(response.ResponsePayload, payloadFormat, response.ResponseHeaders);

            if (payloadType == RuleEngine.PayloadType.Error)
            {
                passed = true;
            }
            else
            {
                passed = false;
                info   = new ExtensionRuleViolationInfo(ErrorMessage, context.Destination, response.StatusCode.ToString());
            }

            return(passed);
        }
コード例 #15
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    propNames = MetadataHelper.GetNumericPropertyNames(out entityTypeShortName);
            string propName  = propNames[0];

            if (string.IsNullOrEmpty(entityTypeShortName) || string.IsNullOrEmpty(propName))
            {
                return(passed);
            }

            string entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL();

            // Set the negative number as 2.0. It is only a testing number, so it can be any numbers.
            double divisor = 2.0;

            // Set the threshold as 2.5. It is only a testing number, so it can be any numbers.
            double threshold = 2.5;
            string url       = string.Format("{0}/{1}?$filter={2} div {3} gt {4}", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, propName, divisor, threshold);
            var    resp      = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
            var    detail    = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);

            info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                var jObj = JObject.Parse(resp.ResponsePayload);
                var jArr = jObj.GetValue(Constants.Value);
                passed = true;
                foreach (JObject entity in jArr)
                {
                    try
                    {
                        double val = Convert.ToDouble(entity[propName]);
                        if (val / divisor <= threshold)
                        {
                            passed = false;
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        return(null);
                    }
                }
            }

            return(passed);
        }
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus     = ServiceStatus.GetInstance();
            string navigPropName = string.Empty;
            string entityTypeShortName;
            var    entityTypeShortNames    = new List <string>();
            Tuple <string, string> keyProp = null;

            do
            {
                var navigPropNames = MetadataHelper.GetNavigationPropertyNames(out entityTypeShortName, entityTypeShortNames);
                if (null == navigPropNames || !navigPropNames.Any())
                {
                    return(passed);
                }

                navigPropName = navigPropNames[0];
                entityTypeShortNames.Add(entityTypeShortName);
                keyProp = MetadataHelper.GetKeyProperty(entityTypeShortName);
            }while (null == keyProp);

            string keyPropName  = keyProp.Item1;
            string keyPropType  = keyProp.Item2;
            var    entitySetUrl = entityTypeShortName.GetAccessEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                return(passed);
            }

            string url  = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl;
            var    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                return(passed);
            }

            var entities = JsonParserHelper.GetEntities(resp.ResponsePayload);

            if (!entities.Any())
            {
                return(passed);
            }

            var    entity     = entities.First();
            string keyPropVal = entity[keyPropName].ToString();
            string pattern    = "Edm.String" == keyPropType ? "{0}('{1}')/{2}/$ref" : "{0}({1})/{2}/$ref";

            url  = string.Format(pattern, url, keyPropVal, navigPropName);
            resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
            var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionRef", url, HttpMethod.Get, string.Empty);

            info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                entities = JsonParserHelper.GetEntities(resp.ResponsePayload);
                if (!entities.Any())
                {
                    return(false);
                }

                entity = entities.First();
                var odataId = entity[Constants.V4OdataId].ToString();
                resp   = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                passed = null != resp && HttpStatusCode.OK == resp.StatusCode;
            }
            else
            {
                passed = false;
            }

            return(passed);
        }
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            Response resp = WebHelper.Get(new Uri(context.ServiceBaseUri + "/$all"), Constants.AcceptHeaderJson,
                                          RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name, context.ServiceBaseUri + "/$all",
                                                                             HttpMethod.Get, context.RequestHeaders.ToString());

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                return(passed = false);
            }

            JObject allFeed;

            resp.ResponsePayload.TryToJObject(out allFeed);

            if (allFeed == null || JTokenType.Object != allFeed.Type)
            {
                return(passed = false);
            }

            JArray allEntities = JsonParserHelper.GetEntries(allFeed);

            passed = true;

            List <string> entitySetURLs = MetadataHelper.GetEntitySetURLs();

            foreach (string entitySetUrl in entitySetURLs)
            {
                string entityTypeShortName = entitySetUrl.MapEntitySetNameToEntityTypeShortName();
                Tuple <string, string> key = MetadataHelper.GetKeyProperty(entityTypeShortName);

                resp = WebHelper.Get(new Uri(context.ServiceBaseUri + "/" + entitySetUrl),
                                     Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    continue;
                }

                JObject feed;
                resp.ResponsePayload.TryToJObject(out feed);

                if (feed == null || JTokenType.Object != feed.Type)
                {
                    continue;
                }

                JArray entities = JsonParserHelper.GetEntries(feed);
                foreach (JToken entity in entities)
                {
                    if (!Find(allEntities, key.Item1, entity[key].ToString()))
                    {
                        return(passed = false);
                    }
                }
            }

            return(passed);
        }
コード例 #18
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name);
            var filterRestrictions           = AnnotationsHelper.GetFilterRestrictions(context.MetadataDocument, context.VocCapabilities);

            if (string.IsNullOrEmpty(filterRestrictions.Item1) ||
                null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any())
            {
                detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            string entitySet         = filterRestrictions.Item1;
            string primitivePropName = filterRestrictions.Item2.First().PropertyName;
            string primitivePropType = filterRestrictions.Item2.First().PropertyType;

            string url  = string.Format("{0}/{1}", context.ServiceBaseUri, entitySet);
            var    resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            JObject feed;

            resp.ResponsePayload.TryToJObject(out feed);

            if (feed != null && JTokenType.Object == feed.Type)
            {
                var    entities = JsonParserHelper.GetEntries(feed);
                string propVal  = "Edm.String" == primitivePropType?string.Format("'{0}'", entities[0][primitivePropName].ToString()) : entities[0][primitivePropName].ToString();

                #region Equal operation on filter.
                // The comparison operators does not contain "undefined".
                url    = string.Format("{0}?$filter={1} undefined {2}", url, primitivePropName, propVal);
                resp   = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp);

                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    JObject jObj;
                    resp.ResponsePayload.TryToJObject(out jObj);

                    if (jObj != null && JTokenType.Object == jObj.Type)
                    {
                        var entries = JsonParserHelper.GetEntries(jObj).ToList();
                        var temp    = entries.FindAll(en => propVal == en[primitivePropName].ToString()).Select(en => en);

                        if (entries.Count() == temp.Count())
                        {
                            passed = true;
                        }
                        else
                        {
                            passed = false;
                            detail.ErrorMessage = string.Format("The actual result of filter operation is {0}, and the expected result of filter operation is {1}", entities.Count, temp.Count());
                        }
                    }
                }
                else if (resp.StatusCode == HttpStatusCode.NotImplemented)
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    detail.ErrorMessage = String.Format(JsonParserHelper.GetErrorMessage(resp.ResponsePayload));
                }
                #endregion
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
コード例 #19
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            ServiceStatus serviceStatus    = ServiceStatus.GetInstance();
            TermDocuments termDocs         = TermDocuments.GetInstance();
            DataFactory   dFactory         = DataFactory.Instance();
            var           detail1          = new ExtensionRuleResultDetail(this.Name);
            var           detail2          = new ExtensionRuleResultDetail(this.Name);
            var           detail3          = new ExtensionRuleResultDetail(this.Name);
            List <string> keyPropertyTypes = new List <string>()
            {
                "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String"
            };
            List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, null, NavigationRoughType.SingleValued).ToList();

            if (null == entityTypeElements || 0 == entityTypeElements.Count())
            {
                detail1.ErrorMessage = "To verify this rule it expects an entity type with Int32/Int64/Int16/Guid/String key property, but there is no this entity type in metadata so can not verify this rule.";
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            string entityTypeShortName = string.Empty;
            string entitySetName       = string.Empty;
            string entitySetUrl        = string.Empty;
            string navigPropName       = string.Empty;

            foreach (var en in entityTypeElements)
            {
                var matchEntity = en.EntitySetName.GetRestrictions(serviceStatus.MetadataDocument, termDocs.VocCapabilitiesDoc,
                                                                   new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >()
                {
                    AnnotationsHelper.GetExpandRestrictions, AnnotationsHelper.GetInsertRestrictions
                    , AnnotationsHelper.GetDeleteRestrictions, AnnotationsHelper.GetUpdateRestrictions
                });

                if (!string.IsNullOrEmpty(matchEntity.Item1) &&
                    matchEntity.Item2 != null && matchEntity.Item2.Any() &&
                    matchEntity.Item3 != null && matchEntity.Item3.Any())
                {
                    entityTypeShortName = en.EntityTypeShortName;
                    entitySetName       = matchEntity.Item1;
                    entitySetUrl        = entitySetName.MapEntitySetNameToEntitySetURL();
                    foreach (NavigProperty np in matchEntity.Item3)
                    {
                        string nEntityTypeShortName = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment();
                        if (np.NavigationRoughType == NavigationRoughType.SingleValued && !nEntityTypeShortName.IsMediaType())
                        {
                            navigPropName = np.NavigationPropertyName;
                            break;
                        }
                    }
                }
                if (!string.IsNullOrEmpty(entitySetName) && !string.IsNullOrEmpty(navigPropName))
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(entitySetName) || string.IsNullOrEmpty(navigPropName))
            {
                detail1.ErrorMessage = "Cannot find the appropriate entity-set URL to verify this rule.";
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            string navigPropEntitySet = navigPropName.MapNavigationPropertyNameToEntitySetURL(entityTypeShortName);
            string url             = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl;
            var    additionalInfos = new List <AdditionalInfo>();
            var    reqData         = dFactory.ConstructInsertedEntityData(entitySetName, entityTypeShortName, new List <string>()
            {
                navigPropName
            }, out additionalInfos);
            string reqDataStr  = reqData.ToString();
            bool   isMediaType = !string.IsNullOrEmpty(additionalInfos.Last().ODataMediaEtag);
            var    resp        = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos);

            detail1 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr);
            if (HttpStatusCode.Created == resp.StatusCode)
            {
                string entityId = additionalInfos.Last().EntityId;
                url     = serviceStatus.RootURL.TrimEnd('/') + @"/" + navigPropEntitySet;
                resp    = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, serviceStatus.DefaultHeaders);
                detail2 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, serviceStatus.DefaultHeaders), resp);
                if (resp.StatusCode.HasValue && HttpStatusCode.OK == resp.StatusCode)
                {
                    JObject feed;
                    resp.ResponsePayload.TryToJObject(out feed);
                    var entities = JsonParserHelper.GetEntries(feed);
                    if (entities.Any())
                    {
                        string v4OdataIdVal = string.Empty;
                        if (entities.First[Constants.V4OdataId] != null)
                        {
                            v4OdataIdVal = entities.First[Constants.V4OdataId].ToString();
                        }

                        url        = string.Format("{0}/{1}/$ref", entityId.TrimEnd('/'), navigPropName.TrimEnd('/'));
                        reqDataStr =
                            @"{
                                """ + Constants.V4OdataId + @""" : """ + v4OdataIdVal + @"""
                        }";
                        bool hasEtag = additionalInfos.Last().HasEtag;
                        resp    = WebHelper.UpdateEntity(url, context.RequestHeaders, reqDataStr, HttpMethod.Put, hasEtag);
                        detail3 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Put, string.Empty, resp, string.Empty, reqDataStr);

                        if (null != resp && HttpStatusCode.NoContent == resp.StatusCode)
                        {
                            passed = true;
                        }
                        else
                        {
                            passed = false;
                            detail3.ErrorMessage = "PUT to $ref failed by above URI";
                        }
                    }
                }
                else
                {
                    passed = false;
                    detail2.ErrorMessage = "Get entity failed from above URI.";
                }

                // Restore the service.
                var resps = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos);
            }
            else
            {
                passed = false;
                detail1.ErrorMessage = "Created the new entity failed for above URI.";
            }

            var details = new List <ExtensionRuleResultDetail>()
            {
                detail1, detail2, detail3
            }.RemoveNullableDetails();

            info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, details);

            return(passed);
        }
コード例 #20
0
        /// <summary>
        /// Verify SvcDoc.Core.4603
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(context.ResponsePayload);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);

            nsmgr.AddNamespace("app", Constants.NSApp);
            nsmgr.AddNamespace("metadata", Constants.NSMetadata);
            XmlNode node = xmlDoc.SelectSingleNode(@"/app:service", nsmgr);

            if (node != null && node.Attributes["context", Constants.NSMetadata] != null)
            {
                string contextValue = node.Attributes["context", Constants.NSMetadata].Value;

                // Send request with contextValue.
                string   acceptHeader  = Constants.ContentTypeXml;
                Response response      = WebHelper.Get(new Uri(contextValue), acceptHeader, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                var      payloadFormat = response.ResponsePayload.GetFormatFromPayload();
                var      payloadType   = ContextHelper.GetPayloadType(response.ResponsePayload, payloadFormat, response.ResponseHeaders);

                if (payloadType == RuleEngine.PayloadType.Metadata)
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                }
            }

            return(passed);
        }
コード例 #21
0
        /// <summary>
        /// Verify rule logic
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            // metadata accept-header.
            string   AcceptAtomXml = Constants.ContentTypeAtom;
            Response response      = WebHelper.Get(context.Destination, AcceptAtomXml, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            if (response.StatusCode.HasValue && response.StatusCode.Value == System.Net.HttpStatusCode.OK)
            {
                var      contentType = context.ResponseHttpHeaders.GetHeaderValue(Constants.ContentType);
                string[] pairs       = contentType.Split(new char[] { ';', ' ' });
                foreach (string pair in pairs)
                {
                    if (pair.Equals("application/xml"))
                    {
                        passed = true;
                        break;
                    }
                    else
                    {
                        passed = false;
                    }
                }
            }
            else
            {
                passed = false;
            }

            if (passed == false)
            {
                info = new ExtensionRuleViolationInfo(ErrorMessage, context.Destination, response.StatusCode.ToString());
            }

            return(passed);
        }
コード例 #22
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            ServiceStatus serviceStatus    = ServiceStatus.GetInstance();
            TermDocuments termDocs         = TermDocuments.GetInstance();
            DataFactory   dFactory         = DataFactory.Instance();
            var           detail1          = new ExtensionRuleResultDetail(this.Name);
            var           detail2          = new ExtensionRuleResultDetail(this.Name);
            var           detail3          = new ExtensionRuleResultDetail(this.Name);
            var           detail4          = new ExtensionRuleResultDetail(this.Name);
            List <string> keyPropertyTypes = new List <string>()
            {
                "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String"
            };
            List <string> norPropertyTypes = new List <string>()
            {
                "Edm.String"
            };
            List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, norPropertyTypes, NavigationRoughType.CollectionValued).ToList();

            if (null == entityTypeElements || 0 == entityTypeElements.Count())
            {
                detail1.ErrorMessage = "It expects an entity type with Int32 key property and containing a string property to Patch/Post, but there is no this entity type in metadata so can not verify this rule.";
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            foreach (var et in entityTypeElements)
            {
                string navigPropName = null;
                string navigPropRelatedEntitySetUrl      = null;
                string navigPropRelatedEntityTypeKeyName = null;
                var    matchEntity = et.EntitySetName.GetRestrictions(serviceStatus.MetadataDocument, termDocs.VocCapabilitiesDoc,
                                                                      new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >()
                {
                    AnnotationsHelper.GetDeleteRestrictions, AnnotationsHelper.GetInsertRestrictions, AnnotationsHelper.GetUpdateRestrictions
                });

                if (string.IsNullOrEmpty(matchEntity.Item1) ||
                    matchEntity.Item2 == null || !matchEntity.Item2.Any() ||
                    matchEntity.Item3 == null || !matchEntity.Item3.Any())
                {
                    continue;
                }

                foreach (var np in matchEntity.Item3)
                {
                    navigPropName = np.NavigationPropertyName;
                    string navigEntityTypeShortName     = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment();
                    List <NormalProperty> navigKeyProps = MetadataHelper.GetKeyProperties(serviceStatus.MetadataDocument, navigEntityTypeShortName).ToList();

                    if (navigKeyProps.Count == 1 && keyPropertyTypes.Contains(navigKeyProps[0].PropertyType))
                    {
                        navigPropRelatedEntitySetUrl      = navigEntityTypeShortName.MapEntityTypeShortNameToEntitySetURL();
                        navigPropRelatedEntityTypeKeyName = navigKeyProps[0].PropertyName;

                        break;
                    }
                }

                if (!string.IsNullOrEmpty(navigPropRelatedEntityTypeKeyName) && !string.IsNullOrEmpty(navigPropRelatedEntitySetUrl))
                {
                    string entitySetUrl    = et.EntitySetName.MapEntitySetNameToEntitySetURL();
                    string url             = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl;
                    var    additionalInfos = new List <AdditionalInfo>();
                    var    reqData         = dFactory.ConstructInsertedEntityData(et.EntitySetName, et.EntityTypeShortName, null, out additionalInfos);
                    string reqDataStr      = reqData.ToString();
                    bool   isMediaType     = !string.IsNullOrEmpty(additionalInfos.Last().ODataMediaEtag);
                    var    resp            = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos);
                    detail1 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr);

                    if (null != resp && HttpStatusCode.Created == resp.StatusCode)
                    {
                        string  entityId  = additionalInfos.Last().EntityId;
                        bool    hasEtag   = additionalInfos.Last().HasEtag;
                        JObject newEntity = JObject.Parse(resp.ResponsePayload);
                        url     = serviceStatus.RootURL.TrimEnd('/') + @"/" + navigPropRelatedEntitySetUrl;
                        resp    = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, serviceStatus.DefaultHeaders);
                        detail2 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, serviceStatus.DefaultHeaders), resp);
                        if (resp.StatusCode == HttpStatusCode.OK)
                        {
                            JObject feed;
                            resp.ResponsePayload.TryToJObject(out feed);
                            var entities = JsonParserHelper.GetEntries(feed);

                            if (entities.Count > 0 && entities[0][Constants.V4OdataId] != null)
                            {
                                reqDataStr = @"{""" + Constants.V4OdataId + @""" : """ + entities[0][Constants.V4OdataId].ToString() + @"""}";
                                url        = string.Format("{0}/{1}/$ref", entityId, navigPropName);

                                // Verify to send a POST Http request and response with a 204 No Content status code.
                                resp    = WebHelper.CreateEntity(url, reqDataStr);
                                detail3 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr);

                                if (null != resp && resp.StatusCode == HttpStatusCode.NoContent)
                                {
                                    if (resp.ResponseHeaders.Contains("OData-EntityId"))
                                    {
                                        // Verify to send a PATCH Http request and response with a 204 No Content status code.
                                        List <string> norPropertyNames = et.NormalProperties
                                                                         .Where(np => norPropertyTypes.Contains(np.PropertyType) && !np.IsKey)
                                                                         .Select(np => np.PropertyName).ToList();
                                        if (!norPropertyNames.Any())
                                        {
                                            detail3.ErrorMessage = "The entity-type does not contain any properties can be updated.";
                                            info = new ExtensionRuleViolationInfo(new Uri(url), resp.ResponsePayload, detail3);

                                            return(passed);
                                        }

                                        reqData = dFactory.ConstructUpdatedEntityData(newEntity, norPropertyNames);
                                        resp    = WebHelper.UpdateEntity(entityId, context.RequestHeaders, reqDataStr, HttpMethod.Patch, hasEtag);
                                        detail4 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Patch, string.Empty, resp, string.Empty, reqDataStr);

                                        if (HttpStatusCode.NoContent == resp.StatusCode)
                                        {
                                            if (resp.ResponseHeaders.Contains("OData-EntityId"))
                                            {
                                                passed = true;
                                            }
                                            else
                                            {
                                                passed = false;
                                                detail4.ErrorMessage = "The response headers does not contain OData-EntityId header for above patch request.";
                                            }
                                        }
                                        else
                                        {
                                            passed = false;
                                            detail4.ErrorMessage = "Patch HTTP request failed.";
                                        }
                                    }
                                    else
                                    {
                                        passed = false;
                                        detail3.ErrorMessage = "The response headers does not contain OData-EntityId header for above POST request.";
                                    }
                                }
                                else
                                {
                                    passed = false;
                                    detail3.ErrorMessage = "POST HTTP request failed for above URI.";
                                }
                            }
                        }

                        // Restore the service.
                        var resps = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos);
                    }
                    else
                    {
                        passed = false;
                        detail1.ErrorMessage = "Created the new entity failed for above URI.";
                    }

                    break;
                }
            }

            var details = new List <ExtensionRuleResultDetail>()
            {
                detail1, detail2, detail3, detail4
            }.RemoveNullableDetails();

            info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, details);

            return(passed);
        }
コード例 #23
0
        /// <summary>
        /// Verify SvcDoc.Core.4012
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            JObject allobject;

            context.ResponsePayload.TryToJObject(out allobject);
            if (allobject == null)
            {
                return(passed);
            }

            foreach (JObject val in (JArray)allobject[Constants.Value])
            {
                if (val[Constants.Kind] != null && val[Constants.Kind].Value <string>().ToString().StripOffDoubleQuotes().Equals("ServiceDocument"))
                {
                    string   url      = val[Constants.Url].Value <string>().ToString().StripOffDoubleQuotes();
                    Response response = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                    JObject jo;
                    response.ResponsePayload.TryToJObject(out jo);
                    var payloadFormat = response.ResponsePayload.GetFormatFromPayload();
                    var payloadType   = ContextHelper.GetPayloadType(response.ResponsePayload, payloadFormat, response.ResponseHeaders);

                    if (payloadType != RuleEngine.PayloadType.ServiceDoc)
                    {
                        passed = false;
                        info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                        break;
                    }
                    else
                    {
                        passed = true;
                    }
                }
            }

            return(passed);
        }
コード例 #24
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?                     passed   = null;
            var                       response = WebHelper.Get(context.Destination, string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
            PayloadFormat             format   = ContextHelper.GetFormatFromPayload(response.ResponsePayload);
            ExtensionRuleResultDetail detail   = new ExtensionRuleResultDetail(this.Name, context.Destination.AbsoluteUri, "GET", StringHelper.MergeHeaders(string.Empty, context.RequestHeaders), response);

            if (response != null && response.StatusCode != null)
            {
                if (format == RuleEngine.PayloadFormat.JsonLight)
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    detail.ErrorMessage = "Get above URI with accept header 'application/json', the response is not JSON format.";
                }
            }
            else
            {
                passed = false;
                detail.ErrorMessage = String.Format("No response returned from above URI with accept header 'application/json'.");
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            Response resp = WebHelper.Get(new Uri(context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + "$all"), Constants.AcceptHeaderJson,
                                          RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name, context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + "$all",
                                                                             HttpMethod.Get, context.RequestHeaders.ToString());

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                return(passed = false);
            }

            JObject allFeed;

            resp.ResponsePayload.TryToJObject(out allFeed);

            if (allFeed == null || JTokenType.Object != allFeed.Type)
            {
                return(passed = false);
            }

            JArray allEntities = JsonParserHelper.GetEntries(allFeed);

            passed = true;

            List <string> entitySetURLs = MetadataHelper.GetEntitySetURLs();

            foreach (string entitySetUrl in entitySetURLs)
            {
                string entityTypeShortName = entitySetUrl.MapEntitySetNameToEntityTypeShortName();
                Tuple <string, string> key = MetadataHelper.GetKeyProperty(entityTypeShortName);

                resp = WebHelper.Get(new Uri(context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + entitySetUrl),
                                     Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
                detail.URI                = context.ServiceBaseUri.OriginalString.TrimEnd('/') + @"/" + entitySetUrl;
                detail.ResponsePayload    = resp.ResponsePayload;
                detail.ResponseHeaders    = resp.ResponseHeaders;
                detail.HTTPMethod         = "GET";
                detail.ResponseStatusCode = resp.StatusCode.ToString();

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    continue;
                }

                JObject feed;
                resp.ResponsePayload.TryToJObject(out feed);

                if (feed == null || JTokenType.Object != feed.Type)
                {
                    continue;
                }

                JArray entities = JsonParserHelper.GetEntries(feed);
                foreach (JToken entity in entities)
                {
                    try
                    {
                        var test = entity;


                        if (!Find(allEntities, key.Item1, entity[key].ToString()))
                        {
                            passed = false;
                            //public ExtensionRuleResultDetail(string ruleName, string uri, string httpMethod, string requestHeaders, string responseStatusCode = "", string responseHeaders = "", string responsePayload = "", string errorMessage = "", string requestData = "")
                            ExtensionRuleResultDetail detail2 = new ExtensionRuleResultDetail(this.Name);
                            detail2.ErrorMessage = "Unable to find key / value in entity set using:  " + key.Item1 + "/" + entity[key].ToString();
                            info.AddDetail(detail2);
                        }
                        else
                        {
                            return(passed = true);
                        }
                    }
                    catch (Exception ex)
                    {
                        passed = false;
                        ExtensionRuleResultDetail detail3 = new ExtensionRuleResultDetail(this.Name);
                        detail3.ErrorMessage = "Exception occured try to find key / value in entity set:  " + ex.Message;
                        info.AddDetail(detail3);
                    }
                }
            }

            return(passed);
        }
コード例 #26
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            ServiceStatus             serviceStatus    = ServiceStatus.GetInstance();
            TermDocuments             termDocs         = TermDocuments.GetInstance();
            DataFactory               dFactory         = DataFactory.Instance();
            ExtensionRuleResultDetail detail1          = new ExtensionRuleResultDetail(this.Name);
            ExtensionRuleResultDetail detail2          = new ExtensionRuleResultDetail(this.Name);
            List <string>             keyPropertyTypes = new List <string>()
            {
                "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String"
            };
            List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, null, NavigationRoughType.None).ToList();

            if (null == entityTypeElements || 0 == entityTypeElements.Count())
            {
                detail1.ErrorMessage = "To verify this rule it expects an entity type with Int32/Int64/Int16/Guid/String key property, but there is no this entity type in metadata so can not verify this rule.";
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            // To get test entity which is deleteable and insertable
            EntityTypeElement entityType = null;

            foreach (var entityEle in entityTypeElements)
            {
                var matchEntity = entityEle.EntitySetName.GetRestrictions(serviceStatus.MetadataDocument, termDocs.VocCapabilitiesDoc,
                                                                          new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >()
                {
                    AnnotationsHelper.GetInsertRestrictions, AnnotationsHelper.GetDeleteRestrictions
                });

                if (!string.IsNullOrEmpty(matchEntity.Item1) &&
                    matchEntity.Item2 != null && matchEntity.Item2.Any() &&
                    matchEntity.Item3 != null && matchEntity.Item3.Any())
                {
                    entityType = entityEle;
                    break;
                }
            }

            if (null == entityType)
            {
                detail1.ErrorMessage = "To verify this rule it expects an entity type with deleteable and insertable restrictions, but there is no entity type in metadata which is insertable and deleteable.";
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            string entitySetUrl = entityType.EntitySetName.MapEntitySetNameToEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                detail1.ErrorMessage = string.Format("Cannot find the entity-set URL which is matched with {0}.", entityType.EntityTypeShortName);
                info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1);

                return(passed);
            }

            string url             = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl;
            var    additionalInfos = new List <AdditionalInfo>();
            var    reqData         = dFactory.ConstructInsertedEntityData(entityType.EntitySetName, entityType.EntityTypeShortName, null, out additionalInfos);
            string reqDataStr      = reqData.ToString();
            bool   isMediaType     = !string.IsNullOrEmpty(additionalInfos.Last().ODataMediaEtag);
            var    resp            = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos);

            detail1 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr);

            // If create successfully, the resource is updatable and deletable.
            if (resp.StatusCode.HasValue && resp.StatusCode == HttpStatusCode.Created)
            {
                // Get feed response.
                resp    = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, serviceStatus.DefaultHeaders);
                detail2 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, serviceStatus.DefaultHeaders), resp);
                if (resp.StatusCode.HasValue && resp.StatusCode == HttpStatusCode.OK)
                {
                    JObject jo;
                    resp.ResponsePayload.TryToJObject(out jo);
                    var entries = JsonParserHelper.GetEntries(jo);
                    foreach (JObject entry in entries)
                    {
                        if (entry[Constants.V4OdataEditLink] == null)
                        {
                            passed = false;
                            detail2.ErrorMessage = "Not all entities from above URI contain edit links.";
                            break;
                        }
                    }

                    if (passed == null)
                    {
                        passed = true;
                    }
                }
                else
                {
                    passed = false;
                    detail2.ErrorMessage = "Get feed resource failed from above URI.";
                }

                // Restore the service.
                var resps = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos);
            }
            else
            {
                passed = null;
                detail1.ErrorMessage = "Created new entity failed, it is not an updatable resource and can not verify this rule.";
            }

            var details = new List <ExtensionRuleResultDetail>()
            {
                detail1, detail2
            }.RemoveNullableDetails();

            info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, details);

            return(passed);
        }
コード例 #27
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;
            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name);
            var restrictions = new Dictionary <string, Tuple <List <NormalProperty>, List <NavigProperty> > >();

            if (!AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities, ref restrictions))
            {
                detail.ErrorMessage = "Cannot find any appropriate entity-sets which supports $expand system query options.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            if (!AnnotationsHelper.IsSuitableNavigationProperty(NavigationRoughType.CollectionValued, ref restrictions))
            {
                detail.ErrorMessage = "Cannot find any collection-valued navigation properties in any entity-sets which supports $expand system query options.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            string entitySet             = string.Empty;
            string navigPropName         = string.Empty;
            string primitivePropertyName = string.Empty;

            foreach (var r in restrictions)
            {
                if (string.IsNullOrEmpty(r.Key) ||
                    null == r.Value.Item1 || !r.Value.Item1.Any() ||
                    null == r.Value.Item2 || !r.Value.Item2.Any())
                {
                    continue;
                }

                foreach (var np in r.Value.Item2)
                {
                    string nEntityType = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment();
                    var    funcs       = new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >()
                    {
                        AnnotationsHelper.GetFilterRestrictions
                    };
                    var expectedTypes = new List <string>()
                    {
                        "Edm.String"
                    };
                    var props = MetadataHelper.GetNormalProperties(context.MetadataDocument, nEntityType);

                    if (null == props || !props.Any())
                    {
                        continue;
                    }

                    var targetProps = props.Where(p => expectedTypes.Contains(p.PropertyType)).Select(p => p);

                    if (!targetProps.Any())
                    {
                        continue;
                    }

                    navigPropName         = np.NavigationPropertyName;
                    primitivePropertyName = targetProps.First().PropertyName;

                    break;
                }

                entitySet = r.Key;

                if (!string.IsNullOrEmpty(navigPropName) && !string.IsNullOrEmpty(primitivePropertyName))
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(entitySet))
            {
                detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query option.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            if (string.IsNullOrEmpty(navigPropName))
            {
                detail.ErrorMessage = "Cannot get expanded entities because cannot get collection type of navigation property from metadata";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            if (string.IsNullOrEmpty(primitivePropertyName))
            {
                detail.ErrorMessage = "Cannot get an appropriate primitive property from navigation properties.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            string url  = string.Format("{0}/{1}?$expand={2}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, navigPropName);
            var    resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            if (null == resp || HttpStatusCode.OK != resp.StatusCode)
            {
                detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            JObject feed;

            resp.ResponsePayload.TryToJObject(out feed);
            var entities = JsonParserHelper.GetEntries(feed);

            if (null == entities || !entities.Any())
            {
                detail.ErrorMessage = string.Format("Cannot find any entities from the entity-set '{0}'", entitySet);
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            string searchVal = string.Empty;

            foreach (var en in entities)
            {
                if (null != en[navigPropName] || JTokenType.Array == en[navigPropName].Type || en[navigPropName].Any())
                {
                    if (en[navigPropName].First != null)
                    {
                        if (JTokenType.Object != en[navigPropName].First.Type)
                        {
                            break;
                        }

                        var nEntity = en[navigPropName].First as JObject;
                        searchVal = nEntity[primitivePropertyName].ToString().Contains(" ") ?
                                    string.Format("\"{0}\"", nEntity[primitivePropertyName].ToString()) :
                                    nEntity[primitivePropertyName].ToString();

                        if (!string.IsNullOrEmpty(searchVal))
                        {
                            break;
                        }
                    }
                    else
                    {
                        detail.ErrorMessage = "The entity set " + entitySet + " with Navigation Property " + navigPropName + " is NULL.  Cannot find any appropriate search values in the expanded entities";
                        info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                        return(passed);
                    }
                }
            }

            if (string.IsNullOrEmpty(searchVal))
            {
                detail.ErrorMessage = "Cannot find any appropriate search values in the expanded entities.";
                info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);

                return(passed);
            }

            url    = string.Format("{0}/{1}?$expand={2}($search={3})", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, navigPropName, searchVal);
            resp   = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);
            detail = new ExtensionRuleResultDetail(this.Name, url, "GET", String.Empty, resp);

            if (null != resp && resp.StatusCode == HttpStatusCode.OK)
            {
                resp.ResponsePayload.TryToJObject(out feed);

                if (null != feed && JTokenType.Object == feed.Type)
                {
                    entities = JsonParserHelper.GetEntries(feed);

                    foreach (var e in entities)
                    {
                        var navigEntities = e[navigPropName].ToList();

                        if (null == navigEntities || !navigEntities.Any())
                        {
                            continue;
                        }

                        foreach (var ne in navigEntities)
                        {
                            passed = null;

                            if (searchVal.StripOffDoubleQuotes() == ne[primitivePropertyName].ToString())
                            {
                                passed = true;
                            }

                            if (passed == null)
                            {
                                passed = false;
                                detail.ErrorMessage = "The service does not execute an accurate result on the system query option '$search' for expanded properties.";
                            }
                        }

                        if (passed == false)
                        {
                            break;
                        }
                    }

                    if (null == passed)
                    {
                        detail.ErrorMessage = "Cannot find any appropriate data to verify this rule.";
                    }
                }
                else
                {
                    detail.ErrorMessage = "The service does not return an correct response payload.";
                }
            }
            else
            {
                passed = false;
                detail.ErrorMessage = "The service does not support the system query option '$search' for expanded properties.";
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            var    svcStatus = ServiceStatus.GetInstance();
            string entityTypeShortName;
            var    propTypes = new string[1] {
                "Edm.DateTimeOffset"
            };
            var propNames = MetadataHelper.GetPropertyNames(propTypes, out entityTypeShortName);

            if (null == propNames || !propNames.Any())
            {
                var detail1 = new ExtensionRuleResultDetail(this.Name);
                detail1.ErrorMessage = "No properties were returned for Edm.DateTimeOffset.  Nothing to test";
                info = new ExtensionRuleViolationInfo(context.ServiceBaseUri, string.Empty, detail1);
                return(passed);
            }

            string propName     = propNames[0];
            var    entitySetUrl = entityTypeShortName.GetAccessEntitySetURL();

            if (string.IsNullOrEmpty(entitySetUrl))
            {
                var detail1 = new ExtensionRuleResultDetail(this.Name);
                detail1.ErrorMessage = "Entity Set URL was empty.  Unable to test.";
                info = new ExtensionRuleViolationInfo(context.ServiceBaseUri, string.Empty, detail1);

                return(passed);
            }

            string url  = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl;
            var    resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);

            if (null != resp && HttpStatusCode.OK == resp.StatusCode)
            {
                var settings = new JsonSerializerSettings();
                settings.DateParseHandling = DateParseHandling.None;
                JObject jObj    = JsonConvert.DeserializeObject(resp.ResponsePayload, settings) as JObject;
                JArray  jArr    = jObj.GetValue(Constants.Value) as JArray;
                var     entity  = jArr.First as JObject;
                var     propVal = string.Empty;

                for (int i = 0; i < propNames.Count - 1; i++)
                {
                    try
                    {
                        propVal = entity[propNames[i].ToString()].ToString();
                    }
                    catch
                    {
                    }
                    if (!string.IsNullOrEmpty(propVal))
                    {
                        propName = propNames[i].ToString();
                        break;
                    }
                }


                if (!string.IsNullOrEmpty(propVal))
                {
                    int index = propVal.IndexOf('T');
                    if (index < 0)
                    {
                        var detail1 = new ExtensionRuleResultDetail(this.Name);
                        detail1.ErrorMessage = propVal + " is missing the delimiter T in the date time format.";
                        info = new ExtensionRuleViolationInfo(context.ServiceBaseUri, string.Empty, detail1);

                        passed = false;
                        return(passed);
                    }
                    else
                    {
                        propVal = propVal.Substring(index - 2, 2);
                        url     = string.Format("{0}?$filter=day({1}) eq {2}", url, propName, propVal);
                        resp    = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders);
                        var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty);
                        detail.URI                = url;
                        detail.ResponsePayload    = resp.ResponsePayload;
                        detail.ResponseHeaders    = resp.ResponseHeaders;
                        detail.HTTPMethod         = "GET";
                        detail.ResponseStatusCode = resp.StatusCode.ToString();

                        info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail);
                        if (null != resp && HttpStatusCode.OK == resp.StatusCode)
                        {
                            jObj = JsonConvert.DeserializeObject(resp.ResponsePayload, settings) as JObject;
                            jArr = jObj.GetValue(Constants.Value) as JArray;
                            foreach (JObject et in jArr)
                            {
                                passed = et[propName].ToString().Substring(index - 2, 2) == propVal;
                                if (passed == false)
                                {
                                    detail.ErrorMessage = et[propName].ToString().Substring(index - 2, 2) + " is not equal to " + propVal;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            detail.ErrorMessage = "The server returned an error response:  " + detail.ResponseStatusCode;
                            passed = false;
                        }
                    }
                }
                else
                {
                    var detail1 = new ExtensionRuleResultDetail(this.Name);
                    detail1.ErrorMessage = "The property value is empty.  Unable to test.";
                    info = new ExtensionRuleViolationInfo(context.ServiceBaseUri, string.Empty, detail1);

                    passed = false;
                }
            }

            return(passed);
        }
コード例 #29
0
        /// <summary>
        /// Verifies the service implementation feature.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if the service implementation feature passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name);

            info   = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            detail = info.Details[0];

            List <string> supportedPropertyTypes = new List <string>();

            #region Using ge and le as the single condition

            supportedPropertyTypes.Clear();
            supportedPropertyTypes.AddRange(new List <string> {
                PrimitiveDataTypes.Int16, PrimitiveDataTypes.Int32, PrimitiveDataTypes.Int64,
                PrimitiveDataTypes.Decimal, PrimitiveDataTypes.Double
            });

            var filterRestrictions = AnnotationsHelper.GetFilterRestrictionsWithoutNavi(context.MetadataDocument, context.VocCapabilities, supportedPropertyTypes);

            if (string.IsNullOrEmpty(filterRestrictions.Item1) ||
                null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any())
            {
                detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service.";
            }
            else
            {
                string entitySet         = filterRestrictions.Item1;
                string primitivePropName = filterRestrictions.Item2.First().PropertyName;
                string primitivePropType = filterRestrictions.Item2.First().PropertyType;

                string url  = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet);
                var    resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    passed = false;
                    detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                }
                else
                {
                    JObject feed;
                    resp.ResponsePayload.TryToJObject(out feed);

                    if (feed == null || JTokenType.Object != feed.Type)
                    {
                        passed = false;
                        detail.ErrorMessage = "The service does not return a valid response for system query option";
                    }
                    else
                    {
                        var   entities = JsonParserHelper.GetEntries(feed);
                        Int64 propVal  = entities[0][primitivePropName].Value <Int64>();

                        string pattern = "{0}/{1}?$filter=not {2} eq {3}";
                        url  = string.Format(pattern, context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, primitivePropName, propVal);
                        resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                        detail.URI                = url;
                        detail.HTTPMethod         = "GET";
                        detail.RequestHeaders     = StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders);
                        detail.ResponseStatusCode = resp != null && resp.StatusCode.HasValue ? resp.StatusCode.Value.ToString() : "";
                        detail.ResponseHeaders    = string.IsNullOrEmpty(resp.ResponseHeaders) ? "" : resp.ResponseHeaders;
                        detail.ResponsePayload    = string.IsNullOrEmpty(resp.ResponsePayload) ? "" : resp.ResponsePayload;

                        if (resp.StatusCode != HttpStatusCode.OK)
                        {
                            passed = false;
                            detail.ErrorMessage = "Request failed with system query option $filter not.";
                        }
                        else
                        {
                            JObject feed1;
                            resp.ResponsePayload.TryToJObject(out feed1);

                            if (feed1 == null || JTokenType.Object != feed1.Type)
                            {
                                passed = false;
                                detail.ErrorMessage = "The service does not return a valid response for system query option $filter not.";
                            }
                            else
                            {
                                var entities1 = JsonParserHelper.GetEntries(feed1).ToList();
                                var temp      = entities1.FindAll(en => (en[primitivePropName].Value <Int64>() == propVal)).Select(en => en);

                                if (temp.Count() == 0)
                                {
                                    passed = true;
                                }
                                else
                                {
                                    passed = false;
                                    detail.ErrorMessage = "The service does not execute an accurate result with system query option $filter not.";
                                }
                            }
                        }
                    }
                }
            }

            #endregion Using ge and le as the single condition

            if (passed.HasValue && passed.Value)
            {
                return(passed);
            }

            #region Using startswith and endswith as the single condition

            supportedPropertyTypes.Clear();
            supportedPropertyTypes.Add(PrimitiveDataTypes.String);

            filterRestrictions = AnnotationsHelper.GetFilterRestrictionsWithoutNavi(context.MetadataDocument, context.VocCapabilities, supportedPropertyTypes);

            if (string.IsNullOrEmpty(filterRestrictions.Item1) ||
                null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any())
            {
                detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service.";
            }
            else
            {
                string entitySet         = filterRestrictions.Item1;
                string primitivePropName = filterRestrictions.Item2.First().PropertyName;
                string primitivePropType = filterRestrictions.Item2.First().PropertyType;

                string url  = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet);
                var    resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (null == resp || HttpStatusCode.OK != resp.StatusCode)
                {
                    passed = false;
                    detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload);
                }
                else
                {
                    JObject feed;
                    resp.ResponsePayload.TryToJObject(out feed);

                    if (feed == null || JTokenType.Object != feed.Type)
                    {
                        passed = false;
                        detail.ErrorMessage = "The service does not return a valid response for system query option";
                    }
                    else
                    {
                        var    entities = JsonParserHelper.GetEntries(feed);
                        string propVal  = entities[0][primitivePropName].Value <string>();

                        string pattern = "{0}/{1}?$filter=not endswith({2},'{3}')";
                        url  = string.Format(pattern, context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, primitivePropName, propVal);
                        resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                        detail.URI                = url;
                        detail.HTTPMethod         = "GET";
                        detail.RequestHeaders     = StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders);
                        detail.ResponseStatusCode = resp != null && resp.StatusCode.HasValue ? resp.StatusCode.Value.ToString() : "";
                        detail.ResponseHeaders    = string.IsNullOrEmpty(resp.ResponseHeaders) ? "" : resp.ResponseHeaders;
                        detail.ResponsePayload    = string.IsNullOrEmpty(resp.ResponsePayload) ? "" : resp.ResponsePayload;

                        if (resp.StatusCode != HttpStatusCode.OK)
                        {
                            passed = false;
                            detail.ErrorMessage = "Request failed with system query option $filter not.";
                        }
                        else
                        {
                            JObject feed1;
                            resp.ResponsePayload.TryToJObject(out feed1);

                            if (feed1 == null || JTokenType.Object != feed1.Type)
                            {
                                passed = false;
                                detail.ErrorMessage = "The service does not return a valid response for system query option $filter not.";
                            }
                            else
                            {
                                var entities1 = JsonParserHelper.GetEntries(feed1).ToList();
                                var temp      = entities1.FindAll(en => en[primitivePropName].Value <string>().EndsWith(propVal)).Select(en => en);

                                if (temp.Count() == 0)
                                {
                                    passed = true;
                                }
                                else
                                {
                                    passed = false;
                                    detail.ErrorMessage = "The service does not execute an accurate result with system query option $filter not.";
                                }
                            }
                        }
                    }
                }
            }

            #endregion Using ge and le as the single condition

            return(passed);
        }
コード例 #30
0
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            string  acceptHeader = string.Empty;
            bool?   resultOfIEEE754CompatibleFalse        = null;
            bool?   resultOfIEEE754CompatibleNotSpecified = null;
            JObject jo;

            string odataCount = Constants.V4OdataCount;

            if (context.Version == ODataVersion.V3)
            {
                odataCount = Constants.OdataCount;
            }

            if (context.PayloadType == RuleEngine.PayloadType.Feed || context.PayloadType == RuleEngine.PayloadType.Entry)
            {
                Uri absoluteUri = new Uri(context.Destination.OriginalString.Split('?')[0]);
                Uri relativeUri = new Uri("?$format=application/json;odata.metadata=full;IEEE754Compatible=false", UriKind.Relative);
                Uri combinedUri = new Uri(absoluteUri, relativeUri);

                // Send request with IEEE754Compatible=false query parameter.
                acceptHeader = Constants.AcceptHeaderJson;
                Response responseOfIEEE754CompatibleFalse = WebHelper.Get(combinedUri, acceptHeader, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                if (responseOfIEEE754CompatibleFalse.StatusCode == HttpStatusCode.OK)
                {
                    responseOfIEEE754CompatibleFalse.ResponsePayload.TryToJObject(out jo);
                    resultOfIEEE754CompatibleFalse = this.IsInt64AndDecimalAsNumber(jo, context.PayloadType, odataCount);
                }

                if (resultOfIEEE754CompatibleFalse.HasValue)
                {
                    if (resultOfIEEE754CompatibleFalse.Value == true)
                    {
                        // Send request with not specifying IEEE754Compatible query parameter.
                        relativeUri = new Uri("?$format=application/json;odata.metadata=full", UriKind.Relative);
                        combinedUri = new Uri(absoluteUri, relativeUri);
                        Response responseOfIEEE754CompatibleNotSpecified = WebHelper.Get(combinedUri, acceptHeader, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                        if (responseOfIEEE754CompatibleNotSpecified.StatusCode == HttpStatusCode.OK)
                        {
                            responseOfIEEE754CompatibleNotSpecified.ResponsePayload.TryToJObject(out jo);
                            resultOfIEEE754CompatibleNotSpecified = this.IsInt64AndDecimalAsNumber(jo, context.PayloadType, odataCount);

                            if (resultOfIEEE754CompatibleNotSpecified.HasValue && resultOfIEEE754CompatibleNotSpecified.Value == true)
                            {
                                passed = true;
                            }
                            else
                            {
                                passed = false;
                                info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                            }
                        }
                    }
                    else
                    {
                        passed = false;
                        info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                    }
                }
            }

            return(passed);
        }