From d2973ee469c4260c3f364511d53d78358b7a08da Mon Sep 17 00:00:00 2001 From: Bamieh Date: Mon, 4 Nov 2024 17:11:52 +0300 Subject: [PATCH 1/7] add deprecate type --- examples/routing_example/common/index.ts | 1 + .../routes/deprecated_routes/unversioned.ts | 26 ++++++- .../routes/deprecated_routes/versioned.ts | 17 +++-- .../src/deprecations/i18n_texts.ts | 7 +- .../http/core-http-server/src/router/route.ts | 68 ++++++++++++++++--- 5 files changed, 96 insertions(+), 23 deletions(-) diff --git a/examples/routing_example/common/index.ts b/examples/routing_example/common/index.ts index b83582b66ff08..5bec77ebe0c0f 100644 --- a/examples/routing_example/common/index.ts +++ b/examples/routing_example/common/index.ts @@ -17,6 +17,7 @@ export const POST_MESSAGE_ROUTE_PATH = '/api/post_message'; export const INTERNAL_GET_MESSAGE_BY_ID_ROUTE = '/internal/get_message'; export const DEPRECATED_ROUTES = { + DEPRECATED_ROUTE: '/api/routing_example/d/deprecated_route', REMOVED_ROUTE: '/api/routing_example/d/removed_route', MIGRATED_ROUTE: '/api/routing_example/d/migrated_route', VERSIONED_ROUTE: '/api/routing_example/d/versioned', diff --git a/examples/routing_example/server/routes/deprecated_routes/unversioned.ts b/examples/routing_example/server/routes/deprecated_routes/unversioned.ts index 4e1451a91fc38..aeb856d2eaf61 100644 --- a/examples/routing_example/server/routes/deprecated_routes/unversioned.ts +++ b/examples/routing_example/server/routes/deprecated_routes/unversioned.ts @@ -12,6 +12,28 @@ import { schema } from '@kbn/config-schema'; import { DEPRECATED_ROUTES } from '../../../common'; export const registerDeprecatedRoute = (router: IRouter) => { + router.get( + { + path: DEPRECATED_ROUTES.DEPRECATED_ROUTE, + validate: false, + options: { + access: 'public', + deprecated: { + documentationUrl: 'https://elastic.co/', + severity: 'warning', + message: + 'This deprecation message will be surfaced in UA. use `i18n.translate` to internationalize this message.', + reason: { type: 'deprecate' }, + }, + }, + }, + async (ctx, req, res) => { + return res.ok({ + body: { result: 'Called deprecated route. Check UA to see the deprecation.' }, + }); + } + ); + router.get( { path: DEPRECATED_ROUTES.REMOVED_ROUTE, @@ -27,7 +49,7 @@ export const registerDeprecatedRoute = (router: IRouter) => { }, async (ctx, req, res) => { return res.ok({ - body: { result: 'Called deprecated route. Check UA to see the deprecation.' }, + body: { result: 'Called to be removed route. Check UA to see the deprecation.' }, }); } ); @@ -55,7 +77,7 @@ export const registerDeprecatedRoute = (router: IRouter) => { }, async (ctx, req, res) => { return res.ok({ - body: { result: 'Called deprecated route. Check UA to see the deprecation.' }, + body: { result: 'Called to be migrated route. Check UA to see the deprecation.' }, }); } ); diff --git a/examples/routing_example/server/routes/deprecated_routes/versioned.ts b/examples/routing_example/server/routes/deprecated_routes/versioned.ts index 54d6f779f77c3..95a745fef9cf6 100644 --- a/examples/routing_example/server/routes/deprecated_routes/versioned.ts +++ b/examples/routing_example/server/routes/deprecated_routes/versioned.ts @@ -7,16 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import type { RequestHandler } from '@kbn/core-http-server'; import type { IRouter } from '@kbn/core/server'; import { DEPRECATED_ROUTES } from '../../../common'; -const createDummyHandler = - (version: string): RequestHandler => - (ctx, req, res) => { - return res.ok({ body: { result: `API version ${version}.` } }); - }; - export const registerVersionedDeprecatedRoute = (router: IRouter) => { const versionedRoute = router.versioned.get({ path: DEPRECATED_ROUTES.VERSIONED_ROUTE, @@ -40,7 +33,11 @@ export const registerVersionedDeprecatedRoute = (router: IRouter) => { validate: false, version: '1', }, - createDummyHandler('1') + (ctx, req, res) => { + return res.ok({ + body: { result: 'Called deprecated verison of the API. API version 1 -> 2' }, + }); + } ); versionedRoute.addVersion( @@ -48,6 +45,8 @@ export const registerVersionedDeprecatedRoute = (router: IRouter) => { version: '2', validate: false, }, - createDummyHandler('2') + (ctx, req, res) => { + return res.ok({ body: { result: 'Called API version 2' } }); + } ); }; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts index cb1dacc97bd91..c7682704e40a7 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts @@ -35,7 +35,7 @@ export const getApiDeprecationMessage = ( details: RouterDeprecatedRouteDetails, apiUsageStats: CoreDeprecatedApiUsageStats ): string[] => { - const { routePath, routeMethod } = details; + const { routePath, routeMethod, routeDeprecationOptions } = details; const { apiLastCalledAt, apiTotalCalls, markedAsResolvedLastCalledAt, totalMarkedAsResolved } = apiUsageStats; @@ -71,6 +71,11 @@ export const getApiDeprecationMessage = ( ); } + if (routeDeprecationOptions.message) { + // Surfaces additional deprecation messages passed into the route in UA + messages.push(routeDeprecationOptions.message); + } + return messages; }; diff --git a/packages/core/http/core-http-server/src/router/route.ts b/packages/core/http/core-http-server/src/router/route.ts index 17fecd1c48b17..eec9a01f60562 100644 --- a/packages/core/http/core-http-server/src/router/route.ts +++ b/packages/core/http/core-http-server/src/router/route.ts @@ -120,36 +120,82 @@ export type Privilege = string; * created from HTTP API introspection (like OAS). */ export interface RouteDeprecationInfo { + /** + * link to the documentation for more details on the deprecation. + */ documentationUrl: string; + /** + * The description message to be displayed for the deprecation. + * Check the README for writing deprecations in `src/core/server/deprecations/README.mdx` + */ + message?: string; + /** + * levels: + * - warning: will not break deployment upon upgrade. + * - critical: needs to be addressed before upgrade. + */ severity: 'warning' | 'critical'; - reason: VersionBumpDeprecationType | RemovalApiDeprecationType | MigrationApiDeprecationType; + /** + * API deprecation reason: + * - bump: New version of the API is available. + * - remove: API was fully removed with no replacement. + * - migrate: API has been migrated to a different path. + * - deprecated: the deprecated API is deprecated, it might be removed or migrated, or got a version bump in the future. + * It is a catch-all deprecation for APIs but the API will work in the next upgrades. + */ + reason: + | VersionBumpDeprecationType + | RemovalApiDeprecationType + | MigrationApiDeprecationType + | DeprecateApiDeprecationType; } -/** - * bump deprecation reason denotes a new version of the API is available - */ interface VersionBumpDeprecationType { + /** + * bump deprecation reason denotes a new version of the API is available + */ type: 'bump'; + /** + * new version of the API to be used instead. + */ newApiVersion: string; } -/** - * remove deprecation reason denotes the API was fully removed with no replacement - */ interface RemovalApiDeprecationType { + /** + * remove deprecation reason denotes the API was fully removed with no replacement + */ type: 'remove'; } -/** - * migrate deprecation reason denotes the API has been migrated to a different API path - * Please make sure that if you are only incrementing the version of the API to use 'bump' instead - */ interface MigrationApiDeprecationType { + /** + * migrate deprecation reason denotes the API has been migrated to a different API path + * Please make sure that if you are only incrementing the version of the API to use 'bump' instead + */ type: 'migrate'; + /** + * new API path to be used instead + */ newApiPath: string; + /** + * new API method (GET POST PUT DELETE) to be used with the new API. + */ newApiMethod: string; } +interface DeprecateApiDeprecationType { + /** + * deprecate deprecation reason denotes the API is deprecated but it doesnt have a replacement + * or a clear version that it will be removed in. This is useful to alert users that the API is deprecated + * to allow them as much time as possible to work around this fact before the deprecation + * turns into a `remove` or `migrate` or `bump` type. + * + * Recommended to pair this with `severity: 'warning'` to avoid blocking the upgrades for this type. + */ + type: 'deprecate'; +} + /** * A set of privileges that can be used to define complex authorization requirements. * From 3429a39da47501fdf1c4bcb89ec9dc1dddd6999c Mon Sep 17 00:00:00 2001 From: Bamieh Date: Mon, 4 Nov 2024 17:41:05 +0300 Subject: [PATCH 2/7] update copy for deprecate type --- .../src/deprecations/i18n_texts.ts | 23 ++++++++++++++----- x-pack/plugins/upgrade_assistant/README.md | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts index c7682704e40a7..0f64d0fb695c0 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts @@ -111,6 +111,15 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta ); break; } + case 'deprecate': { + manualSteps.push( + i18n.translate('core.deprecations.deprecations.manualSteps.removeTypeExplainationStep', { + defaultMessage: + 'For now, the API will still work, but will be moved or removed in a future version. Check the documentation 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.', + }) + ); + break; + } case 'migrate': { const { newApiPath, newApiMethod } = routeDeprecationOptions.reason; const newRouteWithMethod = `${newApiMethod.toUpperCase()} ${newApiPath}`; @@ -126,12 +135,14 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta } } - 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.', - }) - ); + 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.', + }) + ); + } return manualSteps; }; diff --git a/x-pack/plugins/upgrade_assistant/README.md b/x-pack/plugins/upgrade_assistant/README.md index 2acac8e3e734d..9e2cf1b47e60a 100644 --- a/x-pack/plugins/upgrade_assistant/README.md +++ b/x-pack/plugins/upgrade_assistant/README.md @@ -292,6 +292,7 @@ GET kbn:/api/routing_example/d/versioned?apiVersion=2 # Non-versioned routes GET kbn:/api/routing_example/d/removed_route +GET kbn:/api/routing_example/d/deprecated_route POST kbn:/api/routing_example/d/migrated_route {} ``` From 56505c2d96d2f787558bf638f574479d9534aeb0 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Mon, 4 Nov 2024 17:45:07 +0300 Subject: [PATCH 3/7] udpate tests --- .../src/deprecations/api_deprecations.test.ts | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts index b431088152f3e..028b5a7f0882b 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts @@ -228,6 +228,51 @@ describe('#registerApiDeprecationsInfo', () => { `); }); + it('returns deprecated type deprecated route', async () => { + const getDeprecations = createGetApiDeprecations({ coreUsageData, http }); + const deprecatedRoute = createDeprecatedRouteDetails({ + routePath: '/api/test_deprecated/', + routeDeprecationOptions: { reason: { type: 'deprecate' }, message: 'additional message' }, + }); + http.getRegisteredDeprecatedApis.mockReturnValue([deprecatedRoute]); + usageClientMock.getDeprecatedApiUsageStats.mockResolvedValue([ + createApiUsageStat(buildApiDeprecationId(deprecatedRoute)), + ]); + + const deprecations = await getDeprecations(); + expect(deprecations).toMatchInlineSnapshot(` + Array [ + Object { + "apiId": "123|get|/api/test_deprecated", + "correctiveActions": Object { + "manualSteps": Array [ + "Identify the origin of these API calls.", + "For now, the API will still work, but will be moved or removed in a future version. Check the documentation 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.", + ], + "mark_as_resolved_api": Object { + "apiTotalCalls": 13, + "routeMethod": "get", + "routePath": "/api/test_deprecated/", + "routeVersion": "123", + "timestamp": 2024-10-17T12:06:41.224Z, + "totalMarkedAsResolved": 1, + }, + }, + "deprecationType": "api", + "documentationUrl": "https://fake-url", + "domainId": "core.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.", + "This issue has been marked as resolved on Thursday, October 17, 2024 8:06 AM -04:00 but the API has been called 12 times since.", + "additional message", + ], + "title": "The \\"GET /api/test_deprecated/\\" route is deprecated", + }, + ] + `); + }); + it('does not return resolved deprecated route', async () => { const getDeprecations = createGetApiDeprecations({ coreUsageData, http }); const deprecatedRoute = createDeprecatedRouteDetails({ routePath: '/api/test_resolved/' }); From 10fb9bde2c895bca1845d275baa1667b57a6e4ba Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:56:16 +0000 Subject: [PATCH 4/7] [CI] Auto-commit changed files from 'node scripts/notice' --- examples/routing_example/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/routing_example/tsconfig.json b/examples/routing_example/tsconfig.json index 86bfda9d3d529..b35e8dbd34f4a 100644 --- a/examples/routing_example/tsconfig.json +++ b/examples/routing_example/tsconfig.json @@ -20,6 +20,5 @@ "@kbn/core-http-browser", "@kbn/config-schema", "@kbn/react-kibana-context-render", - "@kbn/core-http-server", ] } From e205bdb75de65a7af99079e7d2b49116c8a1c940 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Mon, 4 Nov 2024 19:59:29 +0300 Subject: [PATCH 5/7] Update examples/routing_example/server/routes/deprecated_routes/versioned.ts Co-authored-by: florent-leborgne --- .../server/routes/deprecated_routes/versioned.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/routing_example/server/routes/deprecated_routes/versioned.ts b/examples/routing_example/server/routes/deprecated_routes/versioned.ts index 95a745fef9cf6..060bc64403dba 100644 --- a/examples/routing_example/server/routes/deprecated_routes/versioned.ts +++ b/examples/routing_example/server/routes/deprecated_routes/versioned.ts @@ -35,7 +35,7 @@ export const registerVersionedDeprecatedRoute = (router: IRouter) => { }, (ctx, req, res) => { return res.ok({ - body: { result: 'Called deprecated verison of the API. API version 1 -> 2' }, + body: { result: 'Called deprecated version of the API. API version 1 -> 2' }, }); } ); From a510df7651ca5f0b10e266c31026231ae2b3a83b Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Mon, 4 Nov 2024 20:59:49 +0300 Subject: [PATCH 6/7] Update packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts --- .../src/deprecations/i18n_texts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts index 0f64d0fb695c0..e52dd1f3d8fd1 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts @@ -115,7 +115,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta manualSteps.push( i18n.translate('core.deprecations.deprecations.manualSteps.removeTypeExplainationStep', { defaultMessage: - 'For now, the API will still work, but will be moved or removed in a future version. Check the documentation 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.', + '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.', }) ); break; From 26a822bb33448b1d4e2513f96316fd37a37686f0 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Mon, 4 Nov 2024 21:03:35 +0300 Subject: [PATCH 7/7] update snapshot --- .../src/deprecations/api_deprecations.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts index 028b5a7f0882b..5f9d0bfbb4b84 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts @@ -247,7 +247,7 @@ describe('#registerApiDeprecationsInfo', () => { "correctiveActions": Object { "manualSteps": Array [ "Identify the origin of these API calls.", - "For now, the API will still work, but will be moved or removed in a future version. Check the documentation 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.", + "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.", ], "mark_as_resolved_api": Object { "apiTotalCalls": 13,