To retrieve missing incidents, configure how far back in time (in minutes) to get incidents that were created a while ago but indexed a few minutes ago. In addition, store the fields to be used by the lookback methods.
During a fetch-incidents
run, some edge case scenarios may cause you to miss incidents from the third-party product.
The most common scenarios are:
Indexing issues in the product: For example, if incident A was created before incident B and only B was indexed,
fetch-incidents
fetches only B and not A. If A was indexed after the fetch was called, the next fetch fetches only from the created time of B.An update in the incident information: Some implementations of
fetch-incidents
use a query filter to fetch only specific incidents. If initially an incident did not match the query (meaning, it was not fetched) but at some point was updated so that it now matches the query,fetch-incidents
does not pull the updated incident because the time to fetch it already passed.
Solution
The look_back
parameter enables configuring how far back in time (in minutes) fetch-incidents
will look to get the incidents that were created a while ago but indexed a few minutes ago. In addition, the LastRun
object stores the following fields to be used by the lookback methods:
time
- The time to fetch the next fetch call (as in a regular fetch).limit
- The maximum number of incidents retrieved in the next fetch. If the current fetch run has the samestart_time
as the last fetch (determined inget_fetch_run_time_range()
), this field is increased by the limit instance parameter value, and then incidents retrieved in the last fetch are filtered out.found_incident_ids
- The IDs of incidents fetched in previous runs. Used for filtering duplicates in the next runs.
Lookback methods
Lookback is implemented using the following generic methods. For more information about lookback generic methods, see CommonServerPython.
get_fetch_run_time_range()
- Using the last run object and other parameters, this method calculates and retrieves the time range in which to fetch. If thelook_back
parameter is defined, then the start time will always be greater than or equal tonow - look_back
.filter_incidents_by_duplicates_and_limit()
- After getting the incidents using the third-party API call, you need to filter out the duplicate incidents. From the example above, after incident A is indexed the next fetch gets incidents A and B, but B must be filtered out since it was already fetched.Note
If after filtering duplicates you have more incidents than the limit,
fetch-incidents
will get only up to the limit number of incidents.update_last_run_object()
- Updates the existing last run object. The function updates the found IDs from theget_found_incident_ids
function and also updates the new time and limit from thecreate_updated_last_run_object
function and returns the updated last run object.
Helper methods
The following helpers are used in the above lookback methods, and should not be used when implementing fetch-incidents
in the integration.
get_latest_incident_created_time()
- Given a list of incidents and the created time field, this function will return the latest incident created time.remove_old_incidents_ids()
- Removes old incident IDs from the last run object to avoid overloading.get_found_incident_ids()
- Returns a list of the new fetched incident IDs. This is saved in the last run object and used to filter duplicates in the nextfetch-incidents
call.create_updated_last_run_object()
- Creates a new last run object with a new time and limit for the next fetch.
Example fetch with lookback
def fetch_incidents(params: dict): incidents = [] fetch_limit_param = params.get('limit') look_back = int(params.get('look_back', 0)) first_fetch = params.get('first_fetch') time_zone = params.get('time_zone', 0) last_run = demisto.getLastRun() # If the start time in the current fetch is the same as the start time in the previous fetch, the fetch_limit may be different from the fetch_limit_param. fetch_limit = last_run.get('limit') or fetch_limit_param # It's important to get here the end_fetch_time to pass it into the update_last_run_object function. start_fetch_time, end_fetch_time = get_fetch_run_time_range(last_run=last_run, first_fetch=first_fetch, look_back=look_back, timezone=time_zone) # Here you insert functions for building the query and sending the API call to get the incidents. For example: query = build_query(start_fetch_time, end_fetch_time, fetch_limit) incidents_res = get_incidents_request(query) incidents = filter_incidents_by_duplicates_and_limit(incidents_res=incidents_res, last_run=last_run, fetch_limit=fetch_limit_param, id_field='incident_id') last_run = update_last_run_object(last_run=last_run, incidents=incidents, fetch_limit=fetch_limit_param, start_fetch_time=start_fetch_time, end_fetch_time=end_fetch_time, look_back=look_back, created_time_field='created', id_field='incident_id') demisto.incidents(incidents) demisto.setLastRun(last_run)
Notes
Fetching incidents is flexible and you can use the various functions according to your needs.
You can also use the generic methods for regular
fetch-incidents
without lookback.If the
look_back
value is increased byk
minutes, you may get duplicate incidents for thek
minutes that overlap with the previous fetch.