Skip to content

Commit

Permalink
[Response Ops] Allow _source field for ES DSL query rules (elastic#…
Browse files Browse the repository at this point in the history
…142223)

* Allowing _source in ES query DSL

* Adding functional test

* Adding to doc

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
2 people authored and WafaaNasr committed Oct 14, 2022
1 parent 18cb5f6 commit 46ed5cb
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/user/alerting/rule-types/es-query.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ the *time window*.
Size:: Specifies the number of documents to pass to the configured actions when
the threshold condition is met.
{es} query:: Specifies the ES DSL query. The number of documents that
match this query is evaluated against the threshold condition. Only the `query`, `fields` and `runtime_mappings`
match this query is evaluated against the threshold condition. Only the `query`, `fields`, `_source` and `runtime_mappings`
fields are used, other DSL fields are not considered.
Threshold:: Defines a threshold value and a comparison operator (`is above`,
`is above or equals`, `is below`, `is below or equals`, or `is between`). The
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface BuildSortedEventsQuery extends BuildSortedEventsQueryOpts {
timeField: string;
fields?: string[];
runtime_mappings?: unknown;
_source?: unknown;
}

export const buildSortedEventsQuery = ({
Expand All @@ -40,6 +41,7 @@ export const buildSortedEventsQuery = ({
fields,
// eslint-disable-next-line @typescript-eslint/naming-convention
runtime_mappings,
_source,
}: BuildSortedEventsQuery): ESSearchRequest => {
const sortField = timeField;
const docFields = [timeField].map((tstamp) => ({
Expand Down Expand Up @@ -89,6 +91,7 @@ export const buildSortedEventsQuery = ({
},
...(runtime_mappings ? { runtime_mappings } : {}),
...(fields ? { fields } : {}),
...(_source != null ? { _source } : {}),
};

if (searchAfterSortId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function fetchEsQuery(
const esClient = scopedClusterClient.asCurrentUser;
const {
// eslint-disable-next-line @typescript-eslint/naming-convention
parsedQuery: { query, fields, runtime_mappings },
parsedQuery: { query, fields, runtime_mappings, _source },
dateStart,
dateEnd,
} = getSearchParams(params);
Expand Down Expand Up @@ -76,6 +76,7 @@ export async function fetchEsQuery(
track_total_hits: true,
fields,
runtime_mappings,
_source,
});

logger.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context';
export default function alertingTests({ loadTestFile }: FtrProviderContext) {
describe('es_query', () => {
loadTestFile(require.resolve('./rule'));
loadTestFile(require.resolve('./query_dsl_only'));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export default function ruleTests({ getService }: FtrProviderContext) {
"fields": [
{
"field": "@timestamp",
"format": "epoch_millis"
"format": "epoch_millis"
}
],
"query": {
Expand Down Expand Up @@ -190,6 +190,73 @@ export default function ruleTests({ getService }: FtrProviderContext) {
}
});

it(`runs correctly: _source: false field for esQuery search type`, async () => {
// write documents from now to the future end date in groups
await createEsDocumentsInGroups(ES_GROUPS_TO_WRITE, endDate);
await createRule({
name: 'always fire',
esQuery: `
{
"query": {
"match_all": { }
},
"_source": false
}`.replace(`"`, `\"`),
size: 100,
thresholdComparator: '>',
threshold: [-1],
});

const docs = await waitForDocs(2);
for (let i = 0; i < docs.length; i++) {
const doc = docs[i];
const { name, title } = doc._source.params;
expect(name).to.be('always fire');
expect(title).to.be(`rule 'always fire' matched query`);

const hits = JSON.parse(doc._source.hits);
expect(hits).not.to.be.empty();
hits.forEach((hit: any) => {
expect(hit._source).to.be(undefined);
});
}
});

it(`runs correctly: _source field for esQuery search type`, async () => {
// write documents from now to the future end date in groups
await createEsDocumentsInGroups(ES_GROUPS_TO_WRITE, endDate);
await createRule({
name: 'always fire',
esQuery: `
{
"query": {
"match_all": { }
},
"_source": "testedValue*"
}`.replace(`"`, `\"`),
size: 100,
thresholdComparator: '>',
threshold: [-1],
});

const docs = await waitForDocs(2);
for (let i = 0; i < docs.length; i++) {
const doc = docs[i];
const { name, title } = doc._source.params;
expect(name).to.be('always fire');
expect(title).to.be(`rule 'always fire' matched query`);

const hits = JSON.parse(doc._source.hits);
expect(hits).not.to.be.empty();
hits.forEach((hit: any) => {
expect(hit._source).not.to.be.empty();
Object.keys(hit._source).forEach((key) => {
expect(key.startsWith('testedValue')).to.be(true);
});
});
}
});

async function createRule(params: CreateRuleParams): Promise<string> {
const action = {
id: connectorId,
Expand Down

0 comments on commit 46ed5cb

Please sign in to comment.