-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backport msg size limit 11.0.1 (#1022)
* Mention Azure Storage Explorer * Add Azurite gitignore to src * Make sure messages close to the size limit can be moved as is to the error queue --------- Co-authored-by: Bob Langley <[email protected]>
- Loading branch information
1 parent
58638b7
commit e912dcd
Showing
10 changed files
with
303 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Azurite queue | ||
__queuestorage__ | ||
__azurite_db_queue__.json | ||
__azurite_db_queue_extent__.json | ||
|
||
# Azurite blob | ||
__blobstorage__ | ||
__azurite_db_blob__.json | ||
__azurite_db_blob_extent__.json | ||
|
||
# Azurite table | ||
__azurite_db_table__.json | ||
__azurite_db_table_extent__.json |
179 changes: 179 additions & 0 deletions
179
src/AcceptanceTests/Receiving/When_receiving_large_message.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
namespace NServiceBus.Transport.AzureStorageQueues.AcceptanceTests | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using AcceptanceTesting; | ||
using AcceptanceTesting.Customization; | ||
using Azure.Transports.WindowsAzureStorageQueues; | ||
using global::Azure.Storage.Queues; | ||
using global::Newtonsoft.Json; | ||
using NServiceBus.AcceptanceTests; | ||
using NServiceBus.AcceptanceTests.EndpointTemplates; | ||
using NServiceBus.Faults; | ||
using NUnit.Framework; | ||
|
||
public class When_receiving_large_message : NServiceBusAcceptanceTest | ||
{ | ||
[Test] | ||
public async Task Should_consume_it_without_the_error_headers_when_message_size_very_close_to_limit() | ||
{ | ||
var ctx = await Scenario.Define<Context>() | ||
.WithEndpoint<Receiver>(b => | ||
{ | ||
b.When((bus, c) => | ||
{ | ||
var connectionString = Testing.Utilities.GetEnvConfiguredConnectionString(); | ||
var queueClient = new QueueClient(connectionString, "receivinglargemessage-receiver"); | ||
|
||
//This value is fine tuned to ensure adding the 2 error headers make the message too large | ||
string contentCloseToLimits = new string('x', (35 * 1024) + 425); | ||
|
||
var message = new MyMessage { SomeProperty = contentCloseToLimits, }; | ||
|
||
var messageSerialized = JsonConvert.SerializeObject(message, typeof(MyMessage), Formatting.Indented, new JsonSerializerSettings()); | ||
|
||
string id = Guid.NewGuid().ToString(); | ||
var wrapper = new MessageWrapper | ||
{ | ||
Id = id, | ||
Body = Encoding.UTF8.GetBytes(messageSerialized), | ||
Headers = new Dictionary<string, string> | ||
{ | ||
{ Headers.EnclosedMessageTypes, $"{typeof(MyMessage).AssemblyQualifiedName}" }, | ||
{ Headers.MessageId, id }, | ||
{ Headers.CorrelationId, id }, | ||
{TestIndependence.HeaderName, c.TestRunId.ToString()} | ||
} | ||
}; | ||
|
||
var wrapperSerialized = JsonConvert.SerializeObject(wrapper, typeof(MessageWrapper), Formatting.Indented, new JsonSerializerSettings()); | ||
|
||
var base64Encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(wrapperSerialized)); | ||
|
||
return queueClient.SendMessageAsync(base64Encoded); | ||
}).DoNotFailOnErrorMessages(); | ||
}) | ||
.WithEndpoint<ErrorSpy>() | ||
.Done(c => c.MessageMovedToTheErrorQueue) | ||
.Run(); | ||
|
||
Assert.IsFalse(ctx.IsFailedQHeaderPresent, "IsFailedQHeaderPresent"); | ||
Assert.IsFalse(ctx.IsExceptionTypeHeaderPresent, "IsExceptionTypeHeaderPresent"); | ||
} | ||
|
||
[Test] | ||
public async Task Should_consume_it_with_only_two_error_headers_when_message_size_close_to_limit() | ||
{ | ||
var ctx = await Scenario.Define<Context>() | ||
.WithEndpoint<Receiver>(b => | ||
{ | ||
b.When((bus, c) => | ||
{ | ||
var connectionString = Testing.Utilities.GetEnvConfiguredConnectionString(); | ||
var queueClient = new QueueClient(connectionString, "receivinglargemessage-receiver"); | ||
|
||
string contentCloseToLimits = new string('x', (35 * 1024) + 400); | ||
|
||
var message = new MyMessage { SomeProperty = contentCloseToLimits, }; | ||
|
||
var messageSerialized = JsonConvert.SerializeObject(message, typeof(MyMessage), Formatting.Indented, new JsonSerializerSettings()); | ||
|
||
string id = Guid.NewGuid().ToString(); | ||
var wrapper = new MessageWrapper | ||
{ | ||
Id = id, | ||
Body = Encoding.UTF8.GetBytes(messageSerialized), | ||
Headers = new Dictionary<string, string> | ||
{ | ||
{ Headers.EnclosedMessageTypes, $"{typeof(MyMessage).AssemblyQualifiedName}" }, | ||
{ Headers.MessageId, id }, | ||
{ Headers.CorrelationId, id }, | ||
{TestIndependence.HeaderName, c.TestRunId.ToString()} | ||
} | ||
}; | ||
|
||
var wrapperSerialized = JsonConvert.SerializeObject(wrapper, typeof(MessageWrapper), Formatting.Indented, new JsonSerializerSettings()); | ||
|
||
var base64Encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(wrapperSerialized)); | ||
|
||
return queueClient.SendMessageAsync(base64Encoded); | ||
}).DoNotFailOnErrorMessages(); | ||
}) | ||
.WithEndpoint<ErrorSpy>() | ||
.Done(c => c.MessageMovedToTheErrorQueue) | ||
.Run(); | ||
|
||
Assert.IsTrue(ctx.IsFailedQHeaderPresent, "IsFailedQHeaderPresent"); | ||
Assert.IsTrue(ctx.IsExceptionTypeHeaderPresent, "IsExceptionTypeHeaderPresent"); | ||
} | ||
|
||
class Context : ScenarioContext | ||
{ | ||
public bool MessageMovedToTheErrorQueue { get; set; } | ||
public bool IsFailedQHeaderPresent { get; set; } | ||
public bool IsExceptionTypeHeaderPresent { get; set; } | ||
|
||
} | ||
|
||
class Receiver : EndpointConfigurationBuilder | ||
{ | ||
public Receiver() => EndpointSetup<DefaultServer>(c => | ||
{ | ||
c.UseSerialization<NewtonsoftJsonSerializer>(); | ||
c.SendFailedMessagesTo(Conventions.EndpointNamingConvention(typeof(ErrorSpy))); | ||
}); | ||
|
||
public class MyHandler : IHandleMessages<MyMessage> | ||
{ | ||
public Task Handle(MyMessage message, IMessageHandlerContext context) | ||
{ | ||
throw new InvalidOperationException(); | ||
} | ||
} | ||
} | ||
|
||
class ErrorSpy : EndpointConfigurationBuilder | ||
{ | ||
public ErrorSpy() => EndpointSetup<DefaultServer>(config => | ||
{ | ||
config.UseSerialization<NewtonsoftJsonSerializer>(); | ||
config.LimitMessageProcessingConcurrencyTo(1); | ||
}); | ||
|
||
class MyMessageHandler : IHandleMessages<MyMessage> | ||
{ | ||
public MyMessageHandler(Context testContext) => this.testContext = testContext; | ||
|
||
public Task Handle(MyMessage message, IMessageHandlerContext context) | ||
{ | ||
if (context.MessageHeaders.TryGetValue(TestIndependence.HeaderName, out var testRunId) | ||
&& testRunId == testContext.TestRunId.ToString()) | ||
{ | ||
testContext.MessageMovedToTheErrorQueue = true; | ||
} | ||
if (context.MessageHeaders.ContainsKey(FaultsHeaderKeys.FailedQ) | ||
&& testRunId == testContext.TestRunId.ToString()) | ||
{ | ||
testContext.IsFailedQHeaderPresent = true; | ||
} | ||
if (context.MessageHeaders.ContainsKey("NServiceBus.ExceptionInfo.ExceptionType") | ||
&& testRunId == testContext.TestRunId.ToString()) | ||
{ | ||
testContext.IsExceptionTypeHeaderPresent = true; | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
readonly Context testContext; | ||
} | ||
} | ||
|
||
public class MyMessage : IMessage | ||
{ | ||
public string SomeProperty { get; set; } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.