Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CP-2322 Investigate pagination. #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

CP-2322 Investigate pagination. #1

wants to merge 1 commit into from

Conversation

joaomper-TE
Copy link
Owner

@joaomper-TE joaomper-TE commented Sep 5, 2024

My idea is that we build 2 classes, one for fetching all results (makes all API calls in 1 call to the method) as well as an iterator (in here PaginatorIterator) that the clients could use to fetch the results async - this can be useful for not exhausting rate-limits.

Comment on lines +27 to +37
Paginator<EndpointAgent, ListEndpointAgentsResponse> paginator = new Paginator<>(
cursor -> {
try {
return apiInstance.getEndpointAgents(max, cursor, aid, List.of(), false,
false, null, "CSCO-W-PW02XZDB");
}
catch (ApiException e) {
throw new RuntimeException(e);
}
},
ListEndpointAgentsResponse::getAgents
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally we would abstract away this logic. In the scope of the spike I didn't invest much time in figuring out how

Copy link

@brumarqu-te brumarqu-te Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree yeah, should be simple since we control 100% the SDK generation logic we can add a new method that already returns this Paginator instance at the api level.

Copy link

@jabrowne-te jabrowne-te Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it would be ideal to abstract it away, but, @brumarqu-te, I'm curious how exactly you imagine this working?

Because it needs to be at method/operation level, rather than API level, right? So are you thinking we will use some custom extension to define which operations are paginated, and what the primary field is?

Or maybe I'm totally missing something 🤔

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i imagined those being conditionally added as an additional operation during the post processing phase of the generator. haven't put much thought into what the condition would be but real quick and dirty: introspecting the input for cursor or output for _links.next ...

... maybe simple was not the best word 😅 but definitely "doable" 😄

Comment on lines +39 to +46
var getLinks = clazz.getMethod("getLinks", null);
var links = getLinks.invoke(result);

var getNext = links.getClass().getMethod("getNext", null);
var next = getNext.invoke(links, null);

if (next != null) {
var getHref = next.getClass().getMethod("getHref", null);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the 3 reflection gets because we have different Schemas for the PaginationLinks. AgentsApi uses their own PaginationNextAndSelfLink while AlertsApi uses a PaginationLinks. We could overcome this by slightly changing the OAS

this.dataExtractor = dataExtractor;
}

public List<T> getAll() throws ApiException {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something for discussing i'm thinking that we might not want to make this operation available because it can generate a lot of requests 🤔

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, definitely something to consider

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we better no have a get all option

return allResults;
}

private String extractCursor(String href) {
Copy link

@brumarqu-te brumarqu-te Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure if cursor is the only parameter needed for pagination, i think i recall some apis needing the time window as well (i'm not totally sure though). If this is true we'll need to take all parameters into consideration or just follow the link it might be safer.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, the time range parameters are needed for it to work properly

ListEndpointAgentsResponse::getAgents
);

StreamSupport.stream(paginator.spliterator(), false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a simple example of a handy abstraction, AWS SDK "hides" this logic under a stream() method,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants