SPRNET-1337

-Applied recommended fix from forum post
-Added new unit test to validate that handlers are acting in parallel once new patch introduced
This commit is contained in:
sbohlen
2010-08-27 17:00:05 +00:00
parent 7d523c654a
commit 7626d3f38e
8 changed files with 342 additions and 59 deletions

View File

@@ -81,11 +81,11 @@ namespace Spring.Messaging.Listener
q.ConvertAndSend("Goodbye World 1");
Assert.AreEqual(0, listener.MessageCount, "PRECONDITION FAILURE: Unable to send the message!");
distributedTxMessageListenerContainer.Start();
Thread.Sleep(waitInMillis);
distributedTxMessageListenerContainer.Stop();
distributedTxMessageListenerContainer.Shutdown();
Thread.Sleep(2500);
@@ -105,6 +105,8 @@ namespace Spring.Messaging.Listener
//must match the retry count in the object registration for test to pass!
const int EXCEPTION_QUEUE_RETRY_COUNT = 2;
int expectedMessageCount = MESSAGE_COUNT + (MESSAGE_COUNT * EXCEPTION_QUEUE_RETRY_COUNT);
MessageQueueTemplate q = applicationContext["queueTemplate"] as MessageQueueTemplate;
Assert.IsNotNull(q);
@@ -115,13 +117,22 @@ namespace Spring.Messaging.Listener
Assert.AreEqual(0, listener.MessageCount);
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
timer.Start();
distributedTxMessageListenerContainer.Start();
//this test needs to wait somewhat longer than the others in order to consistently pass so
//artificially inflate the waiting period before attempting subsequent asserts:
Thread.Sleep((int)(waitInMillis * 1.5));
while (listener.MessageCount < expectedMessageCount)
{
if (timer.ElapsedMilliseconds > 60000)
Assert.Fail("Did not receive expected number of messages within the permitted time limit.");
}
Assert.AreEqual(MESSAGE_COUNT + (MESSAGE_COUNT * EXCEPTION_QUEUE_RETRY_COUNT), listener.MessageCount);
timer.Stop();
System.Diagnostics.Debug.WriteLine("elapsed time = " + timer.ElapsedMilliseconds);
Assert.AreEqual(expectedMessageCount, listener.MessageCount);
distributedTxMessageListenerContainer.Stop();
distributedTxMessageListenerContainer.Shutdown();

View File

@@ -0,0 +1,120 @@
#region License
/*
* Copyright <20> 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
#region Imports
using System.Threading;
using NUnit.Framework;
using Spring.Messaging.Core;
using Spring.Testing.NUnit;
using System.Diagnostics;
using System;
#endregion
namespace Spring.Messaging.Listener
{
/// <summary>
/// This class contains tests for
/// </summary>
/// <author>Mark Pollack</author>
/// <version>$Id:$</version>
[TestFixture]
public class MultiThreadedNonTransactionalMessageListenerContainerTests : AbstractDependencyInjectionSpringContextTests
{
private NonTransactionalMessageListenerContainer container;
private WaitingHandler listener;
private SimpleExceptionHandler exceptionHandler;
[SetUp]
public override void SetUp()
{
MessageQueueUtils.RecreateMessageQueue(@".\Private$\testqueue", false);
MessageQueueUtils.RecreateMessageQueue(@".\Private$\testresponsequeue", false);
base.SetUp();
}
public SimpleExceptionHandler ExceptionHandler
{
set { exceptionHandler = value; }
}
public NonTransactionalMessageListenerContainer Container
{
get { return container; }
set { container = value; }
}
public WaitingHandler Listener
{
get { return listener; }
set { listener = value; }
}
[Test]
public void Test()
{
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
MessageQueueTemplate q = applicationContext["testQueueTemplate"] as MessageQueueTemplate;
Assert.IsNotNull(q);
q.ConvertAndSend("Hello World 1");
q.ConvertAndSend("Hello World 2");
q.ConvertAndSend("Hello World 3");
q.ConvertAndSend("Hello World 4");
q.ConvertAndSend("Hello World 5");
//Reset the state so that running all tests together will succeed.
exceptionHandler.MessageCount = 0;
Assert.AreEqual(0, listener.MessageCount);
timer.Start();
container.Start();
while (listener.MessageCount < 5)
{
//provide an exit if the test is completely over-length
if (timer.ElapsedMilliseconds > 120000)
Assert.Fail("Did not receive expected number of messages with the expected time-limit!");
}
timer.Stop();
container.Stop();
container.Shutdown();
Debug.WriteLine(String.Format("Elapsed Milliseconds: {0}", timer.ElapsedMilliseconds));
Assert.Less(timer.ElapsedMilliseconds, 50000);
Assert.AreEqual(5, listener.MessageCount);
Assert.AreEqual(0, exceptionHandler.MessageCount);
}
protected override string[] ConfigLocations
{
get { return new string[] { "assembly://Spring.Messaging.Tests/Spring.Messaging.Listener/MultiThreadedNonTransactionalMessageListenerContainerTests.xml" }; }
}
}
}

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
xmlns:db="http://www.springframework.net/database">
<db:provider id="DbProvider"
provider="System.Data.SqlClient"
connectionString="Data Source=MARKT60\SQL2005;Initial Catalog=Spring;Persist Security Info=True;User ID=springqa;Password=springqa"/>
<object id="adoTransactionManager"
type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data">
<property name="DbProvider" ref="DbProvider"/>
</object>
<object id='msmqTestQueue' type='Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging'>
<property name='Path' value='.\Private$\testqueue'/>
<property name='MessageReadPropertyFilterSetAll' value='true'/>
<property name='ProductTemplate'>
<object>
<property name='Label' value='MyTestQueueLabel'/>
</object>
</property>
</object>
<object id='msmqTestResponseQueue' type='Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging'>
<property name='Path' value='.\Private$\testresponsequeue'/>
<property name='MessageReadPropertyFilterSetAll' value='true'/>
<property name='ProductTemplate'>
<object>
<property name='Label' value='MyTestResponseQueueLabel'/>
</object>
</property>
</object>
<object id='testremotequeue' type='Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging'>
<property name='Path' value='FormatName:Direct=OS:RAVEN\Private$\testqueue'/>
<property name='RemoteQueue' value="true"/>
</object>
<object id="testRemoteTemplate" type="Spring.Messaging.Core.MessageQueueTemplate, Spring.Messaging">
<property name="DefaultMessageQueueObjectName" value="testremotequeue"/>
<property name="MessageConverterObjectName" value="binaryMessageConverter"/>
</object>
<object id="testQueueTemplate" type="Spring.Messaging.Core.MessageQueueTemplate, Spring.Messaging">
<property name="DefaultMessageQueueObjectName" value="msmqTestQueue"/>
<property name="MessageConverterObjectName" value="binaryMessageConverter"/>
</object>
<!-- Message Converters -->
<object id="messageConverter" type="Spring.Messaging.Support.Converters.XmlMessageConverter, Spring.Messaging"
singleton="false">
<property name="TargetTypes" value="System.String"/>
</object>
<object id="binaryMessageConverter" type="Spring.Messaging.Support.Converters.BinaryMessageConverter, Spring.Messaging" singleton="false">
</object>
<object id="nonTransactionalMessageListenerContainer" type="Spring.Messaging.Listener.NonTransactionalMessageListenerContainer, Spring.Messaging">
<property name="MessageQueueObjectName" value="testremotequeue"/>
<property name="MaxConcurrentListeners" value="5"/>
<property name="ListenerTimeLimit" value="20s"/>
<property name="MessageListener" ref="messageListenerAdapter"/>
<property name="ExceptionHandler" ref="exceptionHandler"/>
<property name="AutoStartup" value="false"/>
</object>
<!-- Adapter -->
<object id="messageListenerAdapter" type="Spring.Messaging.Listener.MessageListenerAdapter, Spring.Messaging">
<property name="DefaultResponseQueueName" value="msmqTestResponseQueue"/>
<property name="MessageConverterObjectName" value="binaryMessageConverter"/>
<property name="HandlerObject" ref="waitingHandler"/>
</object>
<!-- Message and Exception Handlers -->
<object id="waitingHandler" type="Spring.Messaging.Listener.WaitingHandler, Spring.Messaging.Tests">
</object>
<object id="exceptionHandler" type="Spring.Messaging.Listener.SimpleExceptionHandler, Spring.Messaging.Tests">
</object>
</objects>

View File

@@ -0,0 +1,49 @@
using System;
using Common.Logging;
using System.Threading;
namespace Spring.Messaging.Listener
{
public class WaitingHandler
{
#region Logging
private static readonly ILog LOG = LogManager.GetLogger(typeof(WaitingHandler));
#endregion
private int messageCount;
private string stateVariable;
public WaitingHandler()
{
this.stateVariable = "hello";
}
public WaitingHandler(string stateVariable)
{
this.stateVariable = stateVariable;
}
public int MessageCount
{
get { return messageCount; }
set { messageCount = value; }
}
public string HandleMessage(string msgTxt)
{
LOG.Debug(String.Format("Received text = [{0}]", msgTxt));
LOG.Debug("constructor set state string = " + stateVariable);
Thread.Sleep(10000);
messageCount++;
LOG.Debug("Message listener count = " + messageCount);
return msgTxt + " - processed!";
}
}
}

View File

@@ -75,6 +75,7 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Messaging\Listener\NonTransactionalMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\Listener\MultiThreadedNonTransactionalMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\Listener\TransactionalMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\queue-context.xml" />
<EmbeddedResource Include="Messaging\Core\MessageQueueTemplateTests.xml" />
@@ -87,11 +88,13 @@
<ItemGroup>
<Compile Include="Messaging\Core\MessageQueueMetadataCacheTests.cs" />
<Compile Include="Messaging\Core\MessageQueueUtils.cs" />
<Compile Include="Messaging\Core\WaitingHander.cs" />
<Compile Include="Messaging\Core\ThreadingTests.cs" />
<Compile Include="Messaging\Listener\Adapter\MessageListenerAdapterTests.cs" />
<Compile Include="Messaging\Listener\DistributedTxMessageListenerContainerTests.cs" />
<Compile Include="Messaging\Listener\LoggingExceptionHandler.cs" />
<Compile Include="Messaging\Listener\NonTransactionalMessageListenerContainerTests.cs">
<Compile Include="Messaging\Listener\NonTransactionalMessageListenerContainerTests.cs" />
<Compile Include="Messaging\Listener\MultiThreadedNonTransactionalMessageListenerContainerTests.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Messaging\Listener\SimpleExceptionHandler.cs" />

View File

@@ -76,6 +76,7 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Messaging\Listener\NonTransactionalMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\Listener\MultiThreadedNonTransactionalMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\Listener\TransactionalMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\queue-context.xml" />
<EmbeddedResource Include="Messaging\Core\MessageQueueTemplateTests.xml" />
@@ -88,13 +89,15 @@
<ItemGroup>
<Compile Include="MessagingCompilerOptionsTests.cs" />
<Compile Include="MessagingExceptionTests.cs" />
<Compile Include="Messaging\Listener\WaitingHandler.cs" />
<Compile Include="Messaging\Core\MessageQueueMetadataCacheTests.cs" />
<Compile Include="Messaging\Core\MessageQueueUtils.cs" />
<Compile Include="Messaging\Core\ThreadingTests.cs" />
<Compile Include="Messaging\Listener\Adapter\MessageListenerAdapterTests.cs" />
<Compile Include="Messaging\Listener\DistributedTxMessageListenerContainerTests.cs" />
<Compile Include="Messaging\Listener\LoggingExceptionHandler.cs" />
<Compile Include="Messaging\Listener\NonTransactionalMessageListenerContainerTests.cs">
<Compile Include="Messaging\Listener\NonTransactionalMessageListenerContainerTests.cs" />
<Compile Include="Messaging\Listener\MultiThreadedNonTransactionalMessageListenerContainerTests.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Messaging\Listener\SimpleExceptionHandler.cs" />

View File

@@ -56,6 +56,8 @@
<ItemGroup>
<Compile Include="Messaging\Core\MessageQueueTemplateTests.cs" />
<Compile Include="Messaging\Core\MessageQueueUtils.cs" />
<Compile Include="Messaging\Listener\WaitingHandler.cs" />
<Compile Include="Messaging\Listener\MultiThreadedNonTransactionalMessageListenerContainerTests.cs" />
<Compile Include="Messaging\Support\MessageQueueFactoryObjectTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@@ -88,6 +90,9 @@
<EmbeddedResource Include="Messaging\Core\MessageQueueTemplateTests.xml" />
<EmbeddedResource Include="Messaging\Listener\DistributedTxMessageListenerContainerTests.xml" />
<EmbeddedResource Include="Messaging\Core\MessageQueueMetadataCacheTests.xml" />
<EmbeddedResource Include="Messaging\Listener\MultiThreadedNonTransactionalMessageListenerContainerTests.xml">
<SubType>Designer</SubType>
</EmbeddedResource>
<Content Include="Spring.Messaging.Tests.dll.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>