From 405ef9ed151b74d0d910fab966434a9201847531 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Tue, 1 Mar 2022 13:50:58 +0100 Subject: [PATCH] [APM] Setting for default env for service inventory (#126151) --- .../public/components/routing/app_root.tsx | 41 +++--- .../index.test.tsx | 119 ++++++++++++++++++ .../index.tsx | 48 +++++++ x-pack/plugins/observability/common/index.ts | 1 + .../observability/common/ui_settings_keys.ts | 1 + x-pack/plugins/observability/public/index.ts | 1 + .../observability/server/ui_settings.ts | 15 ++- 7 files changed, 206 insertions(+), 20 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.test.tsx create mode 100644 x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.tsx diff --git a/x-pack/plugins/apm/public/components/routing/app_root.tsx b/x-pack/plugins/apm/public/components/routing/app_root.tsx index aca6d3d737e3d..0bab92c74f1bd 100644 --- a/x-pack/plugins/apm/public/components/routing/app_root.tsx +++ b/x-pack/plugins/apm/public/components/routing/app_root.tsx @@ -36,6 +36,7 @@ import { ApmHeaderActionMenu } from '../shared/apm_header_action_menu'; import { RedirectWithDefaultDateRange } from '../shared/redirect_with_default_date_range'; import { apmRouter } from './apm_route_config'; import { TrackPageview } from './track_pageview'; +import { RedirectWithDefaultEnvironment } from '../shared/redirect_with_default_environment'; export function ApmAppRoot({ apmPluginContextValue, @@ -60,26 +61,28 @@ export function ApmAppRoot({ - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + diff --git a/x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.test.tsx b/x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.test.tsx new file mode 100644 index 0000000000000..469e384a06ee4 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.test.tsx @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { RouterProvider } from '@kbn/typed-react-router-config'; +import { render } from '@testing-library/react'; +import { createMemoryHistory, Location, MemoryHistory } from 'history'; +import qs from 'query-string'; +import { RedirectWithDefaultEnvironment } from './'; +import { apmRouter } from '../../routing/apm_route_config'; +import * as useApmPluginContextExports from '../../../context/apm_plugin/use_apm_plugin_context'; +import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; + +describe('RedirectWithDefaultEnvironment', () => { + let history: MemoryHistory; + + beforeEach(() => { + history = createMemoryHistory(); + }); + + function renderUrl( + location: Pick, + defaultSetting: string + ) { + history.replace(location); + + jest + .spyOn(useApmPluginContextExports, 'useApmPluginContext') + .mockReturnValue({ + core: { + uiSettings: { + get: () => defaultSetting, + }, + }, + } as any); + + return render( + + + <>Foo + + + ); + } + + it('eventually renders the child element', async () => { + const element = renderUrl( + { + pathname: '/services', + search: location.search, + }, + '' + ); + + await expect(element.findByText('Foo')).resolves.not.toBeUndefined(); + + // assertion to make sure our element test actually works + await expect(element.findByText('Bar')).rejects.not.toBeUndefined(); + }); + + it('redirects to ENVIRONMENT_ALL if not set', async () => { + renderUrl( + { + pathname: '/services', + search: location.search, + }, + '' + ); + + expect(qs.parse(history.entries[0].search).environment).toEqual( + ENVIRONMENT_ALL.value + ); + }); + + it('redirects to the default environment if set', () => { + renderUrl( + { + pathname: '/services', + search: location.search, + }, + 'production' + ); + + expect(qs.parse(history.entries[0].search).environment).toEqual( + 'production' + ); + }); + + it('does not redirect when an environment has been set', () => { + renderUrl( + { + pathname: '/services', + search: qs.stringify({ + environment: 'development', + }), + }, + 'production' + ); + + expect(qs.parse(history.entries[0].search).environment).toEqual( + 'development' + ); + }); + + it('does not redirect for the service overview', () => { + renderUrl( + { + pathname: '/services/opbeans-java', + search: location.search, + }, + '' + ); + + expect(qs.parse(history.entries[0].search).environment).toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.tsx b/x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.tsx new file mode 100644 index 0000000000000..83f93a0c6d090 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/redirect_with_default_environment/index.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useLocation, Redirect } from 'react-router-dom'; +import qs from 'query-string'; +import React from 'react'; +import { defaultApmServiceEnvironment } from '../../../../../observability/common'; +import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; +import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; + +export function RedirectWithDefaultEnvironment({ + children, +}: { + children: React.ReactElement; +}) { + const { core } = useApmPluginContext(); + const location = useLocation(); + + const query = qs.parse(location.search); + + if ('environment' in query) { + return children; + } + + if (location.pathname === '/services' || location.pathname === '/services/') { + const defaultServiceEnvironment = + core.uiSettings.get(defaultApmServiceEnvironment) || + ENVIRONMENT_ALL.value; + + return ( + + ); + } + + return children; +} diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index 3eb59effedc3a..3f31eb5f9140c 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -14,6 +14,7 @@ export { maxSuggestions, enableComparisonByDefault, enableInfrastructureView, + defaultApmServiceEnvironment, } from './ui_settings_keys'; export const casesFeatureId = 'observabilityCases'; diff --git a/x-pack/plugins/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability/common/ui_settings_keys.ts index ea8a2f20ea4e7..2557217b2211e 100644 --- a/x-pack/plugins/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability/common/ui_settings_keys.ts @@ -9,3 +9,4 @@ export const enableInspectEsQueries = 'observability:enableInspectEsQueries'; export const maxSuggestions = 'observability:maxSuggestions'; export const enableComparisonByDefault = 'observability:enableComparisonByDefault'; export const enableInfrastructureView = 'observability:enableInfrastructureView'; +export const defaultApmServiceEnvironment = 'observability:apmDefaultServiceEnvironment'; diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index 0fa1469180da5..0ef02fda3fa47 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -27,6 +27,7 @@ export { enableInspectEsQueries, enableComparisonByDefault, enableInfrastructureView, + defaultApmServiceEnvironment, } from '../common/ui_settings_keys'; export { uptimeOverviewLocatorID } from '../common'; diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 8d37398b8a07b..866c8fe5432d5 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -14,12 +14,13 @@ import { enableInspectEsQueries, maxSuggestions, enableInfrastructureView, + defaultApmServiceEnvironment, } from '../common/ui_settings_keys'; /** * uiSettings definitions for Observability. */ -export const uiSettings: Record> = { +export const uiSettings: Record> = { [enableInspectEsQueries]: { category: [observabilityFeatureId], name: i18n.translate('xpack.observability.enableInspectEsQueriesExperimentName', { @@ -64,4 +65,16 @@ export const uiSettings: Record> = { }), schema: schema.boolean(), }, + [defaultApmServiceEnvironment]: { + category: [observabilityFeatureId], + name: i18n.translate('xpack.observability.defaultApmServiceEnvironment', { + defaultMessage: 'Default service environment', + }), + description: i18n.translate('xpack.observability.defaultApmServiceEnvironmentDescription', { + defaultMessage: + 'Set the default environment for the APM app. When left empty, data from all environments will be displayed by default.', + }), + value: '', + schema: schema.string(), + }, };