Skip to content

Conversation

@TinaHeiligers
Copy link
Contributor

@TinaHeiligers TinaHeiligers commented May 26, 2023

fix #152994

saved objects convert to using models. Ideally, type owners should still be able to validate objects against an expected model version schema for creating and editing their objects.

This PR adds support for optionally declaring model.schema.create, with which to validate against a config.schema.
Validation schemas for models are mapped to their virtual model version (model version '1' -> virtual version 10.1.0) in the validationMap.

@TinaHeiligers TinaHeiligers requested a review from pgayvallet May 26, 2023 02:58
Copy link
Contributor Author

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

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

Draft early stages of adding tests

@TinaHeiligers TinaHeiligers changed the title [WIP] Adds support for model version schema [SOR] Adds support for validation schema with models May 29, 2023
@TinaHeiligers TinaHeiligers requested a review from pgayvallet May 29, 2023 01:21
@TinaHeiligers TinaHeiligers force-pushed the kbn-152994-SO-model-version-support-schema branch from 0ad3f3e to ca9b8ac Compare May 29, 2023 21:33
@TinaHeiligers TinaHeiligers added Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting v8.9.0 Feature:Saved Objects Epic:ZDTmigrations Zero downtime migrations labels May 29, 2023
@TinaHeiligers TinaHeiligers marked this pull request as ready for review May 29, 2023 23:00
@TinaHeiligers TinaHeiligers requested a review from a team as a code owner May 29, 2023 23:00
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@TinaHeiligers TinaHeiligers removed the request for review from pgayvallet May 29, 2023 23:00
@TinaHeiligers
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Member

@afharo afharo left a comment

Choose a reason for hiding this comment

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

LGTM. I just added a few nits.

I didn't approve because I'd like to rely on SO gurus for this 😇

@TinaHeiligers
Copy link
Contributor Author

TinaHeiligers commented May 30, 2023

We need a different way to target the validation version on write since we can't just take the latest stack version for documents that are already on 10.x.0.

Proposed solutions: don't pass version as an option to validate from SOR create and bulkCreate APIs and leave the (now unused) version option in the logic chain for targeting a version or, since option.version won't be used anymore, keep it simple and remove the option.

Since we already know issues will arise and, since it's going to be unused anyway, I'm going with removing the option altogether. There's no point in carting something along "just in case". We can add it back if we need to.

@TinaHeiligers TinaHeiligers marked this pull request as draft May 30, 2023 17:48
@TinaHeiligers
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Contributor Author

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

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

initial draft self review: comments to myself and todos

Copy link
Contributor Author

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

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

Self review 2

document.migrationVersion?.[document.type] ??
this.defaultVersion;
const schemaVersion = previousVersionWithSchema(this.orderedVersions, docVersion);
let usedVersion = version;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even though the version option is (or should be) unused now, keeping the behavior allows us to reuse it if needed.

I'm open to removing the option if someone objects.

Copy link
Contributor

Choose a reason for hiding this comment

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

Correct me if I'm wrong, but in current state, the version option is effectively unused (given usedVersion is always replaced L52-L56), right?

I'm fine either way (keeping it or removing it), but if we do keep it, then we need the version parameter to be used if specified (it doesn't make sense to keep an option ignored by the implementation), and to adapt the call to validate to no longer pass the option, here:

try {
validator.validate(doc, this.kibanaVersion);
} catch (error) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're entirely right, version isn't used anymore and it doesn't make sense to keep dead code around. I will remove it.

@TinaHeiligers TinaHeiligers marked this pull request as ready for review June 1, 2023 22:02
Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

Great work, looking good to me!

Just asked a few questions for clarification before approval:

*/

import type { ObjectType } from '@kbn/config-schema';
import { SavedObjectsValidationSpec } from '../validation';
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: import type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

document.migrationVersion?.[document.type] ??
this.defaultVersion;
const schemaVersion = previousVersionWithSchema(this.orderedVersions, docVersion);
let usedVersion = version;
Copy link
Contributor

Choose a reason for hiding this comment

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

Correct me if I'm wrong, but in current state, the version option is effectively unused (given usedVersion is always replaced L52-L56), right?

I'm fine either way (keeping it or removing it), but if we do keep it, then we need the version parameter to be used if specified (it doesn't make sense to keep an option ignored by the implementation), and to adapt the call to validate to no longer pass the option, here:

try {
validator.validate(doc, this.kibanaVersion);
} catch (error) {

Comment on lines 119 to 122
const virtualVersion = modelVersionToVirtualVersion(key);
if (modelVersion.schemas?.create) {
combinedSchemas[virtualVersion] = modelVersion.schemas!.create!;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: modelVersionToVirtualVersion can be done within the if block to avoid calling it when not needed

if (modelVersion.schemas?.create) {
    const virtualVersion = modelVersionToVirtualVersion(key);
    combinedSchemas[virtualVersion] = modelVersion.schemas!.create!;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 193 to 197
it('should use the correct schema for documents with with virtualModelVersion higher than default when not a valid virtual model version', () => {
const data = createMockObject({ typeMigrationVersion: '11.1.4' });
validator.validate(data);
expect(getCalledVersion()).toEqual('3.0.0');
});
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: atm, 11.1.4 is an 'invalid' version for any document to have, given there's no reason to have a major superior to 10, so I wouldn't add tests about it tbh. (also, why does it use the 3.0.0 schema and not the 10.1.0 one?)

Copy link
Contributor Author

@TinaHeiligers TinaHeiligers Jun 2, 2023

Choose a reason for hiding this comment

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

also, why does it use the 3.0.0 schema and not the 10.1.0 one?

The docVersion is 11.1.4and the default version is 3.2.0. Because 11.1.4 isn't a valid virtual mode version, the conditional:

usedVersion = isVirtualModelVersion(docVersion) ? docVersion : this.defaultVersion;

implements the false path: usedVersion = this.defaultVersion, and previousVersionWithSchema returns 3.0.0.

Hence 3.0.0 and not 10.1.0.

Comment on lines 187 to 191
it('should use the correct schema for documents with virtualModelVersion', () => {
const data = createMockObject({ typeMigrationVersion: '10.1.0' });
validator.validate(data);
expect(getCalledVersion()).toEqual('10.1.0');
});
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: Instead of registering a 10.1.0 schema, I would register one of 10.2.0 and then assert that

  • a document with version 10.1.0 uses schema 4.3.0
  • a document with version 10.2.0 uses schema 10.2.0
  • a document with version 10.3.0 uses schema 10.2.0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

a document with version 10.1.0 uses schema 4.3.0

The default version is 3.3.0 in the tests, so the schema that will be used is 3.0.0

@TinaHeiligers
Copy link
Contributor Author

@elasticmachine merge upstream

@TinaHeiligers
Copy link
Contributor Author

@pgayvallet I've answered your questions and handled the changes. Could you please take another look?

@TinaHeiligers
Copy link
Contributor Author

@elasticmachine merge upstream

@kibana-ci
Copy link

💚 Build Succeeded

Metrics [docs]

Unknown metric groups

API count

id before after diff
@kbn/core-saved-objects-server 534 535 +1

ESLint disabled line counts

id before after diff
enterpriseSearch 19 21 +2
securitySolution 414 418 +4
total +6

Total ESLint disabled count

id before after diff
enterpriseSearch 20 22 +2
securitySolution 498 502 +4
total +6

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines 142 to 150
// jest.clearAllMocks();

data = createMockObject({
migrationVersion: {
[type]: '3.0.0',
},
});
validator.validate(data);
expect(getCalledVersion()).toEqual('3.0.0');
// data = createMockObject({
// migrationVersion: {
// [type]: '3.2.0',
// },
// });
// validator.validate(data);
// expect(getCalledVersion()).toEqual('3.0.0');
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: remove commented code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

should already be done

@TinaHeiligers TinaHeiligers merged commit fd068da into elastic:main Jun 5, 2023
@TinaHeiligers TinaHeiligers deleted the kbn-152994-SO-model-version-support-schema branch June 5, 2023 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting Epic:ZDTmigrations Zero downtime migrations Feature:Saved Objects release_note:skip Skip the PR/issue when compiling release notes Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// v8.9.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SO Model version: add support for schema

6 participants