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

E2E Test Coverage Part 2 & Add .NET 9.0 Support #218

Merged
merged 22 commits into from
Jan 20, 2025
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
56 changes: 35 additions & 21 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@ on:
workflow_dispatch:

env:
# Disable the .NET logo in the console output.
DOTNET_NOLOGO: true
# Disable the .NET first time experience to skip caching NuGet packages and speed up the build.
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
# Disable sending .NET CLI telemetry to Microsoft.
DOTNET_CLI_TELEMETRY_OPTOUT: true
# Set the build number in MinVer.
MINVERBUILDMETADATA: build.${{github.run_number}}
MINVERBUILDMETADATA: build.${{ github.run_number }}

jobs:
build:
name: pipeline-${{matrix.os}}-dotnet-${{matrix.dotnet-version}}
runs-on: ${{matrix.os}}
name: pipeline-${{ matrix.os }}-dotnet-${{ matrix.dotnet-version }}
runs-on: ${{ matrix.os }}

services:
hivemq:
Expand All @@ -41,33 +37,43 @@ jobs:

strategy:
matrix:
# Docker containers not supported on windows and macOS in Github runners.
# os: [ubuntu-latest, windows-latest, macOS-latest]
os: [ubuntu-latest]
dotnet-version: ['6.0.x', '7.0.x', '8.0.x']
dotnet-version: ['6.0.x', '7.0.x', '8.0.x', '9.0.x']
steps:
- name: "Checkout"
- name: Checkout
uses: actions/[email protected]
with:
lfs: true
fetch-depth: 0
- name: "Install .NET Core SDK"

- name: Install .NET Core SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: '${{ matrix.dotnet-version }}'
- name: "Dotnet Tool Restore"

- name: List Installed SDKs
run: dotnet --list-sdks

- name: Create temporary global.json
run: echo '{"sdk":{"version":"${{ matrix.dotnet-version }}"}}' > global.json

- name: Dotnet Tool Restore
run: dotnet tool restore
shell: pwsh
- name: "Dotnet Cake Build"

- name: Dotnet Cake Build
run: dotnet cake --target=Build
shell: pwsh
- name: "Dotnet Cake Test"
run: dotnet cake --target=Test

- name: Dotnet Cake Test
run: dotnet cake --target=Test --framework net${{ matrix.dotnet-version }}
shell: pwsh
- name: "Dotnet Cake Pack"

- name: Dotnet Cake Pack
run: dotnet cake --target=Pack
shell: pwsh
- name: "Upload NuGet packages"

- name: Upload NuGet packages
uses: actions/upload-artifact@v4
with:
name: nuget-packages-${{ matrix.dotnet-version }}
Expand All @@ -77,22 +83,30 @@ jobs:
needs: build
runs-on: ubuntu-latest
steps:
- name: "Download NuGet packages"
- name: Download NuGet packages for .NET 6.0
uses: actions/download-artifact@v4
with:
name: nuget-packages-6.0.x
path: ./Artifacts
- name: "Download NuGet packages"

- name: Download NuGet packages for .NET 7.0
uses: actions/download-artifact@v4
with:
name: nuget-packages-7.0.x
path: ./Artifacts
- name: "Download NuGet packages"

- name: Download NuGet packages for .NET 8.0
uses: actions/download-artifact@v4
with:
name: nuget-packages-8.0.x
path: ./Artifacts

- name: Download NuGet packages for .NET 9.0
uses: actions/download-artifact@v4
with:
name: nuget-packages-9.0.x
path: ./Artifacts

- name: Push to NuGet
if: github.event_name == 'release'
run: dotnet nuget push ./Artifacts/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
[![Nuget](https://img.shields.io/nuget/dt/HiveMQtt?style=for-the-badge)](https://www.nuget.org/packages/HiveMQtt)
[![GitHub](https://img.shields.io/github/license/hivemq/hivemq-mqtt-client-dotnet?style=for-the-badge)](https://github.com/hivemq/hivemq-mqtt-client-dotnet/blob/main/LICENSE)


![Static Badge](https://img.shields.io/badge/.NET%20Core-6-%23512BD4?style=for-the-badge)
![Static Badge](https://img.shields.io/badge/.NET%20Core-7-%23512BD4?style=for-the-badge)
![Static Badge](https://img.shields.io/badge/.NET%20Core-8-%23512BD4?style=for-the-badge)
![Static Badge](https://img.shields.io/badge/.NET-6.0-%23512BD4?style=for-the-badge)
![Static Badge](https://img.shields.io/badge/.NET-7.0-%23512BD4?style=for-the-badge)
![Static Badge](https://img.shields.io/badge/.NET-8.0-%23512BD4?style=for-the-badge)
![Static Badge](https://img.shields.io/badge/.NET-9.0-%23512BD4?style=for-the-badge)

### 💽 Installation & Compatibility
* **Easy-to-Install**: Available as a [Nuget package](https://www.nuget.org/packages/HiveMQtt).
* **Globally Compatible**: Built to be a fully compliant MQTT 5.0 client compatible with all modern MQTT brokers.
* **Multi-Targeted**: Supports .NET 6.0, 7.0 & 8.0
* **Multi-Targeted**: Supports .NET 6.0, 7.0, 8.0 & 9.0

### 🚀 Features
* **MQTT 5.0 Support**: Fully compliant with the latest [MQTT 5.0 specification](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html), ensuring compatibility with modern MQTT brokers.
Expand Down
10 changes: 5 additions & 5 deletions Source/HiveMQtt/Client/Connection/ConnectionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
{
// Don't use CancelAsync here to maintain backwards compatibility
// with >=.net6.0. CancelAsync was introduced in .net8.0
this.cancellationTokenSource.Cancel();

Check warning on line 143 in Source/HiveMQtt/Client/Connection/ConnectionManager.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-8.0.x

Cancel synchronously blocks. Await CancelAsync instead. (https://github.com/Microsoft/vs-threading/blob/main/doc/analyzers/VSTHRD103.md)

Check warning on line 143 in Source/HiveMQtt/Client/Connection/ConnectionManager.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Cancel synchronously blocks. Await CancelAsync instead. (https://github.com/Microsoft/vs-threading/blob/main/doc/analyzers/VSTHRD103.md)

Check warning on line 143 in Source/HiveMQtt/Client/Connection/ConnectionManager.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Cancel synchronously blocks. Await CancelAsync instead. (https://github.com/Microsoft/vs-threading/blob/main/doc/analyzers/VSTHRD103.md)

// Delay for a short period to allow the tasks to cancel
await Task.Delay(1000).ConfigureAwait(false);
Expand All @@ -152,7 +152,7 @@
}
else
{
Logger.Error("ConnectionPublishWriterTask did not complete");
Logger.Trace("ConnectionPublishWriterTask did not complete in time");
}

if (this.ConnectionWriterTask is not null && this.ConnectionWriterTask.IsCompleted)
Expand All @@ -161,7 +161,7 @@
}
else
{
Logger.Error("ConnectionWriterTask did not complete");
Logger.Trace("ConnectionWriterTask did not complete in time");
}

if (this.ConnectionReaderTask is not null && this.ConnectionReaderTask.IsCompleted)
Expand All @@ -170,7 +170,7 @@
}
else
{
Logger.Error("ConnectionReaderTask did not complete");
Logger.Trace("ConnectionReaderTask did not complete in time");
}

if (this.ReceivedPacketsHandlerTask is not null && this.ReceivedPacketsHandlerTask.IsCompleted)
Expand All @@ -179,7 +179,7 @@
}
else
{
Logger.Error("ReceivedPacketsHandlerTask did not complete");
Logger.Trace("ReceivedPacketsHandlerTask did not complete in time");
}

if (this.ConnectionMonitorTask is not null && this.ConnectionMonitorTask.IsCompleted)
Expand All @@ -188,7 +188,7 @@
}
else
{
Logger.Error("ConnectionMonitorTask did not complete");
Logger.Trace("ConnectionMonitorTask did not complete in time");
}
}

Expand Down
9 changes: 7 additions & 2 deletions Source/HiveMQtt/Client/Connection/ConnectionManagerTasks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ private async Task RunTaskHealthCheckAsync(Task? task, string taskName)
private Task ConnectionMonitorAsync(CancellationToken cancellationToken) => Task.Run(
async () =>
{
var keepAlivePeriod = this.Client.Options.KeepAlive / 2;
Logger.Trace($"{this.Client.Options.ClientId}-(CM)- Starting...{this.State}");
if (this.Client.Options.KeepAlive == 0)
{
Logger.Debug($"{this.Client.Options.ClientId}-(CM)- KeepAlive is 0. No pings will be sent.");
}

var keepAlivePeriod = this.Client.Options.KeepAlive;
this.lastCommunicationTimer.Start();

while (true)
Expand All @@ -62,7 +67,7 @@ private Task ConnectionMonitorAsync(CancellationToken cancellationToken) => Task
// If connected and no recent packets have been sent, send a ping
if (this.State == ConnectState.Connected)
{
if (this.lastCommunicationTimer.Elapsed > TimeSpan.FromSeconds(keepAlivePeriod))
if (this.Client.Options.KeepAlive > 0 && this.lastCommunicationTimer.Elapsed > TimeSpan.FromSeconds(keepAlivePeriod))
{
// Send PingReq
Logger.Trace($"{this.Client.Options.ClientId}-(CM)- --> PingReq");
Expand Down
6 changes: 6 additions & 0 deletions Source/HiveMQtt/Client/Exceptions/HiveMQttClientException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@
*/
namespace HiveMQtt.Client.Exceptions;

using System.Runtime.Serialization;

[Serializable]

public class
HiveMQttClientException : Exception
{
protected HiveMQttClientException(SerializationInfo info, StreamingContext context)
{
}

public HiveMQttClientException()
{
}
Expand Down
5 changes: 4 additions & 1 deletion Source/HiveMQtt/Client/HiveMQClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public async Task<PublishResult> PublishAsync(MQTT5PublishMessage message, Cance
// QoS 2: Assured Delivery
var packetIdentifier = await this.Connection.PacketIDManager.GetAvailablePacketIDAsync().ConfigureAwait(false);
var publishPacket = new PublishPacket(message, (ushort)packetIdentifier);
PublishResult? publishResult = null;
var publishResult = new PublishResult(publishPacket.Message);

Logger.Trace($"Queuing QoS 2 publish packet for send: {publishPacket.GetType().Name} id={publishPacket.PacketIdentifier}");
this.Connection.OutgoingPublishQueue.Enqueue(publishPacket);
Expand Down Expand Up @@ -472,4 +472,7 @@ public async Task<UnsubscribeResult> UnsubscribeAsync(UnsubscribeOptions unsubOp
this.AfterUnsubscribeEventLauncher(unsubscribeResult);
return unsubscribeResult;
}

// Method to check if ping are sent based on the KeepAlive option
public bool IsPingSent() => this.Options.KeepAlive > 0;
}
2 changes: 2 additions & 0 deletions Source/HiveMQtt/Client/HiveMQClientUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ public static bool MatchTopic(string pattern, string candidate)

// If pattern contains a multi-level wildcard character, it must be the last character in the pattern
// and it must be preceded by a topic level separator.
#pragma warning disable SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.
var mlwcValidityRegex = new Regex(@"(?<!/)#");
#pragma warning restore SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.

if (pattern.Contains("/#/") | mlwcValidityRegex.IsMatch(pattern))
{
Expand Down
2 changes: 2 additions & 0 deletions Source/HiveMQtt/Client/Transport/WebSocketTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@
do
{
result = await this.Socket.ReceiveAsync(buffer, CancellationToken.None).ConfigureAwait(false);
#pragma warning disable CA1835 // Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
await ms.WriteAsync(buffer.Array, buffer.Offset, result.Count, cancellationToken).ConfigureAwait(false);

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-6.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-6.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-7.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-7.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-7.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-7.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-8.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-8.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-8.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.

Check warning on line 121 in Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Possible null reference argument for parameter 'buffer' in 'Task MemoryStream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)'.
#pragma warning restore CA1835 // Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
}
while (!result.EndOfMessage);

Expand Down
25 changes: 25 additions & 0 deletions Source/HiveMQtt/Client/internal/Validator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
}

// Regular expression to match any character that is NOT in the specified set
var regex = new Regex("[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]");

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-7.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time.

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-7.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time.

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-8.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time.

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-8.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1045)

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1045)

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time.

Check warning on line 43 in Source/HiveMQtt/Client/internal/Validator.cs

View workflow job for this annotation

GitHub Actions / pipeline-ubuntu-latest-dotnet-9.0.x

Use 'GeneratedRegexAttribute' to generate the regular expression implementation at compile-time. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1045)

// Check if the input string contains any character that does not match the pattern
if (regex.IsMatch(clientId))
Expand Down Expand Up @@ -90,6 +90,7 @@
/// <exception cref="ArgumentNullException">Thrown when the topic filter is null.</exception>
/// <exception cref="HiveMQttClientException">Thrown when the topic filter is longer than 65535 characters or empty.</exception>
/// <exception cref="HiveMQttClientException">Thrown when the topic filter contains any null characters.</exception>
/// <exception cref="ArgumentException">Thrown when the topic filter contains invalid wildcard usage.</exception>
public static void ValidateTopicFilter(string topic)
{
ArgumentNullException.ThrowIfNull(topic);
Expand All @@ -108,5 +109,29 @@
{
throw new HiveMQttClientException("A topic name cannot contain any null characters.");
}

// Check for invalid usage of '#' wildcard
if (topic.Contains('#'))
{
if (topic.IndexOf('#') != topic.Length - 1)
{
throw new ArgumentException("The '#' wildcard must be the last character in the topic filter.");
}

if (topic.Length > 1 && topic[^2] != '/')
{
throw new ArgumentException("The '#' wildcard must be preceded by a topic level separator or be the only character.");
}
}

// Check for invalid usage of '+' wildcard
var segments = topic.Split('/');
foreach (var segment in segments)
{
if (segment.Contains('+') && segment != "+")
{
throw new ArgumentException("The '+' wildcard must stand alone and cannot be part of another string.");
}
}
}
}
19 changes: 18 additions & 1 deletion Source/HiveMQtt/HiveMQtt.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Build">
<TargetFrameworks>net6.0;net7.0;net8.0;</TargetFrameworks>
<!-- Include net6.0 only if the SDK supports it -->
<TargetFrameworks Condition="'$(NETCoreSdkVersion)' >= '6.0.0'">net6.0</TargetFrameworks>

<!-- Add net7.0 conditionally if the SDK supports it -->
<TargetFrameworks Condition="'$(NETCoreSdkVersion)' >= '7.0.0'">
$(TargetFrameworks);net7.0
</TargetFrameworks>

<!-- Add net8.0 conditionally if the SDK supports it -->
<TargetFrameworks Condition="'$(NETCoreSdkVersion)' >= '8.0.0'">
$(TargetFrameworks);net8.0
</TargetFrameworks>

<!-- Add net9.0 conditionally if the SDK supports it -->
<TargetFrameworks Condition="'$(NETCoreSdkVersion)' >= '9.0.0'">
$(TargetFrameworks);net9.0
</TargetFrameworks>

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

Expand Down
4 changes: 0 additions & 4 deletions Source/HiveMQtt/HiveMQtt.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ VisualStudioVersion = 25.0.1704.5
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiveMQtt", "HiveMQtt.csproj", "{7A86FFD4-6CD2-419C-B8E8-53437CDB1E8B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiveMQtt-CLI", "..\..\Examples\HiveMQtt-CLI\HiveMQtt-CLI\HiveMQtt-CLI.csproj", "{B7404198-178C-43C5-9136-4BF25D23EC7E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reconnect", "..\..\Examples\Reconnect\Reconnect.csproj", "{FE0AD218-169C-4DE6-ADBE-0B55695620B4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
1 change: 1 addition & 0 deletions Source/HiveMQtt/MQTT5/Types/TopicFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class TopicFilter
{
public TopicFilter(string topic, QualityOfService qos = QualityOfService.AtMostOnceDelivery, bool? noLocal = null, bool? retainAsPublished = null, RetainHandling? retainHandling = null)
{
Client.Internal.Validator.ValidateTopicFilter(topic);
this.Topic = topic;
this.QoS = qos;
this.NoLocal = noLocal;
Expand Down
8 changes: 2 additions & 6 deletions Tests/HiveMQtt.Test/HiveMQClient/LWTTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ public async Task Last_Will_With_Properties_Async()
Assert.Equal("last will message", args.PublishMessage.PayloadAsString);
Assert.Equal("application/text", args.PublishMessage.ContentType);
Assert.Equal("response/topic", args.PublishMessage.ResponseTopic);
#pragma warning disable SA1010 // Opening square brackets should be spaced correctly
byte[] correlationData = [1, 2, 3, 4, 5];
#pragma warning restore SA1010 // Opening square brackets should be spaced correctly
var correlationData = new byte[] { 1, 2, 3, 4, 5 };
Assert.Equal(correlationData, args.PublishMessage.CorrelationData);
Assert.Equal(MQTT5PayloadFormatIndicator.UTF8Encoded, args.PublishMessage.PayloadFormatIndicator);
Assert.Equal(100, args.PublishMessage.MessageExpiryInterval);
Expand Down Expand Up @@ -65,9 +63,7 @@ public async Task Last_Will_With_Properties_Async()
options.LastWillAndTestament.QoS = QualityOfService.AtLeastOnceDelivery;
options.LastWillAndTestament.ContentType = "application/text";
options.LastWillAndTestament.ResponseTopic = "response/topic";
#pragma warning disable SA1010 // Opening square brackets should be spaced correctly
byte[] correlationData = [1, 2, 3, 4, 5];
#pragma warning restore SA1010 // Opening square brackets should be spaced correctly
var correlationData = new byte[] { 1, 2, 3, 4, 5 };
options.LastWillAndTestament.CorrelationData = correlationData;
options.LastWillAndTestament.UserProperties.Add("userPropertyKey", "userPropertyValue");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ public async Task Last_Will_With_Properties_Async()
Assert.True(listenerClient.IsConnected());

var taskLWTReceived = new TaskCompletionSource<bool>();
#pragma warning disable SA1010 // Opening square brackets should be spaced correctly
byte[] correlationDataBytes = [1, 2, 3, 4, 5];
#pragma warning restore SA1010 // Opening square brackets should be spaced correctly
var correlationData = new byte[] { 1, 2, 3, 4, 5 };

// Set the event handler for the message received event
listenerClient.OnMessageReceived += (sender, args) =>
Expand All @@ -53,7 +51,7 @@ public async Task Last_Will_With_Properties_Async()
Assert.Equal("last will message", args.PublishMessage.PayloadAsString);
Assert.Equal("application/text", args.PublishMessage.ContentType);
Assert.Equal("response/topic", args.PublishMessage.ResponseTopic);
Assert.Equal(correlationDataBytes, args.PublishMessage.CorrelationData);
Assert.Equal(correlationData, args.PublishMessage.CorrelationData);
Assert.Equal(MQTT5PayloadFormatIndicator.UTF8Encoded, args.PublishMessage.PayloadFormatIndicator);
Assert.Equal(100, args.PublishMessage.MessageExpiryInterval);
Assert.Single(args.PublishMessage.UserProperties);
Expand All @@ -77,7 +75,7 @@ public async Task Last_Will_With_Properties_Async()
.WithQualityOfServiceLevel(QualityOfService.AtLeastOnceDelivery)
.WithContentType("application/text")
.WithResponseTopic("response/topic")
.WithCorrelationData(correlationDataBytes)
.WithCorrelationData(correlationData)
.WithPayloadFormatIndicator(MQTT5PayloadFormatIndicator.UTF8Encoded)
.WithMessageExpiryInterval(100)
.WithUserProperty("userPropertyKey", "userPropertyValue")
Expand Down
Loading
Loading