From e10ac401f543f5540b5ada8f80533ddfbd0bc728 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Wed, 15 Nov 2023 13:51:01 +0100 Subject: [PATCH] feat: consider input and argument usage for breaking change detection (#255) Co-authored-by: Dustin Deus --- cli/src/commands/subgraph/commands/check.ts | 8 +- .../src/wg/cosmo/platform/v1/platform_pb.ts | 3 + .../src/core/bufservices/PlatformService.ts | 31 +- .../src/core/composition/schemaCheck.ts | 29 +- .../core/services/AccessTokenAuthenticator.ts | 2 - .../src/core/services/ApiKeyAuthenticator.ts | 2 - .../src/core/services/Authentication.ts | 3 - .../SchemaUsageTrafficInspector.test.ts | 196 ++++++++ .../services/SchemaUsageTrafficInspector.ts | 224 +++++---- controlplane/src/db/models.ts | 1 - .../graphqlmetrics/v1/graphqlmetrics.pb.go | 425 +++++++++++++----- graphqlmetrics/metrics_service.go | 62 ++- ...31010143332_graphql_schema_usage_table.sql | 6 + ...3333_graphql_schema_usage_table_5m_90d.sql | 8 +- ...graphql_metrics_schema_usage_5m_90d_mv.sql | 6 +- .../graphqlmetrics/v1/graphqlmetrics.proto | 31 +- proto/wg/cosmo/platform/v1/platform.proto | 2 + router-tests/go.mod | 2 +- router-tests/go.sum | 4 +- router/core/context.go | 14 +- router/core/graphql_handler.go | 7 +- router/core/graphql_prehandler.go | 4 +- router/core/operation_metrics.go | 60 ++- router/core/operation_parser.go | 43 +- router/core/operation_planner.go | 26 +- router/core/router_metrics.go | 5 +- router/core/websocket.go | 4 +- .../graphqlmetrics/v1/graphqlmetrics.pb.go | 424 ++++++++++++----- router/go.mod | 17 +- router/go.sum | 54 +++ router/internal/graphqlmetrics/aggregation.go | 20 +- .../graphqlmetrics/aggregation_test.go | 178 ++++++++ .../src/components/analytics/field-usage.tsx | 1 + .../graph/[slug]/checks/[checkId]/details.tsx | 1 + .../graph/[slug]/checks/[checkId]/index.tsx | 1 + .../[slug]/checks/[checkId]/operations.tsx | 1 + 36 files changed, 1513 insertions(+), 392 deletions(-) create mode 100644 controlplane/src/core/services/SchemaUsageTrafficInspector.test.ts diff --git a/cli/src/commands/subgraph/commands/check.ts b/cli/src/commands/subgraph/commands/check.ts index b84d3dbfab..0264e66087 100644 --- a/cli/src/commands/subgraph/commands/check.ts +++ b/cli/src/commands/subgraph/commands/check.ts @@ -109,14 +109,16 @@ export default (opts: BaseCommandOptions) => { console.log(`\nChecking the proposed schema for subgraph ${pc.bold(name)}.`); - // No operations imply no clients and no subgraphs + // No operations usage stats mean the check was not performed against any live traffic if (resp.operationUsageStats) { - if (resp.operationUsageStats?.totalOperations === 0) { - // Composition errors are still considered failures + if (resp.operationUsageStats.totalOperations === 0) { + // Composition errors are still considered failures, otherwise we can consider this a success + // because no operations were affected by the change success = resp.compositionErrors.length === 0; console.log(`No operations were affected by this schema change.`); finalStatement = `This schema change didn't affect any operations from existing client traffic.`; } else { + // Composition and breaking errors are considered failures because operations were affected by the change success = resp.breakingChanges.length === 0 && resp.compositionErrors.length === 0; console.log( diff --git a/connect/src/wg/cosmo/platform/v1/platform_pb.ts b/connect/src/wg/cosmo/platform/v1/platform_pb.ts index ab845c17e6..4c8c35054b 100644 --- a/connect/src/wg/cosmo/platform/v1/platform_pb.ts +++ b/connect/src/wg/cosmo/platform/v1/platform_pb.ts @@ -1036,6 +1036,9 @@ export class CheckSubgraphSchemaResponse extends Message 0; await schemaCheckRepo.createSchemaCheckChanges({ @@ -627,11 +628,17 @@ export default function (opts: RouterOptions): Partial[] = []; - // For operations checks we only consider breaking changes - const inspectorChanges = trafficInspector.schemaChangesToInspectorChanges( - schemaChanges.breakingChanges, - storedBreakingChanges, - ); + let inspectorChanges: InspectorSchemaChange[] = []; + try { + // For operations checks we only consider breaking changes + // This method will throw if the schema changes cannot be converted to inspector changes + inspectorChanges = trafficInspector.schemaChangesToInspectorChanges( + schemaChanges.breakingChanges, + storedBreakingChanges, + ); + } catch { + isInspectable = false; + } for (const composition of result.compositions) { const graphConfig = await fedGraphRepo.getConfig(composition.id); @@ -652,13 +659,14 @@ export default function (opts: RouterOptions): Partial 0) { + // We don't collect operation usage when we have composition errors or + // when we don't have any inspectable changes. That means any breaking change is really breaking + if (composition.errors.length === 0 && isInspectable && inspectorChanges.length > 0) { if (graphConfig.trafficCheckDays <= 0) { continue; } - const result = await trafficInspector.inspect(inspectorChanges.changes, { + const result = await trafficInspector.inspect(inspectorChanges, { daysToConsider: graphConfig.trafficCheckDays, federatedGraphId: composition.id, organizationId: authContext.organizationId, @@ -687,9 +695,6 @@ export default function (opts: RouterOptions): Partial = - collectOperationUsageStats(inspectedOperations); - if (req.gitInfo && opts.githubApp) { const githubRepo = new GitHubRepository(opts.db, opts.githubApp); await githubRepo.createCommitCheck({ @@ -711,7 +716,7 @@ export default function (opts: RouterOptions): Partial { + const changes = await diff(oldSchemaSDL, newSchemaSDL); + return changes.map((change) => { + return { + message: change.message, + changeType: change.type, + path: change.path ?? '', + isBreaking: + change.criticality.level === CriticalityLevel.Breaking || + // We consider enum value changes as breaking changes because it is common to use enums in switch statements + // and if a value is removed or added, the switch statement will not be exhaustive anymore and might + // lead to unexpected behavior. + change.type === ChangeType.EnumValueRemoved || + change.type === ChangeType.EnumValueAdded, + }; + }); +} + export async function getDiffBetweenGraphs( oldSchemaSDL: string, newSchemaSDL?: string, @@ -56,16 +74,7 @@ export async function getDiffBetweenGraphs( } } - const changes: Change[] = await diff(oldSchema, newSchema); - - const schemaChanges: SchemaDiff[] = changes.map((change) => { - return { - message: change.message, - changeType: change.type, - path: change.path ?? '', - isBreaking: change.criticality.level === CriticalityLevel.Breaking, - }; - }); + const schemaChanges = await getSchemaDiff(oldSchema, newSchema); const breakingChanges = schemaChanges.filter((change) => change.isBreaking); diff --git a/controlplane/src/core/services/AccessTokenAuthenticator.ts b/controlplane/src/core/services/AccessTokenAuthenticator.ts index 929f831f6b..2ae337893f 100644 --- a/controlplane/src/core/services/AccessTokenAuthenticator.ts +++ b/controlplane/src/core/services/AccessTokenAuthenticator.ts @@ -1,10 +1,8 @@ import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb'; -import { addDays } from 'date-fns'; import AuthUtils from '../auth-utils.js'; import { AuthenticationError } from '../errors/errors.js'; import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; import { checkUserAccess } from '../util.js'; -import { calLink } from './Authentication.js'; export type AccessTokenAuthContext = { userId: string; diff --git a/controlplane/src/core/services/ApiKeyAuthenticator.ts b/controlplane/src/core/services/ApiKeyAuthenticator.ts index 80e4710aec..bd6787e571 100644 --- a/controlplane/src/core/services/ApiKeyAuthenticator.ts +++ b/controlplane/src/core/services/ApiKeyAuthenticator.ts @@ -1,11 +1,9 @@ import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb'; -import { addDays } from 'date-fns'; import { eq } from 'drizzle-orm'; import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; import { AuthenticationError } from '../errors/errors.js'; import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; -import { calLink } from './Authentication.js'; export type ApiKeyAuthContext = { organizationId: string; diff --git a/controlplane/src/core/services/Authentication.ts b/controlplane/src/core/services/Authentication.ts index 174af1e270..6f8df33589 100644 --- a/controlplane/src/core/services/Authentication.ts +++ b/controlplane/src/core/services/Authentication.ts @@ -1,5 +1,4 @@ import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb'; -import { addDays } from 'date-fns'; import { lru } from 'tiny-lru'; import { AuthContext } from '../../types/index.js'; import { AuthenticationError } from '../errors/errors.js'; @@ -13,8 +12,6 @@ import WebSessionAuthenticator from './WebSessionAuthenticator.js'; // The maximum time to cache the user auth context for the web session authentication. const maxAuthCacheTtl = 30 * 1000; // 30 seconds -export const calLink = 'https://cal.com/stefan-avram-wundergraph/wundergraph-introduction'; - export interface Authenticator { authenticate(headers: Headers): Promise; authenticateRouter(headers: Headers): Promise; diff --git a/controlplane/src/core/services/SchemaUsageTrafficInspector.test.ts b/controlplane/src/core/services/SchemaUsageTrafficInspector.test.ts new file mode 100644 index 0000000000..520de9b271 --- /dev/null +++ b/controlplane/src/core/services/SchemaUsageTrafficInspector.test.ts @@ -0,0 +1,196 @@ +import { describe, expect, test } from 'vitest'; +import { buildSchema, GraphQLSchema } from 'graphql'; +import { getSchemaDiff } from '../composition/schemaCheck.js'; +import { InspectorSchemaChange, toInspectorChange } from './SchemaUsageTrafficInspector.js'; + +describe('Schema Change converter', (ctx) => { + describe('Arguments', (ctx) => { + test('Add a new required argument', async () => { + const a = buildSchema(/* GraphQL */ ` + type Query { + a: String + } + `); + const b = buildSchema(/* GraphQL */ ` + type Query { + a(b: Boolean!): String + } + `); + + const changes = await getBreakingChanges(a, b); + + expect(changes).toEqual([ + { + isArgument: true, + path: ['a', 'b'], + schemaChangeId: '0', + typeName: 'Query', + }, + ]); + + test('Add a new required argument nested', async () => { + const a = buildSchema(/* GraphQL */ ` + type Rocket { + details: String + } + type Query { + a(b: Boolean!): Rocket + } + `); + const b = buildSchema(/* GraphQL */ ` + type Rocket { + details(all: Boolean!): String + } + type Query { + a(b: Boolean!): Rocket + } + `); + + const changes = await getBreakingChanges(a, b); + + expect(changes).toEqual([ + { + isArgument: true, + path: ['details', 'all'], + schemaChangeId: '0', + typeName: 'Rocket', + }, + ]); + }); + }); + }); + + describe('Input', (ctx) => { + test('Add a new required Input field', async () => { + const a = buildSchema(/* GraphQL */ ` + input Foo { + a: String! + } + `); + const b = buildSchema(/* GraphQL */ ` + input Foo { + a: String! + b: String! + } + `); + + const changes = await getBreakingChanges(a, b); + + expect(changes).toEqual([ + { + fieldName: 'b', + isInput: true, + schemaChangeId: '0', + typeName: 'Foo', + }, + ]); + }); + + test('Change the type of an Input field', async () => { + const a = buildSchema(/* GraphQL */ ` + input Foo { + a: String! + } + `); + const b = buildSchema(/* GraphQL */ ` + input Foo { + a: Int! + } + `); + + const changes = await getBreakingChanges(a, b); + + expect(changes).toEqual([ + { + fieldName: 'a', + isInput: true, + schemaChangeId: '0', + typeName: 'Foo', + }, + ]); + }); + }); + + describe('Types', (ctx) => { + test('Type removed', async () => { + const a = buildSchema(/* GraphQL */ ` + type Rocket { + details: String + } + type Query { + a(b: Boolean!): Rocket + } + `); + const b = buildSchema(/* GraphQL */ ` + type Query { + a(b: Boolean!): String + } + `); + + const changes = await getBreakingChanges(a, b); + + expect(changes).toEqual([ + { + schemaChangeId: '0', + typeName: 'Rocket', + }, + { + fieldName: 'a', + schemaChangeId: '1', + typeName: 'Query', + }, + ]); + }); + }); + + describe('Enums', (ctx) => { + test('Enum Value added', async () => { + const a = buildSchema(/* GraphQL */ ` + type Query { + fieldA: String + } + + enum enumA { + A + } + `); + + const b = buildSchema(/* GraphQL */ ` + type Query { + fieldA: String + } + + enum enumA { + A + B + } + `); + + const changes = await getBreakingChanges(a, b); + + expect(changes).toEqual([ + { + namedType: 'enumA', + schemaChangeId: '0', + }, + ]); + }); + }); +}); + +async function getBreakingChanges(a: GraphQLSchema, b: GraphQLSchema): Promise { + const changes = await getSchemaDiff(a, b); + return changes + .map((c, i) => + toInspectorChange( + { + path: c.path!, + message: c.message, + changeType: c.changeType, + isBreaking: c.isBreaking, + }, + i.toString(), + ), + ) + .filter((c) => c !== null) as InspectorSchemaChange[]; +} diff --git a/controlplane/src/core/services/SchemaUsageTrafficInspector.ts b/controlplane/src/core/services/SchemaUsageTrafficInspector.ts index e5886b5426..c4ff194921 100644 --- a/controlplane/src/core/services/SchemaUsageTrafficInspector.ts +++ b/controlplane/src/core/services/SchemaUsageTrafficInspector.ts @@ -1,12 +1,16 @@ +import { ChangeType } from '@graphql-inspector/core'; import { ClickHouseClient } from '../clickhouse/index.js'; import { SchemaDiff } from '../composition/schemaCheck.js'; import { SchemaCheckChangeAction } from '../../db/models.js'; export interface InspectorSchemaChange { schemaChangeId: string; - typeName: string; + typeName?: string; namedType?: string; fieldName?: string; + path?: string[]; + isInput?: boolean; + isArgument?: boolean; } export interface InspectorFilter { @@ -15,11 +19,6 @@ export interface InspectorFilter { daysToConsider: number; } -export interface InspectorChanges { - inspectable: boolean; - changes: InspectorSchemaChange[]; -} - export interface InspectorOperationResult { schemaChangeId: string; hash: string; @@ -44,16 +43,28 @@ export class SchemaUsageTrafficInspector { for (const change of changes) { const where: string[] = []; - // Only for enum value changes + // Used for arguments usage check + if (change.path) { + where.push( + `startsWith(Path, [${change.path.map((seg) => `'${seg}'`).join(',')}]) AND length(Path) = ${ + change.path.length + }`, + ); + } if (change.namedType) { where.push(`NamedType = '${change.namedType}'`); } if (change.typeName) { where.push(`hasAny(TypeNames, ['${change.typeName}'])`); - // fieldName can be empty if a type was removed - if (change.fieldName) { - where.push(`FieldName = '${change.fieldName}'`); - } + } + // fieldName can be empty if a type was removed + if (change.fieldName) { + where.push(`FieldName = '${change.fieldName}'`); + } + if (change.isInput) { + where.push(`IsInput = true`); + } else if (change.isArgument) { + where.push(`IsArgument = true`); } const query = ` @@ -64,6 +75,7 @@ export class SchemaUsageTrafficInspector { max(toUnixTimestamp(Timestamp)) as lastSeen FROM ${this.client.database}.gql_metrics_schema_usage_5m_90d WHERE + -- Filter first on date and customer to reduce the amount of data Timestamp >= toStartOfDay(now()) - interval ${filter.daysToConsider} day AND FederatedGraphID = '${filter.federatedGraphId}' AND OrganizationID = '${filter.organizationId}' AND @@ -99,97 +111,28 @@ export class SchemaUsageTrafficInspector { } /** - * Check if a schema change is fully inspectable. - * Fully inspectable means that we can translate the schema change to an inspector change. - * If this is not given, we add the risk to release breaking changes that are not covered by the traffic analysis. - */ - private isInspectable(schemaChanges: SchemaDiff[]): boolean { - return schemaChanges.every((change) => { - switch (change.changeType) { - case 'INPUT_FIELD_TYPE_CHANGED': - case 'INPUT_FIELD_REMOVED': - case 'INPUT_FIELD_DEFAULT_VALUE_CHANGED': - case 'FIELD_ARGUMENT_REMOVED': - case 'FIELD_ARGUMENT_TYPE_CHANGED': - case 'FIELD_ARGUMENT_DEFAULT_CHANGED': - case 'DIRECTIVE_REMOVED': - case 'DIRECTIVE_ARGUMENT_REMOVED': - case 'DIRECTIVE_ARGUMENT_DEFAULT_VALUE_CHANGED': - case 'DIRECTIVE_LOCATION_REMOVED': { - return false; - } - default: { - return true; - } - } - }); - } - - /** - * Convert schema changes to inspector changes. + * Convert schema changes to inspector changes. Throws an error if a change is not supported. + * Ultimately, will result in a breaking change because the change is not inspectable with the current implementation. */ public schemaChangesToInspectorChanges( schemaChanges: SchemaDiff[], schemaCheckActions: SchemaCheckChangeAction[], - ): InspectorChanges { - const inspectable = this.isInspectable(schemaChanges); - if (!inspectable) { - return { inspectable: false, changes: [] }; - } - + ): InspectorSchemaChange[] { const operations = schemaChanges .map((change) => { - const path = change.path.split('.'); // find the schema check action that matches the change const schemaCheckAction = schemaCheckActions.find( (action) => action.path === change.path && action.changeType === change.changeType, ); - // there must be a schema check action for every change otherwise it is a bug if (!schemaCheckAction) { - return null; - } - - switch (change.changeType) { - // 1. When a type is removed we know the exact type name e.g. 'Engineer'. We have no field name. - // 2. When an interface type is removed or added we know the interface 'RoleType'. We have no field name. - case 'TYPE_REMOVED': - case 'OBJECT_TYPE_INTERFACE_ADDED': - case 'OBJECT_TYPE_INTERFACE_REMOVED': { - return { - schemaChangeId: schemaCheckAction.id, - typeName: path[0], - } as InspectorSchemaChange; - } - // 1. When a field is removed we know the exact type and field name e.g. 'Engineer.name' - // 2. When a field type has changed in a breaking way, we know the exact type name and field name e.g. 'Engineer.name' - case 'FIELD_REMOVED': - case 'FIELD_TYPE_CHANGED': { - return { - schemaChangeId: schemaCheckAction.id, - typeName: path[0], - fieldName: path[1], - } as InspectorSchemaChange; - } - // 1. When an enum value is added or removed, we only know the affected type. This is fine because any change to an enum value is breaking. - // 2. When a union member is removed, we only know the affected parent type. We use namedType to check for the usage of the union member. - case 'UNION_MEMBER_REMOVED': - case 'ENUM_VALUE_ADDED': - case 'ENUM_VALUE_REMOVED': { - return { - schemaChangeId: schemaCheckAction.id, - namedType: path[0], - } as InspectorSchemaChange; - } - default: { - // ignore all other changes - throw new Error(`Unsupported change type ${change.changeType}`); - } + throw new Error(`Could not find schema check action for change ${change.message}`); } + return toInspectorChange(change, schemaCheckAction.id); }) .filter((change) => change !== null) as InspectorSchemaChange[]; - return { inspectable: true, changes: operations }; + return operations; } } @@ -236,3 +179,112 @@ export function collectOperationUsageStats(inspectorResult: InspectorOperationRe lastSeenAt: lastSeenAt.toUTCString(), }; } + +/** + * Convert a schema change to an inspector change. Throws an error if the change is not supported. + * Only breaking changes should be passed to this function because we only care about breaking changes. + */ +export function toInspectorChange(change: SchemaDiff, schemaCheckId: string): InspectorSchemaChange | null { + const path = change.path.split('.'); + + switch (change.changeType) { + // Not inspectable yet + case ChangeType.SchemaMutationTypeChanged: + case ChangeType.SchemaQueryTypeChanged: + case ChangeType.SchemaSubscriptionTypeChanged: + case ChangeType.DirectiveRemoved: + case ChangeType.DirectiveArgumentAdded: + case ChangeType.DirectiveArgumentRemoved: + case ChangeType.DirectiveArgumentDefaultValueChanged: + case ChangeType.DirectiveArgumentTypeChanged: + case ChangeType.DirectiveLocationRemoved: { + throw new Error(`Directive or schema root type changes are not inspectable`); + } + // Safe to ignore + case ChangeType.DirectiveAdded: + case ChangeType.FieldArgumentDescriptionChanged: + case ChangeType.FieldArgumentDefaultChanged: + case ChangeType.DirectiveDescriptionChanged: + case ChangeType.DirectiveArgumentDescriptionChanged: + case ChangeType.DirectiveLocationAdded: + case ChangeType.EnumValueDescriptionChanged: + case ChangeType.EnumValueDeprecationReasonChanged: + case ChangeType.EnumValueDeprecationReasonAdded: + case ChangeType.EnumValueDeprecationReasonRemoved: + case ChangeType.FieldDescriptionChanged: + case ChangeType.FieldDescriptionAdded: + case ChangeType.FieldDescriptionRemoved: + case ChangeType.FieldDeprecationAdded: + case ChangeType.FieldDeprecationRemoved: + case ChangeType.FieldDeprecationReasonChanged: + case ChangeType.FieldDeprecationReasonAdded: + case ChangeType.FieldDeprecationReasonRemoved: + case ChangeType.InputFieldDescriptionAdded: + case ChangeType.InputFieldDescriptionRemoved: + case ChangeType.InputFieldDescriptionChanged: + case ChangeType.InputFieldDefaultValueChanged: + case ChangeType.TypeDescriptionChanged: + case ChangeType.TypeDescriptionRemoved: + case ChangeType.TypeDescriptionAdded: + case ChangeType.TypeAdded: + case ChangeType.FieldAdded: + case ChangeType.UnionMemberAdded: { + return null; + } + // 1. When a type is removed we know the exact type name e.g. 'Engineer'. We have no field name. + // 2. When an interface type is removed or added we know the interface 'RoleType'. We have no field name. + case ChangeType.TypeRemoved: + case ChangeType.TypeKindChanged: + case ChangeType.ObjectTypeInterfaceAdded: + case ChangeType.ObjectTypeInterfaceRemoved: { + return { + schemaChangeId: schemaCheckId, + typeName: path[0], + }; + } + // 1. When a field is removed we know the exact type and field name e.g. 'Engineer.name' + // 2. When a field type has changed in a breaking way, we know the exact type name and field name e.g. 'Engineer.name' + case ChangeType.FieldRemoved: + case ChangeType.FieldTypeChanged: { + return { + schemaChangeId: schemaCheckId, + typeName: path[0], + fieldName: path[1], + }; + } + // 1. When an enum value is added or removed, we only know the affected type. This is fine because any change to an enum value is breaking. + // 2. When a union member is removed, we only know the affected parent type. We use namedType to check for the usage of the union member. + case ChangeType.UnionMemberRemoved: + case ChangeType.EnumValueAdded: + case ChangeType.EnumValueRemoved: { + return { + schemaChangeId: schemaCheckId, + namedType: path[0], + }; + } + // 1. When the type of input field has changed, we know the exact type name and field name e.g. 'MyInput.name' + case ChangeType.InputFieldTypeChanged: + case ChangeType.InputFieldRemoved: + case ChangeType.InputFieldAdded: { + return { + schemaChangeId: schemaCheckId, + fieldName: path[1], + typeName: path[0], + isInput: true, + }; + } + // 1. When an argument has changed, we know the exact path to the argument e.g. 'Query.engineer.id' + // and the type name e.g. 'Query' + case ChangeType.FieldArgumentRemoved: + case ChangeType.FieldArgumentAdded: // Only when a required argument is added + case ChangeType.FieldArgumentTypeChanged: { + return { + schemaChangeId: schemaCheckId, + path: path.slice(1), // The path to the updated argument e.g. 'engineer.name' of the type names + typeName: path[0], // Enclosing type e.g. 'Query' or 'Engineer' when the argument is on a field of type Engineer + isArgument: true, + }; + } + } + // no return to enforce that all cases are handled +} diff --git a/controlplane/src/db/models.ts b/controlplane/src/db/models.ts index 58dcab72bd..9c1d9340a7 100644 --- a/controlplane/src/db/models.ts +++ b/controlplane/src/db/models.ts @@ -1,7 +1,6 @@ import { federatedGraphs, memberRoleEnum, - organizationsMembers, schemaCheckChangeAction, schemaCheckChangeActionOperationUsage, subgraphs, diff --git a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index a55bb1b000..a2a544fdbe 100644 --- a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -146,6 +146,10 @@ type SchemaUsageInfo struct { RequestInfo *RequestInfo `protobuf:"bytes,6,opt,name=RequestInfo,proto3" json:"RequestInfo,omitempty"` // Attributes is a map of attributes that can be used to filter the metrics Attributes map[string]string `protobuf:"bytes,7,rep,name=Attributes,proto3" json:"Attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // ArgumentMetrics is the list of used arguments in the request document + ArgumentMetrics []*ArgumentUsageInfo `protobuf:"bytes,8,rep,name=ArgumentMetrics,proto3" json:"ArgumentMetrics,omitempty"` + // InputMetrics is the list of used input fields in the request document + InputMetrics []*InputUsageInfo `protobuf:"bytes,9,rep,name=InputMetrics,proto3" json:"InputMetrics,omitempty"` } func (x *SchemaUsageInfo) Reset() { @@ -229,6 +233,20 @@ func (x *SchemaUsageInfo) GetAttributes() map[string]string { return nil } +func (x *SchemaUsageInfo) GetArgumentMetrics() []*ArgumentUsageInfo { + if x != nil { + return x.ArgumentMetrics + } + return nil +} + +func (x *SchemaUsageInfo) GetInputMetrics() []*InputUsageInfo { + if x != nil { + return x.InputMetrics + } + return nil +} + type ClientInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -407,11 +425,11 @@ type TypeFieldUsageInfo struct { // Path is the path to the field in the request document but without the root type query, mutation, or subscription Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` - // TypeNames is the list of type names that the field is used as + // TypeNames is the list of enclosing type names of the field TypeNames []string `protobuf:"bytes,2,rep,name=TypeNames,proto3" json:"TypeNames,omitempty"` // SubgraphIDs is the list of datasource IDs (e.g subgraph ID) that the field is used from SubgraphIDs []string `protobuf:"bytes,3,rep,name=SubgraphIDs,proto3" json:"SubgraphIDs,omitempty"` - // Count is the number of times the field is used + // Count is the number of times the field is used. Useful for batching at client side. Count uint64 `protobuf:"varint,4,opt,name=Count,proto3" json:"Count,omitempty"` // NamedType is the underlying type of the field NamedType string `protobuf:"bytes,5,opt,name=NamedType,proto3" json:"NamedType,omitempty"` @@ -484,6 +502,156 @@ func (x *TypeFieldUsageInfo) GetNamedType() string { return "" } +type ArgumentUsageInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path is the path to the field in the request document but without the root type query, mutation, or subscription + Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` + // TypeName is the enclosing type name of the argument + TypeName string `protobuf:"bytes,2,opt,name=TypeName,proto3" json:"TypeName,omitempty"` + // Count is the number of times the argument is used. Useful for batching at client side. + Count uint64 `protobuf:"varint,3,opt,name=Count,proto3" json:"Count,omitempty"` + // NamedType is the underlying type of the argument + NamedType string `protobuf:"bytes,4,opt,name=NamedType,proto3" json:"NamedType,omitempty"` +} + +func (x *ArgumentUsageInfo) Reset() { + *x = ArgumentUsageInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArgumentUsageInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArgumentUsageInfo) ProtoMessage() {} + +func (x *ArgumentUsageInfo) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArgumentUsageInfo.ProtoReflect.Descriptor instead. +func (*ArgumentUsageInfo) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{6} +} + +func (x *ArgumentUsageInfo) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +func (x *ArgumentUsageInfo) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ArgumentUsageInfo) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *ArgumentUsageInfo) GetNamedType() string { + if x != nil { + return x.NamedType + } + return "" +} + +type InputUsageInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path is the path to the field in the request document but without the root type query, mutation, or subscription + Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` + // TypeName is the enclosing type name of the argument + TypeName string `protobuf:"bytes,2,opt,name=TypeName,proto3" json:"TypeName,omitempty"` + // Count is the number of times the argument is used. Useful for batching at client side. + Count uint64 `protobuf:"varint,3,opt,name=Count,proto3" json:"Count,omitempty"` + // NamedType is the underlying type of the input field + NamedType string `protobuf:"bytes,4,opt,name=NamedType,proto3" json:"NamedType,omitempty"` +} + +func (x *InputUsageInfo) Reset() { + *x = InputUsageInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InputUsageInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InputUsageInfo) ProtoMessage() {} + +func (x *InputUsageInfo) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InputUsageInfo.ProtoReflect.Descriptor instead. +func (*InputUsageInfo) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{7} +} + +func (x *InputUsageInfo) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +func (x *InputUsageInfo) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *InputUsageInfo) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *InputUsageInfo) GetNamedType() string { + if x != nil { + return x.NamedType + } + return "" +} + type PublishGraphQLRequestMetricsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -495,7 +663,7 @@ type PublishGraphQLRequestMetricsRequest struct { func (x *PublishGraphQLRequestMetricsRequest) Reset() { *x = PublishGraphQLRequestMetricsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -508,7 +676,7 @@ func (x *PublishGraphQLRequestMetricsRequest) String() string { func (*PublishGraphQLRequestMetricsRequest) ProtoMessage() {} func (x *PublishGraphQLRequestMetricsRequest) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -521,7 +689,7 @@ func (x *PublishGraphQLRequestMetricsRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use PublishGraphQLRequestMetricsRequest.ProtoReflect.Descriptor instead. func (*PublishGraphQLRequestMetricsRequest) Descriptor() ([]byte, []int) { - return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{6} + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{8} } func (x *PublishGraphQLRequestMetricsRequest) GetSchemaUsage() []*SchemaUsageInfo { @@ -540,7 +708,7 @@ type PublishOperationCoverageReportResponse struct { func (x *PublishOperationCoverageReportResponse) Reset() { *x = PublishOperationCoverageReportResponse{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -553,7 +721,7 @@ func (x *PublishOperationCoverageReportResponse) String() string { func (*PublishOperationCoverageReportResponse) ProtoMessage() {} func (x *PublishOperationCoverageReportResponse) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -566,7 +734,7 @@ func (x *PublishOperationCoverageReportResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use PublishOperationCoverageReportResponse.ProtoReflect.Descriptor instead. func (*PublishOperationCoverageReportResponse) Descriptor() ([]byte, []int) { - return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{7} + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{9} } var File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto protoreflect.FileDescriptor @@ -583,7 +751,7 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x22, 0xdf, 0x04, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x88, 0x06, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5a, @@ -617,79 +785,104 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x3a, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x76, - 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, - 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x9c, - 0x01, 0x0a, 0x12, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x73, 0x61, 0x67, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x79, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x79, - 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x49, 0x44, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x75, - 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x49, 0x44, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x74, 0x0a, - 0x23, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0b, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x77, 0x67, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, - 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, 0x0a, - 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, - 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, 0x54, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, 0x43, - 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x32, 0xb8, 0x01, 0x0a, 0x15, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, 0x2e, - 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, + 0x74, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x0f, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x77, + 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x41, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x4e, 0x0a, 0x0c, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3a, 0x0a, 0x0a, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x76, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x3d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, - 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, - 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0xa3, 0x02, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x61, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, - 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, - 0x3b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, - 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, 0x02, 0x1a, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, - 0x31, 0xe2, 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, - 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, - 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x22, + 0x26, 0x0a, 0x0a, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x9c, 0x01, 0x0a, 0x12, 0x54, 0x79, 0x70, 0x65, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, + 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x49, 0x44, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x49, + 0x44, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, + 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x77, 0x0a, 0x11, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x50, + 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x1a, 0x0a, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, + 0x74, 0x0a, 0x0e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x74, 0x0a, 0x23, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0b, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, + 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x02, 0x32, 0xb8, 0x01, 0x0a, 0x15, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x15, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, + 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xa3, 0x02, 0x0a, + 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, + 0x13, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x61, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, + 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, + 0x02, 0x1a, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, + 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -705,7 +898,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP() []byte { } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []interface{}{ (OperationType)(0), // 0: wg.cosmo.graphqlmetrics.v1.OperationType (*RequestInfo)(nil), // 1: wg.cosmo.graphqlmetrics.v1.RequestInfo @@ -714,26 +907,30 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []interface{} (*OperationInfo)(nil), // 4: wg.cosmo.graphqlmetrics.v1.OperationInfo (*SchemaInfo)(nil), // 5: wg.cosmo.graphqlmetrics.v1.SchemaInfo (*TypeFieldUsageInfo)(nil), // 6: wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo - (*PublishGraphQLRequestMetricsRequest)(nil), // 7: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest - (*PublishOperationCoverageReportResponse)(nil), // 8: wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse - nil, // 9: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + (*ArgumentUsageInfo)(nil), // 7: wg.cosmo.graphqlmetrics.v1.ArgumentUsageInfo + (*InputUsageInfo)(nil), // 8: wg.cosmo.graphqlmetrics.v1.InputUsageInfo + (*PublishGraphQLRequestMetricsRequest)(nil), // 9: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest + (*PublishOperationCoverageReportResponse)(nil), // 10: wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse + nil, // 11: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_depIdxs = []int32{ - 6, // 0: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.TypeFieldMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo - 4, // 1: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.OperationInfo:type_name -> wg.cosmo.graphqlmetrics.v1.OperationInfo - 5, // 2: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.SchemaInfo:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaInfo - 3, // 3: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ClientInfo:type_name -> wg.cosmo.graphqlmetrics.v1.ClientInfo - 1, // 4: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.RequestInfo:type_name -> wg.cosmo.graphqlmetrics.v1.RequestInfo - 9, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry - 0, // 6: wg.cosmo.graphqlmetrics.v1.OperationInfo.Type:type_name -> wg.cosmo.graphqlmetrics.v1.OperationType - 2, // 7: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo - 7, // 8: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest - 8, // 9: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse - 9, // [9:10] is the sub-list for method output_type - 8, // [8:9] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 6, // 0: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.TypeFieldMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo + 4, // 1: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.OperationInfo:type_name -> wg.cosmo.graphqlmetrics.v1.OperationInfo + 5, // 2: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.SchemaInfo:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaInfo + 3, // 3: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ClientInfo:type_name -> wg.cosmo.graphqlmetrics.v1.ClientInfo + 1, // 4: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.RequestInfo:type_name -> wg.cosmo.graphqlmetrics.v1.RequestInfo + 11, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + 7, // 6: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ArgumentMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.ArgumentUsageInfo + 8, // 7: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.InputMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.InputUsageInfo + 0, // 8: wg.cosmo.graphqlmetrics.v1.OperationInfo.Type:type_name -> wg.cosmo.graphqlmetrics.v1.OperationType + 2, // 9: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo + 9, // 10: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest + 10, // 11: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse + 11, // [11:12] is the sub-list for method output_type + 10, // [10:11] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() } @@ -815,7 +1012,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { } } file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PublishGraphQLRequestMetricsRequest); i { + switch v := v.(*ArgumentUsageInfo); i { case 0: return &v.state case 1: @@ -827,6 +1024,30 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { } } file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InputUsageInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublishGraphQLRequestMetricsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PublishOperationCoverageReportResponse); i { case 0: return &v.state @@ -845,7 +1066,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc, NumEnums: 1, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/graphqlmetrics/metrics_service.go b/graphqlmetrics/metrics_service.go index 202bd7d047..c50767ab9b 100644 --- a/graphqlmetrics/metrics_service.go +++ b/graphqlmetrics/metrics_service.go @@ -163,10 +163,70 @@ func (s *MetricsService) PublishGraphQLMetrics( strconv.FormatInt(int64(schemaUsage.RequestInfo.StatusCode), 10), schemaUsage.RequestInfo.Error, fieldUsage.SubgraphIDs, + false, + false, schemaUsage.Attributes, ) if err != nil { - s.logger.Error("Failed to append metric to batch", zap.Error(err)) + s.logger.Error("Failed to append field metric to batch", zap.Error(err)) + return nil, errMetricWriteFailed + } + } + + for _, argumentUsage := range schemaUsage.ArgumentMetrics { + + err := metricBatch.Append( + insertTime, + claims.OrganizationID, + claims.FederatedGraphID, + schemaUsage.SchemaInfo.Version, + schemaUsage.OperationInfo.Hash, + schemaUsage.OperationInfo.Name, + operationType, + argumentUsage.Count, + argumentUsage.Path, + []string{argumentUsage.TypeName}, + argumentUsage.NamedType, + schemaUsage.ClientInfo.Name, + schemaUsage.ClientInfo.Version, + strconv.FormatInt(int64(schemaUsage.RequestInfo.StatusCode), 10), + schemaUsage.RequestInfo.Error, + []string{}, + true, + false, + schemaUsage.Attributes, + ) + if err != nil { + s.logger.Error("Failed to append argument metric to batch", zap.Error(err)) + return nil, errMetricWriteFailed + } + } + + for _, inputUsage := range schemaUsage.InputMetrics { + + err := metricBatch.Append( + insertTime, + claims.OrganizationID, + claims.FederatedGraphID, + schemaUsage.SchemaInfo.Version, + schemaUsage.OperationInfo.Hash, + schemaUsage.OperationInfo.Name, + operationType, + inputUsage.Count, + inputUsage.Path, + []string{inputUsage.TypeName}, + inputUsage.NamedType, + schemaUsage.ClientInfo.Name, + schemaUsage.ClientInfo.Version, + strconv.FormatInt(int64(schemaUsage.RequestInfo.StatusCode), 10), + schemaUsage.RequestInfo.Error, + []string{}, + false, + true, + schemaUsage.Attributes, + ) + if err != nil { + s.logger.Error("Failed to append input metric to batch", zap.Error(err)) return nil, errMetricWriteFailed } } diff --git a/graphqlmetrics/migrations/20231010143332_graphql_schema_usage_table.sql b/graphqlmetrics/migrations/20231010143332_graphql_schema_usage_table.sql index 13f1881ac1..84873bc56f 100644 --- a/graphqlmetrics/migrations/20231010143332_graphql_schema_usage_table.sql +++ b/graphqlmetrics/migrations/20231010143332_graphql_schema_usage_table.sql @@ -36,6 +36,12 @@ CREATE TABLE IF NOT EXISTS gql_metrics_schema_usage -- SubgraphIDs identify the subgraphs that were used to resolve the field SubgraphIDs Array(LowCardinality(String)) CODEC(ZSTD(3)), -- Sorted before insertion + -- Indicates if the usage was from an argument or a field + IsArgument bool CODEC(ZSTD(3)), + + -- Indicates if the usage was from an input field + IsInput bool CODEC(ZSTD(3)), + -- Additional information Attributes Map(LowCardinality(String), String) CODEC(ZSTD(3)), diff --git a/graphqlmetrics/migrations/20231010143333_graphql_schema_usage_table_5m_90d.sql b/graphqlmetrics/migrations/20231010143333_graphql_schema_usage_table_5m_90d.sql index a1f0e106f2..a2612a2bd1 100644 --- a/graphqlmetrics/migrations/20231010143333_graphql_schema_usage_table_5m_90d.sql +++ b/graphqlmetrics/migrations/20231010143333_graphql_schema_usage_table_5m_90d.sql @@ -29,6 +29,12 @@ CREATE TABLE IF NOT EXISTS gql_metrics_schema_usage_5m_90d -- SubgraphIDs identify the subgraphs that were used to resolve the field SubgraphIDs Array(LowCardinality(String)) CODEC(ZSTD(3)), + -- Indicates if the usage was from an argument or a field + IsArgument bool CODEC(ZSTD(3)), + + -- Indicates if the usage was from an input field + IsInput bool CODEC(ZSTD(3)), + --- Total usages TotalUsages UInt64 CODEC(ZSTD(3)), TotalErrors UInt64 CODEC(ZSTD(3)), @@ -44,7 +50,7 @@ CREATE TABLE IF NOT EXISTS gql_metrics_schema_usage_5m_90d ) ENGINE = SummingMergeTree PARTITION BY toDate(Timestamp) -ORDER BY (OrganizationID, FederatedGraphID, ClientName, ClientVersion, RouterConfigVersion, OperationHash, Path, FieldName, NamedType, TypeNames, SubgraphIDs, toUnixTimestamp(Timestamp)) +ORDER BY (OrganizationID, FederatedGraphID, ClientName, ClientVersion, RouterConfigVersion, OperationHash, Path, FieldName, NamedType, TypeNames, SubgraphIDs, IsArgument, IsInput, toUnixTimestamp(Timestamp)) -- We store 90 days of data in this table. TTL toDateTime(Timestamp) + toIntervalDay(90) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1 diff --git a/graphqlmetrics/migrations/20231010143334_graphql_metrics_schema_usage_5m_90d_mv.sql b/graphqlmetrics/migrations/20231010143334_graphql_metrics_schema_usage_5m_90d_mv.sql index c585a58b22..6c802e415f 100644 --- a/graphqlmetrics/migrations/20231010143334_graphql_metrics_schema_usage_5m_90d_mv.sql +++ b/graphqlmetrics/migrations/20231010143334_graphql_metrics_schema_usage_5m_90d_mv.sql @@ -19,6 +19,8 @@ SELECT toLowCardinality(ClientName) as ClientName, toLowCardinality(ClientVersion) as ClientVersion, SubgraphIDs as SubgraphIDs, + IsArgument as IsArgument, + IsInput as IsInput, sum(Count) as TotalUsages, sumIf(Count, HasError OR position(HttpStatusCode,'5') = 1 OR position(HttpStatusCode,'4') = 1) as TotalErrors, sumIf(Count, position(HttpStatusCode,'4') = 1) AS TotalClientErrors @@ -38,7 +40,9 @@ GROUP BY FieldName, NamedType, TypeNames, - SubgraphIDs + SubgraphIDs, + IsArgument, + IsInput ORDER BY Timestamp; diff --git a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto index 00fc4c90d1..a9b1801ef9 100644 --- a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto +++ b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto @@ -12,7 +12,6 @@ enum OperationType { SUBSCRIPTION = 2; } message RequestInfo { - int32 StatusCode = 1; bool error = 2; } @@ -32,6 +31,10 @@ message SchemaUsageInfo { RequestInfo RequestInfo = 6; // Attributes is a map of attributes that can be used to filter the metrics map Attributes = 7; + // ArgumentMetrics is the list of used arguments in the request document + repeated ArgumentUsageInfo ArgumentMetrics = 8; + // InputMetrics is the list of used input fields in the request document + repeated InputUsageInfo InputMetrics = 9; } message ClientInfo { @@ -60,16 +63,38 @@ message SchemaInfo { message TypeFieldUsageInfo { // Path is the path to the field in the request document but without the root type query, mutation, or subscription repeated string Path = 1; - // TypeNames is the list of type names that the field is used as + // TypeNames is the list of enclosing type names of the field repeated string TypeNames = 2; // SubgraphIDs is the list of datasource IDs (e.g subgraph ID) that the field is used from repeated string SubgraphIDs = 3; - // Count is the number of times the field is used + // Count is the number of times the field is used. Useful for batching at client side. uint64 Count = 4; // NamedType is the underlying type of the field string NamedType = 5; } +message ArgumentUsageInfo { + // Path is the path to the field in the request document but without the root type query, mutation, or subscription + repeated string Path = 1; + // TypeName is the enclosing type name of the argument + string TypeName = 2; + // Count is the number of times the argument is used. Useful for batching at client side. + uint64 Count = 3; + // NamedType is the underlying type of the argument + string NamedType = 4; +} + +message InputUsageInfo { + // Path is the path to the field in the request document but without the root type query, mutation, or subscription + repeated string Path = 1; + // TypeName is the enclosing type name of the argument + string TypeName = 2; + // Count is the number of times the argument is used. Useful for batching at client side. + uint64 Count = 3; + // NamedType is the underlying type of the input field + string NamedType = 4; +} + message PublishGraphQLRequestMetricsRequest { repeated SchemaUsageInfo SchemaUsage = 1; } diff --git a/proto/wg/cosmo/platform/v1/platform.proto b/proto/wg/cosmo/platform/v1/platform.proto index da7a12d811..708bdbb34f 100644 --- a/proto/wg/cosmo/platform/v1/platform.proto +++ b/proto/wg/cosmo/platform/v1/platform.proto @@ -127,6 +127,8 @@ message CheckSubgraphSchemaResponse { repeated SchemaChange breakingChanges = 2; repeated SchemaChange nonBreakingChanges = 3; repeated CompositionError compositionErrors = 4; + // Contains the operation usage stats for the operations that are impacted by the schema changes. + // Can be undefined when the schema changes are not inspectable by real traffic breaking change detection. CheckOperationUsageStats operationUsageStats = 5; } diff --git a/router-tests/go.mod b/router-tests/go.mod index 87258bbf70..92bada9ddb 100644 --- a/router-tests/go.mod +++ b/router-tests/go.mod @@ -90,7 +90,7 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/urfave/cli/v2 v2.25.5 // indirect github.com/vektah/gqlparser/v2 v2.5.10 // indirect - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231107092313-0c3d635b9c18 // indirect + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231110114615-aaa3d9a98722 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect diff --git a/router-tests/go.sum b/router-tests/go.sum index 1115dd3aaa..c12184bb8b 100644 --- a/router-tests/go.sum +++ b/router-tests/go.sum @@ -273,8 +273,8 @@ github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/vektah/gqlparser/v2 v2.5.10 h1:6zSM4azXC9u4Nxy5YmdmGu4uKamfwsdKTwp5zsEealU= github.com/vektah/gqlparser/v2 v2.5.10/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231107092313-0c3d635b9c18 h1:uehizkCPbiyKeVwlTsDo+LpUMcpLAok23BogfKZIrxo= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231107092313-0c3d635b9c18/go.mod h1:NQ2xZkUCh3sdbmMVusyYCd+HmlQ/rKFFHCvr6JIRhIY= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231110114615-aaa3d9a98722 h1:2dNt/fqDIw/4C2ZtZHngbPJKJBJ9m1xM4ttbwaBcPNM= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231110114615-aaa3d9a98722/go.mod h1:NQ2xZkUCh3sdbmMVusyYCd+HmlQ/rKFFHCvr6JIRhIY= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/router/core/context.go b/router/core/context.go index 4b1cd4b68c..438295254b 100644 --- a/router/core/context.go +++ b/router/core/context.go @@ -349,6 +349,10 @@ type operationContext struct { preparedPlan *planWithMetaData } +func (o *operationContext) Variables() []byte { + return o.variables +} + func (o *operationContext) Name() string { return o.name } @@ -365,10 +369,6 @@ func (o *operationContext) Content() string { return o.content } -func (o *operationContext) Variables() []byte { - return o.variables -} - func (o *operationContext) ClientInfo() ClientInfo { return *o.clientInfo } @@ -409,10 +409,7 @@ func subgraphsFromContext(ctx context.Context) []Subgraph { return subgraphs } -func buildRequestContext(w http.ResponseWriter, r *http.Request, opContext *operationContext, operation *ParsedOperation, requestLogger *zap.Logger) *requestContext { - variablesCopy := make([]byte, len(operation.Variables)) - copy(variablesCopy, operation.Variables) - +func buildRequestContext(w http.ResponseWriter, r *http.Request, opContext *operationContext, requestLogger *zap.Logger) *requestContext { subgraphs := subgraphsFromContext(r.Context()) requestContext := &requestContext{ logger: requestLogger, @@ -422,6 +419,5 @@ func buildRequestContext(w http.ResponseWriter, r *http.Request, opContext *oper operation: opContext, subgraphs: subgraphs, } - return requestContext } diff --git a/router/core/graphql_handler.go b/router/core/graphql_handler.go index 7331f950c0..dadd54719a 100644 --- a/router/core/graphql_handler.go +++ b/router/core/graphql_handler.go @@ -107,13 +107,8 @@ func (h *GraphQLHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { requestLogger := h.log.With(logging.WithRequestID(middleware.GetReqID(r.Context()))) operationCtx := getOperationContext(r.Context()) - extractedVariables := make([]byte, len(operationCtx.preparedPlan.variables)) - copy(extractedVariables, operationCtx.preparedPlan.variables) - requestVariables := operationCtx.Variables() - combinedVariables := MergeJsonRightIntoLeft(requestVariables, extractedVariables) - ctx := &resolve.Context{ - Variables: combinedVariables, + Variables: operationCtx.Variables(), Request: resolve.Request{ Header: r.Header, }, diff --git a/router/core/graphql_prehandler.go b/router/core/graphql_prehandler.go index c1241697a8..7e20094341 100644 --- a/router/core/graphql_prehandler.go +++ b/router/core/graphql_prehandler.go @@ -60,7 +60,7 @@ func (h *PreHandler) Handler(next http.Handler) http.Handler { var writtenBytes int clientInfo := NewClientInfoFromRequest(r) - metrics := h.metrics.StartOperation(clientInfo, r.ContentLength) + metrics := h.metrics.StartOperation(clientInfo, requestLogger, r.ContentLength) defer func() { metrics.Finish(hasRequestError, statusCode, writtenBytes) @@ -110,7 +110,7 @@ func (h *PreHandler) Handler(next http.Handler) http.Handler { return } - requestContext := buildRequestContext(w, r, opContext, operation, requestLogger) + requestContext := buildRequestContext(w, r, opContext, requestLogger) metrics.AddOperationContext(opContext) ctxWithRequest := withRequestContext(r.Context(), requestContext) diff --git a/router/core/operation_metrics.go b/router/core/operation_metrics.go index 16f051d36a..8e0dce7fb2 100644 --- a/router/core/operation_metrics.go +++ b/router/core/operation_metrics.go @@ -2,9 +2,11 @@ package core import ( "context" + "go.uber.org/zap" "strconv" "time" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" semconv "go.opentelemetry.io/otel/semconv/v1.21.0" graphqlmetricsv1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" @@ -35,6 +37,7 @@ type OperationMetrics struct { gqlMetricsExporter *graphqlmetrics.Exporter routerConfigVersion string opContext *operationContext + logger *zap.Logger } func (m *OperationMetrics) exportSchemaUsageInfo(operationContext *operationContext, statusCode int, hasError bool) { @@ -42,15 +45,55 @@ func (m *OperationMetrics) exportSchemaUsageInfo(operationContext *operationCont return } - fieldUsageInfos := make([]*graphqlmetricsv1.TypeFieldUsageInfo, len(operationContext.preparedPlan.schemaUsageInfo.TypeFields)) + usageInfo, err := plan.GetSchemaUsageInfo( + operationContext.preparedPlan.preparedPlan, + operationContext.preparedPlan.operationDocument, + operationContext.preparedPlan.schemaDocument, + operationContext.Variables(), + ) + if err != nil { + m.logger.Error("failed to get schema usage info", zap.Error(err)) + return + } - for i := range operationContext.preparedPlan.schemaUsageInfo.TypeFields { + fieldUsageInfos := make([]*graphqlmetricsv1.TypeFieldUsageInfo, len(usageInfo.TypeFields)) + argumentUsageInfos := make([]*graphqlmetricsv1.ArgumentUsageInfo, len(usageInfo.Arguments)) + inputUsageInfos := make([]*graphqlmetricsv1.InputUsageInfo, len(usageInfo.InputTypeFields)) + + for i := range usageInfo.TypeFields { fieldUsageInfos[i] = &graphqlmetricsv1.TypeFieldUsageInfo{ Count: 1, - Path: operationContext.preparedPlan.schemaUsageInfo.TypeFields[i].Path, - TypeNames: operationContext.preparedPlan.schemaUsageInfo.TypeFields[i].TypeNames, - SubgraphIDs: operationContext.preparedPlan.schemaUsageInfo.TypeFields[i].Source.IDs, - NamedType: operationContext.preparedPlan.schemaUsageInfo.TypeFields[i].NamedType, + Path: usageInfo.TypeFields[i].Path, + TypeNames: usageInfo.TypeFields[i].EnclosingTypeNames, + SubgraphIDs: usageInfo.TypeFields[i].Source.IDs, + NamedType: usageInfo.TypeFields[i].FieldTypeName, + } + } + + for i := range usageInfo.Arguments { + argumentUsageInfos[i] = &graphqlmetricsv1.ArgumentUsageInfo{ + Count: 1, + Path: []string{usageInfo.Arguments[i].FieldName, usageInfo.Arguments[i].ArgumentName}, + TypeName: usageInfo.Arguments[i].EnclosingTypeName, + NamedType: usageInfo.Arguments[i].ArgumentTypeName, + } + } + + for i := range usageInfo.InputTypeFields { + // In that case it is a top level input field usage e.g employee(id: 1) + if len(usageInfo.InputTypeFields[i].EnclosingTypeNames) == 0 { + inputUsageInfos[i] = &graphqlmetricsv1.InputUsageInfo{ + Count: uint64(usageInfo.InputTypeFields[i].Count), + NamedType: usageInfo.InputTypeFields[i].FieldTypeName, + // Root input fields have no enclosing type name and no path + } + } else { + inputUsageInfos[i] = &graphqlmetricsv1.InputUsageInfo{ + Path: []string{usageInfo.InputTypeFields[i].EnclosingTypeNames[0], usageInfo.InputTypeFields[i].FieldName}, + Count: uint64(usageInfo.InputTypeFields[i].Count), + TypeName: usageInfo.InputTypeFields[i].EnclosingTypeNames[0], + NamedType: usageInfo.InputTypeFields[i].FieldTypeName, + } } } @@ -80,6 +123,8 @@ func (m *OperationMetrics) exportSchemaUsageInfo(operationContext *operationCont Name: operationContext.clientInfo.Name, Version: operationContext.clientInfo.Version, }, + ArgumentMetrics: argumentUsageInfos, + InputMetrics: inputUsageInfos, RequestInfo: &graphqlmetricsv1.RequestInfo{ Error: hasError, StatusCode: int32(statusCode), @@ -141,7 +186,7 @@ func (m *OperationMetrics) AddClientInfo(info *ClientInfo) { // startOperationMetrics starts the metrics for an operation. This should only be called by // RouterMetrics.StartOperation() -func startOperationMetrics(mtr *metric.Metrics, requestContentLength int64, gqlMetricsExporter *graphqlmetrics.Exporter, routerConfigVersion string) *OperationMetrics { +func startOperationMetrics(mtr *metric.Metrics, logger *zap.Logger, requestContentLength int64, gqlMetricsExporter *graphqlmetrics.Exporter, routerConfigVersion string) *OperationMetrics { operationStartTime := time.Now() inflightMetric := mtr.MeasureInFlight(context.Background()) @@ -152,6 +197,7 @@ func startOperationMetrics(mtr *metric.Metrics, requestContentLength int64, gqlM inflightMetric: inflightMetric, gqlMetricsExporter: gqlMetricsExporter, routerConfigVersion: routerConfigVersion, + logger: logger, } } diff --git a/router/core/operation_parser.go b/router/core/operation_parser.go index 8855f03243..62ad3d75b5 100644 --- a/router/core/operation_parser.go +++ b/router/core/operation_parser.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" "github.com/wundergraph/cosmo/router/internal/pool" "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astjson" "github.com/wundergraph/graphql-go-tools/v2/pkg/astnormalization" "github.com/wundergraph/graphql-go-tools/v2/pkg/astparser" "github.com/wundergraph/graphql-go-tools/v2/pkg/astprinter" @@ -59,10 +60,15 @@ func NewOperationParser(executor *Executor, maxOperationSizeInBytes int64) *Oper parseKitPool: &sync.Pool{ New: func() interface{} { return &parseKit{ - parser: astparser.NewParser(), - doc: ast.NewSmallDocument(), - keyGen: xxhash.New(), - normalizer: astnormalization.NewWithOpts(astnormalization.WithInlineFragmentSpreads(), astnormalization.WithRemoveFragmentDefinitions(), astnormalization.WithRemoveNotMatchingOperationDefinitions()), + parser: astparser.NewParser(), + doc: ast.NewSmallDocument(), + keyGen: xxhash.New(), + normalizer: astnormalization.NewWithOpts( + astnormalization.WithExtractVariables(), + astnormalization.WithInlineFragmentSpreads(), + astnormalization.WithRemoveFragmentDefinitions(), + astnormalization.WithRemoveNotMatchingOperationDefinitions(), + ), printer: &astprinter.Printer{}, normalizedOperation: &bytes.Buffer{}, unescapedDocument: make([]byte, 1024), @@ -242,6 +248,11 @@ func (p *OperationParser) parse(body []byte) (*ParsedOperation, error) { if err != nil { return nil, errors.WithStack(fmt.Errorf("failed to print normalized operation: %w", err)) } + // hash extracted variables + _, err = kit.keyGen.Write(kit.doc.Input.Variables) + if err != nil { + return nil, errors.WithStack(fmt.Errorf("failed to write variables: %w", err)) + } operationID := kit.keyGen.Sum64() // generate the operation ID // print the operation with the original operation name kit.doc.OperationDefinitions[operationDefinitionRef].Name = originalOperationNameRef @@ -250,11 +261,33 @@ func (p *OperationParser) parse(body []byte) (*ParsedOperation, error) { return nil, errors.WithStack(fmt.Errorf("failed to print normalized operation: %w", err)) } + if requestVariableBytes == nil { + requestVariableBytes = []byte("{}") + } + + js := &astjson.JSON{} + err = js.ParseObject(requestVariableBytes) + if err != nil { + return nil, errors.WithStack(fmt.Errorf("failed to parse variables: %w", err)) + } + if kit.doc.Input.Variables != nil { + extractedVariables, err := js.AppendObject(kit.doc.Input.Variables) + if err != nil { + return nil, errors.WithStack(fmt.Errorf("failed to append variables: %w", err)) + } + js.MergeNodes(js.RootNode, extractedVariables) + } + merged := bytes.NewBuffer(make([]byte, 0, len(requestVariableBytes)+len(kit.doc.Input.Variables))) + err = js.PrintRoot(merged) + if err != nil { + return nil, errors.WithStack(fmt.Errorf("failed to print variables: %w", err)) + } + return &ParsedOperation{ ID: operationID, Name: string(requestOperationNameBytes), Type: requestOperationType, - Variables: requestVariableBytes, + Variables: merged.Bytes(), NormalizedRepresentation: kit.normalizedOperation.String(), }, nil } diff --git a/router/core/operation_planner.go b/router/core/operation_planner.go index 93b6fb2115..5c28085b3b 100644 --- a/router/core/operation_planner.go +++ b/router/core/operation_planner.go @@ -3,11 +3,11 @@ package core import ( "context" "errors" - "github.com/wundergraph/graphql-go-tools/v2/pkg/astnormalization" "strconv" "github.com/dgraph-io/ristretto" "github.com/wundergraph/cosmo/router/internal/unsafebytes" + "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" "github.com/wundergraph/graphql-go-tools/v2/pkg/astparser" "github.com/wundergraph/graphql-go-tools/v2/pkg/astvalidation" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" @@ -16,9 +16,8 @@ import ( ) type planWithMetaData struct { - preparedPlan plan.Plan - variables []byte - schemaUsageInfo plan.SchemaUsageInfo + preparedPlan plan.Plan + operationDocument, schemaDocument *ast.Document } type OperationPlanner struct { @@ -42,9 +41,6 @@ func (p *OperationPlanner) preparePlan(requestOperationName []byte, requestOpera validation := astvalidation.DefaultOperationValidator() - norm := astnormalization.NewNormalizer(true, true) - norm.NormalizeOperation(&doc, p.executor.Definition, &report) - // validate the document before planning state := validation.Validate(&doc, p.executor.Definition, &report) if state != astvalidation.Valid { @@ -61,29 +57,21 @@ func (p *OperationPlanner) preparePlan(requestOperationName []byte, requestOpera post := postprocess.DefaultProcessor() post.Process(preparedPlan) - extractedVariables := make([]byte, len(doc.Input.Variables)) - copy(extractedVariables, doc.Input.Variables) - - schemaUsageInfo := plan.GetSchemaUsageInfo(preparedPlan) - return planWithMetaData{ - preparedPlan: preparedPlan, - variables: extractedVariables, - schemaUsageInfo: schemaUsageInfo, + preparedPlan: preparedPlan, + operationDocument: &doc, + schemaDocument: p.executor.Definition, }, nil } func (p *OperationPlanner) Plan(operation *ParsedOperation, clientInfo *ClientInfo) (*operationContext, error) { - variablesCopy := make([]byte, len(operation.Variables)) - copy(variablesCopy, operation.Variables) - opContext := &operationContext{ name: operation.Name, opType: operation.Type, content: operation.NormalizedRepresentation, hash: operation.ID, - variables: variablesCopy, clientInfo: clientInfo, + variables: operation.Variables, } operationID := opContext.Hash() diff --git a/router/core/router_metrics.go b/router/core/router_metrics.go index fde82fe7c2..9ed2ca68cf 100644 --- a/router/core/router_metrics.go +++ b/router/core/router_metrics.go @@ -3,6 +3,7 @@ package core import ( "github.com/wundergraph/cosmo/router/internal/graphqlmetrics" "github.com/wundergraph/cosmo/router/internal/metric" + "go.uber.org/zap" ) // RouterMetrics encapsulates all data and configuration that the router @@ -16,12 +17,12 @@ type RouterMetrics struct { // StartOperation starts the metrics for a new GraphQL operation. The returned value is a OperationMetrics // where the caller must always call Finish() (usually via defer()). If the metrics are disabled, this // returns nil, but OperationMetrics is safe to call with a nil receiver. -func (m *RouterMetrics) StartOperation(clientInfo *ClientInfo, requestContentLength int64) *OperationMetrics { +func (m *RouterMetrics) StartOperation(clientInfo *ClientInfo, logger *zap.Logger, requestContentLength int64) *OperationMetrics { if m == nil || m.metrics == nil { // Return a nil OperationMetrics, which will be a no-op, to simplify callers return nil } - metrics := startOperationMetrics(m.metrics, requestContentLength, m.gqlMetricsExporter, m.routerConfigVersion) + metrics := startOperationMetrics(m.metrics, logger, requestContentLength, m.gqlMetricsExporter, m.routerConfigVersion) if clientInfo != nil { metrics.AddClientInfo(clientInfo) } diff --git a/router/core/websocket.go b/router/core/websocket.go index 03109f97fc..85515236af 100644 --- a/router/core/websocket.go +++ b/router/core/websocket.go @@ -433,7 +433,7 @@ func (h *WebSocketConnectionHandler) executeSubscription(ctx context.Context, ms statusCode := http.StatusOK responseSize := 0 - metrics := h.metrics.StartOperation(h.clientInfo, int64(len(msg.Payload))) + metrics := h.metrics.StartOperation(h.clientInfo, h.logger, int64(len(msg.Payload))) defer func() { metrics.Finish(hasRequestError, statusCode, responseSize) }() @@ -479,7 +479,7 @@ func (h *WebSocketConnectionHandler) executeSubscription(ctx context.Context, ms rw := newWebsocketResponseWriter(msg.ID, h.protocol, h.logger) defer h.Complete(rw) - requestContext := buildRequestContext(rw, h.r, opContext, operation, h.logger) + requestContext := buildRequestContext(rw, h.r, opContext, h.logger) ctxWithOperation := withOperationContext(cancellableCtx, opContext) r := h.r.WithContext(ctxWithOperation) diff --git a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index a3450d6683..a7761079e7 100644 --- a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -146,6 +146,10 @@ type SchemaUsageInfo struct { RequestInfo *RequestInfo `protobuf:"bytes,6,opt,name=RequestInfo,proto3" json:"RequestInfo,omitempty"` // Attributes is a map of attributes that can be used to filter the metrics Attributes map[string]string `protobuf:"bytes,7,rep,name=Attributes,proto3" json:"Attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // ArgumentMetrics is the list of used arguments in the request document + ArgumentMetrics []*ArgumentUsageInfo `protobuf:"bytes,8,rep,name=ArgumentMetrics,proto3" json:"ArgumentMetrics,omitempty"` + // InputMetrics is the list of used input fields in the request document + InputMetrics []*InputUsageInfo `protobuf:"bytes,9,rep,name=InputMetrics,proto3" json:"InputMetrics,omitempty"` } func (x *SchemaUsageInfo) Reset() { @@ -229,6 +233,20 @@ func (x *SchemaUsageInfo) GetAttributes() map[string]string { return nil } +func (x *SchemaUsageInfo) GetArgumentMetrics() []*ArgumentUsageInfo { + if x != nil { + return x.ArgumentMetrics + } + return nil +} + +func (x *SchemaUsageInfo) GetInputMetrics() []*InputUsageInfo { + if x != nil { + return x.InputMetrics + } + return nil +} + type ClientInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -407,11 +425,11 @@ type TypeFieldUsageInfo struct { // Path is the path to the field in the request document but without the root type query, mutation, or subscription Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` - // TypeNames is the list of type names that the field is used as + // TypeNames is the list of enclosing type names of the field TypeNames []string `protobuf:"bytes,2,rep,name=TypeNames,proto3" json:"TypeNames,omitempty"` // SubgraphIDs is the list of datasource IDs (e.g subgraph ID) that the field is used from SubgraphIDs []string `protobuf:"bytes,3,rep,name=SubgraphIDs,proto3" json:"SubgraphIDs,omitempty"` - // Count is the number of times the field is used + // Count is the number of times the field is used. Useful for batching at client side. Count uint64 `protobuf:"varint,4,opt,name=Count,proto3" json:"Count,omitempty"` // NamedType is the underlying type of the field NamedType string `protobuf:"bytes,5,opt,name=NamedType,proto3" json:"NamedType,omitempty"` @@ -484,6 +502,156 @@ func (x *TypeFieldUsageInfo) GetNamedType() string { return "" } +type ArgumentUsageInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path is the path to the field in the request document but without the root type query, mutation, or subscription + Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` + // TypeName is the enclosing type name of the argument + TypeName string `protobuf:"bytes,2,opt,name=TypeName,proto3" json:"TypeName,omitempty"` + // Count is the number of times the argument is used. Useful for batching at client side. + Count uint64 `protobuf:"varint,3,opt,name=Count,proto3" json:"Count,omitempty"` + // NamedType is the underlying type of the argument + NamedType string `protobuf:"bytes,4,opt,name=NamedType,proto3" json:"NamedType,omitempty"` +} + +func (x *ArgumentUsageInfo) Reset() { + *x = ArgumentUsageInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArgumentUsageInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArgumentUsageInfo) ProtoMessage() {} + +func (x *ArgumentUsageInfo) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArgumentUsageInfo.ProtoReflect.Descriptor instead. +func (*ArgumentUsageInfo) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{6} +} + +func (x *ArgumentUsageInfo) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +func (x *ArgumentUsageInfo) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ArgumentUsageInfo) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *ArgumentUsageInfo) GetNamedType() string { + if x != nil { + return x.NamedType + } + return "" +} + +type InputUsageInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path is the path to the field in the request document but without the root type query, mutation, or subscription + Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` + // TypeName is the enclosing type name of the argument + TypeName string `protobuf:"bytes,2,opt,name=TypeName,proto3" json:"TypeName,omitempty"` + // Count is the number of times the argument is used. Useful for batching at client side. + Count uint64 `protobuf:"varint,3,opt,name=Count,proto3" json:"Count,omitempty"` + // NamedType is the underlying type of the input field + NamedType string `protobuf:"bytes,4,opt,name=NamedType,proto3" json:"NamedType,omitempty"` +} + +func (x *InputUsageInfo) Reset() { + *x = InputUsageInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InputUsageInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InputUsageInfo) ProtoMessage() {} + +func (x *InputUsageInfo) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InputUsageInfo.ProtoReflect.Descriptor instead. +func (*InputUsageInfo) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{7} +} + +func (x *InputUsageInfo) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +func (x *InputUsageInfo) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *InputUsageInfo) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *InputUsageInfo) GetNamedType() string { + if x != nil { + return x.NamedType + } + return "" +} + type PublishGraphQLRequestMetricsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -495,7 +663,7 @@ type PublishGraphQLRequestMetricsRequest struct { func (x *PublishGraphQLRequestMetricsRequest) Reset() { *x = PublishGraphQLRequestMetricsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -508,7 +676,7 @@ func (x *PublishGraphQLRequestMetricsRequest) String() string { func (*PublishGraphQLRequestMetricsRequest) ProtoMessage() {} func (x *PublishGraphQLRequestMetricsRequest) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -521,7 +689,7 @@ func (x *PublishGraphQLRequestMetricsRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use PublishGraphQLRequestMetricsRequest.ProtoReflect.Descriptor instead. func (*PublishGraphQLRequestMetricsRequest) Descriptor() ([]byte, []int) { - return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{6} + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{8} } func (x *PublishGraphQLRequestMetricsRequest) GetSchemaUsage() []*SchemaUsageInfo { @@ -540,7 +708,7 @@ type PublishOperationCoverageReportResponse struct { func (x *PublishOperationCoverageReportResponse) Reset() { *x = PublishOperationCoverageReportResponse{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -553,7 +721,7 @@ func (x *PublishOperationCoverageReportResponse) String() string { func (*PublishOperationCoverageReportResponse) ProtoMessage() {} func (x *PublishOperationCoverageReportResponse) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7] + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -566,7 +734,7 @@ func (x *PublishOperationCoverageReportResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use PublishOperationCoverageReportResponse.ProtoReflect.Descriptor instead. func (*PublishOperationCoverageReportResponse) Descriptor() ([]byte, []int) { - return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{7} + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{9} } var File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto protoreflect.FileDescriptor @@ -583,7 +751,7 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x22, 0xdf, 0x04, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x88, 0x06, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5a, @@ -617,78 +785,104 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x3a, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x76, - 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, - 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x9c, - 0x01, 0x0a, 0x12, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x73, 0x61, 0x67, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x79, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x79, - 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x49, 0x44, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x75, - 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x49, 0x44, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x74, 0x0a, - 0x23, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0b, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x77, 0x67, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, - 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, 0x0a, - 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, - 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, 0x54, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, 0x43, - 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x32, 0xb8, 0x01, 0x0a, 0x15, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, 0x2e, - 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, + 0x74, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x0f, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x77, + 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x41, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x4e, 0x0a, 0x0c, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3a, 0x0a, 0x0a, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x76, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x3d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, - 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, - 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0x9b, 0x02, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x59, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, - 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, - 0x02, 0x1a, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, - 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, - 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, - 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x22, + 0x26, 0x0a, 0x0a, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x9c, 0x01, 0x0a, 0x12, 0x54, 0x79, 0x70, 0x65, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, + 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x49, 0x44, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x49, + 0x44, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, + 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x77, 0x0a, 0x11, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x50, + 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x1a, 0x0a, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, + 0x74, 0x0a, 0x0e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x74, 0x0a, 0x23, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0b, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, + 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x02, 0x32, 0xb8, 0x01, 0x0a, 0x15, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x15, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, + 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9b, 0x02, 0x0a, + 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, + 0x13, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x59, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, + 0x3b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, + 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, 0x02, 0x1a, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, + 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -704,7 +898,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP() []byte { } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []interface{}{ (OperationType)(0), // 0: wg.cosmo.graphqlmetrics.v1.OperationType (*RequestInfo)(nil), // 1: wg.cosmo.graphqlmetrics.v1.RequestInfo @@ -713,26 +907,30 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []interface{} (*OperationInfo)(nil), // 4: wg.cosmo.graphqlmetrics.v1.OperationInfo (*SchemaInfo)(nil), // 5: wg.cosmo.graphqlmetrics.v1.SchemaInfo (*TypeFieldUsageInfo)(nil), // 6: wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo - (*PublishGraphQLRequestMetricsRequest)(nil), // 7: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest - (*PublishOperationCoverageReportResponse)(nil), // 8: wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse - nil, // 9: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + (*ArgumentUsageInfo)(nil), // 7: wg.cosmo.graphqlmetrics.v1.ArgumentUsageInfo + (*InputUsageInfo)(nil), // 8: wg.cosmo.graphqlmetrics.v1.InputUsageInfo + (*PublishGraphQLRequestMetricsRequest)(nil), // 9: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest + (*PublishOperationCoverageReportResponse)(nil), // 10: wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse + nil, // 11: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_depIdxs = []int32{ - 6, // 0: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.TypeFieldMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo - 4, // 1: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.OperationInfo:type_name -> wg.cosmo.graphqlmetrics.v1.OperationInfo - 5, // 2: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.SchemaInfo:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaInfo - 3, // 3: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ClientInfo:type_name -> wg.cosmo.graphqlmetrics.v1.ClientInfo - 1, // 4: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.RequestInfo:type_name -> wg.cosmo.graphqlmetrics.v1.RequestInfo - 9, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry - 0, // 6: wg.cosmo.graphqlmetrics.v1.OperationInfo.Type:type_name -> wg.cosmo.graphqlmetrics.v1.OperationType - 2, // 7: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo - 7, // 8: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest - 8, // 9: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse - 9, // [9:10] is the sub-list for method output_type - 8, // [8:9] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 6, // 0: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.TypeFieldMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo + 4, // 1: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.OperationInfo:type_name -> wg.cosmo.graphqlmetrics.v1.OperationInfo + 5, // 2: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.SchemaInfo:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaInfo + 3, // 3: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ClientInfo:type_name -> wg.cosmo.graphqlmetrics.v1.ClientInfo + 1, // 4: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.RequestInfo:type_name -> wg.cosmo.graphqlmetrics.v1.RequestInfo + 11, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + 7, // 6: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ArgumentMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.ArgumentUsageInfo + 8, // 7: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.InputMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.InputUsageInfo + 0, // 8: wg.cosmo.graphqlmetrics.v1.OperationInfo.Type:type_name -> wg.cosmo.graphqlmetrics.v1.OperationType + 2, // 9: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo + 9, // 10: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest + 10, // 11: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse + 11, // [11:12] is the sub-list for method output_type + 10, // [10:11] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() } @@ -814,7 +1012,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { } } file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PublishGraphQLRequestMetricsRequest); i { + switch v := v.(*ArgumentUsageInfo); i { case 0: return &v.state case 1: @@ -826,6 +1024,30 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { } } file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InputUsageInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublishGraphQLRequestMetricsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PublishOperationCoverageReportResponse); i { case 0: return &v.state @@ -844,7 +1066,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc, NumEnums: 1, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/router/go.mod b/router/go.mod index 1bde2981d7..0453d749cf 100644 --- a/router/go.mod +++ b/router/go.mod @@ -27,7 +27,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/tidwall/gjson v1.14.4 github.com/tidwall/sjson v1.2.5 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231107092313-0c3d635b9c18 + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231110114615-aaa3d9a98722 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 go.opentelemetry.io/otel v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 @@ -52,10 +52,12 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.9.2 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/dave/jennifer v1.4.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/evanphx/json-patch v0.5.2 // indirect github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-gonic/gin v1.9.1 // indirect github.com/go-logr/logr v1.2.4 // indirect @@ -67,13 +69,19 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jensneuse/byte-template v0.0.0-20200214152254-4f3cf06e5c68 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/magiconair/properties v1.8.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/pelletier/go-toml v1.6.0 // indirect github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/common v0.42.0 // indirect @@ -81,6 +89,12 @@ require ( github.com/r3labs/sse/v2 v2.8.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/cobra v0.0.5 // indirect + github.com/spf13/jwalterweatherman v1.0.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.3.2 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/vektah/gqlparser/v2 v2.5.10 // indirect @@ -99,6 +113,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/router/go.sum b/router/go.sum index 66bd36462e..74671b605b 100644 --- a/router/go.sum +++ b/router/go.sum @@ -9,6 +9,7 @@ github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRB github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -28,6 +29,12 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhD github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a h1:8d1CEOF1xldesKds5tRG3tExBsMOgWYownMHNCsev54= github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/dave/jennifer v1.4.0 h1:tNJFJmLDVTLu+v05mVZ88RINa3vQqnyyWkTKWYz0CwE= +github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,6 +51,9 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -116,6 +126,12 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE= github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFEB7inlalqfNqw65aNkM1lGX2yt3NmbS8= +github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jensneuse/abstractlogger v0.0.4 h1:sa4EH8fhWk3zlTDbSncaWKfwxYM8tYSlQ054ETLyyQY= github.com/jensneuse/abstractlogger v0.0.4/go.mod h1:6WuamOHuykJk8zED/R0LNiLhWR6C7FIAo43ocUEB3mo= github.com/jensneuse/byte-template v0.0.0-20200214152254-4f3cf06e5c68 h1:E80wOd3IFQcoBxLkAUpUQ3BoGrZ4DxhQdP21+HH1s6A= @@ -138,6 +154,7 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -150,6 +167,8 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91 h1:JnZSkFP1/GLwKCEuuWVhsacvbDQIVa5BRwAwd+9k2Vw= github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -160,6 +179,9 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -168,11 +190,15 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= @@ -188,6 +214,7 @@ github.com/r3labs/sse/v2 v2.8.1/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEm github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/santhosh-tekuri/jsonschema/v5 v5.3.0 h1:uIkTLo0AGRc8l7h5l9r+GcYi9qfVPt6lD4/bhmzfiKo= github.com/santhosh-tekuri/jsonschema/v5 v5.3.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= @@ -199,6 +226,21 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sosodev/duration v1.1.0 h1:kQcaiGbJaIsRqgQy7VGlZrVw1giWO+lDoX3MCPnpVO4= github.com/sosodev/duration v1.1.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -227,6 +269,7 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -234,6 +277,9 @@ github.com/vektah/gqlparser/v2 v2.5.10 h1:6zSM4azXC9u4Nxy5YmdmGu4uKamfwsdKTwp5zs github.com/vektah/gqlparser/v2 v2.5.10/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231107092313-0c3d635b9c18 h1:uehizkCPbiyKeVwlTsDo+LpUMcpLAok23BogfKZIrxo= github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231107092313-0c3d635b9c18/go.mod h1:NQ2xZkUCh3sdbmMVusyYCd+HmlQ/rKFFHCvr6JIRhIY= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231110114615-aaa3d9a98722 h1:2dNt/fqDIw/4C2ZtZHngbPJKJBJ9m1xM4ttbwaBcPNM= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.2.0.20231110114615-aaa3d9a98722/go.mod h1:NQ2xZkUCh3sdbmMVusyYCd+HmlQ/rKFFHCvr6JIRhIY= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= @@ -280,8 +326,10 @@ go.withmatt.com/connect-brotli v0.4.0/go.mod h1:c2eELz56za+/Mxh1yJrlglZ4VM9krpOC golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= @@ -298,9 +346,11 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -311,6 +361,7 @@ golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -343,7 +394,10 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/router/internal/graphqlmetrics/aggregation.go b/router/internal/graphqlmetrics/aggregation.go index 23506d3d25..109858380e 100644 --- a/router/internal/graphqlmetrics/aggregation.go +++ b/router/internal/graphqlmetrics/aggregation.go @@ -9,23 +9,29 @@ import graphqlmetricsv12 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo // - The client info is equal which means that the same client was used // - The attributes are equal -func Aggregate(items []*graphqlmetricsv12.SchemaUsageInfo) []*graphqlmetricsv12.SchemaUsageInfo { - aggregated := make([]*graphqlmetricsv12.SchemaUsageInfo, 0, len(items)) - duplicates := make(map[*graphqlmetricsv12.SchemaUsageInfo]struct{}, len(items)) +func Aggregate(schemaUsageInfos []*graphqlmetricsv12.SchemaUsageInfo) []*graphqlmetricsv12.SchemaUsageInfo { + aggregated := make([]*graphqlmetricsv12.SchemaUsageInfo, 0, len(schemaUsageInfos)) + duplicates := make(map[*graphqlmetricsv12.SchemaUsageInfo]struct{}, len(schemaUsageInfos)) // check for same schema usage infos and aggregate field metrics - for _, a := range items { + for _, a := range schemaUsageInfos { - // skip already aggregated items + // skip already aggregated schemaUsageInfos if _, ok := duplicates[a]; ok { continue } - for _, b := range items { + for _, b := range schemaUsageInfos { if a != b && isSchemaUsageInfoEqual(a, b) { for k, metric := range b.TypeFieldMetrics { a.TypeFieldMetrics[k].Count += metric.Count } + for k, metric := range b.ArgumentMetrics { + a.ArgumentMetrics[k].Count += metric.Count + } + for k, metric := range b.InputMetrics { + a.InputMetrics[k].Count += metric.Count + } duplicates[b] = struct{}{} } } @@ -37,7 +43,7 @@ func Aggregate(items []*graphqlmetricsv12.SchemaUsageInfo) []*graphqlmetricsv12. } func isSchemaUsageInfoEqual(a, b *graphqlmetricsv12.SchemaUsageInfo) bool { - // Different hash imply different query type, name and fields + // Different hash imply already different query type, name, arguments, fields if a.OperationInfo.Hash != b.OperationInfo.Hash { return false } diff --git a/router/internal/graphqlmetrics/aggregation_test.go b/router/internal/graphqlmetrics/aggregation_test.go index aeb971ee5a..bdbde530f6 100644 --- a/router/internal/graphqlmetrics/aggregation_test.go +++ b/router/internal/graphqlmetrics/aggregation_test.go @@ -25,6 +25,22 @@ func TestAggregateCountWithEqualUsages(t *testing.T) { Count: 1, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -60,6 +76,22 @@ func TestAggregateCountWithEqualUsages(t *testing.T) { Count: 1, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -85,6 +117,8 @@ func TestAggregateCountWithEqualUsages(t *testing.T) { require.Equal(t, 1, len(result)) require.Equal(t, uint64(3), result[0].TypeFieldMetrics[0].Count) require.Equal(t, uint64(2), result[0].TypeFieldMetrics[1].Count) + require.Equal(t, uint64(2), result[0].ArgumentMetrics[0].Count) + require.Equal(t, uint64(2), result[0].InputMetrics[0].Count) } func TestAggregateWithDifferentOperationInfo(t *testing.T) { @@ -104,6 +138,22 @@ func TestAggregateWithDifferentOperationInfo(t *testing.T) { Hash: "123456", // different hash Name: "user", }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, SchemaInfo: &graphqlmetricsv1.SchemaInfo{ Version: "1", }, @@ -126,6 +176,22 @@ func TestAggregateWithDifferentOperationInfo(t *testing.T) { Count: 1, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -149,6 +215,10 @@ func TestAggregateWithDifferentOperationInfo(t *testing.T) { require.Equal(t, 2, len(result)) require.Equal(t, uint64(2), result[0].TypeFieldMetrics[0].Count) require.Equal(t, uint64(1), result[1].TypeFieldMetrics[0].Count) + require.Equal(t, uint64(1), result[0].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[1].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[0].InputMetrics[0].Count) + require.Equal(t, uint64(1), result[1].InputMetrics[0].Count) } func TestAggregateWithDifferentClientInfo(t *testing.T) { @@ -163,6 +233,22 @@ func TestAggregateWithDifferentClientInfo(t *testing.T) { Count: 2, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -190,6 +276,22 @@ func TestAggregateWithDifferentClientInfo(t *testing.T) { Count: 1, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -213,6 +315,10 @@ func TestAggregateWithDifferentClientInfo(t *testing.T) { require.Equal(t, 2, len(result)) require.Equal(t, uint64(2), result[0].TypeFieldMetrics[0].Count) require.Equal(t, uint64(1), result[1].TypeFieldMetrics[0].Count) + require.Equal(t, uint64(1), result[0].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[1].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[0].InputMetrics[0].Count) + require.Equal(t, uint64(1), result[1].InputMetrics[0].Count) } func TestAggregateWithDifferentRequestInfo(t *testing.T) { @@ -227,6 +333,22 @@ func TestAggregateWithDifferentRequestInfo(t *testing.T) { Count: 2, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -254,6 +376,22 @@ func TestAggregateWithDifferentRequestInfo(t *testing.T) { Count: 1, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -277,6 +415,10 @@ func TestAggregateWithDifferentRequestInfo(t *testing.T) { require.Equal(t, 2, len(result)) require.Equal(t, uint64(2), result[0].TypeFieldMetrics[0].Count) require.Equal(t, uint64(1), result[1].TypeFieldMetrics[0].Count) + require.Equal(t, uint64(1), result[0].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[1].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[0].InputMetrics[0].Count) + require.Equal(t, uint64(1), result[1].InputMetrics[0].Count) } func TestAggregateWithDifferentHash(t *testing.T) { @@ -297,6 +439,22 @@ func TestAggregateWithDifferentHash(t *testing.T) { Count: 6, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123456", // emulate different hash because of different fields @@ -320,6 +478,22 @@ func TestAggregateWithDifferentHash(t *testing.T) { Count: 1, }, }, + ArgumentMetrics: []*graphqlmetricsv1.ArgumentUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, + InputMetrics: []*graphqlmetricsv1.InputUsageInfo{ + { + Path: []string{"user", "id"}, + TypeName: "User", + Count: 1, + NamedType: "ID", + }, + }, OperationInfo: &graphqlmetricsv1.OperationInfo{ Type: graphqlmetricsv1.OperationType_QUERY, Hash: "123", @@ -340,4 +514,8 @@ func TestAggregateWithDifferentHash(t *testing.T) { require.Equal(t, uint64(2), result[0].TypeFieldMetrics[0].Count) require.Equal(t, uint64(6), result[0].TypeFieldMetrics[1].Count) require.Equal(t, uint64(1), result[1].TypeFieldMetrics[0].Count) + require.Equal(t, uint64(1), result[0].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[1].ArgumentMetrics[0].Count) + require.Equal(t, uint64(1), result[0].InputMetrics[0].Count) + require.Equal(t, uint64(1), result[1].InputMetrics[0].Count) } diff --git a/studio/src/components/analytics/field-usage.tsx b/studio/src/components/analytics/field-usage.tsx index ec1cd6ad44..7187026d98 100644 --- a/studio/src/components/analytics/field-usage.tsx +++ b/studio/src/components/analytics/field-usage.tsx @@ -350,6 +350,7 @@ export const FieldUsageSheet = () => { }, }), enabled: !!showUsage && !!graph?.graph?.name, + refetchOnWindowFocus: false, }); let content: React.ReactNode; diff --git a/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/details.tsx b/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/details.tsx index 1ab475323a..238a4e038b 100644 --- a/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/details.tsx +++ b/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/details.tsx @@ -27,6 +27,7 @@ const CheckDetailsPage: NextPageWithLayout = () => { graphName: graphContext?.graph?.name, }), enabled: !!graphContext?.graph?.name, + refetchOnWindowFocus: false, }); if (isLoading) return ; diff --git a/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/index.tsx b/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/index.tsx index 0be0a631da..051698d7a5 100644 --- a/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/index.tsx +++ b/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/index.tsx @@ -94,6 +94,7 @@ const CheckOverviewPage: NextPageWithLayout = () => { graphName: graphContext?.graph?.name, }), enabled: !!graphContext?.graph?.name, + refetchOnWindowFocus: false, }); const { data: allGraphsData } = useQuery(getFederatedGraphs.useQuery()); diff --git a/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/operations.tsx b/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/operations.tsx index d58583a4ab..18af776b5a 100644 --- a/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/operations.tsx +++ b/studio/src/pages/[organizationSlug]/graph/[slug]/checks/[checkId]/operations.tsx @@ -137,6 +137,7 @@ const CheckOperationsPage: NextPageWithLayout = () => { graphName: graphContext?.graph?.name, }), enabled: !!graphContext?.graph?.name, + refetchOnWindowFocus: false, }); const [search, setSearch] = useState(router.query.search as string);