Skip to content

Commit

Permalink
Added RabbitMQ Subscription Provider (#5599)
Browse files Browse the repository at this point in the history
  • Loading branch information
rstaib authored Dec 12, 2022
1 parent a2f64ad commit 86efd66
Show file tree
Hide file tree
Showing 15 changed files with 776 additions and 2 deletions.
30 changes: 30 additions & 0 deletions src/HotChocolate/Core/HotChocolate.Core.sln
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Execution.Abst
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Subscriptions.Tests", "test\Subscriptions.Tests\HotChocolate.Subscriptions.Tests.csproj", "{0B08ACE1-F3BF-4375-9381-22ACA1ECD387}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Subscriptions.RabbitMQ", "src\Subscriptions.RabbitMQ\HotChocolate.Subscriptions.RabbitMQ.csproj", "{E541AEB3-45D8-4089-A2BD-45859999A30D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Subscriptions.RabbitMQ.Tests", "test\Subscriptions.RabbitMQ.Tests\HotChocolate.Subscriptions.RabbitMQ.Tests.csproj", "{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -734,6 +738,30 @@ Global
{0B08ACE1-F3BF-4375-9381-22ACA1ECD387}.Release|x64.Build.0 = Release|Any CPU
{0B08ACE1-F3BF-4375-9381-22ACA1ECD387}.Release|x86.ActiveCfg = Release|Any CPU
{0B08ACE1-F3BF-4375-9381-22ACA1ECD387}.Release|x86.Build.0 = Release|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Debug|x64.ActiveCfg = Debug|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Debug|x64.Build.0 = Debug|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Debug|x86.ActiveCfg = Debug|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Debug|x86.Build.0 = Debug|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Release|Any CPU.Build.0 = Release|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Release|x64.ActiveCfg = Release|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Release|x64.Build.0 = Release|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Release|x86.ActiveCfg = Release|Any CPU
{E541AEB3-45D8-4089-A2BD-45859999A30D}.Release|x86.Build.0 = Release|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Debug|x64.ActiveCfg = Debug|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Debug|x64.Build.0 = Debug|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Debug|x86.ActiveCfg = Debug|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Debug|x86.Build.0 = Debug|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Release|Any CPU.Build.0 = Release|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Release|x64.ActiveCfg = Release|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Release|x64.Build.0 = Release|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Release|x86.ActiveCfg = Release|Any CPU
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -790,6 +818,8 @@ Global
{7FCCCA0F-FE75-4847-B464-982C02661F07} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{52E5E2D0-7DD2-429F-8D3F-805648332D66} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{0B08ACE1-F3BF-4375-9381-22ACA1ECD387} = {7462D089-D350-44D6-8131-896D949A65B7}
{E541AEB3-45D8-4089-A2BD-45859999A30D} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{EDA108F7-2C3D-4C7B-A1C1-286D6FB87761} = {7462D089-D350-44D6-8131-896D949A65B7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4D94C77-6657-4630-9D42-0A9AC5153A1B}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static IRequestExecutorBuilder AddNatsSubscriptions(
}

builder.AddSubscriptionDiagnostics();
AddNatsSubscriptions(builder.Services);
AddNatsSubscriptions(builder.Services, options);
return builder;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>HotChocolate.Subscriptions.Nats</PackageId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using HotChocolate.Execution.Configuration;
using Microsoft.Extensions.DependencyInjection.Extensions;
using HotChocolate.Subscriptions;
using HotChocolate.Subscriptions.RabbitMQ;
using RabbitMQ.Client;

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// These helper methods allows to register the RabbitMQ subscription provider with the GraphQL configuration.
/// </summary>
public static class RabbitMQPubSubExtensions
{
/// <summary>
/// Adds support for using RabbitMQ as a subscription provider.
/// </summary>
/// <param name="builder">
/// The GraphQL configuration builder.
/// </param>
/// <param name="connectionFactory">
/// The RabbitMQ connection factory. This parameter is optional; the default value is <c>null</c>.
/// The following properties will be overriden with <c>true</c> to make the connection recoverable.
/// - <c>AutomaticRecoveryEnabled</c>
/// - <c>DispatchConsumersAsync</c>
/// </param>
/// <param name="options">
/// The subscription provider options. This parameter is optional; the default value is <c>null</c>.
/// </param>
/// <returns>
/// Returns the GraphQL configuration builder for configuration chaining.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="builder"/> is <c>null</c>.
/// </exception>
public static IRequestExecutorBuilder AddRabbitMQSubscriptions(
this IRequestExecutorBuilder builder,
ConnectionFactory? connectionFactory = null,
SubscriptionOptions? options = null)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}

builder
.AddSubscriptionDiagnostics()
.Services
.AddRabbitMQSubscriptions(connectionFactory, options);

return builder;
}

private static void AddRabbitMQSubscriptions(
this IServiceCollection services,
ConnectionFactory? connectionFactory = null,
SubscriptionOptions? options = null)
{
services.TryAddSingleton(connectionFactory ?? new ConnectionFactory());
services.TryAddSingleton<IRabbitMQConnection, RabbitMQConnection>();
services.TryAddSingleton(options ?? new SubscriptionOptions());
services.TryAddSingleton<IMessageSerializer, DefaultJsonMessageSerializer>();
services.TryAddSingleton<RabbitMQPubSub>();
services.TryAddSingleton<ITopicEventSender>(sp => sp.GetRequiredService<RabbitMQPubSub>());
services.TryAddSingleton<ITopicEventReceiver>(sp => sp.GetRequiredService<RabbitMQPubSub>());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>HotChocolate.Subscriptions.RabbitMQ</PackageId>
<AssemblyName>HotChocolate.Subscriptions.RabbitMQ</AssemblyName>
<RootNamespace>HotChocolate.Subscriptions.RabbitMQ</RootNamespace>
<Description>Contains a Hot Chocolate GraphQL subscription provider for RabbitMQ.</Description>
</PropertyGroup>

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TargetFrameworks>$(Library2TargetFrameworks)</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<InternalsVisibleTo Include="HotChocolate.Subscriptions.RabbitMQ.Tests" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Execution.Abstractions\HotChocolate.Execution.Abstractions.csproj" />
<ProjectReference Include="..\Subscriptions\HotChocolate.Subscriptions.csproj" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\RabbitMQResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>RabbitMQResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\RabbitMQResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>RabbitMQResources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.4.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using RabbitMQ.Client;

namespace HotChocolate.Subscriptions.RabbitMQ;

internal interface IRabbitMQConnection
{
public Task<IModel> GetChannelAsync();
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>

<root>
<xsd:schema id="root"
xmlns=""
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">

</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="RabbitMQPubSubExtensions_AddRabbitMQSubscriptions_PrefixInvalid" xml:space="preserve">
<value>Prefix can only contain letters and numbers.</value>
</data>
<data name="RabbitMQPubSub_RabbitMQPubSub_PrefixCannotBeNull" xml:space="preserve">
<value>Value cannot be null or whitespace.</value>
</data>
<data name="Subscription_Unsubscribe_UnsubscribedFromRabbitMQ" xml:space="preserve">
<value>Unsubscribed from RabbitMQ.</value>
</data>
<data name="RabbitMQTopic_ConnectAsync_SubscribedToRabbitMQ" xml:space="preserve">
<value>Subscribed to RabbitMQ.</value>
</data>
<data name="RabbitMQConnection_InitializeConnection_ConnectionSucceededButFailedUnexpectedly" xml:space="preserve">
<value>Although the connection was successful, something went wrong.</value>
</data>
<data name="RabbitMQConnection_InitializeConnection_ConnectionAttemptFailed" xml:space="preserve">
<value>Connection could not be established. Connection attempt: {0}</value>
</data>
<data name="RabbitMQConnection_InitializeConnection_ConnectionFailedAfterRetry" xml:space="preserve">
<value>Connection could not be established after {0} connection attempts. Please check the connection settings and message broker service status.</value>
</data>
<data name="RabbitMQConnection_InitializeConnection_ConnectionFailedUnexpectedly" xml:space="preserve">
<value>Something went completely wrong,</value>
</data>
<data name="RabbitMQConnectionFailedException_RabbitMQConnectionFailedException_ConnectionFailed" xml:space="preserve">
<value>Connection could not be established after {0} attempts.</value>
</data>
</root>
Loading

0 comments on commit 86efd66

Please sign in to comment.