Skip to content
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
10 changes: 7 additions & 3 deletions src/Transport/Failover/FailoverTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,13 @@ public void HandleTransportFailure(Exception e)
{
if (CanReconnect())
{
Tracer.WarnFormat("Transport failed to {0}, attempting to automatically reconnect due to: {1}",
ConnectedTransportURI, e.Message);
reconnectOk = true;
//Check to see if the exception is a security exception
if (!(e is NMSSecurityException))
{
Tracer.WarnFormat("Transport failed to {0}, attempting to automatically reconnect due to: {1}",
ConnectedTransportURI, e.Message);
reconnectOk = true;
}
}

initialized = false;
Expand Down
25 changes: 19 additions & 6 deletions src/Transport/InactivityMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Threading;
using Apache.NMS.ActiveMQ.Commands;
using Apache.NMS.ActiveMQ.Threads;
using Apache.NMS.ActiveMQ.Util;
using Apache.NMS.ActiveMQ.Util.Synchronization;
using Apache.NMS.Util;

Expand Down Expand Up @@ -230,32 +231,44 @@ protected override async System.Threading.Tasks.Task OnCommand(ITransport sender
inRead.Value = true;
try
{
if(command.IsKeepAliveInfo)
if (command is ExceptionResponse)
{
ExceptionResponse error = command as ExceptionResponse;
NMSException exception = ExceptionFromBrokerError.CreateExceptionFromBrokerError(error.Exception);
if (exception is NMSSecurityException)
{
OnException(this, exception);
}
else
{
Tracer.WarnFormat("ExceptionResponse received from the broker:{0}", command.GetType());
}
}else if (command.IsKeepAliveInfo)
{
KeepAliveInfo info = command as KeepAliveInfo;
if(info.ResponseRequired)
if (info.ResponseRequired)
{
try
{
info.ResponseRequired = false;
Oneway(info);
}
catch(IOException ex)
catch (IOException ex)
{
OnException(this, ex);
}
}
}
else if(command.IsWireFormatInfo)
else if (command.IsWireFormatInfo)
{
lock(monitor)
lock (monitor)
{
remoteWireFormatInfo = command as WireFormatInfo;
try
{
StartMonitorThreads();
}
catch(IOException ex)
catch (IOException ex)
{
OnException(this, ex);
}
Expand Down
78 changes: 78 additions & 0 deletions src/Util/ExceptionFromBrokerError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Apache.NMS.ActiveMQ.Commands;
using System;
using System.Reflection;


namespace Apache.NMS.ActiveMQ.Util
{
internal class ExceptionFromBrokerError
{
public static NMSException CreateExceptionFromBrokerError(BrokerError brokerError)
{
String exceptionClassName = brokerError.ExceptionClass;

if (String.IsNullOrEmpty(exceptionClassName))
{
return new BrokerException(brokerError);
}

NMSException exception = null;
String message = brokerError.Message;

// We only create instances of exceptions from the NMS API
Assembly nmsAssembly = Assembly.GetAssembly(typeof(NMSException));

// First try and see if it's one we populated ourselves in which case
// it will have the correct namespace and exception name.
Type exceptionType = nmsAssembly.GetType(exceptionClassName, false, true);

// Exceptions from the broker don't have the same namespace, so we
// trim that and try using the NMS namespace to see if we can get an
// NMSException based version of the same type. We have to convert
// the JMS prefixed exceptions to NMS also.
if (null == exceptionType)
{
if (exceptionClassName.StartsWith("java.lang.SecurityException"))
{
exceptionClassName = "Apache.NMS.NMSSecurityException";
}
else if (!exceptionClassName.StartsWith("Apache.NMS"))
{
string transformClassName;

if (exceptionClassName.Contains("."))
{
int pos = exceptionClassName.LastIndexOf(".");
transformClassName = exceptionClassName.Substring(pos + 1).Replace("JMS", "NMS");
}
else
{
transformClassName = exceptionClassName;
}

exceptionClassName = "Apache.NMS." + transformClassName;
}

exceptionType = nmsAssembly.GetType(exceptionClassName, false, true);
}

if (exceptionType != null)
{
object[] args = null;
if (!String.IsNullOrEmpty(message))
{
args = new object[1];
args[0] = message;
}

exception = Activator.CreateInstance(exceptionType, args) as NMSException;
}
else
{
exception = new BrokerException(brokerError);
}

return exception;
}
}
}
47 changes: 47 additions & 0 deletions test/Transport/Inactivity/InactivityMonitorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,53 @@ public void TestWriteMessageFail()
{
}
}
public class TestableInactivityMonitor : InactivityMonitor
{
public TestableInactivityMonitor(ITransport next) : base(next) { }

// Expose protected method for testing
public Task TestOnCommand(ITransport sender, Command command)
{
return OnCommand(sender, command);
}
}
[Test]
public void OnCommand_WithNMSSecurityException_ShouldCallOnException()
{
// Arrange
var brokerError = new BrokerError
{
ExceptionClass = "javax.jms.JMSSecurityException",
Message = "Authentication failed"
};

var exceptionResponse = new ExceptionResponse
{
Exception = brokerError
};

// Mock the static method call - this would require making ExceptionFromBrokerError testable
// For this test, we'll assume it returns an NMSSecurityException
var securityException = new NMSSecurityException("Authentication failed");
TestableInactivityMonitor monitor = new TestableInactivityMonitor(this.transport);
monitor.Exception += new ExceptionHandler(OnException);
monitor.CommandAsync += new CommandHandlerAsync(OnCommand);
bool exceptionHandlerCalled = false;
Exception caughtException = null;
monitor.Exception += (sender, args) =>
{
exceptionHandlerCalled = true;
caughtException = args;
};
// Act
Task task=monitor.TestOnCommand(transport, exceptionResponse);
task.Wait();
// Assert
Assert.IsTrue(exceptionHandlerCalled, "Exception handler should have been called");
Assert.IsNotNull(caughtException, "Exception should have been caught");
Assert.IsInstanceOf<NMSSecurityException>(caughtException, "Should be NMSSecurityException");
Assert.AreEqual("Authentication failed", caughtException.Message);
}

[Test]
public void TestNonFailureSendCase()
Expand Down