[8.x] Use groupBy when groupings is not populated correctly (#189672) (#193456)

# Backport

This will backport the following commits from `main` to `8.x`:
- [Use groupBy when groupings is not populated correctly
(#189672)](https://github.com/elastic/kibana/pull/189672)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Kevin
Delemme","email":"kevin.delemme@elastic.co"},"sourceCommit":{"committedDate":"2024-09-19T17:19:23Z","message":"Use
groupBy when groupings is not populated correctly
(#189672)","sha":"c509747a7b59da5eec63d95792404b1ad3559131","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-management","v8.16.0"],"title":"Use
groupBy when groupings is not populated
correctly","number":189672,"url":"https://github.com/elastic/kibana/pull/189672","mergeCommit":{"message":"Use
groupBy when groupings is not populated correctly
(#189672)","sha":"c509747a7b59da5eec63d95792404b1ad3559131"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/189672","number":189672,"mergeCommit":{"message":"Use
groupBy when groupings is not populated correctly
(#189672)","sha":"c509747a7b59da5eec63d95792404b1ad3559131"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Kevin Delemme <kevin.delemme@elastic.co>
This commit is contained in:
Kibana Machine 2024-09-20 04:48:50 +10:00 committed by GitHub
parent e2edfd5017
commit 647ac36494
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 58 additions and 131 deletions

View file

@ -5,13 +5,14 @@
* 2.0.
*/
import * as t from 'io-ts';
import { allOrAnyStringOrArray } from '../../schema';
const getSLOInstancesParamsSchema = t.type({
path: t.type({ id: t.string }),
});
const getSLOInstancesResponseSchema = t.type({
groupBy: t.union([t.string, t.array(t.string)]),
groupBy: allOrAnyStringOrArray,
instances: t.array(t.string),
});

View file

@ -6,7 +6,7 @@
*/
import * as t from 'io-ts';
import { indicatorSchema, objectiveSchema } from '../../schema';
import { dateType } from '../../schema/common';
import { allOrAnyStringOrArray, dateType } from '../../schema/common';
const getPreviewDataParamsSchema = t.type({
body: t.intersection([
@ -20,7 +20,7 @@ const getPreviewDataParamsSchema = t.type({
t.partial({
objective: objectiveSchema,
instanceId: t.string,
groupBy: t.string,
groupBy: allOrAnyStringOrArray,
remoteName: t.string,
groupings: t.record(t.string, t.unknown),
}),

View file

@ -29,7 +29,7 @@ export function useGetPreviewData({
remoteName,
}: {
isValid: boolean;
groupBy?: string;
groupBy?: string | string[];
instanceId?: string;
remoteName?: string;
groupings?: Record<string, unknown>;

View file

@ -42,6 +42,7 @@ export function EventsChartPanel({ slo, range, selectedTabId, onBrushed }: Props
const { isLoading, data } = useGetPreviewData({
range,
isValid: true,
groupBy: slo.groupBy,
indicator: slo.indicator,
groupings: slo.groupings,
instanceId: slo.instanceId,

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import { ALL_VALUE } from '@kbn/slo-schema';
import {
getSLOPipelineId,
SLO_INGEST_PIPELINE_INDEX_NAME_PREFIX,
@ -43,47 +44,24 @@ export const getSLOPipelineTemplate = (slo: SLODefinition) => ({
},
},
{
script: {
description: 'Generated the instanceId field for SLO rollup data',
source: `
// This function will recursively collect all the values of a HashMap of HashMaps
Collection collectValues(HashMap subject) {
Collection values = new ArrayList();
// Iterate through the values
for(Object value: subject.values()) {
// If the value is a HashMap, recurse
if (value instanceof HashMap) {
values.addAll(collectValues((HashMap) value));
} else {
values.add(String.valueOf(value));
}
}
return values;
}
// Create the string builder
StringBuilder instanceId = new StringBuilder();
if (ctx["slo"]["groupings"] == null) {
ctx["slo"]["instanceId"] = "*";
} else {
// Get the values as a collection
Collection values = collectValues(ctx["slo"]["groupings"]);
// Convert to a list and sort
List sortedValues = new ArrayList(values);
Collections.sort(sortedValues);
// Create comma delimited string
for(String instanceValue: sortedValues) {
instanceId.append(instanceValue);
instanceId.append(",");
}
// Assign the slo.instanceId
ctx["slo"]["instanceId"] = instanceId.length() > 0 ? instanceId.substring(0, instanceId.length() - 1) : "*";
}
`,
dot_expander: {
path: 'slo.groupings',
field: '*',
ignore_failure: true,
if: 'ctx.slo.groupings != null',
},
},
{
set: {
description: 'Generated the instanceId field based on the groupings field',
field: 'slo.instanceId',
value:
[slo.groupBy].flat().includes(ALL_VALUE) || [slo.groupBy].flat().length === 0
? ALL_VALUE
: [slo.groupBy]
.flat()
.map((field) => `{{{slo.groupings.${field}}}}`)
.join(','),
},
},
],

View file

@ -43,47 +43,18 @@ Array [
},
},
Object {
"script": Object {
"description": "Generated the instanceId field for SLO rollup data",
"source": "
// This function will recursively collect all the values of a HashMap of HashMaps
Collection collectValues(HashMap subject) {
Collection values = new ArrayList();
// Iterate through the values
for(Object value: subject.values()) {
// If the value is a HashMap, recurse
if (value instanceof HashMap) {
values.addAll(collectValues((HashMap) value));
} else {
values.add(String.valueOf(value));
}
}
return values;
}
// Create the string builder
StringBuilder instanceId = new StringBuilder();
if (ctx[\\"slo\\"][\\"groupings\\"] == null) {
ctx[\\"slo\\"][\\"instanceId\\"] = \\"*\\";
} else {
// Get the values as a collection
Collection values = collectValues(ctx[\\"slo\\"][\\"groupings\\"]);
// Convert to a list and sort
List sortedValues = new ArrayList(values);
Collections.sort(sortedValues);
// Create comma delimited string
for(String instanceValue: sortedValues) {
instanceId.append(instanceValue);
instanceId.append(\\",\\");
}
// Assign the slo.instanceId
ctx[\\"slo\\"][\\"instanceId\\"] = instanceId.length() > 0 ? instanceId.substring(0, instanceId.length() - 1) : \\"*\\";
}
",
"dot_expander": Object {
"field": "*",
"if": "ctx.slo.groupings != null",
"ignore_failure": true,
"path": "slo.groupings",
},
},
Object {
"set": Object {
"description": "Generated the instanceId field based on the groupings field",
"field": "slo.instanceId",
"value": "*",
},
},
],

View file

@ -239,47 +239,18 @@ exports[`ResetSLO resets all associated resources 8`] = `
},
},
Object {
"script": Object {
"description": "Generated the instanceId field for SLO rollup data",
"source": "
// This function will recursively collect all the values of a HashMap of HashMaps
Collection collectValues(HashMap subject) {
Collection values = new ArrayList();
// Iterate through the values
for(Object value: subject.values()) {
// If the value is a HashMap, recurse
if (value instanceof HashMap) {
values.addAll(collectValues((HashMap) value));
} else {
values.add(String.valueOf(value));
}
}
return values;
}
// Create the string builder
StringBuilder instanceId = new StringBuilder();
if (ctx[\\"slo\\"][\\"groupings\\"] == null) {
ctx[\\"slo\\"][\\"instanceId\\"] = \\"*\\";
} else {
// Get the values as a collection
Collection values = collectValues(ctx[\\"slo\\"][\\"groupings\\"]);
// Convert to a list and sort
List sortedValues = new ArrayList(values);
Collections.sort(sortedValues);
// Create comma delimited string
for(String instanceValue: sortedValues) {
instanceId.append(instanceValue);
instanceId.append(\\",\\");
}
// Assign the slo.instanceId
ctx[\\"slo\\"][\\"instanceId\\"] = instanceId.length() > 0 ? instanceId.substring(0, instanceId.length() - 1) : \\"*\\";
}
",
"dot_expander": Object {
"field": "*",
"if": "ctx.slo.groupings != null",
"ignore_failure": true,
"path": "slo.groupings",
},
},
Object {
"set": Object {
"description": "Generated the instanceId field based on the groupings field",
"field": "slo.instanceId",
"value": "*",
},
},
],

View file

@ -43,7 +43,7 @@ interface Options {
interval: string;
instanceId?: string;
remoteName?: string;
groupBy?: string;
groupBy?: string | string[];
groupings?: Record<string, unknown>;
}
export class GetPreviewData {
@ -516,15 +516,20 @@ export class GetPreviewData {
private getGroupingsFilter(options: Options, filter: estypes.QueryDslQueryContainer[]) {
const groupingsKeys = Object.keys(options.groupings || []);
if (groupingsKeys.length) {
groupingsKeys.forEach((key) => {
filter.push({
term: { [key]: options.groupings?.[key] },
});
});
} else if (options.instanceId !== ALL_VALUE && options.groupBy) {
filter.push({
term: { [options.groupBy]: options.instanceId },
} else if (options.instanceId && options.instanceId !== ALL_VALUE && options.groupBy) {
const instanceIdPart = options.instanceId.split(',');
const groupByPart = Array.isArray(options.groupBy) ? options.groupBy : [options.groupBy];
groupByPart.forEach((groupBy, index) => {
filter.push({
term: { [groupBy]: instanceIdPart[index] },
});
});
}
}