Skip to content

Commit

Permalink
Merge branch '2.x' into backport/backport-4164-to-2.x
Browse files Browse the repository at this point in the history
Signed-off-by: Manasvini B Suryanarayana <[email protected]>
  • Loading branch information
manasvinibs authored Jun 14, 2023
2 parents 2367a3b + 473f3a4 commit 76d57eb
Show file tree
Hide file tree
Showing 19 changed files with 467 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @ananzh @kavilla @seanneumann @AMoo-Miki @ashwin-pc @joshuarrrr @abbyhu2000 @zengyan-amazon @kristenTian @zhongnansu @manasvinibs
* @ananzh @kavilla @seanneumann @AMoo-Miki @ashwin-pc @joshuarrrr @abbyhu2000 @zengyan-amazon @kristenTian @zhongnansu @manasvinibs @ZilongX @Flyingliuhub
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [VisBuilder] Fix Firefox legend selection issue ([#3732](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3732))
- [VisBuilder] Fix type errors ([#3732](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3732))
- [VisBuilder] Fix indexpattern selection in filter bar ([#3751](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3751))
- Remove `lmdb-store` to fix backport issue ([#4266](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4266))

### 🚞 Infrastructure

Expand Down Expand Up @@ -90,6 +91,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Multiple DataSource] Present the authentication type choices in a drop-down ([#3693](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3693))
- [Table Visualization] Move format table, consolidate types and add unit tests ([#3397](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3397))
- [Table Visualization] Remove custom styling for text-align:center in favor of OUI utility class. ([#4164](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4164))
- Replace the use of `bluebird` in `saved_objects` plugin ([#4026](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4026))

### 🔩 Tests

Expand Down
2 changes: 2 additions & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This document contains a list of maintainers in this repo. See [opensearch-proje
| Kristen Tian | [kristenTian](https://github.com/kristenTian) | Amazon |
| Zhongnan Su | [zhongnansu](https://github.com/zhongnansu) | Amazon |
| Manasvini B Suryanarayana | [manasvinibs](https://github.com/manasvinibs) | Amazon |
| Tao Liu | [Flyingliuhub](https://github.com/Flyingliuhub) | Amazon |
| Zilong Xia | [ZilongX](https://github.com/ZilongX) | Amazon |

## Emeritus

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { PanelViewWithSharingLong } from './panel_view_with_sharing_long';
import { PanelEdit } from './panel_edit';
import { PanelEditWithDrilldowns } from './panel_edit_with_drilldowns';
import { PanelEditWithDrilldownsAndContextActions } from './panel_edit_with_drilldowns_and_context_actions';
import { PanelGroupOptionsAndContextActions } from './panel_group_options_and_context_actions';

export const ContextMenuExamples: React.FC = () => {
return (
Expand All @@ -59,7 +60,6 @@ export const ContextMenuExamples: React.FC = () => {
<PanelViewWithSharingLong />
</EuiFlexItem>
</EuiFlexGroup>

<EuiFlexGroup>
<EuiFlexItem>
<PanelEdit />
Expand All @@ -71,6 +71,11 @@ export const ContextMenuExamples: React.FC = () => {
<PanelEditWithDrilldownsAndContextActions />
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup>
<EuiFlexItem>
<PanelGroupOptionsAndContextActions />
</EuiFlexItem>
</EuiFlexGroup>
</EuiText>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import * as React from 'react';
import { EuiButton, EuiContextMenu, EuiPopover } from '@elastic/eui';
import useAsync from 'react-use/lib/useAsync';
import { buildContextMenuForActions, Action } from '../../../../src/plugins/ui_actions/public';
import { sampleAction } from './util';

export const PanelGroupOptionsAndContextActions: React.FC = () => {
const [open, setOpen] = React.useState(false);

const context = {};
const trigger: any = 'TEST_TRIGGER';
const drilldownGrouping: Action['grouping'] = [
{
id: 'drilldowns',
getDisplayName: () => 'Uncategorized group',
getIconType: () => 'popout',
order: 20,
},
];
const exampleGroup: Action['grouping'] = [
{
id: 'example',
getDisplayName: () => 'Example group',
getIconType: () => 'cloudStormy',
order: 20,
category: 'visAug',
},
];
const alertingGroup: Action['grouping'] = [
{
id: 'alerting',
getDisplayName: () => 'Alerting',
getIconType: () => 'cloudStormy',
order: 20,
category: 'visAug',
},
];
const anomaliesGroup: Action['grouping'] = [
{
id: 'anomalies',
getDisplayName: () => 'Anomalies',
getIconType: () => 'cloudStormy',
order: 30,
category: 'visAug',
},
];
const actions = [
sampleAction('test-1', 100, 'Edit visualization', 'pencil'),
sampleAction('test-2', 99, 'Clone panel', 'partial'),

sampleAction('test-9', 10, 'Create drilldown', 'plusInCircle', drilldownGrouping),
sampleAction('test-10', 9, 'Manage drilldowns', 'list', drilldownGrouping),

sampleAction('test-11', 10, 'Example action', 'dashboardApp', exampleGroup),
sampleAction('test-11', 10, 'Alertin action 1', 'dashboardApp', alertingGroup),
sampleAction('test-12', 9, 'Alertin action 2', 'dashboardApp', alertingGroup),
sampleAction('test-13', 8, 'Anomalies 1', 'cloudStormy', anomaliesGroup),
sampleAction('test-14', 7, 'Anomalies 2', 'link', anomaliesGroup),
];

const panels = useAsync(() =>
buildContextMenuForActions({
actions: actions.map((action) => ({ action, context, trigger })),
})
);

return (
<EuiPopover
button={<EuiButton onClick={() => setOpen((x) => !x)}>Grouping with categories</EuiButton>}
isOpen={open}
panelPaddingSize="none"
anchorPosition="downLeft"
closePopover={() => setOpen(false)}
>
<EuiContextMenu initialPanelId={'mainMenu'} panels={panels.value} />
</EuiPopover>
);
};
1 change: 0 additions & 1 deletion packages/osd-optimizer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"jest-diff": "^27.5.1",
"js-yaml": "^3.14.0",
"json-stable-stringify": "^1.0.1",
"lmdb-store": "^1.6.11",
"node-sass": "^8.0.0",
"lmdb": "^2.8.0",
"normalize-path": "^3.0.0",
Expand Down
30 changes: 30 additions & 0 deletions release-notes/opensearch-dashboards.release-notes-2.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Version 2.8.0 Release Notes

### 🛡 Security

- [CVE-2023-2251] Bump yaml to `2.2.2` ([#3947](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3947))

### 📈 Features/Enhancements

- [Multiple Datasource] Support Amazon OpenSearch Serverless ([#3957](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3957))
- Add support for Node.js >=14.20.1 <19 ([#4071](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4071))
- Bundle Node.js 14 as a fallback for operating systems that cannot run Node.js 18 ([#4151](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4151))
- Enhance grouping for context menus ([#3924](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3924))

### 🐛 Bug Fixes

- [BUG] Fix bottom bar visibility using createPortal ([#3978](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3978))

### 🚞 Infrastructure

- Add threshold to code coverage config to prevent workflow failures ([#4040](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4040))
- [CI] Skip checksum verification on OpenSearch snapshot for cypress tests ([#4188](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4188))

### 🛠 Maintenance

- Use `exec` in the CLI shell scripts to prevent new process creation ([#3955](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3955))
- Remove timeline application ([#3971](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3971))

## 🎉 Welcome

Thank you to all the first-time contributors who made this release possible: @sikhote, @SergeyMyssak!
1 change: 1 addition & 0 deletions src/core/server/legacy/legacy_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ export class LegacyService implements CoreService {
addClientWrapper: setupDeps.core.savedObjects.addClientWrapper,
registerType: setupDeps.core.savedObjects.registerType,
getImportExportObjectLimit: setupDeps.core.savedObjects.getImportExportObjectLimit,
setRepositoryFactoryProvider: setupDeps.core.savedObjects.setRepositoryFactoryProvider,
},
status: {
isStatusPageAnonymous: setupDeps.core.status.isStatusPageAnonymous,
Expand Down
1 change: 1 addition & 0 deletions src/core/server/plugins/plugin_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
addClientWrapper: deps.savedObjects.addClientWrapper,
registerType: deps.savedObjects.registerType,
getImportExportObjectLimit: deps.savedObjects.getImportExportObjectLimit,
setRepositoryFactoryProvider: deps.savedObjects.setRepositoryFactoryProvider,
},
status: {
core$: deps.status.core$,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const createSetupContractMock = () => {
addClientWrapper: jest.fn(),
registerType: jest.fn(),
getImportExportObjectLimit: jest.fn(),
setRepositoryFactoryProvider: jest.fn(),
};

setupContract.getImportExportObjectLimit.mockReturnValue(100);
Expand Down
63 changes: 62 additions & 1 deletion src/core/server/saved_objects/saved_objects_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ import { errors as opensearchErrors } from '@opensearch-project/opensearch';
import { SavedObjectsService } from './saved_objects_service';
import { mockCoreContext } from '../core_context.mock';
import { Env } from '../config';
import { configServiceMock } from '../mocks';
import { configServiceMock, savedObjectsRepositoryMock } from '../mocks';
import { opensearchServiceMock } from '../opensearch/opensearch_service.mock';
import { opensearchClientMock } from '../opensearch/client/mocks';
import { httpServiceMock } from '../http/http_service.mock';
import { httpServerMock } from '../http/http_server.mocks';
import { SavedObjectsClientFactoryProvider } from './service/lib';
import { NodesVersionCompatibility } from '../opensearch/version_check/ensure_opensearch_version';
import { SavedObjectsRepository } from './service/lib/repository';
import { SavedObjectRepositoryFactoryProvider } from './service/lib/scoped_client_provider';

jest.mock('./service/lib/repository');

Expand Down Expand Up @@ -169,6 +170,27 @@ describe('SavedObjectsService', () => {
expect(typeRegistryInstanceMock.registerType).toHaveBeenCalledWith(type);
});
});

describe('#setRepositoryFactoryProvider', () => {
it('throws error if a repository is already registered', async () => {
const coreContext = createCoreContext();
const soService = new SavedObjectsService(coreContext);
const setup = await soService.setup(createSetupDeps());

const firstRepository: SavedObjectRepositoryFactoryProvider = () =>
savedObjectsRepositoryMock.create();
const secondRepository: SavedObjectRepositoryFactoryProvider = () =>
savedObjectsRepositoryMock.create();

setup.setRepositoryFactoryProvider(firstRepository);

expect(() => {
setup.setRepositoryFactoryProvider(secondRepository);
}).toThrowErrorMatchingInlineSnapshot(
`"custom repository factory is already set, and can only be set once"`
);
});
});
});

describe('#start()', () => {
Expand Down Expand Up @@ -281,6 +303,15 @@ describe('SavedObjectsService', () => {
}).toThrowErrorMatchingInlineSnapshot(
`"cannot call \`registerType\` after service startup."`
);

const customRpository: SavedObjectRepositoryFactoryProvider = () =>
savedObjectsRepositoryMock.create();

expect(() => {
setup.setRepositoryFactoryProvider(customRpository);
}).toThrowErrorMatchingInlineSnapshot(
'"cannot call `setRepositoryFactoryProvider` after service startup."'
);
});

describe('#getTypeRegistry', () => {
Expand Down Expand Up @@ -368,6 +399,36 @@ describe('SavedObjectsService', () => {

expect(includedHiddenTypes).toEqual(['someHiddenType']);
});

it('Should not create SavedObjectsRepository when custom repository is registered ', async () => {
const coreContext = createCoreContext({ skipMigration: false });
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
const setup = await soService.setup(coreSetup);

const customRpository: SavedObjectRepositoryFactoryProvider = () =>
savedObjectsRepositoryMock.create();
setup.setRepositoryFactoryProvider(customRpository);

const coreStart = createStartDeps();
const { createInternalRepository } = await soService.start(coreStart);
createInternalRepository();

expect(SavedObjectsRepository.createRepository as jest.Mocked<any>).not.toHaveBeenCalled();
});

it('Should create SavedObjectsRepository when no custom repository is registered ', async () => {
const coreContext = createCoreContext({ skipMigration: false });
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
await soService.setup(coreSetup);

const coreStart = createStartDeps();
const { createInternalRepository } = await soService.start(coreStart);
createInternalRepository();

expect(SavedObjectsRepository.createRepository as jest.Mocked<any>).toHaveBeenCalled();
});
});
});
});
42 changes: 35 additions & 7 deletions src/core/server/saved_objects/saved_objects_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { ISavedObjectsRepository, SavedObjectsRepository } from './service/lib/r
import {
SavedObjectsClientFactoryProvider,
SavedObjectsClientWrapperFactory,
SavedObjectRepositoryFactoryProvider,
} from './service/lib/scoped_client_provider';
import { Logger } from '../logging';
import { SavedObjectTypeRegistry, ISavedObjectTypeRegistry } from './saved_objects_type_registry';
Expand Down Expand Up @@ -166,6 +167,14 @@ export interface SavedObjectsServiceSetup {
* Returns the maximum number of objects allowed for import or export operations.
*/
getImportExportObjectLimit: () => number;

/**
* Set the default {@link SavedObjectRepositoryFactoryProvider | factory provider} for creating Saved Objects repository.
* Only one repository can be set, subsequent calls to this method will fail.
*/
setRepositoryFactoryProvider: (
respositoryFactoryProvider: SavedObjectRepositoryFactoryProvider
) => void;
}

/**
Expand Down Expand Up @@ -291,6 +300,8 @@ export class SavedObjectsService
private typeRegistry = new SavedObjectTypeRegistry();
private started = false;

private respositoryFactoryProvider?: SavedObjectRepositoryFactoryProvider;

constructor(private readonly coreContext: CoreContext) {
this.logger = coreContext.logger.get('savedobjects-service');
}
Expand Down Expand Up @@ -348,6 +359,15 @@ export class SavedObjectsService
this.typeRegistry.registerType(type);
},
getImportExportObjectLimit: () => this.config!.maxImportExportSize,
setRepositoryFactoryProvider: (repositoryProvider) => {
if (this.started) {
throw new Error('cannot call `setRepositoryFactoryProvider` after service startup.');
}
if (this.respositoryFactoryProvider) {
throw new Error('custom repository factory is already set, and can only be set once');
}
this.respositoryFactoryProvider = repositoryProvider;
},
};
}

Expand Down Expand Up @@ -422,13 +442,21 @@ export class SavedObjectsService
opensearchClient: OpenSearchClient,
includedHiddenTypes: string[] = []
) => {
return SavedObjectsRepository.createRepository(
migrator,
this.typeRegistry,
opensearchDashboardsConfig.index,
opensearchClient,
includedHiddenTypes
);
if (this.respositoryFactoryProvider) {
return this.respositoryFactoryProvider({
migrator,
typeRegistry: this.typeRegistry,
includedHiddenTypes,
});
} else {
return SavedObjectsRepository.createRepository(
migrator,
this.typeRegistry,
opensearchDashboardsConfig.index,
opensearchClient,
includedHiddenTypes
);
}
};

const repositoryFactory: SavedObjectsRepositoryFactory = {
Expand Down
Loading

0 comments on commit 76d57eb

Please sign in to comment.