Move tsvb server to new platform (#55310)

This commit is contained in:
Joe Reuter 2020-01-30 16:42:56 +01:00 committed by GitHub
parent c504c40ba9
commit 74b9ed6414
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
218 changed files with 407 additions and 387 deletions

View file

@ -40,7 +40,7 @@
"visTypeMetric": "src/legacy/core_plugins/vis_type_metric",
"visTypeTable": "src/legacy/core_plugins/vis_type_table",
"visTypeTagCloud": "src/legacy/core_plugins/vis_type_tagcloud",
"visTypeTimeseries": "src/legacy/core_plugins/vis_type_timeseries",
"visTypeTimeseries": ["src/legacy/core_plugins/vis_type_timeseries", "src/plugins/vis_type_timeseries"],
"visTypeVega": "src/legacy/core_plugins/vis_type_vega",
"visTypeVislib": "src/legacy/core_plugins/vis_type_vislib",
"visualizations": [

View file

@ -21,7 +21,6 @@ import { resolve } from 'path';
import { Legacy } from 'kibana';
import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types';
import { VisTypeTimeseriesSetup } from '../../../plugins/vis_type_timeseries/server';
const metricsPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
new Plugin({
@ -47,11 +46,6 @@ const metricsPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPlu
},
},
},
init: (server: Legacy.Server) => {
const visTypeTimeSeriesPlugin = server.newPlatform.setup.plugins
.metrics as VisTypeTimeseriesSetup;
visTypeTimeSeriesPlugin.__legacy.registerLegacyAPI({ server });
},
config(Joi: any) {
return Joi.object({
enabled: Joi.boolean().default(true),

View file

@ -36,7 +36,7 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
import { METRIC_TYPES } from '../../../common/metric_types';
import { METRIC_TYPES } from '../../../../../../plugins/vis_type_timeseries/common/metric_types';
export const FilterRatioAgg = props => {
const { series, fields, panel } = props;

View file

@ -23,10 +23,10 @@ import { includes } from 'lodash';
import { injectI18n } from '@kbn/i18n/react';
import { EuiComboBox } from '@elastic/eui';
import { calculateSiblings } from '../lib/calculate_siblings';
import { calculateLabel } from '../../../common/calculate_label';
import { basicAggs } from '../../../common/basic_aggs';
import { toPercentileNumber } from '../../../common/to_percentile_number';
import { METRIC_TYPES } from '../../../common/metric_types';
import { calculateLabel } from '../../../../../../plugins/vis_type_timeseries/common/calculate_label';
import { basicAggs } from '../../../../../../plugins/vis_type_timeseries/common/basic_aggs';
import { toPercentileNumber } from '../../../../../../plugins/vis_type_timeseries/common/to_percentile_number';
import { METRIC_TYPES } from '../../../../../../plugins/vis_type_timeseries/common/metric_types';
function createTypeFilter(restrict, exclude) {
return metric => {

View file

@ -36,7 +36,7 @@ import {
EuiFieldNumber,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { MODEL_TYPES } from '../../../common/model_options';
import { MODEL_TYPES } from '../../../../../../plugins/vis_type_timeseries/common/model_options';
const DEFAULTS = {
model_type: MODEL_TYPES.UNWEIGHTED,

View file

@ -34,7 +34,7 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
import { METRIC_TYPES } from '../../../common/metric_types';
import { METRIC_TYPES } from '../../../../../../plugins/vis_type_timeseries/common/metric_types';
export function StandardAgg(props) {
const { model, panel, series, fields, uiRestrictions } = props;

View file

@ -36,7 +36,7 @@ import {
} from '@elastic/eui';
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
import { PANEL_TYPES } from '../../../common/panel_types';
import { PANEL_TYPES } from '../../../../../../plugins/vis_type_timeseries/common/panel_types';
const isFieldTypeEnabled = (fieldRestrictions, fieldType) =>
fieldRestrictions.length ? fieldRestrictions.includes(fieldType) : true;

View file

@ -42,8 +42,11 @@ import {
AUTO_INTERVAL,
} from './lib/get_interval';
import { i18n } from '@kbn/i18n';
import { TIME_RANGE_DATA_MODES, TIME_RANGE_MODE_KEY } from '../../common/timerange_data_modes';
import { PANEL_TYPES } from '../../common/panel_types';
import {
TIME_RANGE_DATA_MODES,
TIME_RANGE_MODE_KEY,
} from '../../../../../plugins/vis_type_timeseries/common/timerange_data_modes';
import { PANEL_TYPES } from '../../../../../plugins/vis_type_timeseries/common/panel_types';
import { isTimerangeModeEnabled } from '../lib/check_ui_restrictions';
import { VisDataContext } from '../contexts/vis_data_context';
@ -138,8 +141,8 @@ export const IndexPattern = ({ fields, prefix, onChange, disabled, model: _model
</EuiFormRow>
<EuiText size="xs" style={{ margin: 0 }}>
{i18n.translate('visTypeTimeseries.indexPattern.timeRange.hint', {
defaultMessage: `This setting controls the timespan used for matching documents.
"Entire timerange" will match all the documents selected in the timepicker.
defaultMessage: `This setting controls the timespan used for matching documents.
"Entire timerange" will match all the documents selected in the timepicker.
"Last value" will match only the documents for the specified interval from the end of the timerange.`,
})}
</EuiText>

View file

@ -18,7 +18,7 @@
*/
import _ from 'lodash';
import { getLastValue } from '../../../common/get_last_value';
import { getLastValue } from '../../../../../../plugins/vis_type_timeseries/common/get_last_value';
import { createTickFormatter } from './tick_formatter';
import moment from 'moment';

View file

@ -20,7 +20,7 @@ import moment from 'moment';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
import { parseEsInterval } from '../../../../data/public';
import { GTE_INTERVAL_RE } from '../../../common/interval_regexp';
import { GTE_INTERVAL_RE } from '../../../../../../plugins/vis_type_timeseries/common/interval_regexp';
export const AUTO_INTERVAL = 'auto';

View file

@ -19,7 +19,7 @@
import _ from 'lodash';
import { newMetricAggFn } from './new_metric_agg_fn';
import { isBasicAgg } from '../../../common/agg_lookup';
import { isBasicAgg } from '../../../../../../plugins/vis_type_timeseries/common/agg_lookup';
import { handleAdd, handleChange } from './collection_actions';
export const seriesChangeHandler = (props, items) => doc => {

View file

@ -36,7 +36,7 @@ import {
EuiFieldText,
} from '@elastic/eui';
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
import { FIELD_TYPES } from '../../../common/field_types';
import { FIELD_TYPES } from '../../../../../../plugins/vis_type_timeseries/common/field_types';
import { STACKED_OPTIONS } from '../../visualizations/constants';
const DEFAULTS = { terms_direction: 'desc', terms_size: 10, terms_order_by: '_count' };

View file

@ -28,7 +28,7 @@ import { VisPicker } from './vis_picker';
import { PanelConfig } from './panel_config';
import { createBrushHandler } from '../lib/create_brush_handler';
import { fetchFields } from '../lib/fetch_fields';
import { extractIndexPatterns } from '../../common/extract_index_patterns';
import { extractIndexPatterns } from '../../../../../plugins/vis_type_timeseries/common/extract_index_patterns';
import { esKuery } from '../../../../../plugins/data/public';
import { npStart } from 'ui/new_platform';

View file

@ -28,7 +28,7 @@ import {
isGteInterval,
AUTO_INTERVAL,
} from './lib/get_interval';
import { PANEL_TYPES } from '../../common/panel_types';
import { PANEL_TYPES } from '../../../../../plugins/vis_type_timeseries/common/panel_types';
import { start as embeddables } from '../../../embeddable_api/public/np_ready/public/legacy';
const MIN_CHART_HEIGHT = 300;

View file

@ -21,7 +21,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import { EuiTabs, EuiTab } from '@elastic/eui';
import { injectI18n } from '@kbn/i18n/react';
import { PANEL_TYPES } from '../../common/panel_types';
import { PANEL_TYPES } from '../../../../../plugins/vis_type_timeseries/common/panel_types';
function VisPickerItem(props) {
const { label, type, selected } = props;

View file

@ -23,7 +23,7 @@ import { visWithSplits } from '../../vis_with_splits';
import { createTickFormatter } from '../../lib/tick_formatter';
import _, { get, isUndefined, assign, includes } from 'lodash';
import { Gauge } from '../../../visualizations/views/gauge';
import { getLastValue } from '../../../../common/get_last_value';
import { getLastValue } from '../../../../../../../plugins/vis_type_timeseries/common/get_last_value';
function getColors(props) {
const { model, visData } = props;

View file

@ -26,7 +26,7 @@ import { Markdown } from '../../../../../kibana_react/public';
import { ErrorComponent } from '../../error';
import { replaceVars } from '../../lib/replace_vars';
import { convertSeriesToVars } from '../../lib/convert_series_to_vars';
import { isBackgroundInverted } from '../../../../common/set_is_reversed';
import { isBackgroundInverted } from '../../../lib/set_is_reversed';
const getMarkdownId = id => `markdown-${id}`;

View file

@ -23,8 +23,8 @@ import { visWithSplits } from '../../vis_with_splits';
import { createTickFormatter } from '../../lib/tick_formatter';
import _, { get, isUndefined, assign, includes, pick } from 'lodash';
import { Metric } from '../../../visualizations/views/metric';
import { getLastValue } from '../../../../common/get_last_value';
import { isBackgroundInverted } from '../../../../common/set_is_reversed';
import { getLastValue } from '../../../../../../../plugins/vis_type_timeseries/common/get_last_value';
import { isBackgroundInverted } from '../../../lib/set_is_reversed';
function getColors(props) {
const { model, visData } = props;

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { basicAggs } from '../../../../common/basic_aggs';
import { basicAggs } from '../../../../../../../plugins/vis_type_timeseries/common/basic_aggs';
export function isSortable(metric) {
return basicAggs.includes(metric.type);

View file

@ -22,14 +22,14 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { npStart } from 'ui/new_platform';
import { createTickFormatter } from '../../lib/tick_formatter';
import { calculateLabel } from '../../../../common/calculate_label';
import { calculateLabel } from '../../../../../../../plugins/vis_type_timeseries/common/calculate_label';
import { isSortable } from './is_sortable';
import { EuiToolTip, EuiIcon } from '@elastic/eui';
import { replaceVars } from '../../lib/replace_vars';
import { fieldFormats } from '../../../../../../../plugins/data/public';
import { FormattedMessage } from '@kbn/i18n/react';
import { METRIC_TYPES } from '../../../../common/metric_types';
import { METRIC_TYPES } from '../../../../../../../plugins/vis_type_timeseries/common/metric_types';
function getColor(rules, colorKey, value) {
let color;

View file

@ -35,7 +35,7 @@ import {
import { Split } from '../../split';
import { createTextHandler } from '../../lib/create_text_handler';
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
import { PANEL_TYPES } from '../../../../common/panel_types';
import { PANEL_TYPES } from '../../../../../../../plugins/vis_type_timeseries/common/panel_types';
const TimeseriesSeriesUI = injectI18n(function(props) {
const {

View file

@ -34,7 +34,7 @@ import { getAxisLabelString } from '../../lib/get_axis_label_string';
import { getInterval } from '../../lib/get_interval';
import { areFieldsDifferent } from '../../lib/charts';
import { createXaxisFormatter } from '../../lib/create_xaxis_formatter';
import { isBackgroundDark } from '../../../../common/set_is_reversed';
import { isBackgroundDark } from '../../../lib/set_is_reversed';
import { STACKED_OPTIONS } from '../../../visualizations/constants';
export class TimeseriesVisualization extends Component {

View file

@ -19,8 +19,8 @@
import { createTickFormatter } from '../../lib/tick_formatter';
import { TopN } from '../../../visualizations/views/top_n';
import { getLastValue } from '../../../../common/get_last_value';
import { isBackgroundInverted } from '../../../../common/set_is_reversed';
import { getLastValue } from '../../../../../../../plugins/vis_type_timeseries/common/get_last_value';
import { isBackgroundInverted } from '../../../lib/set_is_reversed';
import { replaceVars } from '../../lib/replace_vars';
import PropTypes from 'prop-types';
import React from 'react';

View file

@ -20,7 +20,7 @@
import React from 'react';
import { getDisplayName } from './lib/get_display_name';
import { last, findIndex, first } from 'lodash';
import { calculateLabel } from '../../common/calculate_label';
import { calculateLabel } from '../../../../../plugins/vis_type_timeseries/common/calculate_label';
export function visWithSplits(WrappedComponent) {
function SplitVisComponent(props) {

View file

@ -18,7 +18,10 @@
*/
import { get } from 'lodash';
import { RESTRICTIONS_KEYS, DEFAULT_UI_RESTRICTION } from '../../common/ui_restrictions';
import {
RESTRICTIONS_KEYS,
DEFAULT_UI_RESTRICTION,
} from '../../../../../plugins/vis_type_timeseries/common/ui_restrictions';
/**
* Generic method for checking all types of the UI Restrictions

View file

@ -19,7 +19,7 @@
import { kfetch } from 'ui/kfetch';
import { toastNotifications } from 'ui/notify';
import { i18n } from '@kbn/i18n';
import { extractIndexPatterns } from '../../common/extract_index_patterns';
import { extractIndexPatterns } from '../../../../../plugins/vis_type_timeseries/common/extract_index_patterns';
export async function fetchFields(indexPatterns = ['*']) {
const patterns = Array.isArray(indexPatterns) ? indexPatterns : [indexPatterns];

View file

@ -18,9 +18,9 @@
*/
import color from 'color';
import chrome from '../../../ui/public/chrome';
import { getUISettings } from '../services';
const IS_DARK_THEME = chrome.getUiSettingsClient().get('theme:darkMode');
const isDarkTheme = () => getUISettings().get('theme:darkMode');
/**
* Returns true if the color that is passed has low luminosity
@ -34,7 +34,7 @@ const isColorDark = c => {
* Defaults to checking `theme:darkMode`.
*/
export const isThemeDark = currentTheme => {
let themeIsDark = currentTheme || IS_DARK_THEME;
let themeIsDark = currentTheme || isDarkTheme();
// If passing a string, check the luminosity
if (typeof currentTheme === 'string') {

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { GTE_INTERVAL_RE } from '../../common/interval_regexp';
import { GTE_INTERVAL_RE } from '../../../../../plugins/vis_type_timeseries/common/interval_regexp';
import { i18n } from '@kbn/i18n';
import { parseInterval } from '../../../../../plugins/data/public';

View file

@ -26,7 +26,7 @@ import { metricsRequestHandler } from './request_handler';
// @ts-ignore
import { EditorController } from './editor_controller';
// @ts-ignore
import { PANEL_TYPES } from '../common/panel_types';
import { PANEL_TYPES } from '../../../../plugins/vis_type_timeseries/common/panel_types';
export const metricsVisDefinition = {
name: 'metrics',

View file

@ -21,8 +21,8 @@ import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import classNames from 'classnames';
import { isBackgroundInverted, isBackgroundDark } from '../../../common/set_is_reversed';
import { getLastValue } from '../../../common/get_last_value';
import { isBackgroundInverted, isBackgroundDark } from '../../lib/set_is_reversed';
import { getLastValue } from '../../../../../../plugins/vis_type_timeseries/common/get_last_value';
import { getValueBy } from '../lib/get_value_by';
import { GaugeVis } from './gauge_vis';
import reactcss from 'reactcss';

View file

@ -20,7 +20,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import _ from 'lodash';
import { getLastValue } from '../../../common/get_last_value';
import { getLastValue } from '../../../../../../plugins/vis_type_timeseries/common/get_last_value';
import reactcss from 'reactcss';
import { calculateCoordinates } from '../lib/calculate_coordinates';

View file

@ -19,7 +19,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { getLastValue } from '../../../common/get_last_value';
import { getLastValue } from '../../../../../../plugins/vis_type_timeseries/common/get_last_value';
import reactcss from 'reactcss';
const RENDER_MODES = {

View file

@ -1,44 +0,0 @@
/*
* 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.
*/
// @ts-ignore
import { fieldsRoutes } from './routes/fields';
// @ts-ignore
import { visDataRoutes } from './routes/vis';
// @ts-ignore
import { SearchStrategiesRegister } from './lib/search_strategies/search_strategies_register';
// @ts-ignore
import { getVisData } from './lib/get_vis_data';
import { Framework } from '../../../../plugins/vis_type_timeseries/server';
import { ValidationTelemetryServiceSetup } from '../../../../plugins/vis_type_timeseries/server';
export const init = async (
framework: Framework,
__LEGACY: any,
validationTelemetry: ValidationTelemetryServiceSetup
) => {
const { core } = framework;
const router = core.http.createRouter();
visDataRoutes(router, framework, validationTelemetry);
// [LEGACY_TODO]
fieldsRoutes(__LEGACY.server);
SearchStrategiesRegister.init(__LEGACY.server);
};

View file

@ -1,37 +0,0 @@
/*
* 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 { SearchStrategiesRegister } from './search_strategies/search_strategies_register';
import { uniq } from 'lodash';
import { getIndexPatternObject } from './vis_data/helpers/get_index_pattern';
import { isNestedField } from '../../../../../plugins/data/server';
export async function getFields(req) {
const indexPattern = req.query.index;
const { indexPatternString } = await getIndexPatternObject(req, indexPattern);
const { searchStrategy, capabilities } = await SearchStrategiesRegister.getViableStrategy(
req,
indexPatternString
);
const fields = (
await searchStrategy.getFieldsForWildcard(req, indexPatternString, capabilities)
).filter(field => field.aggregatable && !isNestedField(field));
return uniq(fields, field => field.name);
}

View file

@ -1,30 +0,0 @@
/*
* 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 { IndexPatternsFetcher } from '../../../../../plugins/data/server/';
export const getIndexPatternService = {
assign: 'indexPatternsService',
method(req) {
const dataCluster = req.server.plugins.elasticsearch.getCluster('data');
const callDataCluster = (...args) => {
return dataCluster.callWithRequest(req, ...args);
};
return new IndexPatternsFetcher(callDataCluster);
},
};

View file

@ -1,20 +0,0 @@
/*
* 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 { SearchStrategiesRegister } from './search_strategies_register';

View file

@ -1,42 +0,0 @@
/*
* 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 class AbstractSearchStrategy {
constructor(server, callWithRequestFactory, SearchRequest) {
this.getCallWithRequestInstance = req => callWithRequestFactory(server, req);
this.getSearchRequest = req => {
const callWithRequest = this.getCallWithRequestInstance(req);
return new SearchRequest(req, callWithRequest);
};
}
async getFieldsForWildcard(req, indexPattern) {
const { indexPatternsService } = req.pre;
return await indexPatternsService.getFieldsForWildcard({
pattern: indexPattern,
});
}
checkForViability() {
throw new TypeError('Must override method');
}
}

View file

@ -32,6 +32,13 @@ export type VisTypeTimeseriesConfig = TypeOf<typeof config.schema>;
export { ValidationTelemetryServiceSetup } from './validation_telemetry';
// @ts-ignore
export { AbstractSearchStrategy } from './lib/search_strategies/strategies/abstract_search_strategy';
// @ts-ignore
export { AbstractSearchRequest } from './lib/search_strategies/search_requests/abstract_request';
// @ts-ignore
export { DefaultSearchCapabilities } from './lib/search_strategies/default_search_capabilities';
export function plugin(initializerContext: PluginInitializerContext) {
return new VisTypeTimeseriesPlugin(initializerContext);
}

View file

@ -0,0 +1,89 @@
/*
* 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 { uniq } from 'lodash';
import { first, map } from 'rxjs/operators';
import { KibanaRequest, RequestHandlerContext } from 'kibana/server';
// @ts-ignore
import { getIndexPatternObject } from './vis_data/helpers/get_index_pattern';
import { isNestedField } from '../../../data/server';
import { Framework } from '../plugin';
import { FieldDescriptor, IndexPatternsFetcher } from '../../../data/server';
import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy';
export async function getFields(
requestContext: RequestHandlerContext,
request: KibanaRequest,
framework: Framework,
indexPattern: string
) {
// NOTE / TODO: This facade has been put in place to make migrating to the New Platform easier. It
// removes the need to refactor many layers of dependencies on "req", and instead just augments the top
// level object passed from here. The layers should be refactored fully at some point, but for now
// this works and we are still using the New Platform services for these vis data portions.
const reqFacade: ReqFacade = {
...request,
framework,
payload: {},
pre: {
indexPatternsService: new IndexPatternsFetcher(
requestContext.core.elasticsearch.dataClient.callAsCurrentUser
),
},
getUiSettingsService: () => requestContext.core.uiSettings.client,
getSavedObjectsClient: () => requestContext.core.savedObjects.client,
server: {
plugins: {
elasticsearch: {
getCluster: () => {
return {
callWithRequest: async (req: any, endpoint: string, params: any) => {
return await requestContext.core.elasticsearch.dataClient.callAsCurrentUser(
endpoint,
params
);
},
};
},
},
},
},
getEsShardTimeout: async () => {
return await framework.globalConfig$
.pipe(
first(),
map(config => config.elasticsearch.shardTimeout.asMilliseconds())
)
.toPromise();
},
};
const { indexPatternString } = await getIndexPatternObject(reqFacade, indexPattern);
const {
searchStrategy,
capabilities,
} = (await framework.searchStrategyRegistry.getViableStrategy(reqFacade, indexPatternString))!;
const fields = ((await searchStrategy.getFieldsForWildcard(
reqFacade,
indexPatternString,
capabilities
)) as FieldDescriptor[]).filter(field => field.aggregatable && !isNestedField(field));
return uniq(fields, field => field.name);
}

View file

@ -17,11 +17,12 @@
* under the License.
*/
import { RequestHandlerContext } from 'src/core/server';
import { FakeRequest, RequestHandlerContext } from 'kibana/server';
import _ from 'lodash';
import { first, map } from 'rxjs/operators';
import { getPanelData } from './vis_data/get_panel_data';
import { Framework } from '../../../../../plugins/vis_type_timeseries/server';
import { Framework } from '../index';
import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy';
interface GetVisDataResponse {
[key: string]: GetVisDataPanel;
@ -56,15 +57,18 @@ export type GetVisData = (
export function getVisData(
requestContext: RequestHandlerContext,
options: GetVisDataOptions,
request: FakeRequest & { body: GetVisDataOptions },
framework: Framework
): Promise<GetVisDataResponse> {
// NOTE / TODO: This facade has been put in place to make migrating to the New Platform easier. It
// removes the need to refactor many layers of dependencies on "req", and instead just augments the top
// level object passed from here. The layers should be refactored fully at some point, but for now
// this works and we are still using the New Platform services for these vis data portions.
const reqFacade: any = {
payload: options,
const reqFacade: ReqFacade = {
...request,
framework,
pre: {},
payload: request.body,
getUiSettingsService: () => requestContext.core.uiSettings.client,
getSavedObjectsClient: () => requestContext.core.savedObjects.client,
server: {
@ -92,7 +96,7 @@ export function getVisData(
.toPromise();
},
};
const promises = reqFacade.payload.panels.map(getPanelData(reqFacade));
const promises = (reqFacade.payload as GetVisDataOptions).panels.map(getPanelData(reqFacade));
return Promise.all(promises).then(res => {
return res.reduce((acc, data) => {
return _.assign(acc as any, data);

View file

@ -17,5 +17,4 @@
* under the License.
*/
export { init } from './init';
export { getVisData, GetVisData, GetVisDataOptions } from './lib/get_vis_data';
export { SearchStrategyRegistry } from './search_strategy_registry';

View file

@ -16,10 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import { SearchStrategiesRegister } from './search_strategies_register';
import { SearchStrategyRegistry } from './search_strategy_registry';
// @ts-ignore
import { AbstractSearchStrategy } from './strategies/abstract_search_strategy';
// @ts-ignore
import { DefaultSearchStrategy } from './strategies/default_search_strategy';
import { AbstractSearchRequest } from './searh_requests/abstract_request';
// @ts-ignore
import { DefaultSearchCapabilities } from './default_search_capabilities';
class MockSearchStrategy extends AbstractSearchStrategy {
@ -31,34 +34,21 @@ class MockSearchStrategy extends AbstractSearchStrategy {
}
}
describe('SearchStrategiesRegister', () => {
let server;
let strategies;
let anotherSearchStrategy;
describe('SearchStrategyRegister', () => {
let registry: SearchStrategyRegistry;
beforeAll(() => {
server = {
expose: jest.fn((strategy, func) => {
server[strategy] = func;
}),
};
strategies = [
['AbstractSearchStrategy', AbstractSearchStrategy],
['AbstractSearchRequest', AbstractSearchRequest],
['DefaultSearchCapabilities', DefaultSearchCapabilities],
['addSearchStrategy', expect.any(Function)],
];
SearchStrategiesRegister.init(server);
registry = new SearchStrategyRegistry();
});
test('should init strategies register', () => {
expect(server.expose.mock.calls).toEqual(strategies);
expect(server.addSearchStrategy()[0] instanceof DefaultSearchStrategy).toBe(true);
expect(
registry.addStrategy({} as AbstractSearchStrategy)[0] instanceof DefaultSearchStrategy
).toBe(true);
});
test('should not add a strategy if it is not an instance of AbstractSearchStrategy', () => {
const addedStrategies = server.addSearchStrategy({});
const addedStrategies = registry.addStrategy({} as AbstractSearchStrategy);
expect(addedStrategies.length).toEqual(1);
expect(addedStrategies[0] instanceof DefaultSearchStrategy).toBe(true);
@ -68,18 +58,15 @@ describe('SearchStrategiesRegister', () => {
const req = {};
const indexPattern = '*';
const { searchStrategy, capabilities } = await SearchStrategiesRegister.getViableStrategy(
req,
indexPattern
);
const { searchStrategy, capabilities } = (await registry.getViableStrategy(req, indexPattern))!;
expect(searchStrategy instanceof DefaultSearchStrategy).toBe(true);
expect(capabilities instanceof DefaultSearchCapabilities).toBe(true);
});
test('should add a strategy if it is an instance of AbstractSearchStrategy', () => {
anotherSearchStrategy = new MockSearchStrategy();
const addedStrategies = server.addSearchStrategy(anotherSearchStrategy);
const anotherSearchStrategy = new MockSearchStrategy({}, {} as any, {});
const addedStrategies = registry.addStrategy(anotherSearchStrategy);
expect(addedStrategies.length).toEqual(2);
expect(addedStrategies[0] instanceof AbstractSearchStrategy).toBe(true);
@ -88,13 +75,12 @@ describe('SearchStrategiesRegister', () => {
test('should return a MockSearchStrategy instance', async () => {
const req = {};
const indexPattern = '*';
const anotherSearchStrategy = new MockSearchStrategy({}, {} as any, {});
registry.addStrategy(anotherSearchStrategy);
const { searchStrategy, capabilities } = await SearchStrategiesRegister.getViableStrategy(
req,
indexPattern
);
const { searchStrategy, capabilities } = (await registry.getViableStrategy(req, indexPattern))!;
expect(searchStrategy instanceof AbstractSearchStrategy).toBe(true);
expect(searchStrategy instanceof MockSearchStrategy).toBe(true);
expect(capabilities).toEqual({});
});
});

View file

@ -16,34 +16,32 @@
* specific language governing permissions and limitations
* under the License.
*/
import { AbstractSearchStrategy } from './strategies/abstract_search_strategy';
import { AbstractSearchRequest } from './searh_requests/abstract_request';
import { DefaultSearchStrategy } from './strategies/default_search_strategy';
import { DefaultSearchCapabilities } from './default_search_capabilities';
import { AbstractSearchStrategy } from './strategies/abstract_search_strategy';
// @ts-ignore
import { DefaultSearchStrategy } from './strategies/default_search_strategy';
// @ts-ignore
import { extractIndexPatterns } from '../../../common/extract_index_patterns';
const strategies = [];
export type RequestFacade = any;
export type Panel = any;
const addStrategy = searchStrategy => {
if (searchStrategy instanceof AbstractSearchStrategy) {
strategies.unshift(searchStrategy);
}
return strategies;
};
export class SearchStrategyRegistry {
private strategies: AbstractSearchStrategy[] = [];
export class SearchStrategiesRegister {
static init(server) {
server.expose('AbstractSearchStrategy', AbstractSearchStrategy);
server.expose('AbstractSearchRequest', AbstractSearchRequest);
server.expose('DefaultSearchCapabilities', DefaultSearchCapabilities);
server.expose('addSearchStrategy', searchStrategy => addStrategy(searchStrategy));
addStrategy(new DefaultSearchStrategy(server));
constructor() {
this.addStrategy(new DefaultSearchStrategy());
}
static async getViableStrategy(req, indexPattern) {
for (const searchStrategy of strategies) {
public addStrategy(searchStrategy: AbstractSearchStrategy) {
if (searchStrategy instanceof AbstractSearchStrategy) {
this.strategies.unshift(searchStrategy);
}
return this.strategies;
}
async getViableStrategy(req: RequestFacade, indexPattern: string) {
for (const searchStrategy of this.strategies) {
const { isViable, capabilities } = await searchStrategy.checkForViability(req, indexPattern);
if (isViable) {
@ -55,9 +53,9 @@ export class SearchStrategiesRegister {
}
}
static async getViableStrategyForPanel(req, panel) {
async getViableStrategyForPanel(req: RequestFacade, panel: Panel) {
const indexPattern = extractIndexPatterns(panel).join(',');
return SearchStrategiesRegister.getViableStrategy(req, indexPattern);
return this.getViableStrategy(req, indexPattern);
}
}

View file

@ -0,0 +1,87 @@
/*
* 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 {
APICaller,
FakeRequest,
IUiSettingsClient,
SavedObjectsClientContract,
} from 'kibana/server';
import { Framework } from '../../../plugin';
import { IndexPatternsFetcher } from '../../../../../data/server';
/**
* ReqFacade is a regular KibanaRequest object extended with additional service
* references to ensure backwards compatibility for existing integrations.
*
* This will be replaced by standard KibanaRequest and RequestContext objects in a later version.
*/
export type ReqFacade = FakeRequest & {
framework: Framework;
payload: unknown;
pre: {
indexPatternsService?: IndexPatternsFetcher;
};
getUiSettingsService: () => IUiSettingsClient;
getSavedObjectsClient: () => SavedObjectsClientContract;
server: {
plugins: {
elasticsearch: {
getCluster: () => {
callWithRequest: (req: ReqFacade, endpoint: string, params: any) => Promise<any>;
};
};
};
};
getEsShardTimeout: () => Promise<number>;
};
export class AbstractSearchStrategy {
public getCallWithRequestInstance: (req: ReqFacade) => APICaller;
public getSearchRequest: (req: ReqFacade) => any;
constructor(
server: any,
callWithRequestFactory: (server: any, req: ReqFacade) => APICaller,
SearchRequest: any
) {
this.getCallWithRequestInstance = req => callWithRequestFactory(server, req);
this.getSearchRequest = req => {
const callWithRequest = this.getCallWithRequestInstance(req);
return new SearchRequest(req, callWithRequest);
};
}
async getFieldsForWildcard(req: ReqFacade, indexPattern: string, capabilities: any) {
const { indexPatternsService } = req.pre;
return await indexPatternsService!.getFieldsForWildcard({
pattern: indexPattern,
});
}
checkForViability(
req: ReqFacade,
indexPattern: string
): { isViable: boolean; capabilities: any } {
throw new TypeError('Must override method');
}
}

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { AbstractSearchStrategy } from './abstract_search_strategy';
import { SearchRequest } from '../searh_requests/search_request';
import { SearchRequest } from '../search_requests/search_request';
import { DefaultSearchCapabilities } from '../default_search_capabilities';
const callWithRequestFactory = (server, request) => {

View file

@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
import { handleAnnotationResponse } from './response_processors/annotations/';
import { getAnnotationRequestParams } from './annorations/get_request_params';
import { handleAnnotationResponse } from './response_processors/annotations';
import { getAnnotationRequestParams } from './annotations/get_request_params';
import { getLastSeriesTimestamp } from './helpers/timestamp';
function validAnnotation(annotation) {

View file

@ -20,15 +20,14 @@ import { getSeriesRequestParams } from './series/get_request_params';
import { handleResponseBody } from './series/handle_response_body';
import { handleErrorResponse } from './handle_error_response';
import { getAnnotations } from './get_annotations';
import { SearchStrategiesRegister } from '../search_strategies/search_strategies_register';
import { getEsQueryConfig } from './helpers/get_es_query_uisettings';
import { getActiveSeries } from './helpers/get_active_series';
export async function getSeriesData(req, panel) {
const { searchStrategy, capabilities } = await SearchStrategiesRegister.getViableStrategyForPanel(
req,
panel
);
const {
searchStrategy,
capabilities,
} = await req.framework.searchStrategyRegistry.getViableStrategyForPanel(req, panel);
const searchRequest = searchStrategy.getSearchRequest(req);
const esQueryConfig = await getEsQueryConfig(req);
const meta = {

View file

@ -20,16 +20,16 @@ import { buildRequestBody } from './table/build_request_body';
import { handleErrorResponse } from './handle_error_response';
import { get } from 'lodash';
import { processBucket } from './table/process_bucket';
import { SearchStrategiesRegister } from '../search_strategies/search_strategies_register';
import { getEsQueryConfig } from './helpers/get_es_query_uisettings';
import { getIndexPatternObject } from './helpers/get_index_pattern';
export async function getTableData(req, panel) {
const panelIndexPattern = panel.index_pattern;
const { searchStrategy, capabilities } = await SearchStrategiesRegister.getViableStrategy(
req,
panelIndexPattern
);
const {
searchStrategy,
capabilities,
} = await req.framework.searchStrategyRegistry.getViableStrategy(req, panelIndexPattern);
const searchRequest = searchStrategy.getSearchRequest(req);
const esQueryConfig = await getEsQueryConfig(req);
const { indexPatternObject } = await getIndexPatternObject(req, panelIndexPattern);

View file

@ -24,7 +24,7 @@ import {
convertIntervalToUnit,
ASCENDING_UNIT_ORDER,
} from './unit_to_seconds';
import { getTimerangeDuration } from '../helpers/get_timerange';
import { getTimerangeDuration } from './get_timerange';
import { INTERVAL_STRING_RE, GTE_INTERVAL_RE } from '../../../../common/interval_regexp';
const calculateBucketData = (timeInterval, capabilities) => {

Some files were not shown because too many files have changed in this diff Show more