[APM] Setting for default env for service inventory (#126151)

This commit is contained in:
Dario Gieselaar 2022-03-01 13:50:58 +01:00 committed by GitHub
parent 1bc178fe76
commit 405ef9ed15
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 206 additions and 20 deletions

View file

@ -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({
<i18nCore.Context>
<TimeRangeIdContextProvider>
<RouterProvider history={history} router={apmRouter as any}>
<RedirectWithDefaultDateRange>
<TrackPageview>
<BreadcrumbsContextProvider>
<UrlParamsProvider>
<LicenseProvider>
<AnomalyDetectionJobsContextProvider>
<InspectorContextProvider>
<ApmThemeProvider>
<MountApmHeaderActionMenu />
<RedirectWithDefaultEnvironment>
<RedirectWithDefaultDateRange>
<TrackPageview>
<BreadcrumbsContextProvider>
<UrlParamsProvider>
<LicenseProvider>
<AnomalyDetectionJobsContextProvider>
<InspectorContextProvider>
<ApmThemeProvider>
<MountApmHeaderActionMenu />
<Route component={ScrollToTopOnPathChange} />
<RouteRenderer />
</ApmThemeProvider>
</InspectorContextProvider>
</AnomalyDetectionJobsContextProvider>
</LicenseProvider>
</UrlParamsProvider>
</BreadcrumbsContextProvider>
</TrackPageview>
</RedirectWithDefaultDateRange>
<Route component={ScrollToTopOnPathChange} />
<RouteRenderer />
</ApmThemeProvider>
</InspectorContextProvider>
</AnomalyDetectionJobsContextProvider>
</LicenseProvider>
</UrlParamsProvider>
</BreadcrumbsContextProvider>
</TrackPageview>
</RedirectWithDefaultDateRange>
</RedirectWithDefaultEnvironment>
</RouterProvider>
</TimeRangeIdContextProvider>
</i18nCore.Context>

View file

@ -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<Location, 'pathname' | 'search'>,
defaultSetting: string
) {
history.replace(location);
jest
.spyOn(useApmPluginContextExports, 'useApmPluginContext')
.mockReturnValue({
core: {
uiSettings: {
get: () => defaultSetting,
},
},
} as any);
return render(
<RouterProvider history={history} router={apmRouter as any}>
<RedirectWithDefaultEnvironment>
<>Foo</>
</RedirectWithDefaultEnvironment>
</RouterProvider>
);
}
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();
});
});

View file

@ -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<string>(defaultApmServiceEnvironment) ||
ENVIRONMENT_ALL.value;
return (
<Redirect
to={qs.stringifyUrl({
url: location.pathname,
query: {
...query,
environment: defaultServiceEnvironment,
},
})}
/>
);
}
return children;
}

View file

@ -14,6 +14,7 @@ export {
maxSuggestions,
enableComparisonByDefault,
enableInfrastructureView,
defaultApmServiceEnvironment,
} from './ui_settings_keys';
export const casesFeatureId = 'observabilityCases';

View file

@ -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';

View file

@ -27,6 +27,7 @@ export {
enableInspectEsQueries,
enableComparisonByDefault,
enableInfrastructureView,
defaultApmServiceEnvironment,
} from '../common/ui_settings_keys';
export { uptimeOverviewLocatorID } from '../common';

View file

@ -14,12 +14,13 @@ import {
enableInspectEsQueries,
maxSuggestions,
enableInfrastructureView,
defaultApmServiceEnvironment,
} from '../common/ui_settings_keys';
/**
* uiSettings definitions for Observability.
*/
export const uiSettings: Record<string, UiSettingsParams<boolean | number>> = {
export const uiSettings: Record<string, UiSettingsParams<boolean | number | string>> = {
[enableInspectEsQueries]: {
category: [observabilityFeatureId],
name: i18n.translate('xpack.observability.enableInspectEsQueriesExperimentName', {
@ -64,4 +65,16 @@ export const uiSettings: Record<string, UiSettingsParams<boolean | number>> = {
}),
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(),
},
};