import { TreeOptions , Tree , EndpointDocGenerator , Event , } from '../../../plugins/security_solution/common/endpoint/generate_data' ; import { firstNonNullValue } from '../../../plugins/security_solution/common/endpoint/models/ecs_safety_helpers' ; import { FtrProviderContext } from '../ftr_provider_context' ; export const processEventsIndex = 'logs-endpoint.events.process-default' ; /**
 * Options for build a resolver tree
 */ export interface Options extends TreeOptions { /**
     * Number of trees to generate.
     */ numTrees ? : number ; seed ? : string ; } /**
 * Structure containing the generated trees and the ES index they live in
 */ export interface GeneratedTrees { trees : Tree [ ] ; indices : string [ ] ; } /**
 * Structure containing the events inserted into ES and the index they live in
 */ export interface InsertedEvents { eventsInfo : Array < { _id : string ; event : Event ; } > ; indices : string [ ] ; } interface BulkCreateHeader { create : { _index : string ; } ; } export function ResolverGeneratorProvider ( { getService } ) { const client = getService ( 'es' ) ; return { async insertEvents ( events , eventsIndex = processEventsIndex ) { const body = events . reduce ( ( array , doc ) => { array . push ( { create : { _index : eventsIndex } } , doc ) ; return array ; } , [ ] ) ; const bulkResp = await client . bulk ( { body , refresh : true } ) ; const eventsInfo = events . map ( ( event , i ) => { return { event , _id : bulkResp . items [ i ] . create ?. _id } ; } ) ; return { eventsInfo , indices : [ eventsIndex ] } ; } , async createTrees ( options , eventsIndex = processEventsIndex , alertsIndex = 'logs-endpoint.alerts-default' ) { const seed = options . seed || 'resolver-seed' ; const allTrees = [ ] ; const generator = new EndpointDocGenerator ( seed ) ; const numTrees = options . numTrees ?? 1 ; for ( let j = 0 ; j < numTrees ; j ++ ) { const tree = generator . generateTree ( options ) ; const body = tree . allEvents . reduce ( ( array , doc ) => { let index = eventsIndex ; if ( firstNonNullValue ( doc . event ?. kind ) === 'alert' ) { index = alertsIndex ; } /**
                     * We're using data streams which require that a bulk use `create` instead of `index`.
                     */ array . push ( { create : { _index : index } } , doc ) ; return array ; } , [ ] ) ; await client . bulk ( { body , refresh : true } ) ; allTrees . push ( tree ) ; } return { trees : allTrees , indices : [ eventsIndex , alertsIndex ] } ; } , async deleteData ( genData ) { for ( const index of genData . indices ) { /**
                 * The ingest manager handles creating the template for the endpoint's indices. It is using a V2 template
                 * with data streams. Data streams aren't included in the javascript elasticsearch client in kibana yet so we
                 * need to do raw requests here. Delete a data stream is slightly different than that of a regular index which
                 * is why we're using _data_stream here.
                 */ await client . transport . request ( { method : 'DELETE' , path : `_data_stream/${ index }` , } ) ; } } , } ; }