Skip to content

Commit db78d70

Browse files
[Usage Collection] [schema] Explicit "array" definition (#78141)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent e111c2a commit db78d70

File tree

19 files changed

+362
-240
lines changed

19 files changed

+362
-240
lines changed

packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema.json

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,19 @@
3535
}
3636
},
3737
"my_array": {
38-
"properties": {
39-
"total": {
40-
"type": "number"
41-
},
42-
"type": {
43-
"type": "boolean"
38+
"type": "array",
39+
"items": {
40+
"properties": {
41+
"total": {
42+
"type": "number"
43+
},
44+
"type": {
45+
"type": "boolean"
46+
}
4447
}
4548
}
4649
},
47-
"my_str_array": { "type": "keyword" }
50+
"my_str_array": { "type": "array", "items": { "type": "keyword" } }
4851
}
4952
}
5053
}

packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ export const parsedWorkingCollector: ParsedUsageCollection = [
5555
},
5656
},
5757
my_array: {
58-
total: {
59-
type: 'number',
58+
type: 'array',
59+
items: {
60+
total: {
61+
type: 'number',
62+
},
63+
type: { type: 'boolean' },
6064
},
61-
type: { type: 'boolean' },
6265
},
63-
my_str_array: { type: 'keyword' },
66+
my_str_array: { type: 'array', items: { type: 'keyword' } },
6467
},
6568
},
6669
fetch: {
@@ -91,18 +94,22 @@ export const parsedWorkingCollector: ParsedUsageCollection = [
9194
},
9295
},
9396
my_array: {
94-
total: {
95-
kind: SyntaxKind.NumberKeyword,
96-
type: 'NumberKeyword',
97-
},
98-
type: {
99-
kind: SyntaxKind.BooleanKeyword,
100-
type: 'BooleanKeyword',
97+
items: {
98+
total: {
99+
kind: SyntaxKind.NumberKeyword,
100+
type: 'NumberKeyword',
101+
},
102+
type: {
103+
kind: SyntaxKind.BooleanKeyword,
104+
type: 'BooleanKeyword',
105+
},
101106
},
102107
},
103108
my_str_array: {
104-
kind: SyntaxKind.StringKeyword,
105-
type: 'StringKeyword',
109+
items: {
110+
kind: SyntaxKind.StringKeyword,
111+
type: 'StringKeyword',
112+
},
106113
},
107114
},
108115
},

packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap

Lines changed: 25 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/kbn-telemetry-tools/src/tools/manage_schema.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export type AllowedSchemaTypes =
2828
| 'date'
2929
| 'float';
3030

31-
export function compatibleSchemaTypes(type: AllowedSchemaTypes) {
31+
export function compatibleSchemaTypes(type: AllowedSchemaTypes | 'array') {
3232
switch (type) {
3333
case 'keyword':
3434
case 'text':
@@ -40,6 +40,8 @@ export function compatibleSchemaTypes(type: AllowedSchemaTypes) {
4040
case 'float':
4141
case 'long':
4242
return 'number';
43+
case 'array':
44+
return 'array';
4345
default:
4446
throw new Error(`Unknown schema type ${type}`);
4547
}
@@ -66,10 +68,22 @@ export function isObjectMapping(entity: any) {
6668
return false;
6769
}
6870

71+
function isArrayMapping(entity: any): entity is { type: 'array'; items: object } {
72+
return typeof entity === 'object' && entity.type === 'array' && typeof entity.items === 'object';
73+
}
74+
75+
function getValueMapping(value: any) {
76+
return isObjectMapping(value) ? transformToEsMapping(value) : value;
77+
}
78+
6979
function transformToEsMapping(usageMappingValue: any) {
7080
const fieldMapping: any = { properties: {} };
7181
for (const [key, value] of Object.entries(usageMappingValue)) {
72-
fieldMapping.properties[key] = isObjectMapping(value) ? transformToEsMapping(value) : value;
82+
if (isArrayMapping(value)) {
83+
fieldMapping.properties[key] = { ...value, items: getValueMapping(value.items) };
84+
} else {
85+
fieldMapping.properties[key] = getValueMapping(value);
86+
}
7387
}
7488
return fieldMapping;
7589
}

packages/kbn-telemetry-tools/src/tools/serializer.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ describe('getDescriptor', () => {
8484
expect(descriptor).toEqual({
8585
prop1: { kind: TelemetryKinds.MomentDate, type: 'MomentDate' },
8686
prop2: { kind: TelemetryKinds.MomentDate, type: 'MomentDate' },
87-
prop3: { kind: TelemetryKinds.MomentDate, type: 'MomentDate' },
88-
prop4: { kind: TelemetryKinds.Date, type: 'Date' },
87+
prop3: { items: { kind: TelemetryKinds.MomentDate, type: 'MomentDate' } },
88+
prop4: { items: { kind: TelemetryKinds.Date, type: 'Date' } },
8989
});
9090
});
9191

packages/kbn-telemetry-tools/src/tools/serializer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor |
139139
}
140140

141141
if (ts.isArrayTypeNode(node)) {
142-
return getDescriptor(node.elementType, program);
142+
return { items: getDescriptor(node.elementType, program) };
143143
}
144144

145145
if (ts.isLiteralTypeNode(node)) {

src/fixtures/telemetry_collectors/working_collector.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,15 @@ export const myCollector = makeUsageCollector<Usage>({
9090
type: { type: 'boolean' },
9191
},
9292
my_array: {
93-
total: {
94-
type: 'number',
93+
type: 'array',
94+
items: {
95+
total: {
96+
type: 'number',
97+
},
98+
type: { type: 'boolean' },
9599
},
96-
type: { type: 'boolean' },
97100
},
98-
my_str_array: { type: 'keyword' },
101+
my_str_array: { type: 'array', items: { type: 'keyword' } },
99102
my_index_signature_prop: {
100103
count: { type: 'number' },
101104
avg: { type: 'number' },

src/plugins/home/server/services/sample_data/usage/collector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ export async function makeSampleDataUsageCollector(
3838
fetch: fetchProvider(index),
3939
isReady: () => true,
4040
schema: {
41-
installed: { type: 'keyword' },
41+
installed: { type: 'array', items: { type: 'keyword' } },
4242
last_install_date: { type: 'date' },
4343
last_install_set: { type: 'keyword' },
4444
last_uninstall_date: { type: 'date' },
4545
last_uninstall_set: { type: 'keyword' },
46-
uninstalled: { type: 'keyword' },
46+
uninstalled: { type: 'array', items: { type: 'keyword' } },
4747
},
4848
});
4949

src/plugins/telemetry/schema/oss_plugins.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
"sample-data": {
3030
"properties": {
3131
"installed": {
32-
"type": "keyword"
32+
"type": "array",
33+
"items": {
34+
"type": "keyword"
35+
}
3336
},
3437
"last_install_date": {
3538
"type": "date"
@@ -44,7 +47,10 @@
4447
"type": "keyword"
4548
},
4649
"uninstalled": {
47-
"type": "keyword"
50+
"type": "array",
51+
"items": {
52+
"type": "keyword"
53+
}
4854
}
4955
}
5056
},

src/plugins/usage_collection/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ The `AllowedSchemaTypes` is the list of allowed schema types for the usage field
140140
'keyword', 'text', 'number', 'boolean', 'long', 'date', 'float'
141141
```
142142

143+
### Arrays
144+
145+
If any of your properties is an array, the schema definition must follow the convention below:
146+
147+
```
148+
{ type: 'array', items: {...mySchemaDefinitionOfTheEntriesInTheArray} }
149+
```
150+
143151
### Example
144152

145153
```ts
@@ -152,6 +160,8 @@ export const myCollector = makeUsageCollector<Usage>({
152160
some_obj: {
153161
total: 123,
154162
},
163+
some_array: ['value1', 'value2'],
164+
some_array_of_obj: [{total: 123}],
155165
};
156166
},
157167
schema: {
@@ -163,6 +173,18 @@ export const myCollector = makeUsageCollector<Usage>({
163173
type: 'number',
164174
},
165175
},
176+
some_array: {
177+
type: 'array',
178+
items: { type: 'keyword' }
179+
},
180+
some_array_of_obj: {
181+
type: 'array',
182+
items: {
183+
total: {
184+
type: 'number',
185+
},
186+
},
187+
},
166188
},
167189
});
168190
```

0 commit comments

Comments
 (0)