Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement HTTP API versioned types in usage collection plugin #152875

Merged

Conversation

TinaHeiligers
Copy link
Contributor

@TinaHeiligers TinaHeiligers commented Mar 8, 2023

Similar to 152111 prepares usage collection plugin types for versioning

In this PR we ensure that we are adhering to the goals of versioned HTTP APIs to:

  1. Not send SO attributes directly over the wire (the usage collection plugin doesn't consume the saved objects HTTP APIs)
  2. Have a separate set of interfaces that can be referenced publically and maintained by the server

The types for the following HTTP API routes have been versioned:

  • stats
  • ui_counters
  • selected usage_counters types requiring changes

Stats API

The stats route reports (along with other metrics), a subset of cores' OpsMetrics. Since usage isn't included in the response anymore (ref #151082), we have a few options to allow us to detect changes to these metrics:

  1. Move the entire stats route to core
  2. Keep the types for metrics generic and rely on some sort of validation elsewhere
  3. Directly import the types for metrics from packages/core/metrics/core-metrics-server/index.ts and rely on validation elsewhere
  4. Create duplicates of these types and explicitly declare, with the current types, the full response payload.
  5. something else?

This PR takes the 4th approach: Use duplicates with explicitly declaring the full response body.

How to test this:

  • functional tests will ensure that the implementations of these APIs haven't changed
  • Run kibana with es as normal and navigate to the stats route. It should remain working with and without extended and legacy queries:

{basepath}/api/stats?extended&legacy
{basepath}/api/stats?extended
{basepath}/api/stats

@TinaHeiligers TinaHeiligers added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:Telemetry release_note:skip Skip the PR/issue when compiling release notes backport:skip This commit does not require backporting v8.8.0 labels Mar 8, 2023
Copy link
Contributor

@jloleysens jloleysens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a quick review, let me know if that helps with the failed test!

Comment on lines +112 to +115
const body: Stats.v1.StatsHTTPBodyTyped = {
...kibanaStats,
...extended,
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

const extendedClusterUuid = isLegacy ? { clusterUuid } : { cluster_uuid: clusterUuid };
extended = {
usage: {},
extendedClusterUuid,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to spread this?

Suggested change
extendedClusterUuid,
...extendedClusterUuid,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, that makes sense! I'll give it a go.


let extended;
if (isExtended) {
const core = await context.core;
const { asCurrentUser } = core.elasticsearch.client;
// as of https://github.com/elastic/kibana/pull/151082, usage will always be an empty object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this comment!

* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exporting the types as aliased to the unversioned type definitions allows us to use:
Stats.v1.StatsHTTPBodyTyped for example

Copy link
Contributor Author

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self review with comments to reviewers

*/

/**
* The types are exact duplicates of the ops metrics types declared in core needed for reporting in the stats api.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're duplicating the types from core so that we'll detect any changes to the original metrics.

};
}
/** Stats response body */
export type StatsHTTPBodyTyped = LastOpsMetrics | KibanaStats | ExtendedStats;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explicitly declare (with appropriate types) the full response body from the stats api


if (response.status !== 'ok') {
const okStatus: UiCounters.v1.UiCountersResponseOk = response.status;
if (response.status !== okStatus) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The responses are hard-coded, depending on whether fetch throws or not, so we declare separate types for each outcome.

const SNAPSHOT_REGEX = /-snapshot/i;

interface UsageObject {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to v1

@@ -26,16 +27,22 @@ export function registerUiCountersRoute(
},
},
async (context, req, res) => {
const { report } = req.body;
const requestBody: UiCounters.v1.UiCountersRequestBody = req.body;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request needs to be fully versioned to accommodate future changes.

const bodyOk: UiCounters.v1.UiCountersResponseOk = {
status: 'ok',
};
return res.ok({ body: bodyOk });
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly type the hard-coded response.

@@ -5,13 +5,14 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { UsageCounter, CounterMetric } from './usage_counter';
import { UsageCounter } from './usage_counter';
import type { UsageCounters } from '../../common/types';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type and implementation having the same name might not be appropriate. I'm open to renaming the type, if needed.

@TinaHeiligers
Copy link
Contributor Author

@elasticmachine merge upstream

1 similar comment
@TinaHeiligers
Copy link
Contributor Author

@elasticmachine merge upstream

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
usageCollection 15 16 +1

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
usageCollection 1 2 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
usageCollection 5.0KB 5.0KB +8.0B
Unknown metric groups

API count

id before after diff
usageCollection 58 55 -3

ESLint disabled line counts

id before after diff
securitySolution 431 433 +2

Total ESLint disabled count

id before after diff
securitySolution 508 510 +2

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@TinaHeiligers TinaHeiligers marked this pull request as ready for review March 8, 2023 20:16
@TinaHeiligers TinaHeiligers requested a review from a team as a code owner March 8, 2023 20:16
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@jloleysens jloleysens self-requested a review March 9, 2023 09:48
Copy link
Contributor

@jloleysens jloleysens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @TinaHeiligers !

@TinaHeiligers TinaHeiligers merged commit 8a9789b into elastic:main Mar 9, 2023
@TinaHeiligers TinaHeiligers deleted the versioned-apis-usage-collection branch March 9, 2023 16:20
bmorelli25 pushed a commit to bmorelli25/kibana that referenced this pull request Mar 10, 2023
…c#152875)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Telemetry release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants