All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudfoundry.util.PaginationUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.cloudfoundry.util;

import java.util.Optional;
import java.util.function.Function;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * A utility class to provide functions for handling PaginatedResponse and those containing lists of Resources.
 */
public final class PaginationUtils {

    private PaginationUtils() {}

    /**
     * Generate the stream of resources accumulated from a series of responses obtained from the page supplier.
     *
     * @param pageSupplier a function from integers to {@link Mono}s of {@link org.cloudfoundry.client.v2.PaginatedResponse}s.
     * @param           the type of resource in the list on each {@link org.cloudfoundry.client.v2.PaginatedResponse}.
     * @param           the type of {@link org.cloudfoundry.client.v2.PaginatedResponse}.
     * @return a stream of T objects.
     */
    public static <
                    T extends org.cloudfoundry.client.v2.Resource,
                    U extends org.cloudfoundry.client.v2.PaginatedResponse>
            Flux requestClientV2Resources(Function> pageSupplier) {

        return pageSupplier
                .apply(1)
                .flatMapMany(requestClientV2AdditionalPages(pageSupplier))
                .flatMap(ResourceUtils::getResources);
    }

    /**
     * Generate the stream of resources accumulated from a series of responses obtained from the page supplier.
     *
     * @param pageSupplier a function from integers to {@link Mono}s of {@link org.cloudfoundry.client.v3.PaginatedResponse}s.
     * @param           the type of resource in the list on each {@link org.cloudfoundry.client.v3.PaginatedResponse}.
     * @param           the type of {@link org.cloudfoundry.client.v3.PaginatedResponse}.
     * @return a stream of T objects.
     */
    @SuppressWarnings("rawtypes")
    public static >
            Flux requestClientV3Resources(Function> pageSupplier) {
        return pageSupplier
                .apply(1)
                .flatMapMany(requestClientV3AdditionalPages(pageSupplier))
                .flatMapIterable(org.cloudfoundry.client.v3.PaginatedResponse::getResources);
    }

    /**
     * Generate the stream of resources accumulated from a series of responses obtained from the page supplier.
     *
     * @param pageSupplier a function from integers to {@link Mono}s of {@link org.cloudfoundry.uaa.PaginatedResponse}s.
     * @param           the type of resource in the list on each {@link org.cloudfoundry.uaa.PaginatedResponse}.
     * @param           the type of {@link org.cloudfoundry.uaa.PaginatedResponse}.
     * @return a stream of T objects.
     */
    @SuppressWarnings("rawtypes")
    public static >
            Flux requestUaaResources(Function> pageSupplier) {
        return pageSupplier
                .apply(1)
                .flatMapMany(requestUaaAdditionalPages(pageSupplier))
                .flatMapIterable(org.cloudfoundry.uaa.PaginatedResponse::getResources);
    }

    private static  Function> requestAdditionalPages(
            Function> pageSupplier, Function totalPagesSupplier) {
        return response -> {
            Integer totalPages = Optional.ofNullable(totalPagesSupplier.apply(response)).orElse(1);

            return Flux.range(2, totalPages - 1)
                    .flatMap(pageSupplier)
                    .startWith(response)
                    .buffer()
                    .flatMapIterable(d -> d);
        };
    }

    private static >
            Function> requestClientV2AdditionalPages(
                    Function> pageSupplier) {
        return requestAdditionalPages(pageSupplier, response -> response.getTotalPages());
    }

    private static >
            Function> requestClientV3AdditionalPages(
                    Function> pageSupplier) {
        return requestAdditionalPages(
                pageSupplier, response -> response.getPagination().getTotalPages());
    }

    private static >
            Function> requestUaaAdditionalPages(
                    Function> pageSupplier) {
        return response -> {
            Integer totalPages = (response.getTotalResults() - 1) / response.getItemsPerPage() + 1;

            return Flux.range(1, totalPages - 1)
                    .map(page -> 1 + (page * response.getItemsPerPage()))
                    .flatMap(pageSupplier)
                    .startWith(response)
                    .buffer()
                    .flatMapIterable(d -> d);
        };
    }
}