diff --git a/router-tests/connectrpc/connectrpc_client_test.go b/router-tests/connectrpc/connectrpc_client_test.go index 664998c327..39d16f30a2 100644 --- a/router-tests/connectrpc/connectrpc_client_test.go +++ b/router-tests/connectrpc/connectrpc_client_test.go @@ -26,7 +26,7 @@ func TestConnectRPC_ClientProtocols(t *testing.T) { GraphQLHandler: EmployeeGraphQLHandler(), }) defer ts.Close() - + err := ts.Start() require.NoError(t, err) @@ -126,7 +126,7 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) { ts := NewTestConnectRPCServer(t, ConnectRPCServerOptions{ GraphQLHandler: ErrorGraphQLHandler("Employee not found"), }) - + err := ts.Start() require.NoError(t, err) @@ -169,11 +169,11 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) { "errors": [{"message": "Could not fetch pets"}] }`)) } - + ts := NewTestConnectRPCServer(t, ConnectRPCServerOptions{ GraphQLHandler: handler, }) - + err := ts.Start() require.NoError(t, err) @@ -189,7 +189,7 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) { _, err = client.GetEmployeeById(context.Background(), req) // Per GraphQL spec, errors at top level should result in an error require.Error(t, err) - + var connectErr *connect.Error require.ErrorAs(t, err, &connectErr) assert.Equal(t, connect.CodeUnknown, connectErr.Code()) @@ -225,7 +225,7 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) { ts := NewTestConnectRPCServer(t, ConnectRPCServerOptions{ GraphQLHandler: HTTPErrorHandler(http.StatusInternalServerError, "Internal Server Error"), }) - + err := ts.Start() require.NoError(t, err) diff --git a/router-tests/connectrpc/connectrpc_server_lifecycle_test.go b/router-tests/connectrpc/connectrpc_server_lifecycle_test.go index 2c837a8dec..35836d93fe 100644 --- a/router-tests/connectrpc/connectrpc_server_lifecycle_test.go +++ b/router-tests/connectrpc/connectrpc_server_lifecycle_test.go @@ -107,4 +107,4 @@ func TestConnectRPC_ServerLifecycle_GracefulShutdown(t *testing.T) { assert.NoError(t, err) assert.Less(t, duration, 10*time.Second, "stop should complete within timeout") }) -} \ No newline at end of file +} diff --git a/router-tests/connectrpc/connectrpc_test.go b/router-tests/connectrpc/connectrpc_test.go index 0f5de24c06..0109dc7f96 100644 --- a/router-tests/connectrpc/connectrpc_test.go +++ b/router-tests/connectrpc/connectrpc_test.go @@ -13,7 +13,7 @@ func TestConnectRPC_ServiceDiscovery(t *testing.T) { t.Run("discovers services from proto files", func(t *testing.T) { ts := NewTestConnectRPCServer(t, ConnectRPCServerOptions{}) - + err := ts.Start() require.NoError(t, err) @@ -30,8 +30,8 @@ func TestConnectRPC_ServiceDiscovery(t *testing.T) { for _, serviceName := range serviceNames { t.Logf(" - Service: %s", serviceName) } - + operationCount := ts.GetOperationCount() t.Logf("Discovered %d operation(s)", operationCount) }) -} \ No newline at end of file +} diff --git a/router-tests/modules/verify-operation-context-values/module.go b/router-tests/modules/verify-operation-context-values/module.go index b044bc71c5..ac53d2f236 100644 --- a/router-tests/modules/verify-operation-context-values/module.go +++ b/router-tests/modules/verify-operation-context-values/module.go @@ -50,11 +50,11 @@ func (m *VerifyOperationContextValuesModule) Middleware(ctx core.RequestContext, } // Convert variables to JSON string for easier testing - captured.VariablesJSON = "{}" + captured.VariablesJSON = "{}" if captured.Variables != nil { variablesBytes := captured.Variables.MarshalTo(nil) captured.VariablesJSON = string(variablesBytes) - } + } // Send the captured values to the test select { case m.ResultsChan <- captured: diff --git a/router/core/context.go b/router/core/context.go index 6162f96499..408abfeac9 100644 --- a/router/core/context.go +++ b/router/core/context.go @@ -708,9 +708,9 @@ func (o *operationContext) GetTypeFieldUsageInfoMetrics() []*graphqlmetrics.Type // OperationTimings contains timing information for various stages of operation processing type OperationTimings struct { - ParsingTime time.Duration - ValidationTime time.Duration - PlanningTime time.Duration + ParsingTime time.Duration + ValidationTime time.Duration + PlanningTime time.Duration NormalizationTime time.Duration } diff --git a/router/core/operation_processor.go b/router/core/operation_processor.go index a4842d6b57..68d71af2ed 100644 --- a/router/core/operation_processor.go +++ b/router/core/operation_processor.go @@ -111,23 +111,23 @@ type OperationProcessorOptions struct { PersistedOperationClient *persistedoperation.Client AutomaticPersistedOperationCacheTtl int - EnablePersistedOperationsCache bool - PersistedOpsNormalizationCache *ristretto.Cache[uint64, NormalizationCacheEntry] - NormalizationCache *ristretto.Cache[uint64, NormalizationCacheEntry] - QueryDepthCache *ristretto.Cache[uint64, ComplexityCacheEntry] - VariablesNormalizationCache *ristretto.Cache[uint64, VariablesNormalizationCacheEntry] - RemapVariablesCache *ristretto.Cache[uint64, RemapVariablesCacheEntry] - ValidationCache *ristretto.Cache[uint64, bool] - OperationHashCache *ristretto.Cache[uint64, string] - ParseKitPoolSize int - IntrospectionEnabled bool - ApolloCompatibilityFlags config.ApolloCompatibilityFlags - ApolloRouterCompatibilityFlags config.ApolloRouterCompatibilityFlags - DisableExposingVariablesContentOnValidationError bool - RelaxSubgraphOperationFieldSelectionMergingNullability bool - ComplexityLimits *config.ComplexityLimits - ParserTokenizerLimits astparser.TokenizerLimits - OperationNameLengthLimit int + EnablePersistedOperationsCache bool + PersistedOpsNormalizationCache *ristretto.Cache[uint64, NormalizationCacheEntry] + NormalizationCache *ristretto.Cache[uint64, NormalizationCacheEntry] + QueryDepthCache *ristretto.Cache[uint64, ComplexityCacheEntry] + VariablesNormalizationCache *ristretto.Cache[uint64, VariablesNormalizationCacheEntry] + RemapVariablesCache *ristretto.Cache[uint64, RemapVariablesCacheEntry] + ValidationCache *ristretto.Cache[uint64, bool] + OperationHashCache *ristretto.Cache[uint64, string] + ParseKitPoolSize int + IntrospectionEnabled bool + ApolloCompatibilityFlags config.ApolloCompatibilityFlags + ApolloRouterCompatibilityFlags config.ApolloRouterCompatibilityFlags + DisableExposingVariablesContentOnValidationError bool + RelaxSubgraphOperationFieldSelectionMergingNullability bool + ComplexityLimits *config.ComplexityLimits + ParserTokenizerLimits astparser.TokenizerLimits + OperationNameLengthLimit int } // OperationProcessor provides shared resources to the parseKit and OperationKit. @@ -1422,10 +1422,10 @@ func (o *OperationKit) skipIncludeVariableNames() []string { } type parseKitOptions struct { - apolloCompatibilityFlags config.ApolloCompatibilityFlags - apolloRouterCompatibilityFlags config.ApolloRouterCompatibilityFlags - disableExposingVariablesContentOnValidationError bool - relaxSubgraphOperationFieldSelectionMergingNullability bool + apolloCompatibilityFlags config.ApolloCompatibilityFlags + apolloRouterCompatibilityFlags config.ApolloRouterCompatibilityFlags + disableExposingVariablesContentOnValidationError bool + relaxSubgraphOperationFieldSelectionMergingNullability bool } func createParseKit(i int, options *parseKitOptions) *parseKit { @@ -1486,9 +1486,9 @@ func NewOperationProcessor(opts OperationProcessorOptions) *OperationProcessor { operationNameLengthLimit: opts.OperationNameLengthLimit, complexityLimits: opts.ComplexityLimits, parseKitOptions: &parseKitOptions{ - apolloCompatibilityFlags: opts.ApolloCompatibilityFlags, - apolloRouterCompatibilityFlags: opts.ApolloRouterCompatibilityFlags, - disableExposingVariablesContentOnValidationError: opts.DisableExposingVariablesContentOnValidationError, + apolloCompatibilityFlags: opts.ApolloCompatibilityFlags, + apolloRouterCompatibilityFlags: opts.ApolloRouterCompatibilityFlags, + disableExposingVariablesContentOnValidationError: opts.DisableExposingVariablesContentOnValidationError, relaxSubgraphOperationFieldSelectionMergingNullability: opts.RelaxSubgraphOperationFieldSelectionMergingNullability, }, } diff --git a/router/core/plan_generator.go b/router/core/plan_generator.go index a92264b042..b06a74999b 100644 --- a/router/core/plan_generator.go +++ b/router/core/plan_generator.go @@ -342,7 +342,7 @@ func (pg *PlanGenerator) loadConfiguration(routerConfig *nodev1.RouterConfig, lo if _, ok := redisSources[providerId]; !ok { redisSources[providerId] = nil routerEngineConfig.Events.Providers.Redis = append(routerEngineConfig.Events.Providers.Redis, config.RedisEventSource{ - ID: providerId, + ID: providerId, }) } } diff --git a/router/pkg/config/config.go b/router/pkg/config/config.go index 79adc0972d..e0998c6e4c 100644 --- a/router/pkg/config/config.go +++ b/router/pkg/config/config.go @@ -414,33 +414,33 @@ type EngineExecutionConfiguration struct { ForceEnableInboundRequestDeduplication bool `envDefault:"false" env:"ENGINE_FORCE_ENABLE_INBOUND_REQUEST_DEDUPLICATION" yaml:"force_enable_inbound_request_deduplication"` EnableRequestTracing bool `envDefault:"true" env:"ENGINE_ENABLE_REQUEST_TRACING" yaml:"enable_request_tracing"` // EnableExecutionPlanCacheResponseHeader is deprecated, use EngineDebugConfiguration.EnableCacheResponseHeaders instead. - EnableExecutionPlanCacheResponseHeader bool `envDefault:"false" env:"ENGINE_ENABLE_EXECUTION_PLAN_CACHE_RESPONSE_HEADER" yaml:"enable_execution_plan_cache_response_header"` - MaxConcurrentResolvers int `envDefault:"1024" env:"ENGINE_MAX_CONCURRENT_RESOLVERS" yaml:"max_concurrent_resolvers,omitempty"` - EnableNetPoll bool `envDefault:"true" env:"ENGINE_ENABLE_NET_POLL" yaml:"enable_net_poll"` - WebSocketClientPollTimeout time.Duration `envDefault:"1s" env:"ENGINE_WEBSOCKET_CLIENT_POLL_TIMEOUT" yaml:"websocket_client_poll_timeout,omitempty"` - WebSocketClientConnBufferSize int `envDefault:"128" env:"ENGINE_WEBSOCKET_CLIENT_CONN_BUFFER_SIZE" yaml:"websocket_client_conn_buffer_size,omitempty"` - WebSocketClientReadTimeout time.Duration `envDefault:"5s" env:"ENGINE_WEBSOCKET_CLIENT_READ_TIMEOUT" yaml:"websocket_client_read_timeout,omitempty"` - WebSocketClientWriteTimeout time.Duration `envDefault:"10s" env:"ENGINE_WEBSOCKET_CLIENT_WRITE_TIMEOUT" yaml:"websocket_client_write_timeout,omitempty"` - WebSocketClientPingInterval time.Duration `envDefault:"15s" env:"ENGINE_WEBSOCKET_CLIENT_PING_INTERVAL" yaml:"websocket_client_ping_interval,omitempty"` - WebSocketClientPingTimeout time.Duration `envDefault:"30s" env:"ENGINE_WEBSOCKET_CLIENT_PING_TIMEOUT" yaml:"websocket_client_ping_timeout,omitempty"` - WebSocketClientFrameTimeout time.Duration `envDefault:"100ms" env:"ENGINE_WEBSOCKET_CLIENT_FRAME_TIMEOUT" yaml:"websocket_client_frame_timeout,omitempty"` - ExecutionPlanCacheSize int64 `envDefault:"1024" env:"ENGINE_EXECUTION_PLAN_CACHE_SIZE" yaml:"execution_plan_cache_size,omitempty"` - MinifySubgraphOperations bool `envDefault:"true" env:"ENGINE_MINIFY_SUBGRAPH_OPERATIONS" yaml:"minify_subgraph_operations"` - EnablePersistedOperationsCache bool `envDefault:"true" env:"ENGINE_ENABLE_PERSISTED_OPERATIONS_CACHE" yaml:"enable_persisted_operations_cache"` - EnableNormalizationCache bool `envDefault:"true" env:"ENGINE_ENABLE_NORMALIZATION_CACHE" yaml:"enable_normalization_cache"` - NormalizationCacheSize int64 `envDefault:"1024" env:"ENGINE_NORMALIZATION_CACHE_SIZE" yaml:"normalization_cache_size,omitempty"` - OperationHashCacheSize int64 `envDefault:"2048" env:"ENGINE_OPERATION_HASH_CACHE_SIZE" yaml:"operation_hash_cache_size,omitempty"` - ParseKitPoolSize int `envDefault:"16" env:"ENGINE_PARSEKIT_POOL_SIZE" yaml:"parsekit_pool_size,omitempty"` - EnableValidationCache bool `envDefault:"true" env:"ENGINE_ENABLE_VALIDATION_CACHE" yaml:"enable_validation_cache"` - ValidationCacheSize int64 `envDefault:"1024" env:"ENGINE_VALIDATION_CACHE_SIZE" yaml:"validation_cache_size,omitempty"` - DisableExposingVariablesContentOnValidationError bool `envDefault:"false" env:"ENGINE_DISABLE_EXPOSING_VARIABLES_CONTENT_ON_VALIDATION_ERROR" yaml:"disable_exposing_variables_content_on_validation_error"` - ResolverMaxRecyclableParserSize int `envDefault:"32768" env:"ENGINE_RESOLVER_MAX_RECYCLABLE_PARSER_SIZE" yaml:"resolver_max_recyclable_parser_size,omitempty"` - EnableSubgraphFetchOperationName bool `envDefault:"false" env:"ENGINE_ENABLE_SUBGRAPH_FETCH_OPERATION_NAME" yaml:"enable_subgraph_fetch_operation_name"` - DisableVariablesRemapping bool `envDefault:"false" env:"ENGINE_DISABLE_VARIABLES_REMAPPING" yaml:"disable_variables_remapping"` - EnableRequireFetchReasons bool `envDefault:"false" env:"ENGINE_ENABLE_REQUIRE_FETCH_REASONS" yaml:"enable_require_fetch_reasons"` - SubscriptionFetchTimeout time.Duration `envDefault:"30s" env:"ENGINE_SUBSCRIPTION_FETCH_TIMEOUT" yaml:"subscription_fetch_timeout,omitempty"` - ValidateRequiredExternalFields bool `envDefault:"false" env:"ENGINE_VALIDATE_REQUIRED_EXTERNAL_FIELDS" yaml:"validate_required_external_fields"` - RelaxSubgraphOperationFieldSelectionMergingNullability bool `envDefault:"false" env:"ENGINE_RELAX_SUBGRAPH_OPERATION_FIELD_SELECTION_MERGING_NULLABILITY" yaml:"relax_subgraph_operation_field_selection_merging_nullability"` + EnableExecutionPlanCacheResponseHeader bool `envDefault:"false" env:"ENGINE_ENABLE_EXECUTION_PLAN_CACHE_RESPONSE_HEADER" yaml:"enable_execution_plan_cache_response_header"` + MaxConcurrentResolvers int `envDefault:"1024" env:"ENGINE_MAX_CONCURRENT_RESOLVERS" yaml:"max_concurrent_resolvers,omitempty"` + EnableNetPoll bool `envDefault:"true" env:"ENGINE_ENABLE_NET_POLL" yaml:"enable_net_poll"` + WebSocketClientPollTimeout time.Duration `envDefault:"1s" env:"ENGINE_WEBSOCKET_CLIENT_POLL_TIMEOUT" yaml:"websocket_client_poll_timeout,omitempty"` + WebSocketClientConnBufferSize int `envDefault:"128" env:"ENGINE_WEBSOCKET_CLIENT_CONN_BUFFER_SIZE" yaml:"websocket_client_conn_buffer_size,omitempty"` + WebSocketClientReadTimeout time.Duration `envDefault:"5s" env:"ENGINE_WEBSOCKET_CLIENT_READ_TIMEOUT" yaml:"websocket_client_read_timeout,omitempty"` + WebSocketClientWriteTimeout time.Duration `envDefault:"10s" env:"ENGINE_WEBSOCKET_CLIENT_WRITE_TIMEOUT" yaml:"websocket_client_write_timeout,omitempty"` + WebSocketClientPingInterval time.Duration `envDefault:"15s" env:"ENGINE_WEBSOCKET_CLIENT_PING_INTERVAL" yaml:"websocket_client_ping_interval,omitempty"` + WebSocketClientPingTimeout time.Duration `envDefault:"30s" env:"ENGINE_WEBSOCKET_CLIENT_PING_TIMEOUT" yaml:"websocket_client_ping_timeout,omitempty"` + WebSocketClientFrameTimeout time.Duration `envDefault:"100ms" env:"ENGINE_WEBSOCKET_CLIENT_FRAME_TIMEOUT" yaml:"websocket_client_frame_timeout,omitempty"` + ExecutionPlanCacheSize int64 `envDefault:"1024" env:"ENGINE_EXECUTION_PLAN_CACHE_SIZE" yaml:"execution_plan_cache_size,omitempty"` + MinifySubgraphOperations bool `envDefault:"true" env:"ENGINE_MINIFY_SUBGRAPH_OPERATIONS" yaml:"minify_subgraph_operations"` + EnablePersistedOperationsCache bool `envDefault:"true" env:"ENGINE_ENABLE_PERSISTED_OPERATIONS_CACHE" yaml:"enable_persisted_operations_cache"` + EnableNormalizationCache bool `envDefault:"true" env:"ENGINE_ENABLE_NORMALIZATION_CACHE" yaml:"enable_normalization_cache"` + NormalizationCacheSize int64 `envDefault:"1024" env:"ENGINE_NORMALIZATION_CACHE_SIZE" yaml:"normalization_cache_size,omitempty"` + OperationHashCacheSize int64 `envDefault:"2048" env:"ENGINE_OPERATION_HASH_CACHE_SIZE" yaml:"operation_hash_cache_size,omitempty"` + ParseKitPoolSize int `envDefault:"16" env:"ENGINE_PARSEKIT_POOL_SIZE" yaml:"parsekit_pool_size,omitempty"` + EnableValidationCache bool `envDefault:"true" env:"ENGINE_ENABLE_VALIDATION_CACHE" yaml:"enable_validation_cache"` + ValidationCacheSize int64 `envDefault:"1024" env:"ENGINE_VALIDATION_CACHE_SIZE" yaml:"validation_cache_size,omitempty"` + DisableExposingVariablesContentOnValidationError bool `envDefault:"false" env:"ENGINE_DISABLE_EXPOSING_VARIABLES_CONTENT_ON_VALIDATION_ERROR" yaml:"disable_exposing_variables_content_on_validation_error"` + ResolverMaxRecyclableParserSize int `envDefault:"32768" env:"ENGINE_RESOLVER_MAX_RECYCLABLE_PARSER_SIZE" yaml:"resolver_max_recyclable_parser_size,omitempty"` + EnableSubgraphFetchOperationName bool `envDefault:"false" env:"ENGINE_ENABLE_SUBGRAPH_FETCH_OPERATION_NAME" yaml:"enable_subgraph_fetch_operation_name"` + DisableVariablesRemapping bool `envDefault:"false" env:"ENGINE_DISABLE_VARIABLES_REMAPPING" yaml:"disable_variables_remapping"` + EnableRequireFetchReasons bool `envDefault:"false" env:"ENGINE_ENABLE_REQUIRE_FETCH_REASONS" yaml:"enable_require_fetch_reasons"` + SubscriptionFetchTimeout time.Duration `envDefault:"30s" env:"ENGINE_SUBSCRIPTION_FETCH_TIMEOUT" yaml:"subscription_fetch_timeout,omitempty"` + ValidateRequiredExternalFields bool `envDefault:"false" env:"ENGINE_VALIDATE_REQUIRED_EXTERNAL_FIELDS" yaml:"validate_required_external_fields"` + RelaxSubgraphOperationFieldSelectionMergingNullability bool `envDefault:"false" env:"ENGINE_RELAX_SUBGRAPH_OPERATION_FIELD_SELECTION_MERGING_NULLABILITY" yaml:"relax_subgraph_operation_field_selection_merging_nullability"` } type BlockOperationConfiguration struct { diff --git a/router/pkg/connectrpc/handler_test.go b/router/pkg/connectrpc/handler_test.go index b85206b2da..3887cc4879 100644 --- a/router/pkg/connectrpc/handler_test.go +++ b/router/pkg/connectrpc/handler_test.go @@ -176,4 +176,3 @@ func TestConvertProtoJSONToGraphQLVariables(t *testing.T) { }`, string(result)) }) } - diff --git a/router/pkg/connectrpc/operation_loader.go b/router/pkg/connectrpc/operation_loader.go index 9d0889e581..af93ebc690 100644 --- a/router/pkg/connectrpc/operation_loader.go +++ b/router/pkg/connectrpc/operation_loader.go @@ -116,4 +116,3 @@ func LoadOperationsForService(serviceName string, operationFiles []string, logge return operations, nil } - diff --git a/router/pkg/connectrpc/vanguard_service_test.go b/router/pkg/connectrpc/vanguard_service_test.go index 2fdbd54211..4689618f9c 100644 --- a/router/pkg/connectrpc/vanguard_service_test.go +++ b/router/pkg/connectrpc/vanguard_service_test.go @@ -215,7 +215,7 @@ func TestVanguardService_ServiceHandler(t *testing.T) { // Create handler with mock server protoLoader := GetSharedProtoLoader(t, "testdata/services/employee.v1") - + // Build operations map with service-scoped approach before creating registry serviceName := "employee.v1.EmployeeService" operations := map[string]map[string]*schemaloader.Operation{ diff --git a/router/pkg/mcpserver/server.go b/router/pkg/mcpserver/server.go index 35b365bba4..81a9f504f3 100644 --- a/router/pkg/mcpserver/server.go +++ b/router/pkg/mcpserver/server.go @@ -40,7 +40,6 @@ func requestHeadersFromRequest(ctx context.Context, r *http.Request) context.Con return withRequestHeaders(ctx, headers) } - // headersFromContext extracts the request headers from the context. func headersFromContext(ctx context.Context) (http.Header, error) { headers, ok := ctx.Value(requestHeadersKey{}).(http.Header)