Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
//
// AssemblyInfo.cs
//
// Author:
// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
//
// (C) 2003 Ximian, Inc. http://www.ximian.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Reflection;
using System.Resources;
using System.Security;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about the System.Messaging assembly
[assembly: AssemblyTitle ("Mono.Messaging.RabbitMQ.dll")]
[assembly: AssemblyDescription ("Mono.Messaging.RabbitMQ.dll")]
[assembly: AssemblyDefaultAlias ("Mono.Messaging.RabbitMQ.dll")]
[assembly: AssemblyCompany (Consts.MonoCompany)]
[assembly: AssemblyProduct (Consts.MonoProduct)]
[assembly: AssemblyCopyright (Consts.MonoCopyright)]
[assembly: AssemblyVersion (Consts.FxVersion)]
[assembly: SatelliteContractVersion (Consts.FxVersion)]
[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
[assembly: NeutralResourcesLanguage ("en-US")]
[assembly: ComVisible (false)]
[assembly: CLSCompliant (false)]
[assembly: AssemblyDelaySign (true)]
[assembly: AssemblyKeyFile("../mono.pub")]
[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
[assembly: CompilationRelaxations (CompilationRelaxations.NoStringInterning)]

View File

@@ -0,0 +1,24 @@
2009-07-18 Michael Barker <mike@middlesoft.co.uk>
* AssemblyInfo.cs: Switch to mono.pub certificate for signing
assembly.
* Mono.Messaging.RabbitMQ_test_net_2_0.dll.config: New
2009-07-11 Michael Barker <mike@middlesoft.co.uk>
* Mono.Messaging.RabbitMQ_test.dll.sources: Moved MessageEnumeratorTest.cs
and MessageBaseTest.cs from Mono.Messaging.Test.
2009-01-05 Michael Barker <mike@middlesoft.co.uk>
* Makefile: Added nunit.mocks to test build
* Mono.Messaging.RabbitMQ_test.dll.sources: Added additional formatter
tests.
2008-09-29 Michael Barker <mike@middlesoft.co.uk>
* AssemblyInfo.cs: New
2009-05-19 Michael Barker <mike@middlesoft.co.uk>
* Makefile: Added environment variable for the RabbitMQMessagingProvider

View File

@@ -0,0 +1,17 @@
thisdir = class/Mono.Messaging.RabbitMQ
SUBDIRS =
include ../../build/rules.make
LIBRARY = Mono.Messaging.RabbitMQ.dll
LIB_MCS_FLAGS = /r:System.dll \
/r:System.Messaging.dll \
/r:Mono.Messaging.dll \
/r:RabbitMQ.Client \
-nowarn:618
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -nowarn:0618 -nowarn:219 -nowarn:169 \
/r:nunit.mocks.dll
include ../../build/library.make
export MONO_MESSAGING_PROVIDER=Mono.Messaging.RabbitMQ.RabbitMQMessagingProvider,Mono.Messaging.RabbitMQ

View File

@@ -0,0 +1,12 @@
./Assembly/AssemblyInfo.cs
../../build/common/Consts.cs
../../build/common/Locale.cs
./Mono.Messaging.RabbitMQ/IMessagingContext.cs
./Mono.Messaging.RabbitMQ/MessageFactory.cs
./Mono.Messaging.RabbitMQ/MessagingContext.cs
./Mono.Messaging.RabbitMQ/MessagingContextPool.cs
./Mono.Messaging.RabbitMQ/RabbitMQMessageEnumerator.cs
./Mono.Messaging.RabbitMQ/RabbitMQMessageQueue.cs
./Mono.Messaging.RabbitMQ/RabbitMQMessageQueueTransaction.cs
./Mono.Messaging.RabbitMQ/RabbitMQMessagingProvider.cs

View File

@@ -0,0 +1,78 @@
2010-06-23 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: Modified to support RabbitMQ 1.8
* RabbitMQMessageEnumerator.cs: Modified to support RabbitMQ 1.8
2009-07-14 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: Refactored, removed dead code and renamed methods.
2009-07-11 Michael Barker <mike@middlesoft.co.uk>
* MessageFactory.cs: Switched to DateTime.UtcNow.
* RabbitMQMessageQueue.cs: Removed some unecessary references to realm.
* RabbitMQMessagingProvider.cs: Removed some unecessary references to realm.
Changed volatile field to use Interlocked.Increment (++i is not thread safe).
2009-05-23 Michael Barker <mike@middlesoft.co.uk>
* MessageFactory.cs: Moved TimeSpanToInt32 method to here.
* RabbitMQMessageEnumerator.cs: Added Remove/MoveNext methods that include
timeouts.
* RabbitMQMessageQueue.cs: Updated to cater for moved TimeSpanToInt32 method
2009-05-20 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageEnumerator.cs: Removed references to realms & tickets.
* RabbitMQMessageQueue.cs: Removed references to realms & tickets.
2009-05-19 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: Added comments.
2008-12-22 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: Changed to extend MessageQueueBase to make use
of default asynchronous Receive/Peek methods.
2008-12-07 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: Throw MessageUnavailableException when there are
no messages.
2008-11-23 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: Added selector support for ReceiveBy{Id,CorrelationId}
and support for MessageQueueTransactionType, currently only None and Single
are supported. Added PeekBy{Id,CorrelationId} methods.
* MessageFactory.cs: Made read/write message methods non-static and requires
the MessagingProvider as a constructor parameter.
2008-11-02 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueueTransaction.cs: New, Handles transactional delivery
by maintaining the transaction context.
* RabbitMQMessageQueue.cs: Added support for transactions, purging, deleting
and refactored some of the methods to improve the code reuse.
* RabbitMQMessagingProvider.cs: Added methods for queue deletion and
creating transactions.
2008-10-26 Michael Barker <mike@middlesoft.co.uk>
* MessageFactory.cs: Support all properties defined in the 1.1 version of
System.Messaging, including Recoverable and Priority. Changed Timestamp
conversion methods to support .NET 1.1 compilation.
* RabbitMQMessageQueue.cs: Removed unnecessary constants.
2008-10-12 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageEnumerator.cs: New
* MessageFactory.cs: Utility class for creating MessageBase objects from
serialized data off the queue.
* RabbitMQMessageQueue.cs: Using MessageFactory methods to handle message
serialization.
2008-09-29 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessageQueue.cs: New
* RabbitMQMessagingProvider.cs: New

View File

@@ -0,0 +1,63 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Util;
namespace Mono.Messaging.RabbitMQ {
/// <summary>
/// </summary>
public interface IMessagingContext : IDisposable {
IMessage Receive (QueueReference qRef, TimeSpan timeout, IsMatch matcher, bool ack);
void Send (QueueReference qRef, IMessage msg);
// IConnection Connection { get; }
// IModel Model { get; }
void Delete (QueueReference qRef);
void Purge (QueueReference qRef);
}
public delegate bool IsMatch (BasicDeliverEventArgs result);
public delegate IConnection CreateConnectionDelegate (string host);
}

View File

@@ -0,0 +1,231 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.IO;
using System.Text;
using Mono.Messaging;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Util;
namespace Mono.Messaging.RabbitMQ {
public class MessageFactory {
private static readonly string SENDER_VERSION_KEY = "SenderVersion";
private static readonly string SOURCE_MACHINE_KEY = "SourceMachine";
private static readonly string BODY_TYPE_KEY = "BodyType";
private static readonly string ACKNOWLEDGE_TYPE_KEY = "AcknowledgeType";
private static readonly string ADMINISTRATION_QUEUE_KEY = "AdministrationQueue";
private static readonly string APP_SPECIFIC_KEY = "AppSpecific";
private static readonly string AUTHENTICATION_PROVIDER_NAME_KEY = "AuthenticationProviderName";
private static readonly string AUTHENTICATION_PROVIDER_TYPE_KEY = "AuthenticationProviderType";
private static readonly string CONNECTOR_TYPE_KEY = "ConnectorType";
private static readonly string DESTINATION_SYMMETRIC_KEY_KEY = "DestinationSymmetricKey";
private static readonly string DIGITAL_SIGNATURE_KEY = "DigitalSignature";
private static readonly string ENCRYPTION_ALGORITHM_KEY = "EncryptionAlgorithm";
private static readonly string EXTENSION_KEY = "Extension";
private static readonly string HASH_ALGORITHM_KEY = "HashAlgorithm";
private static readonly string LABEL_KEY = "Label";
private static readonly string SENDER_CERTIFICATE_KEY = "SenderCertificate";
private static readonly string TIME_TO_BE_RECEIVED_KEY = "TimeToBeReceived";
private static readonly string TIME_TO_REACH_QUEUE_KEY = "TimeToReachQueue";
private static readonly string USE_AUTHENTICATION_KEY = "UseAuthentication";
private static readonly string USE_DEAD_LETTER_QUEUE_KEY = "UseDeadLetterQueue";
private static readonly string USE_ENCRYPTION_KEY = "UseEncryption";
private static readonly string TRANSACTION_ID_KEY = "TrandactionId";
private static readonly int PERSISTENT_DELIVERY_MODE = 2;
private readonly RabbitMQMessagingProvider provider;
public MessageFactory (RabbitMQMessagingProvider provider)
{
this.provider = provider;
}
public IMessageBuilder WriteMessage (IModel ch, IMessage msg)
{
BasicMessageBuilder mb = new BasicMessageBuilder (ch);
mb.Properties.MessageId = msg.Id;
if (msg.CorrelationId != null)
mb.Properties.CorrelationId = msg.CorrelationId;
// TODO: Change to DateTime.UtcNow??
mb.Properties.Timestamp = MessageFactory.DateTimeToAmqpTimestamp (DateTime.UtcNow);
Hashtable headers = new Hashtable ();
headers[SENDER_VERSION_KEY] = msg.SenderVersion;
headers[SOURCE_MACHINE_KEY] = (string) System.Environment.MachineName;
headers[BODY_TYPE_KEY] = msg.BodyType;
headers[ACKNOWLEDGE_TYPE_KEY] = (int) msg.AcknowledgeType;
if (msg.AdministrationQueue != null)
headers[ADMINISTRATION_QUEUE_KEY] = msg.AdministrationQueue.QRef.ToString ();
headers[APP_SPECIFIC_KEY] = msg.AppSpecific;
headers[AUTHENTICATION_PROVIDER_NAME_KEY] = msg.AuthenticationProviderName;
headers[AUTHENTICATION_PROVIDER_TYPE_KEY] = (int) msg.AuthenticationProviderType;
headers[CONNECTOR_TYPE_KEY] = msg.ConnectorType.ToString ();
headers[DESTINATION_SYMMETRIC_KEY_KEY] = msg.DestinationSymmetricKey;
headers[DIGITAL_SIGNATURE_KEY] = msg.DigitalSignature;
headers[ENCRYPTION_ALGORITHM_KEY] = (int) msg.EncryptionAlgorithm;
headers[EXTENSION_KEY] = msg.Extension;
headers[HASH_ALGORITHM_KEY] = (int) msg.HashAlgorithm;
SetValue (headers, LABEL_KEY, msg.Label);
mb.Properties.Priority = (byte) (int) msg.Priority;
mb.Properties.SetPersistent (msg.Recoverable);
if (msg.ResponseQueue != null)
mb.Properties.ReplyTo = msg.ResponseQueue.QRef.ToString ();
headers[SENDER_CERTIFICATE_KEY] = msg.SenderCertificate;
headers[TIME_TO_BE_RECEIVED_KEY] = msg.TimeToBeReceived.Ticks;
headers[TIME_TO_REACH_QUEUE_KEY] = msg.TimeToReachQueue.Ticks;
SetValue (headers, TRANSACTION_ID_KEY, msg.TransactionId);
headers[USE_AUTHENTICATION_KEY] = msg.UseAuthentication;
headers[USE_DEAD_LETTER_QUEUE_KEY] = msg.UseDeadLetterQueue;
headers[USE_ENCRYPTION_KEY] = msg.UseEncryption;
mb.Properties.Headers = headers;
Stream s = msg.BodyStream;
s.Seek (0, SeekOrigin.Begin);
byte[] buf = new byte[s.Length];
msg.BodyStream.Read (buf, 0, buf.Length);
mb.BodyStream.Write (buf, 0, buf.Length);
return mb;
}
private static void SetValue (Hashtable headers, string name, object val)
{
if (val != null)
headers[name] = val;
}
public IMessage ReadMessage (QueueReference destination, BasicDeliverEventArgs result)
{
/*
if (destination == null)
throw new ArgumentException ("destination must not be null");
if (result == null)
throw new ArgumentException ("result must not be null");
*/
MessageBase msg = new MessageBase ();
Stream s = new MemoryStream ();
s.Write (result.Body, 0, result.Body.Length);
DateTime arrivedTime = DateTime.Now;
IDictionary headers = result.BasicProperties.Headers;
long senderVersion = (long) headers[SENDER_VERSION_KEY];
string sourceMachine = GetString (headers, SOURCE_MACHINE_KEY);
DateTime sentTime = AmqpTimestampToDateTime (result.BasicProperties.Timestamp);
string transactionId = GetString (headers, TRANSACTION_ID_KEY);
msg.SetDeliveryInfo (Acknowledgment.None,
arrivedTime,
new RabbitMQMessageQueue (provider,
destination,
true),
result.BasicProperties.MessageId,
MessageType.Normal,
new byte[0],
senderVersion,
sentTime,
sourceMachine,
transactionId);
msg.CorrelationId = result.BasicProperties.CorrelationId;
msg.BodyStream = s;
msg.BodyType = (int) result.BasicProperties.Headers[BODY_TYPE_KEY];
msg.AcknowledgeType = (AcknowledgeTypes)
Enum.ToObject (typeof (AcknowledgeTypes),
headers[ACKNOWLEDGE_TYPE_KEY]);
string adminQueuePath = GetString (headers, ADMINISTRATION_QUEUE_KEY);
if (adminQueuePath != null) {
QueueReference qRef = QueueReference.Parse (adminQueuePath);
msg.AdministrationQueue = new RabbitMQMessageQueue (provider,
qRef,
true);
}
msg.AppSpecific = (int) headers[APP_SPECIFIC_KEY];
msg.AuthenticationProviderName = GetString (headers, AUTHENTICATION_PROVIDER_NAME_KEY);
msg.AuthenticationProviderType = (CryptographicProviderType) Enum.ToObject (typeof (CryptographicProviderType), headers[AUTHENTICATION_PROVIDER_TYPE_KEY]);
string connectorType = GetString (headers, CONNECTOR_TYPE_KEY);
msg.ConnectorType = new Guid(connectorType);
msg.DestinationSymmetricKey = (byte[]) headers[DESTINATION_SYMMETRIC_KEY_KEY];
msg.DigitalSignature = (byte[]) headers[DIGITAL_SIGNATURE_KEY];
msg.EncryptionAlgorithm = (EncryptionAlgorithm) Enum.ToObject (typeof (EncryptionAlgorithm), headers[ENCRYPTION_ALGORITHM_KEY]);
msg.Extension = (byte[]) headers[EXTENSION_KEY];
msg.HashAlgorithm = (HashAlgorithm) Enum.ToObject (typeof (HashAlgorithm), headers[HASH_ALGORITHM_KEY]);
msg.Label = GetString (headers, LABEL_KEY);
msg.Priority = (MessagePriority) Enum.ToObject (typeof (MessagePriority), result.BasicProperties.Priority);
msg.Recoverable = result.BasicProperties.DeliveryMode == PERSISTENT_DELIVERY_MODE;
if (result.BasicProperties.ReplyTo != null)
msg.ResponseQueue = new RabbitMQMessageQueue (provider, QueueReference.Parse (result.BasicProperties.ReplyTo), true);
msg.SenderCertificate = (byte[]) headers[SENDER_CERTIFICATE_KEY];
msg.TimeToBeReceived = new TimeSpan((long) headers[TIME_TO_BE_RECEIVED_KEY]);
msg.TimeToReachQueue = new TimeSpan((long) headers[TIME_TO_REACH_QUEUE_KEY]);
msg.UseAuthentication = (bool) headers[USE_AUTHENTICATION_KEY];
msg.UseDeadLetterQueue = (bool) headers[USE_DEAD_LETTER_QUEUE_KEY];
msg.UseEncryption = (bool) headers[USE_ENCRYPTION_KEY];
return msg;
}
public static string GetString (IDictionary properties, String key)
{
byte[] b = (byte[]) properties[key];
if (b == null)
return null;
return Encoding.UTF8.GetString (b);
}
public static AmqpTimestamp DateTimeToAmqpTimestamp (DateTime t)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan ts = t.ToUniversalTime () - epoch;
return new AmqpTimestamp((long) ts.TotalSeconds);
}
public static DateTime AmqpTimestampToDateTime (AmqpTimestamp ats)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return epoch.AddSeconds (ats.UnixTime).ToLocalTime ();
}
public static int TimeSpanToMillis (TimeSpan timespan)
{
if (timespan == TimeSpan.MaxValue)
return -1;
else
return (int) timespan.TotalMilliseconds;
}
}
}

View File

@@ -0,0 +1,212 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Util;
namespace Mono.Messaging.RabbitMQ {
/// <summary>
/// A context containing a connection and a model, holds state information
/// regarding current messaging context.
///
/// Do not share across threads.
/// </summary>
public class MessagingContext : IMessagingContext {
private readonly MessageFactory helper;
private readonly CreateConnectionDelegate createConnection;
private IConnection cn;
private MessagingContextPool contextPool = null;
private IModel model = null;
private String host = null;
private bool isDisposed = false;
private Object syncObj = new Object ();
public MessagingContext (MessageFactory factory, string host, CreateConnectionDelegate createConnection)
{
this.helper = factory;
this.host = host;
this.createConnection = createConnection;
}
public IConnection Connection {
get {
if (null == cn) {
cn = createConnection (host);
}
return cn;
}
}
public IModel Model {
get {
if (null == model) {
model = Connection.CreateModel ();
}
return model;
}
}
internal MessagingContextPool Pool {
set { contextPool = value; }
get { return contextPool; }
}
internal string Host {
set {
if (host != value) {
ResetConnection ();
host = value;
}
}
get { return host; }
}
public IMessage Receive (QueueReference qRef, TimeSpan timeout, IsMatch matcher, bool ack)
{
if (matcher == null)
{
return Receive (qRef, MessageFactory.TimeSpanToMillis (timeout), ack);
}
else
{
return ReceiveWithMatcher (qRef, MessageFactory.TimeSpanToMillis (timeout), matcher, ack);
}
}
private IMessage Receive (QueueReference qRef, int timeout, bool ack)
{
IModel _model = Model;
string finalName = _model.QueueDeclare (qRef.Queue, false);
using (Subscription sub = new Subscription (_model, finalName)) {
BasicDeliverEventArgs result;
if (sub.Next (timeout, out result)) {
IMessage m = helper.ReadMessage (qRef, result);
if (ack)
sub.Ack (result);
return m;
} else {
throw new MonoMessagingException ("No Message Available");
}
}
}
private IMessage ReceiveWithMatcher (QueueReference qRef, int timeout, IsMatch matcher, bool ack)
{
IModel _model = Model;
string finalName = _model.QueueDeclare (qRef.Queue, false);
using (Subscription sub = new Subscription (_model, finalName)) {
BasicDeliverEventArgs result;
while (sub.Next (timeout, out result)) {
if (matcher (result)) {
IMessage m = helper.ReadMessage (qRef, result);
if (ack)
sub.Ack (result);
return m;
}
}
throw new MessageUnavailableException ("Message not available");
}
}
public void Send (QueueReference qRef, IMessage message)
{
IModel _model = Model;
string finalName = _model.QueueDeclare (qRef.Queue, false);
IMessageBuilder mb = helper.WriteMessage (_model, message);
model.BasicPublish ("", finalName,
(IBasicProperties) mb.GetContentHeader (),
mb.GetContentBody ());
}
public void Delete (QueueReference qRef)
{
Model.QueueDelete (qRef.Queue, false, false, false);
}
public void Purge (QueueReference qRef)
{
Model.QueuePurge (qRef.Queue, false);
}
public void Dispose ()
{
if (model != null) {
model.Close ();
model = null;
}
if (null != contextPool) {
contextPool.ReturnContext (this);
return;
}
Dispose (true);
GC.SuppressFinalize (this);
}
private void ResetConnection ()
{
if (cn != null)
cn.Dispose ();
}
protected virtual void Dispose (bool disposing)
{
lock (syncObj) {
if (!isDisposed && disposing) {
isDisposed = true;
ResetConnection ();
}
}
}
}
}

View File

@@ -0,0 +1,74 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Text;
using RabbitMQ.Client;
namespace Mono.Messaging.RabbitMQ {
public class MessagingContextPool
{
private readonly CreateConnectionDelegate createConnectionDelegate;
private readonly ConcurrentLinkedQueue<MessagingContext> pool =
new ConcurrentLinkedQueue<MessagingContext>();
private readonly MessageFactory messageFactory;
public MessagingContextPool (MessageFactory messageFactory,
CreateConnectionDelegate createConnectionDelegate)
{
this.messageFactory = messageFactory;
this.createConnectionDelegate = createConnectionDelegate;
}
public MessagingContext GetContext (string host)
{
MessagingContext context = pool.Dequeue ();
if (context == null) {
context = new MessagingContext (messageFactory, host, createConnectionDelegate);
context.Pool = this;
}
context.Host = host;
return context;
}
public void ReturnContext (MessagingContext context)
{
pool.Enqueue (context);
}
}
}

View File

@@ -0,0 +1,195 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using Mono.Messaging;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Util;
namespace Mono.Messaging.RabbitMQ {
public class RabbitMQMessageEnumerator : IMessageEnumerator {
private readonly MessageFactory helper;
private readonly QueueReference qRef;
private IConnection cn = null;
private BasicDeliverEventArgs current = null;
private IModel model = null;
private Subscription subscription = null;
public RabbitMQMessageEnumerator (MessageFactory helper,
QueueReference qRef) {
this.helper = helper;
this.qRef = qRef;
}
public IMessage Current {
get {
if (current == null)
throw new InvalidOperationException ();
return CreateMessage (current);
}
}
public IntPtr CursorHandle {
get { throw new NotImplementedException (); }
}
public void Close ()
{
if (subscription != null) {
subscription.Close ();
subscription = null;
}
if (model != null) {
model.Dispose ();
model = null;
}
if (cn != null) {
cn.Dispose ();
cn = null;
}
}
public void Dispose (bool disposing)
{
}
public void Dispose ()
{
Close ();
}
public void Reset ()
{
Close ();
}
private IModel Model {
get {
if (cn == null) {
ConnectionFactory cf = new ConnectionFactory ();
cf.Address = qRef.Host;
cn = cf.CreateConnection ();
}
if (model == null) {
model = cn.CreateModel ();
}
return model;
}
}
private Subscription Subscription {
get {
if (subscription == null) {
IModel ch = Model;
string finalName = ch.QueueDeclare (qRef.Queue, false);
subscription = new Subscription (ch, finalName);
}
return subscription;
}
}
public bool MoveNext ()
{
Subscription sub = Subscription;
return sub.Next (500, out current);
}
public bool MoveNext (TimeSpan timeout)
{
int timeoutMillis = MessageFactory.TimeSpanToMillis (timeout);
return Subscription.Next (timeoutMillis, out current);
}
public IMessage RemoveCurrent ()
{
if (current == null)
throw new InvalidOperationException ();
IMessage msg = CreateMessage (current);
Subscription.Ack (current);
return msg;
}
public IMessage RemoveCurrent (IMessageQueueTransaction transaction)
{
throw new NotSupportedException ("Unable to remove messages within a transaction");
}
public IMessage RemoveCurrent (MessageQueueTransactionType transactionType)
{
throw new NotSupportedException ("Unable to remove messages within a transaction");
}
public IMessage RemoveCurrent (TimeSpan timeout)
{
// Timeout makes no sense for this implementation, so we just work
// the same as the non-timeout based one.
if (current == null)
throw new InvalidOperationException ();
IMessage msg = CreateMessage (current);
Subscription.Ack (current);
return msg;
}
public IMessage RemoveCurrent (TimeSpan timeout, IMessageQueueTransaction transaction)
{
throw new NotSupportedException ("Unable to remove messages within a transaction");
}
public IMessage RemoveCurrent (TimeSpan timeout, MessageQueueTransactionType transactionType)
{
throw new NotSupportedException ("Unable to remove messages within a transaction");
}
private IMessage CreateMessage (BasicDeliverEventArgs result)
{
return helper.ReadMessage (qRef, result);
}
}
}

View File

@@ -0,0 +1,490 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Util;
namespace Mono.Messaging.RabbitMQ {
/// <summary>
/// RabbitMQ Implementation of a message queue. Currrently this implementation
/// attempts to be as stateless as possible. Connection the AMQP server
/// are only created as needed.
/// </summary>
public class RabbitMQMessageQueue : MessageQueueBase, IMessageQueue {
private readonly RabbitMQMessagingProvider provider;
private readonly MessageFactory helper;
private readonly bool transactional;
private readonly TimeSpan noTime = new TimeSpan(0, 0, 0, 0, 500);
private bool authenticate = false;
private short basePriority = 0;
private Guid category = Guid.Empty;
private bool denySharedReceive = false;
private EncryptionRequired encryptionRequired;
private long maximumJournalSize = -1;
private long maximumQueueSize = -1;
private ISynchronizeInvoke synchronizingObject = null;
private bool useJournalQueue = false;
private QueueReference qRef = QueueReference.DEFAULT;
public RabbitMQMessageQueue (RabbitMQMessagingProvider provider,
bool transactional)
: this (provider, QueueReference.DEFAULT, transactional)
{
}
public RabbitMQMessageQueue (RabbitMQMessagingProvider provider,
QueueReference qRef,
bool transactional)
{
this.provider = provider;
this.helper = new MessageFactory (provider);
this.qRef = qRef;
this.transactional = transactional;
}
protected override IMessageQueue Queue {
get { return this; }
}
public bool Authenticate {
get { return authenticate; }
set { authenticate = value; }
}
public short BasePriority {
get { return basePriority; }
set { basePriority = value; }
}
public bool CanRead {
get { throw new NotImplementedException (); }
}
public bool CanWrite {
get { throw new NotImplementedException (); }
}
public Guid Category {
get { return category; }
set { category = value; }
}
public DateTime CreateTime {
get { throw new NotImplementedException (); }
}
public bool DenySharedReceive {
get { return denySharedReceive; }
set { denySharedReceive = value; }
}
public EncryptionRequired EncryptionRequired {
get { return encryptionRequired; }
set { encryptionRequired = value; }
}
public Guid Id {
get { throw new NotImplementedException (); }
}
public DateTime LastModifyTime {
get { throw new NotImplementedException (); }
}
public long MaximumJournalSize {
get { return maximumJournalSize; }
set { maximumJournalSize = value; }
}
public long MaximumQueueSize {
get { return maximumQueueSize; }
set { maximumQueueSize = value; }
}
public IntPtr ReadHandle {
get { throw new NotImplementedException (); }
}
public ISynchronizeInvoke SynchronizingObject {
get { return synchronizingObject; }
set { synchronizingObject = value; }
}
public bool Transactional {
get { return transactional; }
}
public bool UseJournalQueue {
get { return useJournalQueue; }
set { useJournalQueue = value; }
}
public IntPtr WriteHandle {
get { throw new NotImplementedException (); }
}
public QueueReference QRef {
get { return qRef; }
set { qRef = value; }
}
private void SetDeliveryInfo (IMessage msg, string transactionId)
{
msg.SetDeliveryInfo (Acknowledgment.None,
DateTime.MinValue,
this,
Guid.NewGuid ().ToString () + "\\0",
MessageType.Normal,
new byte[0],
0,
DateTime.UtcNow,
null,
transactionId);
}
public void Close ()
{
}
public static void Delete (QueueReference qRef)
{
RabbitMQMessagingProvider provider = (RabbitMQMessagingProvider) MessagingProviderLocator.GetProvider ();
using (IMessagingContext context = provider.CreateContext (qRef.Host)) {
context.Delete (qRef);
}
}
public void Send (IMessage msg)
{
if (QRef == QueueReference.DEFAULT)
throw new MonoMessagingException ("Path has not been specified");
if (msg.BodyStream == null)
throw new ArgumentException ("BodyStream is null, Message is not serialized properly");
using (IMessagingContext context = CurrentContext) {
try {
SetDeliveryInfo (msg, null);
context.Send (QRef, msg);
} catch (BrokerUnreachableException e) {
throw new ConnectionException (QRef, e);
}
}
}
public void Send (IMessage msg, IMessageQueueTransaction transaction)
{
if (QRef == QueueReference.DEFAULT)
throw new MonoMessagingException ("Path has not been specified");
if (msg.BodyStream == null)
throw new ArgumentException ("Message is not serialized properly");
RabbitMQMessageQueueTransaction tx = (RabbitMQMessageQueueTransaction) transaction;
SetDeliveryInfo (msg, tx.Id);
tx.Send (QRef, msg);
}
public void Send (IMessage msg, MessageQueueTransactionType transactionType)
{
switch (transactionType) {
case MessageQueueTransactionType.Single:
using (IMessageQueueTransaction tx = NewTx ()) {
try {
Send (msg, tx);
tx.Commit ();
} catch (Exception e) {
tx.Abort ();
throw new MonoMessagingException(e.Message, e);
}
}
break;
case MessageQueueTransactionType.None:
Send (msg);
break;
case MessageQueueTransactionType.Automatic:
throw new NotSupportedException("Automatic transaction types not supported");
}
}
public void Purge ()
{
using (IMessagingContext context = CurrentContext) {
context.Purge (QRef);
}
}
public IMessage Peek ()
{
return DoReceive (TimeSpan.MaxValue, null, false);
}
public IMessage Peek (TimeSpan timeout)
{
return DoReceive (timeout, null, false);
}
public IMessage PeekById (string id)
{
return DoReceive (noTime, ById (id), false);
}
public IMessage PeekById (string id, TimeSpan timeout)
{
return DoReceive (timeout, ById (id), false);
}
public IMessage PeekByCorrelationId (string id)
{
return DoReceive (noTime, ByCorrelationId (id), false);
}
public IMessage PeekByCorrelationId (string id, TimeSpan timeout)
{
return DoReceive (timeout, ByCorrelationId (id), false);
}
public IMessage Receive ()
{
return DoReceive (TimeSpan.MaxValue, null, true);
}
public IMessage Receive (TimeSpan timeout)
{
return DoReceive (timeout, null, true);
}
public IMessage Receive (TimeSpan timeout,
IMessageQueueTransaction transaction)
{
return DoReceive (transaction, timeout, null, true);
}
public IMessage Receive (TimeSpan timeout,
MessageQueueTransactionType transactionType)
{
return DoReceive (transactionType, timeout, null, true);
}
public IMessage Receive (IMessageQueueTransaction transaction)
{
return DoReceive (transaction, TimeSpan.MaxValue, null, true);
}
public IMessage Receive (MessageQueueTransactionType transactionType)
{
return DoReceive (transactionType, TimeSpan.MaxValue, null, true);
}
public IMessage ReceiveById (string id)
{
return DoReceive (noTime, ById (id), true);
}
public IMessage ReceiveById (string id, TimeSpan timeout)
{
return DoReceive (timeout, ById (id), true);
}
public IMessage ReceiveById (string id,
IMessageQueueTransaction transaction)
{
return DoReceive (transaction, noTime, ById (id), true);
}
public IMessage ReceiveById (string id,
MessageQueueTransactionType transactionType)
{
return DoReceive (transactionType, noTime, ById (id), true);
}
public IMessage ReceiveById (string id, TimeSpan timeout,
IMessageQueueTransaction transaction)
{
return DoReceive (transaction, timeout, ById (id), true);
}
public IMessage ReceiveById (string id, TimeSpan timeout,
MessageQueueTransactionType transactionType)
{
return DoReceive (transactionType, timeout, ById (id), true);
}
public IMessage ReceiveByCorrelationId (string id)
{
return DoReceive (noTime, ByCorrelationId (id), true);
}
public IMessage ReceiveByCorrelationId (string id, TimeSpan timeout)
{
return DoReceive (timeout, ByCorrelationId (id), true);
}
public IMessage ReceiveByCorrelationId (string id,
IMessageQueueTransaction transaction)
{
return DoReceive (transaction, noTime, ByCorrelationId (id), true);
}
public IMessage ReceiveByCorrelationId (string id,
MessageQueueTransactionType transactionType)
{
return DoReceive (transactionType, noTime, ByCorrelationId (id), true);
}
public IMessage ReceiveByCorrelationId (string id, TimeSpan timeout,
IMessageQueueTransaction transaction)
{
return DoReceive (transaction, timeout, ByCorrelationId (id), true);
}
public IMessage ReceiveByCorrelationId (string id, TimeSpan timeout,
MessageQueueTransactionType transactionType)
{
return DoReceive (transactionType, timeout, ByCorrelationId (id), true);
}
public IMessageEnumerator GetMessageEnumerator ()
{
return new RabbitMQMessageEnumerator (helper, QRef);
}
private IMessage DoReceive (MessageQueueTransactionType transactionType,
TimeSpan timeout, IsMatch matcher, bool ack)
{
switch (transactionType) {
case MessageQueueTransactionType.Single:
using (RabbitMQMessageQueueTransaction tx = NewTx ()) {
bool success = false;
try {
IMessage msg = DoReceive ((IMessagingContext) tx, timeout, matcher, ack);
tx.Commit ();
success = true;
return msg;
} finally {
if (!success)
tx.Abort ();
}
}
case MessageQueueTransactionType.None:
return DoReceive (timeout, matcher, true);
default:
throw new NotSupportedException (transactionType + " not supported");
}
}
private IMessage DoReceive (IMessageQueueTransaction transaction,
TimeSpan timeout, IsMatch matcher, bool ack)
{
RabbitMQMessageQueueTransaction tx = (RabbitMQMessageQueueTransaction) transaction;
return DoReceive ((IMessagingContext) tx, timeout, matcher, ack);
}
private IMessage DoReceive (TimeSpan timeout, IsMatch matcher, bool ack)
{
using (IMessagingContext context = CurrentContext) {
return DoReceive (context, timeout, matcher, ack);
}
}
private IMessage DoReceive (IMessagingContext context, TimeSpan timeout,
IsMatch matcher, bool ack)
{
return context.Receive (QRef, timeout, matcher, ack);
}
private IMessagingContext CurrentContext {
get {
return provider.CreateContext (qRef.Host);
}
}
private class IdMatcher
{
private readonly string id;
public IdMatcher (string id)
{
this.id = id;
}
public bool MatchById (BasicDeliverEventArgs result)
{
return result.BasicProperties.MessageId == id;
}
}
private static IsMatch ById (string id)
{
return new IdMatcher (id).MatchById;
}
private class CorrelationIdMatcher
{
private readonly string correlationId;
public CorrelationIdMatcher (string correlationId)
{
this.correlationId = correlationId;
}
public bool MatchById (BasicDeliverEventArgs result)
{
return result.BasicProperties.CorrelationId == correlationId;
}
}
private static IsMatch ByCorrelationId (string correlationId)
{
return new CorrelationIdMatcher (correlationId).MatchById;
}
private RabbitMQMessageQueueTransaction NewTx ()
{
return (RabbitMQMessageQueueTransaction) provider.CreateMessageQueueTransaction ();
}
}
}

View File

@@ -0,0 +1,185 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Text;
using Mono.Messaging;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Util;
namespace Mono.Messaging.RabbitMQ {
public class RabbitMQMessageQueueTransaction : IMessageQueueTransaction, IMessagingContext {
private readonly string txId;
private readonly MessagingContextPool contextPool;
private MessageQueueTransactionStatus status = MessageQueueTransactionStatus.Initialized;
private String host = null;
private bool isDisposed = false;
private Object syncObj = new Object ();
private bool isActive = false;
private MessagingContext context = null;
public RabbitMQMessageQueueTransaction (string txId, MessagingContextPool contextPool)
{
this.txId = txId;
this.contextPool = contextPool;
}
private IModel Model {
get { return Context.Model; }
}
private IConnection Connection {
get { return Context.Connection; }
}
private MessagingContext Context {
get {
if (null == context) {
context = contextPool.GetContext (host);
}
return context;
}
}
public IMessage Receive (QueueReference qRef, TimeSpan timeout, IsMatch matcher, bool ack)
{
lock (syncObj) {
ValidateHost (qRef);
Model.TxSelect ();
isActive = true;
return Context.Receive (qRef, timeout, matcher, ack);
}
}
public void Send (QueueReference qRef, IMessage msg)
{
lock (syncObj) {
ValidateHost (qRef);
Model.TxSelect ();
isActive = true;
Context.Send (qRef, msg);
}
}
private void ValidateHost (QueueReference qRef)
{
if (null == host) {
host = qRef.Host;
} else if (host != qRef.Host) {
throw new MonoMessagingException ("Transactions can not span multiple hosts");
}
}
public MessageQueueTransactionStatus Status {
get {
lock (syncObj)
return status;
}
}
public void Abort ()
{
lock (syncObj) {
if (isActive)
Context.Model.TxRollback ();
status = MessageQueueTransactionStatus.Aborted;
}
}
public void Begin ()
{
lock (syncObj) {
if (status == MessageQueueTransactionStatus.Pending)
throw new InvalidOperationException ("Transaction already started");
status = MessageQueueTransactionStatus.Pending;
}
}
public void Commit ()
{
lock (syncObj) {
Context.Model.TxCommit ();
status = MessageQueueTransactionStatus.Committed;
}
}
public void Delete (QueueReference qRef)
{
lock (syncObj) {
Context.Delete (qRef);
}
}
public void Purge (QueueReference qRef)
{
lock (syncObj) {
Context.Purge (qRef);
}
}
public string Id {
get { return txId; }
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
lock (syncObj) {
if (!isDisposed && disposing) {
if (context != null)
context.Dispose ();
isDisposed = true;
}
}
}
}
}

View File

@@ -0,0 +1,167 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Mono.Messaging;
using RabbitMQ.Client;
namespace Mono.Messaging.RabbitMQ {
public class RabbitMQMessagingProvider : IMessagingProvider {
private int txCounter = 0;
private readonly uint localIp;
private readonly MessagingContextPool contextPool;
public RabbitMQMessagingProvider ()
{
localIp = GetLocalIP ();
contextPool = new MessagingContextPool (new MessageFactory (this),
CreateConnection);
}
private static uint GetLocalIP ()
{
String strHostName = Dns.GetHostName ();
IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
foreach (IPAddress ip in ipEntry.AddressList) {
if (AddressFamily.InterNetwork == ip.AddressFamily) {
byte[] addr = ip.GetAddressBytes ();
uint localIP = 0;
for (int i = 0; i < 4 && i < addr.Length; i++) {
localIP += (uint) (addr[i] << 8 * (3 - i));
}
return localIP;
}
}
return 0;
}
public IMessage CreateMessage ()
{
return new MessageBase ();
}
public IMessageQueueTransaction CreateMessageQueueTransaction ()
{
Interlocked.Increment (ref txCounter);
string txId = localIp.ToString () + txCounter.ToString ();
return new RabbitMQMessageQueueTransaction (txId, contextPool);
}
public IMessagingContext CreateContext (string host)
{
return contextPool.GetContext (host);
}
private IConnection CreateConnection (string host)
{
ConnectionFactory cf = new ConnectionFactory ();
cf.Address = host;
return cf.CreateConnection ();
}
public void DeleteQueue (QueueReference qRef)
{
RabbitMQMessageQueue.Delete (qRef);
}
private readonly IDictionary queues = new Hashtable ();
private readonly ReaderWriterLock qLock = new ReaderWriterLock ();
private const int TIMEOUT = 15000;
public IMessageQueue[] GetPublicQueues ()
{
IMessageQueue[] qs;
qLock.AcquireReaderLock (TIMEOUT);
try {
ICollection qCollection = queues.Values;
qs = new IMessageQueue[qCollection.Count];
qCollection.CopyTo (qs, 0);
return qs;
} finally {
qLock.ReleaseReaderLock ();
}
}
public bool Exists (QueueReference qRef)
{
qLock.AcquireReaderLock (TIMEOUT);
try {
return queues.Contains (qRef);
} finally {
qLock.ReleaseReaderLock ();
}
}
public IMessageQueue CreateMessageQueue (QueueReference qRef,
bool transactional)
{
qLock.AcquireWriterLock (TIMEOUT);
try {
IMessageQueue mq = new RabbitMQMessageQueue (this, qRef, transactional);
queues[qRef] = mq;
return mq;
} finally {
qLock.ReleaseWriterLock ();
}
}
public IMessageQueue GetMessageQueue (QueueReference qRef)
{
qLock.AcquireReaderLock (TIMEOUT);
try {
if (queues.Contains (qRef))
return (IMessageQueue) queues[qRef];
else {
LockCookie lc = qLock.UpgradeToWriterLock (TIMEOUT);
try {
IMessageQueue mq = new RabbitMQMessageQueue (this, qRef, false);
queues[qRef] = mq;
return mq;
} finally {
qLock.DowngradeFromWriterLock (ref lc);
}
}
} finally {
qLock.ReleaseReaderLock ();
}
}
}
}

View File

@@ -0,0 +1,9 @@
Mono.Messaging.RabbitMQ/FailuresTest.cs
Mono.Messaging.RabbitMQ/RabbitMQMessagingProviderTest.cs
Mono.Messaging.RabbitMQ/BinaryMessageFormatterTest.cs
Mono.Messaging.RabbitMQ/XmlMessageFormatterTest.cs
Mono.Messaging.RabbitMQ/TestUtils.cs
Mono.Messaging.RabbitMQ/MessageTest.cs
Mono.Messaging.RabbitMQ/MessagingContextPoolTest.cs
Mono.Messaging.RabbitMQ/MessageBaseTest.cs
Mono.Messaging.RabbitMQ/MessageEnumeratorExceptionTest.cs

View File

@@ -0,0 +1,119 @@
//
// BinaryMessageFormatterTest.cs -
// NUnit Test Cases for BinaryMessageFormatter
//
// Author:
// Michael Barker <mike@middlesoft.co.uk>
//
// Copyright (C) 2008 Michael Barker
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Messaging;
using Mono.Messaging;
using NUnit.Framework;
using NUnit.Mocks;
namespace MonoTests.Mono.Messaging.RabbitMQ
{
[TestFixture]
public class BinaryMessageFormatterTest
{
DynamicMock mock1;
IMessage msg1;
DynamicMock mock2;
IMessage msg2;
[SetUp]
public void SetUp ()
{
mock1 = new DynamicMock (typeof (IMessage));
msg1 = (IMessage) mock1.MockInstance;
mock2 = new DynamicMock (typeof (IMessage));
msg2 = (IMessage) mock2.MockInstance;
}
[Test]
public void FormatString ()
{
string s = "this is a test string";
Stream ms = new MemoryStream ();
mock1.ExpectAndReturn ("get_BodyStream", ms);
mock1.ExpectAndReturn ("get_BodyStream", ms);
mock1.Expect ("set_BodyType", 768);
mock2.ExpectAndReturn ("get_BodyStream", ms);
mock2.ExpectAndReturn ("get_BodyStream", ms);
Message m = TestUtils.CreateMessage (msg1);
m.Formatter = new BinaryMessageFormatter ();
m.Formatter.Write (m, s);
Stream stream = m.BodyStream;
Assert.IsTrue (stream.Length > 0);
Message m2 = TestUtils.CreateMessage (msg2);
m2.Formatter = new BinaryMessageFormatter ();
Assert.AreEqual(s, m2.Formatter.Read (m2), "The string did not serialise/deserialise properly");
mock1.Verify ();
mock2.Verify ();
}
[Test]
public void FormatComplexObject ()
{
Stream ms = new MemoryStream ();
mock1.ExpectAndReturn ("get_BodyStream", ms);
mock1.ExpectAndReturn ("get_BodyStream", ms);
mock2.ExpectAndReturn ("get_BodyStream", ms);
mock2.ExpectAndReturn ("get_BodyStream", ms);
Thingy2 t0 = new Thingy2();
t0.Iii = 42;
t0.Sss = "Some Text";
t0.Ttt = DateTime.Now;
Message m = TestUtils.CreateMessage (msg1);
m.Formatter = new BinaryMessageFormatter ();
m.Formatter.Write (m, t0);
Stream stream = m.BodyStream;
Assert.IsTrue (stream.Length > 0);
Message m2 = TestUtils.CreateMessage (msg2);
m2.Formatter = new BinaryMessageFormatter ();
Thingy2 t1 = (Thingy2) m2.Formatter.Read (m2);
Assert.AreEqual(t0.Iii, t1.Iii, "The string did not serialise/deserialise properly");
Assert.AreEqual(t0.Sss, t1.Sss, "The string did not serialise/deserialise properly");
Assert.AreEqual(t0.Ttt, t1.Ttt, "The string did not serialise/deserialise properly");
mock1.Verify ();
mock2.Verify ();
}
}
}

View File

@@ -0,0 +1,86 @@
2009-07-19 Michael Barker <mike@middlesoft.co.uk>
* AdminTest.cs: Moved to System.Messaging
* AsyncPeekTest.cs: Moved to System.Messaging
* AsyncReceiveTest.cs: Moved to System.Messaging
* BasicMessagingTest.cs: Moved to System.Messaging
* MessageEnumeratorTest.cs: Moved to System.Messaging
* MQUtil.cs: Moved to System.Messaging
* PeekTest.cs: Moved to System.Messaging
* SelectorTest.cs: Moved to System.Messaging
2009-07-11 Michael Barker <mike@middlesoft.co.uk>
* MessageBaseTest.cs: Moved from Mono.Messaging.Test
* MessageEnumeratorTest.cs: Moved from Mono.Messaging.Test
* MessageTest.cs: Used using aliases to prevent namespace clashes.
* AdminTest.cs: Remove unused variables.
* AsyncPeekTest.cs: Remove unused variables.
* AsyncReceiveTest.cs: Remove unused variables.
2009-05-23 Michael Barker <mike@middlesoft.co.uk>
* MessageEnumeratorTest.cs: Added tests for timeout methods.
2009-01-05 Michael Barker <mike@middlesoft.co.uk>
* BinaryMessageFormatter.cs, XMLMessageFormatterTest.cs, TestUtils.cs,
MessageTest.cs: Moved in from System.Messaging namespace.
2009-01-03 Michael Barker <mike@middlesoft.co.uk>
* AsyncPeekTest.cs: Added test for handling exceptions aysnchronously.
* AsyncReceiveTest.cs: Added test for handling exceptions aysnchronously.
2008-12-20 Michael Barker <mike@middlesoft.co.uk>
* AsyncReceiveTest.cs: New, tests for Asynchronous Receive methods.
* AsyncPeekTest.cs: New, tests for Asynchronous Peek methods.
* MessageQueueEnumeratorTest.cs: Removed unecesary logging.
2008-12-06 Michael Barker <mike@middlesoft.co.uk>
* AdminTest.cs: Updated to run against MS.NET
* BasicMessagingTest.cs: Updated to run against MS.NET
* FailuresTest.cs: Updated to run against MS.NET
* MessageEnumeratorTest.cs: Updated to run against MS.NET
* MQUtil.cs: Updated to run against MS.NET
* PeekTest.cs: Updated to run against MS.NET
* SelectorTest.cs: Updated to run against MS.NET
* TransactionMessagingTest.cs: Updated to run against MS.NET
2008-12-01 Michael Barker <mike@middlesoft.co.uk>
* AdminTest.cs: Added tests for queue discovery methods.
2008-11-23 Michael Barker <mike@middlesoft.co.uk>
* TransactionMessagingTest.cs: Added tests for all methods that the
transaction type argument, currently only Single is supported. Added methods
with transactions and timeout.
* PeekTest.cs: Added PeekBy{Id,CorrelationId} tests.
2008-11-09 Michael Barker <mike@middlesoft.co.uk>
* SelectorTest.cs: New, tests for ReceiveByXYZ() methods
2008-11-04 Michael Barker <mike@middlesoft.co.uk>
* PeekTest.cs: New, tests for peeking at messages.
2008-11-02 Michael Barker <mike@middlesoft.co.uk>
* TransactionMessagingTest.cs: New, tests for transactional messaging.
* FailuresTest.cs: New, tests for exceptions.
* AdminTest.cs: New, tests for administration functions.
2008-09-29 Michael Barker <mike@middlesoft.co.uk>
* BasicMessagingTest.cs: New
* RabbitMQMessagingProviderTest.cs: New
2009-05-19 Michael Barker <mike@middlesoft.co.uk>
* RabbitMQMessagingProviderTest.cs: Added test for dynamic create of
MessagingProvider

View File

@@ -0,0 +1,66 @@
//
// Test.Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Messaging;
using System.Reflection;
using System.Threading;
using System.Text.RegularExpressions;
using NUnit.Framework;
namespace MonoTests.Mono.Messaging.RabbitMQ
{
[TestFixture]
public class FailuresTest {
[Test]
[ExpectedException (typeof (MessageQueueException))]
public void SendWithPathNotSet ()
{
MessageQueue q = new MessageQueue ();
Message m = new Message ("foobar", new BinaryMessageFormatter ());
q.Send (m);
}
[Test]
[ExpectedException (typeof (MessageQueueException))]
public void SendInTransactionWithPathNotSet ()
{
MessageQueue q = new MessageQueue ();
Message m = new Message ("foobar", new BinaryMessageFormatter ());
MessageQueueTransaction tx = new MessageQueueTransaction ();
q.Send (m, tx);
}
}
}

View File

@@ -0,0 +1,119 @@
//
// Mono.Messaging.RabbitMQ
//
// Authors:
// Michael Barker (mike@middlesoft.co.uk)
//
// (C) 2008 Michael Barker
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Messaging;
using System.Reflection;
using Mono.Messaging;
using SystemAcknowledgeTypes = System.Messaging.AcknowledgeTypes;
using SystemCryptographicProviderType = System.Messaging.CryptographicProviderType;
using SystemEncryptionAlgorithm = System.Messaging.EncryptionAlgorithm;
using SystemHashAlgorithm = System.Messaging.HashAlgorithm;
using SystemMessagePriority = System.Messaging.MessagePriority;
using NUnit.Framework;
namespace MonoTests.Mono.Messaging {
[TestFixture]
public class MessageBaseTest {
[Test]
public void CheckDefaultValues ()
{
Type[] types = {
typeof (IMessage), typeof (object), typeof (IMessageFormatter)
};
ConstructorInfo ci = typeof (Message).GetConstructor (
BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder, types, new ParameterModifier[0]);
if (ci == null)
throw new Exception ("ConstructorInfo is null");
Message m = (Message) ci.Invoke (new object[] { new MessageBase (), null, null });
Assert.IsNull (m.Body, "Body default should be Null");
Assert.IsNull (m.Formatter, "Formatter default should null");
Assert.AreEqual (SystemAcknowledgeTypes.None,
m.AcknowledgeType,
"AcknowledgeType default should be None");
Assert.AreEqual (null, m.AdministrationQueue,
"AdministrationQueue default should be null");
Assert.AreEqual (0, m.AppSpecific, "AppSpecific default should be 0");
Assert.AreEqual (true, m.AttachSenderId, "AttachSenderId default should be true");
Assert.AreEqual ("Microsoft Base Cryptographic Provider, Ver. 1.0", m.AuthenticationProviderName,
"AuthenticationProviderName should default to \"Microsoft Base Cryptographic Provider, Ver. 1.0\"");
Assert.AreEqual (SystemCryptographicProviderType.RsaFull,
m.AuthenticationProviderType,
"AuthenticationProviderType should default to RsaFull");
Assert.AreEqual (null, m.BodyStream, "BodyStream should default to null");
Assert.AreEqual (Guid.Empty, m.ConnectorType, "ConnectorType should default to empty");
Assert.AreEqual (null, m.CorrelationId, "CorrelationId should default to null");
Assert.AreEqual (new byte[0], m.DestinationSymmetricKey,
"DestinationSymmetricKey should default to an empty array");
Assert.AreEqual (new byte[0], m.DigitalSignature,
"DigitalSignature default to an empty array");
Assert.AreEqual (SystemEncryptionAlgorithm.Rc2,
m.EncryptionAlgorithm,
"EncryptionAlgorithm should default to Rc2");
Assert.AreEqual (new byte[0], m.Extension,
"Extension should default to an empty array");
Assert.AreEqual (SystemHashAlgorithm.Sha, m.HashAlgorithm,
"HashAlgorithm should default to Sha");
Assert.AreEqual (Guid.Empty.ToString () + "\\0", m.Id, "Id should default to Guid.Empty");
Assert.AreEqual ("", m.Label, "Label should default to \"\"");
Assert.AreEqual (false, m.IsFirstInTransaction, "IsFirstInTransaction should default to false");
Assert.AreEqual (false, m.IsLastInTransaction, "IsLastInTransaction should default to false");
Assert.AreEqual (SystemMessagePriority.Normal, m.Priority,
"Priority should default to Normal");
Assert.AreEqual (false, m.Recoverable, "Recoverable should default to false");
Assert.AreEqual (null, m.ResponseQueue, "ResponseQueue should default to null");
//Assert.AreEqual (null, m.SecurityContext, "SecurityContext should default to null");
Assert.AreEqual (new byte[0], m.SenderCertificate,
"SenderCertificate should default to an empty array");
Assert.AreEqual (Message.InfiniteTimeout, m.TimeToBeReceived,
"TimeToBeReceived should default to InfiniteTimeout");
Assert.AreEqual (Message.InfiniteTimeout, m.TimeToReachQueue,
"TimeToReadQueue should default to InfiniteTimeout");
Assert.AreEqual (false, m.UseAuthentication,
"UseAuthentication should default to false");
Assert.AreEqual (false, m.UseDeadLetterQueue,
"UseDeadLetterQueue should default to false");
Assert.AreEqual (false, m.UseEncryption, "Encryption should default to false");
Assert.AreEqual (false, m.UseJournalQueue,
"UseJournalQueue should default to false");
Assert.AreEqual (false, m.UseTracing, "UseTracing should default to false");
}
}
}

View File

@@ -0,0 +1,109 @@
//
// MessageEnumeratorTest.cs -
// NUnit Test Cases for MessageEnumerator
//
// Author:
// Michael Barker <mike@middlesoft.co.uk>
//
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Security;
using System.Security.Permissions;
using System.Reflection;
using Mono.Messaging;
using SystemMessageEnumerator = System.Messaging.MessageEnumerator;
using SystemMessageQueueException = System.Messaging.MessageQueueException;
using SystemIMessageFormatter = System.Messaging.IMessageFormatter;
using NUnit.Framework;
using NUnit.Mocks;
namespace MonoTests.Mono.Messaging {
[TestFixture]
public class MessageEnumeratorExceptionTest
{
private DynamicMock mockME;
[SetUp]
public void Init ()
{
mockME = new DynamicMock (typeof (IMessageEnumerator));
}
[Test]
[ExpectedException(typeof(SystemMessageQueueException))]
public void RemoveCurrentThrowsConnectionException ()
{
mockME.ExpectAndThrow ("RemoveCurrent", new ConnectionException (QueueReference.DEFAULT), null);
SystemMessageEnumerator me = CreateEnumerator ((IMessageEnumerator) mockME.MockInstance);
me.RemoveCurrent ();
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void RemoveCurrentThrowsMessageUnavailableException ()
{
mockME.ExpectAndThrow ("RemoveCurrent", new MessageUnavailableException (), null);
SystemMessageEnumerator me = CreateEnumerator ((IMessageEnumerator) mockME.MockInstance);
me.RemoveCurrent ();
}
[Test]
[ExpectedException(typeof(SystemMessageQueueException))]
public void RemoveCurrentThrowsMonoMessagingException ()
{
mockME.ExpectAndThrow ("RemoveCurrent", new MonoMessagingException (), null);
SystemMessageEnumerator me = CreateEnumerator ((IMessageEnumerator) mockME.MockInstance);
me.RemoveCurrent ();
}
[Test]
[ExpectedException(typeof(NotImplementedException))]
public void RemoveCurrentThrowsMessageNotImplemented ()
{
mockME.ExpectAndThrow ("RemoveCurrent", new NotImplementedException (), null);
SystemMessageEnumerator me = CreateEnumerator ((IMessageEnumerator) mockME.MockInstance);
me.RemoveCurrent ();
}
public SystemMessageEnumerator CreateEnumerator (IMessageEnumerator ime)
{
Type[] types = {
typeof (IMessageEnumerator), typeof (SystemIMessageFormatter)
};
ConstructorInfo ci = typeof (SystemMessageEnumerator).GetConstructor (
BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder, types, new ParameterModifier[0]);
if (ci == null)
throw new Exception ("ConstructorInfo is null");
return (SystemMessageEnumerator) ci.Invoke (new object[] { ime, null });
}
}
}

View File

@@ -0,0 +1,68 @@
//
// MessageTest.cs -
// NUnit Test Cases for MessageQueuePermissionAttribute
//
// Author:
// Michael Barker <sebastien@ximian.com>
//
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using NUnit.Framework;
using NUnit.Mocks;
using System;
using System.Security;
using System.Security.Permissions;
using System.Reflection;
using SystemMessage = System.Messaging.Message;
using SystemAcknowledgeTypes = System.Messaging.AcknowledgeTypes;
using Mono.Messaging;
namespace MonoTests.Mono.Messaging.RabbitMQ {
[TestFixture]
public class MessageTest {
DynamicMock messageMock;
IMessage iMessage;
[SetUp]
public void SetUp ()
{
messageMock = new DynamicMock (typeof (IMessage));
iMessage = (IMessage) messageMock.MockInstance;
}
[Test]
public void SetProperties ()
{
messageMock.Expect ("set_AcknowledgeType",
AcknowledgeTypes.FullReachQueue);
SystemMessage m = TestUtils.CreateMessage (iMessage);
m.AcknowledgeType = SystemAcknowledgeTypes.FullReachQueue;
messageMock.Verify ();
}
}
}

Some files were not shown because too many files have changed in this diff Show More