mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Sort server-side in SavedObject export (#55128)
Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
This commit is contained in:
parent
265c079a8a
commit
ff37dd1c25
2 changed files with 85 additions and 13 deletions
|
@ -108,8 +108,6 @@ describe('getSortedObjectsForExport()', () => {
|
||||||
"namespace": undefined,
|
"namespace": undefined,
|
||||||
"perPage": 500,
|
"perPage": 500,
|
||||||
"search": undefined,
|
"search": undefined,
|
||||||
"sortField": "_id",
|
|
||||||
"sortOrder": "asc",
|
|
||||||
"type": Array [
|
"type": Array [
|
||||||
"index-pattern",
|
"index-pattern",
|
||||||
"search",
|
"search",
|
||||||
|
@ -256,8 +254,6 @@ describe('getSortedObjectsForExport()', () => {
|
||||||
"namespace": undefined,
|
"namespace": undefined,
|
||||||
"perPage": 500,
|
"perPage": 500,
|
||||||
"search": "foo",
|
"search": "foo",
|
||||||
"sortField": "_id",
|
|
||||||
"sortOrder": "asc",
|
|
||||||
"type": Array [
|
"type": Array [
|
||||||
"index-pattern",
|
"index-pattern",
|
||||||
"search",
|
"search",
|
||||||
|
@ -345,8 +341,6 @@ describe('getSortedObjectsForExport()', () => {
|
||||||
"namespace": "foo",
|
"namespace": "foo",
|
||||||
"perPage": 500,
|
"perPage": 500,
|
||||||
"search": undefined,
|
"search": undefined,
|
||||||
"sortField": "_id",
|
|
||||||
"sortOrder": "asc",
|
|
||||||
"type": Array [
|
"type": Array [
|
||||||
"index-pattern",
|
"index-pattern",
|
||||||
"search",
|
"search",
|
||||||
|
@ -399,6 +393,79 @@ describe('getSortedObjectsForExport()', () => {
|
||||||
).rejects.toThrowErrorMatchingInlineSnapshot(`"Can't export more than 1 objects"`);
|
).rejects.toThrowErrorMatchingInlineSnapshot(`"Can't export more than 1 objects"`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sorts objects within type', async () => {
|
||||||
|
savedObjectsClient.find.mockResolvedValueOnce({
|
||||||
|
total: 3,
|
||||||
|
per_page: 10000,
|
||||||
|
page: 1,
|
||||||
|
saved_objects: [
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
type: 'index-pattern',
|
||||||
|
attributes: {
|
||||||
|
name: 'baz',
|
||||||
|
},
|
||||||
|
references: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
type: 'index-pattern',
|
||||||
|
attributes: {
|
||||||
|
name: 'foo',
|
||||||
|
},
|
||||||
|
references: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
type: 'index-pattern',
|
||||||
|
attributes: {
|
||||||
|
name: 'bar',
|
||||||
|
},
|
||||||
|
references: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const exportStream = await getSortedObjectsForExport({
|
||||||
|
exportSizeLimit: 10000,
|
||||||
|
savedObjectsClient,
|
||||||
|
types: ['index-pattern'],
|
||||||
|
});
|
||||||
|
const response = await readStreamToCompletion(exportStream);
|
||||||
|
expect(response).toMatchInlineSnapshot(`
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"attributes": Object {
|
||||||
|
"name": "foo",
|
||||||
|
},
|
||||||
|
"id": "1",
|
||||||
|
"references": Array [],
|
||||||
|
"type": "index-pattern",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"attributes": Object {
|
||||||
|
"name": "bar",
|
||||||
|
},
|
||||||
|
"id": "2",
|
||||||
|
"references": Array [],
|
||||||
|
"type": "index-pattern",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"attributes": Object {
|
||||||
|
"name": "baz",
|
||||||
|
},
|
||||||
|
"id": "3",
|
||||||
|
"references": Array [],
|
||||||
|
"type": "index-pattern",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"exportedCount": 3,
|
||||||
|
"missingRefCount": 0,
|
||||||
|
"missingReferences": Array [],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
test('exports selected objects and sorts them', async () => {
|
test('exports selected objects and sorts them', async () => {
|
||||||
savedObjectsClient.bulkGet.mockResolvedValueOnce({
|
savedObjectsClient.bulkGet.mockResolvedValueOnce({
|
||||||
saved_objects: [
|
saved_objects: [
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import Boom from 'boom';
|
import Boom from 'boom';
|
||||||
import { createListStream } from '../../../../legacy/utils/streams';
|
import { createListStream } from '../../../../legacy/utils/streams';
|
||||||
import { SavedObjectsClientContract } from '../types';
|
import { SavedObjectsClientContract, SavedObject } from '../types';
|
||||||
import { fetchNestedDependencies } from './inject_nested_depdendencies';
|
import { fetchNestedDependencies } from './inject_nested_depdendencies';
|
||||||
import { sortObjects } from './sort_objects';
|
import { sortObjects } from './sort_objects';
|
||||||
|
|
||||||
|
@ -105,15 +105,17 @@ async function fetchObjectsToExport({
|
||||||
const findResponse = await savedObjectsClient.find({
|
const findResponse = await savedObjectsClient.find({
|
||||||
type: types,
|
type: types,
|
||||||
search,
|
search,
|
||||||
sortField: '_id',
|
|
||||||
sortOrder: 'asc',
|
|
||||||
perPage: exportSizeLimit,
|
perPage: exportSizeLimit,
|
||||||
namespace,
|
namespace,
|
||||||
});
|
});
|
||||||
if (findResponse.total > exportSizeLimit) {
|
if (findResponse.total > exportSizeLimit) {
|
||||||
throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`);
|
throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`);
|
||||||
}
|
}
|
||||||
return findResponse.saved_objects;
|
|
||||||
|
// sorts server-side by _id, since it's only available in fielddata
|
||||||
|
return findResponse.saved_objects.sort((a: SavedObject, b: SavedObject) =>
|
||||||
|
a.id > b.id ? 1 : -1
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw Boom.badRequest('Either `type` or `objects` are required.');
|
throw Boom.badRequest('Either `type` or `objects` are required.');
|
||||||
}
|
}
|
||||||
|
@ -137,14 +139,17 @@ export async function getSortedObjectsForExport({
|
||||||
exportSizeLimit,
|
exportSizeLimit,
|
||||||
namespace,
|
namespace,
|
||||||
});
|
});
|
||||||
let exportedObjects = [...rootObjects];
|
let exportedObjects = [];
|
||||||
let missingReferences: SavedObjectsExportResultDetails['missingReferences'] = [];
|
let missingReferences: SavedObjectsExportResultDetails['missingReferences'] = [];
|
||||||
|
|
||||||
if (includeReferencesDeep) {
|
if (includeReferencesDeep) {
|
||||||
const fetchResult = await fetchNestedDependencies(rootObjects, savedObjectsClient, namespace);
|
const fetchResult = await fetchNestedDependencies(rootObjects, savedObjectsClient, namespace);
|
||||||
exportedObjects = fetchResult.objects;
|
exportedObjects = sortObjects(fetchResult.objects);
|
||||||
missingReferences = fetchResult.missingRefs;
|
missingReferences = fetchResult.missingRefs;
|
||||||
|
} else {
|
||||||
|
exportedObjects = sortObjects(rootObjects);
|
||||||
}
|
}
|
||||||
exportedObjects = sortObjects(exportedObjects);
|
|
||||||
const exportDetails: SavedObjectsExportResultDetails = {
|
const exportDetails: SavedObjectsExportResultDetails = {
|
||||||
exportedCount: exportedObjects.length,
|
exportedCount: exportedObjects.length,
|
||||||
missingRefCount: missingReferences.length,
|
missingRefCount: missingReferences.length,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue