2010-06-23: Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / RabbitMQ.Client / src / client / api / AmqpTcpEndpoint.cs
1 // This source code is dual-licensed under the Apache License, version
2 // 2.0, and the Mozilla Public License, version 1.1.
3 //
4 // The APL v2.0:
5 //
6 //---------------------------------------------------------------------------
7 //   Copyright (C) 2007-2010 LShift Ltd., Cohesive Financial
8 //   Technologies LLC., and Rabbit Technologies Ltd.
9 //
10 //   Licensed under the Apache License, Version 2.0 (the "License");
11 //   you may not use this file except in compliance with the License.
12 //   You may obtain a copy of the License at
13 //
14 //       http://www.apache.org/licenses/LICENSE-2.0
15 //
16 //   Unless required by applicable law or agreed to in writing, software
17 //   distributed under the License is distributed on an "AS IS" BASIS,
18 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 //   See the License for the specific language governing permissions and
20 //   limitations under the License.
21 //---------------------------------------------------------------------------
22 //
23 // The MPL v1.1:
24 //
25 //---------------------------------------------------------------------------
26 //   The contents of this file are subject to the Mozilla Public License
27 //   Version 1.1 (the "License"); you may not use this file except in
28 //   compliance with the License. You may obtain a copy of the License at
29 //   http://www.rabbitmq.com/mpl.html
30 //
31 //   Software distributed under the License is distributed on an "AS IS"
32 //   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
33 //   License for the specific language governing rights and limitations
34 //   under the License.
35 //
36 //   The Original Code is The RabbitMQ .NET Client.
37 //
38 //   The Initial Developers of the Original Code are LShift Ltd,
39 //   Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
40 //
41 //   Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
42 //   Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
43 //   are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
44 //   Technologies LLC, and Rabbit Technologies Ltd.
45 //
46 //   Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
47 //   Ltd. Portions created by Cohesive Financial Technologies LLC are
48 //   Copyright (C) 2007-2010 Cohesive Financial Technologies
49 //   LLC. Portions created by Rabbit Technologies Ltd are Copyright
50 //   (C) 2007-2010 Rabbit Technologies Ltd.
51 //
52 //   All Rights Reserved.
53 //
54 //   Contributor(s): ______________________________________.
55 //
56 //---------------------------------------------------------------------------
57 using System;
58 using System.Collections;
59 using RabbitMQ.Client.Impl;
60
61 namespace RabbitMQ.Client
62 {
63     ///<summary>Represents a TCP-addressable AMQP peer, including the
64     ///protocol variant to use, and a host name and port
65     ///number.</summary>
66     ///<para>
67     /// Some of the constructors take, as a convenience, a System.Uri
68     /// instance representing an AMQP server address. The use of Uri
69     /// here is not standardised - Uri is simply a convenient
70     /// container for internet-address-like components. In particular,
71     /// the Uri "Scheme" property is ignored: only the "Host" and
72     /// "Port" properties are extracted.
73     ///</para>
74     public class AmqpTcpEndpoint
75     {
76         ///<summary>Indicates that the default port for the protocol should be used</summary>
77         public const int UseDefaultPort = -1;
78
79         private IProtocol m_protocol;
80         ///<summary>Retrieve or set the IProtocol of this AmqpTcpEndpoint.</summary>
81         public IProtocol Protocol
82         {
83             get { return m_protocol; }
84             set { m_protocol = value; }
85         }
86
87         private string m_hostName;
88         ///<summary>Retrieve or set the hostname of this AmqpTcpEndpoint.</summary>
89         public string HostName
90         {
91             get { return m_hostName; }
92             set { m_hostName = value; }
93         }
94
95         private int m_port;
96         ///<summary>Retrieve or set the port number of this
97         ///AmqpTcpEndpoint. A port number of -1 causes the default
98         ///port number for the IProtocol to be used.</summary>
99         public int Port
100         {
101             get { return (m_port == UseDefaultPort) ? m_protocol.DefaultPort : m_port; }
102             set { m_port = value; }
103         }
104
105
106         private SslOption m_ssl;
107         ///<summary>Retrieve the SSL options for this AmqpTcpEndpoint.
108         ///If not set, null is returned</summary>
109         public SslOption Ssl
110         {
111             get { return m_ssl; }
112             set { m_ssl = value; }
113         }
114
115         ///<summary>Construct an AmqpTcpEndpoint with the given
116         ///IProtocol, hostname, port number and ssl option. If the port 
117         ///number is -1, the default port number for the IProtocol 
118         ///will be used.</summary>
119         public AmqpTcpEndpoint(IProtocol protocol, string hostName, int portOrMinusOne, SslOption ssl)
120         {
121             m_protocol = protocol;
122             m_hostName = hostName;
123             m_port = portOrMinusOne;
124             m_ssl = ssl;
125         }
126
127         ///<summary>Construct an AmqpTcpEndpoint with the given
128         ///IProtocol, hostname, and port number. If the port number is
129         ///-1, the default port number for the IProtocol will be
130         ///used.</summary>
131         public AmqpTcpEndpoint(IProtocol protocol, string hostName, int portOrMinusOne) :
132             this(protocol, hostName, portOrMinusOne, new SslOption())
133         {
134         }
135
136         ///<summary>Construct an AmqpTcpEndpoint with the given
137         ///IProtocol and hostname, using the default port for the
138         ///IProtocol.</summary>
139         public AmqpTcpEndpoint(IProtocol protocol, string hostName) :
140             this(protocol, hostName, -1)
141         {
142         }
143
144         ///<summary>Construct an AmqpTcpEndpoint with the given
145         ///IProtocol, "localhost" as the hostname, and using the
146         ///default port for the IProtocol.</summary>
147         public AmqpTcpEndpoint(IProtocol protocol) :
148             this(protocol, "localhost", -1)
149         {
150         }
151
152         ///<summary>Construct an AmqpTcpEndpoint with the given
153         ///hostname and port number, using the IProtocol from
154         ///Protocols.FromEnvironment(). If the port number is
155         ///-1, the default port number for the IProtocol will be
156         ///used.</summary>
157         public AmqpTcpEndpoint(string hostName, int portOrMinusOne) :
158             this(Protocols.FromEnvironment(), hostName, portOrMinusOne)
159         {
160         }
161
162         ///<summary>Construct an AmqpTcpEndpoint with the given
163         ///hostname, using the IProtocol from
164         ///Protocols.FromEnvironment(), and the default port number of
165         ///that IProtocol.</summary>
166         public AmqpTcpEndpoint(string hostName) :
167             this(Protocols.FromEnvironment(), hostName)
168         {
169         }
170
171         ///<summary>Construct an AmqpTcpEndpoint with a hostname of
172         ///"localhost", using the IProtocol from
173         ///Protocols.FromEnvironment(), and the default port number of
174         ///that IProtocol.</summary>
175         public AmqpTcpEndpoint() :
176             this(Protocols.FromEnvironment())
177         {
178         }
179
180         ///<summary>Construct an AmqpTcpEndpoint with the given
181         ///IProtocol, Uri and ssl options.</summary>
182         ///<remarks>
183         /// Please see the class overview documentation for
184         /// information about the Uri format in use.
185         ///</remarks>
186         public AmqpTcpEndpoint(IProtocol protocol, Uri uri, SslOption ssl) :
187             this(protocol, uri.Host, uri.Port, ssl)
188         {
189         }
190
191         ///<summary>Construct an AmqpTcpEndpoint with the given
192         ///IProtocol and Uri.</summary>
193         ///<remarks>
194         /// Please see the class overview documentation for
195         /// information about the Uri format in use.
196         ///</remarks>
197         public AmqpTcpEndpoint(IProtocol protocol, Uri uri) :
198             this(protocol, uri.Host, uri.Port)
199         {
200         }
201
202         ///<summary>Construct an AmqpTcpEndpoint with the given
203         ///Uri, using the IProtocol from
204         ///Protocols.FromEnvironment().</summary>
205         ///<remarks>
206         /// Please see the class overview documentation for
207         /// information about the Uri format in use.
208         ///</remarks>
209         public AmqpTcpEndpoint(Uri uri) :
210             this(Protocols.FromEnvironment(), uri)
211         {
212         }
213
214         ///<summary>Returns a URI-like string of the form
215         ///amqp-PROTOCOL://HOSTNAME:PORTNUMBER</summary>
216         ///<remarks>
217         /// This method is intended mainly for debugging and logging use.
218         ///</remarks>
219         public override string ToString()
220         {
221             return "amqp-" + Protocol + "://" + HostName + ":" + Port;
222         }
223
224         ///<summary>Compares this instance by value (protocol,
225         ///hostname, port) against another instance</summary>
226         public override bool Equals(object obj)
227         {
228             AmqpTcpEndpoint other = obj as AmqpTcpEndpoint;
229             if (other == null) return false;
230             if (other.Protocol != Protocol) return false;
231             if (other.HostName != HostName) return false;
232             if (other.Port != Port) return false;
233             return true;
234         }
235
236         ///<summary>Implementation of hash code depending on protocol,
237         ///hostname and port, to line up with the implementation of
238         ///Equals()</summary>
239         public override int GetHashCode()
240         {
241             return
242                 Protocol.GetHashCode() ^
243                 HostName.GetHashCode() ^
244                 Port;
245         }
246
247         ///<summary>Construct an instance from a protocol and an
248         ///address in "hostname:port" format.</summary>
249         ///<remarks>
250         /// If the address string passed in contains ":", it is split
251         /// into a hostname and a port-number part. Otherwise, the
252         /// entire string is used as the hostname, and the port-number
253         /// is set to -1 (meaning the default number for the protocol
254         /// variant specified).
255         ///</remarks>
256         public static AmqpTcpEndpoint Parse(IProtocol protocol, string address) {
257             int index = address.IndexOf(':');
258             if (index == -1) {
259                 return new AmqpTcpEndpoint(protocol, address, -1);
260             } else {
261                 string portStr = address.Substring(index + 1).Trim();
262                 int portNum = (portStr.Length == 0) ? -1 : int.Parse(portStr);
263                 return new AmqpTcpEndpoint(protocol,
264                                            address.Substring(0, index),
265                                            portNum);
266             }
267         }
268
269         ///<summary>Splits the passed-in string on ",", and passes the
270         ///substrings to AmqpTcpEndpoint.Parse()</summary>
271         ///<remarks>
272         /// Accepts a string of the form "hostname:port,
273         /// hostname:port, ...", where the ":port" pieces are
274         /// optional, and returns a corresponding array of
275         /// AmqpTcpEndpoints.
276         ///</remarks>
277         public static AmqpTcpEndpoint[] ParseMultiple(IProtocol protocol, string addresses) {
278             string[] partsArr = addresses.Split(new char[] { ',' });
279             ArrayList results = new ArrayList();
280             foreach (string partRaw in partsArr) {
281                 string part = partRaw.Trim();
282                 if (part.Length > 0) {
283                     results.Add(Parse(protocol, part));
284                 }
285             }
286             return (AmqpTcpEndpoint[]) results.ToArray(typeof(AmqpTcpEndpoint));
287         }
288     }
289 }