You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,217 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
class AnnouncementDispatcherAsyncResult : AsyncResult
|
||||
{
|
||||
readonly AnnouncementSendsAsyncResult[] innerResults;
|
||||
|
||||
[Fx.Tag.SynchronizationObject(Blocking = false, Kind = Fx.Tag.SynchronizationKind.InterlockedNoSpin)]
|
||||
int completions;
|
||||
|
||||
AsyncCallback onAnnouncementSendsCompletedCallback;
|
||||
|
||||
[Fx.Tag.SynchronizationObject(Blocking = false, Kind = Fx.Tag.SynchronizationKind.InterlockedNoSpin)]
|
||||
int completesCounter;
|
||||
|
||||
bool cancelled;
|
||||
|
||||
[Fx.Tag.SynchronizationObject()]
|
||||
object thisLock;
|
||||
|
||||
public AnnouncementDispatcherAsyncResult(
|
||||
Collection<AnnouncementEndpoint> endpoints,
|
||||
Collection<EndpointDiscoveryMetadata> metadatas,
|
||||
DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator,
|
||||
bool online,
|
||||
AsyncCallback callback,
|
||||
object state
|
||||
)
|
||||
: base(callback, state)
|
||||
{
|
||||
if (metadatas.Count == 0)
|
||||
{
|
||||
Complete(true);
|
||||
return;
|
||||
}
|
||||
bool success = false;
|
||||
this.cancelled = false;
|
||||
this.thisLock = new object();
|
||||
this.innerResults = new AnnouncementSendsAsyncResult[endpoints.Count];
|
||||
this.onAnnouncementSendsCompletedCallback = Fx.ThunkCallback(new AsyncCallback(OnAnnouncementSendsCompleted));
|
||||
Collection<UniqueId> messageIds = AllocateMessageIds(metadatas.Count);
|
||||
|
||||
try
|
||||
{
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < this.innerResults.Length; i++)
|
||||
{
|
||||
AnnouncementClient announcementClient = new AnnouncementClient(endpoints[i]);
|
||||
announcementClient.MessageSequenceGenerator = discoveryMessageSequenceGenerator;
|
||||
this.innerResults[i] =
|
||||
new AnnouncementSendsAsyncResult(
|
||||
announcementClient,
|
||||
metadatas,
|
||||
messageIds,
|
||||
online,
|
||||
endpoints[i].MaxAnnouncementDelay,
|
||||
random,
|
||||
this.onAnnouncementSendsCompletedCallback,
|
||||
this);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
this.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Start(TimeSpan timeout, bool canCompleteSynchronously)
|
||||
{
|
||||
if (this.IsCompleted || this.cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool synchronousCompletion = canCompleteSynchronously;
|
||||
Exception error = null;
|
||||
bool complete = false;
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < this.innerResults.Length; i++)
|
||||
{
|
||||
this.innerResults[i].Start(timeout);
|
||||
if (this.innerResults[i].CompletedSynchronously)
|
||||
{
|
||||
AnnouncementSendsAsyncResult.End(this.innerResults[i]);
|
||||
complete = (Interlocked.Increment(ref this.completions) == innerResults.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
synchronousCompletion = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (Fx.IsFatal(e))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
error = e;
|
||||
}
|
||||
if (error != null)
|
||||
{
|
||||
CallCompleteOnce(synchronousCompletion, error);
|
||||
}
|
||||
else if (complete)
|
||||
{
|
||||
CallCompleteOnce(synchronousCompletion, null);
|
||||
}
|
||||
}
|
||||
|
||||
void OnAnnouncementSendsCompleted(IAsyncResult result)
|
||||
{
|
||||
if (!result.CompletedSynchronously)
|
||||
{
|
||||
Exception error = null;
|
||||
try
|
||||
{
|
||||
AnnouncementSendsAsyncResult.End(result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (Fx.IsFatal(e))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
error = e;
|
||||
}
|
||||
if (error != null)
|
||||
{
|
||||
CallCompleteOnce(false, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Interlocked.Increment(ref this.completions) == innerResults.Length)
|
||||
{
|
||||
CallCompleteOnce(false, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (!this.cancelled)
|
||||
{
|
||||
bool doCancel = false;
|
||||
lock (this.thisLock)
|
||||
{
|
||||
if (!this.cancelled)
|
||||
{
|
||||
doCancel = true;
|
||||
this.cancelled = true;
|
||||
}
|
||||
}
|
||||
if (doCancel)
|
||||
{
|
||||
for (int i = 0; i < this.innerResults.Length; i++)
|
||||
{
|
||||
if (this.innerResults[i] != null)
|
||||
{
|
||||
this.innerResults[i].Cancel();
|
||||
}
|
||||
}
|
||||
CompleteOnCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CompleteOnCancel()
|
||||
{
|
||||
if (Threading.Interlocked.Increment(ref this.completesCounter) == 1)
|
||||
{
|
||||
Complete(false, new OperationCanceledException());
|
||||
}
|
||||
}
|
||||
|
||||
void CallCompleteOnce(bool completedSynchronously, Exception e)
|
||||
{
|
||||
if (Threading.Interlocked.Increment(ref this.completesCounter) == 1)
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
Cancel();
|
||||
}
|
||||
Complete(completedSynchronously, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void End(IAsyncResult result)
|
||||
{
|
||||
AsyncResult.End<AnnouncementDispatcherAsyncResult>(result);
|
||||
}
|
||||
|
||||
static Collection<UniqueId> AllocateMessageIds(int count)
|
||||
{
|
||||
Collection<UniqueId> messageIds = new Collection<UniqueId>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
messageIds.Add(new UniqueId());
|
||||
}
|
||||
|
||||
return messageIds;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Description;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
public class AnnouncementEndpoint : ServiceEndpoint
|
||||
{
|
||||
TimeSpan maxAnnouncementDelay;
|
||||
DiscoveryVersion discoveryVersion;
|
||||
|
||||
public AnnouncementEndpoint()
|
||||
: this(DiscoveryVersion.DefaultDiscoveryVersion)
|
||||
{
|
||||
}
|
||||
|
||||
public AnnouncementEndpoint(Binding binding, EndpointAddress address)
|
||||
: this(DiscoveryVersion.DefaultDiscoveryVersion, binding, address)
|
||||
{
|
||||
}
|
||||
|
||||
public AnnouncementEndpoint(DiscoveryVersion discoveryVersion)
|
||||
: this(discoveryVersion, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public AnnouncementEndpoint(DiscoveryVersion discoveryVersion, Binding binding, EndpointAddress address)
|
||||
: base(GetAnnouncementContract(discoveryVersion))
|
||||
{
|
||||
// Send replies async to maintain performance
|
||||
this.EndpointBehaviors.Add(new DispatcherSynchronizationBehavior { AsynchronousSendEnabled = true });
|
||||
|
||||
this.discoveryVersion = discoveryVersion;
|
||||
base.Address = address;
|
||||
base.Binding = binding;
|
||||
}
|
||||
|
||||
public TimeSpan MaxAnnouncementDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxAnnouncementDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
TimeoutHelper.ThrowIfNegativeArgument(value, "value");
|
||||
this.maxAnnouncementDelay = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DiscoveryVersion DiscoveryVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.discoveryVersion;
|
||||
}
|
||||
}
|
||||
|
||||
static ContractDescription GetAnnouncementContract(DiscoveryVersion discoveryVersion)
|
||||
{
|
||||
if (discoveryVersion == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("discoveryVersion");
|
||||
}
|
||||
|
||||
return discoveryVersion.Implementation.GetAnnouncementContract();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System;
|
||||
using System.Runtime;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
public class AnnouncementEventArgs : EventArgs
|
||||
{
|
||||
internal AnnouncementEventArgs(
|
||||
DiscoveryMessageSequence messageSequence,
|
||||
EndpointDiscoveryMetadata endpointDiscoveryMetadata)
|
||||
{
|
||||
this.MessageSequence = messageSequence;
|
||||
this.EndpointDiscoveryMetadata = endpointDiscoveryMetadata;
|
||||
}
|
||||
|
||||
public DiscoveryMessageSequence MessageSequence { get; private set; }
|
||||
|
||||
public EndpointDiscoveryMetadata EndpointDiscoveryMetadata { get; private set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System.Xml;
|
||||
using System.Runtime;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
|
||||
class AnnouncementSendsAsyncResult : RandomDelaySendsAsyncResult
|
||||
{
|
||||
AnnouncementClient announcementClient;
|
||||
Collection<EndpointDiscoveryMetadata> publishedEndpoints;
|
||||
Collection<UniqueId> messageIds;
|
||||
bool online;
|
||||
|
||||
internal AnnouncementSendsAsyncResult(
|
||||
AnnouncementClient announcementClient,
|
||||
Collection<EndpointDiscoveryMetadata> publishedEndpoints,
|
||||
Collection<UniqueId> messageIds,
|
||||
bool online,
|
||||
TimeSpan maxDelay,
|
||||
Random random,
|
||||
AsyncCallback callback,
|
||||
object state)
|
||||
: base(publishedEndpoints.Count, maxDelay, announcementClient, random, callback, state)
|
||||
{
|
||||
Fx.Assert(publishedEndpoints.Count == messageIds.Count, "There must be one message Ids for each EndpointDiscoveryMetadata.");
|
||||
this.announcementClient = announcementClient;
|
||||
this.publishedEndpoints = publishedEndpoints;
|
||||
this.messageIds = messageIds;
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginSend(int index, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
using (new OperationContextScope(this.announcementClient.InnerChannel))
|
||||
{
|
||||
OperationContext.Current.OutgoingMessageHeaders.MessageId = this.messageIds[index];
|
||||
|
||||
if (this.online)
|
||||
{
|
||||
return this.announcementClient.BeginAnnounceOnline(this.publishedEndpoints[index], callback, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.announcementClient.BeginAnnounceOffline(this.publishedEndpoints[index], callback, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnEndSend(IAsyncResult result)
|
||||
{
|
||||
if (this.online)
|
||||
{
|
||||
this.announcementClient.EndAnnounceOnline(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.announcementClient.EndAnnounceOffline(result);
|
||||
}
|
||||
}
|
||||
public static void End(IAsyncResult result)
|
||||
{
|
||||
AsyncResult.End<AnnouncementSendsAsyncResult>(result);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,211 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Discovery.Version11;
|
||||
using System.ServiceModel.Discovery.VersionApril2005;
|
||||
using System.ServiceModel.Discovery.VersionCD1;
|
||||
|
||||
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
|
||||
public class AnnouncementService :
|
||||
IAnnouncementContractApril2005,
|
||||
IAnnouncementContract11,
|
||||
IAnnouncementContractCD1,
|
||||
IAnnouncementServiceImplementation
|
||||
{
|
||||
DuplicateDetector<UniqueId> duplicateDetector;
|
||||
|
||||
public AnnouncementService()
|
||||
: this(DiscoveryDefaults.DuplicateMessageHistoryLength)
|
||||
{
|
||||
}
|
||||
|
||||
public AnnouncementService(int duplicateMessageHistoryLength)
|
||||
{
|
||||
if (duplicateMessageHistoryLength < 0)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentOutOfRange(
|
||||
"duplicateMessageHistoryLength",
|
||||
duplicateMessageHistoryLength,
|
||||
SR.DiscoveryNegativeDuplicateMessageHistoryLength);
|
||||
}
|
||||
|
||||
if (duplicateMessageHistoryLength > 0)
|
||||
{
|
||||
this.duplicateDetector = new DuplicateDetector<UniqueId>(duplicateMessageHistoryLength);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<AnnouncementEventArgs> OnlineAnnouncementReceived;
|
||||
public event EventHandler<AnnouncementEventArgs> OfflineAnnouncementReceived;
|
||||
|
||||
void IAnnouncementContractApril2005.HelloOperation(HelloMessageApril2005 message)
|
||||
{
|
||||
Fx.Assert("The [....] method IAnnouncementContractApril2005.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementContractApril2005.BeginHelloOperation(HelloMessageApril2005 message, AsyncCallback callback, object state)
|
||||
{
|
||||
return new HelloOperationApril2005AsyncResult(this, message, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementContractApril2005.EndHelloOperation(IAsyncResult result)
|
||||
{
|
||||
HelloOperationApril2005AsyncResult.End(result);
|
||||
}
|
||||
|
||||
void IAnnouncementContractApril2005.ByeOperation(ByeMessageApril2005 message)
|
||||
{
|
||||
Fx.Assert("The [....] method IAnnouncementContractApril2005.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementContractApril2005.BeginByeOperation(ByeMessageApril2005 message, AsyncCallback callback, object state)
|
||||
{
|
||||
return new ByeOperationApril2005AsyncResult(this, message, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementContractApril2005.EndByeOperation(IAsyncResult result)
|
||||
{
|
||||
ByeOperationApril2005AsyncResult.End(result);
|
||||
}
|
||||
|
||||
void IAnnouncementContract11.HelloOperation(HelloMessage11 message)
|
||||
{
|
||||
Fx.Assert("The [....] method IAnnouncementContract11.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementContract11.BeginHelloOperation(HelloMessage11 message, AsyncCallback callback, object state)
|
||||
{
|
||||
return new HelloOperation11AsyncResult(this, message, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementContract11.EndHelloOperation(IAsyncResult result)
|
||||
{
|
||||
HelloOperation11AsyncResult.End(result);
|
||||
}
|
||||
|
||||
void IAnnouncementContract11.ByeOperation(ByeMessage11 message)
|
||||
{
|
||||
Fx.Assert("The [....] method IAnnouncementContract11.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementContract11.BeginByeOperation(ByeMessage11 message, AsyncCallback callback, object state)
|
||||
{
|
||||
return new ByeOperation11AsyncResult(this, message, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementContract11.EndByeOperation(IAsyncResult result)
|
||||
{
|
||||
ByeOperation11AsyncResult.End(result);
|
||||
}
|
||||
|
||||
void IAnnouncementContractCD1.HelloOperation(HelloMessageCD1 message)
|
||||
{
|
||||
Fx.Assert("The [....] method IAnnouncementContractCD1.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementContractCD1.BeginHelloOperation(HelloMessageCD1 message, AsyncCallback callback, object state)
|
||||
{
|
||||
return new HelloOperationCD1AsyncResult(this, message, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementContractCD1.EndHelloOperation(IAsyncResult result)
|
||||
{
|
||||
HelloOperationCD1AsyncResult.End(result);
|
||||
}
|
||||
|
||||
void IAnnouncementContractCD1.ByeOperation(ByeMessageCD1 message)
|
||||
{
|
||||
Fx.Assert("The [....] method IAnnouncementContractCD1.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementContractCD1.BeginByeOperation(ByeMessageCD1 message, AsyncCallback callback, object state)
|
||||
{
|
||||
return new ByeOperationCD1AsyncResult(this, message, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementContractCD1.EndByeOperation(IAsyncResult result)
|
||||
{
|
||||
ByeOperationCD1AsyncResult.End(result);
|
||||
}
|
||||
|
||||
bool IAnnouncementServiceImplementation.IsDuplicate(UniqueId messageId)
|
||||
{
|
||||
return (this.duplicateDetector != null) && (!this.duplicateDetector.AddIfNotDuplicate(messageId));
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementServiceImplementation.OnBeginOnlineAnnouncement(
|
||||
DiscoveryMessageSequence messageSequence,
|
||||
EndpointDiscoveryMetadata endpointDiscoveryMetadata,
|
||||
AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
return this.OnBeginOnlineAnnouncement(messageSequence, endpointDiscoveryMetadata, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementServiceImplementation.OnEndOnlineAnnouncement(IAsyncResult result)
|
||||
{
|
||||
this.OnEndOnlineAnnouncement(result);
|
||||
}
|
||||
|
||||
IAsyncResult IAnnouncementServiceImplementation.OnBeginOfflineAnnouncement(
|
||||
DiscoveryMessageSequence messageSequence,
|
||||
EndpointDiscoveryMetadata endpointDiscoveryMetadata,
|
||||
AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
return this.OnBeginOfflineAnnouncement(messageSequence, endpointDiscoveryMetadata, callback, state);
|
||||
}
|
||||
|
||||
void IAnnouncementServiceImplementation.OnEndOfflineAnnouncement(IAsyncResult result)
|
||||
{
|
||||
this.OnEndOfflineAnnouncement(result);
|
||||
}
|
||||
|
||||
protected virtual IAsyncResult OnBeginOnlineAnnouncement(
|
||||
DiscoveryMessageSequence messageSequence,
|
||||
EndpointDiscoveryMetadata endpointDiscoveryMetadata,
|
||||
AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
EventHandler<AnnouncementEventArgs> handler = this.OnlineAnnouncementReceived;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new AnnouncementEventArgs(messageSequence, endpointDiscoveryMetadata));
|
||||
}
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected virtual void OnEndOnlineAnnouncement(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected virtual IAsyncResult OnBeginOfflineAnnouncement(
|
||||
DiscoveryMessageSequence messageSequence,
|
||||
EndpointDiscoveryMetadata endpointDiscoveryMetadata,
|
||||
AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
|
||||
EventHandler<AnnouncementEventArgs> handler = this.OfflineAnnouncementReceived;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new AnnouncementEventArgs(messageSequence, endpointDiscoveryMetadata));
|
||||
}
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected virtual void OnEndOfflineAnnouncement(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
// WARNING: This object is not thread safe.
|
||||
// Use SyncRoot to protect access to methods and properties as required.
|
||||
abstract class AsyncOperationContext
|
||||
{
|
||||
AsyncOperation asyncOperation;
|
||||
TimeSpan duration;
|
||||
bool isCompleted;
|
||||
int maxResults;
|
||||
UniqueId operationId;
|
||||
Nullable<DateTime> startTime;
|
||||
|
||||
[Fx.Tag.SynchronizationObject()]
|
||||
object syncRoot;
|
||||
|
||||
IOThreadTimer timer;
|
||||
object userState;
|
||||
|
||||
internal AsyncOperationContext(UniqueId operationId, int maxResults, TimeSpan duration, object userState)
|
||||
{
|
||||
Fx.Assert(operationId != null, "The operation id must be non null.");
|
||||
Fx.Assert(maxResults > 0, "The maxResults parameter must be positive.");
|
||||
Fx.Assert(duration > TimeSpan.Zero, "The duration parameter must be positive.");
|
||||
|
||||
this.maxResults = maxResults;
|
||||
this.duration = duration;
|
||||
this.userState = userState;
|
||||
this.operationId = operationId;
|
||||
this.syncRoot = new object();
|
||||
}
|
||||
|
||||
public AsyncOperation AsyncOperation
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.asyncOperation;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.asyncOperation = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.duration;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.isCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSyncOperation
|
||||
{
|
||||
get
|
||||
{
|
||||
return (UserState is SyncOperationState);
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxResults
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxResults;
|
||||
}
|
||||
}
|
||||
|
||||
public UniqueId OperationId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.operationId;
|
||||
}
|
||||
}
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
return syncRoot;
|
||||
}
|
||||
}
|
||||
|
||||
public object UserState
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.userState;
|
||||
}
|
||||
}
|
||||
|
||||
public Nullable<DateTime> StartedAt
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.startTime;
|
||||
}
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
{
|
||||
this.StopTimer();
|
||||
this.isCompleted = true;
|
||||
}
|
||||
|
||||
public void StartTimer(Action<object> waitCallback)
|
||||
{
|
||||
Fx.Assert(this.timer == null, "The timer object must be null.");
|
||||
Fx.Assert(this.isCompleted == false, "The timer cannot be started if the context is closed.");
|
||||
|
||||
this.startTime = DateTime.UtcNow;
|
||||
this.timer = new IOThreadTimer(waitCallback, this, false);
|
||||
this.timer.Set(this.Duration);
|
||||
}
|
||||
|
||||
void StopTimer()
|
||||
{
|
||||
if (this.timer != null)
|
||||
{
|
||||
this.timer.Cancel();
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,255 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using SR2 = System.ServiceModel.Discovery.SR;
|
||||
|
||||
class AsyncOperationLifetimeManager
|
||||
{
|
||||
[Fx.Tag.SynchronizationObject()]
|
||||
object thisLock;
|
||||
|
||||
bool isAborted;
|
||||
AsyncWaitHandle closeHandle;
|
||||
Dictionary<UniqueId, AsyncOperationContext> activeOperations;
|
||||
|
||||
public AsyncOperationLifetimeManager()
|
||||
{
|
||||
this.thisLock = new object();
|
||||
this.activeOperations = new Dictionary<UniqueId, AsyncOperationContext>();
|
||||
}
|
||||
|
||||
public bool IsAborted
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.isAborted;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClosed
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.closeHandle != null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryAdd(AsyncOperationContext context)
|
||||
{
|
||||
Fx.Assert(context != null, "The context must be non null.");
|
||||
|
||||
lock (this.thisLock)
|
||||
{
|
||||
if (this.IsAborted || this.IsClosed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.activeOperations.ContainsKey(context.OperationId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.activeOperations.Add(context.OperationId, context);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public AsyncOperationContext[] Abort()
|
||||
{
|
||||
AsyncOperationContext[] retValue = null;
|
||||
bool setCloseHandle = false;
|
||||
|
||||
lock (this.thisLock)
|
||||
{
|
||||
if (this.IsAborted)
|
||||
{
|
||||
return new AsyncOperationContext[] { };
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isAborted = true;
|
||||
}
|
||||
|
||||
retValue = new AsyncOperationContext[this.activeOperations.Count];
|
||||
this.activeOperations.Values.CopyTo(retValue, 0);
|
||||
this.activeOperations.Clear();
|
||||
setCloseHandle = this.closeHandle != null;
|
||||
}
|
||||
|
||||
if (setCloseHandle)
|
||||
{
|
||||
this.closeHandle.Set();
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public bool TryLookup(UniqueId operationId, out AsyncOperationContext context)
|
||||
{
|
||||
bool success;
|
||||
|
||||
lock (this.thisLock)
|
||||
{
|
||||
success = this.activeOperations.TryGetValue(operationId, out context);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public bool TryLookup<T>(UniqueId operationId, out T context) where T : AsyncOperationContext
|
||||
{
|
||||
AsyncOperationContext asyncContext = null;
|
||||
if (TryLookup(operationId, out asyncContext))
|
||||
{
|
||||
context = asyncContext as T;
|
||||
if (context != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
context = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public T Remove<T>(UniqueId operationId) where T : AsyncOperationContext
|
||||
{
|
||||
AsyncOperationContext context = null;
|
||||
bool setCloseHandle = false;
|
||||
|
||||
lock (this.thisLock)
|
||||
{
|
||||
if ((this.activeOperations.TryGetValue(operationId, out context)) &&
|
||||
(context is T))
|
||||
{
|
||||
this.activeOperations.Remove(operationId);
|
||||
setCloseHandle = (this.closeHandle != null) && (this.activeOperations.Count == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (setCloseHandle)
|
||||
{
|
||||
this.closeHandle.Set();
|
||||
}
|
||||
|
||||
return context as T;
|
||||
}
|
||||
|
||||
public bool TryRemoveUnique(object userState, out AsyncOperationContext context)
|
||||
{
|
||||
bool success = false;
|
||||
bool setCloseHandle = false;
|
||||
context = null;
|
||||
|
||||
lock (this.thisLock)
|
||||
{
|
||||
foreach (AsyncOperationContext value in this.activeOperations.Values)
|
||||
{
|
||||
if (object.Equals(value.UserState, userState))
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
context = value;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
this.activeOperations.Remove(context.OperationId);
|
||||
setCloseHandle = (this.closeHandle != null) && (this.activeOperations.Count == 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (setCloseHandle)
|
||||
{
|
||||
this.closeHandle.Set();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public void Close(TimeSpan timeout)
|
||||
{
|
||||
InitializeCloseHandle();
|
||||
if (!this.closeHandle.Wait(timeout))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new TimeoutException(SR2.TimeoutOnOperation(timeout)));
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
InitializeCloseHandle();
|
||||
return new CloseAsyncResult(this.closeHandle, timeout, callback, state);
|
||||
}
|
||||
|
||||
public void EndClose(IAsyncResult result)
|
||||
{
|
||||
CloseAsyncResult.End(result);
|
||||
}
|
||||
|
||||
void InitializeCloseHandle()
|
||||
{
|
||||
bool setCloseHandle = false;
|
||||
lock (this.thisLock)
|
||||
{
|
||||
this.closeHandle = new AsyncWaitHandle(EventResetMode.ManualReset);
|
||||
setCloseHandle = (this.activeOperations.Count == 0);
|
||||
|
||||
if (this.IsAborted)
|
||||
{
|
||||
setCloseHandle = true;
|
||||
}
|
||||
}
|
||||
if (setCloseHandle)
|
||||
{
|
||||
this.closeHandle.Set();
|
||||
}
|
||||
}
|
||||
|
||||
class CloseAsyncResult : AsyncResult
|
||||
{
|
||||
static Action<object, TimeoutException> onWaitCompleted = new Action<object, TimeoutException>(OnWaitCompleted);
|
||||
AsyncWaitHandle asyncWaitHandle;
|
||||
|
||||
internal CloseAsyncResult(AsyncWaitHandle asyncWaitHandle, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
this.asyncWaitHandle = asyncWaitHandle;
|
||||
if (this.asyncWaitHandle.WaitAsync(onWaitCompleted, this, timeout))
|
||||
{
|
||||
Complete(true);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnWaitCompleted(object state, TimeoutException asyncException)
|
||||
{
|
||||
CloseAsyncResult thisPtr = (CloseAsyncResult)state;
|
||||
thisPtr.Complete(false, asyncException);
|
||||
}
|
||||
|
||||
internal static void End(IAsyncResult result)
|
||||
{
|
||||
AsyncResult.End<CloseAsyncResult>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.Xml;
|
||||
using System.Runtime.Diagnostics;
|
||||
using System.ServiceModel.Diagnostics;
|
||||
|
||||
abstract class ByeOperationAsyncResult<TMessage> : AsyncResult
|
||||
where TMessage : class
|
||||
{
|
||||
static AsyncCompletion onOnOfflineAnnoucementCompletedCallback =
|
||||
new AsyncCompletion(OnOnOfflineAnnouncementCompleted);
|
||||
|
||||
IAnnouncementServiceImplementation announcementServiceImpl;
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||
internal ByeOperationAsyncResult(
|
||||
IAnnouncementServiceImplementation announcementServiceImpl,
|
||||
TMessage message,
|
||||
AsyncCallback callback,
|
||||
object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
this.announcementServiceImpl = announcementServiceImpl;
|
||||
|
||||
if (this.IsInvalid(message))
|
||||
{
|
||||
this.Complete(true);
|
||||
return;
|
||||
}
|
||||
|
||||
IAsyncResult innerAsyncResult =
|
||||
this.announcementServiceImpl.OnBeginOfflineAnnouncement(
|
||||
this.GetMessageSequence(message),
|
||||
this.GetEndpointDiscoveryMetadata(message),
|
||||
this.PrepareAsyncCompletion(onOnOfflineAnnoucementCompletedCallback),
|
||||
this);
|
||||
|
||||
if (innerAsyncResult.CompletedSynchronously && OnOnOfflineAnnouncementCompleted(innerAsyncResult))
|
||||
{
|
||||
this.Complete(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract bool ValidateContent(TMessage message);
|
||||
protected abstract DiscoveryMessageSequence GetMessageSequence(TMessage message);
|
||||
protected abstract EndpointDiscoveryMetadata GetEndpointDiscoveryMetadata(TMessage message);
|
||||
|
||||
static bool OnOnOfflineAnnouncementCompleted(IAsyncResult result)
|
||||
{
|
||||
ByeOperationAsyncResult<TMessage> thisPtr = (ByeOperationAsyncResult<TMessage>)result.AsyncState;
|
||||
thisPtr.announcementServiceImpl.OnEndOfflineAnnouncement(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsInvalid(TMessage message)
|
||||
{
|
||||
UniqueId messageId = OperationContext.Current.IncomingMessageHeaders.MessageId;
|
||||
if (messageId == null)
|
||||
{
|
||||
if (TD.DiscoveryMessageWithNullMessageIdIsEnabled())
|
||||
{
|
||||
TD.DiscoveryMessageWithNullMessageId(null, ProtocolStrings.TracingStrings.Bye);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EventTraceActivity eventTraceActivity = null;
|
||||
if (Fx.Trace.IsEtwProviderEnabled)
|
||||
{
|
||||
eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(OperationContext.Current.IncomingMessage);
|
||||
}
|
||||
|
||||
if (this.announcementServiceImpl.IsDuplicate(messageId))
|
||||
{
|
||||
if (TD.DuplicateDiscoveryMessageIsEnabled())
|
||||
{
|
||||
TD.DuplicateDiscoveryMessage(eventTraceActivity, ProtocolStrings.TracingStrings.Bye, messageId.ToString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (this.ValidateContent(message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TD.DiscoveryMessageWithInvalidContentIsEnabled())
|
||||
{
|
||||
TD.DiscoveryMessageWithInvalidContent(eventTraceActivity, ProtocolStrings.TracingStrings.Bye, messageId.ToString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
using System;
|
||||
using System.Runtime;
|
||||
|
||||
class CompiledScopeCriteria
|
||||
{
|
||||
string compiledScope;
|
||||
CompiledScopeCriteriaMatchBy matchBy;
|
||||
|
||||
public CompiledScopeCriteria(string compiledScope, CompiledScopeCriteriaMatchBy matchBy)
|
||||
{
|
||||
Fx.Assert(compiledScope != null, "The compiledScope must be non null.");
|
||||
this.compiledScope = compiledScope;
|
||||
this.matchBy = matchBy;
|
||||
}
|
||||
|
||||
public string CompiledScope
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.compiledScope;
|
||||
}
|
||||
}
|
||||
|
||||
public CompiledScopeCriteriaMatchBy MatchBy
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.matchBy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
namespace System.ServiceModel.Discovery
|
||||
{
|
||||
enum CompiledScopeCriteriaMatchBy
|
||||
{
|
||||
StartsWith,
|
||||
Exact
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.Configuration;
|
||||
using System.Globalization;
|
||||
using System.ServiceModel.Configuration;
|
||||
|
||||
[ConfigurationCollection(typeof(ChannelEndpointElement), AddItemName = ConfigurationStrings.Endpoint)]
|
||||
public sealed class AnnouncementChannelEndpointElementCollection : ServiceModelConfigurationElementCollection<ChannelEndpointElement>
|
||||
{
|
||||
public AnnouncementChannelEndpointElementCollection()
|
||||
{
|
||||
this.AddElementName = ConfigurationStrings.Endpoint;
|
||||
}
|
||||
|
||||
protected override object GetElementKey(ConfigurationElement element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("element");
|
||||
}
|
||||
|
||||
ChannelEndpointElement channelEndpointElement = (ChannelEndpointElement)element;
|
||||
|
||||
string address = channelEndpointElement.Address == null ? "" : channelEndpointElement.Address.ToString().ToUpperInvariant();
|
||||
|
||||
return string.Format(CultureInfo.InvariantCulture,
|
||||
"kind:{0};endpointConfiguration:{1};address:{2};bindingConfiguration:{3};binding:{4};",
|
||||
channelEndpointElement.Kind,
|
||||
channelEndpointElement.EndpointConfiguration,
|
||||
address,
|
||||
channelEndpointElement.BindingConfiguration,
|
||||
channelEndpointElement.Binding);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.ServiceModel.Discovery;
|
||||
|
||||
public class AnnouncementEndpointCollectionElement : StandardEndpointCollectionElement<AnnouncementEndpoint, AnnouncementEndpointElement>
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.ServiceModel.Description;
|
||||
using SR2 = System.ServiceModel.Discovery.SR;
|
||||
|
||||
public class AnnouncementEndpointElement : StandardEndpointElement
|
||||
{
|
||||
ConfigurationPropertyCollection properties;
|
||||
|
||||
public AnnouncementEndpointElement()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.MaxAnnouncementDelay, DefaultValue = ConfigurationStrings.TimeSpanZero)]
|
||||
[TypeConverter(typeof(TimeSpanOrInfiniteConverter))]
|
||||
[ServiceModelTimeSpanValidator(MinValueString = ConfigurationStrings.TimeSpanZero)]
|
||||
public TimeSpan MaxAnnouncementDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TimeSpan)base[ConfigurationStrings.MaxAnnouncementDelay];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base[ConfigurationStrings.MaxAnnouncementDelay] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.DiscoveryVersion, DefaultValue = ProtocolStrings.VersionNameDefault)]
|
||||
[TypeConverter(typeof(DiscoveryVersionConverter))]
|
||||
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationValidatorAttributeRule)]
|
||||
public DiscoveryVersion DiscoveryVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DiscoveryVersion)base[ConfigurationStrings.DiscoveryVersion];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base[ConfigurationStrings.DiscoveryVersion] = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override Type EndpointType
|
||||
{
|
||||
get { return typeof(AnnouncementEndpoint); }
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.properties == null)
|
||||
{
|
||||
ConfigurationPropertyCollection properties = base.Properties;
|
||||
|
||||
properties.Add(
|
||||
new ConfigurationProperty(
|
||||
ConfigurationStrings.MaxAnnouncementDelay,
|
||||
typeof(TimeSpan),
|
||||
TimeSpan.Zero,
|
||||
new TimeSpanOrInfiniteConverter(),
|
||||
new TimeSpanOrInfiniteValidator(TimeSpan.Zero, TimeSpan.MaxValue),
|
||||
ConfigurationPropertyOptions.None));
|
||||
|
||||
properties.Add(
|
||||
new ConfigurationProperty(
|
||||
ConfigurationStrings.DiscoveryVersion,
|
||||
typeof(DiscoveryVersion),
|
||||
DiscoveryVersion.DefaultDiscoveryVersion,
|
||||
new DiscoveryVersionConverter(),
|
||||
null,
|
||||
ConfigurationPropertyOptions.None));
|
||||
|
||||
this.properties = properties;
|
||||
}
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override ServiceEndpoint CreateServiceEndpoint(ContractDescription contractDescription)
|
||||
{
|
||||
return new AnnouncementEndpoint(this.DiscoveryVersion);
|
||||
}
|
||||
|
||||
protected internal override void InitializeFrom(ServiceEndpoint endpoint)
|
||||
{
|
||||
base.InitializeFrom(endpoint);
|
||||
|
||||
AnnouncementEndpoint source = (AnnouncementEndpoint)endpoint;
|
||||
this.MaxAnnouncementDelay = source.MaxAnnouncementDelay;
|
||||
this.DiscoveryVersion = source.DiscoveryVersion;
|
||||
}
|
||||
|
||||
protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(channelEndpointElement.Contract))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR2.DiscoveryConfigContractSpecified(channelEndpointElement.Kind)));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(serviceEndpointElement.Contract))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR2.DiscoveryConfigContractSpecified(serviceEndpointElement.Kind)));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ServiceEndpointElement serviceEndpointElement)
|
||||
{
|
||||
ApplyConfiguration(endpoint);
|
||||
}
|
||||
|
||||
protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ChannelEndpointElement serviceEndpointElement)
|
||||
{
|
||||
ApplyConfiguration(endpoint);
|
||||
}
|
||||
|
||||
void ApplyConfiguration(ServiceEndpoint endpoint)
|
||||
{
|
||||
AnnouncementEndpoint announcementEndpoint = (AnnouncementEndpoint)endpoint;
|
||||
announcementEndpoint.MaxAnnouncementDelay = this.MaxAnnouncementDelay;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.Configuration;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.ServiceModel.Description;
|
||||
using SR2 = System.ServiceModel.Discovery.SR;
|
||||
|
||||
class ConfigurationDiscoveryEndpointProvider : DiscoveryEndpointProvider
|
||||
{
|
||||
readonly ChannelEndpointElement channelEndpointElement;
|
||||
|
||||
public ConfigurationDiscoveryEndpointProvider()
|
||||
{
|
||||
this.channelEndpointElement = ConfigurationUtility.GetDefaultDiscoveryEndpointElement();
|
||||
}
|
||||
|
||||
public ConfigurationDiscoveryEndpointProvider(ChannelEndpointElement channelEndpointElement)
|
||||
{
|
||||
Fx.Assert(channelEndpointElement != null, "The channelEndpointElement parameter must be non null.");
|
||||
|
||||
ConfigurationDiscoveryEndpointProvider.ValidateAndGetDiscoveryEndpoint(channelEndpointElement);
|
||||
this.channelEndpointElement = channelEndpointElement;
|
||||
}
|
||||
|
||||
public override DiscoveryEndpoint GetDiscoveryEndpoint()
|
||||
{
|
||||
return ConfigurationDiscoveryEndpointProvider.ValidateAndGetDiscoveryEndpoint(this.channelEndpointElement);
|
||||
}
|
||||
|
||||
static DiscoveryEndpoint ValidateAndGetDiscoveryEndpoint(ChannelEndpointElement channelEndpointElement)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channelEndpointElement.Kind))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new ConfigurationErrorsException(
|
||||
SR2.DiscoveryConfigDiscoveryEndpointMissingKind(
|
||||
typeof(DiscoveryEndpoint).FullName)));
|
||||
}
|
||||
|
||||
ServiceEndpoint serviceEndpoint = ConfigLoader.LookupEndpoint(channelEndpointElement, null);
|
||||
|
||||
if (serviceEndpoint == null)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new ConfigurationErrorsException(
|
||||
SR2.DiscoveryConfigInvalidEndpointConfiguration(
|
||||
channelEndpointElement.Kind)));
|
||||
}
|
||||
|
||||
DiscoveryEndpoint discoveryEndpoint = serviceEndpoint as DiscoveryEndpoint;
|
||||
if (discoveryEndpoint == null)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new InvalidOperationException(
|
||||
SR2.DiscoveryConfigInvalidDiscoveryEndpoint(
|
||||
typeof(DiscoveryEndpoint).FullName,
|
||||
channelEndpointElement.Kind,
|
||||
serviceEndpoint.GetType().FullName)));
|
||||
}
|
||||
|
||||
return discoveryEndpoint;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
static class ConfigurationStrings
|
||||
{
|
||||
public const string AnnouncementEndpoints = "announcementEndpoints";
|
||||
public const string DiscoveryClient = "discoveryClient";
|
||||
public const string DiscoveryClientSettings = "discoveryClientSettings";
|
||||
public const string DiscoveryVersion = "discoveryVersion";
|
||||
public const string Duration = "duration";
|
||||
public const string Enabled = "enabled";
|
||||
public const string Endpoint = "endpoint";
|
||||
public const string Extensions = "extensions";
|
||||
public const string FindCriteria = "findCriteria";
|
||||
public const string IsSystemEndpoint = "isSystemEndpoint";
|
||||
public const string MaxAnnouncementDelay = "maxAnnouncementDelay";
|
||||
public const string MaxResponseDelay = "maxResponseDelay";
|
||||
public const string MaxResults = "maxResults";
|
||||
public const string MulticastAddress = "multicastAddress";
|
||||
public const string Name = "name";
|
||||
public const string Namespace = "namespace";
|
||||
public const string DiscoveryMode = "discoveryMode";
|
||||
public const string Scopes = "scopes";
|
||||
public const string Scope = "scope";
|
||||
public const string ScopeMatchBy = "scopeMatchBy";
|
||||
public const string Types = "types";
|
||||
public const string UdpDiscoveryEndpoint = "udpDiscoveryEndpoint";
|
||||
// UDP transport settings
|
||||
public const string TransportSettings = "transportSettings";
|
||||
public const string DuplicateMessageHistoryLength = "duplicateMessageHistoryLength";
|
||||
public const string MaxPendingMessageCount = "maxPendingMessageCount";
|
||||
public const string MaxReceivedMessageSize = "maxReceivedMessageSize";
|
||||
public const string MaxBufferPoolSize = "maxBufferPoolSize";
|
||||
public const string MaxMulticastRetransmitCount = "maxMulticastRetransmitCount";
|
||||
public const string MaxUnicastRetransmitCount = "maxUnicastRetransmitCount";
|
||||
public const string MulticastInterfaceId = "multicastInterfaceId";
|
||||
public const string SocketReceiveBufferSize = "socketReceiveBufferSize";
|
||||
public const string TimeToLive = "timeToLive";
|
||||
|
||||
public const string TimeSpanZero = "00:00:00";
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.Configuration;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.ServiceModel.Description;
|
||||
using SR2 = System.ServiceModel.Discovery.SR;
|
||||
|
||||
class ConfigurationUtility
|
||||
{
|
||||
public static ChannelEndpointElement GetDefaultDiscoveryEndpointElement()
|
||||
{
|
||||
return new ChannelEndpointElement() { Kind = ConfigurationStrings.UdpDiscoveryEndpoint };
|
||||
}
|
||||
|
||||
public static T LookupEndpoint<T>(ChannelEndpointElement channelEndpointElement) where T : ServiceEndpoint
|
||||
{
|
||||
Fx.Assert(channelEndpointElement != null, "The parameter channelEndpointElement must be non null.");
|
||||
Fx.Assert(!string.IsNullOrEmpty(channelEndpointElement.Kind), "The Kind property of the specified channelEndpointElement parameter cannot be null or empty.");
|
||||
|
||||
return ConfigLoader.LookupEndpoint(channelEndpointElement, null) as T;
|
||||
}
|
||||
internal static void InitializeAndValidateUdpChannelEndpointElement(ChannelEndpointElement channelEndpointElement)
|
||||
{
|
||||
if (!(channelEndpointElement.Address == null || String.IsNullOrEmpty(channelEndpointElement.Address.ToString())))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR2.DiscoveryConfigAddressSpecifiedForUdpDiscoveryEndpoint(channelEndpointElement.Kind)));
|
||||
}
|
||||
channelEndpointElement.Address = null;
|
||||
}
|
||||
|
||||
internal static void InitializeAndValidateUdpServiceEndpointElement(ServiceEndpointElement serviceEndpointElement)
|
||||
{
|
||||
if (!(serviceEndpointElement.Address == null || String.IsNullOrEmpty(serviceEndpointElement.Address.ToString())))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR2.DiscoveryConfigAddressSpecifiedForUdpDiscoveryEndpoint(serviceEndpointElement.Kind)));
|
||||
}
|
||||
serviceEndpointElement.Address = null;
|
||||
|
||||
if (serviceEndpointElement.ListenUri != null)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR2.DiscoveryConfigListenUriSpecifiedForUdpDiscoveryEndpoint(serviceEndpointElement.Kind)));
|
||||
}
|
||||
}
|
||||
|
||||
internal static TEndpoint LookupEndpointFromClientSection<TEndpoint>(string endpointConfigurationName) where TEndpoint : ServiceEndpoint
|
||||
{
|
||||
Fx.Assert(endpointConfigurationName != null, "The endpointConfigurationName parameter must be non null.");
|
||||
|
||||
TEndpoint retval = default(TEndpoint);
|
||||
|
||||
bool wildcard = string.Equals(endpointConfigurationName, "*", StringComparison.Ordinal);
|
||||
|
||||
ClientSection clientSection = ClientSection.GetSection();
|
||||
foreach (ChannelEndpointElement channelEndpointElement in clientSection.Endpoints)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channelEndpointElement.Kind))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (endpointConfigurationName == channelEndpointElement.Name || wildcard)
|
||||
{
|
||||
TEndpoint endpoint = LookupEndpoint<TEndpoint>(channelEndpointElement);
|
||||
if (endpoint != null)
|
||||
{
|
||||
if (retval != null)
|
||||
{
|
||||
if (wildcard)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new InvalidOperationException(
|
||||
SR2.DiscoveryConfigMultipleEndpointsMatchWildcard(
|
||||
typeof(TEndpoint).FullName,
|
||||
clientSection.SectionInformation.SectionName)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new InvalidOperationException(
|
||||
SR2.DiscoveryConfigMultipleEndpointsMatch(
|
||||
typeof(TEndpoint).FullName,
|
||||
endpointConfigurationName,
|
||||
clientSection.SectionInformation.SectionName)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = endpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == null)
|
||||
{
|
||||
if (wildcard)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new InvalidOperationException(
|
||||
SR2.DiscoveryConfigNoEndpointsMatchWildcard(
|
||||
typeof(TEndpoint).FullName,
|
||||
clientSection.SectionInformation.SectionName)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new InvalidOperationException(
|
||||
SR2.DiscoveryConfigNoEndpointsMatch(
|
||||
typeof(TEndpoint).FullName,
|
||||
endpointConfigurationName,
|
||||
clientSection.SectionInformation.SectionName)));
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.Configuration;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Description;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
public sealed class ContractTypeNameElement : ConfigurationElement
|
||||
{
|
||||
ConfigurationPropertyCollection properties;
|
||||
|
||||
public ContractTypeNameElement()
|
||||
{
|
||||
}
|
||||
|
||||
public ContractTypeNameElement(string name, string ns)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Namespace = ns;
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.Namespace, DefaultValue = NamingHelper.DefaultNamespace, Options = ConfigurationPropertyOptions.IsKey)]
|
||||
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationValidatorAttributeRule, Justification = "Validator not requiered")]
|
||||
public string Namespace
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)base[ConfigurationStrings.Namespace];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base[ConfigurationStrings.Namespace] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.Name, Options = ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired)]
|
||||
[StringValidator(MinLength = 1)]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)base[ConfigurationStrings.Name];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base[ConfigurationStrings.Name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.properties == null)
|
||||
{
|
||||
ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection();
|
||||
|
||||
properties.Add(
|
||||
new ConfigurationProperty(
|
||||
ConfigurationStrings.Namespace,
|
||||
typeof(string),
|
||||
NamingHelper.DefaultNamespace,
|
||||
null,
|
||||
null,
|
||||
System.Configuration.ConfigurationPropertyOptions.IsKey));
|
||||
|
||||
properties.Add(
|
||||
new ConfigurationProperty(
|
||||
ConfigurationStrings.Name,
|
||||
typeof(string),
|
||||
null,
|
||||
null,
|
||||
new StringValidator(1),
|
||||
System.Configuration.ConfigurationPropertyOptions.IsKey |
|
||||
System.Configuration.ConfigurationPropertyOptions.IsRequired));
|
||||
|
||||
this.properties = properties;
|
||||
}
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.Configuration;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.Xml;
|
||||
|
||||
[ConfigurationCollection(typeof(ContractTypeNameElement))]
|
||||
public sealed class ContractTypeNameElementCollection : ServiceModelConfigurationElementCollection<ContractTypeNameElement>
|
||||
{
|
||||
protected override object GetElementKey(ConfigurationElement element)
|
||||
{
|
||||
ContractTypeNameElement contractTypeNameElement = (ContractTypeNameElement)element;
|
||||
return new XmlQualifiedName(contractTypeNameElement.Name, contractTypeNameElement.Namespace);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Discovery.Configuration
|
||||
{
|
||||
using System.Configuration;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Configuration;
|
||||
using SR2 = System.ServiceModel.Discovery.SR;
|
||||
|
||||
[Fx.Tag.XamlVisible(false)]
|
||||
public sealed class DiscoveryClientElement : BindingElementExtensionElement
|
||||
{
|
||||
ConfigurationPropertyCollection properties;
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.Endpoint)]
|
||||
[SuppressMessage(
|
||||
FxCop.Category.Configuration,
|
||||
FxCop.Rule.ConfigurationPropertyNameRule,
|
||||
Justification = "The configuration name for this element is 'endpoint'.")]
|
||||
public ChannelEndpointElement DiscoveryEndpoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ChannelEndpointElement)base[ConfigurationStrings.Endpoint];
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.FindCriteria)]
|
||||
public FindCriteriaElement FindCriteria
|
||||
{
|
||||
get
|
||||
{
|
||||
return (FindCriteriaElement)base[ConfigurationStrings.FindCriteria];
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage(
|
||||
FxCop.Category.Configuration,
|
||||
FxCop.Rule.ConfigurationPropertyAttributeRule,
|
||||
Justification = "This property only overrides the base property.")]
|
||||
public override Type BindingElementType
|
||||
{
|
||||
get { return typeof(DiscoveryClientBindingElement); }
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.properties == null)
|
||||
{
|
||||
ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection();
|
||||
|
||||
properties.Add(
|
||||
new ConfigurationProperty(
|
||||
ConfigurationStrings.Endpoint,
|
||||
typeof(ChannelEndpointElement),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ConfigurationPropertyOptions.None));
|
||||
|
||||
properties.Add(
|
||||
new ConfigurationProperty(
|
||||
ConfigurationStrings.FindCriteria,
|
||||
typeof(FindCriteriaElement),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ConfigurationPropertyOptions.None));
|
||||
|
||||
this.properties = properties;
|
||||
}
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ApplyConfiguration(BindingElement bindingElement)
|
||||
{
|
||||
base.ApplyConfiguration(bindingElement);
|
||||
|
||||
DiscoveryClientBindingElement discoveryClientBindingElement = (DiscoveryClientBindingElement)bindingElement;
|
||||
|
||||
if (PropertyValueOrigin.Default == this.ElementInformation.Properties[ConfigurationStrings.Endpoint].ValueOrigin)
|
||||
{
|
||||
discoveryClientBindingElement.DiscoveryEndpointProvider = new ConfigurationDiscoveryEndpointProvider();
|
||||
}
|
||||
else
|
||||
{
|
||||
discoveryClientBindingElement.DiscoveryEndpointProvider = new ConfigurationDiscoveryEndpointProvider(this.DiscoveryEndpoint);
|
||||
}
|
||||
|
||||
this.FindCriteria.ApplyConfiguration(discoveryClientBindingElement.FindCriteria);
|
||||
}
|
||||
|
||||
public override void CopyFrom(ServiceModelExtensionElement from)
|
||||
{
|
||||
base.CopyFrom(from);
|
||||
|
||||
DiscoveryClientElement source = (DiscoveryClientElement)from;
|
||||
|
||||
if (PropertyValueOrigin.Default == this.ElementInformation.Properties[ConfigurationStrings.Endpoint].ValueOrigin)
|
||||
{
|
||||
ChannelEndpointElement udpChannelEndpointElement = ConfigurationUtility.GetDefaultDiscoveryEndpointElement();
|
||||
udpChannelEndpointElement.Copy(source.DiscoveryEndpoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DiscoveryEndpoint.Copy(source.DiscoveryEndpoint);
|
||||
}
|
||||
this.FindCriteria.CopyFrom(source.FindCriteria);
|
||||
}
|
||||
|
||||
protected internal override BindingElement CreateBindingElement()
|
||||
{
|
||||
DiscoveryClientBindingElement discoveryClientBindingElement = new DiscoveryClientBindingElement();
|
||||
this.ApplyConfiguration(discoveryClientBindingElement);
|
||||
|
||||
return discoveryClientBindingElement;
|
||||
}
|
||||
|
||||
protected internal override void InitializeFrom(BindingElement bindingElement)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(
|
||||
new NotSupportedException(SR2.DiscoveryConfigInitializeFromNotSupported));
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user