Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/spaces-phase-1' into spaces/se…
Browse files Browse the repository at this point in the history
…curing
  • Loading branch information
kobelb committed Sep 5, 2018
2 parents cef2e78 + 8b77134 commit 7b4575b
Show file tree
Hide file tree
Showing 54 changed files with 1,931 additions and 2,623 deletions.
3 changes: 3 additions & 0 deletions src/server/mappings/kibana_index_mappings_mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const BASE_SAVED_OBJECT_MAPPINGS = {
doc: {
dynamic: 'strict',
properties: {
namespace: {
type: 'keyword'
},
type: {
type: 'keyword'
},
Expand Down
2 changes: 1 addition & 1 deletion src/server/saved_objects/saved_objects_mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function savedObjectsMixin(kbnServer, server) {
server.route(createGetRoute(prereqs));
server.route(createUpdateRoute(prereqs));

server.decorate('server', 'savedObjects', createSavedObjectsService(server));
server.decorate('server', 'savedObjects', createSavedObjectsService(server, kbnServer.uiExports.savedObjectsSchema));

const savedObjectsClientCache = new WeakMap();
server.decorate('request', 'getSavedObjectsClient', function () {
Expand Down
10 changes: 7 additions & 3 deletions src/server/saved_objects/service/create_saved_objects_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
* under the License.
*/

import { getRootPropertiesObjects } from '../..//mappings';
import { SavedObjectsRepository, ScopedSavedObjectsClientProvider, SavedObjectsRepositoryProvider } from './lib';
import { getRootPropertiesObjects } from '../../mappings';
import { SavedObjectsRepository, ScopedSavedObjectsClientProvider, SavedObjectsRepositoryProvider, SavedObjectsSchema } from './lib';
import { SavedObjectsClient } from './saved_objects_client';

export function createSavedObjectsService(server) {
export function createSavedObjectsService(server, uiExportsSchema) {
const onBeforeWrite = async () => {
const adminCluster = server.plugins.elasticsearch.getCluster('admin');

Expand Down Expand Up @@ -59,10 +59,13 @@ export function createSavedObjectsService(server) {
}
};

const schema = new SavedObjectsSchema(uiExportsSchema);

const mappings = server.getKibanaIndexMappingsDsl();
const repositoryProvider = new SavedObjectsRepositoryProvider({
index: server.config().get('kibana.index'),
mappings,
schema,
onBeforeWrite,
});

Expand All @@ -86,6 +89,7 @@ export function createSavedObjectsService(server) {
types: Object.keys(getRootPropertiesObjects(mappings)),
SavedObjectsClient,
SavedObjectsRepository,
schema,
getSavedObjectsRepository: (...args) =>
repositoryProvider.getRepository(...args),
getScopedSavedObjectsClient: (...args) =>
Expand Down
1 change: 1 addition & 0 deletions src/server/saved_objects/service/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
export { SavedObjectsRepository } from './repository';
export { ScopedSavedObjectsClientProvider } from './scoped_client_provider';
export { SavedObjectsRepositoryProvider } from './repository_provider';
export { SavedObjectsSchema } from './schema';

import * as errors from './errors';
export { errors };
96 changes: 53 additions & 43 deletions src/server/saved_objects/service/lib/repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ export class SavedObjectsRepository {
const {
index,
mappings,
schema,
callCluster,
onBeforeWrite = () => { },
} = options;

this._index = index;
this._mappings = mappings;
this._schema = schema;
this._type = getRootType(this._mappings);
this._onBeforeWrite = onBeforeWrite;
this._unwrappedCallCluster = callCluster;
Expand All @@ -54,35 +56,35 @@ export class SavedObjectsRepository {
* @param {object} [options={}]
* @property {string} [options.id] - force id on creation, not recommended
* @property {boolean} [options.overwrite=false]
* @property {object} [options.extraDocumentProperties={}] - extra properties to append to the document body, outside of the object's type property
* @property {string} [options.namespace]
* @returns {promise} - { id, type, version, attributes }
*/
async create(type, attributes = {}, options = {}) {
const {
id,
extraDocumentProperties = {},
overwrite = false
overwrite = false,
namespace,
} = options;

const method = id && !overwrite ? 'create' : 'index';
const time = this._getCurrentTime();

try {
const response = await this._writeToCluster(method, {
id: this._generateEsId(type, id),
id: this._generateEsId(namespace, type, id),
type: this._type,
index: this._index,
refresh: 'wait_for',
body: {
...extraDocumentProperties,
...namespace && !this._schema.isNamespaceAgnostic(type) && { namespace },
type,
updated_at: time,
[type]: attributes,
},
});

return {
id: trimIdPrefix(response._id, type),
id: trimIdPrefix(this._schema, response._id, namespace, type),
type,
updated_at: time,
version: response._version,
Expand All @@ -101,14 +103,16 @@ export class SavedObjectsRepository {
/**
* Creates multiple documents at once
*
* @param {array} objects - [{ type, id, attributes, extraDocumentProperties }]
* @param {array} objects - [{ type, id, attributes }]
* @param {object} [options={}]
* @property {boolean} [options.overwrite=false] - overwrites existing documents
* @property {string} [options.namespace]
* @returns {promise} - {saved_objects: [[{ id, type, version, attributes, error: { message } }]}
*/
async bulkCreate(objects, options = {}) {
const {
overwrite = false
overwrite = false,
namespace
} = options;
const time = this._getCurrentTime();
const objectToBulkRequest = (object) => {
Expand All @@ -117,12 +121,12 @@ export class SavedObjectsRepository {
return [
{
[method]: {
_id: this._generateEsId(object.type, object.id),
_id: this._generateEsId(namespace, object.type, object.id),
_type: this._type,
}
},
{
...object.extraDocumentProperties,
... namespace && !this._schema.isNamespaceAgnostic(object.type) && { namespace },
type: object.type,
updated_at: time,
[object.type]: object.attributes,
Expand Down Expand Up @@ -186,11 +190,17 @@ export class SavedObjectsRepository {
*
* @param {string} type
* @param {string} id
* @param {object} [options={}]
* @property {string} [options.namespace]
* @returns {promise}
*/
async delete(type, id) {
async delete(type, id, options = {}) {
const {
namespace
} = options;

const response = await this._writeToCluster('delete', {
id: this._generateEsId(type, id),
id: this._generateEsId(namespace, type, id),
type: this._type,
index: this._index,
refresh: 'wait_for',
Expand Down Expand Up @@ -220,12 +230,12 @@ export class SavedObjectsRepository {
* @property {string} [options.search]
* @property {Array<string>} [options.searchFields] - see Elasticsearch Simple Query String
* Query field argument for more information
* @property {object} [options.filters] - ES Query filters to append
* @property {integer} [options.page=1]
* @property {integer} [options.perPage=20]
* @property {string} [options.sortField]
* @property {string} [options.sortOrder]
* @property {Array<string>} [options.fields]
* @property {string} [options.namespace]
* @returns {promise} - { saved_objects: [{ id, type, version, attributes }], total, per_page, page }
*/
async find(options = {}) {
Expand All @@ -238,7 +248,7 @@ export class SavedObjectsRepository {
sortField,
sortOrder,
fields,
filters,
namespace,
} = options;

if (searchFields && !Array.isArray(searchFields)) {
Expand All @@ -249,10 +259,6 @@ export class SavedObjectsRepository {
throw new TypeError('options.searchFields must be an array');
}

if (filters && !Array.isArray(filters)) {
throw new TypeError('options.filters must be an array');
}

const esOptions = {
index: this._index,
size: perPage,
Expand All @@ -261,13 +267,13 @@ export class SavedObjectsRepository {
ignore: [404],
body: {
version: true,
...getSearchDsl(this._mappings, {
...getSearchDsl(this._mappings, this._schema, {
namespace,
search,
searchFields,
type,
sortField,
sortOrder,
filters
})
}
};
Expand All @@ -292,7 +298,7 @@ export class SavedObjectsRepository {
saved_objects: response.hits.hits.map(hit => {
const { type, updated_at: updatedAt } = hit._source;
return {
id: trimIdPrefix(hit._id, type),
id: trimIdPrefix(this._schema, hit._id, namespace, type),
type,
...updatedAt && { updated_at: updatedAt },
version: hit._version,
Expand All @@ -306,8 +312,8 @@ export class SavedObjectsRepository {
* Returns an array of objects by id
*
* @param {array} objects - an array ids, or an array of objects containing id and optionally type
* @param {object} [options = {}]
* @param {array} [options.extraDocumentProperties = []] - an array of extra properties to return from the underlying document
* @param {object} [options={}]
* @property {string} [options.namespace]
* @returns {promise} - { saved_objects: [{ id, type, version, attributes }] }
* @example
*
Expand All @@ -317,6 +323,10 @@ export class SavedObjectsRepository {
* ])
*/
async bulkGet(objects = [], options = {}) {
const {
namespace
} = options;

if (objects.length === 0) {
return { saved_objects: [] };
}
Expand All @@ -325,16 +335,14 @@ export class SavedObjectsRepository {
index: this._index,
body: {
docs: objects.map(object => ({
_id: this._generateEsId(object.type, object.id),
_id: this._generateEsId(namespace, object.type, object.id),
_type: this._type,
}))
}
});

const { docs } = response;

const { extraDocumentProperties = [] } = options;

return {
saved_objects: docs.map((doc, i) => {
const { id, type } = objects[i];
Expand All @@ -353,9 +361,6 @@ export class SavedObjectsRepository {
type,
...time && { updated_at: time },
version: doc._version,
...extraDocumentProperties
.map(s => ({ [s]: doc._source[s] }))
.reduce((acc, prop) => ({ ...acc, ...prop }), {}),
attributes: {
...doc._source[type],
}
Expand All @@ -371,13 +376,17 @@ export class SavedObjectsRepository {
*
* @param {string} type
* @param {string} id
* @param {object} [options = {}]
* @param {array} [options.extraDocumentProperties = []] - an array of extra properties to return from the underlying document
* @param {object} [options={}]
* @property {string} [options.namespace]
* @returns {promise} - { id, type, version, attributes }
*/
async get(type, id, options = {}) {
const {
namespace
} = options;

const response = await this._callCluster('get', {
id: this._generateEsId(type, id),
id: this._generateEsId(namespace, type, id),
type: this._type,
index: this._index,
ignore: [404]
Expand All @@ -390,18 +399,13 @@ export class SavedObjectsRepository {
throw errors.createGenericNotFoundError(type, id);
}

const { extraDocumentProperties = [] } = options;

const { updated_at: updatedAt } = response._source;

return {
id,
type,
...updatedAt && { updated_at: updatedAt },
version: response._version,
...extraDocumentProperties
.map(s => ({ [s]: response._source[s] }))
.reduce((acc, prop) => ({ ...acc, ...prop }), {}),
attributes: {
...response._source[type],
}
Expand All @@ -415,21 +419,26 @@ export class SavedObjectsRepository {
* @param {string} id
* @param {object} [options={}]
* @property {integer} options.version - ensures version matches that of persisted object
* @param {array} [options.extraDocumentProperties = {}] - an object of extra properties to write into the underlying document
* @property {string} [options.namespace]
* @returns {promise}
*/
async update(type, id, attributes, options = {}) {
const {
version,
namespace
} = options;

const time = this._getCurrentTime();
const response = await this._writeToCluster('update', {
id: this._generateEsId(type, id),
id: this._generateEsId(namespace, type, id),
type: this._type,
index: this._index,
version: options.version,
version,
refresh: 'wait_for',
ignore: [404],
body: {
doc: {
...options.extraDocumentProperties,
...namespace && !this._schema.isNamespaceAgnostic(type) && { namespace },
updated_at: time,
[type]: attributes,
}
Expand Down Expand Up @@ -467,8 +476,9 @@ export class SavedObjectsRepository {
}
}

_generateEsId(type, id) {
return `${type}:${id || uuid.v1()}`;
_generateEsId(namespace, type, id) {
const namespacePrefix = namespace && !this._schema.isNamespaceAgnostic(type) ? `${namespace}:` : '';
return `${namespacePrefix}${type}:${id || uuid.v1()}`;
}

_getCurrentTime() {
Expand Down
Loading

0 comments on commit 7b4575b

Please sign in to comment.