You've already forked linux-packaging-mono
Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
10
external/referencesource/System.ServiceModel.Routing/SuppressMessages.cs
vendored
Normal file
10
external/referencesource/System.ServiceModel.Routing/SuppressMessages.cs
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
|
||||
// When a resource from SR.resx is called from internal accessible code FxCop can't tell that it ever gets called
|
||||
[module: SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Scope = "member", Target = "System.ServiceModel.Routing.SR.get_RoutingTableNotConfigured():System.String")]
|
||||
[module: SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Scope = "member", Target = "System.ServiceModel.Routing.SR.set_Culture(System.Globalization.CultureInfo):System.Void")]
|
@ -0,0 +1,378 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Routing;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using SR2 = System.ServiceModel.SR;
|
||||
|
||||
class SynchronousSendBindingElement : BindingElement
|
||||
{
|
||||
public override BindingElement Clone()
|
||||
{
|
||||
return new SynchronousSendBindingElement();
|
||||
}
|
||||
|
||||
public override T GetProperty<T>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("context");
|
||||
}
|
||||
|
||||
return context.GetInnerProperty<T>();
|
||||
}
|
||||
|
||||
public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("context");
|
||||
}
|
||||
|
||||
|
||||
Type typeofTChannel = typeof(TChannel);
|
||||
|
||||
if (typeofTChannel == typeof(IDuplexChannel) ||
|
||||
typeofTChannel == typeof(IDuplexSessionChannel) ||
|
||||
typeofTChannel == typeof(IRequestChannel) ||
|
||||
typeofTChannel == typeof(IRequestSessionChannel) ||
|
||||
typeofTChannel == typeof(IOutputChannel) ||
|
||||
typeofTChannel == typeof(IOutputSessionChannel))
|
||||
{
|
||||
return context.CanBuildInnerChannelFactory<TChannel>();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("context");
|
||||
}
|
||||
|
||||
if (!this.CanBuildChannelFactory<TChannel>(context.Clone()))
|
||||
{
|
||||
throw FxTrace.Exception.Argument("TChannel", SR2.GetString(SR2.ChannelTypeNotSupported, typeof(TChannel)));
|
||||
}
|
||||
|
||||
IChannelFactory<TChannel> innerFactory = context.BuildInnerChannelFactory<TChannel>();
|
||||
if (innerFactory != null)
|
||||
{
|
||||
return new SynchronousChannelFactory<TChannel>(context.Binding, innerFactory);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
class SynchronousChannelFactory<TChannel> : LayeredChannelFactory<TChannel>
|
||||
{
|
||||
public SynchronousChannelFactory(IDefaultCommunicationTimeouts timeouts, IChannelFactory<TChannel> innerFactory)
|
||||
: base(timeouts, innerFactory)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
this.InnerChannelFactory.Open(timeout);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected override void OnEndOpen(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
|
||||
{
|
||||
IChannelFactory<TChannel> factory = (IChannelFactory<TChannel>)this.InnerChannelFactory;
|
||||
TChannel channel = factory.CreateChannel(address, via);
|
||||
if (channel != null)
|
||||
{
|
||||
Type channelType = typeof(TChannel);
|
||||
if (channelType == typeof(IDuplexSessionChannel))
|
||||
{
|
||||
channel = (TChannel)(object)new SynchronousDuplexSessionChannel(this, (IDuplexSessionChannel)channel);
|
||||
}
|
||||
else if (channelType == typeof(IRequestChannel))
|
||||
{
|
||||
channel = (TChannel)(object)new SynchronousRequestChannel(this, (IRequestChannel)channel);
|
||||
}
|
||||
else if (channelType == typeof(IRequestSessionChannel))
|
||||
{
|
||||
channel = (TChannel)(object)new SynchronousRequestSessionChannel(this, (IRequestSessionChannel)channel);
|
||||
}
|
||||
else if (channelType == typeof(IOutputChannel))
|
||||
{
|
||||
channel = (TChannel)(object)new SynchronousOutputChannel(this, (IOutputChannel)channel);
|
||||
}
|
||||
else if (channelType == typeof(IOutputSessionChannel))
|
||||
{
|
||||
channel = (TChannel)(object)new SynchronousOutputSessionChannel(this, (IOutputSessionChannel)channel);
|
||||
}
|
||||
else if (channelType == typeof(IDuplexChannel))
|
||||
{
|
||||
channel = (TChannel)(object)new SynchronousDuplexChannel(this, (IDuplexChannel)channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw FxTrace.Exception.AsError(base.CreateChannelTypeNotSupportedException(typeof(TChannel)));
|
||||
}
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SynchronousChannelBase<TChannel> : LayeredChannel<TChannel>
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
protected SynchronousChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
this.InnerChannel.Open(timeout);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected override void OnEndOpen(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousDuplexChannelBase<TChannel> : SynchronousOutputChannelBase<TChannel>
|
||||
where TChannel : class, IDuplexChannel
|
||||
{
|
||||
public SynchronousDuplexChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.InnerChannel.BeginReceive(timeout, callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginReceive(AsyncCallback callback, object state)
|
||||
{
|
||||
return this.InnerChannel.BeginReceive(callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.InnerChannel.BeginTryReceive(timeout, callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.InnerChannel.BeginWaitForMessage(timeout, callback, state);
|
||||
}
|
||||
|
||||
public Message EndReceive(IAsyncResult result)
|
||||
{
|
||||
return this.InnerChannel.EndReceive(result);
|
||||
}
|
||||
|
||||
public bool EndTryReceive(IAsyncResult result, out Message message)
|
||||
{
|
||||
return this.InnerChannel.EndTryReceive(result, out message);
|
||||
}
|
||||
|
||||
public bool EndWaitForMessage(IAsyncResult result)
|
||||
{
|
||||
return this.InnerChannel.EndWaitForMessage(result);
|
||||
}
|
||||
|
||||
public EndpointAddress LocalAddress
|
||||
{
|
||||
get { return this.InnerChannel.LocalAddress; }
|
||||
}
|
||||
|
||||
public Message Receive(TimeSpan timeout)
|
||||
{
|
||||
return this.InnerChannel.Receive(timeout);
|
||||
}
|
||||
|
||||
public Message Receive()
|
||||
{
|
||||
return this.InnerChannel.Receive();
|
||||
}
|
||||
|
||||
public bool TryReceive(TimeSpan timeout, out Message message)
|
||||
{
|
||||
return this.InnerChannel.TryReceive(timeout, out message);
|
||||
}
|
||||
|
||||
public bool WaitForMessage(TimeSpan timeout)
|
||||
{
|
||||
return this.InnerChannel.WaitForMessage(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousDuplexChannel : SynchronousDuplexChannelBase<IDuplexChannel>, IDuplexChannel
|
||||
{
|
||||
public SynchronousDuplexChannel(ChannelManagerBase manager, IDuplexChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousDuplexSessionChannel : SynchronousDuplexChannelBase<IDuplexSessionChannel>, IDuplexSessionChannel
|
||||
{
|
||||
public SynchronousDuplexSessionChannel(ChannelManagerBase manager, IDuplexSessionChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
IDuplexSession ISessionChannel<IDuplexSession>.Session
|
||||
{
|
||||
get { return this.InnerChannel.Session; }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SynchronousOutputChannelBase<TChannel> : SynchronousChannelBase<TChannel>
|
||||
where TChannel : class, IOutputChannel
|
||||
{
|
||||
public SynchronousOutputChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
this.InnerChannel.Send(message, timeout);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
this.InnerChannel.Send(message);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
public void EndSend(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
|
||||
public EndpointAddress RemoteAddress
|
||||
{
|
||||
get { return this.InnerChannel.RemoteAddress; }
|
||||
}
|
||||
|
||||
public void Send(Message message, TimeSpan timeout)
|
||||
{
|
||||
this.InnerChannel.Send(message, timeout);
|
||||
}
|
||||
|
||||
public void Send(Message message)
|
||||
{
|
||||
this.InnerChannel.Send(message);
|
||||
}
|
||||
|
||||
public Uri Via
|
||||
{
|
||||
get { return this.InnerChannel.Via; }
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousOutputChannel : SynchronousOutputChannelBase<IOutputChannel>, IOutputChannel
|
||||
{
|
||||
public SynchronousOutputChannel(ChannelManagerBase manager, IOutputChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousOutputSessionChannel : SynchronousOutputChannelBase<IOutputSessionChannel>, IOutputSessionChannel
|
||||
{
|
||||
public SynchronousOutputSessionChannel(ChannelManagerBase manager, IOutputSessionChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
IOutputSession ISessionChannel<IOutputSession>.Session
|
||||
{
|
||||
get { return this.InnerChannel.Session; }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SynchronousRequestChannelBase<TChannel> : SynchronousChannelBase<TChannel>
|
||||
where TChannel : class, IRequestChannel
|
||||
{
|
||||
public SynchronousRequestChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
Message reply = this.InnerChannel.Request(message, timeout);
|
||||
return new CompletedAsyncResult<Message>(reply, callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
Message reply = this.InnerChannel.Request(message);
|
||||
return new CompletedAsyncResult<Message>(reply, callback, state);
|
||||
}
|
||||
|
||||
public Message EndRequest(IAsyncResult result)
|
||||
{
|
||||
return CompletedAsyncResult<Message>.End(result);
|
||||
}
|
||||
|
||||
public EndpointAddress RemoteAddress
|
||||
{
|
||||
get { return this.InnerChannel.RemoteAddress; }
|
||||
}
|
||||
|
||||
public Message Request(Message message, TimeSpan timeout)
|
||||
{
|
||||
return this.InnerChannel.Request(message, timeout);
|
||||
}
|
||||
|
||||
public Message Request(Message message)
|
||||
{
|
||||
return this.InnerChannel.Request(message);
|
||||
}
|
||||
|
||||
public Uri Via
|
||||
{
|
||||
get { return this.InnerChannel.Via; }
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousRequestChannel : SynchronousRequestChannelBase<IRequestChannel>, IRequestChannel
|
||||
{
|
||||
public SynchronousRequestChannel(ChannelManagerBase manager, IRequestChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class SynchronousRequestSessionChannel : SynchronousRequestChannelBase<IRequestSessionChannel>, IRequestSessionChannel
|
||||
{
|
||||
public SynchronousRequestSessionChannel(ChannelManagerBase manager, IRequestSessionChannel innerChannel)
|
||||
: base(manager, innerChannel)
|
||||
{
|
||||
}
|
||||
|
||||
public IOutputSession Session
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.InnerChannel.Session;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Dispatcher
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
using System.ServiceModel.Description;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.ServiceModel.Routing;
|
||||
|
||||
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesMustHaveXamlCallableConstructors)]
|
||||
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesShouldHavePublicParameterlessConstructors)]
|
||||
public class EndpointNameMessageFilter : MessageFilter
|
||||
{
|
||||
const string EndpointNameKey = "System.ServiceModel.Routing.EndpointNameMessageFilter.Name";
|
||||
string endpointName;
|
||||
|
||||
public EndpointNameMessageFilter(string endpointName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(endpointName))
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNullOrEmpty("endpointName");
|
||||
}
|
||||
this.endpointName = endpointName;
|
||||
}
|
||||
|
||||
public override bool Match(Message message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("message");
|
||||
}
|
||||
return MatchInternal(message.Properties);
|
||||
}
|
||||
|
||||
public override bool Match(MessageBuffer buffer)
|
||||
{
|
||||
if (buffer == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("buffer");
|
||||
}
|
||||
using (Message tempMessage = buffer.CreateMessage())
|
||||
{
|
||||
return MatchInternal(tempMessage.Properties);
|
||||
}
|
||||
}
|
||||
|
||||
bool MatchInternal(MessageProperties messageProperties)
|
||||
{
|
||||
object value;
|
||||
if (messageProperties.TryGetValue(EndpointNameKey, out value))
|
||||
{
|
||||
string messageEndpoint = value.ToString();
|
||||
return string.Equals(messageEndpoint, this.endpointName, StringComparison.Ordinal);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static void Set(MessageProperties properties, string endpointName)
|
||||
{
|
||||
properties[EndpointNameKey] = endpointName;
|
||||
}
|
||||
|
||||
internal static void Validate(ICollection<MessageFilter> messageFilters, HashSet<string> endpoints)
|
||||
{
|
||||
foreach (MessageFilter filter in messageFilters)
|
||||
{
|
||||
EndpointNameMessageFilter endpointFilter = filter as EndpointNameMessageFilter;
|
||||
if (endpointFilter != null)
|
||||
{
|
||||
endpointFilter.Validate(endpoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Validate(HashSet<string> endpoints)
|
||||
{
|
||||
if (!endpoints.Contains(this.endpointName))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR.EndpointNameNotFound(this.endpointName)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,301 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Dispatcher
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
using System.Collections;
|
||||
using System.ServiceModel.Routing;
|
||||
|
||||
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesMustHaveXamlCallableConstructors)]
|
||||
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesShouldHavePublicParameterlessConstructors)]
|
||||
public class StrictAndMessageFilter : MessageFilter
|
||||
{
|
||||
MessageFilter filter1;
|
||||
MessageFilter filter2;
|
||||
|
||||
public StrictAndMessageFilter(MessageFilter filter1, MessageFilter filter2)
|
||||
{
|
||||
if (filter1 == null || filter2 == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull(filter1 == null ? "filter1" : "filter2");
|
||||
}
|
||||
|
||||
this.filter1 = filter1;
|
||||
this.filter2 = filter2;
|
||||
}
|
||||
|
||||
public override bool Match(Message message)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotSupportedException());
|
||||
}
|
||||
|
||||
public override bool Match(MessageBuffer buffer)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotSupportedException());
|
||||
}
|
||||
|
||||
protected internal override IMessageFilterTable<TFilterData> CreateFilterTable<TFilterData>()
|
||||
{
|
||||
StrictAndMessageFilterTable<TFilterData> table = new StrictAndMessageFilterTable<TFilterData>();
|
||||
return table;
|
||||
}
|
||||
|
||||
class StrictAndMessageFilterTable<TFilterData> : IMessageFilterTable<TFilterData>
|
||||
{
|
||||
Dictionary<MessageFilter, TFilterData> andFilters;
|
||||
MessageFilterTable<StrictAndMessageFilter> filterTable;
|
||||
|
||||
public StrictAndMessageFilterTable()
|
||||
{
|
||||
this.andFilters = new Dictionary<MessageFilter, TFilterData>();
|
||||
this.filterTable = new MessageFilterTable<StrictAndMessageFilter>();
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return this.andFilters.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public ICollection<MessageFilter> Keys
|
||||
{
|
||||
get { return this.andFilters.Keys; }
|
||||
}
|
||||
|
||||
public ICollection<TFilterData> Values
|
||||
{
|
||||
get { return this.andFilters.Values; }
|
||||
}
|
||||
|
||||
public TFilterData this[MessageFilter key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.andFilters[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
this.andFilters[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotImplementedException());
|
||||
}
|
||||
|
||||
public bool GetMatchingFilter(Message message, out MessageFilter filter)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotImplementedException());
|
||||
}
|
||||
|
||||
public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
|
||||
{
|
||||
if (messageBuffer == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("messageBuffer");
|
||||
}
|
||||
|
||||
List<MessageFilter> firstPassResults = new List<MessageFilter>();
|
||||
if (this.filterTable.GetMatchingFilters(messageBuffer, firstPassResults))
|
||||
{
|
||||
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
|
||||
foreach (StrictAndMessageFilter andFilter in matchingFilters)
|
||||
{
|
||||
results.Add(andFilter);
|
||||
}
|
||||
return (matchingFilters.Count > 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetMatchingFilters(Message message, ICollection<MessageFilter> results)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("message");
|
||||
}
|
||||
|
||||
List<MessageFilter> firstPassResults = new List<MessageFilter>();
|
||||
if (this.filterTable.GetMatchingFilters(message, firstPassResults))
|
||||
{
|
||||
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
|
||||
foreach (StrictAndMessageFilter andFilter in matchingFilters)
|
||||
{
|
||||
results.Add(andFilter);
|
||||
}
|
||||
return (matchingFilters.Count > 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetMatchingValue(MessageBuffer messageBuffer, out TFilterData value)
|
||||
{
|
||||
value = default(TFilterData);
|
||||
List<TFilterData> results = new List<TFilterData>();
|
||||
bool result = this.GetMatchingValues(messageBuffer, results);
|
||||
if (results.Count == 1)
|
||||
{
|
||||
value = results[0];
|
||||
}
|
||||
if (results.Count > 1)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new MultipleFilterMatchesException());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool GetMatchingValue(Message message, out TFilterData value)
|
||||
{
|
||||
value = default(TFilterData);
|
||||
List<TFilterData> results = new List<TFilterData>();
|
||||
bool result = this.GetMatchingValues(message, results);
|
||||
if (results.Count == 1)
|
||||
{
|
||||
value = results[0];
|
||||
}
|
||||
else if (results.Count > 1)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new MultipleFilterMatchesException());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection<TFilterData> results)
|
||||
{
|
||||
if (messageBuffer == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("messageBuffer");
|
||||
}
|
||||
|
||||
List<MessageFilter> firstPassResults = new List<MessageFilter>();
|
||||
if (this.filterTable.GetMatchingFilters(messageBuffer, firstPassResults))
|
||||
{
|
||||
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
|
||||
foreach (StrictAndMessageFilter andFilter in matchingFilters)
|
||||
{
|
||||
results.Add(this.andFilters[andFilter]);
|
||||
}
|
||||
return (matchingFilters.Count > 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetMatchingValues(Message message, ICollection<TFilterData> results)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("message");
|
||||
}
|
||||
|
||||
List<MessageFilter> firstPassResults = new List<MessageFilter>();
|
||||
if (this.filterTable.GetMatchingFilters(message, firstPassResults))
|
||||
{
|
||||
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
|
||||
foreach (StrictAndMessageFilter andFilter in matchingFilters)
|
||||
{
|
||||
results.Add(this.andFilters[andFilter]);
|
||||
}
|
||||
return (matchingFilters.Count > 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IList<StrictAndMessageFilter> FindMatchingAndFilters(List<MessageFilter> firstPassResults)
|
||||
{
|
||||
IList<StrictAndMessageFilter> matchingFilters = new List<StrictAndMessageFilter>();
|
||||
foreach (MessageFilter filter in firstPassResults)
|
||||
{
|
||||
StrictAndMessageFilter andFilter = this.filterTable[filter];
|
||||
// Check if this StrictAndMessageFilter is already in our result set
|
||||
if (!matchingFilters.Contains(andFilter))
|
||||
{
|
||||
if (firstPassResults.Contains(andFilter.filter1) && firstPassResults.Contains(andFilter.filter2))
|
||||
{
|
||||
matchingFilters.Add(andFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchingFilters;
|
||||
}
|
||||
|
||||
public void Add(MessageFilter key, TFilterData value)
|
||||
{
|
||||
StrictAndMessageFilter andFilter = (StrictAndMessageFilter)key;
|
||||
this.andFilters.Add(andFilter, value);
|
||||
this.filterTable.Add(andFilter.filter1, andFilter);
|
||||
this.filterTable.Add(andFilter.filter2, andFilter);
|
||||
}
|
||||
|
||||
public bool ContainsKey(MessageFilter key)
|
||||
{
|
||||
return this.andFilters.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool Remove(MessageFilter key)
|
||||
{
|
||||
StrictAndMessageFilter andFilter = (StrictAndMessageFilter)key;
|
||||
if (this.andFilters.Remove(andFilter))
|
||||
{
|
||||
this.filterTable.Remove(andFilter.filter1);
|
||||
this.filterTable.Remove(andFilter.filter2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetValue(MessageFilter key, out TFilterData value)
|
||||
{
|
||||
return this.andFilters.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<MessageFilter, TFilterData> item)
|
||||
{
|
||||
this.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
this.andFilters.Clear();
|
||||
this.filterTable.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<MessageFilter, TFilterData> item)
|
||||
{
|
||||
return this.andFilters.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<MessageFilter, TFilterData>[] array, int arrayIndex)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotImplementedException());
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<MessageFilter, TFilterData> item)
|
||||
{
|
||||
return this.andFilters.Remove(item.Key);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<MessageFilter, TFilterData>> GetEnumerator()
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotImplementedException());
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotImplementedException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
484
external/referencesource/System.ServiceModel.Routing/System/ServiceModel/Routing/ClientFactory.cs
vendored
Normal file
484
external/referencesource/System.ServiceModel.Routing/System/ServiceModel/Routing/ClientFactory.cs
vendored
Normal file
@ -0,0 +1,484 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Description;
|
||||
using System.Transactions;
|
||||
using System.Runtime.Diagnostics;
|
||||
using System.ServiceModel.Diagnostics;
|
||||
|
||||
static class ClientFactory
|
||||
{
|
||||
public static IRoutingClient Create(RoutingEndpointTrait endpointTrait, RoutingService service, bool impersonating)
|
||||
{
|
||||
Type contractType = endpointTrait.RouterContract;
|
||||
IRoutingClient client;
|
||||
if (contractType == typeof(ISimplexDatagramRouter))
|
||||
{
|
||||
client = new SimplexDatagramClient(endpointTrait, service.RoutingConfig, impersonating);
|
||||
}
|
||||
else if (contractType == typeof(IRequestReplyRouter))
|
||||
{
|
||||
client = new RequestReplyClient(endpointTrait, service.RoutingConfig, impersonating);
|
||||
}
|
||||
else if (contractType == typeof(ISimplexSessionRouter))
|
||||
{
|
||||
client = new SimplexSessionClient(endpointTrait, service.RoutingConfig, impersonating);
|
||||
}
|
||||
else //if (contractType == typeof(IDuplexSessionRouter))
|
||||
{
|
||||
Fx.Assert(contractType == typeof(IDuplexSessionRouter), "Only one contract type remaining.");
|
||||
client = new DuplexSessionClient(service, endpointTrait, impersonating);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
abstract class RoutingClientBase<TChannel> : ClientBase<TChannel>, IRoutingClient
|
||||
where TChannel : class
|
||||
{
|
||||
bool openCompleted;
|
||||
object thisLock;
|
||||
Queue<OperationAsyncResult> waiters;
|
||||
|
||||
protected RoutingClientBase(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
|
||||
: base(endpointTrait.Endpoint.Binding, endpointTrait.Endpoint.Address)
|
||||
{
|
||||
Initialize(endpointTrait, routingConfig, impersonating);
|
||||
}
|
||||
|
||||
protected RoutingClientBase(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, object callbackInstance, bool impersonating)
|
||||
: base(new InstanceContext(callbackInstance), endpointTrait.Endpoint.Binding, endpointTrait.Endpoint.Address)
|
||||
{
|
||||
Initialize(endpointTrait, routingConfig, impersonating);
|
||||
}
|
||||
|
||||
public RoutingEndpointTrait Key
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public event EventHandler Faulted;
|
||||
|
||||
static void ConfigureImpersonation(ServiceEndpoint endpoint, bool impersonating)
|
||||
{
|
||||
// Used for both impersonation and ASP.NET Compatibilty Mode. Both currently require
|
||||
// everything to be synchronous.
|
||||
if (impersonating)
|
||||
{
|
||||
CustomBinding binding = endpoint.Binding as CustomBinding;
|
||||
if (binding == null)
|
||||
{
|
||||
binding = new CustomBinding(endpoint.Binding);
|
||||
}
|
||||
|
||||
SynchronousSendBindingElement syncSend = binding.Elements.Find<SynchronousSendBindingElement>();
|
||||
if (syncSend == null)
|
||||
{
|
||||
binding.Elements.Insert(0, new SynchronousSendBindingElement());
|
||||
endpoint.Binding = binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ConfigureTransactionFlow(ServiceEndpoint endpoint)
|
||||
{
|
||||
CustomBinding binding = endpoint.Binding as CustomBinding;
|
||||
if (binding == null)
|
||||
{
|
||||
binding = new CustomBinding(endpoint.Binding);
|
||||
}
|
||||
TransactionFlowBindingElement transactionFlow = binding.Elements.Find<TransactionFlowBindingElement>();
|
||||
if (transactionFlow != null)
|
||||
{
|
||||
transactionFlow.AllowWildcardAction = true;
|
||||
endpoint.Binding = binding;
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
|
||||
{
|
||||
this.thisLock = new object();
|
||||
this.Key = endpointTrait;
|
||||
if (TD.RoutingServiceCreatingClientForEndpointIsEnabled())
|
||||
{
|
||||
TD.RoutingServiceCreatingClientForEndpoint(this.Key.ToString());
|
||||
}
|
||||
ServiceEndpoint clientEndpoint = endpointTrait.Endpoint;
|
||||
ServiceEndpoint endpoint = this.Endpoint;
|
||||
KeyedByTypeCollection<IEndpointBehavior> behaviors = endpoint.Behaviors;
|
||||
endpoint.ListenUri = clientEndpoint.ListenUri;
|
||||
endpoint.ListenUriMode = clientEndpoint.ListenUriMode;
|
||||
endpoint.Name = clientEndpoint.Name;
|
||||
foreach (IEndpointBehavior behavior in clientEndpoint.Behaviors)
|
||||
{
|
||||
// Remove if present, ok to call if not there (will simply return false)
|
||||
behaviors.Remove(behavior.GetType());
|
||||
behaviors.Add(behavior);
|
||||
}
|
||||
|
||||
// If the configuration doesn't explicitly add MustUnderstandBehavior (to override us)
|
||||
// add it here, with mustunderstand = false.
|
||||
if (behaviors.Find<MustUnderstandBehavior>() == null)
|
||||
{
|
||||
behaviors.Add(new MustUnderstandBehavior(false));
|
||||
}
|
||||
|
||||
// If the configuration doesn't explicitly turn off marshaling we add it here.
|
||||
if (routingConfig.SoapProcessingEnabled && behaviors.Find<SoapProcessingBehavior>() == null)
|
||||
{
|
||||
behaviors.Add(new SoapProcessingBehavior());
|
||||
}
|
||||
|
||||
ConfigureTransactionFlow(endpoint);
|
||||
ConfigureImpersonation(endpoint, impersonating);
|
||||
}
|
||||
|
||||
protected override TChannel CreateChannel()
|
||||
{
|
||||
TChannel channel = base.CreateChannel();
|
||||
((ICommunicationObject)channel).Faulted += this.InnerChannelFaulted;
|
||||
return channel;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginOperation(Message message, Transaction transaction, AsyncCallback callback, object state)
|
||||
{
|
||||
return new OperationAsyncResult(this, message, transaction, callback, state);
|
||||
}
|
||||
|
||||
public Message EndOperation(IAsyncResult result)
|
||||
{
|
||||
return OperationAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected abstract IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state);
|
||||
protected abstract Message OnEndOperation(IAsyncResult asyncResult);
|
||||
|
||||
void InnerChannelFaulted(object sender, EventArgs args)
|
||||
{
|
||||
EventHandler handlers = this.Faulted;
|
||||
if (handlers != null)
|
||||
{
|
||||
handlers(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
class OperationAsyncResult : TransactedAsyncResult
|
||||
{
|
||||
static AsyncCompletion openComplete = OpenComplete;
|
||||
static AsyncCompletion operationComplete = OperationComplete;
|
||||
static Action<object> signalWaiter;
|
||||
|
||||
RoutingClientBase<TChannel> parent;
|
||||
Message replyMessage;
|
||||
Message requestMessage;
|
||||
Transaction transaction;
|
||||
|
||||
public OperationAsyncResult(RoutingClientBase<TChannel> parent, Message requestMessage, Transaction transaction, AsyncCallback callback, object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.requestMessage = requestMessage;
|
||||
this.transaction = transaction;
|
||||
|
||||
bool shouldOpen = false;
|
||||
|
||||
if (!this.parent.openCompleted)
|
||||
{
|
||||
lock (this.parent.thisLock)
|
||||
{
|
||||
if (!this.parent.openCompleted)
|
||||
{
|
||||
//The first to open initializes the waiters queue others add themselves to it.
|
||||
if (this.parent.waiters == null)
|
||||
{
|
||||
//it's our job to open the proxy
|
||||
this.parent.waiters = new Queue<OperationAsyncResult>();
|
||||
shouldOpen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Someone beat us to it, just join the list of waiters.
|
||||
this.parent.waiters.Enqueue(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldOpen)
|
||||
{
|
||||
//we are the first so we need to open this channel
|
||||
IAsyncResult asyncResult;
|
||||
using (this.PrepareTransactionalCall(this.transaction))
|
||||
{
|
||||
//This will use the binding's OpenTimeout.
|
||||
asyncResult = ((ICommunicationObject)this.parent).BeginOpen(this.PrepareAsyncCompletion(openComplete), this);
|
||||
}
|
||||
if (this.SyncContinue(asyncResult))
|
||||
{
|
||||
this.Complete(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.CallOperation())
|
||||
{
|
||||
this.Complete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Message End(IAsyncResult result)
|
||||
{
|
||||
OperationAsyncResult thisPtr = AsyncResult.End<OperationAsyncResult>(result);
|
||||
return thisPtr.replyMessage;
|
||||
}
|
||||
|
||||
static bool OpenComplete(IAsyncResult openResult)
|
||||
{
|
||||
OperationAsyncResult thisPtr = (OperationAsyncResult)openResult.AsyncState;
|
||||
try
|
||||
{
|
||||
((ICommunicationObject)thisPtr.parent).EndOpen(openResult);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Queue<OperationAsyncResult> localWaiters = null;
|
||||
|
||||
lock (thisPtr.parent.thisLock)
|
||||
{
|
||||
localWaiters = thisPtr.parent.waiters;
|
||||
thisPtr.parent.waiters = null;
|
||||
thisPtr.parent.openCompleted = true;
|
||||
}
|
||||
|
||||
if (localWaiters != null && localWaiters.Count > 0)
|
||||
{
|
||||
if (signalWaiter == null)
|
||||
{
|
||||
signalWaiter = new Action<object>(SignalWaiter);
|
||||
}
|
||||
|
||||
//foreach over Queue<T> goes FIFO
|
||||
foreach (OperationAsyncResult waiter in localWaiters)
|
||||
{
|
||||
ActionItem.Schedule(signalWaiter, waiter);
|
||||
}
|
||||
}
|
||||
}
|
||||
return thisPtr.CallOperation();
|
||||
}
|
||||
|
||||
bool CallOperation()
|
||||
{
|
||||
IAsyncResult asyncResult;
|
||||
using (this.PrepareTransactionalCall(this.transaction))
|
||||
{
|
||||
asyncResult = this.parent.OnBeginOperation(this.requestMessage, this.PrepareAsyncCompletion(operationComplete), this);
|
||||
}
|
||||
return this.SyncContinue(asyncResult);
|
||||
}
|
||||
|
||||
static bool OperationComplete(IAsyncResult result)
|
||||
{
|
||||
OperationAsyncResult thisPtr = (OperationAsyncResult)result.AsyncState;
|
||||
thisPtr.replyMessage = thisPtr.parent.OnEndOperation(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SignalWaiter(object state)
|
||||
{
|
||||
OperationAsyncResult waiter = (OperationAsyncResult)state;
|
||||
try
|
||||
{
|
||||
if (waiter.CallOperation())
|
||||
{
|
||||
waiter.Complete(false);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (Fx.IsFatal(exception))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
waiter.Complete(false, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SimplexDatagramClient : RoutingClientBase<ISimplexDatagramRouter>
|
||||
{
|
||||
public SimplexDatagramClient(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
|
||||
: base(endpointTrait, routingConfig, impersonating)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.Channel.BeginProcessMessage(message, callback, state);
|
||||
}
|
||||
|
||||
protected override Message OnEndOperation(IAsyncResult result)
|
||||
{
|
||||
this.Channel.EndProcessMessage(result);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class SimplexSessionClient : RoutingClientBase<ISimplexSessionRouter>
|
||||
{
|
||||
public SimplexSessionClient(RoutingEndpointTrait endointTrait, RoutingConfiguration routingConfig, bool impersonating)
|
||||
: base(endointTrait, routingConfig, impersonating)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.Channel.BeginProcessMessage(message, callback, state);
|
||||
}
|
||||
|
||||
protected override Message OnEndOperation(IAsyncResult result)
|
||||
{
|
||||
this.Channel.EndProcessMessage(result);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class DuplexSessionClient : RoutingClientBase<IDuplexSessionRouter>
|
||||
{
|
||||
public DuplexSessionClient(RoutingService service, RoutingEndpointTrait endpointTrait, bool impersonating)
|
||||
: base(endpointTrait, service.RoutingConfig, new DuplexCallbackProxy(service.ChannelExtension.ActivityID, endpointTrait.CallbackInstance), impersonating)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.Channel.BeginProcessMessage(message, callback, state);
|
||||
}
|
||||
|
||||
protected override Message OnEndOperation(IAsyncResult result)
|
||||
{
|
||||
this.Channel.EndProcessMessage(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
class DuplexCallbackProxy : IDuplexRouterCallback
|
||||
{
|
||||
Guid activityID;
|
||||
IDuplexRouterCallback callbackInstance;
|
||||
EventTraceActivity eventTraceActivity;
|
||||
|
||||
public DuplexCallbackProxy(Guid activityID, IDuplexRouterCallback callbackInstance)
|
||||
{
|
||||
this.activityID = activityID;
|
||||
this.callbackInstance = callbackInstance;
|
||||
if (Fx.Trace.IsEtwProviderEnabled)
|
||||
{
|
||||
this.eventTraceActivity = new EventTraceActivity(activityID);
|
||||
}
|
||||
}
|
||||
|
||||
IAsyncResult IDuplexRouterCallback.BeginProcessMessage(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
FxTrace.Trace.SetAndTraceTransfer(this.activityID, true);
|
||||
try
|
||||
{
|
||||
return new CallbackAsyncResult(this.callbackInstance, message, callback, state);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (TD.RoutingServiceDuplexCallbackExceptionIsEnabled())
|
||||
{
|
||||
TD.RoutingServiceDuplexCallbackException(this.eventTraceActivity, "DuplexCallbackProxy.BeginProcessMessage", e);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void IDuplexRouterCallback.EndProcessMessage(IAsyncResult result)
|
||||
{
|
||||
FxTrace.Trace.SetAndTraceTransfer(this.activityID, true);
|
||||
try
|
||||
{
|
||||
CallbackAsyncResult.End(result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (TD.RoutingServiceDuplexCallbackExceptionIsEnabled())
|
||||
{
|
||||
TD.RoutingServiceDuplexCallbackException(this.eventTraceActivity, "DuplexCallbackProxy.EndProcessMessage", e);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// We have to have an AsyncResult implementation here in order to handle the
|
||||
// TransactionScope appropriately (use PrepareTransactionalCall, SyncContinue, etc...)
|
||||
class CallbackAsyncResult : TransactedAsyncResult
|
||||
{
|
||||
static AsyncCompletion processCallback = ProcessCallback;
|
||||
IDuplexRouterCallback callbackInstance;
|
||||
|
||||
public CallbackAsyncResult(IDuplexRouterCallback callbackInstance, Message message, AsyncCallback callback, object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
this.callbackInstance = callbackInstance;
|
||||
|
||||
IAsyncResult result;
|
||||
using (this.PrepareTransactionalCall(TransactionMessageProperty.TryGetTransaction(message)))
|
||||
{
|
||||
result = this.callbackInstance.BeginProcessMessage(message,
|
||||
this.PrepareAsyncCompletion(processCallback), this);
|
||||
}
|
||||
|
||||
if (this.SyncContinue(result))
|
||||
{
|
||||
this.Complete(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void End(IAsyncResult result)
|
||||
{
|
||||
AsyncResult.End<CallbackAsyncResult>(result);
|
||||
}
|
||||
|
||||
static bool ProcessCallback(IAsyncResult result)
|
||||
{
|
||||
CallbackAsyncResult thisPtr = (CallbackAsyncResult)result.AsyncState;
|
||||
thisPtr.callbackInstance.EndProcessMessage(result);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RequestReplyClient : RoutingClientBase<IRequestReplyRouter>
|
||||
{
|
||||
public RequestReplyClient(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
|
||||
: base(endpointTrait, routingConfig, impersonating)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.Channel.BeginProcessRequest(message, callback, state);
|
||||
}
|
||||
|
||||
protected override Message OnEndOperation(IAsyncResult result)
|
||||
{
|
||||
return this.Channel.EndProcessRequest(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Description;
|
||||
|
||||
sealed class ClientEndpointLoader : ChannelFactory
|
||||
{
|
||||
ClientEndpointLoader(string configurationName)
|
||||
{
|
||||
base.InitializeEndpoint(configurationName, null);
|
||||
base.Endpoint.Name = configurationName;
|
||||
}
|
||||
|
||||
public static ServiceEndpoint LoadEndpoint(string configurationName)
|
||||
{
|
||||
using (ClientEndpointLoader loader = new ClientEndpointLoader(configurationName))
|
||||
{
|
||||
return loader.Endpoint;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ServiceEndpoint CreateDescription()
|
||||
{
|
||||
ServiceEndpoint ep = new ServiceEndpoint(new ContractDescription("contract"));
|
||||
ep.Contract.ConfigurationName = "*";
|
||||
return ep;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing.Configuration
|
||||
{
|
||||
static class ConfigurationStrings
|
||||
{
|
||||
internal const string BackupList = "backupList";
|
||||
internal const string BackupLists = "backupLists";
|
||||
internal const string CustomType = "customType";
|
||||
internal const string EndpointName = "endpointName";
|
||||
internal const string Endpoints = "endpoints";
|
||||
internal const string Entries = "entries";
|
||||
internal const string Filter = "filter";
|
||||
internal const string Filter1 = "filter1";
|
||||
internal const string Filter2 = "filter2";
|
||||
internal const string FilterData = "filterData";
|
||||
internal const string FilterName = "filterName";
|
||||
internal const string Filters = "filters";
|
||||
internal const string FilterTable = "filterTable";
|
||||
internal const string FilterTableName = "filterTableName";
|
||||
internal const string FilterTables = "filterTables";
|
||||
internal const string FilterType = "filterType";
|
||||
//internal const string Impersonation = "impersonation";
|
||||
internal const string Name = "name";
|
||||
internal const string Namespace = "namespace";
|
||||
internal const string NamespaceTable = "namespaceTable";
|
||||
internal const string Prefix = "prefix";
|
||||
internal const string Priority = "priority";
|
||||
internal const string ProcessMessages = "processMessages";
|
||||
internal const string RouteOnHeadersOnly = "routeOnHeadersOnly";
|
||||
internal const string SoapProcessingEnabled = "soapProcessingEnabled";
|
||||
internal const string EnsureOrderedDispatch = "ensureOrderedDispatch";
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing.Configuration
|
||||
{
|
||||
using System;
|
||||
|
||||
public enum FilterType
|
||||
{
|
||||
Action,
|
||||
EndpointAddress,
|
||||
PrefixEndpointAddress,
|
||||
And,
|
||||
Custom,
|
||||
EndpointName,
|
||||
MatchAll,
|
||||
XPath
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.ServiceModel.Description;
|
||||
|
||||
public sealed class RoutingExtensionElement : BehaviorExtensionElement
|
||||
{
|
||||
public RoutingExtensionElement()
|
||||
{
|
||||
this.RouteOnHeadersOnly = RoutingConfiguration.DefaultRouteOnHeadersOnly;
|
||||
}
|
||||
|
||||
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationPropertyAttributeRule, Justification = "this is not a configuration property")]
|
||||
public override Type BehaviorType
|
||||
{
|
||||
get { return typeof(RoutingBehavior); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.RouteOnHeadersOnly, DefaultValue = RoutingConfiguration.DefaultRouteOnHeadersOnly, Options = ConfigurationPropertyOptions.None)]
|
||||
public bool RouteOnHeadersOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)this[ConfigurationStrings.RouteOnHeadersOnly];
|
||||
}
|
||||
set
|
||||
{
|
||||
this[ConfigurationStrings.RouteOnHeadersOnly] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationValidatorAttributeRule, Justification = "fxcop didn't like [StringValidator(MinLength = 0)]")]
|
||||
[ConfigurationProperty(ConfigurationStrings.FilterTableName, DefaultValue = null)]
|
||||
public string FilterTableName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)this[ConfigurationStrings.FilterTableName];
|
||||
}
|
||||
set
|
||||
{
|
||||
this[ConfigurationStrings.FilterTableName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.SoapProcessingEnabled, DefaultValue = RoutingConfiguration.DefaultSoapProcessingEnabled)]
|
||||
public bool SoapProcessingEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)this[ConfigurationStrings.SoapProcessingEnabled];
|
||||
}
|
||||
set
|
||||
{
|
||||
this[ConfigurationStrings.SoapProcessingEnabled] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.EnsureOrderedDispatch, DefaultValue = RoutingConfiguration.DefaultEnsureOrderedDispatch)]
|
||||
public bool EnsureOrderedDispatch
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)this[ConfigurationStrings.EnsureOrderedDispatch];
|
||||
}
|
||||
set
|
||||
{
|
||||
this[ConfigurationStrings.EnsureOrderedDispatch] = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override object CreateBehavior()
|
||||
{
|
||||
RoutingConfiguration config;
|
||||
if (string.IsNullOrEmpty(this.FilterTableName))
|
||||
{
|
||||
config = new RoutingConfiguration();
|
||||
config.RouteOnHeadersOnly = this.RouteOnHeadersOnly;
|
||||
}
|
||||
else
|
||||
{
|
||||
config = new RoutingConfiguration(RoutingSection.CreateFilterTable(this.FilterTableName), this.RouteOnHeadersOnly);
|
||||
}
|
||||
|
||||
config.SoapProcessingEnabled = this.SoapProcessingEnabled;
|
||||
config.EnsureOrderedDispatch = this.EnsureOrderedDispatch;
|
||||
RoutingBehavior behavior = new RoutingBehavior(config);
|
||||
//behavior.Impersonation = this.Impersonation;
|
||||
return behavior;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.Configuration;
|
||||
|
||||
public class SoapProcessingExtensionElement : BehaviorExtensionElement
|
||||
{
|
||||
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationPropertyAttributeRule, Justification = "this is not a configuration property")]
|
||||
public override Type BehaviorType
|
||||
{
|
||||
get { return typeof(SoapProcessingBehavior); }
|
||||
}
|
||||
|
||||
protected internal override object CreateBehavior()
|
||||
{
|
||||
SoapProcessingBehavior behavior = new SoapProcessingBehavior();
|
||||
behavior.ProcessMessages = this.ProcessMessages;
|
||||
return behavior;
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ConfigurationStrings.ProcessMessages, DefaultValue = true, Options = ConfigurationPropertyOptions.None)]
|
||||
public bool ProcessMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)this[ConfigurationStrings.ProcessMessages];
|
||||
}
|
||||
set
|
||||
{
|
||||
this[ConfigurationStrings.ProcessMessages] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Xml;
|
||||
using System.Runtime;
|
||||
|
||||
class DelegatingHeader : MessageHeader
|
||||
{
|
||||
int index;
|
||||
MessageHeaderInfo info;
|
||||
MessageHeaders originalHeaders;
|
||||
|
||||
public DelegatingHeader(MessageHeaderInfo info, MessageHeaders originalHeaders)
|
||||
{
|
||||
Fx.Assert(info != null, "info is required");
|
||||
Fx.Assert(originalHeaders != null, "originalHeaders is required");
|
||||
|
||||
this.info = info;
|
||||
this.originalHeaders = originalHeaders;
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
void EnsureIndex()
|
||||
{
|
||||
if (this.index < 0)
|
||||
{
|
||||
this.index = this.originalHeaders.FindHeader(this.info.Name, this.info.Namespace);
|
||||
if (this.index < 0)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.SourceHeaderNotFound(this.info.Name, this.info.Namespace)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
|
||||
{
|
||||
this.EnsureIndex();
|
||||
this.originalHeaders.WriteHeaderContents(index, writer);
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
|
||||
{
|
||||
this.EnsureIndex();
|
||||
this.originalHeaders.WriteStartHeader(this.index, writer);
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return this.info.Name; }
|
||||
}
|
||||
|
||||
public override string Namespace
|
||||
{
|
||||
get { return this.info.Namespace; }
|
||||
}
|
||||
|
||||
public override bool MustUnderstand
|
||||
{
|
||||
get { return this.info.MustUnderstand; }
|
||||
}
|
||||
|
||||
public override string Actor
|
||||
{
|
||||
get { return this.info.Actor; }
|
||||
}
|
||||
|
||||
public override bool IsReferenceParameter
|
||||
{
|
||||
get { return this.info.IsReferenceParameter; }
|
||||
}
|
||||
|
||||
public override bool Relay
|
||||
{
|
||||
get { return base.Relay; }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Description;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
|
||||
sealed class GenericTransactionFlowAttribute : Attribute, IOperationBehavior
|
||||
{
|
||||
TransactionFlowAttribute transactionFlowAttribute;
|
||||
|
||||
public GenericTransactionFlowAttribute(TransactionFlowOption flowOption)
|
||||
{
|
||||
this.transactionFlowAttribute = new TransactionFlowAttribute(flowOption);
|
||||
}
|
||||
|
||||
void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
|
||||
{
|
||||
((IOperationBehavior)this.transactionFlowAttribute).AddBindingParameters(operationDescription, bindingParameters);
|
||||
}
|
||||
|
||||
void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
|
||||
{
|
||||
((IOperationBehavior)this.transactionFlowAttribute).ApplyClientBehavior(operationDescription, clientOperation);
|
||||
}
|
||||
|
||||
void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
|
||||
{
|
||||
((IOperationBehavior)this.transactionFlowAttribute).ApplyDispatchBehavior(operationDescription, dispatchOperation);
|
||||
}
|
||||
|
||||
void IOperationBehavior.Validate(OperationDescription operationDescription)
|
||||
{
|
||||
((IOperationBehavior)this.transactionFlowAttribute).Validate(operationDescription);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Allowed)]
|
||||
interface IDuplexRouterCallback
|
||||
{
|
||||
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
|
||||
[GenericTransactionFlow(TransactionFlowOption.Allowed)]
|
||||
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
|
||||
|
||||
void EndProcessMessage(IAsyncResult result);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Required, CallbackContract = typeof(IDuplexRouterCallback))]
|
||||
public interface IDuplexSessionRouter
|
||||
{
|
||||
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
|
||||
[GenericTransactionFlow(TransactionFlowOption.Allowed)]
|
||||
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
|
||||
|
||||
void EndProcessMessage(IAsyncResult result);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Allowed)]
|
||||
public interface IRequestReplyRouter
|
||||
{
|
||||
[OperationContract(AsyncPattern = true, IsOneWay = false, Action = "*", ReplyAction = "*")]
|
||||
[GenericTransactionFlow(TransactionFlowOption.Allowed)]
|
||||
IAsyncResult BeginProcessRequest(Message message, AsyncCallback callback, object state);
|
||||
|
||||
Message EndProcessRequest(IAsyncResult result);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Transactions;
|
||||
|
||||
interface IRoutingClient
|
||||
{
|
||||
IAsyncResult BeginOperation(Message message, Transaction transaction, AsyncCallback callback, object state);
|
||||
Message EndOperation(IAsyncResult result);
|
||||
event EventHandler Faulted;
|
||||
RoutingEndpointTrait Key { get; }
|
||||
CommunicationState State { get; }
|
||||
void Open();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Allowed)]
|
||||
public interface ISimplexDatagramRouter
|
||||
{
|
||||
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
|
||||
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
|
||||
|
||||
void EndProcessMessage(IAsyncResult result);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Required)]
|
||||
public interface ISimplexSessionRouter
|
||||
{
|
||||
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
|
||||
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
|
||||
|
||||
void EndProcessMessage(IAsyncResult result);
|
||||
}
|
||||
}
|
269
external/referencesource/System.ServiceModel.Routing/System/ServiceModel/Routing/MessageRpc.cs
vendored
Normal file
269
external/referencesource/System.ServiceModel.Routing/System/ServiceModel/Routing/MessageRpc.cs
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
//----------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Routing
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Activation;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Description;
|
||||
using System.ServiceModel.Security;
|
||||
using System.Transactions;
|
||||
using SR2 = System.ServiceModel.Routing.SR;
|
||||
using System.Security.Principal;
|
||||
using System.Runtime.Diagnostics;
|
||||
using System.ServiceModel.Diagnostics;
|
||||
|
||||
// This class wraps a Message, MessageBuffer (if requested), and the OperationContext
|
||||
// The message is not buffered if nobody calls MessageRpc.CreateBuffer. If the message
|
||||
// is buffered, then we hang on to the buffer so it can be reused and Clone the message
|
||||
// which became invalid when we buffered this message.
|
||||
class MessageRpc
|
||||
{
|
||||
const int ERROR_BAD_IMPERSONATION_LEVEL = 1346;
|
||||
|
||||
Message originalMessage;
|
||||
Message clonedMessage;
|
||||
MessageBuffer messageBuffer;
|
||||
string uniqueID;
|
||||
Transaction transaction;
|
||||
ReceiveContext receiveContext;
|
||||
IList<SendOperation> operations;
|
||||
WindowsIdentity windowsIdentity;
|
||||
EventTraceActivity eventTraceActivity;
|
||||
|
||||
public MessageRpc(Message message, OperationContext operationContext, bool impersonationRequired)
|
||||
{
|
||||
Fx.Assert(message != null, "message cannot be null");
|
||||
Fx.Assert(operationContext != null, "operationContext cannot be null");
|
||||
|
||||
this.originalMessage = message;
|
||||
this.OperationContext = operationContext;
|
||||
|
||||
if (Fx.Trace.IsEtwProviderEnabled)
|
||||
{
|
||||
this.eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message);
|
||||
}
|
||||
|
||||
//passing in true causes this to return null if the thread is not impersonating.
|
||||
this.windowsIdentity = WindowsIdentity.GetCurrent(true);
|
||||
if (impersonationRequired && !AspNetEnvironment.Current.AspNetCompatibilityEnabled)
|
||||
{
|
||||
if (this.windowsIdentity == null || this.windowsIdentity.ImpersonationLevel != TokenImpersonationLevel.Impersonation)
|
||||
{
|
||||
//Temporarily revert impersonation to process token to throw an exception
|
||||
IDisposable autoRevert = null;
|
||||
try
|
||||
{
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
autoRevert = WindowsIdentity.Impersonate(IntPtr.Zero);
|
||||
}
|
||||
|
||||
Win32Exception errorDetail = new Win32Exception(ERROR_BAD_IMPERSONATION_LEVEL);
|
||||
throw FxTrace.Exception.AsError(new SecurityNegotiationException(errorDetail.Message));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (autoRevert != null)
|
||||
{
|
||||
autoRevert.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReceiveContext.TryGet(message, out this.receiveContext);
|
||||
|
||||
this.transaction = Transaction.Current;
|
||||
if (this.transaction == null)
|
||||
{
|
||||
this.transaction = TransactionMessageProperty.TryGetTransaction(message);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Impersonating
|
||||
{
|
||||
get { return this.windowsIdentity != null; }
|
||||
}
|
||||
|
||||
internal EventTraceActivity EventTraceActivity
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.eventTraceActivity;
|
||||
}
|
||||
}
|
||||
|
||||
public OperationContext OperationContext
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string UniqueID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.uniqueID == null)
|
||||
{
|
||||
if (this.Message.Version != MessageVersion.None &&
|
||||
this.Message.Headers.MessageId != null)
|
||||
{
|
||||
this.uniqueID = this.originalMessage.Headers.MessageId.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.uniqueID = this.GetHashCode().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
return this.uniqueID;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message
|
||||
{
|
||||
get
|
||||
{
|
||||
// If we've created a MessageBuffer then the originalMessage has already been consumed
|
||||
if (this.messageBuffer != null)
|
||||
{
|
||||
Fx.Assert(this.clonedMessage != null, "Need to set clonedMessage if we buffered the message");
|
||||
return this.clonedMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Haven't buffered, can use the original.
|
||||
return this.originalMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ReceiveContext ReceiveContext
|
||||
{
|
||||
get { return this.receiveContext; }
|
||||
}
|
||||
|
||||
public IList<SendOperation> Operations
|
||||
{
|
||||
get { return this.operations; }
|
||||
}
|
||||
|
||||
public Transaction Transaction
|
||||
{
|
||||
get { return this.transaction; }
|
||||
}
|
||||
|
||||
public MessageBuffer CreateBuffer()
|
||||
{
|
||||
if (this.messageBuffer == null)
|
||||
{
|
||||
this.messageBuffer = this.originalMessage.CreateBufferedCopy(int.MaxValue);
|
||||
this.clonedMessage = this.messageBuffer.CreateMessage();
|
||||
}
|
||||
return this.messageBuffer;
|
||||
}
|
||||
|
||||
public IDisposable PrepareCall()
|
||||
{
|
||||
return new CallState(this);
|
||||
}
|
||||
|
||||
public void RouteToSingleEndpoint<TContract>(RoutingConfiguration routingConfig)
|
||||
{
|
||||
IEnumerable<ServiceEndpoint> result;
|
||||
if (routingConfig.RouteOnHeadersOnly)
|
||||
{
|
||||
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
|
||||
routingConfig.InternalFilterTable.GetMatchingValue(this.Message, out result);
|
||||
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBuffer buffer = this.CreateBuffer();
|
||||
|
||||
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
|
||||
routingConfig.InternalFilterTable.GetMatchingValue(buffer, out result);
|
||||
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.NoFilterMatched));
|
||||
}
|
||||
|
||||
if (TD.RoutingServiceMessageRoutedToEndpointsIsEnabled())
|
||||
{
|
||||
TD.RoutingServiceMessageRoutedToEndpoints(this.eventTraceActivity, this.UniqueID, "1");
|
||||
}
|
||||
|
||||
this.operations = new List<SendOperation>(1);
|
||||
this.operations.Add(new SendOperation(result, typeof(TContract), this.OperationContext));
|
||||
}
|
||||
|
||||
public void RouteToEndpoints<TContract>(RoutingConfiguration routingConfig)
|
||||
{
|
||||
List<IEnumerable<ServiceEndpoint>> endpointLists = new List<IEnumerable<ServiceEndpoint>>();
|
||||
if (routingConfig.RouteOnHeadersOnly)
|
||||
{
|
||||
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
|
||||
routingConfig.InternalFilterTable.GetMatchingValues(this.Message, endpointLists);
|
||||
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBuffer messageBuffer = this.CreateBuffer();
|
||||
|
||||
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
|
||||
routingConfig.InternalFilterTable.GetMatchingValues(messageBuffer, endpointLists);
|
||||
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
|
||||
}
|
||||
|
||||
if (TD.RoutingServiceMessageRoutedToEndpointsIsEnabled())
|
||||
{
|
||||
TD.RoutingServiceMessageRoutedToEndpoints(this.eventTraceActivity, this.UniqueID, endpointLists.Count.ToString(TD.Culture));
|
||||
}
|
||||
if (endpointLists.Count == 0)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.NoFilterMatched));
|
||||
}
|
||||
this.operations = new List<SendOperation>(endpointLists.Count);
|
||||
foreach (IEnumerable<ServiceEndpoint> endpointList in endpointLists)
|
||||
{
|
||||
this.operations.Add(new SendOperation(endpointList, typeof(TContract), this.OperationContext));
|
||||
}
|
||||
}
|
||||
|
||||
class CallState : IDisposable
|
||||
{
|
||||
OperationContextScope nullContextScope;
|
||||
WindowsImpersonationContext impersonation;
|
||||
|
||||
public CallState (MessageRpc messageRpc)
|
||||
{
|
||||
this.nullContextScope = new OperationContextScope((OperationContext)null);
|
||||
|
||||
if (messageRpc.windowsIdentity != null)
|
||||
{
|
||||
this.impersonation = messageRpc.windowsIdentity.Impersonate();
|
||||
}
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
if (this.impersonation != null)
|
||||
{
|
||||
this.impersonation.Dispose();
|
||||
}
|
||||
this.nullContextScope.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user