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,195 @@
2010-05-19 Atsushi Enomoto <atsushi@ximian.com>
* ServiceSettingsResponseInfo.cs
RegisterResponseInfo.cs
RefreshResponseInfo.cs
ResolveInfo.cs
UpdateInfo.cs
RegisterInfo.cs
UnregisterInfo.cs
RefreshInfo.cs
ResolveResponseInfo.cs : they don't have field initialization at
constructor now, for FormatterServices.GetUninitializedObject().
Fix regression with related to serialization changes.
2009-08-24 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : use common Constants class.
2009-08-17 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : use wildcard for the actual message
transfer operation.
2009-08-17 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : fix internal member name to get
serialized correctly.
2009-08-14 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : add itself as CallbackContract.
2009-08-14 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : remove receiver contract.
2009-08-14 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : add Disconnect() to receiver contract.
2009-08-07 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : add callback contract.
2009-08-04 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : fix contract and add receiver iface
(might be unnecessary though).
2009-07-31 Atsushi Enomoto <atsushi@ximian.com>
* IPeerConnectorContract.cs : new file for [MC-PRCH].
2009-07-14 Atsushi Enomoto <atsushi@ximian.com>
* ServiceSettingsResponseInfo.cs
RegisterResponseInfo.cs
RefreshResponseInfo.cs
ResolveInfo.cs
UpdateInfo.cs
RegisterInfo.cs
UnregisterInfo.cs
ResolveResponseInfo.cs
RefreshInfo.cs : implement HasBody(). I couldn't find any case
that this method might return false.
2009-07-14 Atsushi Enomoto <atsushi@ximian.com>
* CustomPeerResolverService.cs : remove commented code.
Fix and reduce extra code in ServiceBehaviorAttribute.
2009-07-14 Atsushi Enomoto <atsushi@ximian.com>
* ResolveResponseInfo.cs : by default it returns empty address list,
instead of xsi:nil.
* LocalPeerResolverService.cs : resolve operation should return
all registered nodes but the client itself.
2009-07-14 Atsushi Enomoto <atsushi@ximian.com>
* RefreshResponseInfo.cs : fix name typo.
2009-07-09 Atsushi Enomoto <atsushi@ximian.com>
* LocalPeerResolverService.cs : fix RegistrationLifetime to return.
2009-07-07 Atsushi Enomoto <atsushi@ximian.com>
* CustomPeerResolverService.cs, LocalPeerResolverService.cs,
ICustomPeerResolverContract.cs : add local machine peer resolver
implementation that can work across appdomains (based on
dispatching peer resolver that communicates with a ServiceHost
which is either locally started or running as a different process).
2009-06-01 Atsushi Enomoto <atsushi@ximian.com>
* CustomPeerResolverService.cs : Refresh() now gives readable reply.
2009-05-29 Atsushi Enomoto <atsushi@ximian.com>
* CustomPeerResolverService.cs : implement some members.
2009-05-29 Atsushi Enomoto <atsushi@ximian.com>
* RegisterResponseInfo.cs : it does not always reply lifetime.
2009-05-28 Atsushi Enomoto <atsushi@ximian.com>
* RegisterResponseInfo.cs : oops, Marcos was right. .NET returns
"Update" element here.
2009-05-28 Atsushi Enomoto <atsushi@ximian.com>
* ServiceSettingsResponseInfo.cs, RegisterResponseInfo.cs,
RefreshResponseInfo.cs, ResolveInfo.cs, UpdateInfo.cs,
UnregisterInfo.cs, ResolveResponseInfo.cs, RefreshInfo.cs :
set explicit namespaces on DataContract so that their members can
be serialized in appropriate namespace (namespaces in
MessageBodyMemberAttribute does not apply there).
2009-05-27 Atsushi Enomoto <atsushi@ximian.com>
* ResolveInfo.cs : argument check.
2009-04-21 Atsushi Enomoto <atsushi@ximian.com>
* PeerCustomResolverSettings.cs : added Clone().
2009-04-07 Atsushi Enomoto <atsushi@ximian.com>
* IPeerResolverContract.cs: fix SessionMode value.
2007-08-19 Atsushi Enomoto <atsushi@ximian.com>
* RegisterInfo.cs : marcos would have never thought that this is
the source of message xml incompatibility.
2007-08-19 Marcos Cobena (marcoscobena@gmail.com)
* PeerCustomResolverSettings.cs, RefreshInfo.cs, RefreshResponseInfo.cs,
ServiceSettingsResponseInfo.cs, UnregisterInfo.cs, UpdateInfo.cs: Bunch of updates.
2007-08-19 Atsushi Enomoto <atsushi@ximian.com>
* PeerCustomResolverSettings.cs : this class too.
2007-08-19 Atsushi Enomoto <atsushi@ximian.com>
* PeerResolverSettings.cs : there is nothing actually supported in
this class, so don't forget MonoTODOs.
2007-08-17 Marcos Cobena (marcoscobena@gmail.com)
* CustomPeerResolverService.cs: Updated to dependency types.
* RegisterInfo.cs, RegisterResponseInfo.cs, ResolveInfo.cs,
ResolveResponseInfo.cs, UnregisterInfo.cs: Updated to produce same messages as .NET does.
2007-08-17 Atsushi Enomoto <atsushi@ximian.com>
* RegisterInfo.cs : rewritten. Fixed broken approach to static
object and eliminated duplicate fields. Use DataMember on Guid
field directly.
2007-08-16 Marcos Cobena (marcoscobena@gmail.com)
* PeerReferralPolicy.cs: Moved and updated here from AllEnums.cs.
* PeerResolverMode.cs: Updated API.
* RefreshResult.cs: Updated API.
* RegisterInfo.cs: Almost finished, minus HasBody().
2007-07-24 Marcos Cobena (marcoscobena@gmail.com)
* CustomPeerResolverService.cs, IPeerResolverContract.cs, RegisterInfo.cs, ResolveInfo.cs: Minor changes.
* RegisterResponseInfo.cs: Implemented.
2007-06-28 Marcos Cobena (marcoscobena@gmail.com)
* CustomPeerResolverService.cs : Minor fixes for working against tests.
* New classes initial implementations.
2007-05-18 Marcos Cobena (marcoscobena@gmail.com)
* IPeerResolverContract.cs
CustomPeerResolverService.cs : Minor fixes. IPeerResolverContract
works fine now with attributes.
2007-05-13 Atsushi Enomoto <atsushi@ximian.com>
* IPeerResolverContract.cs CustomPeerResolverService.cs :
whitespaces should be replaced with tabs.
2007-05-04 Marcos Cobena (marcoscobena@gmail.com)
* IPeerResolverContract.cs
CustomPeerResolverService.cs : Initial implementations.

View File

@@ -0,0 +1,213 @@
//
// CustomPeerResolverService.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
// Copyright (C) 2009 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Transactions;
using System.Timers;
namespace System.ServiceModel.PeerResolvers
{
[MonoTODO ("Implement cleanup and refresh")]
[ServiceBehavior (ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single,
UseSynchronizationContext = false)]
public class CustomPeerResolverService : IPeerResolverContract
{
static ServiceHost localhost;
static void SetupCustomPeerResolverServiceHost ()
{
// launch peer resolver service locally only when it does not seem to be running ...
var t = new TcpListener (8931);
try {
t.Start ();
t.Stop ();
} catch {
return;
}
Console.WriteLine ("WARNING: it is running peer resolver service locally. This means, the node registration is valid only within this application domain...");
var host = new ServiceHost (new LocalPeerResolverService (TextWriter.Null));
host.Description.Behaviors.Find<ServiceBehaviorAttribute> ().InstanceContextMode = InstanceContextMode.Single;
host.AddServiceEndpoint (typeof (ICustomPeerResolverContract), new BasicHttpBinding (), "http://localhost:8931");
localhost = host;
host.Open ();
}
ICustomPeerResolverClient client;
bool control_shape, opened;
TimeSpan refresh_interval, cleanup_interval;
public CustomPeerResolverService ()
{
client = ChannelFactory<ICustomPeerResolverClient>.CreateChannel (new BasicHttpBinding (), new EndpointAddress ("http://localhost:8931"));
refresh_interval = new TimeSpan (0, 10, 0);
cleanup_interval = new TimeSpan (0, 1, 0);
}
public TimeSpan CleanupInterval {
get { return cleanup_interval; }
set {
if ((value < TimeSpan.Zero) || (value > TimeSpan.MaxValue))
throw new ArgumentOutOfRangeException (
"The interval is either zero or greater than max value.");
if (opened)
throw new InvalidOperationException ("The interval must be set before it is opened");
cleanup_interval = value;
}
}
public bool ControlShape {
get { return control_shape; }
set {
if (opened)
throw new InvalidOperationException ("The interval must be set before it is opened");
control_shape = value;
}
}
public TimeSpan RefreshInterval {
get { return refresh_interval; }
set {
if ((value < TimeSpan.Zero) || (value > TimeSpan.MaxValue))
throw new ArgumentOutOfRangeException (
"The interval is either zero or greater than max value.");
if (opened)
throw new InvalidOperationException ("The interval must be set before it is opened");
refresh_interval = value;
}
}
[MonoTODO ("Do we have to unregister nodes here?")]
public virtual void Close ()
{
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed by a previous call to this method.");
client.Close ();
opened = false;
if (localhost != null) {
localhost.Close ();
localhost = null;
}
}
public virtual ServiceSettingsResponseInfo GetServiceSettings ()
{
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
return client.GetServiceSettings ();
}
public virtual void Open ()
{
if (localhost == null)
SetupCustomPeerResolverServiceHost ();
if ((CleanupInterval == TimeSpan.Zero) || (RefreshInterval == TimeSpan.Zero))
throw new ArgumentException ("Cleanup interval or refresh interval are set to a time span interval of zero.");
if (opened)
throw new InvalidOperationException ("The service has been started by a previous call to this method.");
opened = true;
client.Open ();
client.SetCustomServiceSettings (new PeerServiceSettingsInfo () { ControlMeshShape = control_shape, RefreshInterval = refresh_interval, CleanupInterval = cleanup_interval });
}
public virtual RefreshResponseInfo Refresh (RefreshInfo refreshInfo)
{
if (refreshInfo == null)
throw new ArgumentException ("Refresh info cannot be null.");
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
return client.Refresh (refreshInfo);
}
public virtual RegisterResponseInfo Register (RegisterInfo registerInfo)
{
if (registerInfo == null)
throw new ArgumentException ("Register info cannot be null.");
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
return client.Register (registerInfo);
}
public virtual RegisterResponseInfo Register (Guid clientId, string meshId, PeerNodeAddress address)
{
return Register (new RegisterInfo (clientId, meshId, address));
}
public virtual ResolveResponseInfo Resolve (ResolveInfo resolveInfo)
{
if (resolveInfo == null)
throw new ArgumentException ("Resolve info cannot be null.");
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
return client.Resolve (resolveInfo);
}
public virtual void Unregister (UnregisterInfo unregisterInfo)
{
if (unregisterInfo == null)
throw new ArgumentException ("Unregister info cannot be null.");
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
client.Unregister (unregisterInfo);
}
public virtual RegisterResponseInfo Update (UpdateInfo updateInfo)
{
if (updateInfo == null)
throw new ArgumentException ("Update info cannot be null.");
if (! opened)
throw new InvalidOperationException ("The service has never been opened or it was closed previously.");
return client.Update (updateInfo);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.PeerResolvers;
using System.ServiceModel.Description;
namespace System.ServiceModel.PeerResolvers
{
[DataContract (Namespace = "http://mono-project.com/ns/2008/07/peer-resolver")]
class PeerServiceSettingsInfo
{
[DataMember]
public TimeSpan RefreshInterval { get; set; }
[DataMember]
public TimeSpan CleanupInterval { get; set; }
[DataMember]
public bool ControlMeshShape { get; set; }
}
[ServiceContract]
interface ICustomPeerResolverContract : IPeerResolverContract
{
[OperationContract]
PeerServiceSettingsInfo GetCustomServiceSettings ();
[OperationContract]
void SetCustomServiceSettings (PeerServiceSettingsInfo info);
}
interface ICustomPeerResolverClient : ICustomPeerResolverContract, IClientChannel
{
}
}

View File

@@ -0,0 +1,226 @@
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.PeerResolvers;
using System.ServiceModel.Description;
namespace System.ServiceModel.PeerResolvers
{
[ServiceContract (Namespace = Constants.NetPeer, SessionMode = SessionMode.Allowed, CallbackContract = typeof (IPeerConnectorContract))]
internal interface IPeerConnectorContract
{
[OperationContract (Action = Constants.NetPeer + "/Connect", IsOneWay = true)]
void Connect (ConnectInfo connect);
[OperationContract (Action = Constants.NetPeer + "/Welcome", IsOneWay = true)]
void Welcome (WelcomeInfo welcome);
[OperationContract (Action = Constants.NetPeer + "/Refuse", IsOneWay = true)]
void Refuse (RefuseInfo refuse);
[OperationContract (Action = Constants.NetPeer + "/Disconnect", IsOneWay = true)]
void Disconnect (DisconnectInfo disconnect);
[OperationContract (Action = Constants.NetPeer + "/LinkUtility", IsOneWay = true)]
void LinkUtility (LinkUtilityInfo linkUtility);
[OperationContract (Action = Constants.NetPeer + "/Ping", IsOneWay = true)]
void Ping ();
[OperationContract (Action = "*", IsOneWay = true)]
void SendMessage (Message msg);
}
// Common datatype
[DataContract (Name = "Referral", Namespace = Constants.NetPeer)]
internal class Referral
{
[DataMember]
public ulong Id { get; set; }
[DataMember]
public PeerNodeAddress PeerNodeAddress { get; set; }
}
internal enum RefuseReason
{
DuplicateNeighbor,
DuplicateNodeId,
NodeBusy,
}
internal enum DisconnectReason
{
LeavingMesh,
NotUsefulNeighbor,
DuplicateNeighbor,
DuplicateNodeId,
}
// Connect
[DataContract (Name = "Connect", Namespace = Constants.NetPeer)]
internal class ConnectInfoDC
{
[DataMember]
public PeerNodeAddress Address { get; set; }
[DataMember]
public ulong NodeId { get; set; }
}
[MessageContract (IsWrapped = false)]
internal class ConnectInfo
{
public ConnectInfo ()
{
dc = new ConnectInfoDC ();
}
[MessageBodyMember (Name = "Connect", Namespace = Constants.NetPeer)]
ConnectInfoDC dc;
public PeerNodeAddress Address {
get { return dc.Address; }
set { dc.Address = value; }
}
public ulong NodeId {
get { return dc.NodeId; }
set { dc.NodeId = value; }
}
}
// Welcome
[DataContract (Name = "Welcome", Namespace = Constants.NetPeer)]
internal class WelcomeInfoDC
{
[DataMember]
public ulong NodeId { get; set; }
[DataMember]
public Referral [] Referrals { get; set; }
}
[MessageContract (IsWrapped = false)]
internal class WelcomeInfo
{
public WelcomeInfo ()
{
dc = new WelcomeInfoDC ();
}
[MessageBodyMember (Name = "Welcome", Namespace = Constants.NetPeer)]
WelcomeInfoDC dc;
public ulong NodeId {
get { return dc.NodeId; }
set { dc.NodeId = value; }
}
public Referral [] Referrals {
get { return dc.Referrals; }
set { dc.Referrals = value; }
}
}
// Refuse
[DataContract (Name = "Refuse", Namespace = Constants.NetPeer)]
internal class RefuseInfoDC
{
[DataMember]
public Referral [] Referrals { get; set; }
[DataMember]
public RefuseReason Reason { get; set; }
}
[MessageContract (IsWrapped = false)]
internal class RefuseInfo
{
public RefuseInfo ()
{
dc = new RefuseInfoDC ();
}
[MessageBodyMember (Name = "Refuse", Namespace = Constants.NetPeer)]
RefuseInfoDC dc;
public Referral [] Referrals {
get { return dc.Referrals; }
set { dc.Referrals = value; }
}
public RefuseReason Reason {
get { return dc.Reason; }
set { dc.Reason = value; }
}
}
// Disconnect
[DataContract (Name = "Disconnect", Namespace = Constants.NetPeer)]
internal class DisconnectInfoDC
{
[DataMember]
public Referral [] Referrals { get; set; }
[DataMember]
public DisconnectReason Reason { get; set; }
}
[MessageContract (IsWrapped = false)]
internal class DisconnectInfo
{
public DisconnectInfo ()
{
dc = new DisconnectInfoDC ();
}
[MessageBodyMember (Name = "Disconnect", Namespace = Constants.NetPeer)]
DisconnectInfoDC dc;
public Referral [] Referrals {
get { return dc.Referrals; }
set { dc.Referrals = value; }
}
public DisconnectReason Reason {
get { return dc.Reason; }
set { dc.Reason = value; }
}
}
// LinkUtilityInfo
[DataContract (Name = "LinkUtilityInfo", Namespace = Constants.NetPeer)]
internal class LinkUtilityInfoDC
{
[DataMember]
public uint Total { get; set; }
[DataMember]
public uint Useful { get; set; }
}
[MessageContract (IsWrapped = false)]
internal class LinkUtilityInfo
{
public LinkUtilityInfo ()
{
dc = new LinkUtilityInfoDC ();
}
[MessageBodyMember (Name = "LinkUtilityInfo", Namespace = Constants.NetPeer)]
LinkUtilityInfoDC dc;
public uint Total {
get { return dc.Total; }
set { dc.Total = value; }
}
public uint Useful {
get { return dc.Useful; }
set { dc.Useful = value; }
}
}
}

View File

@@ -0,0 +1,39 @@
//
// IPeerResolverContract.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
namespace System.ServiceModel.PeerResolvers
{
[ServiceContract (Name = "IPeerResolverContract", Namespace = "http://schemas.microsoft.com/net/2006/05/peer/resolver", SessionMode = SessionMode.Allowed)]
public interface IPeerResolverContract
{
[OperationContract (IsOneWay = false, Name = "GetServiceInfo",
Action = "http://schemas.microsoft.com/net/2006/05/peer/resolver/GetServiceSettings",
ReplyAction = "http://schemas.microsoft.com/net/2006/05/peer/resolver/GetServiceSettingsResponse")]
ServiceSettingsResponseInfo GetServiceSettings ();
[OperationContract (IsOneWay = false, Name = "Refresh",
Action = "http://schemas.microsoft.com/net/2006/05/peer/resolver/Refresh",
ReplyAction = "http://schemas.microsoft.com/net/2006/05/peer/resolver/RefreshResponse")]
RefreshResponseInfo Refresh (RefreshInfo refreshInfo);
[OperationContract (IsOneWay = false, Name = "Register",
Action = "http://schemas.microsoft.com/net/2006/05/peer/resolver/Register",
ReplyAction = "http://schemas.microsoft.com/net/2006/05/peer/resolver/RegisterResponse")]
RegisterResponseInfo Register (RegisterInfo registerInfo);
[OperationContract (IsOneWay = false, Name = "Resolve",
Action = "http://schemas.microsoft.com/net/2006/05/peer/resolver/Resolve",
ReplyAction = "http://schemas.microsoft.com/net/2006/05/peer/resolver/ResolveResponse")]
ResolveResponseInfo Resolve (ResolveInfo resolveInfo);
[OperationContract (IsOneWay = false, Name = "Unregister",
Action = "http://schemas.microsoft.com/net/2006/05/peer/resolver/Unregister")]
void Unregister (UnregisterInfo unregisterInfo);
[OperationContract (IsOneWay = false, Name = "Update",
Action = "http://schemas.microsoft.com/net/2006/05/peer/resolver/Update",
ReplyAction = "http://schemas.microsoft.com/net/2006/05/peer/resolver/UpdateResponse")]
RegisterResponseInfo Update (UpdateInfo updateInfo);
}
}

View File

@@ -0,0 +1,214 @@
//
// LocalPeerResolverService.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 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.
//
#if true
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.PeerResolvers;
namespace System.ServiceModel.PeerResolvers
{
// This implementation of peer resolver should open up node
// registration to some extent, say, valid within the same machine.
//
// A correct implementation should be using something like zeroconf
// to register the local machine as a peer node.
class LocalPeerResolverService : ICustomPeerResolverContract
{
public LocalPeerResolverService (TextWriter log)
{
this.log = log ?? TextWriter.Null;
}
TextWriter log;
Dictionary<string,Mesh> mesh_map = new Dictionary<string,Mesh> ();
// CustomPeerResolverService delegation
// Open(), Close(), ControlShape, RefreshInterval, CleanupInterval
public bool ControlShape { get; set; }
public TimeSpan RefreshInterval { get; set; }
public TimeSpan CleanupInterval { get; set; }
// (internal) ICustomPeerResolverContract implementation
public PeerServiceSettingsInfo GetCustomServiceSettings ()
{
log.WriteLine ("REQUEST: GetCustomServiceSettings");
return new PeerServiceSettingsInfo () {
ControlMeshShape = this.ControlShape,
RefreshInterval = this.RefreshInterval,
CleanupInterval = this.CleanupInterval };
}
public void SetCustomServiceSettings (PeerServiceSettingsInfo info)
{
log.WriteLine ("REQUEST: SetCustomServiceSettings(ControlMeshShape:{0}, RefreshInterval:{1}, CleanupInterval:{2}", info.ControlMeshShape, info.RefreshInterval, info.CleanupInterval);
ControlShape = info.ControlMeshShape;
RefreshInterval = info.RefreshInterval;
CleanupInterval = info.CleanupInterval;
}
// IPeerResolverContract implementation
public ServiceSettingsResponseInfo GetServiceSettings ()
{
return new ServiceSettingsResponseInfo () { ControlMeshShape = this.ControlShape };
}
public RefreshResponseInfo Refresh (RefreshInfo refreshInfo)
{
var r = refreshInfo;
log.WriteLine ("REQUEST: Refresh (Mesh: {0}, Registraion: {1})", r.MeshId, r.RegistrationId);
var mesh = GetExistingMesh (r.MeshId);
var node = mesh.FirstOrDefault (n => n.RegistrationId == r.RegistrationId);
if (node == null)
return new RefreshResponseInfo () { Result = RefreshResult.RegistrationNotFound };
node.Refresh ();
return new RefreshResponseInfo () { Result = RefreshResult.Success, RegistrationLifetime = RefreshInterval - (DateTime.Now - node.LastRefreshTime) };
}
public RegisterResponseInfo Register (RegisterInfo registerInfo)
{
var r = registerInfo;
log.WriteLine ("REQUEST: Register (Mesh: {0}, Client: {1}, NodeAddress: endpoint {2})", r.MeshId, r.ClientId, r.NodeAddress.EndpointAddress);
Mesh mesh;
if (!mesh_map.TryGetValue (r.MeshId, out mesh)) {
mesh = new Mesh (r.MeshId);
mesh_map.Add (r.MeshId, mesh);
}
var node = RegisterNode (mesh, r.ClientId, r.NodeAddress);
return new RegisterResponseInfo () { RegistrationId = node.RegistrationId };
}
public ResolveResponseInfo Resolve (ResolveInfo resolveInfo)
{
var r = resolveInfo;
log.WriteLine ("REQUEST: Resolve (Mesh: {0}, Client: {1}, MaxAddresses: {2})", r.MeshId, r.ClientId, r.MaxAddresses);
Mesh mesh;
var rr = new ResolveResponseInfo ();
if (!mesh_map.TryGetValue (r.MeshId, out mesh))
return rr;
// FIXME: find out how to use the argument ClientId.
// So far, it is used to filter out the registered node from the same ClientId.
foreach (var node in mesh.TakeWhile (n => n.ClientId != r.ClientId)) {
rr.Addresses.Add (node.Address);
if (rr.Addresses.Count == r.MaxAddresses)
break;
}
return rr;
}
public void Unregister (UnregisterInfo unregisterInfo)
{
var u = unregisterInfo;
log.WriteLine ("REQUEST: Unregister (Mesh: {0}, Registration: {1})", u.MeshId, u.RegistrationId);
Mesh mesh = GetExistingMesh (u.MeshId);
lock (mesh) {
var node = mesh.GetRegisteredNode (u.RegistrationId);
mesh.Remove (node);
}
}
public RegisterResponseInfo Update (UpdateInfo updateInfo)
{
var u = updateInfo;
log.WriteLine ("REQUEST: Update (Mesh: {0}, Registration: {1}, NodeAddress:)", u.MeshId, u.RegistrationId, u.NodeAddress);
var mesh = GetExistingMesh (u.MeshId);
var node = mesh.GetRegisteredNode (u.RegistrationId);
node.Update (u.NodeAddress);
return new RegisterResponseInfo () { RegistrationId = node.RegistrationId };
}
Mesh GetExistingMesh (string meshId)
{
Mesh mesh;
if (!mesh_map.TryGetValue (meshId, out mesh))
throw new InvalidOperationException (String.Format ("Specified mesh {0} does not exist", meshId));
return mesh;
}
Node RegisterNode (Mesh mesh, Guid clientId, PeerNodeAddress addr)
{
lock (mesh) {
var node = new Node () { ClientId = clientId, Address = addr };
mesh.Add (node);
node.LastRefreshTime = DateTime.Now;
return node;
}
}
}
class Mesh : List<Node>
{
public Mesh (string id)
{
Id = id;
}
public string Id { get; private set; }
public Node GetRegisteredNode (Guid registrationId)
{
var node = this.FirstOrDefault (n => n.RegistrationId == registrationId);
if (node == null)
throw new InvalidOperationException (String.Format ("Node with registration Id {0} does not exist in the specified mesh {0}", registrationId, Id));
return node;
}
}
class Node
{
public Node ()
{
RegistrationId = Guid.NewGuid ();
}
public Guid RegistrationId { get; private set; }
public Guid ClientId { get; set; }
public PeerNodeAddress Address { get; set; }
public DateTime LastRefreshTime { get; set; }
public void Refresh ()
{
LastRefreshTime = DateTime.Now;
}
public void Update (PeerNodeAddress addr)
{
Address = addr;
LastRefreshTime = DateTime.Now;
}
}
}
#endif

View File

@@ -0,0 +1,45 @@
//
// PeerCustomResolverSettings.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System;
using System.ServiceModel.Channels;
namespace System.ServiceModel.PeerResolvers
{
public class PeerCustomResolverSettings
{
public PeerCustomResolverSettings ()
{
}
public EndpointAddress Address { get; set; }
public Binding Binding { get; set; }
public bool IsBindingSpecified {
get { return Binding != null; }
}
public PeerResolver Resolver { get; set; }
internal PeerCustomResolverBindingElement CreateBinding ()
{
return new PeerCustomResolverBindingElement (this);
}
internal PeerCustomResolverSettings Clone ()
{
return new PeerCustomResolverSettings () {
Binding = this.Binding,
Address = this.Address,
Resolver = this.Resolver
};
}
}
}

View File

@@ -0,0 +1,18 @@
//
// PeerReferralPolicy.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
namespace System.ServiceModel.PeerResolvers
{
public enum PeerReferralPolicy
{
Service,
Share,
DoNotShare
}
}

View File

@@ -0,0 +1,19 @@
//
// PeerResolverMode.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System;
namespace System.ServiceModel.PeerResolvers
{
public enum PeerResolverMode {
Auto,
Pnrp,
Custom
}
}

View File

@@ -0,0 +1,45 @@
//
// PeerResolverSettings.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System;
using System.ServiceModel.Channels;
namespace System.ServiceModel.PeerResolvers
{
public class PeerResolverSettings
{
PeerCustomResolverSettings custom = new PeerCustomResolverSettings ();
// FIXME: Is it really by default Auto?
PeerResolverMode mode = PeerResolverMode.Auto;
public PeerResolverSettings ()
{
}
public PeerCustomResolverSettings Custom {
get { return custom; }
}
public PeerResolverMode Mode { get; set; }
public PeerReferralPolicy ReferralPolicy { get; set; }
internal BindingElement CreateBinding ()
{
switch (Mode) {
case PeerResolverMode.Pnrp:
return new PnrpPeerResolverBindingElement () { ReferralPolicy = this.ReferralPolicy };
default:
var be = Custom.CreateBinding ();
be.ReferralPolicy = this.ReferralPolicy;
return be;
}
}
}
}

View File

@@ -0,0 +1,75 @@
//
// RefreshInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class RefreshInfo
{
[MessageBodyMember (Name = "Refresh", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
RefreshInfoDC Body {
get {
if (body == null)
body = new RefreshInfoDC ();
return body;
}
set { body = value; }
}
RefreshInfoDC body;
public RefreshInfo ()
{
}
public RefreshInfo (string meshId, Guid regId)
: this ()
{
Body.MeshId = meshId;
Body.RegistrationId = regId;
}
public string MeshId {
get { return Body.MeshId; }
}
public Guid RegistrationId {
get { return Body.RegistrationId; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "Refresh", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class RefreshInfoDC
{
string mesh_id;
Guid registration_id;
public RefreshInfoDC ()
{
}
[DataMember]
public string MeshId {
get { return mesh_id; }
set { mesh_id = value; }
}
[DataMember]
public Guid RegistrationId {
get { return registration_id; }
set { registration_id = value; }
}
}
}

View File

@@ -0,0 +1,76 @@
//
// RefreshResponseInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class RefreshResponseInfo
{
[MessageBodyMember (Name = "RefreshResponse", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
RefreshResponseInfoDC Body {
get {
if (body == null)
body = new RefreshResponseInfoDC ();
return body;
}
set { body = value; }
}
RefreshResponseInfoDC body;
public RefreshResponseInfo ()
{
}
public RefreshResponseInfo (TimeSpan registrationLifetime, RefreshResult result)
{
Body.RegistrationLifetime = registrationLifetime;
Body.Result = result;
}
public TimeSpan RegistrationLifetime {
get { return Body.RegistrationLifetime; }
set { Body.RegistrationLifetime = value; }
}
public RefreshResult Result {
get { return Body.Result; }
set { Body.Result = value; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "RefreshResponse", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class RefreshResponseInfoDC
{
TimeSpan registration_lifetime;
RefreshResult result;
public RefreshResponseInfoDC ()
{
}
[DataMember]
public TimeSpan RegistrationLifetime {
get { return registration_lifetime; }
set { registration_lifetime = value; }
}
[DataMember]
public RefreshResult Result {
get { return result; }
set { result = value; }
}
}
}

View File

@@ -0,0 +1,16 @@
//
// RefreshResult.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
namespace System.ServiceModel.PeerResolvers
{
public enum RefreshResult {
Success,
RegistrationNotFound
}
}

View File

@@ -0,0 +1,108 @@
//
// RegisterInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
// Copyright (C) 2007 Novell, Inc. http://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.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class RegisterInfo
{
[MessageBodyMember (Name = "Register", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
RegisterInfoDC Body {
get {
if (body == null)
body = new RegisterInfoDC ();
return body;
}
set { body = value; }
}
RegisterInfoDC body;
public RegisterInfo ()
{
}
public RegisterInfo (Guid client, string meshId, PeerNodeAddress address)
: this ()
{
Body.ClientId = client;
Body.MeshId = meshId;
Body.NodeAddress = address;
}
public Guid ClientId {
get { return Body.ClientId; }
}
public string MeshId {
get { return Body.MeshId; }
}
public PeerNodeAddress NodeAddress {
get { return Body.NodeAddress; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class RegisterInfoDC
{
Guid client_id;
string mesh_id;
PeerNodeAddress node_address;
public RegisterInfoDC ()
{
}
[DataMember]
public Guid ClientId {
get { return client_id; }
set { client_id = value; }
}
[DataMember]
public string MeshId {
get { return mesh_id; }
set { mesh_id = value; }
}
[DataMember]
public PeerNodeAddress NodeAddress {
get { return node_address; }
set { node_address = value; }
}
}
}

View File

@@ -0,0 +1,76 @@
//
// RegisterResponseInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class RegisterResponseInfo
{
[MessageBodyMember (Name = "Update", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")] // .NET indeed returns "Update" element here.
RegisterResponseInfoDC Body {
get {
if (body == null)
body = new RegisterResponseInfoDC ();
return body;
}
set { body = value; }
}
RegisterResponseInfoDC body;
public RegisterResponseInfo ()
{
}
public RegisterResponseInfo (Guid registrationId, TimeSpan registrationLifetime)
{
Body.RegistrationId = registrationId;
Body.RegistrationLifetime = registrationLifetime;
}
public Guid RegistrationId {
get { return Body.RegistrationId; }
set { Body.RegistrationId = value; }
}
public TimeSpan RegistrationLifetime {
get { return Body.RegistrationLifetime; }
set { Body.RegistrationLifetime = value; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "Update", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class RegisterResponseInfoDC
{
Guid registration_id;
TimeSpan registration_lifetime;
public RegisterResponseInfoDC ()
{
}
[DataMember]
public Guid RegistrationId {
get { return registration_id; }
set { registration_id = value; }
}
[DataMember (EmitDefaultValue = false)]
public TimeSpan RegistrationLifetime {
get { return registration_lifetime; }
set { registration_lifetime = value; }
}
}
}

View File

@@ -0,0 +1,90 @@
//
// ResolveInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class ResolveInfo
{
[MessageBodyMember (Name = "Resolve", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
ResolveInfoDC Body {
get {
if (body == null)
body = new ResolveInfoDC ();
return body;
}
set { body = value; }
}
ResolveInfoDC body;
public ResolveInfo ()
{
}
public ResolveInfo (Guid clientId, string meshId, int maxAddresses)
{
if (clientId == Guid.Empty)
throw new ArgumentException ("Empty Guid");
if (String.IsNullOrEmpty (meshId))
throw new ArgumentNullException ("meshId");
if (maxAddresses <= 0)
throw new ArgumentOutOfRangeException ("maxAddresses must be positive integer");
Body.ClientId = clientId;
Body.MeshId = meshId;
Body.MaxAddresses = maxAddresses;
}
public Guid ClientId {
get { return Body.ClientId; }
}
public int MaxAddresses {
get { return Body.MaxAddresses; }
}
public string MeshId {
get { return Body.MeshId; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "Resolve", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class ResolveInfoDC
{
Guid client_id;
int max_addresses;
string mesh_id;
public ResolveInfoDC ()
{
}
[DataMember]
public Guid ClientId {
get { return client_id; }
set { client_id = value; }
}
[DataMember]
public int MaxAddresses {
get { return max_addresses; }
set { max_addresses = value; }
}
[DataMember]
public string MeshId {
get { return mesh_id; }
set { mesh_id = value; }
}
}
}

View File

@@ -0,0 +1,65 @@
//
// ResolveResponseInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class ResolveResponseInfo
{
[MessageBodyMember (Name = "ResolveResponse", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
ResolveResponseInfoDC Body {
get {
if (body == null)
body = new ResolveResponseInfoDC ();
return body;
}
set { body = value; }
}
ResolveResponseInfoDC body;
public ResolveResponseInfo ()
{
}
public ResolveResponseInfo (PeerNodeAddress [] addresses)
{
Body.Addresses = new List<PeerNodeAddress> (addresses);
}
public IList<PeerNodeAddress> Addresses {
get { return Body.Addresses; }
set { Body.Addresses = value; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "ResolveResponse", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class ResolveResponseInfoDC
{
IList<PeerNodeAddress> addresses;
public ResolveResponseInfoDC ()
{
addresses = new List<PeerNodeAddress> ();
}
[DataMember]
public IList<PeerNodeAddress> Addresses {
get { return addresses; }
set { addresses = value; }
}
}
}

View File

@@ -0,0 +1,63 @@
//
// ServiceSettingsResponseInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class ServiceSettingsResponseInfo
{
[MessageBodyMember (Name = "ServiceSettings", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
ServiceSettingsResponseInfoDC Body {
get {
if (body == null)
body = new ServiceSettingsResponseInfoDC ();
return body;
}
set { body = value; }
}
ServiceSettingsResponseInfoDC body;
public ServiceSettingsResponseInfo ()
{
}
public ServiceSettingsResponseInfo (bool control)
{
Body.ControlMeshShape = control;
}
public bool ControlMeshShape {
get { return Body.ControlMeshShape; }
set { Body.ControlMeshShape = value; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "ServiceSettings", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class ServiceSettingsResponseInfoDC
{
bool control_mesh_shape;
public ServiceSettingsResponseInfoDC ()
{
}
[DataMember]
public bool ControlMeshShape {
get { return control_mesh_shape; }
set { control_mesh_shape = value; }
}
}
}

View File

@@ -0,0 +1,74 @@
//
// UnregisterInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class UnregisterInfo
{
[MessageBodyMember (Name = "Unregister", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
UnregisterInfoDC Body {
get {
if (body == null)
body = new UnregisterInfoDC ();
return body;
}
set { body = value; }
}
UnregisterInfoDC body;
public UnregisterInfo ()
{
}
public UnregisterInfo (string meshId, Guid registration_id)
{
Body.MeshId = meshId;
Body.RegistrationId = registration_id;
}
public string MeshId {
get { return Body.MeshId; }
}
public Guid RegistrationId {
get { return Body.RegistrationId; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "Unregister", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class UnregisterInfoDC
{
string mesh_id;
Guid registration_id;
public UnregisterInfoDC ()
{
}
[DataMember]
public string MeshId {
get { return mesh_id; }
set { mesh_id = value; }
}
[DataMember]
public Guid RegistrationId {
get { return registration_id; }
set { registration_id = value; }
}
}
}

View File

@@ -0,0 +1,99 @@
//
// UpdateInfo.cs
//
// Author:
// Marcos Cobena (marcoscobena@gmail.com)
//
// Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
//
using System.Runtime.Serialization;
namespace System.ServiceModel.PeerResolvers
{
[MessageContract (IsWrapped = false)]
public class UpdateInfo
{
[MessageBodyMember (Name = "Update", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
UpdateInfoDC Body {
get {
if (body == null)
body = new UpdateInfoDC ();
return body;
}
set { body = value; }
}
UpdateInfoDC body;
public UpdateInfo ()
{
}
public UpdateInfo (Guid registrationId, Guid client, string meshId, PeerNodeAddress address)
: this ()
{
Body.RegistrationId = registrationId;
Body.ClientId = client;
Body.MeshId = meshId;
Body.NodeAddress = address;
}
public Guid ClientId {
get { return Body.ClientId; }
}
public string MeshId {
get { return Body.MeshId; }
}
public PeerNodeAddress NodeAddress {
get { return Body.NodeAddress; }
}
public Guid RegistrationId {
get { return Body.RegistrationId; }
}
public bool HasBody ()
{
return true; // FIXME: I have no idea when it returns false
}
}
[DataContract (Name = "Update", Namespace = "http://schemas.microsoft.com/net/2006/05/peer")]
internal class UpdateInfoDC
{
Guid client_id;
string mesh_id;
PeerNodeAddress node_address;
Guid registration_id;
public UpdateInfoDC ()
{
}
[DataMember]
public Guid ClientId {
get { return client_id; }
set { client_id = value; }
}
[DataMember]
public string MeshId {
get { return mesh_id; }
set { mesh_id = value; }
}
[DataMember]
public PeerNodeAddress NodeAddress {
get { return node_address; }
set { node_address = value; }
}
[DataMember]
public Guid RegistrationId {
get { return registration_id; }
set { registration_id = value; }
}
}
}