Skip to content

Commit

Permalink
Merge pull request #2472 from Particular/cantConvertToTransportMessage
Browse files Browse the repository at this point in the history
Failure to convert to TransportMessage should result in ErrorQueue
  • Loading branch information
SimonCropp committed Oct 29, 2014
2 parents cd1185b + 4ee392f commit 33947a3
Show file tree
Hide file tree
Showing 15 changed files with 374 additions and 103 deletions.
28 changes: 28 additions & 0 deletions src/NServiceBus.AcceptanceTesting/ScenarioContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace NServiceBus.AcceptanceTesting
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
Expand Down Expand Up @@ -70,5 +72,31 @@ public void AddTrace(string trace)
{
Trace += DateTime.Now.ToString("HH:mm:ss.ffffff") + " - " + trace + Environment.NewLine;
}

public void RecordEndpointLog(string endpointName,string level ,string message)
{
endpointLogs.Add(new EndpointLogItem
{
Endpoint = endpointName,
Level = level,
Message = message
});
}


public List<EndpointLogItem> GetAllLogs()
{
return endpointLogs.ToList();
}


List<EndpointLogItem> endpointLogs = new List<EndpointLogItem>();

public class EndpointLogItem
{
public string Endpoint { get; set; }
public string Message { get; set; }
public string Level { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

public class ContextAppender : ILoggerFactory, ILog
{
public ContextAppender(ScenarioContext context)
public ContextAppender(ScenarioContext context, string endpointName)
{
this.context = context;
this.endpointName = endpointName;
}

void Append(Exception exception)
Expand All @@ -21,6 +22,7 @@ void Append(Exception exception)
}

ScenarioContext context;
readonly string endpointName;

public ILog GetLogger(Type type)
{
Expand Down Expand Up @@ -89,17 +91,23 @@ public void WarnFormat(string format, params object[] args)
public void Error(string message)
{
Trace.WriteLine(message);

context.RecordEndpointLog(endpointName,"error", message);
}

public void Error(string message, Exception exception)
{
Trace.WriteLine(string.Format("{0} {1}", message, exception));
var fullMessage = string.Format("{0} {1}", message, exception);
Trace.WriteLine(fullMessage);
Append(exception);
context.RecordEndpointLog(endpointName, "error", fullMessage);
}

public void ErrorFormat(string format, params object[] args)
{
Trace.WriteLine(string.Format(format, args));
var fullMessage = string.Format(format, args);
Trace.WriteLine(fullMessage);
context.RecordEndpointLog(endpointName, "error", fullMessage);
}

public void Fatal(string message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public BusConfiguration GetConfiguration(RunDescriptor runDescriptor, EndpointCo
{
var settings = runDescriptor.Settings;

LogManager.UseFactory(new ContextAppender(runDescriptor.ScenarioContext));
LogManager.UseFactory(new ContextAppender(runDescriptor.ScenarioContext, endpointConfiguration.EndpointName));

var types = GetTypesScopedByTestClass(endpointConfiguration);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace NServiceBus.AcceptanceTests.Exceptions
{
using System;
using System.Reflection;

static class SerializerCorrupter
{

public static void Corrupt()
{
var msmqUtilitiesType = Type.GetType("NServiceBus.MsmqUtilities, NServiceBus.Core");
var headerSerializerField = msmqUtilitiesType.GetField("headerSerializer", BindingFlags.Static | BindingFlags.NonPublic);
headerSerializerField.SetValue(null, null);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
namespace NServiceBus.AcceptanceTests.Exceptions
{
using System;
using System.Linq;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.AcceptanceTests.EndpointTemplates;
using NUnit.Framework;

public class When_cant_convert_to_TransportMessage : NServiceBusAcceptanceTest
{
[Test]
public void Should_send_message_to_error_queue()
{
Scenario.Define<Context>()
.WithEndpoint<Sender>(b => b.Given(bus => bus.Send(new Message())))
.WithEndpoint<Receiver>()
.AllowExceptions()
.Done(c => c.GetAllLogs().Any(l=>l.Level == "error"))
.Repeat(r=>r.For(ScenarioDescriptors.Transports.Msmq))
.Should(c =>
{
var logs = c.GetAllLogs();
Assert.True(logs.Any(l => l.Message.Contains("is corrupt and will be moved to")));
})
.Run(new RunSettings
{
UseSeparateAppDomains = true
});
}

public class Context : ScenarioContext
{
}

public class Sender : EndpointConfigurationBuilder
{
public Sender()
{
EndpointSetup<DefaultServer>()
.AddMapping<Message>(typeof(Receiver));
}
}

public class Receiver : EndpointConfigurationBuilder
{
public Receiver()
{
SerializerCorrupter.Corrupt();
EndpointSetup<DefaultServer>();
}

}

[Serializable]
public class Message : IMessage
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
namespace NServiceBus.AcceptanceTests.Exceptions
{
using System;
using System.Linq;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.AcceptanceTests.EndpointTemplates;
using NUnit.Framework;
using IMessage = NServiceBus.IMessage;

public class When_cant_convert_to_TransportMessage_NoTransactions : NServiceBusAcceptanceTest
{
[Test]
public void Should_send_message_to_error_queue()
{
Scenario.Define<Context>()
.WithEndpoint<Sender>(b => b.Given(bus => bus.Send(new Message())))
.WithEndpoint<Receiver>()
.AllowExceptions()
.Done(c => c.GetAllLogs().Any(l=>l.Level == "error"))
.Repeat(r=>r.For(ScenarioDescriptors.Transports.Msmq))
.Should(c =>
{
var logs = c.GetAllLogs();
Assert.True(logs.Any(l => l.Message.Contains("is corrupt and will be moved to")));
})
.Run(new RunSettings
{
UseSeparateAppDomains = true
});
}

public class Context : ScenarioContext
{
}

public class Sender : EndpointConfigurationBuilder
{
public Sender()
{
EndpointSetup<DefaultServer>(b => b.Transactions().Disable())
.AddMapping<Message>(typeof(Receiver));
}
}

public class Receiver : EndpointConfigurationBuilder
{
public Receiver()
{
SerializerCorrupter.Corrupt();
EndpointSetup<DefaultServer>(b => b.Transactions().Disable());
}
}

[Serializable]
public class Message : IMessage
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace NServiceBus.AcceptanceTests.Exceptions
{
using System;
using System.Linq;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.AcceptanceTests.EndpointTemplates;
using NUnit.Framework;

public class When_cant_convert_to_TransportMessage_SuppressedDTC : NServiceBusAcceptanceTest
{
[Test]
public void Should_send_message_to_error_queue()
{
Scenario.Define<Context>()
.WithEndpoint<Sender>(b => b.Given(bus => bus.Send(new Message())))
.WithEndpoint<Receiver>()
.AllowExceptions()
.Done(c => c.GetAllLogs().Any(l=>l.Level == "error"))
.Repeat(r=>r.For(ScenarioDescriptors.Transports.Msmq))
.Should(c =>
{
var logs = c.GetAllLogs();
Assert.True(logs.Any(l => l.Message.Contains("is corrupt and will be moved to")));
})
.Run(new RunSettings
{
UseSeparateAppDomains = true
});
}

public class Context : ScenarioContext
{
}

public class Sender : EndpointConfigurationBuilder
{
public Sender()
{
EndpointSetup<DefaultServer>(b => b.Transactions().DisableDistributedTransactions())
.AddMapping<Message>(typeof(Receiver));
}
}

public class Receiver : EndpointConfigurationBuilder
{
public Receiver()
{
SerializerCorrupter.Corrupt();
EndpointSetup<DefaultServer>(b => b.Transactions().DisableDistributedTransactions());
}
}

[Serializable]
public class Message : IMessage
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@
<Compile Include="Config\When__startup_is_complete.cs" />
<Compile Include="CriticalError\When_registering_a_custom_criticalErrorHandler.cs" />
<Compile Include="DataBus\When_using_custom_IDataBus.cs" />
<Compile Include="Exceptions\Cant_convert_to_TransportMessage\SerializerCorrupter.cs" />
<Compile Include="Exceptions\Cant_convert_to_TransportMessage\When_cant_convert_to_TransportMessage_NoTransactions.cs" />
<Compile Include="Exceptions\Cant_convert_to_TransportMessage\When_cant_convert_to_TransportMessage_SuppressedDTC.cs" />
<Compile Include="Exceptions\When_handler_throws_serialization_exception.cs" />
<Compile Include="Exceptions\Message_without_an_id.cs" />
<Compile Include="Sagas\When_reply_from_a_finder.cs" />
<Compile Include="Exceptions\Cant_convert_to_TransportMessage\When_cant_convert_to_TransportMessage.cs" />
<Compile Include="Sagas\When_message_has_a_saga_id.cs" />
<Compile Include="Retries\When_Subscribing_to_errors.cs" />
<Compile Include="Sagas\When_timeout_hit_not_found_saga.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static RunDescriptor Default
}
}

static RunDescriptor Msmq
public static RunDescriptor Msmq
{
get { return AllAvailable.SingleOrDefault(r => r.Key == "MsmqTransport"); }
}
Expand Down
52 changes: 52 additions & 0 deletions src/NServiceBus.Core/Faults/ErrorQueueSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace NServiceBus.Faults
{
using System.Configuration;
using NServiceBus.Config;
using NServiceBus.Logging;
using NServiceBus.Settings;
using NServiceBus.Utils;

static class ErrorQueueSettings
{
public static Address GetConfiguredErrorQueue(ReadOnlySettings settings)
{
var errorQueue = Address.Undefined;

var section = settings.GetConfigSection<MessageForwardingInCaseOfFaultConfig>();
if (section != null)
{
if (string.IsNullOrWhiteSpace(section.ErrorQueue))
{
throw new ConfigurationErrorsException(
"'MessageForwardingInCaseOfFaultConfig' configuration section is found but 'ErrorQueue' value is missing." +
"\n The following is an example for adding such a value to your app config: " +
"\n <MessageForwardingInCaseOfFaultConfig ErrorQueue=\"error\"/> \n");
}

Logger.Debug("Error queue retrieved from <MessageForwardingInCaseOfFaultConfig> element in config file.");

errorQueue = Address.Parse(section.ErrorQueue);
}
else
{
var registryErrorQueue = RegistryReader.Read("ErrorQueue");
if (!string.IsNullOrWhiteSpace(registryErrorQueue))
{
Logger.Debug("Error queue retrieved from registry settings.");
errorQueue = Address.Parse(registryErrorQueue);
}
}

if (errorQueue == Address.Undefined)
{
throw new ConfigurationErrorsException("Faults forwarding requires an error queue to be specified. Please add a 'MessageForwardingInCaseOfFaultConfig' section to your app.config" +
"\n or configure a global one using the powershell command: Set-NServiceBusLocalMachineSettings -ErrorQueue {address of error queue}");
}

return errorQueue;

}

static ILog Logger = LogManager.GetLogger(typeof(ErrorQueueSettings));
}
}
Loading

0 comments on commit 33947a3

Please sign in to comment.