[ 
https://issues.apache.org/jira/browse/CAMEL-25576?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen updated CAMEL-25576:
--------------------------------
    Fix Version/s: 4.24.0

> camel-box - event-logs/getEnterpriseEvents returns only the first chunk of 
> the event log (at most 500 events); the events after it are dropped silently 
> and cannot be requested
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25576
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25576
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-box
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> {{BoxEventLogsManager.getEnterpriseEvents}} (lines 68-96 at main 
> c3829069cb72), the only method of the {{box:event-logs}} API:
> {code:java}
> EnterpriseEventsRequest request = new EnterpriseEventsRequest();
> request.position(position).after(after).before(before).types(types);
> EventLog eventLog = EventLog.getEnterpriseEvents(boxConnection, request);
> List<BoxEvent> results = new ArrayList<>();
> for (BoxEvent event : eventLog) {
>     results.add(event);
> }
> return results;
> {code}
> An {{EventLog}} of box-java-sdk 4.16.4 is one response of the events 
> endpoint: {{EnterpriseEventsRequest}} asks for {{limit = 500}} (the constant 
> in its constructor), and the response has the events of that chunk and 
> {{getNextStreamPosition()}} for the next one. The manager sends one request 
> and returns the events of that response. It does not read the next stream 
> position and does not return it either (the result is a plain 
> {{List<BoxEvent>}}).
> So when more than 500 events lie between {{after}} and {{before}}, the caller 
> gets the first 500 and has no means to ask for the rest: the {{position}} 
> parameter needs a stream position, which only the dropped {{EventLog}} had. 
> Nothing is logged. The javadoc of the method says "@return A list of all the 
> events that met the given criteria", and for {{position}}: "May be null in 
> which case all events within bounds returned".
> h3. Reproduction
> New {{BoxEventLogsManagerPagingTest}} (3 tests) in camel-box-component. A 
> real {{BoxAPIConnection}} gets a {{RequestInterceptor}} that answers the 
> events request from memory like the service: at most 500 events from the 
> requested {{stream_position}}, and {{next_stream_position}} (the fake fails 
> the test after 20 requests). So the SDK parses real responses. On main all 3 
> fail:
> * {{returnsTheEventsOfEveryChunk}} (1200 events): {{all the events within 
> bounds, not only the first chunk ==> expected: <1200> but was: <500>}}.
> * {{startsAtThePositionOfTheCallerAndReadsToTheEnd}} (position 100 of 1200): 
> 1100 events expected, 500 returned.
> * {{stopsWhenTheServiceDoesNotMoveThePosition}}: {{expected: <2> but was: 
> <1>}} (requests; it checks that the new loop ends when a response repeats the 
> position it was asked for, and that events returned twice are kept once).
> h3. Proposed fix
> In {{BoxEventLogsManager.getEnterpriseEvents}}: read on from 
> {{getNextStreamPosition()}} until a chunk is empty, which is the end of the 
> events within bounds; also stop when the service returns no next position or 
> the position it was asked for. The events are collected in a 
> {{LinkedHashSet}} ({{BoxResource.equals}} compares the id), so an event that 
> the service returns in two chunks is kept once and the order of the service 
> is kept. The signature is unchanged; the javadoc of the return value now says 
> that the log is read chunk by chunk and kept in memory.
> Behaviour change, with a 4.24 upgrade-guide entry: the operation returns all 
> the events between {{after}} and {{before}}. Cost: one request per chunk of 
> 500 events and one more that finds the end (two requests where main sent one, 
> when everything fits in one chunk). A wide {{after}} / {{before}} window now 
> returns every event in one list, with that many requests and more memory; the 
> upgrade note and the javadoc say to narrow the window for a large event log. 
> The loop has no limit of its own on the number of chunks: it ends on an empty 
> chunk, on a missing next position or on a position that did not move. I end 
> the loop on an empty chunk and not on a chunk shorter than the limit because 
> I could not confirm from the SDK that a short chunk always means the end. 
> camel-box-api and camel-box-component unit tests with the fix: 6, 0 failures 
> (the integration tests need a Box account and were not run; nothing was run 
> against Box).
> Found with a Lean 4 model of a position-paged service: the event log is a 
> list, a response is a {{take}} / {{drop}} slice of it and the position after 
> it. Property: the result is the log from the position of the caller to its 
> end, every event once and in order. Counterexample for main: with chunks of 
> two, {{[1, 2, 3]}} gives {{[1, 2]}} ({{cex_third_event_dropped}}); with a 
> chunk of 500, 501 events give 500 ({{cex_501_events}}). In the model, reading 
> chunk after chunk returns the list from the start position to its end 
> ({{fix_meets_spec}}), and the same as main when the events fit in one chunk 
> ({{fix_eq_main_one_chunk}}). The model says nothing about the real service. 
> Then confirmed with the real class as described.
> Affected: main (4.23.0-SNAPSHOT at c3829069cb72), and the release branches 
> camel-4.18.x (c3fd5317a5a0), camel-4.22.x (2821f284056c) and camel-4.23.x 
> (197e70656a41): lines 66-95 of {{BoxEventLogsManager}} (the javadoc of the 
> return value and the whole method body) are identical to main on all three. 
> Read, not run.
> Duplicate check (2026-10-12): JIRA text "box getEnterpriseEvents" (none), 
> "box enterprise events position" (2, unrelated: CAMEL-12998, CAMEL-12297); 
> GitHub pull requests "box enterprise events": none; no open pull request 
> touches camel-box.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to