Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move canvas interpreter to OSS #25711

Merged
merged 12 commits into from
Nov 20, 2018
65 changes: 65 additions & 0 deletions packages/kbn-interpreter/common/lib/paths_registry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

class PathsRegistry {
ppisljar marked this conversation as resolved.
Show resolved Hide resolved

constructor() {
this.paths = new Map();
}

register = (type, paths) => {
if (!type) {
throw new Error(`Register requires a type`);
}
const lowerCaseType = type.toLowerCase();

const pathArray = Array.isArray(paths) ? paths : [paths];
if (!this.paths.has(lowerCaseType)) {
this.paths.set(lowerCaseType, []);
}

pathArray.forEach(p => {
this.paths.get(lowerCaseType).push(p);
});
};

registerAll = (paths) => {
Object.keys(paths).forEach(type => {
this.register(type, paths[type]);
});
};

toArray = () => {
return [...this.paths.values()];
};

get = (type) => {
if (!type) {
return [];
}
const lowerCaseType = type.toLowerCase();
return this.paths.has(lowerCaseType) ? this.paths.get(lowerCaseType) : [];
};

reset = () => {
this.paths.clear();
};
}

export const pathsRegistry = new PathsRegistry();
45 changes: 14 additions & 31 deletions packages/kbn-interpreter/public/browser_registries.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,33 @@

import chrome from 'ui/chrome';
import $script from 'scriptjs';
import { typesRegistry } from '@kbn/interpreter/common/lib/types_registry';
import {
argTypeRegistry,
datasourceRegistry,
transformRegistry,
modelRegistry,
viewRegistry,
} from '../../../x-pack/plugins/canvas/public/expression_types/index';
import { elementsRegistry } from '../../../x-pack/plugins/canvas/public/lib/elements_registry';
import { renderFunctionsRegistry } from '../../../x-pack/plugins/canvas/public/lib/render_functions_registry';
import { functionsRegistry as browserFunctions } from '../../../x-pack/plugins/canvas/public/lib/functions_registry';
import { loadPrivateBrowserFunctions } from '../../../x-pack/plugins/canvas/public/lib/load_private_browser_functions';

const registries = {
browserFunctions: browserFunctions,
commonFunctions: browserFunctions,
elements: elementsRegistry,
types: typesRegistry,
renderers: renderFunctionsRegistry,
transformUIs: transformRegistry,
datasourceUIs: datasourceRegistry,
modelUIs: modelRegistry,
viewUIs: viewRegistry,
argumentUIs: argTypeRegistry,
};

let resolve = null;
let called = false;

const populatePromise = new Promise(_resolve => {
let populatePromise = new Promise(_resolve => {
resolve = _resolve;
});

export const getBrowserRegistries = () => {
return populatePromise;
};

export const populateBrowserRegistries = () => {
if (called) throw new Error('function should only be called once per process');
export const populateBrowserRegistries = (registries) => {
if (called) {
ppisljar marked this conversation as resolved.
Show resolved Hide resolved
const oldPromise = populatePromise;
let newResolve;
populatePromise = new Promise(_resolve => {
newResolve = _resolve;
});
return oldPromise.then(() => {
resolve = newResolve;
called = false;
return populateBrowserRegistries(registries);
});
}
called = true;

// loadPrivateBrowserFunctions is sync. No biggie.
loadPrivateBrowserFunctions();

const remainingTypes = Object.keys(registries);
const populatedTypes = {};

Expand Down
44 changes: 44 additions & 0 deletions packages/kbn-interpreter/server/get_plugin_paths.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import fs from 'fs';
import { resolve } from 'path';
import { promisify } from 'util';
import { flatten } from 'lodash';
import { pathsRegistry } from '../common/lib/paths_registry';

const readdir = promisify(fs.readdir);

export const getPluginPaths = type => {
const typePaths = pathsRegistry.get(type);
if (!typePaths) {
throw new Error(`Unknown type: ${type}`);
}

return Promise.all(typePaths.map(path => {

// Get the full path of all files in the directory
return readdir(path).then(files => files.map(file => {
if (!file.endsWith('.js')) {
return;
}
return resolve(path, file);
}).filter(path => path)).catch();
Copy link
Member

Choose a reason for hiding this comment

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

nit: I still find the filter(path => path) confusing here -- had to reread the code a couple times to understand what it was doing. You could use reduce instead to avoid it altogether:

    return readdir(path)
      .then(files => {
        return files.reduce((acc, file) => {
          if (file.endsWith('.js')) {
            acc.push(resolve(path, file));
          }
          return acc;
        }, []);
      })
      .catch();

})).then(flatten);
};
22 changes: 22 additions & 0 deletions packages/kbn-interpreter/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { populateServerRegistries, getServerRegistries } from './server_registries';

export { populateServerRegistries, getServerRegistries };
Copy link
Member

Choose a reason for hiding this comment

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

From what I can tell, we aren't importing directly from @kbn/interpreter/server anywhere, so this index file isn't doing much. I'd propose we either:

  1. Remove this file completely, or
  2. Export getPluginPaths from this file too, then change all of our imports to point to @kbn/interpreter/server.

Copy link
Member Author

Choose a reason for hiding this comment

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

removing the file

11 changes: 9 additions & 2 deletions packages/kbn-interpreter/server/server_registries.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import { typesRegistry } from '../common/lib/types_registry';
import { functionsRegistry as serverFunctions } from '../common/lib/functions_registry';
import { getPluginPaths } from '../../../x-pack/plugins/canvas/server/lib/get_plugin_paths';
import { getPluginPaths } from './get_plugin_paths';

const registries = {
serverFunctions: serverFunctions,
Expand All @@ -46,6 +46,8 @@ export const populateServerRegistries = types => {
const remainingTypes = types;
const populatedTypes = {};

const globalKeys = Object.keys(global);

const loadType = () => {
const type = remainingTypes.pop();
getPluginPaths(type).then(paths => {
Expand All @@ -56,7 +58,12 @@ export const populateServerRegistries = types => {
require(path);
});

global.canvas = undefined;
Object.keys(global).forEach(key => {
ppisljar marked this conversation as resolved.
Show resolved Hide resolved
if (!globalKeys.includes(key)) {
delete global[key];
}
});

populatedTypes[type] = registries[type];
if (remainingTypes.length) loadType();
else resolve(populatedTypes);
Expand Down
9 changes: 0 additions & 9 deletions packages/kbn-interpreter/tsconfig.json

This file was deleted.

21 changes: 21 additions & 0 deletions src/core_plugins/interpreter/common/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export const SECURITY_AUTH_MESSAGE = 'Authentication failed';
export const API_ROUTE = '/api/canvas';
5 changes: 5 additions & 0 deletions src/core_plugins/interpreter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import { resolve } from 'path';
import init from './init';
import { pathsRegistry } from '@kbn/interpreter/common/lib/paths_registry';
import { pluginPaths } from './plugin_paths';

export default function (kibana) {
return new kibana.Plugin({
Expand All @@ -30,6 +32,9 @@ export default function (kibana) {
'plugins/interpreter/load_browser_plugins.js',
],
},
preInit: () => {
pathsRegistry.registerAll(pluginPaths);
},
init,
});
}
Expand Down
7 changes: 2 additions & 5 deletions src/core_plugins/interpreter/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@

import { routes } from './server/routes';
import { functionsRegistry } from '@kbn/interpreter/common/lib/functions_registry';
import { pathsRegistry } from '@kbn/interpreter/common/lib/paths_registry';
import { loadServerPlugins } from '@kbn/interpreter/server/load_server_plugins';
import { pluginPaths } from './plugin_paths';
import { populateServerRegistries } from '@kbn/interpreter/server/server_registries';

export default function (server /*options*/) {
server.injectUiAppVars('canvas', () => {
Expand All @@ -39,6 +37,5 @@ export default function (server /*options*/) {
};
});

pathsRegistry.registerAll(pluginPaths);
loadServerPlugins().then(() => routes(server));
populateServerRegistries(['serverFunctions', 'types']).then(() => routes(server));
}
30 changes: 30 additions & 0 deletions src/core_plugins/interpreter/public/load_browser_plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { populateBrowserRegistries } from '@kbn/interpreter/public/browser_registries';
import { typesRegistry } from '@kbn/interpreter/common/lib/types_registry';
import { functionsRegistry } from '@kbn/interpreter/common/lib/functions_registry';

const types = {
commonFunctions: functionsRegistry,
browserFunctions: functionsRegistry,
types: typesRegistry
};

populateBrowserRegistries(types);
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import expect from 'expect.js';
import { createHandlers } from '../create_handlers';
import { SECURITY_AUTH_MESSAGE } from '../../../../../../x-pack/plugins/canvas/common/lib/constants';
import { SECURITY_AUTH_MESSAGE } from '../../../common/constants';

let securityMode = 'pass';
let isSecurityAvailable = true;
Expand Down
2 changes: 1 addition & 1 deletion src/core_plugins/interpreter/server/lib/create_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
*/

import boom from 'boom';
import { SECURITY_AUTH_MESSAGE } from '../../../../../x-pack/plugins/canvas/common/lib/constants';
import { isSecurityEnabled } from './feature_check';
import { SECURITY_AUTH_MESSAGE } from '../../common/constants';

export const createHandlers = (request, server) => {
const { callWithRequest } = server.plugins.elasticsearch.getCluster('data');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import fs from 'fs';
import ss from 'stream-stream';
import { getPluginPaths } from '../../../../../x-pack/plugins/canvas/server/lib/get_plugin_paths';
import { getPluginPaths } from '@kbn/interpreter/server/get_plugin_paths';

export const getPluginStream = type => {
const stream = ss({
Expand Down
2 changes: 1 addition & 1 deletion src/core_plugins/interpreter/server/lib/get_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import boom from 'boom';
import { API_ROUTE } from '../../../../../x-pack/plugins/canvas/common/lib/constants';
import { API_ROUTE } from '../../common/constants';

export function getRequest(server, { headers }) {
const url = `${API_ROUTE}/ping`;
Expand Down
7 changes: 1 addition & 6 deletions src/core_plugins/interpreter/server/routes/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,14 @@
*/

import { getPluginStream } from '../lib/get_plugin_stream';
import { pluginPaths } from '../../../../../x-pack/plugins/canvas/server/lib/plugin_paths';

export function plugins(server) {
server.route({
method: 'GET',
path: '/api/canvas/plugins',
handler: function (request, h) {
handler: function (request) {
const { type } = request.query;

if (!pluginPaths[type]) {
return h.response({ error: 'Invalid type' }).code(400);
ppisljar marked this conversation as resolved.
Show resolved Hide resolved
}

return getPluginStream(type);
},
config: {
Expand Down
2 changes: 1 addition & 1 deletion src/core_plugins/interpreter/server/routes/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { browser } from '../lib/route_expression/browser';
import { thread } from '../lib/route_expression/thread/index';
import { server as serverEnv } from '../lib/route_expression/server';
import { getRequest } from '../lib/get_request';
import { API_ROUTE } from '../../../../../x-pack/plugins/canvas/common/lib/constants';
import { API_ROUTE } from '../../common/constants';

async function getModifiedRequest(server, socket) {
try {
Expand Down
Loading