import expect from '@kbn/expect' ; import { cloneDeep } from 'lodash' ; import { FtrProviderContext } from '../../../ftr_provider_context' ; import { USER } from '../../../../functional/services/ml/security_common' ; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api' ; import { JobType } from '../../../../../plugins/ml/common/types/saved_objects' ; export default ( { getService } ) => { const ml = getService ( 'ml' ) ; const spacesService = getService ( 'spaces' ) ; const supertest = getService ( 'supertestWithoutAuth' ) ; const adJobId1 = 'fq_single_1' ; const adJobId2 = 'fq_single_2' ; const adJobId3 = 'fq_single_3' ; const adJobIdES = 'fq_single_es' ; const idSpace1 = 'space1' ; async function runSyncRequest ( user , expectedStatusCode ) { const { body } = await supertest . get ( `/s/${ idSpace1 }/api/ml/saved_objects/sync` ) . auth ( user , ml . securityCommon . getPasswordForUser ( user ) ) . set ( COMMON_REQUEST_HEADERS ) . expect ( expectedStatusCode ) ; return body ; } async function runSyncCheckRequest ( user , jobType , expectedStatusCode ) { const { body } = await supertest . post ( `/s/${ idSpace1 }/api/ml/saved_objects/sync_check` ) . auth ( user , ml . securityCommon . getPasswordForUser ( user ) ) . set ( COMMON_REQUEST_HEADERS ) . send ( { jobType } ) . expect ( expectedStatusCode ) ; return body ; } describe ( 'GET saved_objects/sync' , ( ) => { beforeEach ( async ( ) => { await spacesService . create ( { id : idSpace1 , name : 'space_one' , disabledFeatures : [ ] } ) ; await ml . testResources . setKibanaTimeZoneToUTC ( ) ; } ) ; afterEach ( async ( ) => { await spacesService . delete ( idSpace1 ) ; await ml . api . cleanMlIndices ( ) ; await ml . testResources . cleanMLSavedObjects ( ) ; } ) ; it ( 'should sync datafeeds and saved objects' , async ( ) => { const syncNeeded = await runSyncCheckRequest ( USER . ML_POWERUSER_ALL_SPACES , 'anomaly-detector' , 200 ) ; expect ( syncNeeded . result ) . to . eql ( false , 'sync should not be needed' ) ; await ml . api . createAnomalyDetectionJob ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId1 ) , idSpace1 ) ; await ml . api . createAnomalyDetectionJob ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId2 ) , idSpace1 ) ; await ml . api . createAnomalyDetectionJob ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId3 ) , idSpace1 ) ; await ml . api . createAnomalyDetectionJobES ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobIdES ) ) ; const datafeedConfig2 = ml . commonConfig . getADFqDatafeedConfig ( adJobId2 ) ; await ml . api . createDatafeedES ( datafeedConfig2 ) ; const datafeedConfig3 = ml . commonConfig . getADFqDatafeedConfig ( adJobId3 ) ; await ml . api . createDatafeed ( datafeedConfig3 , idSpace1 ) ; await ml . api . deleteDatafeedES ( datafeedConfig3 . datafeed_id ) ; await ml . api . assertJobSpaces ( adJobIdES , 'anomaly-detector' , [ ] ) ; await ml . api . deleteAnomalyDetectionJobES ( adJobId1 ) ; const syncNeeded2 = await runSyncCheckRequest ( USER . ML_POWERUSER_ALL_SPACES , 'anomaly-detector' , 200 ) ; expect ( syncNeeded2 . result ) . to . eql ( true , 'sync should be needed' ) ; const body = await runSyncRequest ( USER . ML_POWERUSER_ALL_SPACES , 200 ) ; expect ( body ) . to . eql ( { datafeedsAdded : { [ adJobId2 ] : { success : true , type : 'anomaly-detector' } } , datafeedsRemoved : { [ adJobId3 ] : { success : true , type : 'anomaly-detector' } } , savedObjectsCreated : { [ adJobIdES ] : { success : true , type : 'anomaly-detector' } } , savedObjectsDeleted : { [ adJobId1 ] : { success : true , type : 'anomaly-detector' } } , } ) ; } ) ; it ( 'should sync datafeeds after recreation in ES with different name' , async ( ) => { const syncNeeded = await runSyncCheckRequest ( USER . ML_POWERUSER_ALL_SPACES , 'anomaly-detector' , 200 ) ; expect ( syncNeeded . result ) . to . eql ( false , 'sync should not be needed' ) ; const jobConfig1 = ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId1 ) ; await ml . api . createAnomalyDetectionJob ( jobConfig1 , idSpace1 ) ; const datafeedConfig1 = ml . commonConfig . getADFqDatafeedConfig ( adJobId1 ) ; await ml . api . createDatafeedES ( datafeedConfig1 ) ; const syncNeeded2 = await runSyncCheckRequest ( USER . ML_POWERUSER_ALL_SPACES , 'anomaly-detector' , 200 ) ; expect ( syncNeeded2 . result ) . to . eql ( true , 'sync should be needed' ) ; const body = await runSyncRequest ( USER . ML_POWERUSER_ALL_SPACES , 200 ) ; expect ( body ) . to . eql ( { datafeedsAdded : { [ adJobId1 ] : { success : true , type : 'anomaly-detector' } } , datafeedsRemoved : { } , savedObjectsCreated : { } , savedObjectsDeleted : { } , } ) ; await ml . api . deleteDatafeedES ( datafeedConfig1 . datafeed_id ) ; const datafeedConfig2 = cloneDeep ( datafeedConfig1 ) ; datafeedConfig2 . datafeed_id = `different_${ datafeedConfig2 . datafeed_id }` ; await ml . api . createDatafeedES ( datafeedConfig2 ) ; const syncNeeded3 = await runSyncCheckRequest ( USER . ML_POWERUSER_ALL_SPACES , 'anomaly-detector' , 200 ) ; expect ( syncNeeded3 . result ) . to . eql ( true , 'sync should be needed' ) ; const body2 = await runSyncRequest ( USER . ML_POWERUSER_ALL_SPACES , 200 ) ; expect ( body2 ) . to . eql ( { datafeedsAdded : { [ adJobId1 ] : { success : true , type : 'anomaly-detector' } } , datafeedsRemoved : { } , savedObjectsCreated : { } , savedObjectsDeleted : { } , } ) ; const syncNeeded4 = await runSyncCheckRequest ( USER . ML_POWERUSER_ALL_SPACES , 'anomaly-detector' , 200 ) ; expect ( syncNeeded4 . result ) . to . eql ( false , 'sync should not be needed' ) ; } ) ; it ( 'should not sync anything if all objects are already synced' , async ( ) => { await ml . api . createAnomalyDetectionJob ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId1 ) , idSpace1 ) ; await ml . api . createAnomalyDetectionJob ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId2 ) , idSpace1 ) ; await ml . api . createAnomalyDetectionJob ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobId3 ) , idSpace1 ) ; await ml . api . createAnomalyDetectionJobES ( ml . commonConfig . getADFqSingleMetricJobConfig ( adJobIdES ) ) ; await runSyncRequest ( USER . ML_POWERUSER_ALL_SPACES , 200 ) ; const body = await runSyncRequest ( USER . ML_POWERUSER_ALL_SPACES , 200 ) ; expect ( body ) . to . eql ( { datafeedsAdded : { } , datafeedsRemoved : { } , savedObjectsCreated : { } , savedObjectsDeleted : { } , } ) ; } ) ; } ) ; } ;