2 // CustomPeerResolverService.cs
5 // Marcos Cobena (marcoscobena@gmail.com)
6 // Atsushi Enomoto <atsushi@ximian.com>
8 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
10 // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
32 using System.Collections.Generic;
35 using System.Net.Sockets;
36 using System.Transactions;
39 namespace System.ServiceModel.PeerResolvers
41 [MonoTODO ("Implement cleanup and refresh")]
42 [ServiceBehavior (ConcurrencyMode = ConcurrencyMode.Multiple,
43 InstanceContextMode = InstanceContextMode.Single,
44 UseSynchronizationContext = false)]
45 public class CustomPeerResolverService : IPeerResolverContract
47 static ServiceHost localhost;
50 static void SetupCustomPeerResolverServiceHost ()
52 string customPort = Environment.GetEnvironmentVariable ("MONO_CUSTOMPEERRESOLVERSERVICE_PORT");
53 if (customPort == null || !int.TryParse (customPort, out port))
56 // launch peer resolver service locally only when it does not seem to be running ...
57 var t = new TcpListener (port);
64 Console.WriteLine ("WARNING: it is running peer resolver service locally. This means, the node registration is valid only within this application domain...");
65 var host = new ServiceHost (new LocalPeerResolverService (TextWriter.Null));
66 host.Description.Behaviors.Find<ServiceBehaviorAttribute> ().InstanceContextMode = InstanceContextMode.Single;
67 host.AddServiceEndpoint (typeof (ICustomPeerResolverContract), new BasicHttpBinding (), $"http://localhost:{port}");
72 ICustomPeerResolverClient client;
73 bool control_shape, opened;
74 TimeSpan refresh_interval, cleanup_interval;
76 public CustomPeerResolverService ()
78 client = ChannelFactory<ICustomPeerResolverClient>.CreateChannel (new BasicHttpBinding (), new EndpointAddress ($"http://localhost:{port}"));
80 refresh_interval = new TimeSpan (0, 10, 0);
81 cleanup_interval = new TimeSpan (0, 1, 0);
84 public TimeSpan CleanupInterval {
85 get { return cleanup_interval; }
87 if ((value < TimeSpan.Zero) || (value > TimeSpan.MaxValue))
88 throw new ArgumentOutOfRangeException (
89 "The interval is either zero or greater than max value.");
91 throw new InvalidOperationException ("The interval must be set before it is opened");
93 cleanup_interval = value;
97 public bool ControlShape {
98 get { return control_shape; }
101 throw new InvalidOperationException ("The interval must be set before it is opened");
102 control_shape = value;
106 public TimeSpan RefreshInterval {
107 get { return refresh_interval; }
109 if ((value < TimeSpan.Zero) || (value > TimeSpan.MaxValue))
110 throw new ArgumentOutOfRangeException (
111 "The interval is either zero or greater than max value.");
113 throw new InvalidOperationException ("The interval must be set before it is opened");
115 refresh_interval = value;
119 [MonoTODO ("Do we have to unregister nodes here?")]
120 public virtual void Close ()
123 throw new InvalidOperationException ("The service has never been opened or it was closed by a previous call to this method.");
127 if (localhost != null) {
133 public virtual ServiceSettingsResponseInfo GetServiceSettings ()
136 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
138 return client.GetServiceSettings ();
141 public virtual void Open ()
143 if (localhost == null)
144 SetupCustomPeerResolverServiceHost ();
146 if ((CleanupInterval == TimeSpan.Zero) || (RefreshInterval == TimeSpan.Zero))
147 throw new ArgumentException ("Cleanup interval or refresh interval are set to a time span interval of zero.");
150 throw new InvalidOperationException ("The service has been started by a previous call to this method.");
155 client.SetCustomServiceSettings (new PeerServiceSettingsInfo () { ControlMeshShape = control_shape, RefreshInterval = refresh_interval, CleanupInterval = cleanup_interval });
158 public virtual RefreshResponseInfo Refresh (RefreshInfo refreshInfo)
160 if (refreshInfo == null)
161 throw new ArgumentException ("Refresh info cannot be null.");
164 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
166 return client.Refresh (refreshInfo);
169 public virtual RegisterResponseInfo Register (RegisterInfo registerInfo)
171 if (registerInfo == null)
172 throw new ArgumentException ("Register info cannot be null.");
175 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
177 return client.Register (registerInfo);
180 public virtual RegisterResponseInfo Register (Guid clientId, string meshId, PeerNodeAddress address)
182 return Register (new RegisterInfo (clientId, meshId, address));
185 public virtual ResolveResponseInfo Resolve (ResolveInfo resolveInfo)
187 if (resolveInfo == null)
188 throw new ArgumentException ("Resolve info cannot be null.");
191 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
193 return client.Resolve (resolveInfo);
196 public virtual void Unregister (UnregisterInfo unregisterInfo)
198 if (unregisterInfo == null)
199 throw new ArgumentException ("Unregister info cannot be null.");
202 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
204 client.Unregister (unregisterInfo);
207 public virtual RegisterResponseInfo Update (UpdateInfo updateInfo)
209 if (updateInfo == null)
210 throw new ArgumentException ("Update info cannot be null.");
213 throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
215 return client.Update (updateInfo);