Skip to content

Commit

Permalink
finalize copy
Browse files Browse the repository at this point in the history
  • Loading branch information
Bamieh committed Nov 10, 2024
1 parent 7663d11 commit e31e86b
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export const registerInternalDeprecatedRoute = (router: IRouter) => {
deprecated: {
documentationUrl: 'https://elastic.co/',
severity: 'critical',
reason: { type: 'remove' },
message: 'Additonal message for internal deprecated api',
reason: { type: 'deprecate' },
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,30 @@ import type {
ApiDeprecationDetails,
DomainDeprecationDetails,
} from '@kbn/core-deprecations-common';
import type { BuildApiDeprecationDetailsParams } from './types';
import type { BuildApiDeprecationDetailsParams } from '../types';
import {
getApiDeprecationMessage,
getApiDeprecationsManualSteps,
getApiDeprecationTitle,
} from './i18n_texts';
import { buildApiDeprecationId } from './api_deprecation_id';

export const buildApiAccessDeprecationDetails = ({
apiUsageStats,
deprecatedApis,
deprecatedApiDetails,
}: BuildApiDeprecationDetailsParams): DomainDeprecationDetails<ApiDeprecationDetails> => {
const { apiId, apiTotalCalls, totalMarkedAsResolved } = apiUsageStats;
const routeDeprecationDetails = deprecatedApis.find(
(routeDetails) => buildApiDeprecationId(routeDetails) === apiId
)!;
const { routeVersion, routePath, routeDeprecationOptions, routeMethod } = routeDeprecationDetails;
const { routeVersion, routePath, routeDeprecationOptions, routeMethod } = deprecatedApiDetails;

const deprecationLevel = routeDeprecationOptions.severity || 'warning';
const deprecationLevel = routeDeprecationOptions?.severity || 'warning';

return {
apiId,
title: getApiDeprecationTitle(routeDeprecationDetails),
title: getApiDeprecationTitle(deprecatedApiDetails),
level: deprecationLevel,
message: getApiDeprecationMessage(routeDeprecationDetails, apiUsageStats),
documentationUrl: routeDeprecationOptions.documentationUrl,
message: getApiDeprecationMessage(deprecatedApiDetails, apiUsageStats),
documentationUrl: routeDeprecationOptions?.documentationUrl,
correctiveActions: {
manualSteps: getApiDeprecationsManualSteps(routeDeprecationDetails),
manualSteps: getApiDeprecationsManualSteps(),
mark_as_resolved_api: {
routePath,
routeMethod,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { RouterDeprecatedApiDetails } from '@kbn/core-http-server';
import { CoreDeprecatedApiUsageStats } from '@kbn/core-usage-data-server';
import { i18n } from '@kbn/i18n';
import moment from 'moment';

export const getApiDeprecationTitle = (
details: Pick<RouterDeprecatedApiDetails, 'routePath' | 'routeMethod'>
) => {
const { routePath, routeMethod } = details;
const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`;

return i18n.translate('core.deprecations.apiAccessDeprecation.infoTitle', {
defaultMessage: 'The "{routeWithMethod}" API is internal to Elastic',
values: {
routeWithMethod,
},
});
};

export const getApiDeprecationMessage = (
details: Pick<
RouterDeprecatedApiDetails,
'routePath' | 'routeMethod' | 'routeDeprecationOptions'
>,
apiUsageStats: CoreDeprecatedApiUsageStats
): string[] => {
const { routePath, routeMethod, routeDeprecationOptions } = details;
const { apiLastCalledAt, apiTotalCalls, markedAsResolvedLastCalledAt, totalMarkedAsResolved } =
apiUsageStats;

const diff = apiTotalCalls - totalMarkedAsResolved;
const wasResolvedBefore = totalMarkedAsResolved > 0;
const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`;

const messages = [
i18n.translate('core.deprecations.apiAccessDeprecation.apiCallsDetailsMessage', {
defaultMessage:
'The API "{routeWithMethod}" has been called {apiTotalCalls} times. The last call was on {apiLastCalledAt}.',
values: {
routeWithMethod,
apiTotalCalls,
apiLastCalledAt: moment(apiLastCalledAt).format('LLLL Z'),
},
}),
];

if (wasResolvedBefore) {
messages.push(
i18n.translate('core.deprecations.apiAccessDeprecation.previouslyMarkedAsResolvedMessage', {
defaultMessage:
'This issue has been marked as resolved on {markedAsResolvedLastCalledAt} but the API has been called {timeSinceLastResolved, plural, one {# time} other {# times}} since.',
values: {
timeSinceLastResolved: diff,
markedAsResolvedLastCalledAt: moment(markedAsResolvedLastCalledAt).format('LLLL Z'),
},
})
);
}

messages.push(
i18n.translate('core.deprecations.apiAccessDeprecation.internalApiExplanationMessage', {
defaultMessage:
'Internal APIs are meant to be used by Elastic services only. You should not use them. External access to these APIs will be restricted.',
})
);

if (routeDeprecationOptions?.message) {
// Surfaces additional deprecation messages passed into the route in UA
messages.push(routeDeprecationOptions.message);
}

return messages;
};

export const getApiDeprecationsManualSteps = (): string[] => {
return [
i18n.translate('core.deprecations.apiAccessDeprecation.manualSteps.identifyCallsOriginStep', {
defaultMessage: 'Identify the origin of these API calls.',
}),
i18n.translate('core.deprecations.apiAccessDeprecation.manualSteps.deleteRequestsStep', {
defaultMessage:
'Delete any requests you have that use this API. Check the learn more link for possible alternatives.',
}),
i18n.translate(
'core.deprecations.apiAccessDeprecation.manualSteps.accessDepractionMarkAsResolvedStep',
{
defaultMessage:
'Once you have successfully stopped using this API, mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.',
}
),
];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export { buildApiAccessDeprecationDetails } from './access_deprecations';
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ describe('#registerApiDeprecationsInfo', () => {
},
"deprecationType": "api",
"documentationUrl": "https://fake-url",
"domainId": "core.routes-deprecations",
"domainId": "core.http.routes-deprecations",
"level": "critical",
"message": Array [
"The API \\"GET /api/test_deprecated/\\" has been called 13 times. The last call was on Sunday, September 1, 2024 6:06 AM -04:00.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@

import { DeprecationsDetails } from '@kbn/core-deprecations-common';

import _ from 'lodash';
import { buildApiRouteDeprecationDetails } from './route_deprecations';
import { buildApiAccessDeprecationDetails } from './access_deprecations';

import { ApiDeprecationsServiceDeps } from './types';
import { buildApiRouteDeprecationDetails } from './route/route_deprecations';
import { buildApiAccessDeprecationDetails } from './access/access_deprecations';
import { buildApiDeprecationId } from './api_deprecation_id';
import type { ApiDeprecationsServiceDeps } from './types';

export const createGetApiDeprecations =
({ http, coreUsageData }: Pick<ApiDeprecationsServiceDeps, 'coreUsageData' | 'http'>) =>
Expand All @@ -31,23 +29,32 @@ export const createGetApiDeprecations =
deprecatedApis.some((routeDetails) => buildApiDeprecationId(routeDetails) === apiId)
)
.map((apiUsageStats) => {
const { internal: internalApiDeprecationedRoutes, ...deprecatedRoutes } = _.groupBy(
deprecatedApis,
'routeAccess'
const { apiId } = apiUsageStats;
const deprecatedApiDetails = deprecatedApis.find(
(routeDetails) => buildApiDeprecationId(routeDetails) === apiId
);
if (!deprecatedApiDetails) {
throw new Error(`Unable to find deprecation details for "${apiId}"`);
}

return [
buildApiRouteDeprecationDetails({
apiUsageStats,
deprecatedApis: Object.values(deprecatedRoutes).flat(),
}),
buildApiAccessDeprecationDetails({
apiUsageStats,
deprecatedApis: Object.values(internalApiDeprecationedRoutes),
}),
];
})
.flat();
const { routeAccess } = deprecatedApiDetails;

switch (routeAccess) {
case 'internal': {
return buildApiAccessDeprecationDetails({
apiUsageStats,
deprecatedApiDetails,
});
}
case 'public':
default: {
return buildApiRouteDeprecationDetails({
apiUsageStats,
deprecatedApiDetails,
});
}
}
});
};

export const registerApiDeprecationsInfo = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ import moment from 'moment';

export const getApiDeprecationTitle = (details: RouterDeprecatedApiDetails) => {
const { routePath, routeMethod, routeDeprecationOptions } = details;
if (!routeDeprecationOptions) {
throw new Error(`Router "deprecated" param is missing for path "${routePath}".`);
}

const deprecationType = routeDeprecationOptions.reason.type;
const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`;
const deprecationTypeText = i18n.translate('core.deprecations.deprecations.apiDeprecationType', {
const deprecationTypeText = i18n.translate('core.deprecations.apiRouteDeprecation.type', {
defaultMessage:
'{deprecationType, select, remove {is removed} bump {has a newer version available} migrate {is migrated to a different API} other {is deprecated}}',
values: { deprecationType },
});

return i18n.translate('core.deprecations.deprecations.apiDeprecationInfoTitle', {
return i18n.translate('core.deprecations.apiRouteDeprecation.infoTitle', {
defaultMessage: 'The "{routeWithMethod}" route {deprecationTypeText}',
values: {
routeWithMethod,
Expand All @@ -36,6 +40,9 @@ export const getApiDeprecationMessage = (
apiUsageStats: CoreDeprecatedApiUsageStats
): string[] => {
const { routePath, routeMethod, routeDeprecationOptions } = details;
if (!routeDeprecationOptions) {
throw new Error(`Router "deprecated" param is missing for path "${routePath}".`);
}
const { apiLastCalledAt, apiTotalCalls, markedAsResolvedLastCalledAt, totalMarkedAsResolved } =
apiUsageStats;

Expand All @@ -44,7 +51,7 @@ export const getApiDeprecationMessage = (
const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`;

const messages = [
i18n.translate('core.deprecations.deprecations.apiDeprecationApiCallsDetailsMessage', {
i18n.translate('core.deprecations.apiRouteDeprecation.apiCallsDetailsMessage', {
defaultMessage:
'The API "{routeWithMethod}" has been called {apiTotalCalls} times. The last call was on {apiLastCalledAt}.',
values: {
Expand All @@ -57,17 +64,14 @@ export const getApiDeprecationMessage = (

if (wasResolvedBefore) {
messages.push(
i18n.translate(
'core.deprecations.deprecations.apiDeprecationPreviouslyMarkedAsResolvedMessage',
{
defaultMessage:
'This issue has been marked as resolved on {markedAsResolvedLastCalledAt} but the API has been called {timeSinceLastResolved, plural, one {# time} other {# times}} since.',
values: {
timeSinceLastResolved: diff,
markedAsResolvedLastCalledAt: moment(markedAsResolvedLastCalledAt).format('LLLL Z'),
},
}
)
i18n.translate('core.deprecations.apiRouteDeprecation.previouslyMarkedAsResolvedMessage', {
defaultMessage:
'This issue has been marked as resolved on {markedAsResolvedLastCalledAt} but the API has been called {timeSinceLastResolved, plural, one {# time} other {# times}} since.',
values: {
timeSinceLastResolved: diff,
markedAsResolvedLastCalledAt: moment(markedAsResolvedLastCalledAt).format('LLLL Z'),
},
})
);
}

Expand All @@ -80,11 +84,15 @@ export const getApiDeprecationMessage = (
};

export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetails): string[] => {
const { routeDeprecationOptions } = details;
const { routePath, routeDeprecationOptions } = details;
if (!routeDeprecationOptions) {
throw new Error(`Router "deprecated" param is missing for path "${routePath}".`);
}

const deprecationType = routeDeprecationOptions.reason.type;

const manualSteps = [
i18n.translate('core.deprecations.deprecations.manualSteps.apiIseprecatedStep', {
i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.identifyCallsOriginStep', {
defaultMessage: 'Identify the origin of these API calls.',
}),
];
Expand All @@ -93,7 +101,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetail
case 'bump': {
const { newApiVersion } = routeDeprecationOptions.reason;
manualSteps.push(
i18n.translate('core.deprecations.deprecations.manualSteps.bumpDetailsStep', {
i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.bumpTypeStep', {
defaultMessage:
'Update the requests to use the following new version of the API instead: "{newApiVersion}".',
values: { newApiVersion },
Expand All @@ -104,7 +112,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetail

case 'remove': {
manualSteps.push(
i18n.translate('core.deprecations.deprecations.manualSteps.removeTypeExplainationStep', {
i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.removeTypeStep', {
defaultMessage:
'This API no longer exists and no replacement is available. Delete any requests you have that use this API.',
})
Expand All @@ -113,7 +121,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetail
}
case 'deprecate': {
manualSteps.push(
i18n.translate('core.deprecations.deprecations.manualSteps.removeTypeExplainationStep', {
i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.deprecateTypeStep', {
defaultMessage:
'For now, the API will still work, but will be moved or removed in a future version. Check the Learn more link for more information. If you are no longer using the API, you can mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.',
})
Expand All @@ -125,7 +133,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetail
const newRouteWithMethod = `${newApiMethod.toUpperCase()} ${newApiPath}`;

manualSteps.push(
i18n.translate('core.deprecations.deprecations.manualSteps.migrateDetailsStep', {
i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.migrateTypeStep', {
defaultMessage:
'Update the requests to use the following new API instead: "{newRouteWithMethod}".',
values: { newRouteWithMethod },
Expand All @@ -137,10 +145,13 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetail

if (deprecationType !== 'deprecate') {
manualSteps.push(
i18n.translate('core.deprecations.deprecations.manualSteps.markAsResolvedStep', {
defaultMessage:
'Check that you are no longer using the old API in any requests, and mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.',
})
i18n.translate(
'core.deprecations.apiRouteDeprecation.manualSteps.routeDepractionMarkAsResolvedStep',
{
defaultMessage:
'Check that you are no longer using the old API in any requests, and mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.',
}
)
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export { buildApiRouteDeprecationDetails } from './route_deprecations';
Loading

0 comments on commit e31e86b

Please sign in to comment.