/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }