[utils] Fix inet_pton fallback.
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.PeerResolvers / CustomPeerResolverService.cs
1 // 
2 // CustomPeerResolverService.cs
3 // 
4 // Author: 
5 //     Marcos Cobena (marcoscobena@gmail.com)
6 //      Atsushi Enomoto  <atsushi@ximian.com>
7 // 
8 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
9 //
10 // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections.Generic;
33 using System.IO;
34 using System.Linq;
35 using System.Net.Sockets;
36 using System.Transactions;
37 using System.Timers;
38
39 namespace System.ServiceModel.PeerResolvers
40 {
41         [MonoTODO ("Implement cleanup and refresh")]
42         [ServiceBehavior (ConcurrencyMode = ConcurrencyMode.Multiple, 
43                           InstanceContextMode = InstanceContextMode.Single,
44                           UseSynchronizationContext = false)]
45         public class CustomPeerResolverService : IPeerResolverContract
46         {
47                 static ServiceHost localhost;
48
49                 static void SetupCustomPeerResolverServiceHost ()
50                 {
51                         // launch peer resolver service locally only when it does not seem to be running ...
52                         var t = new TcpListener (8931);
53                         try {
54                                 t.Start ();
55                                 t.Stop ();
56                         } catch {
57                                 return;
58                         }
59                         Console.WriteLine ("WARNING: it is running peer resolver service locally. This means, the node registration is valid only within this application domain...");
60                         var host = new ServiceHost (new LocalPeerResolverService (TextWriter.Null));
61                         host.Description.Behaviors.Find<ServiceBehaviorAttribute> ().InstanceContextMode = InstanceContextMode.Single;
62                         host.AddServiceEndpoint (typeof (ICustomPeerResolverContract), new BasicHttpBinding (), "http://localhost:8931");
63                         localhost = host;
64                         host.Open ();
65                 }
66
67                 ICustomPeerResolverClient client;
68                 bool control_shape, opened;
69                 TimeSpan refresh_interval, cleanup_interval;
70
71                 public CustomPeerResolverService ()
72                 {
73                         client = ChannelFactory<ICustomPeerResolverClient>.CreateChannel (new BasicHttpBinding (), new EndpointAddress ("http://localhost:8931"));
74
75                         refresh_interval = new TimeSpan (0, 10, 0);
76                         cleanup_interval = new TimeSpan (0, 1, 0);
77                 }
78
79                 public TimeSpan CleanupInterval {
80                         get { return cleanup_interval; }
81                         set { 
82                                 if ((value < TimeSpan.Zero) || (value > TimeSpan.MaxValue))
83                                         throw new ArgumentOutOfRangeException (
84                                         "The interval is either zero or greater than max value.");
85                                 if (opened)
86                                         throw new InvalidOperationException ("The interval must be set before it is opened");
87
88                                 cleanup_interval = value;
89                         }
90                 }
91
92                 public bool ControlShape {
93                         get { return control_shape; }
94                         set {
95                                 if (opened)
96                                         throw new InvalidOperationException ("The interval must be set before it is opened");
97                                 control_shape = value;
98                         }
99                 }
100
101                 public TimeSpan RefreshInterval {
102                         get { return refresh_interval; }
103                         set {
104                                 if ((value < TimeSpan.Zero) || (value > TimeSpan.MaxValue))
105                                         throw new ArgumentOutOfRangeException (
106                                         "The interval is either zero or greater than max value.");
107                                 if (opened)
108                                         throw new InvalidOperationException ("The interval must be set before it is opened");
109
110                                 refresh_interval = value;
111                         }
112                 }
113
114                 [MonoTODO ("Do we have to unregister nodes here?")]
115                 public virtual void Close ()
116                 {
117                         if (! opened)
118                                 throw new InvalidOperationException ("The service has never been opened or it was closed by a previous call to this method.");
119                         client.Close ();
120                         opened = false;
121
122                         if (localhost != null) {
123                                 localhost.Close ();
124                                 localhost = null;
125                         }
126                 }
127
128                 public virtual ServiceSettingsResponseInfo GetServiceSettings ()
129                 {
130                         if (! opened)
131                                 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
132                 
133                         return client.GetServiceSettings ();
134                 }
135
136                 public virtual void Open ()
137                 {
138                         if (localhost == null)
139                                 SetupCustomPeerResolverServiceHost ();
140
141                         if ((CleanupInterval == TimeSpan.Zero) || (RefreshInterval == TimeSpan.Zero))
142                                 throw new ArgumentException ("Cleanup interval or refresh interval are set to a time span interval of zero.");
143
144                         if (opened)
145                                 throw new InvalidOperationException ("The service has been started by a previous call to this method.");
146                         
147                         opened = true;
148
149                         client.Open ();
150                         client.SetCustomServiceSettings (new PeerServiceSettingsInfo () { ControlMeshShape = control_shape, RefreshInterval = refresh_interval, CleanupInterval = cleanup_interval });
151                 }
152
153                 public virtual RefreshResponseInfo Refresh (RefreshInfo refreshInfo)
154                 {
155                         if (refreshInfo == null)
156                                 throw new ArgumentException ("Refresh info cannot be null.");
157                         
158                         if (! opened)
159                                 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
160
161                         return client.Refresh (refreshInfo);
162                 }
163
164                 public virtual RegisterResponseInfo Register (RegisterInfo registerInfo)
165                 {
166                         if (registerInfo == null)
167                                 throw new ArgumentException ("Register info cannot be null.");
168                         
169                         if (! opened)
170                                 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
171                         
172                         return client.Register (registerInfo);
173                 }
174
175                 public virtual RegisterResponseInfo Register (Guid clientId, string meshId, PeerNodeAddress address)
176                 {
177                         return Register (new RegisterInfo (clientId, meshId, address));
178                 }
179
180                 public virtual ResolveResponseInfo Resolve (ResolveInfo resolveInfo)
181                 {
182                         if (resolveInfo == null)
183                                 throw new ArgumentException ("Resolve info cannot be null.");
184                         
185                         if (! opened)
186                                 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
187
188                         return client.Resolve (resolveInfo);
189                 }
190
191                 public virtual void Unregister (UnregisterInfo unregisterInfo)
192                 {
193                         if (unregisterInfo == null)
194                                 throw new ArgumentException ("Unregister info cannot be null.");
195                         
196                         if (! opened)
197                                 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
198
199                         client.Unregister (unregisterInfo);
200                 }
201
202                 public virtual RegisterResponseInfo Update (UpdateInfo updateInfo)
203                 {
204                         if (updateInfo == null)
205                                 throw new ArgumentException ("Update info cannot be null.");
206                         
207                         if (! opened)
208                                 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
209
210                         return client.Update (updateInfo);
211                 }
212         }
213 }