/// <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); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); 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 = null; for (int n = 0; n < entities.Count; n++) { //if (entities[0].Value != null) { try { propVal = entities[0].Value <Int64>(primitivePropName) - 1; break; } catch { } } } if (propVal == null) { detail.ErrorMessage = "Unable to find a suitable property to test. They have all returned NULL. Require a Int64 with data"; passed = false; return(passed); } //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); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); 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 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> { 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 Greater Than system query options in the service."; return(passed); } string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; 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); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed == null || JTokenType.Object != feed.Type) { detail.ErrorMessage = "The service does not return a valid response for system query option"; return(passed); } var entities = JsonParserHelper.GetEntries(feed); Int64 propVal = entities[0].Value <Int64>(primitivePropName) - 1; string pattern = "{0}/{1}?$filter={2} gt {3}"; url = string.Format(pattern, context.ServiceBaseUri, 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 gt."; return(passed); } JObject feed2; resp.ResponsePayload.TryToJObject(out feed2); if (feed2 == null || JTokenType.Object != feed2.Type) { passed = false; detail.ErrorMessage = "The service does not return a valid response for system query option $filter gt."; return(passed); } var entities2 = JsonParserHelper.GetEntries(feed2).ToList(); var temp = entities2.FindAll(en => en.Value <Int64>(primitivePropName) > propVal).Select(en => en); if (entities2.Count() == temp.Count()) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result with system query option $filter gt."; } return(passed); }