Skip to content

Commit

Permalink
Merge branch 'master' into security/sharing-saved-objects-1.5
Browse files Browse the repository at this point in the history
Resolves conflicts from #75172.
  • Loading branch information
jportner committed Aug 19, 2020
2 parents 0d6bcc2 + 9698a07 commit 69516b6
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export interface SavedObjectsBulkCreateObject<T = unknown>
| [originId](./kibana-plugin-core-server.savedobjectsbulkcreateobject.originid.md) | <code>string</code> | Optional ID of the original saved object, if this object's <code>id</code> was regenerated |
| [references](./kibana-plugin-core-server.savedobjectsbulkcreateobject.references.md) | <code>SavedObjectReference[]</code> | |
| [type](./kibana-plugin-core-server.savedobjectsbulkcreateobject.type.md) | <code>string</code> | |
| [version](./kibana-plugin-core-server.savedobjectsbulkcreateobject.version.md) | <code>string</code> | |

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsBulkCreateObject](./kibana-plugin-core-server.savedobjectsbulkcreateobject.md) &gt; [version](./kibana-plugin-core-server.savedobjectsbulkcreateobject.version.md)

## SavedObjectsBulkCreateObject.version property

<b>Signature:</b>

```typescript
version?: string;
```
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions
| [overwrite](./kibana-plugin-core-server.savedobjectscreateoptions.overwrite.md) | <code>boolean</code> | Overwrite existing documents (defaults to false) |
| [references](./kibana-plugin-core-server.savedobjectscreateoptions.references.md) | <code>SavedObjectReference[]</code> | |
| [refresh](./kibana-plugin-core-server.savedobjectscreateoptions.refresh.md) | <code>MutatingOperationRefreshSetting</code> | The Elasticsearch Refresh setting for this operation |
| [version](./kibana-plugin-core-server.savedobjectscreateoptions.version.md) | <code>string</code> | An opaque version number which changes on each successful write operation. Can be used in conjunction with <code>overwrite</code> for implementing optimistic concurrency control. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md) &gt; [version](./kibana-plugin-core-server.savedobjectscreateoptions.version.md)

## SavedObjectsCreateOptions.version property

An opaque version number which changes on each successful write operation. Can be used in conjunction with `overwrite` for implementing optimistic concurrency control.

<b>Signature:</b>

```typescript
version?: string;
```
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@ describe('#createSavedObjects', () => {
});
});

it('filters out version from objects before create', async () => {
const options = setupParams({ objects: [{ ...obj1, version: 'foo' }] });
bulkCreate.mockResolvedValue({ saved_objects: [getResultMock.success(obj1, options)] });

await createSavedObjects(options);
expectBulkCreateArgs.objects(1, [obj1]);
});

const testBulkCreateObjects = async (namespace?: string) => {
const options = setupParams({ objects: objs, namespace });
setupMockResults(options);
Expand Down
3 changes: 2 additions & 1 deletion src/core/server/saved_objects/import/create_saved_objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export const createSavedObjects = async <T>({
new Map<string, SavedObject<T>>()
);

const objectsToCreate = filteredObjects.map((object) => {
// filter out the 'version' field of each object, if it exists
const objectsToCreate = filteredObjects.map(({ version, ...object }) => {
// use the import ID map to ensure that each reference is being created with the correct ID
const references = object.references?.map((reference) => {
const { type, id } = reference;
Expand Down
43 changes: 41 additions & 2 deletions src/core/server/saved_objects/service/lib/repository.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,16 @@ describe('SavedObjectsRepository', () => {
{ method, _index = expect.any(String), getId = () => expect.any(String) }
) => {
const body = [];
for (const { type, id } of objects) {
body.push({ [method]: { _index, _id: getId(type, id) } });
for (const { type, id, if_primary_term: ifPrimaryTerm, if_seq_no: ifSeqNo } of objects) {
body.push({
[method]: {
_index,
_id: getId(type, id),
...(ifPrimaryTerm && ifSeqNo
? { if_primary_term: expect.any(Number), if_seq_no: expect.any(Number) }
: {}),
},
});
body.push(expect.any(Object));
}
expect(client.bulk).toHaveBeenCalledWith(
Expand Down Expand Up @@ -532,6 +540,27 @@ describe('SavedObjectsRepository', () => {
expectClientCallArgsAction([obj1, obj2], { method: 'index' });
});

it(`should use the ES index method with version if ID and version are defined and overwrite=true`, async () => {
await bulkCreateSuccess(
[
{
...obj1,
version: mockVersion,
},
obj2,
],
{ overwrite: true }
);

const obj1WithSeq = {
...obj1,
if_seq_no: mockVersionProps._seq_no,
if_primary_term: mockVersionProps._primary_term,
};

expectClientCallArgsAction([obj1WithSeq, obj2], { method: 'index' });
});

it(`should use the ES create method if ID is defined and overwrite=false`, async () => {
await bulkCreateSuccess([obj1, obj2]);
expectClientCallArgsAction([obj1, obj2], { method: 'create' });
Expand Down Expand Up @@ -1663,6 +1692,16 @@ describe('SavedObjectsRepository', () => {
expect(client.index).toHaveBeenCalled();
});

it(`should use the ES index with version if ID and version are defined and overwrite=true`, async () => {
await createSuccess(type, attributes, { id, overwrite: true, version: mockVersion });
expect(client.index).toHaveBeenCalled();

expect(client.index.mock.calls[0][0]).toMatchObject({
if_seq_no: mockVersionProps._seq_no,
if_primary_term: mockVersionProps._primary_term,
});
});

it(`should use the ES create action if ID is defined and overwrite=false`, async () => {
await createSuccess(type, attributes, { id });
expect(client.create).toHaveBeenCalled();
Expand Down
12 changes: 11 additions & 1 deletion src/core/server/saved_objects/service/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ export class SavedObjectsRepository {
references = [],
refresh = DEFAULT_REFRESH_SETTING,
originId,
version,
} = options;

if (!this._allowedTypes.includes(type)) {
Expand Down Expand Up @@ -263,6 +264,7 @@ export class SavedObjectsRepository {
index: this.getIndexForType(type),
refresh,
body: raw._source,
...(overwrite && version ? decodeRequestVersion(version) : {}),
};

const { body } =
Expand Down Expand Up @@ -348,7 +350,12 @@ export class SavedObjectsRepository {

let savedObjectNamespace;
let savedObjectNamespaces;
const { esRequestIndex, object, method } = expectedBulkGetResult.value;
let versionProperties;
const {
esRequestIndex,
object: { version, ...object },
method,
} = expectedBulkGetResult.value;
if (esRequestIndex !== undefined) {
const indexFound = bulkGetResponse?.statusCode !== 404;
const actualResult = indexFound ? bulkGetResponse?.body.docs[esRequestIndex] : undefined;
Expand All @@ -368,12 +375,14 @@ export class SavedObjectsRepository {
};
}
savedObjectNamespaces = getSavedObjectNamespaces(namespace, docFound && actualResult);
versionProperties = getExpectedVersionProperties(version, actualResult);
} else {
if (this._registry.isSingleNamespace(object.type)) {
savedObjectNamespace = namespace;
} else if (this._registry.isMultiNamespace(object.type)) {
savedObjectNamespaces = getSavedObjectNamespaces(namespace);
}
versionProperties = getExpectedVersionProperties(version);
}

const expectedResult = {
Expand All @@ -399,6 +408,7 @@ export class SavedObjectsRepository {
[method]: {
_id: expectedResult.rawMigratedDoc._id,
_index: this.getIndexForType(object.type),
...(overwrite && versionProperties),
},
},
expectedResult.rawMigratedDoc._source
Expand Down
6 changes: 6 additions & 0 deletions src/core/server/saved_objects/service/saved_objects_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions {
id?: string;
/** Overwrite existing documents (defaults to false) */
overwrite?: boolean;
/**
* An opaque version number which changes on each successful write operation.
* Can be used in conjunction with `overwrite` for implementing optimistic concurrency control.
**/
version?: string;
/** {@inheritDoc SavedObjectsMigrationVersion} */
migrationVersion?: SavedObjectsMigrationVersion;
references?: SavedObjectReference[];
Expand All @@ -55,6 +60,7 @@ export interface SavedObjectsBulkCreateObject<T = unknown> {
id?: string;
type: string;
attributes: T;
version?: string;
references?: SavedObjectReference[];
/** {@inheritDoc SavedObjectsMigrationVersion} */
migrationVersion?: SavedObjectsMigrationVersion;
Expand Down
3 changes: 3 additions & 0 deletions src/core/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2045,6 +2045,8 @@ export interface SavedObjectsBulkCreateObject<T = unknown> {
references?: SavedObjectReference[];
// (undocumented)
type: string;
// (undocumented)
version?: string;
}

// @public (undocumented)
Expand Down Expand Up @@ -2199,6 +2201,7 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions {
// (undocumented)
references?: SavedObjectReference[];
refresh?: MutatingOperationRefreshSetting;
version?: string;
}

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export function createInstallRoute(
let createResults;
try {
createResults = await context.core.savedObjects.client.bulkCreate(
sampleDataset.savedObjects,
sampleDataset.savedObjects.map(({ version, ...savedObject }) => savedObject),
{ overwrite: true }
);
} catch (err) {
Expand Down
2 changes: 1 addition & 1 deletion test/functional/page_objects/visualize_chart_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr
const firstCount = await this.getVisualizationRenderingCount();
log.debug(`-- firstCount=${firstCount}`);

await common.sleep(1000);
await common.sleep(2000);

const secondCount = await this.getVisualizationRenderingCount();
log.debug(`-- secondCount=${secondCount}`);
Expand Down

0 comments on commit 69516b6

Please sign in to comment.