2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / Mono.Messaging.RabbitMQ / Mono.Messaging.RabbitMQ / RabbitMQMessagingProvider.cs
1 //
2 // Mono.Messaging.RabbitMQ
3 //
4 // Authors:
5 //        Michael Barker (mike@middlesoft.co.uk)
6 //
7 // (C) 2008 Michael Barker
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System;
32 using System.Collections;
33 using System.Net;
34 using System.Net.Sockets;
35 using System.Threading;
36
37 using Mono.Messaging;
38
39 namespace Mono.Messaging.RabbitMQ {
40
41         public class RabbitMQMessagingProvider : IMessagingProvider {
42                 
43                 private volatile uint txCounter = 0;
44                 private readonly uint localIp;
45                 private static readonly string DEFAULT_REALM = "/data";
46                 
47                 public RabbitMQMessagingProvider()
48                 {
49                         localIp = GetLocalIP ();
50                 }
51                 
52                 private static uint GetLocalIP ()
53                 {
54                         //IPHostEntry host = Dns.GetHostEntry (Dns.GetHostName ());
55                         String strHostName = Dns.GetHostName ();
56                         IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
57                         foreach (IPAddress ip in ipEntry.AddressList) {
58                                 if (AddressFamily.InterNetwork == ip.AddressFamily) {
59                                         byte[] addr = ip.GetAddressBytes ();
60                                         uint localIP = 0;
61                                         for (int i = 0; i < 4 && i < addr.Length; i++) {
62                                                 localIP += (uint) (addr[i] << 8 * (3 - i));
63                                         }
64                                         return localIP;
65                                 }
66                         }
67                         return 0;
68                 }
69                 
70                 public IMessage CreateMessage ()
71                 {
72                         return new MessageBase ();
73                 }
74                 
75                 public IMessageQueueTransaction CreateMessageQueueTransaction ()
76                 {
77                         string txId = localIp.ToString () + (++txCounter).ToString (); 
78                         return new RabbitMQMessageQueueTransaction (txId);
79                 }
80                 
81                 public void DeleteQueue (QueueReference qRef)
82                 {
83                         RabbitMQMessageQueue.Delete (DEFAULT_REALM, qRef);
84                 }
85                 
86                 private readonly IDictionary queues = new Hashtable ();
87                 private readonly ReaderWriterLock qLock = new ReaderWriterLock ();
88                 private const int TIMEOUT = 15000;
89                 
90                 public IMessageQueue[] GetPublicQueues ()
91                 {
92                         IMessageQueue[] qs;
93                         qLock.AcquireReaderLock (TIMEOUT);
94                         try {
95                                 ICollection qCollection = queues.Values;
96                                 qs = new IMessageQueue[qCollection.Count];
97                                 qCollection.CopyTo (qs, 0);
98                                 return qs;
99                         } finally {
100                                 qLock.ReleaseReaderLock ();
101                         }
102                 }
103                 
104                 public bool Exists (QueueReference qRef)
105                 {
106                         qLock.AcquireReaderLock (TIMEOUT);
107                         try {
108                                 return queues.Contains (qRef);
109                         } finally {
110                                 qLock.ReleaseReaderLock ();
111                         }
112                 }
113                 
114                 public IMessageQueue CreateMessageQueue (QueueReference qRef,
115                                                          bool transactional)
116                 {
117                         qLock.AcquireWriterLock (TIMEOUT);
118                         try {
119                                 IMessageQueue mq = new RabbitMQMessageQueue (this, qRef,
120                                                                              transactional);
121                                 queues[qRef] = mq;
122                                 return mq;
123                         } finally {
124                                 qLock.ReleaseWriterLock ();
125                         }
126                 }
127
128                 public IMessageQueue GetMessageQueue (QueueReference qRef)
129                 {
130                         qLock.AcquireReaderLock (TIMEOUT);
131                         try {
132                                 if (queues.Contains (qRef))
133                                         return (IMessageQueue) queues[qRef];
134                                 else {
135                                         LockCookie lc = qLock.UpgradeToWriterLock (TIMEOUT);
136                                         try {
137                                                 IMessageQueue mq = new RabbitMQMessageQueue (this, qRef,
138                                                                                              false);
139                                                 queues[qRef] = mq;
140                                                 return mq;
141                                         } finally {
142                                                 qLock.DowngradeFromWriterLock (ref lc);
143                                         }
144                                 }
145                         } finally {
146                                 qLock.ReleaseReaderLock ();
147                         }
148                 }
149                 
150
151         }
152 }