Skip to content

Commit

Permalink
feat: Added support of admin_logs_streaming stream type (#740)
Browse files Browse the repository at this point in the history
  • Loading branch information
antusus authored May 27, 2022
1 parent 6a8e8b9 commit 406950a
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 343 deletions.
2 changes: 1 addition & 1 deletion src/box-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class BoxClient {
sharedItems: any;
metadata: any;
collections: any;
events: any;
events: Events;
search: any;
tasks: any;
trash: any;
Expand Down
11 changes: 7 additions & 4 deletions src/enterprise-event-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Options = {
eventTypeFilter?: EventType[];
pollingInterval?: number;
chunkSize?: number;
streamType?: 'admin_logs' | 'admin_logs_streaming';
};

type EventType = string /* FIXME */;
Expand All @@ -31,6 +32,7 @@ type EventType = string /* FIXME */;
const DEFAULT_OPTIONS = Object.freeze({
pollingInterval: 60, // seconds
chunkSize: 500,
streamType: 'admin_logs'
});

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -81,6 +83,7 @@ class EnterpriseEventStream extends Readable {

// Handle the case where the caller passes streamPosition = 0 instead of streamPosition = '0'.
if (
this._options.streamType === 'admin_logs' &&
!this._options.startDate &&
!this._options.streamPosition &&
(this._options.streamPosition as any) !== 0
Expand Down Expand Up @@ -153,14 +156,14 @@ class EnterpriseEventStream extends Readable {
fetchEvents(callback: Function) {
const self = this,
params: {
stream_type?: string;
stream_type?: 'admin_logs' | 'admin_logs_streaming';
stream_position?: string;
created_after?: string;
created_before?: string;
event_type?: string;
limit?: number;
} = {
stream_type: 'admin_logs',
stream_type: this._options.streamType
};

// Use the current stream position.
Expand All @@ -169,11 +172,11 @@ class EnterpriseEventStream extends Readable {
params.stream_position = this._streamPosition;
}

if (this._options.startDate) {
if (this._options.streamType === 'admin_logs' && this._options.startDate) {
params.created_after = this._options.startDate;
}

if (this._options.endDate) {
if (this._options.streamType === 'admin_logs' && this._options.endDate) {
params.created_before = this._options.endDate;
}

Expand Down
62 changes: 55 additions & 7 deletions src/managers/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,46 @@ class Events {
* API Endpoint: '/events'
* Method: GET
*
* To get events from admin events stream you have to pick stream_type from `admin_logs` or `admin_logs_streaming`.
* The `admin_logs` stream emphasis is on completeness over latency,
* which means that Box will deliver admin events in chronological order and without duplicates,
* but with higher latency. You can specify start and end time/dates.
*
* To monitor recent events that have been generated within Box across the enterprise use
* `admin_logs_streaming` as stream type. The emphasis for this feed is on low latency rather than chronological
* accuracy, which means that Box may return events more than once and out of chronological order.
* Events are returned via the API around 12 seconds after they are processed by Box
* (the 12 seconds buffer ensures that new events are not written after your cursor position).
* Only two weeks of events are available via this feed, and you cannot set start and end time/dates.
*
* @param {Object} [options] - Additional options for the request. Can be left null in most cases.
* @param {string} [options.stream_type] - From which stream events should be selected.
* Possible values are `admin_logs` and `admin_logs_streaming`
* @param {string} [options.created_after] - The date to start from in ISO-8601 timestamp format: '2001-01-01T00:00:00-08:00'
* @param {string} [options.created_before] - The date to end at in ISO-8601 timestamp format: '2001-01-01T00:00:00-08:00'
* @param {string} [options.event_type] - String of event types to return coma separated: for example 'DOWNLOAD,UPLOAD'
* @param {number} [options.limit] - Number of events to fetch per call
* @param {string} [options.stream_position] - The stream position to start from (pass '0' for all past events)
* @param {Function} [callback] Passed the current stream position if successful
* @returns {Promise<Object>} A promise resolving to the collection of events
*/
get(options?: Record<string, any>, callback?: Function) {
var params = {
get(options?: {
[key: string]: any;
stream_type?: string,
created_after?: string,
created_before?: string,
event_type?: string,
limit?: number,
stream_position?: string
}, callback?: Function) {
const params = {
qs: options,
};
var apiPath = urlPath(BASE_PATH);
if(options && options.stream_type && options.stream_type === 'admin_logs_streaming') {
const {created_after, created_before, ...filteredOptions} = options;
params.qs = filteredOptions;
}
const apiPath = urlPath(BASE_PATH);
return this.client.wrapWithDefaultHandler(this.client.get)(
apiPath,
params,
Expand All @@ -193,15 +224,15 @@ class Events {
* @returns {Promise<Object>} A promise resolving to the long poll info
*/
getLongPollInfo(callback?: Function) {
var apiPath = urlPath(BASE_PATH);
const apiPath = urlPath(BASE_PATH);
return this.client
.options(apiPath, {})
.then((response: any /* FIXME */) => {
if (response.statusCode !== httpStatusCodes.OK) {
throw errors.buildUnexpectedResponseError(response);
}

var longpollInfo = response.body.entries.find(
let longpollInfo = response.body.entries.find(
(entry: any /* FIXME */) => entry.type === 'realtime_server'
);

Expand Down Expand Up @@ -242,7 +273,7 @@ class Events {
| Function,
callback?: Function
) {
var self = this;
const self = this;
if (typeof streamPosition === 'string') {
if (typeof options === 'function') {
callback = options;
Expand Down Expand Up @@ -283,13 +314,29 @@ class Events {
* Once the stream catches up to the current time, it will begin polling every 'pollingInterval' seconds.
* If 'pollingInterval' = 0, then the stream will end when it catches up to the current time (no polling).
*
* By default, stream pools `admin_logs` for events. The emphasis for this stream is on completeness over latency,
* which means that Box will deliver admin events in chronological order and without duplicates,
* but with higher latency. You can specify start and end time/dates.
*
* To monitor recent events that have been generated within Box across the enterprise use
* `admin_logs_streaming` as stream type. The emphasis for this feed is on low latency rather than chronological
* accuracy, which means that Box may return events more than once and out of chronological order.
* Events are returned via the API around 12 seconds after they are processed by Box
* (the 12 seconds buffer ensures that new events are not written after your cursor position).
* Only two weeks of events are available via this feed, and you cannot set start and end time/dates.
*
* This method will only work with an API connection for an enterprise admin account
* or service account with a manage enterprise properties.
*
* @param {Object} [options] - Options
* @param {string} [options.streamPosition] - The stream position to start from (pass '0' for all past events)
* @param {string} [options.startDate] - The date to start from
* @param {string} [options.endDate] - The date to end at
* @param {EventType[]} [options.eventTypeFilter] - Array of event types to return
* @param {int} [options.pollingInterval=60] - Polling interval (in seconds). Pass 0 for no polling.
* @param {int} [options.chunkSize=500] - Number of events to fetch per call (max = 500)
* @param {string} [options.streamType] - From which stream events should be selected.
* Possible values are `admin_logs` and `admin_logs_streaming`
* @param {Function} [callback] Passed the events stream if successful
* @returns {Promise<EnterpriseEventStream>} A promise resolving to the enterprise event stream
*/
Expand All @@ -301,10 +348,11 @@ class Events {
eventTypeFilter?: EventType[];
pollingInterval?: number;
chunkSize?: number;
streamType?: 'admin_logs' | 'admin_logs_streaming';
},
callback?: Function
) {
var self = this;
const self = this;
return Promise.resolve(
new EnterpriseEventStream(self.client, options)
).asCallback(callback);
Expand Down
Loading

0 comments on commit 406950a

Please sign in to comment.