Skip to content

Commit

Permalink
Merge branch 'master' into security/support-deprecated-roles
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine committed Feb 28, 2020
2 parents a91b341 + 967bef7 commit 7ac1293
Show file tree
Hide file tree
Showing 421 changed files with 3,765 additions and 7,414 deletions.
Expand Up @@ -16,6 +16,8 @@ export interface SavedObjectsServiceSetup

When plugins access the Saved Objects client, a new client is created using the factory provided to `setClientFactory` and wrapped by all wrappers registered through `addClientWrapper`<!-- -->.

All the setup APIs will throw if called after the service has started, and therefor cannot be used from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated.

## Example 1


Expand Down
8 changes: 7 additions & 1 deletion src/core/MIGRATION_EXAMPLES.md
Expand Up @@ -917,4 +917,10 @@ Would be converted to:
```typescript
const migration: SavedObjectMigrationFn = (doc, { log }) => {...}
```
```
### Remarks
The `registerType` API will throw if called after the service has started, and therefor cannot be used from
legacy plugin code. Legacy plugins should use the legacy savedObjects service and the legacy way to register
saved object types until migrated.
30 changes: 30 additions & 0 deletions src/core/server/saved_objects/saved_objects_service.test.ts
Expand Up @@ -232,6 +232,36 @@ describe('SavedObjectsService', () => {
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1);
});

it('throws when calling setup APIs once started', async () => {
const coreContext = createCoreContext({ skipMigration: false });
const soService = new SavedObjectsService(coreContext);
const setup = await soService.setup(createSetupDeps());
await soService.start({});

expect(() => {
setup.setClientFactoryProvider(jest.fn());
}).toThrowErrorMatchingInlineSnapshot(
`"cannot call \`setClientFactoryProvider\` after service startup."`
);

expect(() => {
setup.addClientWrapper(0, 'dummy', jest.fn());
}).toThrowErrorMatchingInlineSnapshot(
`"cannot call \`addClientWrapper\` after service startup."`
);

expect(() => {
setup.registerType({
name: 'someType',
hidden: false,
namespaceAgnostic: false,
mappings: { properties: {} },
});
}).toThrowErrorMatchingInlineSnapshot(
`"cannot call \`registerType\` after service startup."`
);
});

describe('#getTypeRegistry', () => {
it('returns the internal type registry of the service', async () => {
const coreContext = createCoreContext({ skipMigration: false });
Expand Down
15 changes: 15 additions & 0 deletions src/core/server/saved_objects/saved_objects_service.ts
Expand Up @@ -61,6 +61,9 @@ import { registerRoutes } from './routes';
* the factory provided to `setClientFactory` and wrapped by all wrappers
* registered through `addClientWrapper`.
*
* All the setup APIs will throw if called after the service has started, and therefor cannot be used
* from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated.
*
* @example
* ```ts
* import { SavedObjectsClient, CoreSetup } from 'src/core/server';
Expand Down Expand Up @@ -275,6 +278,7 @@ export class SavedObjectsService
private migrator$ = new Subject<KibanaMigrator>();
private typeRegistry = new SavedObjectTypeRegistry();
private validations: PropertyValidators = {};
private started = false;

constructor(private readonly coreContext: CoreContext) {
this.logger = coreContext.logger.get('savedobjects-service');
Expand Down Expand Up @@ -316,19 +320,28 @@ export class SavedObjectsService

return {
setClientFactoryProvider: provider => {
if (this.started) {
throw new Error('cannot call `setClientFactoryProvider` after service startup.');
}
if (this.clientFactoryProvider) {
throw new Error('custom client factory is already set, and can only be set once');
}
this.clientFactoryProvider = provider;
},
addClientWrapper: (priority, id, factory) => {
if (this.started) {
throw new Error('cannot call `addClientWrapper` after service startup.');
}
this.clientFactoryWrappers.push({
priority,
id,
factory,
});
},
registerType: type => {
if (this.started) {
throw new Error('cannot call `registerType` after service startup.');
}
this.typeRegistry.registerType(type);
},
};
Expand Down Expand Up @@ -415,6 +428,8 @@ export class SavedObjectsService
clientProvider.addClientWrapperFactory(priority, id, factory);
});

this.started = true;

return {
migrator,
clientProvider,
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/apm_oss/server/index.ts
Expand Up @@ -38,4 +38,4 @@ export function plugin(initializerContext: PluginInitializerContext) {

export type APMOSSConfig = TypeOf<typeof config.schema>;

export { APMOSSPlugin as Plugin };
export { APMOSSPluginSetup } from './plugin';
6 changes: 5 additions & 1 deletion src/plugins/apm_oss/server/plugin.ts
Expand Up @@ -20,7 +20,7 @@ import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/server';
import { Observable } from 'rxjs';
import { APMOSSConfig } from './';

export class APMOSSPlugin implements Plugin<{ config$: Observable<APMOSSConfig> }> {
export class APMOSSPlugin implements Plugin<APMOSSPluginSetup> {
constructor(private readonly initContext: PluginInitializerContext) {
this.initContext = initContext;
}
Expand All @@ -36,3 +36,7 @@ export class APMOSSPlugin implements Plugin<{ config$: Observable<APMOSSConfig>
start() {}
stop() {}
}

export interface APMOSSPluginSetup {
config$: Observable<APMOSSConfig>;
}
Expand Up @@ -20,7 +20,8 @@
import { TimedItemBuffer } from '../timed_item_buffer';
import { runItemBufferTests } from './run_item_buffer_tests';

describe('TimedItemBuffer', () => {
// FLAKY: https://github.com/elastic/kibana/issues/58662
describe.skip('TimedItemBuffer', () => {
runItemBufferTests(TimedItemBuffer);

test('does not do unnecessary flushes', async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/functional/apps/context/_filters.js
Expand Up @@ -64,7 +64,7 @@ export default function({ getService, getPageObjects }) {
await filterBar.toggleFilterEnabled(TEST_ANCHOR_FILTER_FIELD);
await PageObjects.context.waitUntilContextLoadingHasFinished();

retry.try(async () => {
await retry.try(async () => {
expect(
await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, false)
).to.be(true);
Expand Down
3 changes: 2 additions & 1 deletion test/functional/apps/context/_size.js
Expand Up @@ -30,7 +30,8 @@ export default function({ getService, getPageObjects }) {
const docTable = getService('docTable');
const PageObjects = getPageObjects(['context']);

describe('context size', function contextSize() {
// FLAKY: https://github.com/elastic/kibana/issues/53888
describe.skip('context size', function contextSize() {
before(async function() {
await kibanaServer.uiSettings.update({
'context:defaultSize': `${TEST_DEFAULT_CONTEXT_SIZE}`,
Expand Down
2 changes: 1 addition & 1 deletion test/functional/apps/dashboard/panel_expand_toggle.js
Expand Up @@ -56,7 +56,7 @@ export default function({ getService, getPageObjects }) {

// Add a retry to fix https://github.com/elastic/kibana/issues/14574. Perhaps the recent changes to this
// being a CSS update is causing the UI to change slower than grabbing the panels?
retry.try(async () => {
await retry.try(async () => {
const panelCountAfterMaxThenMinimize = await PageObjects.dashboard.getPanelCount();
expect(panelCountAfterMaxThenMinimize).to.be(panelCount);
});
Expand Down
4 changes: 2 additions & 2 deletions test/functional/apps/visualize/_tsvb_markdown.ts
Expand Up @@ -121,7 +121,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
await visualBuilder.markdownSwitchSubTab('data');
await visualBuilder.cloneSeries();

retry.try(async function seriesCountCheck() {
await retry.try(async function seriesCountCheck() {
const seriesLength = (await visualBuilder.getSeries()).length;
expect(seriesLength).to.be.equal(2);
});
Expand All @@ -131,7 +131,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
await visualBuilder.markdownSwitchSubTab('data');
await visualBuilder.createNewAgg();

retry.try(async function aggregationCountCheck() {
await retry.try(async function aggregationCountCheck() {
const aggregationLength = await visualBuilder.getAggregationCount();
expect(aggregationLength).to.be.equal(2);
});
Expand Down
2 changes: 1 addition & 1 deletion x-pack/.i18nrc.json
Expand Up @@ -26,7 +26,7 @@
"xpack.logstash": "legacy/plugins/logstash",
"xpack.main": "legacy/plugins/xpack_main",
"xpack.maps": "legacy/plugins/maps",
"xpack.ml": "legacy/plugins/ml",
"xpack.ml": ["plugins/ml", "legacy/plugins/ml"],
"xpack.monitoring": "legacy/plugins/monitoring",
"xpack.remoteClusters": "plugins/remote_clusters",
"xpack.reporting": ["plugins/reporting", "legacy/plugins/reporting"],
Expand Down
16 changes: 12 additions & 4 deletions x-pack/legacy/plugins/apm/readme.md
Expand Up @@ -74,21 +74,29 @@ node scripts/jest.js plugins/apm --updateSnapshot
### Functional tests

**Start server**
`node scripts/functional_tests_server --config x-pack/test/functional/config.js`
```
node scripts/functional_tests_server --config x-pack/test/functional/config.js
```

**Run tests**
`node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs'`
```
node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs'
```

APM tests are located in `x-pack/test/functional/apps/apm`.
For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme)

### API integration tests

**Start server**
`node scripts/functional_tests_server --config x-pack/test/api_integration/config.js`
```
node scripts/functional_tests_server --config x-pack/test/api_integration/config.js
```

**Run tests**
`node scripts/functional_test_runner --config x-pack/test/api_integration/config.js --grep='APM specs'`
```
node scripts/functional_test_runner --config x-pack/test/api_integration/config.js --grep='APM specs'
```

APM tests are located in `x-pack/test/api_integration/apis/apm`.
For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme)
Expand Down
21 changes: 15 additions & 6 deletions x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js
Expand Up @@ -21,13 +21,17 @@ export class ESAggMetricField extends AbstractField {
}

getName() {
return this._source.formatMetricKey(this.getAggType(), this.getESDocFieldName());
return this._source.getAggKey(this.getAggType(), this.getRootName());
}

getRootName() {
return this._getESDocFieldName();
}

async getLabel() {
return this._label
? await this._label
: this._source.formatMetricLabel(this.getAggType(), this.getESDocFieldName());
? this._label
: this._source.getAggLabel(this.getAggType(), this.getRootName());
}

getAggType() {
Expand All @@ -42,13 +46,13 @@ export class ESAggMetricField extends AbstractField {
return this.getAggType() === AGG_TYPE.TERMS ? 'string' : 'number';
}

getESDocFieldName() {
_getESDocFieldName() {
return this._esDocField ? this._esDocField.getName() : '';
}

getRequestDescription() {
return this.getAggType() !== AGG_TYPE.COUNT
? `${this.getAggType()} ${this.getESDocFieldName()}`
? `${this.getAggType()} ${this.getRootName()}`
: AGG_TYPE.COUNT;
}

Expand All @@ -64,7 +68,7 @@ export class ESAggMetricField extends AbstractField {
}

getValueAggDsl(indexPattern) {
const field = getField(indexPattern, this.getESDocFieldName());
const field = getField(indexPattern, this.getRootName());
const aggType = this.getAggType();
const aggBody = aggType === AGG_TYPE.TERMS ? { size: 1, shard_size: 1 } : {};
return {
Expand All @@ -77,6 +81,11 @@ export class ESAggMetricField extends AbstractField {
return !isMetricCountable(this.getAggType());
}

canValueBeFormatted() {
// Do not use field formatters for counting metrics
return ![AGG_TYPE.COUNT, AGG_TYPE.UNIQUE_COUNT].includes(this.getAggType());
}

async getOrdinalFieldMetaRequest(config) {
return this._esDocField.getOrdinalFieldMetaRequest(config);
}
Expand Down
8 changes: 8 additions & 0 deletions x-pack/legacy/plugins/maps/public/layers/fields/field.js
Expand Up @@ -17,6 +17,14 @@ export class AbstractField {
return this._fieldName;
}

getRootName() {
return this.getName();
}

canValueBeFormatted() {
return true;
}

getSource() {
return this._source;
}
Expand Down
17 changes: 14 additions & 3 deletions x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';
import { AbstractESSource } from './es_source';
import { ESAggMetricField } from '../fields/es_agg_field';
import { ESDocField } from '../fields/es_doc_field';
Expand Down Expand Up @@ -72,12 +73,22 @@ export class AbstractESAggSource extends AbstractESSource {
return metrics;
}

formatMetricKey(aggType, fieldName) {
getAggKey(aggType, fieldName) {
return aggType !== AGG_TYPE.COUNT ? `${aggType}${AGG_DELIMITER}${fieldName}` : COUNT_PROP_NAME;
}

formatMetricLabel(aggType, fieldName) {
return aggType !== AGG_TYPE.COUNT ? `${aggType} of ${fieldName}` : COUNT_PROP_LABEL;
getAggLabel(aggType, fieldName) {
switch (aggType) {
case AGG_TYPE.COUNT:
return COUNT_PROP_LABEL;
case AGG_TYPE.TERMS:
return i18n.translate('xpack.maps.source.esAggSource.topTermLabel', {
defaultMessage: `Top {fieldName}`,
values: { fieldName },
});
default:
return `${aggType} ${fieldName}`;
}
}

getValueAggsDsl(indexPattern) {
Expand Down

0 comments on commit 7ac1293

Please sign in to comment.