1
0
mirror of synced 2024-11-25 04:03:09 +01:00

Merge branch 'release/2.4' into develop

This commit is contained in:
Mark van Renswoude 2021-05-29 21:55:08 +02:00
commit b925991429
68 changed files with 322 additions and 108 deletions

View File

@ -7,11 +7,11 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="4.9.4" /> <PackageReference Include="Autofac" Version="6.2.0" />
<PackageReference Include="Castle.Windsor" Version="5.0.0" /> <PackageReference Include="Castle.Windsor" Version="5.1.1" />
<PackageReference Include="Ninject" Version="3.3.4" /> <PackageReference Include="Ninject" Version="3.3.4" />
<PackageReference Include="SimpleInjector" Version="4.6.2" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
<PackageReference Include="Unity" Version="5.11.1" /> <PackageReference Include="Unity" Version="5.11.10" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -17,6 +17,8 @@ using Tapeti.UnityContainer;
using Unity; using Unity;
using Container = SimpleInjector.Container; using Container = SimpleInjector.Container;
// ReSharper disable UnusedMember.Global
namespace _01_PublishSubscribe namespace _01_PublishSubscribe
{ {
public class Program public class Program

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.6.2" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.6.2" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.6.2" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.6.2" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.9.0" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -23,11 +23,12 @@ namespace ExampleLib
{ {
private readonly IDependencyContainer dependencyResolver; private readonly IDependencyContainer dependencyResolver;
private readonly int expectedDoneCount; private readonly int expectedDoneCount;
private int doneCount = 0; private int doneCount;
private readonly TaskCompletionSource<bool> doneSignal = new TaskCompletionSource<bool>(); private readonly TaskCompletionSource<bool> doneSignal = new TaskCompletionSource<bool>();
/// <param name="dependencyResolver">Uses Tapeti's IDependencyContainer interface so you can easily switch an example to your favourite IoC container</param> /// <param name="dependencyResolver">Uses Tapeti's IDependencyContainer interface so you can easily switch an example to your favourite IoC container</param>
/// <param name="expectedDoneCount"></param>
public ExampleConsoleApp(IDependencyContainer dependencyResolver, int expectedDoneCount = 1) public ExampleConsoleApp(IDependencyContainer dependencyResolver, int expectedDoneCount = 1)
{ {
this.dependencyResolver = dependencyResolver; this.dependencyResolver = dependencyResolver;

View File

@ -5,7 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,4 @@
using System.ComponentModel.DataAnnotations; namespace Messaging.TapetiExample
namespace Messaging.TapetiExample
{ {
public class SpeedTestMessage public class SpeedTestMessage
{ {

View File

@ -33,7 +33,8 @@ namespace Tapeti.Autofac
} }
/// <inheritdoc /> /// <summary>
/// </summary>
public AutofacDependencyResolver(ContainerBuilder containerBuilder) public AutofacDependencyResolver(ContainerBuilder containerBuilder)
{ {
this.containerBuilder = containerBuilder; this.containerBuilder = containerBuilder;

View File

@ -14,7 +14,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="4.9.4" /> <PackageReference Include="Autofac" Version="6.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -14,7 +14,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Castle.Windsor" Version="5.0.0" /> <PackageReference Include="Castle.Windsor" Version="5.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -13,7 +13,8 @@ namespace Tapeti.CastleWindsor
private readonly IWindsorContainer container; private readonly IWindsorContainer container;
/// <inheritdoc /> /// <summary>
/// </summary>
public WindsorDependencyResolver(IWindsorContainer container) public WindsorDependencyResolver(IWindsorContainer container)
{ {
this.container = container; this.container = container;
@ -51,7 +52,7 @@ namespace Tapeti.CastleWindsor
container.Register( container.Register(
Component Component
.For<TService>() .For<TService>()
.UsingFactoryMethod(() => factory()) .UsingFactoryMethod(factory)
); );
} }
@ -83,7 +84,7 @@ namespace Tapeti.CastleWindsor
container.Register( container.Register(
Component Component
.For<TService>() .For<TService>()
.UsingFactoryMethod(() => factory()) .UsingFactoryMethod(factory)
.LifestyleSingleton() .LifestyleSingleton()
); );
} }

View File

@ -33,7 +33,7 @@ namespace Tapeti.Cmd.Commands
RoutingKey = result.RoutingKey, RoutingKey = result.RoutingKey,
Queue = QueueName, Queue = QueueName,
Properties = result.BasicProperties, Properties = result.BasicProperties,
Body = result.Body Body = result.Body.ToArray()
}); });
if (RemoveMessages) if (RemoveMessages)

View File

@ -15,7 +15,7 @@ namespace Tapeti.Cmd.Commands
{ {
var messageCount = 0; var messageCount = 0;
foreach (var message in MessageSerializer.Deserialize()) foreach (var message in MessageSerializer.Deserialize(channel))
{ {
rateLimiter.Execute(() => rateLimiter.Execute(() =>
{ {

View File

@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using RabbitMQ.Client;
namespace Tapeti.Cmd.Mock
{
public class MockBasicProperties : IBasicProperties
{
public ushort ProtocolClassId { get; set; }
public string ProtocolClassName { get; set; }
public void ClearAppId()
{
throw new NotImplementedException();
}
public void ClearClusterId()
{
throw new NotImplementedException();
}
public void ClearContentEncoding()
{
throw new NotImplementedException();
}
public void ClearContentType()
{
throw new NotImplementedException();
}
public void ClearCorrelationId()
{
throw new NotImplementedException();
}
public void ClearDeliveryMode()
{
throw new NotImplementedException();
}
public void ClearExpiration()
{
throw new NotImplementedException();
}
public void ClearHeaders()
{
throw new NotImplementedException();
}
public void ClearMessageId()
{
throw new NotImplementedException();
}
public void ClearPriority()
{
throw new NotImplementedException();
}
public void ClearReplyTo()
{
throw new NotImplementedException();
}
public void ClearTimestamp()
{
throw new NotImplementedException();
}
public void ClearType()
{
throw new NotImplementedException();
}
public void ClearUserId()
{
throw new NotImplementedException();
}
public bool IsAppIdPresent()
{
throw new NotImplementedException();
}
public bool IsClusterIdPresent()
{
throw new NotImplementedException();
}
public bool IsContentEncodingPresent()
{
throw new NotImplementedException();
}
public bool IsContentTypePresent()
{
throw new NotImplementedException();
}
public bool IsCorrelationIdPresent()
{
throw new NotImplementedException();
}
public bool IsDeliveryModePresent()
{
throw new NotImplementedException();
}
public bool IsExpirationPresent()
{
throw new NotImplementedException();
}
public bool IsHeadersPresent()
{
throw new NotImplementedException();
}
public bool IsMessageIdPresent()
{
throw new NotImplementedException();
}
public bool IsPriorityPresent()
{
throw new NotImplementedException();
}
public bool IsReplyToPresent()
{
throw new NotImplementedException();
}
public bool IsTimestampPresent()
{
throw new NotImplementedException();
}
public bool IsTypePresent()
{
throw new NotImplementedException();
}
public bool IsUserIdPresent()
{
throw new NotImplementedException();
}
public string AppId { get; set; }
public string ClusterId { get; set; }
public string ContentEncoding { get; set; }
public string ContentType { get; set; }
public string CorrelationId { get; set; }
public byte DeliveryMode { get; set; }
public string Expiration { get; set; }
public IDictionary<string, object> Headers { get; set; }
public string MessageId { get; set; }
public bool Persistent { get; set; }
public byte Priority { get; set; }
public string ReplyTo { get; set; }
public PublicationAddress ReplyToAddress { get; set; }
public AmqpTimestamp Timestamp { get; set; }
public string Type { get; set; }
public string UserId { get; set; }
}
}

View File

@ -5,8 +5,8 @@ using System.IO;
using System.Text; using System.Text;
using CommandLine; using CommandLine;
using RabbitMQ.Client; using RabbitMQ.Client;
using RabbitMQ.Client.Framing;
using Tapeti.Cmd.Commands; using Tapeti.Cmd.Commands;
using Tapeti.Cmd.Mock;
using Tapeti.Cmd.RateLimiter; using Tapeti.Cmd.RateLimiter;
using Tapeti.Cmd.Serialization; using Tapeti.Cmd.Serialization;
@ -256,7 +256,7 @@ namespace Tapeti.Cmd
private static IRateLimiter GetRateLimiter(int? maxRate) private static IRateLimiter GetRateLimiter(int? maxRate)
{ {
if (maxRate.GetValueOrDefault() <= 0) if (!maxRate.HasValue || maxRate.Value <= 0)
return new NoRateLimiter(); return new NoRateLimiter();
return new SpreadRateLimiter(maxRate.Value, TimeSpan.FromSeconds(1)); return new SpreadRateLimiter(maxRate.Value, TimeSpan.FromSeconds(1));
@ -376,7 +376,7 @@ namespace Tapeti.Cmd
Port = options.TargetPort ?? options.Port, Port = options.TargetPort ?? options.Port,
VirtualHost = !string.IsNullOrEmpty(options.TargetVirtualHost) ? options.TargetVirtualHost : options.VirtualHost, VirtualHost = !string.IsNullOrEmpty(options.TargetVirtualHost) ? options.TargetVirtualHost : options.VirtualHost,
UserName = !string.IsNullOrEmpty(options.TargetUsername) ? options.TargetUsername : options.Username, UserName = !string.IsNullOrEmpty(options.TargetUsername) ? options.TargetUsername : options.Username,
Password = !string.IsNullOrEmpty(options.TargetPassword) ? options.TargetPassword : options.Password, Password = !string.IsNullOrEmpty(options.TargetPassword) ? options.TargetPassword : options.Password
}; };
return factory.CreateConnection(); return factory.CreateConnection();
@ -417,7 +417,7 @@ namespace Tapeti.Cmd
Queue = "example.queue", Queue = "example.queue",
RoutingKey = "example.routing.key", RoutingKey = "example.routing.key",
DeliveryTag = 42, DeliveryTag = 42,
Properties = new BasicProperties Properties = new MockBasicProperties
{ {
ContentType = "application/json", ContentType = "application/json",
DeliveryMode = 2, DeliveryMode = 2,

View File

@ -6,7 +6,6 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Newtonsoft.Json; using Newtonsoft.Json;
using RabbitMQ.Client; using RabbitMQ.Client;
using RabbitMQ.Client.Framing;
namespace Tapeti.Cmd.Serialization namespace Tapeti.Cmd.Serialization
{ {
@ -61,7 +60,7 @@ namespace Tapeti.Cmd.Serialization
} }
public IEnumerable<Message> Deserialize() public IEnumerable<Message> Deserialize(IModel channel)
{ {
foreach (var file in Directory.GetFiles(path, "*.*.message.txt")) foreach (var file in Directory.GetFiles(path, "*.*.message.txt"))
{ {
@ -80,8 +79,13 @@ namespace Tapeti.Cmd.Serialization
var infoJson = File.ReadAllText(infoFileName); var infoJson = File.ReadAllText(infoFileName);
var info = JsonConvert.DeserializeObject<EasyNetQMessageReceivedInfo>(infoJson); var info = JsonConvert.DeserializeObject<EasyNetQMessageReceivedInfo>(infoJson);
if (info == null)
continue;
var message = info.ToMessage(); var message = info.ToMessage();
message.Properties = properties.ToBasicProperties(); if (properties != null)
message.Properties = properties.ToBasicProperties(channel);
message.Body = Encoding.UTF8.GetBytes(body); message.Body = Encoding.UTF8.GetBytes(body);
yield return message; yield return message;
@ -117,13 +121,13 @@ namespace Tapeti.Cmd.Serialization
if (!basicProperties.IsHeadersPresent()) if (!basicProperties.IsHeadersPresent())
return; return;
foreach (var header in basicProperties.Headers) foreach (var (key, value) in basicProperties.Headers)
Headers.Add(header.Key, (byte[])header.Value); Headers.Add(key, (byte[])value);
} }
public IBasicProperties ToBasicProperties() public IBasicProperties ToBasicProperties(IModel channel)
{ {
var basicProperties = new BasicProperties(); var basicProperties = channel.CreateBasicProperties();
if (ContentTypePresent) basicProperties.ContentType = ContentType; if (ContentTypePresent) basicProperties.ContentType = ContentType;
if (ContentEncodingPresent) basicProperties.ContentEncoding = ContentEncoding; if (ContentEncodingPresent) basicProperties.ContentEncoding = ContentEncoding;
@ -169,6 +173,7 @@ namespace Tapeti.Cmd.Serialization
public IDictionary<string, byte[]> Headers public IDictionary<string, byte[]> Headers
{ {
get => headers; get => headers;
// ReSharper disable once UnusedMember.Local
set { headers = value; HeadersPresent = true; } set { headers = value; HeadersPresent = true; }
} }
@ -268,6 +273,7 @@ namespace Tapeti.Cmd.Serialization
private class EasyNetQMessageReceivedInfo private class EasyNetQMessageReceivedInfo
{ {
// ReSharper disable once UnusedAutoPropertyAccessor.Local - used by JSON deserialization
public string ConsumerTag { get; set; } public string ConsumerTag { get; set; }
public ulong DeliverTag { get; set; } public ulong DeliverTag { get; set; }
public bool Redelivered { get; set; } public bool Redelivered { get; set; }

View File

@ -19,6 +19,6 @@ namespace Tapeti.Cmd.Serialization
public interface IMessageSerializer : IDisposable public interface IMessageSerializer : IDisposable
{ {
void Serialize(Message message); void Serialize(Message message);
IEnumerable<Message> Deserialize(); IEnumerable<Message> Deserialize(IModel channel);
} }
} }

View File

@ -5,7 +5,6 @@ using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using RabbitMQ.Client; using RabbitMQ.Client;
using RabbitMQ.Client.Framing;
namespace Tapeti.Cmd.Serialization namespace Tapeti.Cmd.Serialization
{ {
@ -42,7 +41,7 @@ namespace Tapeti.Cmd.Serialization
} }
public IEnumerable<Message> Deserialize() public IEnumerable<Message> Deserialize(IModel channel)
{ {
using (var reader = new StreamReader(stream, encoding)) using (var reader = new StreamReader(stream, encoding))
{ {
@ -56,7 +55,7 @@ namespace Tapeti.Cmd.Serialization
if (serializableMessage == null) if (serializableMessage == null)
continue; continue;
yield return serializableMessage.ToMessage(); yield return serializableMessage.ToMessage(channel);
} }
} }
} }
@ -134,7 +133,7 @@ namespace Tapeti.Cmd.Serialization
} }
public Message ToMessage() public Message ToMessage(IModel channel)
{ {
return new Message return new Message
{ {
@ -143,7 +142,7 @@ namespace Tapeti.Cmd.Serialization
Exchange = Exchange, Exchange = Exchange,
RoutingKey = RoutingKey, RoutingKey = RoutingKey,
Queue = Queue, Queue = Queue,
Properties = Properties.ToBasicProperties(), Properties = Properties.ToBasicProperties(channel),
Body = Body != null Body = Body != null
? Encoding.UTF8.GetBytes(Body.ToString(Formatting.None)) ? Encoding.UTF8.GetBytes(Body.ToString(Formatting.None))
: RawBody : RawBody
@ -198,17 +197,17 @@ namespace Tapeti.Cmd.Serialization
Headers = new Dictionary<string, string>(); Headers = new Dictionary<string, string>();
// This assumes header values are UTF-8 encoded strings. This is true for Tapeti. // This assumes header values are UTF-8 encoded strings. This is true for Tapeti.
foreach (var pair in fromProperties.Headers) foreach (var (key, value) in fromProperties.Headers)
Headers.Add(pair.Key, Encoding.UTF8.GetString((byte[])pair.Value)); Headers.Add(key, Encoding.UTF8.GetString((byte[])value));
} }
else else
Headers = null; Headers = null;
} }
public IBasicProperties ToBasicProperties() public IBasicProperties ToBasicProperties(IModel channel)
{ {
var properties = new BasicProperties(); var properties = channel.CreateBasicProperties();
if (!string.IsNullOrEmpty(AppId)) properties.AppId = AppId; if (!string.IsNullOrEmpty(AppId)) properties.AppId = AppId;
if (!string.IsNullOrEmpty(ClusterId)) properties.ClusterId = ClusterId; if (!string.IsNullOrEmpty(ClusterId)) properties.ClusterId = ClusterId;
@ -228,8 +227,8 @@ namespace Tapeti.Cmd.Serialization
{ {
properties.Headers = new Dictionary<string, object>(); properties.Headers = new Dictionary<string, object>();
foreach (var pair in Headers) foreach (var (key, value) in Headers)
properties.Headers.Add(pair.Key, Encoding.UTF8.GetBytes(pair.Value)); properties.Headers.Add(key, Encoding.UTF8.GetBytes(value));
} }
return properties; return properties;

View File

@ -15,9 +15,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.7.82" /> <PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="RabbitMQ.Client" Version="5.1.2" /> <PackageReference Include="RabbitMQ.Client" Version="6.2.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -18,7 +18,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -18,7 +18,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -27,7 +27,8 @@ namespace Tapeti.Flow.SQL
private readonly string tableName; private readonly string tableName;
/// <inheritdoc /> /// <summary>
/// </summary>
public SqlConnectionFlowRepository(string connectionString, string tableName = "Flow") public SqlConnectionFlowRepository(string connectionString, string tableName = "Flow")
{ {
this.connectionString = connectionString; this.connectionString = connectionString;

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Text; using System.Linq;
// ReSharper disable UnusedMember.Global
namespace Tapeti.Flow.SQL namespace Tapeti.Flow.SQL
{ {
@ -24,16 +26,8 @@ namespace Tapeti.Flow.SQL
case Exception exception: case Exception exception:
{ {
var sqlExceptions = ExtractSqlExceptions(e); var sqlExceptions = ExtractSqlExceptions(exception);
foreach (var sqlException in sqlExceptions) return sqlExceptions.Select(UnwrapSqlErrors).Any(IsRecoverableSQLError);
{
var sqlErrors = UnwrapSqlErrors(sqlException);
if (IsRecoverableSQLError(sqlErrors))
return true;
}
return false;
} }
default: default:

View File

@ -26,7 +26,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Data.SqlClient" Version="4.6.1" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -63,7 +63,7 @@ namespace Tapeti.Flow.Default
// Do not call when the controller method was filtered, if the same message has two methods // Do not call when the controller method was filtered, if the same message has two methods
return; return;
if (flowContext?.FlowStateLock != null) if (flowContext.FlowStateLock != null)
{ {
if (!flowContext.IsStoredOrDeleted()) if (!flowContext.IsStoredOrDeleted())
// The exception strategy can set the consume result to Success. Instead, check if the yield point // The exception strategy can set the consume result to Success. Instead, check if the yield point

View File

@ -9,13 +9,15 @@ namespace Tapeti.Flow.Default
/// </summary> /// </summary>
internal class FlowHandlerContext : IFlowHandlerContext internal class FlowHandlerContext : IFlowHandlerContext
{ {
/// <inheritdoc /> /// <summary>
/// </summary>
public FlowHandlerContext() public FlowHandlerContext()
{ {
} }
/// <inheritdoc /> /// <summary>
/// </summary>
public FlowHandlerContext(IControllerMessageContext source) public FlowHandlerContext(IControllerMessageContext source)
{ {
if (source == null) if (source == null)

View File

@ -22,7 +22,8 @@ namespace Tapeti.Flow.Default
private readonly IInternalPublisher publisher; private readonly IInternalPublisher publisher;
/// <inheritdoc /> /// <summary>
/// </summary>
public FlowProvider(ITapetiConfig config, IPublisher publisher) public FlowProvider(ITapetiConfig config, IPublisher publisher)
{ {
this.config = config; this.config = config;

View File

@ -15,7 +15,8 @@ namespace Tapeti.Flow.Default
private readonly ITapetiConfig config; private readonly ITapetiConfig config;
/// <inheritdoc /> /// <summary>
/// </summary>
public FlowStarter(ITapetiConfig config) public FlowStarter(ITapetiConfig config)
{ {
this.config = config; this.config = config;

View File

@ -35,7 +35,8 @@ namespace Tapeti.Flow.Default
private volatile bool loaded; private volatile bool loaded;
/// <inheritdoc /> /// <summary>
/// </summary>
public FlowStore(IFlowRepository repository) public FlowStore(IFlowRepository repository)
{ {
this.repository = repository; this.repository = repository;

View File

@ -12,7 +12,8 @@ namespace Tapeti.Flow
{ {
private readonly IFlowRepository flowRepository; private readonly IFlowRepository flowRepository;
/// <inheritdoc /> /// <summary>
/// </summary>
public FlowExtension(IFlowRepository flowRepository) public FlowExtension(IFlowRepository flowRepository)
{ {
this.flowRepository = flowRepository; this.flowRepository = flowRepository;

View File

@ -11,7 +11,8 @@ namespace Tapeti.Flow.FlowHelpers
{ {
private readonly Dictionary<T, LockItem> locks; private readonly Dictionary<T, LockItem> locks;
/// <inheritdoc /> /// <summary>
/// </summary>
public LockCollection(IEqualityComparer<T> comparer) public LockCollection(IEqualityComparer<T> comparer)
{ {
locks = new Dictionary<T, LockItem>(comparer); locks = new Dictionary<T, LockItem>(comparer);

View File

@ -13,7 +13,8 @@ namespace Tapeti.Ninject
private readonly IKernel kernel; private readonly IKernel kernel;
/// <inheritdoc /> /// <summary>
/// </summary>
public NinjectDependencyResolver(IKernel kernel) public NinjectDependencyResolver(IKernel kernel)
{ {
this.kernel = kernel; this.kernel = kernel;

View File

@ -18,7 +18,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog" Version="2.9.0" /> <PackageReference Include="Serilog" Version="2.10.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -14,7 +14,8 @@ namespace Tapeti.SimpleInjector
private readonly Lifestyle defaultsLifestyle; private readonly Lifestyle defaultsLifestyle;
private readonly Lifestyle controllersLifestyle; private readonly Lifestyle controllersLifestyle;
/// <inheritdoc /> /// <summary>
/// </summary>
public SimpleInjectorDependencyResolver(Container container, Lifestyle defaultsLifestyle = null, Lifestyle controllersLifestyle = null) public SimpleInjectorDependencyResolver(Container container, Lifestyle defaultsLifestyle = null, Lifestyle controllersLifestyle = null)
{ {
this.container = container; this.container = container;

View File

@ -19,7 +19,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.6.2" /> <PackageReference Include="SimpleInjector" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -60,7 +60,8 @@ namespace Tapeti.Tests.Default
AssertRoutingKey("acr.test.mixed.case", typeof(ACRTestMIXEDCaseMESSAGE)); AssertRoutingKey("acr.test.mixed.case", typeof(ACRTestMIXEDCaseMESSAGE));
} }
private void AssertRoutingKey(string expected, Type messageType) // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
private static void AssertRoutingKey(string expected, Type messageType)
{ {
if (expected == null) throw new ArgumentNullException(nameof(expected)); if (expected == null) throw new ArgumentNullException(nameof(expected));
if (messageType == null) throw new ArgumentNullException(nameof(messageType)); if (messageType == null) throw new ArgumentNullException(nameof(messageType));

View File

@ -9,9 +9,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>

View File

@ -11,7 +11,8 @@ namespace Tapeti.Transient
private readonly TransientRouter router; private readonly TransientRouter router;
/// <inheritdoc /> /// <summary>
/// </summary>
public TransientExtension(TimeSpan defaultTimeout, string dynamicQueuePrefix) public TransientExtension(TimeSpan defaultTimeout, string dynamicQueuePrefix)
{ {
this.dynamicQueuePrefix = dynamicQueuePrefix; this.dynamicQueuePrefix = dynamicQueuePrefix;

View File

@ -21,7 +21,8 @@ namespace Tapeti.Transient
public QueueType QueueType => QueueType.Dynamic; public QueueType QueueType => QueueType.Dynamic;
/// <inheritdoc /> /// <summary>
/// </summary>
public TransientGenericBinding(TransientRouter router, string dynamicQueuePrefix) public TransientGenericBinding(TransientRouter router, string dynamicQueuePrefix)
{ {
this.router = router; this.router = router;

View File

@ -12,7 +12,8 @@ namespace Tapeti.Transient
private readonly IPublisher publisher; private readonly IPublisher publisher;
/// <inheritdoc /> /// <summary>
/// </summary>
public TransientPublisher(TransientRouter router, IPublisher publisher) public TransientPublisher(TransientRouter router, IPublisher publisher)
{ {
this.router = router; this.router = router;

View File

@ -21,7 +21,8 @@ namespace Tapeti.Transient
public string TransientResponseQueueName { get; set; } public string TransientResponseQueueName { get; set; }
/// <inheritdoc /> /// <summary>
/// </summary>
public TransientRouter(TimeSpan defaultTimeout) public TransientRouter(TimeSpan defaultTimeout)
{ {
defaultTimeoutMs = (int)defaultTimeout.TotalMilliseconds; defaultTimeoutMs = (int)defaultTimeout.TotalMilliseconds;

View File

@ -14,7 +14,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Unity" Version="5.11.1" /> <PackageReference Include="Unity" Version="5.11.10" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -13,7 +13,8 @@ namespace Tapeti.UnityContainer
private readonly IUnityContainer container; private readonly IUnityContainer container;
/// <inheritdoc /> /// <summary>
/// </summary>
public UnityDependencyResolver(IUnityContainer container) public UnityDependencyResolver(IUnityContainer container)
{ {
this.container = container; this.container = container;

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Tapeti.Config namespace Tapeti.Config

View File

@ -1,6 +1,7 @@
using System; using System;
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
// ReSharper disable UnusedMemberInSuper.Global
namespace Tapeti.Config namespace Tapeti.Config
{ {

View File

@ -1,4 +1,5 @@
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
// ReSharper disable UnusedMemberInSuper.Global
namespace Tapeti.Config namespace Tapeti.Config
{ {

View File

@ -10,7 +10,7 @@ namespace Tapeti.Connection
/// <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>
public struct QueueBinding : IEquatable<QueueBinding> public readonly struct QueueBinding : IEquatable<QueueBinding>
{ {
/// <summary></summary> /// <summary></summary>
public readonly string Exchange; public readonly string Exchange;

View File

@ -24,13 +24,19 @@ namespace Tapeti.Connection
/// <inheritdoc /> /// <inheritdoc />
public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body) public override void HandleBasicDeliver(string consumerTag,
ulong deliveryTag,
bool redelivered,
string exchange,
string routingKey,
IBasicProperties properties,
ReadOnlyMemory<byte> body)
{ {
Task.Run(async () => Task.Run(async () =>
{ {
try try
{ {
var response = await consumer.Consume(exchange, routingKey, new RabbitMQMessageProperties(properties), body); var response = await consumer.Consume(exchange, routingKey, new RabbitMQMessageProperties(properties), body.ToArray());
await onRespond(deliveryTag, response); await onRespond(deliveryTag, response);
} }
catch catch

View File

@ -351,7 +351,7 @@ namespace Tapeti.Connection
} }
catch (OperationInterruptedException e) catch (OperationInterruptedException e)
{ {
if (e.ShutdownReason.ReplyCode == RabbitMQ.Client.Framing.Constants.PreconditionFailed) if (e.ShutdownReason.ReplyCode == Constants.PreconditionFailed)
retry = true; retry = true;
else else
throw; throw;
@ -519,9 +519,10 @@ namespace Tapeti.Connection
var bindings = JsonConvert.DeserializeObject<IEnumerable<ManagementBinding>>(content); var bindings = JsonConvert.DeserializeObject<IEnumerable<ManagementBinding>>(content);
// Filter out the binding to an empty source, which is always present for direct-to-queue routing // Filter out the binding to an empty source, which is always present for direct-to-queue routing
return bindings return bindings?
.Where(binding => !string.IsNullOrEmpty(binding.Source)) .Where(binding => !string.IsNullOrEmpty(binding.Source))
.Select(binding => new QueueBinding(binding.Source, binding.RoutingKey)); .Select(binding => new QueueBinding(binding.Source, binding.RoutingKey))
?? Enumerable.Empty<QueueBinding>();
}); });
} }
@ -655,7 +656,7 @@ namespace Tapeti.Connection
Password = connectionParams.Password, Password = connectionParams.Password,
AutomaticRecoveryEnabled = false, AutomaticRecoveryEnabled = false,
TopologyRecoveryEnabled = false, TopologyRecoveryEnabled = false,
RequestedHeartbeat = 30 RequestedHeartbeat = TimeSpan.FromSeconds(30)
}; };
if (connectionParams.ClientProperties != null) if (connectionParams.ClientProperties != null)

View File

@ -18,7 +18,6 @@ namespace Tapeti.Connection
private CancellationTokenSource initializeCancellationTokenSource; private CancellationTokenSource initializeCancellationTokenSource;
/// <inheritdoc />
public TapetiSubscriber(Func<ITapetiClient> clientFactory, ITapetiConfig config) public TapetiSubscriber(Func<ITapetiClient> clientFactory, ITapetiConfig config)
{ {
this.clientFactory = clientFactory; this.clientFactory = clientFactory;

View File

@ -118,7 +118,10 @@ namespace Tapeti.Default
public bool HasBinding => Binding != null; public bool HasBinding => Binding != null;
/// <inheritdoc /> /// <summary>
/// Creates a new default implementation for IBindingParameter
/// </summary>
/// <param name="info"></param>
public ControllerBindingParameter(ParameterInfo info) public ControllerBindingParameter(ParameterInfo info)
{ {
Info = info; Info = info;
@ -155,6 +158,10 @@ namespace Tapeti.Default
public bool HasHandler => Handler != null; public bool HasHandler => Handler != null;
/// <summary>
/// Creates a new default implementation for IBindingResult
/// </summary>
/// <param name="info"></param>
public ControllerBindingResult(ParameterInfo info) public ControllerBindingResult(ParameterInfo info)
{ {
Info = info; Info = info;

View File

@ -32,7 +32,6 @@ namespace Tapeti.Default
IControllerMethodBinding IControllerMessageContext.Binding => decoratedContext.Binding as IControllerMethodBinding; IControllerMethodBinding IControllerMessageContext.Binding => decoratedContext.Binding as IControllerMethodBinding;
/// <inheritdoc />
public ControllerMessageContext(IMessageContext decoratedContext) public ControllerMessageContext(IMessageContext decoratedContext)
{ {
this.decoratedContext = decoratedContext; this.decoratedContext = decoratedContext;

View File

@ -18,7 +18,6 @@ namespace Tapeti.Default
public Exception Exception { get; } public Exception Exception { get; }
/// <inheritdoc />
public ExceptionStrategyContext(IMessageContext messageContext, Exception exception) public ExceptionStrategyContext(IMessageContext messageContext, Exception exception)
{ {
MessageContext = messageContext; MessageContext = messageContext;

View File

@ -60,7 +60,7 @@ namespace Tapeti.Default
if (reader.TokenType != JsonToken.String) if (reader.TokenType != JsonToken.String)
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing enum"); throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing enum");
var enumText = reader.Value.ToString(); var enumText = reader.Value?.ToString() ?? "";
if (enumText == string.Empty && isNullable) if (enumText == string.Empty && isNullable)
return null; return null;

View File

@ -21,7 +21,8 @@ namespace Tapeti.Default
private readonly JsonSerializerSettings serializerSettings; private readonly JsonSerializerSettings serializerSettings;
/// <inheritdoc /> /// <summary>
/// </summary>
public JsonMessageSerializer() public JsonMessageSerializer()
{ {
serializerSettings = new JsonSerializerSettings serializerSettings = new JsonSerializerSettings

View File

@ -29,13 +29,15 @@ namespace Tapeti.Default
public DateTime? Timestamp { get; set; } public DateTime? Timestamp { get; set; }
/// <inheritdoc /> /// <summary>
/// </summary>
public MessageProperties() public MessageProperties()
{ {
} }
/// <inheritdoc /> /// <summary>
/// </summary>
public MessageProperties(IMessageProperties source) public MessageProperties(IMessageProperties source)
{ {
if (source == null) if (source == null)

View File

@ -30,6 +30,7 @@ namespace Tapeti.Default
// Verify the return type matches with the Request attribute of the message class. This is a backwards incompatible change in // Verify the return type matches with the Request attribute of the message class. This is a backwards incompatible change in
// Tapeti 1.2: if you just want to publish another message as a result of the incoming message, explicitly call IPublisher.Publish. // Tapeti 1.2: if you just want to publish another message as a result of the incoming message, explicitly call IPublisher.Publish.
// ReSharper disable once ConvertIfStatementToSwitchStatement
if (!hasClassResult && expectedClassResult != null || hasClassResult && expectedClassResult != actualType) if (!hasClassResult && expectedClassResult != null || hasClassResult && expectedClassResult != actualType)
throw new ArgumentException($"Message handler must return type {expectedClassResult?.FullName ?? "void"} in controller {context.Method.DeclaringType?.FullName}, method {context.Method.Name}, found: {actualType?.FullName ?? "void"}"); throw new ArgumentException($"Message handler must return type {expectedClassResult?.FullName ?? "void"} in controller {context.Method.DeclaringType?.FullName}, method {context.Method.Name}, found: {actualType?.FullName ?? "void"}");

View File

@ -56,14 +56,16 @@ namespace Tapeti.Default
} }
/// <inheritdoc /> /// <summary>
/// </summary>
public RabbitMQMessageProperties(IBasicProperties basicProperties) public RabbitMQMessageProperties(IBasicProperties basicProperties)
{ {
BasicProperties = basicProperties; BasicProperties = basicProperties;
} }
/// <inheritdoc /> /// <summary>
/// </summary>
public RabbitMQMessageProperties(IBasicProperties basicProperties, IMessageProperties source) public RabbitMQMessageProperties(IBasicProperties basicProperties, IMessageProperties source)
{ {
BasicProperties = basicProperties; BasicProperties = basicProperties;

View File

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
// ReSharper disable UnusedMemberInSuper.Global
namespace Tapeti namespace Tapeti
{ {

View File

@ -2,6 +2,7 @@
using Tapeti.Config; using Tapeti.Config;
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
// ReSharper disable UnusedMemberInSuper.Global
namespace Tapeti namespace Tapeti
{ {

View File

@ -3,7 +3,7 @@ using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Tapeti.Config; using Tapeti.Config;
// ReSharper disable once UnusedMember.Global // ReSharper disable UnusedMember.Global
namespace Tapeti namespace Tapeti
{ {

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
// ReSharper disable UnusedMember.Global
namespace Tapeti namespace Tapeti
{ {
/// <inheritdoc /> /// <inheritdoc />

View File

@ -18,9 +18,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="RabbitMQ.Client" Version="5.1.0" /> <PackageReference Include="RabbitMQ.Client" Version="6.2.1" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,8 @@
using System.Configuration; using System.Configuration;
using System.Linq; using System.Linq;
// ReSharper disable UnusedMember.Global
namespace Tapeti namespace Tapeti
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -23,6 +25,7 @@ namespace Tapeti
public class TapetiAppSettingsConnectionParams : TapetiConnectionParams public class TapetiAppSettingsConnectionParams : TapetiConnectionParams
{ {
private const string DefaultPrefix = "rabbitmq:"; private const string DefaultPrefix = "rabbitmq:";
// ReSharper disable InconsistentNaming
private const string KeyHostname = "hostname"; private const string KeyHostname = "hostname";
private const string KeyPort = "port"; private const string KeyPort = "port";
private const string KeyVirtualHost = "virtualhost"; private const string KeyVirtualHost = "virtualhost";
@ -31,9 +34,10 @@ namespace Tapeti
private const string KeyPrefetchCount = "prefetchcount"; private const string KeyPrefetchCount = "prefetchcount";
private const string KeyManagementPort = "managementport"; private const string KeyManagementPort = "managementport";
private const string KeyClientProperty = "clientproperty:"; private const string KeyClientProperty = "clientproperty:";
// ReSharper restore InconsistentNaming
private struct AppSettingsKey private readonly struct AppSettingsKey
{ {
public readonly string Entry; public readonly string Entry;
public readonly string Parameter; public readonly string Parameter;

View File

@ -65,7 +65,8 @@ namespace Tapeti
} }
/// <inheritdoc /> /// <summary>
/// </summary>
public TapetiConnectionParams() public TapetiConnectionParams()
{ {
} }