diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx
index c5771995daa24..9213349a1492b 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx
@@ -4,15 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
import {
- EuiEmptyPrompt,
EuiButton,
- EuiPanel,
+ EuiEmptyPrompt,
EuiFlexGroup,
- EuiFlexItem
+ EuiFlexItem,
+ EuiPanel
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import React from 'react';
+import { invalidLicenseMessage } from '../../../../../../../plugins/apm/common/service_map';
import { useKibanaUrl } from '../../../hooks/useKibanaUrl';
export function PlatinumLicensePrompt() {
@@ -43,14 +44,7 @@ export function PlatinumLicensePrompt() {
)}
]}
- body={
-
- {i18n.translate('xpack.apm.serviceMap.licensePromptBody', {
- defaultMessage:
- "In order to access Service Maps, you must be subscribed to an Elastic Platinum license. With it, you'll have the ability to visualize your entire application stack along with your APM data."
- })}
-
- }
+ body={{invalidLicenseMessage}
}
title={
{i18n.translate('xpack.apm.serviceMap.licensePromptTitle', {
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx
index 5fea4be9ca0da..b14ecaa803f6d 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx
@@ -17,12 +17,14 @@ import React, {
useState
} from 'react';
import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public';
+import { isValidPlatinumLicense } from '../../../../../../../plugins/apm/common/service_map';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { ServiceMapAPIResponse } from '../../../../../../../plugins/apm/server/lib/service_map/get_service_map';
import { useApmPluginContext } from '../../../hooks/useApmPluginContext';
import { useCallApmApi } from '../../../hooks/useCallApmApi';
import { useDeepObjectIdentity } from '../../../hooks/useDeepObjectIdentity';
import { useLicense } from '../../../hooks/useLicense';
+import { useLoadingIndicator } from '../../../hooks/useLoadingIndicator';
import { useLocation } from '../../../hooks/useLocation';
import { useUrlParams } from '../../../hooks/useUrlParams';
import { Controls } from './Controls';
@@ -31,7 +33,6 @@ import { getCytoscapeElements } from './get_cytoscape_elements';
import { PlatinumLicensePrompt } from './PlatinumLicensePrompt';
import { Popover } from './Popover';
import { useRefHeight } from './useRefHeight';
-import { useLoadingIndicator } from '../../../hooks/useLoadingIndicator';
interface ServiceMapProps {
serviceName?: string;
@@ -195,13 +196,13 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [elements]);
- const isValidPlatinumLicense =
- license?.isActive &&
- (license?.type === 'platinum' || license?.type === 'trial');
-
const [wrapperRef, height] = useRefHeight();
- return isValidPlatinumLicense ? (
+ if (!license) {
+ return null;
+ }
+
+ return isValidPlatinumLicense(license) ? (
{
plugins: {
apm_oss: APMOSSPlugin extends Plugin ? TSetup : never;
home: HomeServerPluginSetup;
+ licensing: LicensingPluginSetup;
cloud?: CloudSetup;
usageCollection?: UsageCollectionSetup;
}
diff --git a/x-pack/plugins/apm/server/routes/service_map.ts b/x-pack/plugins/apm/server/routes/service_map.ts
index 584598805f8b3..bead0445d6ccc 100644
--- a/x-pack/plugins/apm/server/routes/service_map.ts
+++ b/x-pack/plugins/apm/server/routes/service_map.ts
@@ -4,13 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as t from 'io-ts';
import Boom from 'boom';
+import * as t from 'io-ts';
+import {
+ invalidLicenseMessage,
+ isValidPlatinumLicense
+} from '../../common/service_map';
import { setupRequest } from '../lib/helpers/setup_request';
-import { createRoute } from './create_route';
-import { uiFiltersRt, rangeRt } from './default_api_types';
import { getServiceMap } from '../lib/service_map/get_service_map';
import { getServiceMapServiceNodeInfo } from '../lib/service_map/get_service_map_service_node_info';
+import { createRoute } from './create_route';
+import { rangeRt, uiFiltersRt } from './default_api_types';
export const serviceMapRoute = createRoute(() => ({
path: '/api/apm/service-map',
@@ -26,6 +30,10 @@ export const serviceMapRoute = createRoute(() => ({
if (!context.config['xpack.apm.serviceMapEnabled']) {
throw Boom.notFound();
}
+ if (!isValidPlatinumLicense(context.licensing.license)) {
+ throw Boom.forbidden(invalidLicenseMessage);
+ }
+
const setup = await setupRequest(context, request);
const {
query: { serviceName, environment, after }
@@ -51,6 +59,9 @@ export const serviceMapServiceNodeRoute = createRoute(() => ({
if (!context.config['xpack.apm.serviceMapEnabled']) {
throw Boom.notFound();
}
+ if (!isValidPlatinumLicense(context.licensing.license)) {
+ throw Boom.forbidden(invalidLicenseMessage);
+ }
const setup = await setupRequest(context, request);
const {