graphql-platform
graphql-platform copied to clipboard
New schema published in the redis cache breaks the live gateway
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
Hi.
So we use HC 12.11.1, Apollo federation, Redis and schema stitching.
We have an issue with the the Gateway and the redis
cache schema publishing.
The gateway is configured with a list of URls for each service, in the form of <name, url>
IE:
"GraphQlUrlCollection": {
"Customer": "https://localhost:5001/graphql/",
...
}
customer
in this instance is used to create a named HttpClient
with its corresponding url.
All is well if the redis
cache also contains a customer
record with the described schema of the service.
However we have found an issue:
If we have a hosted working gateway and someone pushes a new schema to redis
and this schema is not configured in the gateway, the gateway breaks with the following message:
1. Unable to resolve type reference
None: Uuid!. (HotChocolate.Types.ObjectType)
This breaks until someone creates a value for this service in the collection above and restarts the gateway.
Importantly it has to be noted that this only occurs if the schema has a Uuid
type in it. I tried with schemas without Uuid
and it seems fine.
However this obviously is an issue that can be disastrous in production as if a new service is deployed in the environment and pushes a new schema in redis
, that could break the gateway.
I have reproduced this also removing the Apollo federation.
My start-up now is :
services
.AddLogging()
.AddSingleton(sp =>
{
var redisConnectionString = Configuration.GetConnectionString("Redis");
return ConnectionMultiplexer.Connect(ConfigurationOptions.Parse(redisConnectionString));
})
.AddGraphQLServer()
.AddType(() => new UuidType("Uuid", defaultFormat: 'D'))
.AddAuthorization()
.AddRemoteSchemasFromConfiguration(httpOnlySchemas) // This is a small extension method to add remote http clients
.AddRemoteSchemasFromRedis(
SchemaCache.RedisCollectionName,
sp => sp.GetRequiredService<ConnectionMultiplexer>())
.AddTypeExtensionsFromString("type Query @authorize { }")
.RenameTypes()
.IgnoreType("ApplyPolicy")
.AddDirectiveMergeRule(MergeRuleFactory)
.AddTypeExtensionsFromFile("stitching/Stitching-CCD.graphql")
.ModifyRequestOptions(opt =>
opt.IncludeExceptionDetails = _currentEnv.IsDevelopment())
.InitializeOnStartup();
// Below this adds the `Uuid` to all underlying services as otherwise it breaks at start-up with the same error message as before
foreach (var schema in allSchemas)
{
services.AddGraphQL(schema)
.AddType(() => new UuidType("Uuid", defaultFormat: 'N'));
}
To validate the issue ref httpClients and redis I modified the code locally to add a collection of known schemas to the redis extension, and only add this schema if known as shown in this diff, and this works as a workaround, but I guess you guys didn't intend for that to work this way so will refrain to do a PR just yet.
Could you point me in the right direction in the HC code as to where this could potentially break? It definitely seems to occur when a Uuid
is added (and most our schemas use Guid
s so....)
Cheers
Vincent
Steps to reproduce
- Configure a redis cache.
- Make a
gateway
pull from it - Start a service that publishes to
Redis
with aUuid
type in it - Restart the
gateway
, the error message should be occur
Also it has to be noted that step 4 is necessary only locally as I use a local instance of docker redis. In our environments we use a hosted redis in aws
and the gateway polls from it. No restart is necessary in this instance as it breaks once polled.
Relevant log output
BackgroundService failed
HotChocolate.SchemaException: For more details look at the `Errors` property.
1. Unable to resolve type reference `None: Uuid!`. (HotChocolate.Types.ObjectType)
at HotChocolate.Configuration.RegisteredType.GetType[T](ITypeReference typeRef) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Configuration/RegisteredType.CompletionContext.cs:line 86
at HotChocolate.Types.OutputFieldBase`1.OnCompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember, TDefinition definition) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/OutputFieldBase.cs:line 58
at HotChocolate.Types.ObjectField.OnCompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember, ObjectFieldDefinition definition) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/ObjectField.cs:line 121
at HotChocolate.Types.FieldBase`1.CompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/FieldBase.cs:line 63
at HotChocolate.Types.FieldBase`1.HotChocolate.Types.Helpers.IFieldCompletion.CompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/FieldBase.cs:line 85
at HotChocolate.Internal.FieldInitHelper.CompleteFieldsInternal[TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, TField[] fields) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Internal/FieldInitHelper.cs:line 209
at HotChocolate.Internal.FieldInitHelper.CompleteFieldsInternal[TFieldDefinition,TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, IEnumerable`1 fieldDefinitions, Func`3 fieldFactory, Int32 fieldCount) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Internal/FieldInitHelper.cs:line 161
at HotChocolate.Internal.FieldInitHelper.CompleteFields[TFieldDefinition,TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, IReadOnlyList`1 fieldDefs, Func`3 fieldFactory) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Internal/FieldInitHelper.cs:line 76
at HotChocolate.Types.ObjectType.OnCompleteFields(ITypeCompletionContext context, ObjectTypeDefinition definition) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/ObjectType.Initialization.cs:line 73
at HotChocolate.Types.ObjectType.OnCompleteType(ITypeCompletionContext context, ObjectTypeDefinition definition) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/ObjectType.Initialization.cs:line 63
at HotChocolate.Types.TypeSystemObjectBase`1.CompleteType(ITypeCompletionContext context) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Types/TypeSystemObjectBase~1.cs:line 127
at HotChocolate.Configuration.TypeInitializer.<CompleteTypes>g__CompleteType|27_0(RegisteredType registeredType) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Configuration/TypeInitializer.cs:line 386
at HotChocolate.Configuration.TypeInitializer.ProcessTypes(TypeDependencyKind kind, Func`2 action) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Configuration/TypeInitializer.cs:line 429
at HotChocolate.Configuration.TypeInitializer.CompleteTypes() in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Configuration/TypeInitializer.cs:line 393
at HotChocolate.Configuration.TypeInitializer.Initialize() in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/Configuration/TypeInitializer.cs:line 96
at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types, LazySchema lazySchema) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/SchemaBuilder.Setup.cs:line 206
at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/SchemaBuilder.Setup.cs:line 74
at HotChocolate.SchemaBuilder.Create(IDescriptorContext context) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/SchemaBuilder.Create.cs:line 14
at HotChocolate.SchemaBuilder.HotChocolate.ISchemaBuilder.Create(IDescriptorContext context) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Types/SchemaBuilder.Create.cs:line 30
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(NameString schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 351
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(NameString schemaName, RequestExecutorSetup options, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 281
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(NameString schemaName, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 86
at Microsoft.Extensions.DependencyInjection.HotChocolateStitchingRequestExecutorExtensions.<>c__DisplayClass5_0.<<AddRemoteSchema>b__2>d.MoveNext() in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Stitching/src/Stitching/DependencyInjection/HotChocolateStitchingRequestExecutorExtensions.cs:line 237
--- End of stack trace from previous location ---
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(NameString schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 344
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(NameString schemaName, RequestExecutorSetup options, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 281
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(NameString schemaName, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 86
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(NameString schemaName, CancellationToken cancellationToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/Core/src/Execution/RequestExecutorResolver.cs:line 62
at HotChocolate.AspNetCore.Warmup.ExecutorWarmupService.ExecuteAsync(CancellationToken stoppingToken) in /home/vincentmary/work/repos/vmary2014hotchocolate/src/HotChocolate/AspNetCore/src/AspNetCore/Warmup/ExecutorWarmupService.cs:line 40
at Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService backgroundService)
Additional Context?
No response
Product
Hot Chocolate
Version
12.11.1. Also reproduced using 12.12.1 locally.
Describe the bug
I guess I have the similar issue but using AddRemoteSchema or AddRemoteSchemaFromFile
Startup:
builder.Services
.AddGraphQLServer()
.AddRemoteSchemaFromFile("TestSchema", @"schema.graphql")
Schema file "schema.graphql":
scalar ObjectId
type Query {
hello: ObjectId!
}
Steps to reproduce
- Use schema from url or local file
- Start gateway
- See error:
Unable to resolve type reference
None: ObjectId!. (HotChocolate.Types.ObjectType)
. - Adding ".AddType<ObjectIdType>()" from mongo package does not affect the behavior. If schema is described in code (via classes), everything is working ok.
Relevant log output
An unhandled exception has occurred while executing the request.
HotChocolate.SchemaException: For more details look at the `Errors` property.
1. Unable to resolve type reference `None: ObjectId!`. (HotChocolate.Types.ObjectType)
at HotChocolate.Configuration.RegisteredType.GetType[T](ITypeReference typeRef)
at HotChocolate.Types.OutputFieldBase`1.OnCompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember, TDefinition definition)
at HotChocolate.Types.ObjectField.OnCompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember, ObjectFieldDefinition definition)
at HotChocolate.Types.FieldBase`1.CompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember)
at HotChocolate.Internal.FieldInitHelper.CompleteFieldsInternal[TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, TField[] fields)
at HotChocolate.Internal.FieldInitHelper.CompleteFieldsInternal[TFieldDefinition,TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, IEnumerable`1 fieldDefinitions, Func`3 fieldFactory, Int32 fieldCount)
at HotChocolate.Internal.FieldInitHelper.CompleteFields[TFieldDefinition,TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, IReadOnlyList`1 fieldDefs, Func`3 fieldFactory)
at HotChocolate.Types.ObjectType.OnCompleteFields(ITypeCompletionContext context, ObjectTypeDefinition definition)
at HotChocolate.Types.ObjectType.OnCompleteType(ITypeCompletionContext context, ObjectTypeDefinition definition)
at HotChocolate.Types.TypeSystemObjectBase`1.CompleteType(ITypeCompletionContext context)
at HotChocolate.Configuration.TypeInitializer.<CompleteTypes>g__CompleteType|27_0(RegisteredType registeredType)
at HotChocolate.Configuration.TypeInitializer.ProcessTypes(TypeDependencyKind kind, Func`2 action)
at HotChocolate.Configuration.TypeInitializer.CompleteTypes()
at HotChocolate.Configuration.TypeInitializer.Initialize()
at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types, LazySchema lazySchema)
at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context)
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(NameString schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(NameString schemaName, RequestExecutorSetup options, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(NameString schemaName, CancellationToken cancellationToken)
at Microsoft.Extensions.DependencyInjection.HotChocolateStitchingRequestExecutorExtensions.<>c__DisplayClass5_0.<<AddRemoteSchema>b__2>d.MoveNext()
--- End of stack trace from previous location ---
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(NameString schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(NameString schemaName, RequestExecutorSetup options, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(NameString schemaName, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(NameString schemaName, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorProxy.GetRequestExecutorAsync(CancellationToken cancellationToken)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context, AllowedContentType contentType)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.<>c__DisplayClass13_0.<<UseCancellation>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Additional Context?
.NET 6
Product
Hot Chocolate
Version
12.13.2
any ideas or workarounds on this?
@AlexBar
builder.Services
.AddGraphQLServer()
.AddRemoteSchemaFromFile("TestSchema", @"schema.graphql")
.AddType(new AnyType("ObjectId");
builder.Services.AddGraphQL("TestSchema").AddType(new AnyType("ObjectId");
HotChocolate.Stitching is now in legacy mode and is replaced by HotChocolate.Fusion. I am closing this issue as we essentially froze the fusion code.
You can join the preview of Hot Chocolate Fusion now on Slack