Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/All.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
<Project Path="HotChocolate/Fusion/src/Fusion.Composition/HotChocolate.Fusion.Composition.csproj" />
<Project Path="HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolate.Fusion.Diagnostics.csproj" />
<Project Path="HotChocolate/Fusion/src/Fusion.Execution.Types/HotChocolate.Fusion.Execution.Types.csproj" />
<Project Path="HotChocolate/Fusion/src/Fusion.Connectors.InMemory/HotChocolate.Fusion.Connectors.InMemory.csproj" />
<Project Path="HotChocolate/Fusion/src/Fusion.Execution/HotChocolate.Fusion.Execution.csproj" />
<Project Path="HotChocolate/Fusion/src/Fusion.Language/HotChocolate.Fusion.Language.csproj" />
<Project Path="HotChocolate/Fusion/src/Fusion.Packaging/HotChocolate.Fusion.Packaging.csproj" />
Expand All @@ -224,6 +225,7 @@
<Folder Name="/HotChocolate/Fusion/test/">
<Project Path="HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/HotChocolate.Fusion.AspNetCore.Tests.csproj" />
<Project Path="HotChocolate/Fusion/test/Fusion.Composition.Tests/HotChocolate.Fusion.Composition.Tests.csproj" />
<Project Path="HotChocolate/Fusion/test/Fusion.Connectors.InMemory.Tests/HotChocolate.Fusion.Connectors.InMemory.Tests.csproj" />
<Project Path="HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/HotChocolate.Fusion.Diagnostics.Tests.csproj" />
<Project Path="HotChocolate/Fusion/test/Fusion.EventSources.Tests/HotChocolate.Fusion.EventSources.Tests.csproj" />
<Project Path="HotChocolate/Fusion/test/Fusion.Execution.Tests/HotChocolate.Fusion.Execution.Tests.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,65 @@ public VariableBatchRequest WithFeatures(IFeatureCollection? features)
features,
Services,
Flags);

/// <summary>
/// Creates a new <see cref="VariableBatchRequest"/> from a GraphQL source text
/// and a JSON array of variable sets.
/// </summary>
/// <param name="sourceText">
/// The GraphQL operation source text.
/// </param>
/// <param name="variableValues">
/// A JSON document whose root element is an array of variable objects.
/// </param>
/// <param name="documentHash">
/// A GraphQL request document hash.
/// </param>
/// <param name="operationName">
/// A name of an operation in the GraphQL request document that shall be executed.
/// </param>
/// <param name="errorHandlingMode">
/// The requested error handling mode.
/// </param>
/// <param name="extensions">
/// The GraphQL request extension data.
/// </param>
/// <param name="contextData">
/// The initial global request state.
/// </param>
/// <param name="features">
/// The features that shall be used while executing the GraphQL request.
/// </param>
/// <param name="services">
/// The services that shall be used while executing the GraphQL request.
/// </param>
/// <param name="flags">
/// The GraphQL request flags can be used to limit the execution engine capabilities.
/// </param>
/// <returns>
/// Returns a new variable batch request.
/// </returns>
public static VariableBatchRequest FromSourceText(
string sourceText,
JsonDocument variableValues,
OperationDocumentHash? documentHash = null,
string? operationName = null,
ErrorHandlingMode? errorHandlingMode = null,
JsonDocument? extensions = null,
IReadOnlyDictionary<string, object?>? contextData = null,
IFeatureCollection? features = null,
IServiceProvider? services = null,
RequestFlags flags = RequestFlags.AllowAll)
=> new(
new OperationDocumentSourceText(sourceText),
null,
documentHash,
operationName,
errorHandlingMode,
new JsonDocumentOwner(variableValues),
extensions is null ? null : new(extensions),
contextData,
features,
services,
flags);
}
2 changes: 2 additions & 0 deletions src/HotChocolate/Fusion/HotChocolate.Fusion.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Project Path="src/Fusion.Language/HotChocolate.Fusion.Language.csproj" />
<Project Path="src/Fusion.Packaging/HotChocolate.Fusion.Packaging.csproj" />
<Project Path="src/Fusion.SourceSchema.Packaging/HotChocolate.Fusion.SourceSchema.Packaging.csproj" />
<Project Path="src/Fusion.Connectors.InMemory/HotChocolate.Fusion.Connectors.InMemory.csproj" />
<Project Path="src/Fusion.Utilities/HotChocolate.Fusion.Utilities.csproj" />
</Folder>
<Folder Name="/test/">
Expand All @@ -23,6 +24,7 @@
<Project Path="test/Fusion.Language.Tests/HotChocolate.Fusion.Language.Tests.csproj" />
<Project Path="test/Fusion.Packaging.Tests/HotChocolate.Fusion.Packaging.Tests.csproj" />
<Project Path="test/Fusion.SourceSchema.Packaging.Tests/HotChocolate.Fusion.SourceSchema.Packaging.Tests.csproj" />
<Project Path="test/Fusion.Connectors.InMemory.Tests/HotChocolate.Fusion.Connectors.InMemory.Tests.csproj" />
<Project Path="test/Fusion.Utilities.Tests/HotChocolate.Fusion.Utilities.Tests.csproj" />
<Project Path="test/Fusion.Tests.Shared/HotChocolate.Fusion.Tests.Shared.csproj" />
</Folder>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using HotChocolate.Fusion.Logging;

namespace HotChocolate.Fusion.Composition;

/// <summary>
/// The exception that is thrown when schema composition fails.
/// </summary>
public sealed class SchemaCompositionException : Exception
{
/// <summary>
/// Initializes a new instance of <see cref="SchemaCompositionException"/>.
/// </summary>
/// <param name="compositionLog">The composition log containing the errors.</param>
public SchemaCompositionException(CompositionLog compositionLog)
: base(BuildMessage(compositionLog))
{
CompositionLog = compositionLog;
}

/// <summary>
/// Gets the composition log containing the detailed errors and warnings
/// encountered during schema composition.
/// </summary>
public CompositionLog CompositionLog { get; }

private static string BuildMessage(CompositionLog log)
{
ArgumentNullException.ThrowIfNull(log);

var messages = new List<string>();

foreach (var entry in log)
{
if (entry.Severity == LogSeverity.Error)
{
messages.Add(entry.Message);
}
}

return messages.Count switch
{
0 => "Schema composition failed.",
1 => $"Schema composition failed: {messages[0]}",
_ => $"Schema composition failed with {messages.Count} errors: {messages[0]}"
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using HotChocolate.Execution;
using HotChocolate.Execution.Configuration;
using HotChocolate.Fusion.Configuration;
using HotChocolate.Fusion.Connectors.InMemory;
using HotChocolate.Fusion.Execution.Clients;
using HotChocolate.Transport.Formatters;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Extension methods for registering the in-memory connector on <see cref="IFusionGatewayBuilder"/>.
/// </summary>
public static class InMemoryFusionGatewayBuilderExtensions
{
/// <summary>
/// Adds an in-memory schema connector that executes operations directly in-process
/// against the schema registered by the given <paramref name="schemaBuilder"/>.
/// </summary>
/// <param name="builder">The fusion gateway builder.</param>
/// <param name="schemaBuilder">
/// The request executor builder whose <see cref="IRequestExecutorBuilder.Name"/>
/// identifies the source schema.
/// </param>
/// <returns>The fusion gateway builder for chaining.</returns>
public static IFusionGatewayBuilder AddInMemorySchema(
this IFusionGatewayBuilder builder,
IRequestExecutorBuilder schemaBuilder)
{
ArgumentNullException.ThrowIfNull(schemaBuilder);

return builder.AddInMemorySchema(schemaBuilder.Name);
}

/// <summary>
/// Adds an in-memory schema connector that executes operations directly in-process
/// against the schema identified by <paramref name="schemaName"/>.
/// </summary>
/// <param name="builder">The fusion gateway builder.</param>
/// <param name="schemaName">The name of the source schema.</param>
/// <returns>The fusion gateway builder for chaining.</returns>
public static IFusionGatewayBuilder AddInMemorySchema(
this IFusionGatewayBuilder builder,
string schemaName)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrEmpty(schemaName);

if (!builder.Services.Any(d => d.ServiceType == typeof(InMemorySourceSchemaClientFactory)))
{
// Remove default HTTP client factory — in-memory mode doesn't need it.
for (var i = builder.Services.Count - 1; i >= 0; i--)
{
if (builder.Services[i].ServiceType == typeof(ISourceSchemaClientFactory))
{
builder.Services.RemoveAt(i);
}
}

builder.Services.AddSingleton(
static sp => new InMemorySourceSchemaClientFactory(
sp.GetRequiredService<IRequestExecutorProvider>(),
sp.GetRequiredService<IRequestExecutorEvents>(),
JsonResultFormatter.Default));

builder.Services.AddSingleton<ISourceSchemaClientFactory>(
static sp => sp.GetRequiredService<InMemorySourceSchemaClientFactory>());
}

builder.Services.AddSingleton(new InMemorySchemaRegistration(schemaName));

FusionSetupUtilities.Configure(
builder,
setup => setup.DocumentProvider = sp =>
{
var names = sp.GetServices<InMemorySchemaRegistration>()
.Select(r => r.SchemaName).ToArray();
return new InMemoryConfigurationProvider(
names,
sp.GetRequiredService<IRequestExecutorProvider>(),
sp.GetRequiredService<IRequestExecutorEvents>());
});

FusionSetupUtilities.Configure(
builder,
setup => setup.ClientConfigurationModifiers.Add(
_ => new InMemorySourceSchemaClientConfiguration(schemaName)));

return builder;
}
}

internal sealed record InMemorySchemaRegistration(string SchemaName);
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyName>HotChocolate.Fusion.Connectors.InMemory</AssemblyName>
<RootNamespace>HotChocolate.Fusion</RootNamespace>
<LangVersion>preview</LangVersion>
<DefineConstants>$(DefineConstants);FUSION</DefineConstants>
</PropertyGroup>

<ItemGroup>
<InternalsVisibleTo Include="HotChocolate.Fusion.Connectors.InMemory.Tests" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Core\src\Core\HotChocolate.Core.csproj" />
<ProjectReference Include="..\..\..\AspNetCore\src\Transport.Formatters\HotChocolate.Transport.Formatters.csproj" />
<ProjectReference Include="..\Fusion.Composition\HotChocolate.Fusion.Composition.csproj" />
<ProjectReference Include="..\Fusion.Execution\HotChocolate.Fusion.Execution.csproj" />
</ItemGroup>

</Project>
Loading
Loading