Fixed queue arguments error due to wrong value types
Added test for publish overflows Removed support for Unity Container Changed third party package references to ranges Fixed XML documentation
This commit is contained in:
parent
35bd5e920d
commit
bcdb376256
@ -11,7 +11,6 @@
|
|||||||
<PackageReference Include="Castle.Windsor" Version="5.1.2" />
|
<PackageReference Include="Castle.Windsor" Version="5.1.2" />
|
||||||
<PackageReference Include="Ninject" Version="3.3.6" />
|
<PackageReference Include="Ninject" Version="3.3.6" />
|
||||||
<PackageReference Include="SimpleInjector" Version="5.4.1" />
|
<PackageReference Include="SimpleInjector" Version="5.4.1" />
|
||||||
<PackageReference Include="Unity" Version="5.11.10" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -20,7 +19,6 @@
|
|||||||
<ProjectReference Include="..\..\Tapeti.DataAnnotations\Tapeti.DataAnnotations.csproj" />
|
<ProjectReference Include="..\..\Tapeti.DataAnnotations\Tapeti.DataAnnotations.csproj" />
|
||||||
<ProjectReference Include="..\..\Tapeti.Ninject\Tapeti.Ninject.csproj" />
|
<ProjectReference Include="..\..\Tapeti.Ninject\Tapeti.Ninject.csproj" />
|
||||||
<ProjectReference Include="..\..\Tapeti.SimpleInjector\Tapeti.SimpleInjector.csproj" />
|
<ProjectReference Include="..\..\Tapeti.SimpleInjector\Tapeti.SimpleInjector.csproj" />
|
||||||
<ProjectReference Include="..\..\Tapeti.UnityContainer\Tapeti.UnityContainer.csproj" />
|
|
||||||
<ProjectReference Include="..\..\Tapeti\Tapeti.csproj" />
|
<ProjectReference Include="..\..\Tapeti\Tapeti.csproj" />
|
||||||
<ProjectReference Include="..\ExampleLib\ExampleLib.csproj" />
|
<ProjectReference Include="..\ExampleLib\ExampleLib.csproj" />
|
||||||
<ProjectReference Include="..\Messaging.TapetiExample\Messaging.TapetiExample.csproj" />
|
<ProjectReference Include="..\Messaging.TapetiExample\Messaging.TapetiExample.csproj" />
|
||||||
|
@ -13,8 +13,6 @@ using Tapeti.DataAnnotations;
|
|||||||
using Tapeti.Default;
|
using Tapeti.Default;
|
||||||
using Tapeti.Ninject;
|
using Tapeti.Ninject;
|
||||||
using Tapeti.SimpleInjector;
|
using Tapeti.SimpleInjector;
|
||||||
using Tapeti.UnityContainer;
|
|
||||||
using Unity;
|
|
||||||
using Container = SimpleInjector.Container;
|
using Container = SimpleInjector.Container;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
@ -30,7 +28,6 @@ namespace _01_PublishSubscribe
|
|||||||
// or use your IoC container of choice:
|
// or use your IoC container of choice:
|
||||||
//var dependencyResolver = GetAutofacDependencyResolver();
|
//var dependencyResolver = GetAutofacDependencyResolver();
|
||||||
//var dependencyResolver = GetCastleWindsorDependencyResolver();
|
//var dependencyResolver = GetCastleWindsorDependencyResolver();
|
||||||
//var dependencyResolver = GetUnityDependencyResolver();
|
|
||||||
//var dependencyResolver = GetNinjectDependencyResolver();
|
//var dependencyResolver = GetNinjectDependencyResolver();
|
||||||
|
|
||||||
// This helper is used because this example is not run as a service. You do not
|
// This helper is used because this example is not run as a service. You do not
|
||||||
@ -131,17 +128,6 @@ namespace _01_PublishSubscribe
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static IDependencyContainer GetUnityDependencyResolver()
|
|
||||||
{
|
|
||||||
var container = new UnityContainer();
|
|
||||||
|
|
||||||
container.RegisterType<ILogger, ConsoleLogger>();
|
|
||||||
container.RegisterType<ExamplePublisher>();
|
|
||||||
|
|
||||||
return new UnityDependencyResolver(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal static IDependencyContainer GetNinjectDependencyResolver()
|
internal static IDependencyContainer GetNinjectDependencyResolver()
|
||||||
{
|
{
|
||||||
var kernel = new StandardKernel();
|
var kernel = new StandardKernel();
|
||||||
|
@ -79,7 +79,7 @@ namespace ExampleLib
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!(e is AggregateException aggregateException))
|
if (e is not AggregateException aggregateException)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
if (aggregateException.InnerExceptions.Count != 1)
|
if (aggregateException.InnerExceptions.Count != 1)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
<PackageReference Include="Tapeti.Annotations" Version="3.0.0" />
|
<PackageReference Include="Tapeti.Annotations" Version="3.*-*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Builder;
|
using Autofac.Builder;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
namespace Tapeti.Autofac
|
namespace Tapeti.Autofac
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dependency resolver and container implementation for Autofac.
|
/// Dependency resolver and container implementation for Autofac.
|
||||||
/// Since this class needs access to both the ContainerBuilder and the built IContainer,
|
/// Since this class needs access to both the ContainerBuilder and the built IContainer,
|
||||||
@ -83,7 +84,7 @@ namespace Tapeti.Autofac
|
|||||||
{
|
{
|
||||||
CheckContainerBuilder();
|
CheckContainerBuilder();
|
||||||
containerBuilder
|
containerBuilder
|
||||||
.Register(context => factory())
|
.Register(_ => factory())
|
||||||
.As<TService>()
|
.As<TService>()
|
||||||
.PreserveExistingDefaults();
|
.PreserveExistingDefaults();
|
||||||
}
|
}
|
||||||
@ -116,7 +117,7 @@ namespace Tapeti.Autofac
|
|||||||
{
|
{
|
||||||
CheckContainerBuilder();
|
CheckContainerBuilder();
|
||||||
containerBuilder
|
containerBuilder
|
||||||
.Register(context => factory())
|
.Register(_ => factory())
|
||||||
.As<TService>()
|
.As<TService>()
|
||||||
.SingleInstance()
|
.SingleInstance()
|
||||||
.PreserveExistingDefaults();
|
.PreserveExistingDefaults();
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Autofac" Version="6.5.0" />
|
<PackageReference Include="Autofac" Version="6.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Castle.Windsor" Version="5.1.2" />
|
<PackageReference Include="Castle.Windsor" Version="5.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -4,7 +4,6 @@ using Castle.Windsor;
|
|||||||
|
|
||||||
namespace Tapeti.CastleWindsor
|
namespace Tapeti.CastleWindsor
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dependency resolver and container implementation for Castle Windsor.
|
/// Dependency resolver and container implementation for Castle Windsor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3,7 +3,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.DataAnnotations
|
namespace Tapeti.DataAnnotations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the DataAnnotations validation middleware.
|
/// Provides the DataAnnotations validation middleware.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -5,7 +5,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.DataAnnotations
|
namespace Tapeti.DataAnnotations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates consumed messages using System.ComponentModel.DataAnnotations
|
/// Validates consumed messages using System.ComponentModel.DataAnnotations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -5,7 +5,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.DataAnnotations
|
namespace Tapeti.DataAnnotations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates published messages using System.ComponentModel.DataAnnotations
|
/// Validates published messages using System.ComponentModel.DataAnnotations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -11,7 +11,6 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.SQL
|
namespace Tapeti.Flow.SQL
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IFlowRepository implementation for SQL server.
|
/// IFlowRepository implementation for SQL server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -13,7 +13,7 @@ namespace Tapeti.Flow.SQL
|
|||||||
// 2627: Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'. The duplicate key value is %ls.
|
// 2627: Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'. The duplicate key value is %ls.
|
||||||
public static bool IsDuplicateKey(SqlException e)
|
public static bool IsDuplicateKey(SqlException e)
|
||||||
{
|
{
|
||||||
return e != null && (e.Number == 2601 || e.Number == 2627);
|
return e is { Number: 2601 or 2627 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -21,12 +21,12 @@ namespace Tapeti.Flow.SQL
|
|||||||
{
|
{
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case TimeoutException _:
|
case TimeoutException:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Exception exception:
|
case not null:
|
||||||
{
|
{
|
||||||
var sqlExceptions = ExtractSqlExceptions(exception);
|
var sqlExceptions = ExtractSqlExceptions(e);
|
||||||
return sqlExceptions.Select(UnwrapSqlErrors).Any(IsRecoverableSQLError);
|
return sqlExceptions.Select(UnwrapSqlErrors).Any(IsRecoverableSQLError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Annotations
|
namespace Tapeti.Flow.Annotations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marks a message handler as a response message handler which continues a Tapeti Flow.
|
/// Marks a message handler as a response message handler which continues a Tapeti Flow.
|
||||||
/// The method only receives direct messages, and does not create a routing key based binding to the queue.
|
/// The method only receives direct messages, and does not create a routing key based binding to the queue.
|
||||||
|
@ -3,7 +3,6 @@ using JetBrains.Annotations;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Annotations
|
namespace Tapeti.Flow.Annotations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marks this method as the start of a Tapeti Flow. Use IFlowStarter.Start to begin a new flow and
|
/// Marks this method as the start of a Tapeti Flow. Use IFlowStarter.Start to begin a new flow and
|
||||||
/// call this method. Must return an IYieldPoint.
|
/// call this method. Must return an IYieldPoint.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
namespace Tapeti.Flow
|
namespace Tapeti.Flow
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -60,7 +60,7 @@ namespace Tapeti.Flow.Default
|
|||||||
}
|
}
|
||||||
else if (context.Result.Info.ParameterType == typeof(void))
|
else if (context.Result.Info.ParameterType == typeof(void))
|
||||||
{
|
{
|
||||||
context.Result.SetHandler((messageContext, value) => HandleParallelResponse(messageContext));
|
context.Result.SetHandler((messageContext, _) => HandleParallelResponse(messageContext));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new ArgumentException($"Result type must be IYieldPoint, Task or void in controller {context.Method.DeclaringType?.FullName}, method {context.Method.Name}");
|
throw new ArgumentException($"Result type must be IYieldPoint, Task or void in controller {context.Method.DeclaringType?.FullName}, method {context.Method.Name}");
|
||||||
|
@ -3,7 +3,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Default
|
namespace Tapeti.Flow.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation for IFlowHandlerContext
|
/// Default implementation for IFlowHandlerContext
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -206,7 +206,7 @@ namespace Tapeti.Flow.Default
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async ValueTask Execute(IFlowHandlerContext context, IYieldPoint yieldPoint)
|
public async ValueTask Execute(IFlowHandlerContext context, IYieldPoint yieldPoint)
|
||||||
{
|
{
|
||||||
if (!(yieldPoint is DelegateYieldPoint executableYieldPoint))
|
if (yieldPoint is not DelegateYieldPoint executableYieldPoint)
|
||||||
throw new YieldPointException($"Yield point is required in controller {context.Controller.GetType().Name} for method {context.Method.Name}");
|
throw new YieldPointException($"Yield point is required in controller {context.Controller.GetType().Name} for method {context.Method.Name}");
|
||||||
|
|
||||||
FlowContext flowContext = null;
|
FlowContext flowContext = null;
|
||||||
@ -297,8 +297,8 @@ namespace Tapeti.Flow.Default
|
|||||||
{
|
{
|
||||||
private class RequestInfo
|
private class RequestInfo
|
||||||
{
|
{
|
||||||
public object Message { get; set; }
|
public object Message { get; init; }
|
||||||
public ResponseHandlerInfo ResponseHandlerInfo { get; set; }
|
public ResponseHandlerInfo ResponseHandlerInfo { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -372,21 +372,13 @@ namespace Tapeti.Flow.Default
|
|||||||
{
|
{
|
||||||
if (requests.Count == 0)
|
if (requests.Count == 0)
|
||||||
{
|
{
|
||||||
switch (noRequestsBehaviour)
|
return noRequestsBehaviour switch
|
||||||
{
|
{
|
||||||
case FlowNoRequestsBehaviour.Exception:
|
FlowNoRequestsBehaviour.Exception => throw new YieldPointException("At least one request must be added before yielding a parallel request"),
|
||||||
throw new YieldPointException("At least one request must be added before yielding a parallel request");
|
FlowNoRequestsBehaviour.Converge => new DelegateYieldPoint(context => flowProvider.Converge(context, convergeMethod.Method.Name, convergeMethodSync)),
|
||||||
|
FlowNoRequestsBehaviour.EndFlow => new DelegateYieldPoint(EndFlow),
|
||||||
case FlowNoRequestsBehaviour.Converge:
|
_ => throw new ArgumentOutOfRangeException(nameof(noRequestsBehaviour), noRequestsBehaviour, null)
|
||||||
return new DelegateYieldPoint(context =>
|
};
|
||||||
flowProvider.Converge(context, convergeMethod.Method.Name, convergeMethodSync));
|
|
||||||
|
|
||||||
case FlowNoRequestsBehaviour.EndFlow:
|
|
||||||
return new DelegateYieldPoint(EndFlow);
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(noRequestsBehaviour), noRequestsBehaviour, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convergeMethod?.Method == null)
|
if (convergeMethod?.Method == null)
|
||||||
|
@ -6,7 +6,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Default
|
namespace Tapeti.Flow.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation for IFlowStarter.
|
/// Default implementation for IFlowStarter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -18,7 +18,7 @@ namespace Tapeti.Flow.Default
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public FlowMetadata Metadata
|
public FlowMetadata Metadata
|
||||||
{
|
{
|
||||||
get => metadata ?? (metadata = new FlowMetadata());
|
get => metadata ??= new FlowMetadata();
|
||||||
set => metadata = value;
|
set => metadata = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ namespace Tapeti.Flow.Default
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<Guid, ContinuationMetadata> Continuations
|
public Dictionary<Guid, ContinuationMetadata> Continuations
|
||||||
{
|
{
|
||||||
get => continuations ?? (continuations = new Dictionary<Guid, ContinuationMetadata>());
|
get => continuations ??= new Dictionary<Guid, ContinuationMetadata>();
|
||||||
set => continuations = value;
|
set => continuations = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ using Tapeti.Flow.FlowHelpers;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Default
|
namespace Tapeti.Flow.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation of IFlowStore.
|
/// Default implementation of IFlowStore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -119,7 +118,7 @@ namespace Tapeti.Flow.Default
|
|||||||
if (!loaded)
|
if (!loaded)
|
||||||
throw new InvalidOperationException("Flow store is not yet loaded.");
|
throw new InvalidOperationException("Flow store is not yet loaded.");
|
||||||
|
|
||||||
return new ValueTask<Guid?>(continuationLookup.TryGetValue(continuationID, out var result) ? result : (Guid?)null);
|
return new ValueTask<Guid?>(continuationLookup.TryGetValue(continuationID, out var result) ? result : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Default
|
namespace Tapeti.Flow.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation for IFlowRepository. Does not persist any state, relying on the FlowStore's cache instead.
|
/// Default implementation for IFlowRepository. Does not persist any state, relying on the FlowStore's cache instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4,7 +4,6 @@ using Tapeti.Flow.Default;
|
|||||||
|
|
||||||
namespace Tapeti.Flow
|
namespace Tapeti.Flow
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the Flow middleware.
|
/// Provides the Flow middleware.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -35,8 +35,6 @@ namespace Tapeti.Flow.FlowHelpers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
assembly = Assembly.Load(match.Groups["assembly"].Value);
|
assembly = Assembly.Load(match.Groups["assembly"].Value);
|
||||||
if (assembly == null)
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Flow
|
namespace Tapeti.Flow
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides information about the handler for the flow.
|
/// Provides information about the handler for the flow.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -42,7 +42,6 @@ namespace Tapeti.Flow
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a lock on the flow state, to provide thread safety.
|
/// Represents a lock on the flow state, to provide thread safety.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Flow
|
namespace Tapeti.Flow
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when a response is expected to end a flow, but none was provided.
|
/// Raised when a response is expected to end a flow, but none was provided.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -36,6 +36,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||||
<PackageReference Include="Tapeti.Annotations" Version="3.0.0" />
|
<PackageReference Include="Tapeti.Annotations" Version="3.*-*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Flow
|
namespace Tapeti.Flow
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when an invalid yield point is returned.
|
/// Raised when an invalid yield point is returned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4,7 +4,6 @@ using Ninject;
|
|||||||
|
|
||||||
namespace Tapeti.Ninject
|
namespace Tapeti.Ninject
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dependency resolver and container implementation for Ninject.
|
/// Dependency resolver and container implementation for Ninject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -49,7 +48,7 @@ namespace Tapeti.Ninject
|
|||||||
if (kernel.GetBindings(typeof(TService)).Any())
|
if (kernel.GetBindings(typeof(TService)).Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
kernel.Bind<TService>().ToMethod(context => factory());
|
kernel.Bind<TService>().ToMethod(_ => factory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ namespace Tapeti.Ninject
|
|||||||
if (kernel.GetBindings(typeof(TService)).Any())
|
if (kernel.GetBindings(typeof(TService)).Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
kernel.Bind<TService>().ToMethod(context => factory()).InSingletonScope();
|
kernel.Bind<TService>().ToMethod(_ => factory()).InSingletonScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Ninject" Version="3.3.6" />
|
<PackageReference Include="Ninject" Version="3.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
<PackageReference Include="Serilog" Version="2.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
using Tapeti.Connection;
|
||||||
using ISerilogLogger = Serilog.ILogger;
|
using ISerilogLogger = Serilog.ILogger;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
@ -129,7 +130,7 @@ namespace Tapeti.Serilog
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void QueueExistsWarning(string queueName, IReadOnlyDictionary<string, string> existingArguments, IReadOnlyDictionary<string, string> arguments)
|
public void QueueExistsWarning(string queueName, IRabbitMQArguments existingArguments, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
seriLogger.Warning("Tapeti: durable queue {queueName} exists with incompatible x-arguments ({existingArguments} vs. {arguments}) and will not be redeclared, queue will be consumed as-is",
|
seriLogger.Warning("Tapeti: durable queue {queueName} exists with incompatible x-arguments ({existingArguments} vs. {arguments}) and will not be redeclared, queue will be consumed as-is",
|
||||||
queueName,
|
queueName,
|
||||||
|
@ -4,7 +4,6 @@ using SimpleInjector;
|
|||||||
|
|
||||||
namespace Tapeti.SimpleInjector
|
namespace Tapeti.SimpleInjector
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dependency resolver and container implementation for SimpleInjector.
|
/// Dependency resolver and container implementation for SimpleInjector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="SimpleInjector" Version="5.4.1" />
|
<PackageReference Include="SimpleInjector" Version="5.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
// Do not include in the Release build for AppVeyor due to the Docker requirement
|
// Do not include in the Release build for AppVeyor due to the Docker requirement
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Tapeti.Connection;
|
using Tapeti.Connection;
|
||||||
|
using Tapeti.Default;
|
||||||
|
using Tapeti.Exceptions;
|
||||||
using Tapeti.Tests.Mock;
|
using Tapeti.Tests.Mock;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
@ -11,11 +14,14 @@ using Xunit.Abstractions;
|
|||||||
namespace Tapeti.Tests.Client
|
namespace Tapeti.Tests.Client
|
||||||
{
|
{
|
||||||
[Collection(RabbitMQCollection.Name)]
|
[Collection(RabbitMQCollection.Name)]
|
||||||
public class TapetiClientTests
|
public class TapetiClientTests : IAsyncLifetime
|
||||||
{
|
{
|
||||||
private readonly RabbitMQFixture fixture;
|
private readonly RabbitMQFixture fixture;
|
||||||
private readonly MockDependencyResolver dependencyResolver = new();
|
private readonly MockDependencyResolver dependencyResolver = new();
|
||||||
|
|
||||||
|
private TapetiClient client;
|
||||||
|
|
||||||
|
|
||||||
public TapetiClientTests(RabbitMQFixture fixture, ITestOutputHelper testOutputHelper)
|
public TapetiClientTests(RabbitMQFixture fixture, ITestOutputHelper testOutputHelper)
|
||||||
{
|
{
|
||||||
this.fixture = fixture;
|
this.fixture = fixture;
|
||||||
@ -24,6 +30,22 @@ namespace Tapeti.Tests.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Task InitializeAsync()
|
||||||
|
{
|
||||||
|
client = CreateClient();
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task DisposeAsync()
|
||||||
|
{
|
||||||
|
await client.Close();
|
||||||
|
client = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Fixture()
|
public void Fixture()
|
||||||
{
|
{
|
||||||
@ -35,31 +57,50 @@ namespace Tapeti.Tests.Client
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task DynamicQueueDeclareNoPrefix()
|
public async Task DynamicQueueDeclareNoPrefix()
|
||||||
{
|
{
|
||||||
var client = CreateCilent();
|
|
||||||
|
|
||||||
var queueName = await client.DynamicQueueDeclare(null, null, CancellationToken.None);
|
var queueName = await client.DynamicQueueDeclare(null, null, CancellationToken.None);
|
||||||
queueName.Should().NotBeNullOrEmpty();
|
queueName.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
await client.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task DynamicQueueDeclarePrefix()
|
public async Task DynamicQueueDeclarePrefix()
|
||||||
{
|
{
|
||||||
var client = CreateCilent();
|
|
||||||
|
|
||||||
var queueName = await client.DynamicQueueDeclare("dynamicprefix", null, CancellationToken.None);
|
var queueName = await client.DynamicQueueDeclare("dynamicprefix", null, CancellationToken.None);
|
||||||
queueName.Should().StartWith("dynamicprefix");
|
queueName.Should().StartWith("dynamicprefix");
|
||||||
|
}
|
||||||
|
|
||||||
await client.Close();
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PublishHandleOverflow()
|
||||||
|
{
|
||||||
|
var queue1 = await client.DynamicQueueDeclare(null, new RabbitMQArguments
|
||||||
|
{
|
||||||
|
{ "x-max-length", 5 },
|
||||||
|
{ "x-overflow", "reject-publish" }
|
||||||
|
}, CancellationToken.None);
|
||||||
|
|
||||||
|
var queue2 = await client.DynamicQueueDeclare(null, null, CancellationToken.None);
|
||||||
|
|
||||||
|
var body = Encoding.UTF8.GetBytes("Hello world!");
|
||||||
|
var properties = new MessageProperties();
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < 5; i++)
|
||||||
|
await client.Publish(body, properties, null, queue1, true);
|
||||||
|
|
||||||
|
|
||||||
|
var publishOverMaxLength = () => client.Publish(body, properties, null, queue1, true);
|
||||||
|
await publishOverMaxLength.Should().ThrowAsync<NackException>();
|
||||||
|
|
||||||
|
// The channel should recover and allow further publishing
|
||||||
|
await client.Publish(body, properties, null, queue2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO test the other methods
|
// TODO test the other methods
|
||||||
|
|
||||||
|
|
||||||
private TapetiClient CreateCilent()
|
private TapetiClient CreateClient()
|
||||||
{
|
{
|
||||||
return new TapetiClient(
|
return new TapetiClient(
|
||||||
new TapetiConfig.Config(dependencyResolver),
|
new TapetiConfig.Config(dependencyResolver),
|
||||||
|
@ -18,7 +18,7 @@ namespace Tapeti.Tests.Config
|
|||||||
private static readonly MockRepository MoqRepository = new(MockBehavior.Strict);
|
private static readonly MockRepository MoqRepository = new(MockBehavior.Strict);
|
||||||
|
|
||||||
private readonly Mock<ITapetiClient> client;
|
private readonly Mock<ITapetiClient> client;
|
||||||
private readonly Dictionary<string, IReadOnlyDictionary<string, string>> declaredQueues = new();
|
private readonly Dictionary<string, IRabbitMQArguments> declaredQueues = new();
|
||||||
|
|
||||||
|
|
||||||
public QueueArgumentsTest()
|
public QueueArgumentsTest()
|
||||||
@ -45,8 +45,8 @@ namespace Tapeti.Tests.Config
|
|||||||
|
|
||||||
var queue = 0;
|
var queue = 0;
|
||||||
client
|
client
|
||||||
.Setup(c => c.DynamicQueueDeclare(null, It.IsAny<IReadOnlyDictionary<string, string>>(), It.IsAny<CancellationToken>()))
|
.Setup(c => c.DynamicQueueDeclare(null, It.IsAny<IRabbitMQArguments>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback((string _, IReadOnlyDictionary<string, string> arguments, CancellationToken _) =>
|
.Callback((string _, IRabbitMQArguments arguments, CancellationToken _) =>
|
||||||
{
|
{
|
||||||
queue++;
|
queue++;
|
||||||
declaredQueues.Add($"queue-{queue}", arguments);
|
declaredQueues.Add($"queue-{queue}", arguments);
|
||||||
@ -54,8 +54,8 @@ namespace Tapeti.Tests.Config
|
|||||||
.ReturnsAsync(() => $"queue-{queue}");
|
.ReturnsAsync(() => $"queue-{queue}");
|
||||||
|
|
||||||
client
|
client
|
||||||
.Setup(c => c.DurableQueueDeclare(It.IsAny<string>(), It.IsAny<IEnumerable<QueueBinding>>(), It.IsAny<IReadOnlyDictionary<string, string>>(), It.IsAny<CancellationToken>()))
|
.Setup(c => c.DurableQueueDeclare(It.IsAny<string>(), It.IsAny<IEnumerable<QueueBinding>>(), It.IsAny<IRabbitMQArguments>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback((string queueName, IEnumerable<QueueBinding> _, IReadOnlyDictionary<string, string> arguments, CancellationToken _) =>
|
.Callback((string queueName, IEnumerable<QueueBinding> _, IRabbitMQArguments arguments, CancellationToken _) =>
|
||||||
{
|
{
|
||||||
declaredQueues.Add(queueName, arguments);
|
declaredQueues.Add(queueName, arguments);
|
||||||
})
|
})
|
||||||
@ -89,10 +89,10 @@ namespace Tapeti.Tests.Config
|
|||||||
var arguments = declaredQueues["queue-1"];
|
var arguments = declaredQueues["queue-1"];
|
||||||
|
|
||||||
arguments.Should().ContainKey("x-custom").WhoseValue.Should().Be("custom value");
|
arguments.Should().ContainKey("x-custom").WhoseValue.Should().Be("custom value");
|
||||||
arguments.Should().ContainKey("x-another").WhoseValue.Should().Be("another value");
|
arguments.Should().ContainKey("x-another").WhoseValue.Should().Be(true);
|
||||||
arguments.Should().ContainKey("x-max-length").WhoseValue.Should().Be("100");
|
arguments.Should().ContainKey("x-max-length").WhoseValue.Should().Be(100);
|
||||||
arguments.Should().ContainKey("x-max-length-bytes").WhoseValue.Should().Be("100000");
|
arguments.Should().ContainKey("x-max-length-bytes").WhoseValue.Should().Be(100000);
|
||||||
arguments.Should().ContainKey("x-message-ttl").WhoseValue.Should().Be("4269");
|
arguments.Should().ContainKey("x-message-ttl").WhoseValue.Should().Be(4269);
|
||||||
arguments.Should().ContainKey("x-overflow").WhoseValue.Should().Be("reject-publish");
|
arguments.Should().ContainKey("x-overflow").WhoseValue.Should().Be("reject-publish");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,10 +108,10 @@ namespace Tapeti.Tests.Config
|
|||||||
declaredQueues.Should().HaveCount(2);
|
declaredQueues.Should().HaveCount(2);
|
||||||
|
|
||||||
var arguments1 = declaredQueues["queue-1"];
|
var arguments1 = declaredQueues["queue-1"];
|
||||||
arguments1.Should().ContainKey("x-max-length").WhoseValue.Should().Be("100");
|
arguments1.Should().ContainKey("x-max-length").WhoseValue.Should().Be(100);
|
||||||
|
|
||||||
var arguments2 = declaredQueues["queue-2"];
|
var arguments2 = declaredQueues["queue-2"];
|
||||||
arguments2.Should().ContainKey("x-max-length-bytes").WhoseValue.Should().Be("100000");
|
arguments2.Should().ContainKey("x-max-length-bytes").WhoseValue.Should().Be(100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ namespace Tapeti.Tests.Config
|
|||||||
|
|
||||||
|
|
||||||
[DynamicQueue]
|
[DynamicQueue]
|
||||||
[QueueArguments("x-custom", "custom value", "x-another", "another value", MaxLength = 100, MaxLengthBytes = 100000, MessageTTL = 4269, Overflow = RabbitMQOverflow.RejectPublish)]
|
[QueueArguments("x-custom", "custom value", "x-another", true, MaxLength = 100, MaxLengthBytes = 100000, MessageTTL = 4269, Overflow = RabbitMQOverflow.RejectPublish)]
|
||||||
private class TestController
|
private class TestController
|
||||||
{
|
{
|
||||||
public void HandleMessage1(TestMessage1 message)
|
public void HandleMessage1(TestMessage1 message)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
using Tapeti.Connection;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace Tapeti.Tests.Mock
|
namespace Tapeti.Tests.Mock
|
||||||
@ -49,7 +49,7 @@ namespace Tapeti.Tests.Mock
|
|||||||
: $"Declaring {(durable ? "durable" : "dynamic")} queue {queueName}");
|
: $"Declaring {(durable ? "durable" : "dynamic")} queue {queueName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueExistsWarning(string queueName, IReadOnlyDictionary<string, string> existingArguments, IReadOnlyDictionary<string, string> arguments)
|
public void QueueExistsWarning(string queueName, IRabbitMQArguments existingArguments, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
var argumentsText = new StringBuilder();
|
var argumentsText = new StringBuilder();
|
||||||
foreach (var pair in arguments)
|
foreach (var pair in arguments)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
namespace Tapeti.Transient
|
namespace Tapeti.Transient
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -4,7 +4,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Transient
|
namespace Tapeti.Transient
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a binding for transient request response messages.
|
/// Implements a binding for transient request response messages.
|
||||||
/// Register this binding using the WithTransient config extension method.
|
/// Register this binding using the WithTransient config extension method.
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Transient
|
namespace Tapeti.Transient
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation of ITransientPublisher
|
/// Default implementation of ITransientPublisher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -55,7 +55,7 @@ namespace Tapeti.Transient
|
|||||||
public async Task<object> RequestResponse(IPublisher publisher, object request)
|
public async Task<object> RequestResponse(IPublisher publisher, object request)
|
||||||
{
|
{
|
||||||
var correlation = Guid.NewGuid();
|
var correlation = Guid.NewGuid();
|
||||||
var tcs = map.GetOrAdd(correlation, c => new TaskCompletionSource<object>());
|
var tcs = map.GetOrAdd(correlation, _ => new TaskCompletionSource<object>());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -77,7 +77,7 @@ namespace Tapeti.Transient
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (new Timer(TimeoutResponse, tcs, defaultTimeoutMs, -1))
|
await using (new Timer(TimeoutResponse, tcs, defaultTimeoutMs, -1))
|
||||||
{
|
{
|
||||||
return await tcs.Task;
|
return await tcs.Task;
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
||||||
<Authors>Mark van Renswoude</Authors>
|
|
||||||
<Company />
|
|
||||||
<Description>Unity container integration package for Tapeti</Description>
|
|
||||||
<PackageTags>rabbitmq tapeti unity</PackageTags>
|
|
||||||
<PackageLicenseExpression>Unlicense</PackageLicenseExpression>
|
|
||||||
<PackageProjectUrl>https://github.com/MvRens/Tapeti</PackageProjectUrl>
|
|
||||||
<PackageIcon>Tapeti.SimpleInjector.png</PackageIcon>
|
|
||||||
<Version>2.0.0</Version>
|
|
||||||
<LangVersion>9</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Unity" Version="5.11.10" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Tapeti\Tapeti.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="..\resources\icons\Tapeti.SimpleInjector.png">
|
|
||||||
<Pack>True</Pack>
|
|
||||||
<PackagePath></PackagePath>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,90 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Unity;
|
|
||||||
using Unity.Lifetime;
|
|
||||||
|
|
||||||
namespace Tapeti.UnityContainer
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
|
||||||
/// Dependency resolver and container implementation for SimpleInjector.
|
|
||||||
/// </summary>
|
|
||||||
public class UnityDependencyResolver : IDependencyContainer
|
|
||||||
{
|
|
||||||
private readonly IUnityContainer container;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
public UnityDependencyResolver(IUnityContainer container)
|
|
||||||
{
|
|
||||||
this.container = container;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public T Resolve<T>() where T : class
|
|
||||||
{
|
|
||||||
return container.Resolve<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public object Resolve(Type type)
|
|
||||||
{
|
|
||||||
return container.Resolve(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RegisterDefault<TService, TImplementation>() where TService : class where TImplementation : class, TService
|
|
||||||
{
|
|
||||||
if (container.IsRegistered(typeof(TService)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
container.RegisterType<TService, TImplementation>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RegisterDefault<TService>(Func<TService> factory) where TService : class
|
|
||||||
{
|
|
||||||
if (container.IsRegistered(typeof(TService)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
container.RegisterFactory<TService>(c => factory());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RegisterDefaultSingleton<TService, TImplementation>() where TService : class where TImplementation : class, TService
|
|
||||||
{
|
|
||||||
if (container.IsRegistered(typeof(TService)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
container.RegisterSingleton<TService, TImplementation>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RegisterDefaultSingleton<TService>(TService instance) where TService : class
|
|
||||||
{
|
|
||||||
if (container.IsRegistered(typeof(TService)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
container.RegisterInstance(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RegisterDefaultSingleton<TService>(Func<TService> factory) where TService : class
|
|
||||||
{
|
|
||||||
if (container.IsRegistered(typeof(TService)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
container.RegisterFactory<TService>(c => factory(), new SingletonLifetimeManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RegisterController(Type type)
|
|
||||||
{
|
|
||||||
container.RegisterType(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -45,8 +45,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.CastleWindsor", "Tap
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.Autofac", "Tapeti.Autofac\Tapeti.Autofac.csproj", "{B3802005-C941-41B6-A9A5-20573A7C24AE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.Autofac", "Tapeti.Autofac\Tapeti.Autofac.csproj", "{B3802005-C941-41B6-A9A5-20573A7C24AE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.UnityContainer", "Tapeti.UnityContainer\Tapeti.UnityContainer.csproj", "{BA8CA9A2-BAFF-42BB-8439-3DD9D1F6C32E}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.Ninject", "Tapeti.Ninject\Tapeti.Ninject.csproj", "{29478B10-FC53-4E93-ADEF-A775D9408131}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.Ninject", "Tapeti.Ninject\Tapeti.Ninject.csproj", "{29478B10-FC53-4E93-ADEF-A775D9408131}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-StatelessRequestResponse", "Examples\06-StatelessRequestResponse\06-StatelessRequestResponse.csproj", "{152227AA-3165-4550-8997-6EA80C84516E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-StatelessRequestResponse", "Examples\06-StatelessRequestResponse\06-StatelessRequestResponse.csproj", "{152227AA-3165-4550-8997-6EA80C84516E}"
|
||||||
@ -55,7 +53,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-ParallelizationTest", "E
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-MessageHandlerLogging", "Examples\08-MessageHandlerLogging\08-MessageHandlerLogging.csproj", "{906605A6-2CAB-4B29-B0DD-B735BF265E39}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-MessageHandlerLogging", "Examples\08-MessageHandlerLogging\08-MessageHandlerLogging.csproj", "{906605A6-2CAB-4B29-B0DD-B735BF265E39}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tapeti.Benchmarks", "Tapeti.Benchmarks\Tapeti.Benchmarks.csproj", "{DBE56131-9207-4CEA-BA3E-031351677C48}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tapeti.Benchmarks", "Tapeti.Benchmarks\Tapeti.Benchmarks.csproj", "{DBE56131-9207-4CEA-BA3E-031351677C48}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -131,10 +129,6 @@ Global
|
|||||||
{B3802005-C941-41B6-A9A5-20573A7C24AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B3802005-C941-41B6-A9A5-20573A7C24AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B3802005-C941-41B6-A9A5-20573A7C24AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B3802005-C941-41B6-A9A5-20573A7C24AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B3802005-C941-41B6-A9A5-20573A7C24AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B3802005-C941-41B6-A9A5-20573A7C24AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BA8CA9A2-BAFF-42BB-8439-3DD9D1F6C32E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{BA8CA9A2-BAFF-42BB-8439-3DD9D1F6C32E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{BA8CA9A2-BAFF-42BB-8439-3DD9D1F6C32E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{BA8CA9A2-BAFF-42BB-8439-3DD9D1F6C32E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{29478B10-FC53-4E93-ADEF-A775D9408131}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{29478B10-FC53-4E93-ADEF-A775D9408131}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{29478B10-FC53-4E93-ADEF-A775D9408131}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{29478B10-FC53-4E93-ADEF-A775D9408131}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{29478B10-FC53-4E93-ADEF-A775D9408131}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{29478B10-FC53-4E93-ADEF-A775D9408131}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -176,7 +170,6 @@ Global
|
|||||||
{330D05CE-5321-4C7D-8017-2070B891289E} = {266B9B94-A4D2-41C2-860C-24A7C3B63B56}
|
{330D05CE-5321-4C7D-8017-2070B891289E} = {266B9B94-A4D2-41C2-860C-24A7C3B63B56}
|
||||||
{374AAE64-598B-4F67-8870-4A05168FF987} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
{374AAE64-598B-4F67-8870-4A05168FF987} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
||||||
{B3802005-C941-41B6-A9A5-20573A7C24AE} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
{B3802005-C941-41B6-A9A5-20573A7C24AE} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
||||||
{BA8CA9A2-BAFF-42BB-8439-3DD9D1F6C32E} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
|
||||||
{29478B10-FC53-4E93-ADEF-A775D9408131} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
{29478B10-FC53-4E93-ADEF-A775D9408131} = {99380F97-AD1A-459F-8AB3-D404E1E6AD4F}
|
||||||
{152227AA-3165-4550-8997-6EA80C84516E} = {266B9B94-A4D2-41C2-860C-24A7C3B63B56}
|
{152227AA-3165-4550-8997-6EA80C84516E} = {266B9B94-A4D2-41C2-860C-24A7C3B63B56}
|
||||||
{E69E6BA5-68E7-4A4D-A38C-B2526AA66E96} = {266B9B94-A4D2-41C2-860C-24A7C3B63B56}
|
{E69E6BA5-68E7-4A4D-A38C-B2526AA66E96} = {266B9B94-A4D2-41C2-860C-24A7C3B63B56}
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JSON/@EntryIndexedValue">JSON</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JSON/@EntryIndexedValue">JSON</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KV/@EntryIndexedValue">KV</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KV/@EntryIndexedValue">KV</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MQ/@EntryIndexedValue">MQ</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UTF/@EntryIndexedValue">UTF</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
namespace Tapeti.Config
|
namespace Tapeti.Config
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extends the message context with information about the controller.
|
/// Extends the message context with information about the controller.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Tapeti.Connection;
|
||||||
|
|
||||||
namespace Tapeti.Config
|
namespace Tapeti.Config
|
||||||
{
|
{
|
||||||
@ -82,7 +82,7 @@ namespace Tapeti.Config
|
|||||||
/// <param name="messageClass">The message class to be bound to the queue</param>
|
/// <param name="messageClass">The message class to be bound to the queue</param>
|
||||||
/// <param name="queueName">The name of the durable queue</param>
|
/// <param name="queueName">The name of the durable queue</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
ValueTask BindDurable(Type messageClass, string queueName, IReadOnlyDictionary<string, string> arguments);
|
ValueTask BindDurable(Type messageClass, string queueName, IRabbitMQArguments arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binds the messageClass to a dynamic auto-delete queue.
|
/// Binds the messageClass to a dynamic auto-delete queue.
|
||||||
@ -95,7 +95,7 @@ namespace Tapeti.Config
|
|||||||
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
/// <returns>The generated name of the dynamic queue</returns>
|
/// <returns>The generated name of the dynamic queue</returns>
|
||||||
ValueTask<string> BindDynamic(Type messageClass, string queuePrefix, IReadOnlyDictionary<string, string> arguments);
|
ValueTask<string> BindDynamic(Type messageClass, string queuePrefix, IRabbitMQArguments arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Declares a durable queue but does not add a binding for a messageClass' routing key.
|
/// Declares a durable queue but does not add a binding for a messageClass' routing key.
|
||||||
@ -103,7 +103,7 @@ namespace Tapeti.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="queueName">The name of the durable queue</param>
|
/// <param name="queueName">The name of the durable queue</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
ValueTask BindDurableDirect(string queueName, IReadOnlyDictionary<string, string> arguments);
|
ValueTask BindDurableDirect(string queueName, IRabbitMQArguments arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Declares a dynamic queue but does not add a binding for a messageClass' routing key.
|
/// Declares a dynamic queue but does not add a binding for a messageClass' routing key.
|
||||||
@ -113,7 +113,7 @@ namespace Tapeti.Config
|
|||||||
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
/// <returns>The generated name of the dynamic queue</returns>
|
/// <returns>The generated name of the dynamic queue</returns>
|
||||||
ValueTask<string> BindDynamicDirect(Type messageClass, string queuePrefix, IReadOnlyDictionary<string, string> arguments);
|
ValueTask<string> BindDynamicDirect(Type messageClass, string queuePrefix, IRabbitMQArguments arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Declares a dynamic queue but does not add a binding for a messageClass' routing key.
|
/// Declares a dynamic queue but does not add a binding for a messageClass' routing key.
|
||||||
@ -122,7 +122,7 @@ namespace Tapeti.Config
|
|||||||
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
/// <returns>The generated name of the dynamic queue</returns>
|
/// <returns>The generated name of the dynamic queue</returns>
|
||||||
ValueTask<string> BindDynamicDirect(string queuePrefix, IReadOnlyDictionary<string, string> arguments);
|
ValueTask<string> BindDynamicDirect(string queuePrefix, IRabbitMQArguments arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marks the specified durable queue as having an obsolete binding. If after all bindings have subscribed, the queue only contains obsolete
|
/// Marks the specified durable queue as having an obsolete binding. If after all bindings have subscribed, the queue only contains obsolete
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Config
|
namespace Tapeti.Config
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a Controller method is registered.
|
/// Called when a Controller method is registered.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3,7 +3,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Tapeti.Config
|
namespace Tapeti.Config
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Denotes middleware that runs before the controller is instantiated.
|
/// Denotes middleware that runs before the controller is instantiated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3,7 +3,6 @@ using System.Reflection;
|
|||||||
|
|
||||||
namespace Tapeti.Config
|
namespace Tapeti.Config
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a binding to a method in a controller class to handle incoming messages.
|
/// Represents a binding to a method in a controller class to handle incoming messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -77,7 +77,6 @@ namespace Tapeti.Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains a list of registered bindings, with a few added helpers.
|
/// Contains a list of registered bindings, with a few added helpers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Config
|
namespace Tapeti.Config
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides a way for Tapeti extensions to register custom bindings.
|
/// Provides a way for Tapeti extensions to register custom bindings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -6,7 +6,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Connection
|
namespace Tapeti.Connection
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="IEquatable{T}" />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines a queue binding to an exchange using a routing key
|
/// Defines a queue binding to an exchange using a routing key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -52,6 +51,18 @@ namespace Tapeti.Connection
|
|||||||
return ((Exchange != null ? Exchange.GetHashCode() : 0) * 397) ^ (RoutingKey != null ? RoutingKey.GetHashCode() : 0);
|
return ((Exchange != null ? Exchange.GetHashCode() : 0) * 397) ^ (RoutingKey != null ? RoutingKey.GetHashCode() : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary></summary>
|
||||||
|
public static bool operator ==(QueueBinding left, QueueBinding right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary></summary>
|
||||||
|
public static bool operator !=(QueueBinding left, QueueBinding right)
|
||||||
|
{
|
||||||
|
return !left.Equals(right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,7 +104,7 @@ namespace Tapeti.Connection
|
|||||||
/// <param name="bindings">A list of bindings. Any bindings already on the queue which are not in this list will be removed</param>
|
/// <param name="bindings">A list of bindings. Any bindings already on the queue which are not in this list will be removed</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
/// <param name="cancellationToken">Cancelled when the connection is lost</param>
|
/// <param name="cancellationToken">Cancelled when the connection is lost</param>
|
||||||
Task DurableQueueDeclare(string queueName, IEnumerable<QueueBinding> bindings, IReadOnlyDictionary<string, string> arguments, CancellationToken cancellationToken);
|
Task DurableQueueDeclare(string queueName, IEnumerable<QueueBinding> bindings, IRabbitMQArguments arguments, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verifies a durable queue exists. Will raise an exception if it does not.
|
/// Verifies a durable queue exists. Will raise an exception if it does not.
|
||||||
@ -101,7 +112,7 @@ namespace Tapeti.Connection
|
|||||||
/// <param name="queueName">The name of the queue to verify</param>
|
/// <param name="queueName">The name of the queue to verify</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
/// <param name="cancellationToken">Cancelled when the connection is lost</param>
|
/// <param name="cancellationToken">Cancelled when the connection is lost</param>
|
||||||
Task DurableQueueVerify(string queueName, IReadOnlyDictionary<string, string> arguments, CancellationToken cancellationToken);
|
Task DurableQueueVerify(string queueName, IRabbitMQArguments arguments, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a durable queue.
|
/// Deletes a durable queue.
|
||||||
@ -117,7 +128,7 @@ namespace Tapeti.Connection
|
|||||||
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
/// <param name="queuePrefix">An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue.</param>
|
||||||
/// <param name="arguments">Optional arguments</param>
|
/// <param name="arguments">Optional arguments</param>
|
||||||
/// <param name="cancellationToken">Cancelled when the connection is lost</param>
|
/// <param name="cancellationToken">Cancelled when the connection is lost</param>
|
||||||
Task<string> DynamicQueueDeclare(string queuePrefix, IReadOnlyDictionary<string, string> arguments, CancellationToken cancellationToken);
|
Task<string> DynamicQueueDeclare(string queuePrefix, IRabbitMQArguments arguments, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a binding to a dynamic queue.
|
/// Add a binding to a dynamic queue.
|
||||||
|
36
Tapeti/Connection/RabbitMQArguments.cs
Normal file
36
Tapeti/Connection/RabbitMQArguments.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Tapeti.Connection
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public interface IRabbitMQArguments : IReadOnlyDictionary<string, object>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class RabbitMQArguments : Dictionary<string, object>, IRabbitMQArguments
|
||||||
|
{
|
||||||
|
public RabbitMQArguments()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NETSTANDARD2_1_OR_GREATER
|
||||||
|
public RabbitMQArguments(IReadOnlyDictionary<string, object> values) : base(values)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
public RabbitMQArguments(IReadOnlyDictionary<string, object> values)
|
||||||
|
{
|
||||||
|
foreach (var pair in values)
|
||||||
|
Add(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public void AddUTF8(string key, string value)
|
||||||
|
{
|
||||||
|
Add(key, Encoding.UTF8.GetBytes(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,6 @@ namespace Tapeti.Connection
|
|||||||
public delegate Task ResponseFunc(long expectedConnectionReference, ulong deliveryTag, ConsumeResult result);
|
public delegate Task ResponseFunc(long expectedConnectionReference, ulong deliveryTag, ConsumeResult result);
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements the bridge between the RabbitMQ Client consumer and a Tapeti Consumer
|
/// Implements the bridge between the RabbitMQ Client consumer and a Tapeti Consumer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -7,6 +7,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
using RabbitMQ.Client.Events;
|
using RabbitMQ.Client.Events;
|
||||||
using RabbitMQ.Client.Exceptions;
|
using RabbitMQ.Client.Exceptions;
|
||||||
@ -24,7 +25,6 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of ITapetiClient for the RabbitMQ Client library
|
/// Implementation of ITapetiClient for the RabbitMQ Client library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -185,15 +185,18 @@ namespace Tapeti.Connection
|
|||||||
|
|
||||||
var replyCode = publishResultTask.Result;
|
var replyCode = publishResultTask.Result;
|
||||||
|
|
||||||
|
switch (replyCode)
|
||||||
|
{
|
||||||
// There is no RabbitMQ.Client.Framing.Constants value for this "No route" reply code
|
// There is no RabbitMQ.Client.Framing.Constants value for this "No route" reply code
|
||||||
// at the time of writing...
|
// at the time of writing...
|
||||||
if (replyCode == 312)
|
case 312:
|
||||||
throw new NoRouteException(
|
throw new NoRouteException(
|
||||||
$"Mandatory message with exchange '{exchange}' and routing key '{routingKey}' does not have a route");
|
$"Mandatory message with exchange '{exchange}' and routing key '{routingKey}' does not have a route");
|
||||||
|
|
||||||
if (replyCode > 0)
|
case > 0:
|
||||||
throw new NoRouteException(
|
throw new NoRouteException(
|
||||||
$"Mandatory message with exchange '{exchange}' and routing key '{routingKey}' could not be delivered, reply code: {replyCode}");
|
$"Mandatory message with exchange '{exchange}' and routing key '{routingKey}' could not be delivered, reply code: {replyCode}");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +289,7 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task<bool> GetDurableQueueDeclareRequired(string queueName, IReadOnlyDictionary<string, string> arguments)
|
private async Task<bool> GetDurableQueueDeclareRequired(string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
var existingQueue = await GetQueueInfo(queueName);
|
var existingQueue = await GetQueueInfo(queueName);
|
||||||
if (existingQueue == null)
|
if (existingQueue == null)
|
||||||
@ -298,17 +301,44 @@ namespace Tapeti.Connection
|
|||||||
if (arguments == null && existingQueue.Arguments.Count == 0)
|
if (arguments == null && existingQueue.Arguments.Count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (existingQueue.Arguments.NullSafeSameValues(arguments))
|
var existingArguments = ConvertJsonArguments(existingQueue.Arguments);
|
||||||
|
if (existingArguments.NullSafeSameValues(arguments))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
(logger as IBindingLogger)?.QueueExistsWarning(queueName, existingQueue.Arguments, arguments);
|
(logger as IBindingLogger)?.QueueExistsWarning(queueName, existingArguments, arguments);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static RabbitMQArguments ConvertJsonArguments(IReadOnlyDictionary<string, JObject> arguments)
|
||||||
|
{
|
||||||
|
if (arguments == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var result = new RabbitMQArguments();
|
||||||
|
foreach (var pair in arguments)
|
||||||
|
{
|
||||||
|
// ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault - by design
|
||||||
|
object value = pair.Value.Type switch
|
||||||
|
{
|
||||||
|
JTokenType.Integer => pair.Value.Value<int>(),
|
||||||
|
JTokenType.Float => pair.Value.Value<double>(),
|
||||||
|
JTokenType.String => Encoding.UTF8.GetBytes(pair.Value.Value<string>() ?? string.Empty),
|
||||||
|
JTokenType.Boolean => pair.Value.Value<bool>(),
|
||||||
|
JTokenType.Null => null,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(arguments))
|
||||||
|
};
|
||||||
|
|
||||||
|
result.Add(pair.Key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task DurableQueueDeclare(string queueName, IEnumerable<QueueBinding> bindings, IReadOnlyDictionary<string, string> arguments, CancellationToken cancellationToken)
|
public async Task DurableQueueDeclare(string queueName, IEnumerable<QueueBinding> bindings, IRabbitMQArguments arguments, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var declareRequired = await GetDurableQueueDeclareRequired(queueName, arguments);
|
var declareRequired = await GetDurableQueueDeclareRequired(queueName, arguments);
|
||||||
|
|
||||||
@ -343,17 +373,16 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static IDictionary<string, object> GetDeclareArguments(IReadOnlyDictionary<string, string> arguments)
|
private static IDictionary<string, object> GetDeclareArguments(IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
if (arguments == null || arguments.Count == 0)
|
return arguments == null || arguments.Count == 0
|
||||||
return null;
|
? null
|
||||||
|
: arguments.ToDictionary(p => p.Key, p => p.Value);
|
||||||
return arguments.ToDictionary(p => p.Key, p => (object)Encoding.UTF8.GetBytes(p.Value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task DurableQueueVerify(string queueName, IReadOnlyDictionary<string, string> arguments, CancellationToken cancellationToken)
|
public async Task DurableQueueVerify(string queueName, IRabbitMQArguments arguments, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (!await GetDurableQueueDeclareRequired(queueName, arguments))
|
if (!await GetDurableQueueDeclareRequired(queueName, arguments))
|
||||||
return;
|
return;
|
||||||
@ -455,7 +484,7 @@ namespace Tapeti.Connection
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<string> DynamicQueueDeclare(string queuePrefix, IReadOnlyDictionary<string, string> arguments, CancellationToken cancellationToken)
|
public async Task<string> DynamicQueueDeclare(string queuePrefix, IRabbitMQArguments arguments, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
string queueName = null;
|
string queueName = null;
|
||||||
var bindingLogger = logger as IBindingLogger;
|
var bindingLogger = logger as IBindingLogger;
|
||||||
@ -564,7 +593,7 @@ namespace Tapeti.Connection
|
|||||||
public bool Exclusive { get; set; }
|
public bool Exclusive { get; set; }
|
||||||
|
|
||||||
[JsonProperty("arguments")]
|
[JsonProperty("arguments")]
|
||||||
public Dictionary<string, string> Arguments { get; set; }
|
public Dictionary<string, JObject> Arguments { get; set; }
|
||||||
|
|
||||||
[JsonProperty("messages")]
|
[JsonProperty("messages")]
|
||||||
public uint Messages { get; set; }
|
public uint Messages { get; set; }
|
||||||
@ -675,7 +704,7 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
catch (WebException e)
|
catch (WebException e)
|
||||||
{
|
{
|
||||||
if (!(e.Response is HttpWebResponse response))
|
if (e.Response is not HttpWebResponse response)
|
||||||
throw;
|
throw;
|
||||||
|
|
||||||
if (!TransientStatusCodes.Contains(response.StatusCode))
|
if (!TransientStatusCodes.Contains(response.StatusCode))
|
||||||
|
@ -9,7 +9,6 @@ using Tapeti.Helpers;
|
|||||||
|
|
||||||
namespace Tapeti.Connection
|
namespace Tapeti.Connection
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a RabbitMQ consumer to pass messages to the Tapeti middleware.
|
/// Implements a RabbitMQ consumer to pass messages to the Tapeti middleware.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -172,8 +171,7 @@ namespace Tapeti.Connection
|
|||||||
return e switch
|
return e switch
|
||||||
{
|
{
|
||||||
AggregateException aggregateException => aggregateException.InnerExceptions.Any(IgnoreExceptionDuringShutdown),
|
AggregateException aggregateException => aggregateException.InnerExceptions.Any(IgnoreExceptionDuringShutdown),
|
||||||
TaskCanceledException _ => true,
|
OperationCanceledException => true,
|
||||||
OperationCanceledException _ => true,
|
|
||||||
_ => e.InnerException != null && IgnoreExceptionDuringShutdown(e.InnerException)
|
_ => e.InnerException != null && IgnoreExceptionDuringShutdown(e.InnerException)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -151,11 +151,11 @@ namespace Tapeti.Connection
|
|||||||
|
|
||||||
private class PublishContext : IPublishContext
|
private class PublishContext : IPublishContext
|
||||||
{
|
{
|
||||||
public ITapetiConfig Config { get; set; }
|
public ITapetiConfig Config { get; init; }
|
||||||
public string Exchange { get; set; }
|
public string Exchange { get; set; }
|
||||||
public string RoutingKey { get; set; }
|
public string RoutingKey { get; init; }
|
||||||
public object Message { get; set; }
|
public object Message { get; init; }
|
||||||
public IMessageProperties Properties { get; set; }
|
public IMessageProperties Properties { get; init; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,14 +72,12 @@ namespace Tapeti.Connection
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Reconnect()
|
public void Reconnect()
|
||||||
{
|
{
|
||||||
CancellationToken cancellationToken;
|
|
||||||
|
|
||||||
initializeCancellationTokenSource?.Cancel();
|
initializeCancellationTokenSource?.Cancel();
|
||||||
initializeCancellationTokenSource = new CancellationTokenSource();
|
initializeCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
consumerTags.Clear();
|
consumerTags.Clear();
|
||||||
|
|
||||||
cancellationToken = initializeCancellationTokenSource.Token;
|
var cancellationToken = initializeCancellationTokenSource.Token;
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@ -166,7 +164,7 @@ namespace Tapeti.Connection
|
|||||||
{
|
{
|
||||||
public string QueueName;
|
public string QueueName;
|
||||||
public List<Type> MessageClasses;
|
public List<Type> MessageClasses;
|
||||||
public IReadOnlyDictionary<string, string> Arguments;
|
public IRabbitMQArguments Arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<string, List<DynamicQueueInfo>> dynamicQueues = new();
|
private readonly Dictionary<string, List<DynamicQueueInfo>> dynamicQueues = new();
|
||||||
@ -187,12 +185,12 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract ValueTask BindDurable(Type messageClass, string queueName, IReadOnlyDictionary<string, string> arguments);
|
public abstract ValueTask BindDurable(Type messageClass, string queueName, IRabbitMQArguments arguments);
|
||||||
public abstract ValueTask BindDurableDirect(string queueName, IReadOnlyDictionary<string, string> arguments);
|
public abstract ValueTask BindDurableDirect(string queueName, IRabbitMQArguments arguments);
|
||||||
public abstract ValueTask BindDurableObsolete(string queueName);
|
public abstract ValueTask BindDurableObsolete(string queueName);
|
||||||
|
|
||||||
|
|
||||||
public async ValueTask<string> BindDynamic(Type messageClass, string queuePrefix, IReadOnlyDictionary<string, string> arguments)
|
public async ValueTask<string> BindDynamic(Type messageClass, string queuePrefix, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
var result = await DeclareDynamicQueue(messageClass, queuePrefix, arguments);
|
var result = await DeclareDynamicQueue(messageClass, queuePrefix, arguments);
|
||||||
if (!result.IsNewMessageClass)
|
if (!result.IsNewMessageClass)
|
||||||
@ -207,14 +205,14 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async ValueTask<string> BindDynamicDirect(Type messageClass, string queuePrefix, IReadOnlyDictionary<string, string> arguments)
|
public async ValueTask<string> BindDynamicDirect(Type messageClass, string queuePrefix, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
var result = await DeclareDynamicQueue(messageClass, queuePrefix, arguments);
|
var result = await DeclareDynamicQueue(messageClass, queuePrefix, arguments);
|
||||||
return result.QueueName;
|
return result.QueueName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async ValueTask<string> BindDynamicDirect(string queuePrefix, IReadOnlyDictionary<string, string> arguments)
|
public async ValueTask<string> BindDynamicDirect(string queuePrefix, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
// If we don't know the routing key, always create a new queue to ensure there is no overlap.
|
// If we don't know the routing key, always create a new queue to ensure there is no overlap.
|
||||||
// Keep it out of the dynamicQueues dictionary, so it can't be re-used later on either.
|
// Keep it out of the dynamicQueues dictionary, so it can't be re-used later on either.
|
||||||
@ -228,7 +226,7 @@ namespace Tapeti.Connection
|
|||||||
public bool IsNewMessageClass;
|
public bool IsNewMessageClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<DeclareDynamicQueueResult> DeclareDynamicQueue(Type messageClass, string queuePrefix, IReadOnlyDictionary<string, string> arguments)
|
private async Task<DeclareDynamicQueueResult> DeclareDynamicQueue(Type messageClass, string queuePrefix, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
// Group by prefix
|
// Group by prefix
|
||||||
var key = queuePrefix ?? "";
|
var key = queuePrefix ?? "";
|
||||||
@ -284,7 +282,7 @@ namespace Tapeti.Connection
|
|||||||
private struct DurableQueueInfo
|
private struct DurableQueueInfo
|
||||||
{
|
{
|
||||||
public List<Type> MessageClasses;
|
public List<Type> MessageClasses;
|
||||||
public IReadOnlyDictionary<string, string> Arguments;
|
public IRabbitMQArguments Arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -297,7 +295,7 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override ValueTask BindDurable(Type messageClass, string queueName, IReadOnlyDictionary<string, string> arguments)
|
public override ValueTask BindDurable(Type messageClass, string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
// Collect the message classes per queue so we can determine afterwards
|
// Collect the message classes per queue so we can determine afterwards
|
||||||
// if any of the bindings currently set on the durable queue are no
|
// if any of the bindings currently set on the durable queue are no
|
||||||
@ -326,7 +324,7 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override ValueTask BindDurableDirect(string queueName, IReadOnlyDictionary<string, string> arguments)
|
public override ValueTask BindDurableDirect(string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
if (!durableQueues.TryGetValue(queueName, out var durableQueueInfo))
|
if (!durableQueues.TryGetValue(queueName, out var durableQueueInfo))
|
||||||
{
|
{
|
||||||
@ -398,12 +396,12 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override async ValueTask BindDurable(Type messageClass, string queueName, IReadOnlyDictionary<string, string> arguments)
|
public override async ValueTask BindDurable(Type messageClass, string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
await VerifyDurableQueue(queueName, arguments);
|
await VerifyDurableQueue(queueName, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async ValueTask BindDurableDirect(string queueName, IReadOnlyDictionary<string, string> arguments)
|
public override async ValueTask BindDurableDirect(string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
await VerifyDurableQueue(queueName, arguments);
|
await VerifyDurableQueue(queueName, arguments);
|
||||||
}
|
}
|
||||||
@ -414,7 +412,7 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task VerifyDurableQueue(string queueName, IReadOnlyDictionary<string, string> arguments)
|
private async Task VerifyDurableQueue(string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
if (!durableQueues.Add(queueName))
|
if (!durableQueues.Add(queueName))
|
||||||
return;
|
return;
|
||||||
@ -431,12 +429,12 @@ namespace Tapeti.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override ValueTask BindDurable(Type messageClass, string queueName, IReadOnlyDictionary<string, string> arguments)
|
public override ValueTask BindDurable(Type messageClass, string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ValueTask BindDurableDirect(string queueName, IReadOnlyDictionary<string, string> arguments)
|
public override ValueTask BindDurableDirect(string queueName, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binds a parameter of type CancellationToken to a token which is cancelled when the RabbitMQ connection is closed.
|
/// Binds a parameter of type CancellationToken to a token which is cancelled when the RabbitMQ connection is closed.
|
||||||
/// Similar to and very much inspired by ASP.NET's RequestAborted CancellationToken.
|
/// Similar to and very much inspired by ASP.NET's RequestAborted CancellationToken.
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
using Tapeti.Connection;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global - public API
|
// ReSharper disable UnusedMember.Global - public API
|
||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default ILogger implementation for console applications.
|
/// Default ILogger implementation for console applications.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -81,13 +80,13 @@ namespace Tapeti.Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void QueueExistsWarning(string queueName, IReadOnlyDictionary<string, string> existingArguments, IReadOnlyDictionary<string, string> arguments)
|
public void QueueExistsWarning(string queueName, IRabbitMQArguments existingArguments, IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"[Tapeti] Durable queue {queueName} exists with incompatible x-arguments ({GetArgumentsText(existingArguments)} vs. {GetArgumentsText(arguments)}) and will not be redeclared, queue will be consumed as-is");
|
Console.WriteLine($"[Tapeti] Durable queue {queueName} exists with incompatible x-arguments ({GetArgumentsText(existingArguments)} vs. {GetArgumentsText(arguments)}) and will not be redeclared, queue will be consumed as-is");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static string GetArgumentsText(IReadOnlyDictionary<string, string> arguments)
|
private static string GetArgumentsText(IRabbitMQArguments arguments)
|
||||||
{
|
{
|
||||||
var argumentsText = new StringBuilder();
|
var argumentsText = new StringBuilder();
|
||||||
foreach (var pair in arguments)
|
foreach (var pair in arguments)
|
||||||
|
@ -99,7 +99,6 @@ namespace Tapeti.Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation for IBindingParameter
|
/// Default implementation for IBindingParameter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -139,7 +138,6 @@ namespace Tapeti.Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation for IBindingResult
|
/// Default implementation for IBindingResult
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4,11 +4,11 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
using Tapeti.Connection;
|
||||||
using Tapeti.Helpers;
|
using Tapeti.Helpers;
|
||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binding implementation for controller methods. Do not instantiate this class yourself,
|
/// Binding implementation for controller methods. Do not instantiate this class yourself,
|
||||||
/// instead use the ITapetiConfigBuilder RegisterController / RegisterAllControllers extension
|
/// instead use the ITapetiConfigBuilder RegisterController / RegisterAllControllers extension
|
||||||
@ -319,7 +319,7 @@ namespace Tapeti.Default
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Optional arguments (x-arguments) passed when declaring the queue.
|
/// Optional arguments (x-arguments) passed when declaring the queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyDictionary<string, string> QueueArguments { get; set; }
|
public IRabbitMQArguments QueueArguments { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if the QueueInfo properties contain a valid combination.
|
/// Determines if the QueueInfo properties contain a valid combination.
|
||||||
|
@ -4,7 +4,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to resolve any unhandled parameters to Controller methods using the IoC container.
|
/// Attempts to resolve any unhandled parameters to Controller methods using the IoC container.
|
||||||
/// This middleware is included by default in the standard TapetiConfig.
|
/// This middleware is included by default in the standard TapetiConfig.
|
||||||
|
@ -3,7 +3,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default ILogger implementation which does not log anything.
|
/// Default ILogger implementation which does not log anything.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4,7 +4,6 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an <see cref="T:System.Enum" /> to and from its name string value. If an unknown string value is encountered
|
/// Converts an <see cref="T:System.Enum" /> to and from its name string value. If an unknown string value is encountered
|
||||||
/// it will translate to 0xDEADBEEF (-559038737) so it can be gracefully handled.
|
/// it will translate to 0xDEADBEEF (-559038737) so it can be gracefully handled.
|
||||||
|
@ -6,7 +6,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IMessageSerializer implementation for JSON encoding and decoding using Newtonsoft.Json.
|
/// IMessageSerializer implementation for JSON encoding and decoding using Newtonsoft.Json.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -49,7 +48,7 @@ namespace Tapeti.Default
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object Deserialize(byte[] body, IMessageProperties properties)
|
public object Deserialize(byte[] body, IMessageProperties properties)
|
||||||
{
|
{
|
||||||
if (!(properties.ContentType is ContentType))
|
if (properties.ContentType is not ContentType)
|
||||||
throw new ArgumentException($"content_type must be {ContentType}");
|
throw new ArgumentException($"content_type must be {ContentType}");
|
||||||
|
|
||||||
var typeName = properties.GetHeader(ClassTypeHeader);
|
var typeName = properties.GetHeader(ClassTypeHeader);
|
||||||
|
@ -3,7 +3,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the message class from the first parameter of a controller method.
|
/// Gets the message class from the first parameter of a controller method.
|
||||||
/// This middleware is included by default in the standard TapetiConfig.
|
/// This middleware is included by default in the standard TapetiConfig.
|
||||||
|
@ -4,7 +4,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IMessagePropertiesReader implementation for providing properties manually
|
/// IMessagePropertiesReader implementation for providing properties manually
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3,7 +3,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation of an exception strategy which marks the messages as Error.
|
/// Default implementation of an exception strategy which marks the messages as Error.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3,7 +3,6 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IExchangeStrategy implementation which uses the first identifier in the namespace in lower case,
|
/// IExchangeStrategy implementation which uses the first identifier in the namespace in lower case,
|
||||||
/// skipping the first identifier if it is 'Messaging'.
|
/// skipping the first identifier if it is 'Messaging'.
|
||||||
|
@ -8,7 +8,6 @@ using Tapeti.Helpers;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to publish a return value for Controller methods as a response to the incoming message.
|
/// Attempts to publish a return value for Controller methods as a response to the incoming message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -5,7 +5,6 @@ using Tapeti.Config;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Example exception strategy which requeues all messages that result in an error.
|
/// Example exception strategy which requeues all messages that result in an error.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -7,7 +7,6 @@ using Tapeti.Helpers;
|
|||||||
|
|
||||||
namespace Tapeti.Default
|
namespace Tapeti.Default
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IRoutingKeyStrategy implementation which transforms the class name into a dot-separated routing key based
|
/// IRoutingKeyStrategy implementation which transforms the class name into a dot-separated routing key based
|
||||||
/// on the casing. Accounts for acronyms. If the class name ends with 'Message' it is not included in the routing key.
|
/// on the casing. Accounts for acronyms. If the class name ends with 'Message' it is not included in the routing key.
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Exceptions
|
namespace Tapeti.Exceptions
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when a message is nacked by the message bus.
|
/// Raised when a message is nacked by the message bus.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Tapeti.Exceptions
|
namespace Tapeti.Exceptions
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when a mandatory message has no route.
|
/// Raised when a mandatory message has no route.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -10,7 +10,7 @@ namespace Tapeti.Helpers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if two dictionaries are considered compatible. If either is null they are considered empty.
|
/// Checks if two dictionaries are considered compatible. If either is null they are considered empty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool NullSafeSameValues(this IReadOnlyDictionary<string, string> arguments1, IReadOnlyDictionary<string, string> arguments2)
|
public static bool NullSafeSameValues(this IReadOnlyDictionary<string, object> arguments1, IReadOnlyDictionary<string, object> arguments2)
|
||||||
{
|
{
|
||||||
if (arguments1 == null || arguments2 == null)
|
if (arguments1 == null || arguments2 == null)
|
||||||
return (arguments1 == null || arguments1.Count == 0) && (arguments2 == null || arguments2.Count == 0);
|
return (arguments1 == null || arguments1.Count == 0) && (arguments2 == null || arguments2.Count == 0);
|
||||||
|
@ -23,7 +23,6 @@ namespace Tapeti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows registering controller classes into the IoC container. Also registers default implementations,
|
/// Allows registering controller classes into the IoC container. Also registers default implementations,
|
||||||
/// so that the calling application may override these.
|
/// so that the calling application may override these.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
using Tapeti.Connection;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedMemberInSuper.Global
|
// ReSharper disable UnusedMemberInSuper.Global
|
||||||
@ -24,7 +24,6 @@ namespace Tapeti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information about the failed connection.
|
/// Contains information about the failed connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -37,7 +36,6 @@ namespace Tapeti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information about the established connection.
|
/// Contains information about the established connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -140,7 +138,7 @@ namespace Tapeti
|
|||||||
/// <param name="queueName">The name of the queue that is declared</param>
|
/// <param name="queueName">The name of the queue that is declared</param>
|
||||||
/// <param name="existingArguments">The x-arguments of the existing queue</param>
|
/// <param name="existingArguments">The x-arguments of the existing queue</param>
|
||||||
/// <param name="arguments">The x-arguments of the queue that would be declared</param>
|
/// <param name="arguments">The x-arguments of the queue that would be declared</param>
|
||||||
void QueueExistsWarning(string queueName, IReadOnlyDictionary<string, string> existingArguments, IReadOnlyDictionary<string, string> arguments);
|
void QueueExistsWarning(string queueName, IRabbitMQArguments existingArguments, IRabbitMQArguments arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called before a binding is added to a queue.
|
/// Called before a binding is added to a queue.
|
||||||
|
@ -54,7 +54,6 @@ namespace Tapeti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Low-level publisher for Tapeti internal use.
|
/// Low-level publisher for Tapeti internal use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.*" />
|
||||||
<PackageReference Include="RabbitMQ.Client" Version="6.4.0" />
|
<PackageReference Include="RabbitMQ.Client" Version="6.*" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
using System.Configuration;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
|
||||||
|
|
||||||
namespace Tapeti
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation of TapetiConnectionParams which reads the values from the AppSettings.
|
|
||||||
/// </summary>
|
|
||||||
/// <list type="table">
|
|
||||||
/// <listheader>
|
|
||||||
/// <description>AppSettings keys</description>
|
|
||||||
/// </listheader>
|
|
||||||
/// <item><description>rabbitmq:hostname</description></item>
|
|
||||||
/// <item><description>rabbitmq:port</description></item>
|
|
||||||
/// <item><description>rabbitmq:virtualhost</description></item>
|
|
||||||
/// <item><description>rabbitmq:username</description></item>
|
|
||||||
/// <item><description>rabbitmq:password</description></item>
|
|
||||||
/// <item><description>rabbitmq:prefetchcount</description></item>
|
|
||||||
/// <item><description>rabbitmq:managementport</description></item>
|
|
||||||
/// <item><description>rabbitmq:clientproperty:*</description></item>
|
|
||||||
/// </list>
|
|
||||||
public class TapetiAppSettingsConnectionParams : TapetiConnectionParams
|
|
||||||
{
|
|
||||||
private const string DefaultPrefix = "rabbitmq:";
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
private const string KeyHostname = "hostname";
|
|
||||||
private const string KeyPort = "port";
|
|
||||||
private const string KeyVirtualHost = "virtualhost";
|
|
||||||
private const string KeyUsername = "username";
|
|
||||||
private const string KeyPassword = "password";
|
|
||||||
private const string KeyPrefetchCount = "prefetchcount";
|
|
||||||
private const string KeyManagementPort = "managementport";
|
|
||||||
private const string KeyClientProperty = "clientproperty:";
|
|
||||||
// ReSharper restore InconsistentNaming
|
|
||||||
|
|
||||||
|
|
||||||
private readonly struct AppSettingsKey
|
|
||||||
{
|
|
||||||
public readonly string Entry;
|
|
||||||
public readonly string Parameter;
|
|
||||||
|
|
||||||
public AppSettingsKey(string entry, string parameter)
|
|
||||||
{
|
|
||||||
Entry = entry;
|
|
||||||
Parameter = parameter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary></summary>
|
|
||||||
/// <param name="prefix">The prefix to apply to the keys. Defaults to "rabbitmq:"</param>
|
|
||||||
public TapetiAppSettingsConnectionParams(string prefix = DefaultPrefix)
|
|
||||||
{
|
|
||||||
var keys = !string.IsNullOrEmpty(prefix)
|
|
||||||
? ConfigurationManager.AppSettings.AllKeys.Where(k => k.StartsWith(prefix)).Select(k => new AppSettingsKey(k, k.Substring(prefix.Length)))
|
|
||||||
: ConfigurationManager.AppSettings.AllKeys.Select(k => new AppSettingsKey(k, k));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var key in keys)
|
|
||||||
{
|
|
||||||
var value = ConfigurationManager.AppSettings[key.Entry];
|
|
||||||
|
|
||||||
if (key.Parameter.StartsWith(KeyClientProperty))
|
|
||||||
{
|
|
||||||
ClientProperties.Add(key.Parameter.Substring(KeyClientProperty.Length), value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// ReSharper disable once SwitchStatementMissingSomeCases - don't fail if we encounter an unknown value
|
|
||||||
switch (key.Parameter)
|
|
||||||
{
|
|
||||||
case KeyHostname: HostName = value; break;
|
|
||||||
case KeyPort: Port = int.Parse(value); break;
|
|
||||||
case KeyVirtualHost: VirtualHost = value; break;
|
|
||||||
case KeyUsername: Username = value; break;
|
|
||||||
case KeyPassword: Password = value; break;
|
|
||||||
case KeyPrefetchCount: PrefetchCount = ushort.Parse(value); break;
|
|
||||||
case KeyManagementPort: ManagementPort = int.Parse(value); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -189,7 +189,7 @@ namespace Tapeti
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected void RegisterDefaults()
|
protected void RegisterDefaults()
|
||||||
{
|
{
|
||||||
if (!(DependencyResolver is IDependencyContainer container))
|
if (DependencyResolver is not IDependencyContainer container)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ConsoleHelper.IsAvailable())
|
if (ConsoleHelper.IsAvailable())
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Tapeti.Annotations;
|
using Tapeti.Annotations;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
using Tapeti.Connection;
|
||||||
using Tapeti.Default;
|
using Tapeti.Default;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
namespace Tapeti
|
namespace Tapeti
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when an issue is detected in a controller configuration.
|
/// Thrown when an issue is detected in a controller configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -171,40 +170,34 @@ namespace Tapeti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static IReadOnlyDictionary<string, string> GetQueueArguments(QueueArgumentsAttribute queueArgumentsAttribute)
|
private static IRabbitMQArguments GetQueueArguments(QueueArgumentsAttribute queueArgumentsAttribute)
|
||||||
{
|
{
|
||||||
if (queueArgumentsAttribute == null)
|
if (queueArgumentsAttribute == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
#if NETSTANDARD2_1_OR_GREATER
|
var arguments = new RabbitMQArguments(queueArgumentsAttribute.CustomArguments);
|
||||||
var arguments = new Dictionary<string, string>(queueArgumentsAttribute.CustomArguments);
|
|
||||||
#else
|
|
||||||
var arguments = new Dictionary<string, string>();
|
|
||||||
foreach (var pair in queueArgumentsAttribute.CustomArguments)
|
|
||||||
arguments.Add(pair.Key, pair.Value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (queueArgumentsAttribute.MaxLength > 0)
|
if (queueArgumentsAttribute.MaxLength > 0)
|
||||||
arguments.Add(@"x-max-length", queueArgumentsAttribute.MaxLength.ToString());
|
arguments.Add(@"x-max-length", queueArgumentsAttribute.MaxLength);
|
||||||
|
|
||||||
if (queueArgumentsAttribute.MaxLengthBytes > 0)
|
if (queueArgumentsAttribute.MaxLengthBytes > 0)
|
||||||
arguments.Add(@"x-max-length-bytes", queueArgumentsAttribute.MaxLengthBytes.ToString());
|
arguments.Add(@"x-max-length-bytes", queueArgumentsAttribute.MaxLengthBytes);
|
||||||
|
|
||||||
if (queueArgumentsAttribute.MessageTTL > 0)
|
if (queueArgumentsAttribute.MessageTTL > 0)
|
||||||
arguments.Add(@"x-message-ttl", queueArgumentsAttribute.MessageTTL.ToString());
|
arguments.Add(@"x-message-ttl", queueArgumentsAttribute.MessageTTL);
|
||||||
|
|
||||||
switch (queueArgumentsAttribute.Overflow)
|
switch (queueArgumentsAttribute.Overflow)
|
||||||
{
|
{
|
||||||
case RabbitMQOverflow.NotSpecified:
|
case RabbitMQOverflow.NotSpecified:
|
||||||
break;
|
break;
|
||||||
case RabbitMQOverflow.DropHead:
|
case RabbitMQOverflow.DropHead:
|
||||||
arguments.Add(@"x-overflow", @"drop-head");
|
arguments.AddUTF8(@"x-overflow", @"drop-head");
|
||||||
break;
|
break;
|
||||||
case RabbitMQOverflow.RejectPublish:
|
case RabbitMQOverflow.RejectPublish:
|
||||||
arguments.Add(@"x-overflow", @"reject-publish");
|
arguments.AddUTF8(@"x-overflow", @"reject-publish");
|
||||||
break;
|
break;
|
||||||
case RabbitMQOverflow.RejectPublishDeadletter:
|
case RabbitMQOverflow.RejectPublishDeadletter:
|
||||||
arguments.Add(@"x-overflow", @"reject-publish-dlx");
|
arguments.AddUTF8(@"x-overflow", @"reject-publish-dlx");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(queueArgumentsAttribute.Overflow), queueArgumentsAttribute.Overflow, "Unsupported Overflow value");
|
throw new ArgumentOutOfRangeException(nameof(queueArgumentsAttribute.Overflow), queueArgumentsAttribute.Overflow, "Unsupported Overflow value");
|
||||||
|
@ -9,7 +9,6 @@ using Tapeti.Connection;
|
|||||||
|
|
||||||
namespace Tapeti
|
namespace Tapeti
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a connection to RabbitMQ based on the provided Tapeti config.
|
/// Creates a connection to RabbitMQ based on the provided Tapeti config.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Tapeti.Tasks
|
namespace Tapeti.Tasks
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An implementation of a queue which runs tasks on a single thread.
|
/// An implementation of a queue which runs tasks on a single thread.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user