summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRupert Smith <rupertlssmith@apache.org>2008-01-21 14:53:17 +0000
committerRupert Smith <rupertlssmith@apache.org>2008-01-21 14:53:17 +0000
commit91b6324b623c7dfc9fe32d3d041aa93a62ed9fc8 (patch)
tree2a6dc1a156d77d1ebc32ad31d501878dca9a6a20
parentfb555743c2ea148a176522400a2e835a4dbf7c25 (diff)
downloadqpid-python-91b6324b623c7dfc9fe32d3d041aa93a62ed9fc8.tar.gz
Qpid-727. Added closeable interface to connections, channels, producers and consumers. Previously there was no way to close these things in their interfaces.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2.1@613911 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--dotnet/Qpid.Client/Client/Closeable.cs3
-rw-r--r--dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs53
-rw-r--r--dotnet/Qpid.Integration.Tests/default.build7
-rw-r--r--dotnet/Qpid.Integration.Tests/log4net.config48
-rw-r--r--dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs69
-rw-r--r--dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs184
-rw-r--r--dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs4
-rw-r--r--dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs17
-rw-r--r--dotnet/Qpid.Integration.Tests/testcases/SyncConsumerTest.cs4
-rw-r--r--dotnet/Qpid.Messaging/IChannel.cs2
-rw-r--r--dotnet/Qpid.Messaging/ICloseable.cs33
-rw-r--r--dotnet/Qpid.Messaging/IConnection.cs2
-rw-r--r--dotnet/Qpid.Messaging/IMessageConsumer.cs58
-rw-r--r--dotnet/Qpid.Messaging/IMessagePublisher.cs2
14 files changed, 445 insertions, 41 deletions
diff --git a/dotnet/Qpid.Client/Client/Closeable.cs b/dotnet/Qpid.Client/Client/Closeable.cs
index d70f75ee6b..382e0aefde 100644
--- a/dotnet/Qpid.Client/Client/Closeable.cs
+++ b/dotnet/Qpid.Client/Client/Closeable.cs
@@ -19,10 +19,11 @@
*
*/
using System;
+using Apache.Qpid.Messaging;
namespace Apache.Qpid.Client
{
- public abstract class Closeable
+ public abstract class Closeable : ICloseable
{
/// <summary>
/// Used to ensure orderly closing of the object. The only method that is allowed to be called
diff --git a/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs b/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..a11c78b1d9
--- /dev/null
+++ b/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+using log4net.Config;
+[assembly: XmlConfigurator(ConfigFile="log4net.config")]
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Integration.Tests")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Integration.Tests")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7ebdea21-1352-4673-b66e-fdc0beff461f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.1.0.0")]
diff --git a/dotnet/Qpid.Integration.Tests/default.build b/dotnet/Qpid.Integration.Tests/default.build
index 6f3de7e7b8..36c28dc1d7 100644
--- a/dotnet/Qpid.Integration.Tests/default.build
+++ b/dotnet/Qpid.Integration.Tests/default.build
@@ -25,14 +25,15 @@
</csc>
<!--<copy tofile="${build.dir}/${project::get-name()}.dll.config" file="App.config" />-->
- <!--<copy todir="${build.dir}" file="log4net.config"/>-->
+ <copy todir="${build.dir}" file="log4net.config"/>
</target>
<!-- Runs all of the tests in this module. -->
<target name="test" depends="build">
- <nunit2>
- <formatter type="${nant.formatter}" usefile="false" />
+ <nunit2 verbose="true">
+ <formatter type="${nant.formatter}" usefile="true" outputdir="${build.dir}/testresults/" extension="txt"/>
+ <formatter type="Plain" usefile="false"/>
<test>
<assemblies>
<include name="${build.dir}/${project::get-name()}.dll"/>
diff --git a/dotnet/Qpid.Integration.Tests/log4net.config b/dotnet/Qpid.Integration.Tests/log4net.config
new file mode 100644
index 0000000000..974f51c80d
--- /dev/null
+++ b/dotnet/Qpid.Integration.Tests/log4net.config
@@ -0,0 +1,48 @@
+<log4net>
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
+
+ <appender name="console" type="log4net.Appender.ConsoleAppender" >
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%m%n"/>
+ </layout>
+ <threshold value="info"/>
+ </appender>
+
+ <!-- ====================================== -->
+ <!-- Append messages to the socket appender -->
+ <!-- ====================================== -->
+
+ <appender name="UdpAppender" type="log4net.Appender.UdpAppender">
+ <remoteAddress value="127.0.0.1"/>
+ <remotePort value="4445"/>
+ <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
+ <locationInfo value="true"/>
+ </layout>
+ <threshold value="debug"/>
+ </appender>
+
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
+
+ <logger name="Qpid">
+ <level value="debug"/>
+ </logger>
+
+ <logger name="CONSOLE">
+ <level value="info"/>
+ <appender-ref ref="console"/>
+ </logger>
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <appender-ref ref="UdpAppender"/>
+ </root>
+
+</log4net> \ No newline at end of file
diff --git a/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs b/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs
index 8b1535c700..464c18a1d7 100644
--- a/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs
+++ b/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs
@@ -39,12 +39,27 @@ namespace Apache.Qpid.Integration.Tests.testcases
/// <summary> The default AMQ connection URL to use for tests. </summary>
const string connectionUri = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
+ /// <summary> The default AMQ connection URL parsed as a connection info. </summary>
+ protected IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
+
/// <summary> Holds the test connection. </summary>
protected IConnection _connection;
/// <summary> Holds the test channel. </summary>
protected IChannel _channel;
+ /// <summary> Holds an array of connections for building mutiple test end-points. </summary>
+ protected IConnection[] testConnection = new IConnection[2];
+
+ /// <summary> Holds an array of channels for building mutiple test end-points. </summary>
+ protected IChannel[] testChannel = new IChannel[2];
+
+ /// <summary> Holds an array of producers for building mutiple test end-points. </summary>
+ protected IMessagePublisher[] testProducer = new IMessagePublisher[2];
+
+ /// <summary> Holds an array of consumers for building mutiple test end-points. </summary>
+ protected IMessageConsumer[] testConsumer = new IMessageConsumer[2];
+
/// <summary>
/// Creates the test connection and channel.
/// </summary>
@@ -53,7 +68,6 @@ namespace Apache.Qpid.Integration.Tests.testcases
{
log.Debug("public virtual void Init(): called");
- IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
_connection = new AMQConnection(connectionInfo);
_channel = _connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 500, 300);
}
@@ -70,11 +84,62 @@ namespace Apache.Qpid.Integration.Tests.testcases
if (_connection != null)
{
log.Debug("Disposing connection.");
+ //_connection.Close();
_connection.Dispose();
log.Debug("Connection disposed.");
}
}
+ /// <summary> Sets up the nth test end-point. </summary>
+ public void SetUpEndPoint(int n, bool producer, bool consumer, string routingKey)
+ {
+ testConnection[n] = new AMQConnection(connectionInfo);
+ testConnection[n].Start();
+ testChannel[n] = testConnection[n].CreateChannel(true, AcknowledgeMode.AutoAcknowledge, 1);
+
+ if (producer)
+ {
+ testProducer[n] = testChannel[n].CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.DIRECT)
+ .WithRoutingKey(routingKey)
+ .Create();
+ }
+
+ if (consumer)
+ {
+ string queueName = testChannel[n].GenerateUniqueName();
+ testChannel[n].DeclareQueue(queueName, false, true, true);
+ testChannel[n].Bind(queueName, ExchangeNameDefaults.DIRECT, routingKey);
+ testConsumer[n] = testChannel[n].CreateConsumerBuilder(queueName)
+ .Create();
+ }
+ }
+
+ /// <summary> Closes down the nth test end-point. </summary>
+ public void CloseEndPoint(int n)
+ {
+ log.Debug("public void CloseEndPoint(int n): called");
+
+ if (testProducer[n] != null)
+ {
+ testProducer[n].Close();
+ testProducer[n].Dispose();
+ testProducer[n] = null;
+ }
+
+ if (testConsumer[n] != null)
+ {
+ testConsumer[n].Close();
+ testConsumer[n].Dispose();
+ testConsumer[n] = null;
+ }
+
+ testConnection[n].Stop();
+ testConnection[n].Close();
+ testConnection[n].Dispose();
+ testConnection[n] = null;
+ }
+
/// <summary>
/// Consumes n messages, checking that the n+1th is not available within a timeout, and that the consumed messages
/// are text messages with contents equal to the specified message body.
@@ -108,7 +173,7 @@ namespace Apache.Qpid.Integration.Tests.testcases
for (int i = 0; i < n; i++)
{
msg = consumer.Receive(500);
- Assert.IsNotNull(msg, "Consumer did not receive message number " + i);
+ Assert.IsNotNull(msg, "Consumer did not receive message number: " + i);
Assert.AreEqual(body, ((ITextMessage)msg).Text, "Incorrect Message recevied on consumer1.");
}
}
diff --git a/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs b/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs
new file mode 100644
index 0000000000..54f5518d35
--- /dev/null
+++ b/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs
@@ -0,0 +1,184 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// CommitRollbackTest
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Check that an uncommitted send cannot be received.
+ /// <tr><td> Check that a committed send can be received.
+ /// <tr><td> Check that a rolled back send cannot be received.
+ /// <tr><td> Check that an uncommitted receive can be re-received.
+ /// <tr><td> Check that a committed receive cannot be re-received.
+ /// <tr><td> Check that a rolled back receive can be re-received.
+ /// </table>
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class CommitRollbackTest : BaseMessagingTestFixture
+ {
+ /// <summary>Used for debugging purposes.</summary>
+ private static ILog log = LogManager.GetLogger(typeof(CommitRollbackTest));
+
+ /// <summary>Defines the name of the test topic to use with the tests.</summary>
+ public const string TEST_ROUTING_KEY = "commitrollbacktestkey";
+
+ /// <summary>A counter used to supply unique ids. </summary>
+ int uniqueId = 0;
+
+ /// <summary>Used to hold unique ids per test. </summary>
+ int testId;
+
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+
+ // Set up a unqiue id for this test.
+ testId = uniqueId++;
+
+ // Create one producer and one consumer, p2p, tx, consumer with queue bound to producers routing key.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId);
+ }
+
+ [TearDown]
+ public override void Shutdown()
+ {
+ try
+ {
+ // Clean up after the test.
+ CloseEndPoint(0);
+ CloseEndPoint(1);
+ }
+ finally
+ {
+ base.Shutdown();
+ }
+ }
+
+ /// <summary> Check that an uncommitted send cannot be received. </summary>
+ [Test]
+ public void TestUncommittedSendNotReceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(0, "A", testConsumer[1]);
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Check that a committed send can be received. </summary>
+ [Test]
+ public void TestCommittedSendReceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Check that a rolled back send cannot be received. </summary>
+ [Test]
+ public void TestRolledBackSendNotReceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ testChannel[0].Rollback();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(0, "A", testConsumer[1]);
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Check that an uncommitted receive can be re-received. </summary>
+ [Test]
+ public void TestUncommittedReceiveCanBeRereceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+
+ // Close end-point 1 without committing the message, then re-open to consume again.
+ CloseEndPoint(1);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId);
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+ }
+
+ /// <summary> Check that a committed receive cannot be re-received. </summary>
+ [Test]
+ public void TestCommittedReceiveNotRereceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+ testChannel[1].Commit();
+
+ // Close end-point 1 without committing the message, then re-open to consume again.
+ CloseEndPoint(1);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId);
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(0, "A", testConsumer[1]);
+ }
+
+ /// <summary> Check that a rolled back receive can be re-received. </summary>
+ [Test]
+ public void TestRolledBackReceiveCanBeRereceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+ testChannel[1].Rollback();
+
+ // Close end-point 1 without committing the message, then re-open to consume again.
+ CloseEndPoint(1);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId);
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+ }
+ }
+} \ No newline at end of file
diff --git a/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs b/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs
index 035dc81895..c6a78765f0 100644
--- a/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs
+++ b/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs
@@ -66,12 +66,14 @@ namespace Apache.Qpid.Integration.Tests.testcases
base.Shutdown();
}
}
-
+
+ [Test]
public void TestDurableSubscriptionNoAck()
{
TestDurableSubscription(AcknowledgeMode.NoAcknowledge);
}
+ [Test]
public void TestDurableSubscriptionAutoAck()
{
TestDurableSubscription(AcknowledgeMode.AutoAcknowledge);
diff --git a/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs b/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs
index 1cdacfe778..cb26bfdc55 100644
--- a/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs
+++ b/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs
@@ -27,11 +27,11 @@ using Apache.Qpid.Messaging;
namespace Apache.Qpid.Integration.Tests.testcases
{
- [TestFixture, Category("Integration")]
+ [TestFixture, Category("Integration")]
public class ProducerMultiConsumerTest : BaseMessagingTestFixture
{
private static readonly ILog _logger = LogManager.GetLogger(typeof(ProducerMultiConsumerTest));
-
+
private string _commandQueueName = "ServiceQ1";
private const int CONSUMER_COUNT = 5;
@@ -65,6 +65,7 @@ namespace Apache.Qpid.Integration.Tests.testcases
private int _messageReceivedCount = 0;
+ /*
[SetUp]
public override void Init()
{
@@ -90,6 +91,16 @@ namespace Apache.Qpid.Integration.Tests.testcases
}
_connection.Start();
}
+ */
+
+ /*
+ [TearDown]
+ public override void Shutdown()
+ {
+ _connection.Stop();
+ base.Shutdown();
+ }
+ */
public void OnMessage(IMessage m)
{
@@ -104,6 +115,7 @@ namespace Apache.Qpid.Integration.Tests.testcases
System.Diagnostics.Debug.WriteLine(((ITextMessage)m).Text);
}
+ /*
[Test]
public void RunTest()
{
@@ -123,5 +135,6 @@ namespace Apache.Qpid.Integration.Tests.testcases
}
_finishedEvent.WaitOne();
}
+ */
}
}
diff --git a/dotnet/Qpid.Integration.Tests/testcases/SyncConsumerTest.cs b/dotnet/Qpid.Integration.Tests/testcases/SyncConsumerTest.cs
index f813764cb1..0f3030a102 100644
--- a/dotnet/Qpid.Integration.Tests/testcases/SyncConsumerTest.cs
+++ b/dotnet/Qpid.Integration.Tests/testcases/SyncConsumerTest.cs
@@ -56,6 +56,7 @@ namespace Apache.Qpid.Integration.Tests.testcases
private IMessageConsumer _consumer;
private IMessagePublisher _publisher;
+ /*
[SetUp]
public override void Init()
{
@@ -77,7 +78,9 @@ namespace Apache.Qpid.Integration.Tests.testcases
.WithPrefetchLow(100).Create();
_connection.Start();
}
+ */
+ /*
[Test]
public void ReceiveWithInfiniteWait()
{
@@ -123,5 +126,6 @@ namespace Apache.Qpid.Integration.Tests.testcases
// empty queue, should timeout
Assert.IsNull(_consumer.Receive(1000));
}
+ */
}
}
diff --git a/dotnet/Qpid.Messaging/IChannel.cs b/dotnet/Qpid.Messaging/IChannel.cs
index 4da41a773d..10225d156b 100644
--- a/dotnet/Qpid.Messaging/IChannel.cs
+++ b/dotnet/Qpid.Messaging/IChannel.cs
@@ -31,7 +31,7 @@ namespace Apache.Qpid.Messaging
/// You can create a channel by using the CreateChannel() method
/// of the connection object.
/// </remarks>
- public interface IChannel : IDisposable
+ public interface IChannel : IDisposable, ICloseable
{
/// <summary>
/// Acknowledge mode for messages received
diff --git a/dotnet/Qpid.Messaging/ICloseable.cs b/dotnet/Qpid.Messaging/ICloseable.cs
new file mode 100644
index 0000000000..139dc8bf45
--- /dev/null
+++ b/dotnet/Qpid.Messaging/ICloseable.cs
@@ -0,0 +1,33 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Messaging
+{
+ /// <summary>An ICloseable is a resource that can be explicitly closed. Generally speaking a closed resource can no longer be used, and the
+ /// act of closing a resource is usually interpreted as a signal that the closed item can have its resource cleaned up and de-allocated.
+ /// </summary>
+ public interface ICloseable
+ {
+ /// <summary> Close the resource. </summary>
+ void Close();
+ }
+}
diff --git a/dotnet/Qpid.Messaging/IConnection.cs b/dotnet/Qpid.Messaging/IConnection.cs
index 420228fa8e..f664137e02 100644
--- a/dotnet/Qpid.Messaging/IConnection.cs
+++ b/dotnet/Qpid.Messaging/IConnection.cs
@@ -24,7 +24,7 @@ namespace Apache.Qpid.Messaging
{
public delegate void ExceptionListenerDelegate(Exception ex);
- public interface IConnection : IDisposable
+ public interface IConnection : IDisposable, ICloseable
{
/// <summary>
/// The connection listener that has been registered with this connection.
diff --git a/dotnet/Qpid.Messaging/IMessageConsumer.cs b/dotnet/Qpid.Messaging/IMessageConsumer.cs
index 82d697bf61..46cc681d92 100644
--- a/dotnet/Qpid.Messaging/IMessageConsumer.cs
+++ b/dotnet/Qpid.Messaging/IMessageConsumer.cs
@@ -22,35 +22,35 @@ using System;
namespace Apache.Qpid.Messaging
{
- /// <summary>
- /// Describes an object that can be used to receive (consume)
- /// messages from an AMQP queue.
- /// </summary>
- /// <remarks>
- /// Consumers are created using either
- /// <see cref="IChannel.CreateConsumer"/> or using
- /// the builder pattern (preferred) with
- /// <see cref="IChannel.CreateConsumerBuilder"/>.
- ///
- /// <para>
- /// Consumers offer two different ways of receiving messages:
- /// You can attach a delegate to the <see cref="OnMessage"/>
- /// event and be notified when a message arrives, or you can
- /// use the <see cref="Receive"/> and <see cref="ReceiveNoWait"/>
- /// methods to control when you receive messages. Be aware that you can use
- /// one or the other, but not both at the same time.
- /// </para>
- /// <para>
- /// Regardless of which method you choose, the prefetch settings
- /// specified when creating the channel will still control when messages
- /// are actually received from the AMQP broker. Any messages that arrive
- /// between the prefetch window will be queued by the channel
- /// until they can be delivered to the consumer (either though the event
- /// or until the consumer actively calls <see cref="Receive"/>).
- /// </para>
- /// </remarks>
- public interface IMessageConsumer : IDisposable
- {
+ /// <summary>
+ /// Describes an object that can be used to receive (consume)
+ /// messages from an AMQP queue.
+ /// </summary>
+ /// <remarks>
+ /// Consumers are created using either
+ /// <see cref="IChannel.CreateConsumer"/> or using
+ /// the builder pattern (preferred) with
+ /// <see cref="IChannel.CreateConsumerBuilder"/>.
+ ///
+ /// <para>
+ /// Consumers offer two different ways of receiving messages:
+ /// You can attach a delegate to the <see cref="OnMessage"/>
+ /// event and be notified when a message arrives, or you can
+ /// use the <see cref="Receive"/> and <see cref="ReceiveNoWait"/>
+ /// methods to control when you receive messages. Be aware that you can use
+ /// one or the other, but not both at the same time.
+ /// </para>
+ /// <para>
+ /// Regardless of which method you choose, the prefetch settings
+ /// specified when creating the channel will still control when messages
+ /// are actually received from the AMQP broker. Any messages that arrive
+ /// between the prefetch window will be queued by the channel
+ /// until they can be delivered to the consumer (either though the event
+ /// or until the consumer actively calls <see cref="Receive"/>).
+ /// </para>
+ /// </remarks>
+ public interface IMessageConsumer : IDisposable, ICloseable
+ {
/// <summary>
/// Fired when a message is received from the broker by the consumer
/// </summary>
diff --git a/dotnet/Qpid.Messaging/IMessagePublisher.cs b/dotnet/Qpid.Messaging/IMessagePublisher.cs
index fab0df0c2b..d895a9749b 100644
--- a/dotnet/Qpid.Messaging/IMessagePublisher.cs
+++ b/dotnet/Qpid.Messaging/IMessagePublisher.cs
@@ -32,7 +32,7 @@ namespace Apache.Qpid.Messaging
/// using the builder pattern (preferred) with
/// <see cref="IChannel.CreatePublisherBuilder"/>
/// </remarks>
- public interface IMessagePublisher : IDisposable
+ public interface IMessagePublisher : IDisposable, ICloseable
{
/// <summary>
/// Default delivery mode to use with this publisher