/// <summary> /// Generator that allows lazy access to paginated resources. /// </summary> private static IEnumerable <List <TValue> > IteratePages <TValue>(ISharpBucketRequesterV2 sharpBucketRequesterV2, string relativeUrl, int pageLen = DEFAULT_PAGE_LEN, IDictionary <string, object> requestParameters = null) { Debug.Assert(!string.IsNullOrEmpty(relativeUrl)); Debug.Assert(!relativeUrl.Contains("?")); relativeUrl = relativeUrl.Replace(SharpBucketV2.BITBUCKET_URL, ""); if (requestParameters == null) { requestParameters = new Dictionary <string, object>(); } requestParameters["pagelen"] = pageLen; while (true) { var response = sharpBucketRequesterV2.Get <IteratorBasedPage <TValue> >(relativeUrl, requestParameters); if (response == null) { break; } yield return(response.values); if (string.IsNullOrWhiteSpace(response.next)) { break; } var uri = new Uri(response.next); var parsedQuery = HttpUtility.ParseQueryString(uri.Query); requestParameters = parsedQuery.AllKeys.ToDictionary <string, string, object>(key => key, parsedQuery.Get); } }
/// <summary> /// Returns a list of paginated values. /// </summary> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="sharpBucketRequester"></param> /// <param name="relativeUrl">The relative URL to the paginated resource to call.</param> /// <param name="max">Set to 0 for unlimited size.</param> /// <param name="requestParameters"></param> /// <returns></returns> /// <exception cref="BitbucketV2Exception">Thrown when the server fails to respond.</exception> public static List <TValue> GetPaginatedValues <TValue>(this ISharpBucketRequesterV2 sharpBucketRequesterV2, string relativeUrl, int max = 0, IDictionary <string, object> requestParameters = null) { var isMaxConstrained = max > 0; var pageLen = (isMaxConstrained && max < DEFAULT_PAGE_LEN) ? max : DEFAULT_PAGE_LEN; var values = new List <TValue>(); foreach (var page in IteratePages <TValue>(sharpBucketRequesterV2, relativeUrl, pageLen, requestParameters)) { if (page == null) { break; } if (isMaxConstrained && values.Count + page.Count >= max) { values.AddRange(page.GetRange(0, max - values.Count)); Debug.Assert(values.Count == max); break; } values.AddRange(page); } return(values); }
public void EnumerateSearchCodeSearchResults_SearchStringWordFromTeamAtlassianWithPageLenLessThanTheNumberOfEnumeratedResults_RequestsCountShouldIncrementLazily() { ISharpBucketRequesterV2 realSharpBucketRequesterV2 = TestHelpers.SharpBucketV2; var sharpBucketRequesterV2Mock = new Mock <ISharpBucketRequesterV2>(); Expression <Func <ISharpBucketRequesterV2, IteratorBasedPage <SearchCodeSearchResult> > > sendMethod = x => x.Send <IteratorBasedPage <SearchCodeSearchResult> >(It.IsAny <HttpMethod>(), It.IsAny <object>(), It.IsAny <string>(), It.IsAny <object>()); sharpBucketRequesterV2Mock .Setup(sendMethod) .Returns <HttpMethod, object, string, object>((m, b, u, p) => realSharpBucketRequesterV2.Send <IteratorBasedPage <SearchCodeSearchResult> >(m, b, u, p)); var teamsEndPointIntercepted = new TeamsEndPoint(sharpBucketRequesterV2Mock.Object); var searchResults = teamsEndPointIntercepted.TeamResource("atlassian").EnumerateSearchCodeSearchResults("string", 5); sharpBucketRequesterV2Mock.Verify( sendMethod, Times.Never(), "Building the enumerable should not produce any request"); var i = 0; foreach (var _ in searchResults) { if (i < 5) { sharpBucketRequesterV2Mock.Verify( sendMethod, Times.Exactly(1), "Only first page should have been called"); } else { sharpBucketRequesterV2Mock.Verify( sendMethod, Times.Exactly(2), "Only two pages should have been called"); if (i == 9) { break; } } i++; } }
/// <summary> /// Returns an enumeration of paginated values. The pages are requested lazily while iterating on the values. /// </summary> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="sharpBucketRequester"></param> /// <param name="overrideUrl">The override URL.</param> /// <param name="requestParameters"></param> /// <param name="pageLen">The size of a page.</param> /// <returns>A lazy enumerable over the values.</returns> /// <exception cref="BitbucketV2Exception">Thrown when the server fails to respond.</exception> public static async IAsyncEnumerable <TValue> EnumeratePaginatedValuesAsync <TValue>( this ISharpBucketRequesterV2 sharpBucketRequesterV2, string overrideUrl, IDictionary <string, object> requestParameters, int?pageLen, [EnumeratorCancellation] CancellationToken token) { await foreach (var page in IteratePagesAsync <TValue>(sharpBucketRequesterV2, overrideUrl, pageLen ?? DEFAULT_PAGE_LEN, requestParameters, token)) { if (page == null) { yield break; } foreach (var item in page) { yield return(item); } } }
/// <summary> /// Generator that allows lazy access to paginated resources. /// </summary> private static async IAsyncEnumerable <List <TValue> > IteratePagesAsync <TValue>( ISharpBucketRequesterV2 sharpBucketRequesterV2, string overrideUrl, int pageLen, IDictionary <string, object> requestParameters, [EnumeratorCancellation] CancellationToken token) { Debug.Assert(!string.IsNullOrEmpty(overrideUrl)); Debug.Assert(!overrideUrl.Contains("?")); overrideUrl = overrideUrl.Replace(SharpBucketV2.BITBUCKET_URL, ""); if (requestParameters == null) { requestParameters = new Dictionary <string, object>(); } requestParameters["pagelen"] = pageLen; while (true) { var response = await sharpBucketRequesterV2.GetAsync <IteratorBasedPage <TValue> >(overrideUrl, requestParameters, token : token); if (response == null) { break; } yield return(response.values); if (string.IsNullOrWhiteSpace(response.next)) { break; } var uri = new Uri(response.next); var parsedQuery = HttpUtility.ParseQueryString(uri.Query); requestParameters = parsedQuery.AllKeys.ToDictionary <string, string, object>(key => key, parsedQuery.Get); } }
public TeamResource(ISharpBucketRequesterV2 sharpBucketV2, string teamName) : this(new TeamsEndPoint(sharpBucketV2), teamName) { }
public ProjectResource(ISharpBucketRequesterV2 sharpBucketV2, string teamName, string projectKey) : this(new TeamsEndPoint(sharpBucketV2).TeamResource(teamName), projectKey) { }
public RepositoriesAccountResource( ISharpBucketRequesterV2 sharpBucketV2, string accountName, RepositoriesEndPoint repositoriesEndPoint) : this(repositoriesEndPoint, accountName) { }
public RepositoriesEndPoint(ISharpBucketRequesterV2 sharpBucketV2) : base(sharpBucketV2, "repositories/") { }
/// <summary> /// Returns an enumeration of paginated values. The pages are requested lazily while iterating on the values. /// </summary> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="sharpBucketRequester"></param> /// <param name="relativeUrl">The relative URL to the paginated resource to call.</param> /// <param name="requestParameters"></param> /// <param name="pageLen">The size of a page.</param> /// <returns>A lazy enumerable over the values.</returns> /// <exception cref="BitbucketV2Exception">Thrown when the server fails to respond.</exception> public static IEnumerable <TValue> EnumeratePaginatedValues <TValue>(this ISharpBucketRequesterV2 sharpBucketRequesterV2, string relativeUrl, IDictionary <string, object> requestParameters = null, int?pageLen = null) { return(IteratePages <TValue>(sharpBucketRequesterV2, relativeUrl, pageLen ?? DEFAULT_PAGE_LEN, requestParameters) .TakeWhile(page => page != null) .SelectMany(page => page)); }
/// <summary> /// Initializes a new instance of <see cref="EndPoint"/> from a parent <see cref="EndPoint"/>. /// This is the constructor to use for Resources classes. /// </summary> protected EndPoint(EndPoint parentEndPoint, string resourcePathFromParent) { _sharpBucketV2 = parentEndPoint._sharpBucketV2; _baseUrl = parentEndPoint._baseUrl + resourcePathFromParent.Trim('/') + "/"; }
/// <summary> /// Initializes a new instance of <see cref="EndPoint"/> from scratch. /// This is the constructor to use for EndPoint classes. /// </summary> protected EndPoint(ISharpBucketRequesterV2 sharpBucketV2, string resourcePath) { _sharpBucketV2 = sharpBucketV2 ?? throw new ArgumentNullException(nameof(sharpBucketV2)); _baseUrl = resourcePath.Trim('/') + "/"; }
public UserEndpoint(ISharpBucketRequesterV2 sharpBucketV2) : base(sharpBucketV2, "user/") { }
public TeamsEndPoint(ISharpBucketRequesterV2 sharpBucketV2) : base(sharpBucketV2, "teams/") { }
public UsersEndpoint(string accountName, ISharpBucketRequesterV2 sharpBucketV2) : base(sharpBucketV2, $"users/{accountName.GuidOrValue()}/") { _repositoriesResource = new Lazy <RepositoriesAccountResource>( () => new RepositoriesEndPoint(sharpBucketV2).RepositoriesResource(accountName)); }