internal static void SetContractFilterToIncludeAllOperations(EndpointDispatcher dispatcher, ContractDescription contract)
        {
            if (dispatcher == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dispatcher");
            }
            if (contract == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
            }

            if (contract.SessionMode == SessionMode.Required)
            {
                EndpointFilterProvider provider = new EndpointFilterProvider();
                foreach (OperationDescription operation in contract.Operations)
                {
                    if (!operation.IsServerInitiated())
                    {
                        provider.InitiatingActions.Add(operation.Messages[0].Action);
                    }
                }
                int priority;
                dispatcher.ContractFilter = provider.CreateFilter(out priority);
                dispatcher.FilterPriority = priority;
            }
        }
Example #2
0
        internal static EndpointDispatcher BuildEndpointDispatcher(ServiceDescription serviceDescription,
                                                                   ServiceEndpoint endpoint)
        {
            if (serviceDescription == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(serviceDescription));
            }

            var contractDescription = endpoint.Contract;

            if (contractDescription == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(endpoint.Contract));
            }

            EndpointFilterProvider provider = new EndpointFilterProvider();

            EndpointAddress    address    = endpoint.Address;
            EndpointDispatcher dispatcher = new EndpointDispatcher(address, contractDescription.Name, contractDescription.Namespace, endpoint.Id, endpoint.InternalIsSystemEndpoint(serviceDescription));

            DispatchRuntime dispatch = dispatcher.DispatchRuntime;

            if (contractDescription.CallbackContractType != null)
            {
                dispatch.CallbackClientRuntime.CallbackClientType = contractDescription.CallbackContractType;
                dispatch.CallbackClientRuntime.ContractClientType = contractDescription.ContractType;
            }

            for (int i = 0; i < contractDescription.Operations.Count; i++)
            {
                OperationDescription operation = contractDescription.Operations[i];

                if (!operation.IsServerInitiated())
                {
                    BuildDispatchOperation(operation, dispatch, provider);
                }
                else
                {
                    BuildProxyOperation(operation, dispatch.CallbackClientRuntime);
                }
            }

            BindOperations(contractDescription, null, dispatch);

            //dispatcher.SetSupportedChannels(DispatcherBuilder.GetSupportedChannelTypes(contractDescription));
            int filterPriority = 0;

            dispatcher.ContractFilter = provider.CreateFilter(out filterPriority);
            dispatcher.FilterPriority = filterPriority;

            return(dispatcher);
        }
Example #3
0
 static bool HaveCommonInitiatingActions(EndpointFilterProvider x, EndpointFilterProvider y, out string commonAction)
 {
     commonAction = null;
     foreach (string action in x.InitiatingActions)
     {
         if (y.InitiatingActions.Contains(action))
         {
             commonAction = action;
             return(true);
         }
     }
     return(false);
 }
Example #4
0
 public EndpointInfo(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher, EndpointFilterProvider provider)
 {
     this.endpoint           = endpoint;
     this.endpointDispatcher = endpointDispatcher;
     this.provider           = provider;
 }
Example #5
0
        static void BuildDispatchOperation(OperationDescription operation, DispatchRuntime parent, EndpointFilterProvider provider)
        {
            string            requestAction = operation.Messages[0].Action;
            DispatchOperation child         = null;

            if (operation.IsOneWay)
            {
                child = new DispatchOperation(parent, operation.Name, requestAction);
            }
            else
            {
                string replyAction = operation.Messages[1].Action;
                child = new DispatchOperation(parent, operation.Name, requestAction, replyAction);
            }

            child.HasNoDisposableParameters = operation.HasNoDisposableParameters;

            child.IsTerminating = operation.IsTerminating;
            child.IsSessionOpenNotificationEnabled = operation.IsSessionOpenNotificationEnabled;
            for (int i = 0; i < operation.Faults.Count; i++)
            {
                FaultDescription fault = operation.Faults[i];
                child.FaultContractInfos.Add(new FaultContractInfo(fault.Action, fault.DetailType, fault.ElementName, fault.Namespace, operation.KnownTypes));
            }

            if (provider != null)
            {
                if (operation.IsInitiating)
                {
                    provider.InitiatingActions.Add(requestAction);
                }
            }

            if (requestAction != MessageHeaders.WildcardAction)
            {
                parent.Operations.Add(child);
            }
            else
            {
                if (parent.HasMatchAllOperation)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.SFxMultipleContractStarOperations0));
                }

                parent.UnhandledDispatchOperation = child;
            }
        }
Example #6
0
        internal static void InitializeServiceHost(ServiceHostBase serviceHost)
        {
            var description = serviceHost.Description;

            if (serviceHost.ImplementedContracts != null && serviceHost.ImplementedContracts.Count > 0)
            {
                EnsureThereAreApplicationEndpoints(description);
            }

            ValidateDescription(serviceHost);

            var stuffPerListenUriInfo           = new Dictionary <ListenUriInfo, StuffPerListenUriInfo>();
            var endpointInfosPerEndpointAddress = new Dictionary <EndpointAddress, Collection <EndpointInfo> >();

            // Ensure ListenUri and group endpoints per ListenUri
            for (int i = 0; i < description.Endpoints.Count; i++)
            {
                ServiceEndpoint endpoint = description.Endpoints[i];

                ListenUriInfo listenUriInfo = GetListenUriInfoForEndpoint(serviceHost, endpoint);
                if (!stuffPerListenUriInfo.ContainsKey(listenUriInfo))
                {
                    stuffPerListenUriInfo.Add(listenUriInfo, new StuffPerListenUriInfo());
                }
                stuffPerListenUriInfo[listenUriInfo].Endpoints.Add(endpoint);
            }

            foreach (KeyValuePair <ListenUriInfo, StuffPerListenUriInfo> stuff in stuffPerListenUriInfo)
            {
                Uri           listenUri               = stuff.Key.ListenUri;
                ListenUriMode listenUriMode           = stuff.Key.ListenUriMode;
                BindingParameterCollection parameters = stuff.Value.Parameters;
                Binding          binding              = stuff.Value.Endpoints[0].Binding;
                EndpointIdentity identity             = stuff.Value.Endpoints[0].Address.Identity;
                // same EndpointAddressTable instance must be shared between channelDispatcher and parameters
                //ThreadSafeMessageFilterTable<EndpointAddress> endpointAddressTable = new ThreadSafeMessageFilterTable<EndpointAddress>();
                //parameters.Add(endpointAddressTable);

                // add service-level binding parameters
                foreach (IServiceBehavior behavior in description.Behaviors)
                {
                    behavior.AddBindingParameters(description, serviceHost, stuff.Value.Endpoints, parameters);
                }
                for (int i = 0; i < stuff.Value.Endpoints.Count; i++)
                {
                    ServiceEndpoint endpoint  = stuff.Value.Endpoints[i];
                    string          viaString = listenUri.AbsoluteUri;

                    // ensure all endpoints with this ListenUriInfo have same binding
                    if (endpoint.Binding != binding)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ABindingInstanceHasAlreadyBeenAssociatedTo1, viaString)));
                    }

                    // ensure all endpoints with this ListenUriInfo have same identity
                    if (!object.Equals(endpoint.Address.Identity, identity))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                                                                      SR.Format(SR.SFxWhenMultipleEndpointsShareAListenUriTheyMustHaveSameIdentity, viaString)));
                    }

                    // add binding parameters (endpoint scope and below)
                    AddBindingParametersForSecurityContractInformation(endpoint, parameters);
                    AddBindingParameters(endpoint, parameters);
                }

                List <Type> channelTypes = GetSupportedChannelTypes(stuff.Value);

                var bindingQname      = new XmlQualifiedName(binding.Name, binding.Namespace);
                var channelDispatcher = new ChannelDispatcher(listenUri, binding, bindingQname.ToString(), binding, channelTypes);
                //channelDispatcher.SetEndpointAddressTable(endpointAddressTable);
                stuff.Value.ChannelDispatcher = channelDispatcher;

                for (int i = 0; i < stuff.Value.Endpoints.Count; i++)
                {
                    ServiceEndpoint endpoint  = stuff.Value.Endpoints[i];
                    string          viaString = listenUri.AbsoluteUri;

                    //EndpointFilterProvider provider = new EndpointFilterProvider();
                    EndpointDispatcher dispatcher = BuildEndpointDispatcher(description, endpoint);

                    if (!endpointInfosPerEndpointAddress.ContainsKey(endpoint.Address))
                    {
                        endpointInfosPerEndpointAddress.Add(endpoint.Address, new Collection <EndpointInfo>());
                    }

                    endpointInfosPerEndpointAddress[endpoint.Address].Add(new EndpointInfo(endpoint, dispatcher, /*provider*/ null));
                    channelDispatcher.Endpoints.Add(dispatcher);
                } // end foreach "endpoint"

                serviceHost.ChannelDispatchers.Add(channelDispatcher);
            } // end foreach "ListenUri/ChannelDispatcher" group

            // run service behaviors
            for (int i = 0; i < description.Behaviors.Count; i++)
            {
                IServiceBehavior serviceBehavior = description.Behaviors[i];
                serviceBehavior.ApplyDispatchBehavior(description, serviceHost);
            }

            foreach (KeyValuePair <ListenUriInfo, StuffPerListenUriInfo> stuff in stuffPerListenUriInfo)
            {
                for (int i = 0; i < stuff.Value.Endpoints.Count; i++)
                {
                    ServiceEndpoint endpoint = stuff.Value.Endpoints[i];
                    // rediscover which dispatcher goes with this endpoint
                    Collection <EndpointInfo> infos = endpointInfosPerEndpointAddress[endpoint.Address];
                    EndpointInfo info = null;
                    foreach (EndpointInfo ei in infos)
                    {
                        if (ei.Endpoint == endpoint)
                        {
                            info = ei;
                            break;
                        }
                    }
                    EndpointDispatcher dispatcher = info.EndpointDispatcher;
                    // run contract behaviors
                    for (int k = 0; k < endpoint.Contract.Behaviors.Count; k++)
                    {
                        IContractBehavior behavior = endpoint.Contract.Behaviors[k];
                        behavior.ApplyDispatchBehavior(endpoint.Contract, endpoint, dispatcher.DispatchRuntime);
                    }
                    // run endpoint behaviors
                    ApplyBindingInformationFromEndpointToDispatcher(endpoint, dispatcher);
                    for (int j = 0; j < endpoint.Behaviors.Count; j++)
                    {
                        IEndpointBehavior eb = endpoint.Behaviors[j];
                        eb.ApplyDispatchBehavior(endpoint, dispatcher);
                    }
                    // run operation behaviors
                    BindOperations(endpoint.Contract, null, dispatcher.DispatchRuntime);
                }
            }

            EnsureRequiredRuntimeProperties(endpointInfosPerEndpointAddress);

            // Warn about obvious demux conflicts
            foreach (Collection <EndpointInfo> endpointInfos in endpointInfosPerEndpointAddress.Values)
            {
                // all elements of endpointInfos share the same Address (and thus EndpointListener.AddressFilter)
                if (endpointInfos.Count > 1)
                {
                    for (int i = 0; i < endpointInfos.Count; i++)
                    {
                        for (int j = i + 1; j < endpointInfos.Count; j++)
                        {
                            // if not same ListenUri, won't conflict
                            // if not same ChannelType, may not conflict (some transports demux based on this)
                            // if they share a ChannelDispatcher, this means same ListenUri and same ChannelType
                            if (endpointInfos[i].EndpointDispatcher.ChannelDispatcher ==
                                endpointInfos[j].EndpointDispatcher.ChannelDispatcher)
                            {
                                EndpointFilterProvider iProvider = endpointInfos[i].FilterProvider;
                                EndpointFilterProvider jProvider = endpointInfos[j].FilterProvider;
                                // if not default EndpointFilterProvider, we won't try to throw, you're on your own
                                string commonAction;
                                if (iProvider != null && jProvider != null &&
                                    HaveCommonInitiatingActions(iProvider, jProvider, out commonAction))
                                {
                                    // you will definitely get a MultipleFiltersMatchedException at runtime,
                                    // so let's go ahead and throw now
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                              new InvalidOperationException(
                                                  SR.Format(SR.SFxDuplicateInitiatingActionAtSameVia, endpointInfos[i].Endpoint.ListenUri, commonAction)));
                                }
                            }
                        }
                    }
                }
            }
        }