public void Fault(Exception exception)
        {
            FxTrace.Trace.SetAndTraceTransfer(this.ActivityID, true);

            //Notify the error handlers that a problem occurred
            foreach (IErrorHandler errorHandler in this.endpointBehavior.ChannelDispatcher.ErrorHandlers)
            {
                if (errorHandler.HandleError(exception))
                {
                    break;
                }
            }

            SessionChannels channelsToAbort;

            lock (this.thisLock)
            {
                channelsToAbort      = this.sessionChannels;
                this.sessionChannels = null;
            }

            if (channelsToAbort != null)
            {
                channelsToAbort.AbortAll();
            }

            RoutingUtilities.Abort(this.channel, this.channel.LocalAddress);
        }
示例#2
0
        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            RoutingExtension routingExtension = new RoutingExtension(this.configuration);

            serviceHostBase.Extensions.Add(routingExtension);
            for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
            {
                ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
                if (channelDispatcher != null)
                {
                    foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                    {
                        if (!endpointDispatcher.IsSystemEndpoint &&
                            RoutingUtilities.IsRoutingServiceNamespace(endpointDispatcher.ContractNamespace))
                        {
                            DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
                            //Since we use PerSession instancing this concurrency only applies to messages
                            //in the same session, also needed to maintain order.
                            dispatchRuntime.ConcurrencyMode       = ConcurrencyMode.Single;
                            dispatchRuntime.EnsureOrderedDispatch = this.configuration.EnsureOrderedDispatch;
                        }
                    }
                }
            }
        }
示例#3
0
            void IInputSessionShutdown.ChannelFaulted(IDuplexContextChannel channel)
            {
                RoutingChannelExtension channelExtension = channel.Extensions.Find <RoutingChannelExtension>();

                if (channelExtension != null)
                {
                    channelExtension.Fault(new CommunicationObjectFaultedException());
                }
                else
                {
                    RoutingUtilities.Abort(channel, channel.LocalAddress);
                }
            }
示例#4
0
        internal void ResetSession()
        {
            //Are we in a transactional error handling case (i.e. ReceiveContext)?
            if (this.RetryTransaction != null)
            {
                if (this.ChannelExtension.HasSession)
                {
                    this.ChannelExtension.SessionChannels.AbortAll();
                }

                RoutingUtilities.SafeRollbackTransaction(this.RetryTransaction);
                this.RetryTransaction = null;
            }
        }
示例#5
0
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            {
                this.ChannelDispatcher = endpointDispatcher.ChannelDispatcher;
                this.ChannelDispatcher.ChannelInitializers.Add(this);
                endpointDispatcher.DispatchRuntime.InputSessionShutdownHandlers.Add(this);
                endpointDispatcher.DispatchRuntime.AutomaticInputSessionShutdown = false;

                if (endpointDispatcher.DispatchRuntime.ImpersonateCallerForAllOperations)
                {
                    this.ImpersonationRequired = true;
                }
                else if (AspNetEnvironment.Current.AspNetCompatibilityEnabled)
                {
                    this.ImpersonationRequired = true;
                }

                BindingParameterCollection bindingParams = new BindingParameterCollection();

                if (RoutingUtilities.IsTransactedReceive(endpoint.Binding, bindingParams))
                {
                    foreach (OperationDescription operation in endpoint.Contract.Operations)
                    {
                        if (operation.Behaviors.Find <TransactedReceiveOperationBehavior>() == null)
                        {
                            operation.Behaviors.Add(new TransactedReceiveOperationBehavior());
                        }
                    }
                    this.ChannelDispatcher.IsTransactedReceive = true;
                    endpointDispatcher.DispatchRuntime.TransactionAutoCompleteOnSessionClose = true;
                    this.TransactedReceiveEnabled = true;
                }

                IReceiveContextSettings rcSettings = endpoint.Binding.GetProperty <IReceiveContextSettings>(bindingParams);

                if (rcSettings != null && rcSettings.Enabled)
                {
                    foreach (OperationDescription operation in endpoint.Contract.Operations)
                    {
                        ReceiveContextEnabledAttribute rcEnabled = new ReceiveContextEnabledAttribute();
                        rcEnabled.ManualControl = true;
                        operation.Behaviors.Add(rcEnabled);
                    }
                    this.ReceiveContextEnabled = true;

                    //Switch TransactedReceive off, because we don't want the Dispatcher creating any Transaction
                    endpointDispatcher.ChannelDispatcher.IsTransactedReceive = false;
                    endpointDispatcher.DispatchRuntime.TransactionAutoCompleteOnSessionClose = false;
                }
            }
示例#6
0
        void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            HashSet <string> endpoints = new HashSet <string>();

            foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
            {
                if (!endpoint.IsSystemEndpoint &&
                    RoutingUtilities.IsRoutingServiceNamespace(endpoint.Contract.Namespace))
                {
                    endpoint.Behaviors.Add(new RoutingEndpointBehavior(endpoint));
                    endpoints.Add(endpoint.Name);
                }
            }
            EndpointNameMessageFilter.Validate(this.configuration.InternalFilterTable.Keys, endpoints);
        }
示例#7
0
        public void AbortChannel(RoutingEndpointTrait key)
        {
            IRoutingClient client;

            lock (this.sessions)
            {
                if (this.sessions.TryGetValue(key, out client))
                {
                    this.sessions.Remove(key);
                    this.sessionList.Remove(client);
                }
            }

            if (client != null)
            {
                RoutingUtilities.Abort((ICommunicationObject)client, client.Key);
            }
        }
示例#8
0
        public void AbortAll()
        {
            List <IRoutingClient> clients = new List <IRoutingClient>();

            lock (this.sessions)
            {
                foreach (IRoutingClient client in this.sessions.Values)
                {
                    clients.Add(client);
                }
                this.sessions.Clear();
                this.sessionList.Clear();
            }

            foreach (IRoutingClient client in clients)
            {
                RoutingUtilities.Abort((ICommunicationObject)client, client.Key);
            }
        }
            void PreProcess(Message message)
            {
                //If the user does not have manual addressing enabled then clear these out
                if (!this.manualAddressing)
                {
                    MessageHeaders headers             = message.Headers;
                    string         addressingNamespace = RoutingUtilities.GetAddressingNamespace(headers.MessageVersion.Addressing);

                    //Go through in reverse to reduce shifting after RemoveAt(i)
                    for (int i = headers.Count - 1; i >= 0; --i)
                    {
                        MessageHeaderInfo header = headers[i];
                        if (string.Equals(header.Namespace, addressingNamespace, StringComparison.Ordinal))
                        {
                            if (!addressingHeadersToFlow.Contains(header.Name))
                            {
                                headers.RemoveAt(i);
                            }
                        }
                    }
                }
            }
            void FilterHeaders(MessageHeaders headers, HashSet <string> understoodHeadersSet)
            {
                string addressingNamespace = RoutingUtilities.GetAddressingNamespace(headers.MessageVersion.Addressing);

                //Go in reverse to reduce shifting after RemoveAt(i)
                for (int i = headers.Count - 1; i >= 0; --i)
                {
                    MessageHeaderInfo header = headers[i];
                    bool removeHeader        = false;

                    if (string.Equals(header.Namespace, addressingNamespace, StringComparison.Ordinal) &&
                        (addressingHeadersToFlow.Contains(header.Name) || this.manualAddressing))
                    {
                        continue;
                    }

                    if (understoodHeadersSet.Contains(MessageHeaderKey(header)))
                    {
                        // This header was understood at this endpoint, do _not_ flow it
                        removeHeader = true;
                    }
                    else if (ActorIsNextDestination(header, headers.MessageVersion))
                    {
                        //This was a header targeted at the SOAP Intermediary ("actor/next", which is us)
                        //It can explicitly tell us to relay this header when we don't understand it.
                        if (!header.Relay)
                        {
                            removeHeader = true;
                        }
                    }

                    if (removeHeader)
                    {
                        headers.RemoveAt(i);
                    }
                }
            }
            internal Message MarshalMessage(Message source, Uri to, MessageVersion targetVersion)
            {
                Message           result;
                MessageHeaders    sourceHeaders        = source.Headers;
                MessageVersion    sourceVersion        = source.Version;
                UnderstoodHeaders understoodHeaders    = sourceHeaders.UnderstoodHeaders;
                HashSet <string>  understoodHeadersSet = CreateKeys(understoodHeaders);

#if DEBUG_MARSHALING
                System.Text.StringBuilder details = new System.Text.StringBuilder();
                details.AppendFormat("Original Message:\r\n{0}\r\n", source);
                details.AppendLine("Understood Headers:");
                foreach (MessageHeaderInfo understoodHeader in understoodHeaders)
                {
                    details.AppendFormat("\t{0}\t({1})\r\n", understoodHeader.Name, understoodHeader.Namespace);
                }
                details.AppendLine("Properties:");
                foreach (KeyValuePair <string, object> item in source.Properties)
                {
                    details.AppendFormat("\t{0}\t({1})\r\n", item.Key, item.Value);
                }
#endif //DEBUG_MARSHALING


                //if we've understood and verified the security of the message, we need to create a new message
                if (sourceVersion == targetVersion && !RoutingUtilities.IsMessageUsingWSSecurity(understoodHeaders))
                {
                    FilterHeaders(sourceHeaders, understoodHeadersSet);
                    FilterProperties(source.Properties);
                    result = source;
                }
                else
                {
                    if (source.IsFault)
                    {
                        MessageFault messageFault = MessageFault.CreateFault(source, int.MaxValue);
                        string       action       = sourceHeaders.Action;
                        if (string.Equals(action, sourceVersion.Addressing.DefaultFaultAction, StringComparison.Ordinal))
                        {
                            //The action was the default for the sourceVersion set it to the default for the targetVersion.
                            action = targetVersion.Addressing.DefaultFaultAction;
                        }
                        result = Message.CreateMessage(targetVersion, messageFault, action);
                    }
                    else if (source.IsEmpty)
                    {
                        result = Message.CreateMessage(targetVersion, sourceHeaders.Action);
                    }
                    else
                    {
                        XmlDictionaryReader bodyReader = source.GetReaderAtBodyContents();
                        result = Message.CreateMessage(targetVersion, sourceHeaders.Action, bodyReader);
                    }

                    CloneHeaders(result.Headers, sourceHeaders, to, understoodHeadersSet);
                    CloneProperties(result.Properties, source.Properties);
                }

#if DEBUG_MARSHALING
                details.AppendFormat("\r\nMarshaled Message:\r\n{0}\r\n", result);
                details.AppendLine("Properties:");
                foreach (KeyValuePair <string, object> item in result.Properties)
                {
                    details.AppendFormat("\t{0}\t({1})\r\n", item.Key, item.Value);
                }
                System.Diagnostics.Trace.WriteLine(details);
                TD.RoutingServiceDisplayConfig(details.ToString(), "");
#endif //DEBUG_MARSHALING

                return(result);
            }