/// <summary> /// Checks whether the context payload is a partial collection of entrities /// </summary> /// <param name="context">The service context</param> /// <returns>True if it is partial collection; false otherwise</returns> private static bool IsPartialColleclection(ServiceContext context) { bool anyNewEntry = false; JObject contextResponse = JsonParserHelper.GetResponseObject(context); if (contextResponse != null) { JArray contextEntries = JsonParserHelper.GetEntries(contextResponse); if (contextEntries.Count > 0) { // if any more entries return, the context response payload was a partial collection Uri prober = FeedCore2001.ConstructProbeUri(context); var resp = WebHelper.Get(prober, Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (resp == null || string.IsNullOrEmpty(resp.ResponsePayload) || !JsonHelper.IsJsonVerboseFeed(resp.ResponsePayload)) { return(false); } JObject response = JsonParserHelper.GetResponseObject(resp.ResponsePayload); if (response != null) { JArray entries = JsonParserHelper.GetEntries(response); if (entries.Count > 0) { // some producers do not respect $skipton; // need to look at each entry to see whether there is any new entry. HashSet <string> contextEntryKeys = new HashSet <string>(EqualityComparer <string> .Default); foreach (var e in contextEntries) { if (e.Type == JTokenType.Object) { var i = JsonParserHelper.GetTokenOfEntry((JObject)e); contextEntryKeys.Add(i); } } foreach (var e in entries) { if (e.Type == JTokenType.Object) { var i = JsonParserHelper.GetTokenOfEntry((JObject)e); if (!contextEntryKeys.Contains(i)) { anyNewEntry = true; break; } } } } } } } return(anyNewEntry); }
/// <summary> /// Builds the uri for purpose of probing any remaining entries satisfying the request of service context /// use the last entry's token in the feed as the marker of skiptoken; /// and reduce the $top count if top was in context request URI. /// </summary> /// <param name="context">The service context object</param> /// <returns>Uri object if a meaningful prober can be constructed; null otherwise </returns> private static Uri ConstructProbeUri(ServiceContext context) { Uri result = null; JObject response = JsonParserHelper.GetResponseObject(context); if (response != null) { JArray entries = JsonParserHelper.GetEntries(response); if (entries != null) { JObject lastEntry = JsonParserHelper.GetLastEntry(entries); if (lastEntry != null) { string lastToken = JsonParserHelper.GetTokenOfEntry(lastEntry); string lastTokenOfValues = ResourcePathHelper.GetValuesOfKey(lastToken); var uri = context.Destination; ResourcePathHelper pathHelper = new ResourcePathHelper(uri); // replace top value with the reduced value, if $top was in context request string topValue = pathHelper.GetQueryValue("$top"); if (!string.IsNullOrEmpty(topValue)) { pathHelper.RemoveQueryOption("$top"); int entriesGot = entries.Count; int entriesToGet; if (Int32.TryParse(topValue, out entriesToGet) && entriesToGet > entriesGot) { int entriesLeft = entriesToGet - entriesGot; pathHelper.AddQueryOption("$top", entriesLeft.ToString(CultureInfo.InvariantCulture)); } } // set up new skiptoken query pathHelper.RemoveQueryOption("$skiptoken"); pathHelper.AddQueryOption("$skiptoken", lastTokenOfValues); result = new Uri(pathHelper.Product); } } } return(result); }