Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ export class EntityStoreDataClient {

const definition = getEntityDefinition(entityType, this.options.namespace);

logger.info(`Initializing entity store for ${entityType}`);
logger.info(
`In namespace ${this.options.namespace}: Initializing entity store for ${entityType}`
);

const descriptor = await this.engineClient.init(entityType, definition, filter);
await entityClient.createEntityDefinition({
Expand All @@ -92,11 +94,13 @@ export class EntityStoreDataClient {

if (descriptor.status !== ENGINE_STATUS.STOPPED) {
throw new Error(
`Cannot start Entity engine for ${entityType} when current status is: ${descriptor.status}`
`In namespace ${this.options.namespace}: Cannot start Entity engine for ${entityType} when current status is: ${descriptor.status}`
);
}

this.options.logger.info(`Starting entity store for ${entityType}`);
this.options.logger.info(
`In namespace ${this.options.namespace}: Starting entity store for ${entityType}`
);
await this.options.entityClient.startEntityDefinition(definition);

return this.engineClient.update(definition.id, ENGINE_STATUS.STARTED);
Expand All @@ -109,11 +113,13 @@ export class EntityStoreDataClient {

if (descriptor.status !== ENGINE_STATUS.STARTED) {
throw new Error(
`Cannot stop Entity engine for ${entityType} when current status is: ${descriptor.status}`
`In namespace ${this.options.namespace}: Cannot stop Entity engine for ${entityType} when current status is: ${descriptor.status}`
);
}

this.options.logger.info(`Stopping entity store for ${entityType}`);
this.options.logger.info(
`In namespace ${this.options.namespace}: Stopping entity store for ${entityType}`
);
await this.options.entityClient.stopEntityDefinition(definition);

return this.engineClient.update(definition.id, ENGINE_STATUS.STOPPED);
Expand All @@ -130,7 +136,9 @@ export class EntityStoreDataClient {
public async delete(entityType: EntityType, deleteData: boolean) {
const { id } = getEntityDefinition(entityType, this.options.namespace);

this.options.logger.info(`Deleting entity store for ${entityType}`);
this.options.logger.info(
`In namespace ${this.options.namespace}: Deleting entity store for ${entityType}`
);

await this.options.entityClient.deleteEntityDefinition({ id, deleteData });
await this.engineClient.delete(id);
Expand Down
9 changes: 8 additions & 1 deletion x-pack/test/security_solution_api_integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"nlp_cleanup_task:essentials:qa:serverless:release": "npm run run-tests:genai:basic_essentials nlp_cleanup_task serverless qaEnv",

"entity_analytics:server:serverless": "npm run initialize-server:ea:trial_complete risk_engine serverless",
"entity_analytics:runner:serverless": "npm run run-tests:ea:trial_complete risk_engine serverless serverlessEnv",
"entity_analytics:runner:serverless": "npm run run-tests:ea:trial_complete risk_engine serverless serverlessEnv --",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the -- at the end a leftover or are we good to keep it version control for general use?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess we're keeping it 😅

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am in full support ^^

"entity_analytics:qa:serverless": "npm run run-tests:ea:trial_complete risk_engine serverless qaPeriodicEnv",
"entity_analytics:qa:serverless:release": "npm run run-tests:ea:trial_complete risk_engine serverless qaEnv",
"entity_analytics:server:ess": "npm run initialize-server:ea:trial_complete risk_engine ess",
Expand All @@ -76,6 +76,13 @@
"entity_analytics:essentials:server:ess": "npm run initialize-server:ea:basic_essentials risk_engine ess",
"entity_analytics:essentials:runner:ess": "npm run run-tests:ea:basic_essentials risk_engine ess essEnv",

"entity_analytics:entity_store:server:serverless": "npm run initialize-server:ea:trial_complete entity_store serverless",
"entity_analytics:entity_store:runner:serverless": "npm run run-tests:ea:trial_complete entity_store serverless serverlessEnv",
"entity_analytics:entity_store:qa:serverless": "npm run run-tests:ea:trial_complete entity_store serverless qaPeriodicEnv",
"entity_analytics:entity_store:qa:serverless:release": "npm run run-tests:ea:trial_complete entity_store serverless qaEnv",
"entity_analytics:entity_store:server:ess": "npm run initialize-server:ea:trial_complete entity_store ess",
"entity_analytics:entity_store:runner:ess": "npm run run-tests:ea:trial_complete entity_store ess essEnv --",

"edr_workflows:artifacts:server:serverless": "npm run initialize-server:edr-workflows artifacts serverless",
"edr_workflows:artifacts:runner:serverless": "npm run run-tests:edr-workflows artifacts serverless serverlessEnv",
"edr_workflows:artifacts:qa:serverless": "npm run run-tests:edr-workflows artifacts serverless qaPeriodicEnv",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,104 +6,57 @@
*/

import expect from '@kbn/expect';
import { EntityType } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/common.gen';

import { FtrProviderContext } from '../../../../ftr_provider_context';
import { cleanEngines } from '../../utils';
import { EntityStoreUtils } from '../../utils';
export default ({ getService }: FtrProviderContext) => {
const api = getService('securitySolutionApi');
const es = getService('es');

const initEntityEngineForEntityType = async (entityType: EntityType) => {
return api
.initEntityEngine({
params: { entityType },
body: {},
})
.expect(200);
};

const expectTransformExists = async (transformId: string) => {
return expectTransformStatus(transformId, true);
};

const expectTransformNotFound = async (transformId: string, attempts: number = 5) => {
return expectTransformStatus(transformId, false);
};

const expectTransformStatus = async (
transformId: string,
exists: boolean,
attempts: number = 5,
delayMs: number = 2000
) => {
let currentAttempt = 1;
while (currentAttempt <= attempts) {
try {
await es.transform.getTransform({ transform_id: transformId });
if (!exists) {
throw new Error(`Expected transform ${transformId} to not exist, but it does`);
}
return; // Transform exists, exit the loop
} catch (e) {
if (currentAttempt === attempts) {
if (exists) {
throw new Error(`Expected transform ${transformId} to exist, but it does not: ${e}`);
} else {
return; // Transform does not exist, exit the loop
}
}
await new Promise((resolve) => setTimeout(resolve, delayMs));
currentAttempt++;
}
}
};

const expectTransformsExist = async (transformIds: string[]) =>
Promise.all(transformIds.map((id) => expectTransformExists(id)));

const utils = EntityStoreUtils(getService);

describe('@ess @serverless @skipInServerlessMKI Entity Store Engine APIs', () => {
before(async () => {
await cleanEngines({ getService });
await utils.cleanEngines();
});

describe('init', () => {
afterEach(async () => {
await cleanEngines({ getService });
await utils.cleanEngines();
});

it('should have installed the expected user resources', async () => {
await initEntityEngineForEntityType('user');
await utils.initEntityEngineForEntityType('user');

const expectedTransforms = [
'entities-v1-history-ea_default_user_entity_store',
'entities-v1-latest-ea_default_user_entity_store',
];

await expectTransformsExist(expectedTransforms);
await utils.expectTransformsExist(expectedTransforms);
});

it('should have installed the expected host resources', async () => {
await initEntityEngineForEntityType('host');
await utils.initEntityEngineForEntityType('host');

const expectedTransforms = [
'entities-v1-history-ea_default_host_entity_store',
'entities-v1-latest-ea_default_host_entity_store',
];

await expectTransformsExist(expectedTransforms);
await utils.expectTransformsExist(expectedTransforms);
});
});

describe('get and list', () => {
before(async () => {
await Promise.all([
initEntityEngineForEntityType('host'),
initEntityEngineForEntityType('user'),
utils.initEntityEngineForEntityType('host'),
utils.initEntityEngineForEntityType('user'),
]);
});

after(async () => {
await cleanEngines({ getService });
await utils.cleanEngines();
});

describe('get', () => {
Expand Down Expand Up @@ -169,11 +122,11 @@ export default ({ getService }: FtrProviderContext) => {

describe('start and stop', () => {
before(async () => {
await initEntityEngineForEntityType('host');
await utils.initEntityEngineForEntityType('host');
});

after(async () => {
await cleanEngines({ getService });
await utils.cleanEngines();
});

it('should stop the entity engine', async () => {
Expand Down Expand Up @@ -211,7 +164,7 @@ export default ({ getService }: FtrProviderContext) => {

describe('delete', () => {
it('should delete the host entity engine', async () => {
await initEntityEngineForEntityType('host');
await utils.initEntityEngineForEntityType('host');

await api
.deleteEntityEngine({
Expand All @@ -220,12 +173,12 @@ export default ({ getService }: FtrProviderContext) => {
})
.expect(200);

await expectTransformNotFound('entities-v1-history-ea_host_entity_store');
await expectTransformNotFound('entities-v1-latest-ea_host_entity_store');
await utils.expectTransformNotFound('entities-v1-history-ea_host_entity_store');
await utils.expectTransformNotFound('entities-v1-latest-ea_host_entity_store');
});

it('should delete the user entity engine', async () => {
await initEntityEngineForEntityType('user');
await utils.initEntityEngineForEntityType('user');

await api
.deleteEntityEngine({
Expand All @@ -234,8 +187,8 @@ export default ({ getService }: FtrProviderContext) => {
})
.expect(200);

await expectTransformNotFound('entities-v1-history-ea_user_entity_store');
await expectTransformNotFound('entities-v1-latest-ea_user_entity_store');
await utils.expectTransformNotFound('entities-v1-history-ea_user_entity_store');
await utils.expectTransformNotFound('entities-v1-latest-ea_user_entity_store');
});
});
});
Expand Down
Loading