internal void Add(string action, DispatchOperationRuntime operation) { if (map.Contains(action)) { DispatchOperationRuntime existingOperation = (DispatchOperationRuntime)map[action]; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxActionDemuxerDuplicate, existingOperation.Name, operation.Name, action))); } map.Add(action, operation); }
internal ImmutableDispatchRuntime(DispatchRuntime dispatch) { _authenticationBehavior = AuthenticationBehavior.TryCreate(dispatch); _authorizationBehavior = AuthorizationBehavior.TryCreate(dispatch); _concurrency = new ConcurrencyBehavior(dispatch); _error = new ErrorBehavior(dispatch.ChannelDispatcher); _enableFaults = dispatch.EnableFaults; _inputSessionShutdownHandlers = EmptyArray <IInputSessionShutdown> .ToArray(dispatch.InputSessionShutdownHandlers); InstanceBehavior = new InstanceBehavior(dispatch, this); _isOnServer = dispatch.IsOnServer; _manualAddressing = dispatch.ManualAddressing; _messageInspectors = EmptyArray <IDispatchMessageInspector> .ToArray(dispatch.MessageInspectors); _securityImpersonation = SecurityImpersonationBehavior.CreateIfNecessary(dispatch); RequireClaimsPrincipalOnOperationContext = dispatch.RequireClaimsPrincipalOnOperationContext; _impersonateOnSerializingReply = dispatch.ImpersonateOnSerializingReply; _terminate = TerminatingOperationBehavior.CreateIfNecessary(dispatch); _thread = new ThreadBehavior(dispatch); ValidateMustUnderstand = dispatch.ValidateMustUnderstand; ParameterInspectorCorrelationOffset = (dispatch.MessageInspectors.Count + dispatch.MaxCallContextInitializers); _correlationCount = ParameterInspectorCorrelationOffset + dispatch.MaxParameterInspectors; DispatchOperationRuntime unhandled = new DispatchOperationRuntime(dispatch.UnhandledDispatchOperation, this); if (dispatch.OperationSelector == null) { ActionDemuxer demuxer = new ActionDemuxer(); for (int i = 0; i < dispatch.Operations.Count; i++) { DispatchOperation operation = dispatch.Operations[i]; DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this); demuxer.Add(operation.Action, operationRuntime); } demuxer.SetUnhandled(unhandled); _demuxer = demuxer; } else { CustomDemuxer demuxer = new CustomDemuxer(dispatch.OperationSelector); for (int i = 0; i < dispatch.Operations.Count; i++) { DispatchOperation operation = dispatch.Operations[i]; DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this); demuxer.Add(operation.Name, operationRuntime); } demuxer.SetUnhandled(unhandled); _demuxer = demuxer; } _processMessageNonCleanupError = new MessageRpcErrorHandler(ProcessMessageNonCleanupError); _processMessageCleanupError = new MessageRpcErrorHandler(ProcessMessageCleanupError); }
public DispatchOperationRuntime GetOperation(ref Message request) { string operationName = _selector.SelectOperation(ref request); DispatchOperationRuntime operation = null; if (_map.TryGetValue(operationName, out operation)) { return(operation); } else { return(_unhandled); } }
public DispatchOperationRuntime GetOperation(ref Message request) { string action = request.Headers.Action; if (action == null) { action = MessageHeaders.WildcardAction; } DispatchOperationRuntime operation = (DispatchOperationRuntime)map[action]; if (operation != null) { return(operation); } return(unhandled); }
private async Task DispatchAndReleasePumpAsync(RequestContext request, bool cleanThread, RequestInfo requestInfo) { OperationContext currentOperationContext = null; ServiceChannel channel = requestInfo.Channel; EndpointDispatcher endpoint = requestInfo.Endpoint; bool releasedPump = false; try { DispatchRuntime dispatchBehavior = requestInfo.DispatchRuntime; if (channel == null || dispatchBehavior == null) { Fx.Assert("System.ServiceModel.Dispatcher.ChannelHandler.Dispatch(): (channel == null || dispatchBehavior == null)"); return; } Message message; //EventTraceActivity eventTraceActivity = TraceDispatchMessageStart(request.RequestMessage); message = request.RequestMessage; DispatchOperationRuntime operation = dispatchBehavior.GetOperation(ref message); if (operation == null) { Fx.Assert("ChannelHandler.Dispatch (operation == null)"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "No DispatchOperationRuntime found to process message."))); } if (_shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open"))); } //if (MessageLogger.LoggingEnabled) //{ // MessageLogger.LogMessage(ref message, (operation.IsOneWay ? MessageLoggingSource.ServiceLevelReceiveDatagram : MessageLoggingSource.ServiceLevelReceiveRequest) | MessageLoggingSource.LastChance); //} if (operation.IsTerminating && _hasSession) { _isChannelTerminated = true; } bool hasOperationContextBeenSet; if (currentOperationContext != null) { hasOperationContextBeenSet = true; currentOperationContext.ReInit(request, message, channel); } else { hasOperationContextBeenSet = false; currentOperationContext = new OperationContext(request, message, channel, _host); } if (currentOperationContext.EndpointDispatcher == null && _serviceDispatcher != null) { currentOperationContext.EndpointDispatcher = endpoint; } var rpc = new MessageRpc(request, message, operation, channel, _host, this, cleanThread, currentOperationContext, requestInfo.ExistingInstanceContext); //TraceUtility.MessageFlowAtMessageReceived(message, currentOperationContext, eventTraceActivity, true); // passing responsibility for call throttle to MessageRpc // (MessageRpc implicitly owns this throttle once it's created) requestInfo.ChannelHandlerOwnsCallThrottle = false; // explicitly passing responsibility for instance throttle to MessageRpc rpc.MessageRpcOwnsInstanceContextThrottle = requestInfo.ChannelHandlerOwnsInstanceContextThrottle; requestInfo.ChannelHandlerOwnsInstanceContextThrottle = false; // These need to happen before Dispatch but after accessing any ChannelHandler // state, because we go multi-threaded after this ReleasePump(); releasedPump = true; await operation.Parent.DispatchAsync(rpc, hasOperationContextBeenSet); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } await HandleErrorAsync(e, request, requestInfo, channel); } finally { if (!releasedPump) { ReleasePump(); } } }
//bool didTraceProcessMessage1 = false; //bool didTraceProcessMessage2 = false; //bool didTraceProcessMessage3 = false; //bool didTraceProcessMessage31 = false; //bool didTraceProcessMessage4 = false; //bool didTraceProcessMessage41 = false; internal ImmutableDispatchRuntime(DispatchRuntime dispatch) { //this.authenticationBehavior = AuthenticationBehavior.TryCreate(dispatch); //this.authorizationBehavior = AuthorizationBehavior.TryCreate(dispatch); concurrency = new ConcurrencyBehavior(dispatch); error = new ErrorBehavior(dispatch.ChannelDispatcher); enableFaults = dispatch.EnableFaults; inputSessionShutdownHandlers = EmptyArray <IInputSessionShutdown> .ToArray(dispatch.InputSessionShutdownHandlers); instance = new InstanceBehavior(dispatch, this); isOnServer = dispatch.IsOnServer; manualAddressing = dispatch.ManualAddressing; messageInspectors = EmptyArray <IDispatchMessageInspector> .ToArray(dispatch.MessageInspectors); //this.requestReplyCorrelator = new RequestReplyCorrelator(); //this.securityImpersonation = SecurityImpersonationBehavior.CreateIfNecessary(dispatch); //this.RequireClaimsPrincipalOnOperationContext = dispatch.RequireClaimsPrincipalOnOperationContext; //this.impersonateOnSerializingReply = dispatch.ImpersonateOnSerializingReply; terminate = TerminatingOperationBehavior.CreateIfNecessary(dispatch); thread = new ThreadBehavior(dispatch); ValidateMustUnderstand = dispatch.ValidateMustUnderstand; //this.ignoreTransactionFlow = dispatch.IgnoreTransactionMessageProperty; //this.transaction = TransactionBehavior.CreateIfNeeded(dispatch); //sendAsynchronously = dispatch.ChannelDispatcher.SendAsynchronously; ParameterInspectorCorrelationOffset = (dispatch.MessageInspectors.Count + dispatch.MaxCallContextInitializers); correlationCount = ParameterInspectorCorrelationOffset + dispatch.MaxParameterInspectors; DispatchOperationRuntime unhandled = new DispatchOperationRuntime(dispatch.UnhandledDispatchOperation, this); if (dispatch.OperationSelector == null) { ActionDemuxer demuxer = new ActionDemuxer(); for (int i = 0; i < dispatch.Operations.Count; i++) { DispatchOperation operation = dispatch.Operations[i]; DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this); demuxer.Add(operation.Action, operationRuntime); } demuxer.SetUnhandled(unhandled); this.demuxer = demuxer; } else { throw new PlatformNotSupportedException(); // CustomDemuxer demuxer = new CustomDemuxer(dispatch.OperationSelector); // for (int i = 0; i < dispatch.Operations.Count; i++) // { // DispatchOperation operation = dispatch.Operations[i]; // DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this); // demuxer.Add(operation.Name, operationRuntime); // } // demuxer.SetUnhandled(unhandled); // this.demuxer = demuxer; } //processMessage1 = new MessageRpcProcessor(ProcessMessage1); //processMessage11 = new MessageRpcProcessor(ProcessMessage11); //processMessage2 = new MessageRpcProcessor(ProcessMessage2); //processMessage3 = new MessageRpcProcessor(ProcessMessage3); //processMessage31 = new MessageRpcProcessor(ProcessMessage31); //processMessage4 = new MessageRpcProcessor(ProcessMessage4); //processMessage41 = new MessageRpcProcessor(ProcessMessage41); //processMessage5 = new MessageRpcProcessor(ProcessMessage5); //processMessage6 = new MessageRpcProcessor(ProcessMessage6); //processMessage7 = new MessageRpcProcessor(ProcessMessage7); //processMessage8 = new MessageRpcProcessor(ProcessMessage8); //processMessage9 = new MessageRpcProcessor(ProcessMessage9); //processMessageCleanup = new MessageRpcProcessor(ProcessMessageCleanup); processMessageNonCleanupError = new MessageRpcErrorHandler(ProcessMessageNonCleanupError); processMessageCleanupError = new MessageRpcErrorHandler(ProcessMessageCleanupError); }
internal void SetUnhandled(DispatchOperationRuntime operation) { unhandled = operation; }
private Task DispatchAsyncCore(RequestContext request, IChannel channel, EndpointDispatcher endpointDispatcher, CancellationToken token) { var dispatchRuntime = endpointDispatcher.DispatchRuntime; //EndpointDispatcher endpoint = dispatchRuntime.EndpointDispatcher; //bool releasedPump = false; ServiceChannel serviceChannel = null; var sessionIdleManager = channel.GetProperty <ServiceChannel.SessionIdleManager>(); IChannelBinder binder = null; if (channel is IReplyChannel) { var rcbinder = channel.GetProperty <ReplyChannelBinder>(); rcbinder.Init(channel as IReplyChannel, BaseAddress); binder = rcbinder; } else if (channel is IDuplexSessionChannel) { var dcbinder = channel.GetProperty <DuplexChannelBinder>(); dcbinder.Init(channel as IDuplexSessionChannel, _requestReplyCorrelator, BaseAddress); binder = dcbinder; } serviceChannel = new ServiceChannel( binder, endpointDispatcher, Binding, sessionIdleManager.UseIfNeeded(binder, Binding.ReceiveTimeout)); Message message = request.RequestMessage; DispatchOperationRuntime operation = dispatchRuntime.GetOperation(ref message); if (operation == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "No DispatchOperationRuntime found to process message."))); } // TODO: Wire in session open notification //if (shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction) //{ // throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open"))); //} // TODO: Session lifetime //if (operation.IsTerminating && requestInfo.HasSession) //{ // isChannelTerminated = true; //} // TODO: Fix up whatever semantics OperationContext places on a host being passed var currentOperationContext = new OperationContext(request, message, serviceChannel, /*host*/ null); currentOperationContext.EndpointDispatcher = endpointDispatcher; var existingInstanceContext = dispatchRuntime.InstanceContextProvider.GetExistingInstanceContext(request.RequestMessage, serviceChannel.Proxy as IContextChannel); // TODO: Investigate consequences of cleanThread parameter MessageRpc rpc = new MessageRpc(request, message, operation, serviceChannel, /*host*/ null, /*cleanThread*/ true, currentOperationContext, existingInstanceContext /*, eventTraceActivity*/); return(operation.Parent.DispatchAsync(ref rpc, /*hasOperationContextBeenSet*/ false)); // TODO : Fix error handling //catch (Exception e) //{ // if (Fx.IsFatal(e)) // { // throw; // } // return HandleError(e, request, channel); //} }
// Similar to DispatchAndReleasePump on Desktop internal async Task DispatchAsyncCore(RequestContext request, RequestInfo requestInfo, bool cleanThread, OperationContext currentOperationContext) { ServiceChannel channel = requestInfo.Channel; EndpointDispatcher endpoint = requestInfo.Endpoint; try { DispatchRuntime dispatchBehavior = requestInfo.DispatchRuntime; if (channel == null || dispatchBehavior == null) { Fx.Assert("System.ServiceModel.Dispatcher.ChannelHandler.Dispatch(): (channel == null || dispatchBehavior == null)"); } Message message = request.RequestMessage; DispatchOperationRuntime operation = dispatchBehavior.GetOperation(ref message); if (operation == null) { Fx.Assert("ChannelHandler.Dispatch (operation == null)"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException("No DispatchOperationRuntime found to process message.")); } if (_shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open"))); } if (operation.IsTerminating && _hasSession) { _isChannelTerminated = true; } bool hasOperationContextBeenSet; if (currentOperationContext != null) { hasOperationContextBeenSet = true; currentOperationContext.ReInit(request, message, channel); } else { hasOperationContextBeenSet = false; currentOperationContext = new OperationContext(request, message, channel, null); } if (currentOperationContext.EndpointDispatcher == null && _serviceDispatcher != null) { currentOperationContext.EndpointDispatcher = endpoint; } MessageRpc rpc = new MessageRpc(request, message, operation, channel, _host, this, cleanThread, currentOperationContext, requestInfo.ExistingInstanceContext); // passing responsibility for call throttle to MessageRpc // (MessageRpc implicitly owns this throttle once it's created) requestInfo.ChannelHandlerOwnsCallThrottle = false; // explicitly passing responsibility for instance throttle to MessageRpc rpc.MessageRpcOwnsInstanceContextThrottle = requestInfo.ChannelHandlerOwnsInstanceContextThrottle; requestInfo.ChannelHandlerOwnsInstanceContextThrottle = false; // These need to happen before Dispatch but after accessing any ChannelHandler // state, because we go multi-threaded after this until we reacquire pump mutex. await operation.Parent.DispatchAsync(rpc, hasOperationContextBeenSet); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } await HandleErrorAsync(e, request, requestInfo, channel); } }
internal MessageRpc(RequestContext requestContext, Message request, DispatchOperationRuntime operation, ServiceChannel channel, ServiceHostBase host, ChannelHandler channelHandler, bool cleanThread, OperationContext operationContext, InstanceContext instanceContext /*, EventTraceActivity eventTraceActivity*/) { Fx.Assert((operationContext != null), "correwcf.Dispatcher.MessageRpc.MessageRpc(), operationContext == null"); // TODO: ChannelHandler supplied an ErrorHandler, need to supply this some other way. //Fx.Assert(channelHandler != null, "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), channelHandler == null"); //this.Activity = null; //this.EventTraceActivity = eventTraceActivity; AsyncResult = null; TaskResult = null; CanSendReply = true; Channel = channel; this.channelHandler = channelHandler; Correlation = EmptyArray.Allocate(operation.Parent.CorrelationCount); DidDeserializeRequestBody = false; Error = null; ErrorProcessor = null; FaultInfo = new ErrorHandlerFaultInfo(request.Version.Addressing.DefaultFaultAction); HasSecurityContext = false; Host = host; Instance = null; AsyncProcessor = null; NotUnderstoodHeaders = null; Operation = operation; OperationContext = operationContext; paused = false; ParametersDisposed = false; Request = request; RequestContext = requestContext; RequestContextThrewOnReply = false; SuccessfullySendReply = false; RequestVersion = request.Version; Reply = null; ReplyTimeoutHelper = new TimeoutHelper(); SecurityContext = null; InstanceContext = instanceContext; SuccessfullyBoundInstance = false; SuccessfullyIncrementedActivity = false; SuccessfullyLockedInstance = false; switchedThreads = !cleanThread; //this.transaction = null; InputParameters = null; OutputParameters = null; ReturnParameter = null; isInstanceContextSingleton = InstanceContextProviderBase.IsProviderSingleton(Channel.DispatchRuntime.InstanceContextProvider); invokeContinueGate = null; if (!operation.IsOneWay && !operation.Parent.ManualAddressing) { RequestID = request.Headers.MessageId; ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(request); } else { RequestID = null; ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(); } //if (DiagnosticUtility.ShouldUseActivity) //{ // this.Activity = TraceUtility.ExtractActivity(this.Request); //} //if (DiagnosticUtility.ShouldUseActivity || TraceUtility.ShouldPropagateActivity) //{ // this.ResponseActivityId = ActivityIdHeader.ExtractActivityId(this.Request); //} //else //{ ResponseActivityId = Guid.Empty; //} //if (this.EventTraceActivity == null && FxTrace.Trace.IsEnd2EndActivityTracingEnabled) //{ // if (this.Request != null) // { // this.EventTraceActivity = EventTraceActivityHelper.TryExtractActivity(this.Request, true); // } //} }
internal void Add(string name, DispatchOperationRuntime operation) { _map.Add(name, operation); }