Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass logger factory #58

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/ArtemisNetCoreClient/ArtemisNetCoreClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@
</AssemblyAttribute>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
</ItemGroup>

</Project>
13 changes: 7 additions & 6 deletions src/ArtemisNetCoreClient/Session.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using ActiveMQ.Artemis.Core.Client.Framing;
using Microsoft.Extensions.Logging;

namespace ActiveMQ.Artemis.Core.Client;

Expand All @@ -10,9 +11,10 @@ internal class Session : ISession
private readonly ConcurrentDictionary<long, TaskCompletionSource<Packet>> _completionSources = new();
private readonly ConcurrentDictionary<long, Consumer> _consumers = new();

public Session(Transport transport)
public Session(Transport transport, ILoggerFactory loggerFactory)
{
_transport = transport;
var logger = loggerFactory.CreateLogger<Session>();

// TODO: Clean up while loop on close
_ = Task.Run(async () =>
Expand Down Expand Up @@ -40,12 +42,14 @@ public Session(Transport transport)
}
catch (Exception e)
{
logger.LogError(e, "Error in packet processing or network communication");
// TODO: Handle exception
Console.WriteLine(e);
}
}
});
}

public long ChannelId { get; init; }

public async Task CreateAddress(string address, IEnumerable<RoutingType> routingTypes, CancellationToken cancellationToken)
{
Expand All @@ -65,8 +69,7 @@ public async Task CreateAddress(string address, IEnumerable<RoutingType> routing
{
Address = address
};
var response =
await SendBlockingAsync<SessionBindingQueryMessage, SessionBindingQueryResponseMessageV5>(request, cancellationToken);
var response = await SendBlockingAsync<SessionBindingQueryMessage, SessionBindingQueryResponseMessageV5>(request, cancellationToken);

if (response.Exists)
{
Expand Down Expand Up @@ -196,8 +199,6 @@ internal async Task SendAsync<TRequest>(TRequest request, CancellationToken canc
await _transport.SendAsync(request, ChannelId, cancellationToken);
}

public long ChannelId { get; init; }

public async Task StartAsync(CancellationToken cancellationToken)
{
await _transport.SendAsync(new SessionStart(), ChannelId, cancellationToken);
Expand Down
6 changes: 5 additions & 1 deletion src/ArtemisNetCoreClient/SessionFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Net;
using System.Net.Sockets;
using ActiveMQ.Artemis.Core.Client.Framing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

namespace ActiveMQ.Artemis.Core.Client;

Expand Down Expand Up @@ -68,7 +70,7 @@ public async Task<ISession> CreateAsync(Endpoint endpoint, CancellationToken can

if (receivedPacket is CreateSessionResponseMessage)
{
var session = new Session(transport)
var session = new Session(transport, LoggerFactory)
{
ChannelId = createSessionMessageV2.SessionChannelId
};
Expand All @@ -80,4 +82,6 @@ public async Task<ISession> CreateAsync(Endpoint endpoint, CancellationToken can
throw new InvalidOperationException("Received invalid response from the broker");
}
}

public ILoggerFactory LoggerFactory { get; set; } = new NullLoggerFactory();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace ActiveMQ.Artemis.Core.Client.Tests;

public class ByteBufferTests
public class ByteBufferSpec
{
[Fact]
public void should_encode_byte()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
using ActiveMQ.Artemis.Core.Client.Framing;
using ActiveMQ.Artemis.Core.Client.Tests.Utils;
using Xunit;
using Xunit.Abstractions;

namespace ActiveMQ.Artemis.Core.Client.Tests;

public class ConsumerTests
public class ConsumerSpec(ITestOutputHelper testOutputHelper)
{
[Fact]
public async Task should_receive_message()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();
var addressName = Guid.NewGuid().ToString();
await session.CreateAddress(addressName, new[] { RoutingType.Anycast }, testFixture.CancellationToken);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
using ActiveMQ.Artemis.Core.Client.Framing;
using ActiveMQ.Artemis.Core.Client.Tests.Utils;
using Xunit;
using Xunit.Abstractions;

namespace ActiveMQ.Artemis.Core.Client.Tests;

public class ProducerTests
public class ProducerSpec(ITestOutputHelper testOutputHelper)
{
[Fact]
public async Task should_send_message()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();
var addressName = Guid.NewGuid().ToString();
await session.CreateAddress(addressName, new [] { RoutingType.Multicast }, testFixture.CancellationToken);
await using var producer = await session.CreateProducerAsync(new ProducerConfiguration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
using ActiveMQ.Artemis.Core.Client.Framing;
using ActiveMQ.Artemis.Core.Client.Tests.Utils;
using Xunit;
using Xunit.Abstractions;

namespace ActiveMQ.Artemis.Core.Client.Tests;

public class SessionTests
public class SessionSpec(ITestOutputHelper testOutputHelper)
{
[Fact]
public async Task should_establish_session()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

// Act
var connectionFactory = new SessionFactory();
var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
var session = await connectionFactory.CreateAsync(TestFixture.GetEndpoint(), testFixture.CancellationToken);

// Assert
Assert.NotNull(session);
Expand All @@ -27,10 +29,9 @@ public async Task should_establish_session()
public async Task should_create_address_with_selected_routing_type(RoutingType[] routingTypes)
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();

// Act
var addressName = $"{Guid.NewGuid().ToString()}-{string.Join("-", routingTypes)}";
Expand All @@ -49,10 +50,9 @@ public async Task should_create_address_with_selected_routing_type(RoutingType[]
public async Task should_create_queue_with_selected_routing_type(RoutingType routingType)
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();
var addressName = Guid.NewGuid().ToString();
await session.CreateAddress(addressName, [routingType], testFixture.CancellationToken);

Expand All @@ -77,10 +77,9 @@ await session.CreateQueue(new QueueConfiguration
public async Task should_not_return_address_info_when_address_does_not_exist()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();

// Act
var addressName = Guid.NewGuid().ToString();
Expand All @@ -94,10 +93,9 @@ public async Task should_not_return_address_info_when_address_does_not_exist()
public async Task should_not_return_queue_info_when_queue_does_not_exist()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();

// Act
var queueName = Guid.NewGuid().ToString();
Expand All @@ -111,10 +109,9 @@ public async Task should_not_return_queue_info_when_queue_does_not_exist()
public async Task should_create_and_dispose_consumer()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();

var addressName = Guid.NewGuid().ToString();
await session.CreateAddress(addressName, new [] { RoutingType.Multicast }, testFixture.CancellationToken);
Expand All @@ -140,10 +137,9 @@ await session.CreateQueue(new QueueConfiguration
public async Task should_create_and_dispose_producer()
{
// Arrange
await using var testFixture = await TestFixture.CreateAsync();
await using var testFixture = await TestFixture.CreateAsync(testOutputHelper);

var connectionFactory = new SessionFactory();
await using var session = await connectionFactory.CreateAsync(testFixture.GetEndpoint(), testFixture.CancellationToken);
await using var session = await testFixture.CreateSessionAsync();
var addressName = Guid.NewGuid().ToString();
await session.CreateAddress(addressName, new [] { RoutingType.Multicast }, testFixture.CancellationToken);

Expand Down
69 changes: 69 additions & 0 deletions test/ArtemisNetCoreClient.Tests/Utils/Logging/XUnitLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;

namespace ActiveMQ.Artemis.Core.Client.Tests.Utils.Logging;

public sealed class XUnitLogger(ITestOutputHelper output, string name) : ILogger
{
private static readonly string LoglevelPadding = ": ";
private static readonly string MessagePadding;

static XUnitLogger()
{
var logLevelString = GetLogLevelString(LogLevel.Information);
MessagePadding = new string(' ', logLevelString.Length + LoglevelPadding.Length);
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}

var message = formatter(state, exception);

if (!string.IsNullOrEmpty(message) || exception != null)
{
WriteMessage(logLevel, name, message, exception);
}
}

public bool IsEnabled(LogLevel logLevel)
{
return logLevel != LogLevel.None;
}

IDisposable ILogger.BeginScope<TState>(TState state)
{
throw new NotSupportedException();
}

private void WriteMessage(LogLevel logLevel, string logName, string message, Exception? exception)
{
var logLevelString = GetLogLevelString(logLevel);

output.WriteLine($"{logLevelString}: {logName}");

if (!string.IsNullOrEmpty(message))
{
output.WriteLine($"{MessagePadding}{message}");
}

if (exception != null)
{
output.WriteLine(exception.ToString());
}
}

private static string GetLogLevelString(LogLevel logLevel) => logLevel switch
{
LogLevel.Trace => "trce",
LogLevel.Debug => "dbug",
LogLevel.Information => "info",
LogLevel.Warning => "warn",
LogLevel.Error => "fail",
LogLevel.Critical => "crit",
_ => throw new ArgumentOutOfRangeException(nameof(logLevel))
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;

namespace ActiveMQ.Artemis.Core.Client.Tests.Utils.Logging;

public sealed class XUnitLoggerFactory : ILoggerFactory
{
private readonly ITestOutputHelper _output;

public XUnitLoggerFactory(ITestOutputHelper output)
{
_output = output;
}

public ILogger CreateLogger(string categoryName)
{
return new XUnitLogger(_output, categoryName);
}

void IDisposable.Dispose()
{
}

void ILoggerFactory.AddProvider(ILoggerProvider provider)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;

namespace ActiveMQ.Artemis.Core.Client.Tests.Utils.Logging;

public class XUnitLoggerProvider : ILoggerProvider
{
private readonly ITestOutputHelper _testOutputHelper;

public XUnitLoggerProvider(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}

public ILogger CreateLogger(string categoryName)
{
return new XUnitLogger(_testOutputHelper, categoryName);
}

public void Dispose()
{
}
}
Loading
Loading