Skip to content

Commit c31acce

Browse files
authored
Fix more broken usages of bulkCreate (#76005)
1 parent 165752b commit c31acce

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

src/plugins/home/public/application/components/tutorial/saved_objects_installer.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ class SavedObjectsInstallerUi extends React.Component {
6262

6363
let resp;
6464
try {
65-
resp = await this.props.bulkCreate(this.props.savedObjects, {
66-
overwrite: this.state.overwrite,
67-
});
65+
// Filter out the saved object version field, if present, to avoid inadvertently triggering optimistic concurrency control.
66+
const objectsToCreate = this.props.savedObjects.map(
67+
// eslint-disable-next-line no-unused-vars
68+
({ version, ...savedObject }) => savedObject
69+
);
70+
resp = await this.props.bulkCreate(objectsToCreate, { overwrite: this.state.overwrite });
6871
} catch (error) {
6972
if (!this._isMounted) {
7073
return;

src/plugins/home/public/application/components/tutorial/saved_objects_installer.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,25 @@ describe('bulkCreate', () => {
7979

8080
expect(component).toMatchSnapshot();
8181
});
82+
83+
test('should filter out saved object version before calling bulkCreate', async () => {
84+
const bulkCreateMock = jest.fn().mockResolvedValue({
85+
savedObjects: [savedObject],
86+
});
87+
const component = mountWithIntl(
88+
<SavedObjectsInstaller.WrappedComponent
89+
bulkCreate={bulkCreateMock}
90+
savedObjects={[{ ...savedObject, version: 'foo' }]}
91+
/>
92+
);
93+
94+
findTestSubject(component, 'loadSavedObjects').simulate('click');
95+
96+
// Ensure all promises resolve
97+
await new Promise((resolve) => process.nextTick(resolve));
98+
// Ensure the state changes are reflected
99+
component.update();
100+
101+
expect(bulkCreateMock).toHaveBeenCalledWith([savedObject], expect.any(Object));
102+
});
82103
});

x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { getAuthorizationHeader } from '../../lib/request_authorization';
2020
import { MlInfoResponse } from '../../../common/types/ml_server_info';
2121
import {
2222
KibanaObjects,
23+
KibanaObjectConfig,
2324
ModuleDataFeed,
2425
ModuleJob,
2526
Module,
@@ -100,7 +101,7 @@ interface ObjectExistResponse {
100101
id: string;
101102
type: string;
102103
exists: boolean;
103-
savedObject?: any;
104+
savedObject?: { id: string; type: string; attributes: KibanaObjectConfig };
104105
}
105106

106107
interface SaveResults {
@@ -678,14 +679,14 @@ export class DataRecognizer {
678679
let results = { saved_objects: [] as any[] };
679680
const filteredSavedObjects = objectExistResults
680681
.filter((o) => o.exists === false)
681-
.map((o) => o.savedObject);
682+
.map((o) => o.savedObject!);
682683
if (filteredSavedObjects.length) {
683684
results = await this.savedObjectsClient.bulkCreate(
684685
// Add an empty migrationVersion attribute to each saved object to ensure
685686
// it is automatically migrated to the 7.0+ format with a references attribute.
686687
filteredSavedObjects.map((doc) => ({
687688
...doc,
688-
migrationVersion: doc.migrationVersion || {},
689+
migrationVersion: {},
689690
}))
690691
);
691692
}

0 commit comments

Comments
 (0)