-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Entity store/maintainer framework poc #253173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 20 commits
0c6a26c
247b5a6
e7ce286
1163568
54bd453
9656aa0
cbcdcc5
2848ee8
af1f246
5516b54
94257bc
f382b01
7940c03
06597cb
47ee01f
1e7ae7e
f487b32
dba40fd
f7ae5b5
d63d895
2dd6abf
442c007
f3cfb44
9aadac0
684a41f
f6a2287
d53e732
deb6274
6b9cf97
9ded95b
2e792a2
ae48b1f
9d9c7bd
ef9c929
39e0807
19fc383
cd5cae7
e8b290d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| import { z } from '@kbn/zod'; | ||
|
|
||
| export type EntityMaintainerTaskEntry = z.infer<typeof EntityMaintainerTaskEntry>; | ||
| export const EntityMaintainerTaskEntry = z.object({ | ||
| id: z.string(), | ||
| interval: z.string().regex(/[smdh]$/), | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /* | ||
|
chennn1990 marked this conversation as resolved.
Outdated
|
||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| import type { ISavedObjectsRepository } from '@kbn/core/server'; | ||
| import { SavedObjectsErrorHelpers, type Logger } from '@kbn/core/server'; | ||
| import type { EntityMaintainerTaskEntry } from './constants'; | ||
| import { EntityMaintainerTaskEntry as EntityMaintainerTaskEntrySchema } from './constants'; | ||
| import { EntityMaintainersTasksTypeName, EntityMaintainersTasksId } from './types'; | ||
|
|
||
| const ENTITY_MAINTAINERS_TASKS_ATTR = 'entity-maintainers-tasks' as const; | ||
|
|
||
| export class EntityMaintainersTasksClient { | ||
| constructor( | ||
| private readonly repository: ISavedObjectsRepository, | ||
| private readonly logger: Logger | ||
| ) {} | ||
|
|
||
| async getAll(): Promise<EntityMaintainerTaskEntry[]> { | ||
| try { | ||
| const doc = await this.repository.get< | ||
| Record<typeof ENTITY_MAINTAINERS_TASKS_ATTR, unknown[]> | ||
|
chennn1990 marked this conversation as resolved.
Outdated
|
||
| >(EntityMaintainersTasksTypeName, EntityMaintainersTasksId); | ||
| const raw = doc.attributes[ENTITY_MAINTAINERS_TASKS_ATTR] ?? []; | ||
| return raw.map((entry) => EntityMaintainerTaskEntrySchema.parse(entry)); | ||
| } catch (err) { | ||
| if (SavedObjectsErrorHelpers.isNotFoundError(err)) { | ||
| return []; | ||
| } | ||
| this.logger.error(`Failed to get entity maintainer tasks: ${err?.message}`); | ||
| throw err; | ||
| } | ||
| } | ||
|
|
||
| async addOrUpdate(entry: EntityMaintainerTaskEntry): Promise<void> { | ||
| const taskEntry = EntityMaintainerTaskEntrySchema.parse(entry); | ||
| try { | ||
| const existing = await this.repository.get< | ||
| Record<typeof ENTITY_MAINTAINERS_TASKS_ATTR, EntityMaintainerTaskEntry[]> | ||
| >(EntityMaintainersTasksTypeName, EntityMaintainersTasksId); | ||
| const tasks = existing.attributes[ENTITY_MAINTAINERS_TASKS_ATTR] ?? []; | ||
| this.logger.debug(`Tasks registered: ${JSON.stringify(tasks)}`); | ||
| const filtered = tasks.filter((t) => t.id !== taskEntry.id); | ||
| await this.repository.update(EntityMaintainersTasksTypeName, EntityMaintainersTasksId, { | ||
| [ENTITY_MAINTAINERS_TASKS_ATTR]: [...filtered, taskEntry], | ||
| }); | ||
| } catch (err) { | ||
| if (SavedObjectsErrorHelpers.isNotFoundError(err)) { | ||
| this.logger.debug(`Creating entity maintainers tasks document with first entry`); | ||
| await this.repository.create( | ||
| EntityMaintainersTasksTypeName, | ||
| { [ENTITY_MAINTAINERS_TASKS_ATTR]: [taskEntry] }, | ||
| { id: EntityMaintainersTasksId } | ||
| ); | ||
| return; | ||
| } | ||
|
chennn1990 marked this conversation as resolved.
Outdated
|
||
| this.logger.error( | ||
| `Failed to register entity maintainer task in saved object: ${err?.message}` | ||
| ); | ||
| throw err; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| import type { SavedObjectsFullModelVersion } from '@kbn/core-saved-objects-server'; | ||
| import type { SavedObjectsType } from '@kbn/core/server'; | ||
| import { schema } from '@kbn/config-schema'; | ||
|
|
||
| export const EntityMaintainersTasksTypeName = 'entity-maintainers-tasks'; | ||
| export const EntityMaintainersTasksId = 'entity-maintainers-tasks'; | ||
|
|
||
| export const EntityMaintainersTasksTypeMappings: SavedObjectsType['mappings'] = { | ||
| dynamic: false, | ||
| properties: { | ||
| 'entity-maintainers-tasks': { | ||
| type: 'nested', | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hop-dev do you have examples of how others behave? Tbh, I wonder if we even need to have saved objects for this. Isn't this something that we have all in memory always? Why do we need to store in ES? If we have a kibana restart, the maintainer will be registered again, won't it?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah if you go to The other ones have lots of other properties on the object, whereas here we have one single property which is nested, which to me is like saying "these things are separate documents" because we have no shared maintainer properties.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @romulets The reason we are using saved object is because we need the
@hop-dev I will go over to figure out if there is a better option then
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hop-dev that is exactly what i want
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My point is if that's what you want, and you have no other properties on this saved object, why not just have them as separate objects? I won't keep pushing the point, the core team will review too so they might give us some helpful guidance.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want them to be together, because on install, when fetching all the registered id's, i need their related intervals.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Don't we have this in memory always? |
||
| properties: { | ||
| id: { type: 'keyword' }, | ||
| interval: { type: 'keyword' }, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| const entityMaintainerTaskEntrySchema = schema.object({ | ||
| id: schema.string(), | ||
| interval: schema.string(), | ||
| }); | ||
|
|
||
| const entityMaintainersTasksAttributesSchema = { | ||
| 'entity-maintainers-tasks': schema.arrayOf(entityMaintainerTaskEntrySchema), | ||
|
|
||
| }; | ||
|
|
||
| const version1: SavedObjectsFullModelVersion = { | ||
| changes: [], | ||
| schemas: { | ||
| create: schema.object(entityMaintainersTasksAttributesSchema), | ||
| forwardCompatibility: schema.object(entityMaintainersTasksAttributesSchema, { | ||
| unknowns: 'ignore', | ||
| }), | ||
| }, | ||
| }; | ||
|
|
||
| export const EntityMaintainersTasksType: SavedObjectsType = { | ||
| name: EntityMaintainersTasksTypeName, | ||
| hidden: true, | ||
| namespaceType: 'single', | ||
| mappings: EntityMaintainersTasksTypeMappings, | ||
| modelVersions: { 1: version1 }, | ||
| hiddenFromHttpApis: true, | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.