Пример #1
1
        // In this tutorial, the routing service is hosted using a console application to avoid over-complicating the routing
        // proof of concept with complex IIS, hosting, and web.config configurations.  The console hosts can be easily tested
        // without any configuration necessary
        static void Main(string[] args)
        {
            // I am sure that you realize that all of the following could be done in the web.config, but I opted to do it
            // programmitically so that each individual component can be explained along the way
            using (var host = new ServiceHost(typeof(RoutingService)))
            {
                // In this step, we create an BasicHttp binding endpoint that will be used by the hosting interface to
                // expose our routing service.
                // Note the use of the IRequestReplyRouter contract
                ContractDescription contract = ContractDescription.GetContract(typeof(IRequestReplyRouter));
                Binding binding = new BasicHttpBinding();
                var endpointAddress = new EndpointAddress("http://*****:*****@"http://services.bloggedbychris.com/practice/routing/v1/Version/GetVersion");
                var v1Endpoint = new [] {new ServiceEndpoint(contract, new BasicHttpBinding(), new EndpointAddress("http://*****:*****@"http://services.bloggedbychris.com/practice/routing/v2/Version/GetVersion");
                var v2Endpoint = new[] {new ServiceEndpoint(contract, new BasicHttpBinding(), new EndpointAddress("http://localhost:9092/routing/version/"))};
                routingConfiguration.FilterTable.Add(v2Filter, v2Endpoint);

                // Here we add our routing configuration as a service behavior for our routing service
                var routingBehavior = new RoutingBehavior(routingConfiguration);
                host.Description.Behaviors.Add(routingBehavior);

                // Open the ServiceHost to create listeners
                // and start listening for messages.
                host.Open();

                // The service can now be accessed.
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();
            }
        }
Пример #2
0
        private static void ConfigureRouterViaCode(ServiceHost serviceHost)
        {
            //This code sets up the Routing Sample via code.  Rename or delete the App.config file
            //and comment out this method call to run a config-based Routing Service

            //set up some communication defaults
            string deadAddress = "net.tcp://localhost:9090/servicemodelsamples/fakeDestination";
            string realAddress = "net.tcp://localhost:8080/servicemodelsamples/service";
            string routerAddress = "http://localhost/routingservice/router";

            //note that the calculator client will be communicating to the Routing Service via basic
            //HTTP, while the Routing Service is using Net.TCP to communicate to the calculator service.
            //This demonstrates the Routing Service's capability of bridging between different message
            //transports, formats, bindings, etc.  This automatic message conversion is governed by
            //whether or not SoapProcessing (enabled by default) is enabled on the Routing Configuration. 
            Binding routerBinding = new BasicHttpBinding();
            Binding clientBinding = new NetTcpBinding();
            
            //add the endpoint the router will use to recieve messages
            serviceHost.AddServiceEndpoint(typeof(IRequestReplyRouter), routerBinding, routerAddress);
            
            //create the client endpoint the router will route messages to
            //note that the contract description on the client endpoints is actually unused, so
            //this could be any string.  The contract specified here goes unused
            //because the Routing Service replaces this contract with one of the Router
            //contracts at runtime, depending on the contract that a message was received with.
            ContractDescription contract = new ContractDescription("IRequestReplyRouter");
            ServiceEndpoint fakeDestination = new ServiceEndpoint(contract, clientBinding, new EndpointAddress(deadAddress));
            ServiceEndpoint realDestination = new ServiceEndpoint(contract, clientBinding, new EndpointAddress(realAddress));
            
            //create the endpoint list that contains the service endpoints we want to route to
            List<ServiceEndpoint> backupList = new List<ServiceEndpoint>();

            //add the endpoints in the order that the Routing Service should contact them
            //first add the endpoint that we know will be down
            //clearly, normally you wouldn't know that this endpoint was down by default
            backupList.Add(fakeDestination);

            //then add the endpoint that will work
            //the Routing Service will attempt to send to this endpoint only if it 
            //encounters a TimeOutException or CommunicationException when sending
            //to the previous endpoint in the list.
            backupList.Add(realDestination);
            
            //create the default RoutingConfiguration option            
            RoutingConfiguration rc = new RoutingConfiguration();
            
            //add a MatchAll filter to the Routing Configuration's filter table
            //map it to the list of endpoints defined above
            //when a message matches this filter, it will be sent to the endpoints in the list in order
            //if an endpoint is down or doesn't respond (which the first client won't
            //since no service exists at that endpoint), the Routing Service will automatically move the message
            //to the next endpoint in the list and try again.
            rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);
            
            //create the Routing Behavior with the Routing Configuration and add it to the 
            //serviceHost's Description.
            serviceHost.Description.Behaviors.Add(new RoutingBehavior(rc));
                        
        }
        public RoutingBehavior(RoutingConfiguration routingConfiguration)
        {
            if (routingConfiguration == null)
            {
                throw FxTrace.Exception.ArgumentNull("routingConfiguration");
            }

            this.configuration = routingConfiguration;
        }
Пример #4
0
        private static void Main(string[] args)
        {
            const string routerAddress = "http://localhost:8001/router";
            using (var routerHost = new ServiceHost(typeof(RoutingService), new Uri(routerAddress)))
            {
                Binding routerBinding = new BasicHttpBinding();
                routerHost.AddServiceEndpoint(typeof(IRequestReplyRouter), routerBinding, string.Empty);

                Binding greetingBinding = new NetTcpBinding();
                const string greetingBase = "net.tcp://localhost:8000/GreetingService/";

                var contractDescription = ContractDescription.GetContract(typeof(IRequestReplyRouter));
                var helloEndpoint = new ServiceEndpoint(contractDescription, greetingBinding,
                                                        new EndpointAddress(greetingBase + "Hello"));
                var goodbyeEndpoint = new ServiceEndpoint(contractDescription, greetingBinding,
                                                          new EndpointAddress(greetingBase + "Goodbye"));

                var routerConfig = new RoutingConfiguration();
                IEnumerable<ServiceEndpoint> helloEndpoints = new List<ServiceEndpoint>
                                                                  {
                                                                      helloEndpoint,
                                                                  };
                routerConfig.FilterTable.Add(new ActionMessageFilter("Hello"), helloEndpoints);
                IEnumerable<ServiceEndpoint> goodbyeEndpoints = new List<ServiceEndpoint>
                                                                    {
                                                                        goodbyeEndpoint,
                                                                    };
                routerConfig.FilterTable.Add(new ActionMessageFilter("Goodbye"), goodbyeEndpoints);
                routerHost.Description.Behaviors.Add(new RoutingBehavior(routerConfig));

                routerHost.Open();

                Console.WriteLine("Routing service ready.");
                do
                {
                    Console.WriteLine("Press <ESC> to exit.");
                } while (Console.ReadKey(true).Key != ConsoleKey.Escape);
                Console.WriteLine("Exiting...");
                routerHost.Close();
            }
        }
Пример #5
0
        private static void ConfigureRouterViaCode(ServiceHost serviceHost)
        {
            //This code sets up the Routing Sample via code.  Rename or delete the provided
            //App.config and uncomment this method call to run a code-based Routing Service

            //set up some communication defaults
            string clientAddress = "http://localhost:8000/servicemodelsamples/service";
            string routerAddress = "http://localhost:8000/routingservice/router";

            Binding routerBinding = new WSHttpBinding();
            Binding clientBinding = new WSHttpBinding();


            //add the endpoint the router will use to recieve messages
            serviceHost.AddServiceEndpoint(typeof(IRequestReplyRouter), routerBinding, routerAddress);


            //create the client endpoint the router will route messages to
            ContractDescription contract = ContractDescription.GetContract(typeof(IRequestReplyRouter));
            ServiceEndpoint client = new ServiceEndpoint(contract, clientBinding, new EndpointAddress(clientAddress));

            //create a new routing configuration object
            RoutingConfiguration rc = new RoutingConfiguration();

            //create the endpoint list that contains the service endpoints we want to route to
            //in this case we have only one
            List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
            endpointList.Add(client);

            //add a MatchAll filter to the Router's filter table
            //map it to the endpoint list defined earlier
            //when a message matches this filter, it will be sent to the endpoint contained in the list
            rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);

            //attach the behavior to the service host
            serviceHost.Description.Behaviors.Add(new RoutingBehavior(rc));
        }
Пример #6
0
        private static void ConfigureRouterViaCode(ServiceHost serviceHost)
        {
            //This code sets up the Routing Sample via code.  Rename the provided app.config
            //to App.config.example and uncomment this method call to run a config-based Routing Service

            //set up some communication defaults
            //note that some of these are a little artifical for the purpose of demonstrating 
            //different filter types and how to define them

            //the regular calculator service is located at net.tcp://localhost:9090/servicemodelsamples/service/
            string calcDestinationAddress = "net.tcp://localhost:9090/servicemodelsamples/service/";

            //the rounding calc service is located at net.tcp://localhost:8080/servicemodelsamples/service/
            string roundingDestinationAddress = "net.tcp://localhost:8080/servicemodelsamples/service/";
            
            //the "Default" router address
            string routerAddress = "http://localhost/routingservice/router/general";

            //the virtualized address of the regular calculator
            string virtualCalculatorAddress = "http://localhost/routingservice/router/regular/calculator";
            
            //the virtualized address of the rounding calculator
            string virtualRoundingCalculatorAddress = "http://localhost/routingservice/router/rounding/calculator";

            //set up the bindings for the Routing Service's communication with the client
            Binding routerBinding = new WSHttpBinding();

            //set up the bindings for the Routing Service's communication with the Calculator Services
            Binding clientBinding = new NetTcpBinding();

            //use the IRequestReplyRouter since the client and services are expecting request/response communication
            ContractDescription contract = ContractDescription.GetContract(typeof(IRequestReplyRouter));

            //set up the default Router endpoint 
            ServiceEndpoint routerEndpoint = new ServiceEndpoint(contract, routerBinding, new EndpointAddress(routerAddress));
            routerEndpoint.Name = "routerEndpoint";

            //create the virtual endpoint for the regular CalculatorSerivice
            ServiceEndpoint calcEndpoint = new ServiceEndpoint(contract, routerBinding, new EndpointAddress(virtualCalculatorAddress));
            calcEndpoint.Name = "calculatorEndpoint";

            //create the virtual endpoint for the rounding CalculatorSerivice
            ServiceEndpoint roundingEndpoint = new ServiceEndpoint(contract, routerBinding, new EndpointAddress(virtualRoundingCalculatorAddress));
            roundingEndpoint.Name = "roundingEndpoint";

            //add the inbound endpoints that the Routing Service will listen for
            serviceHost.AddServiceEndpoint(routerEndpoint);
            serviceHost.AddServiceEndpoint(calcEndpoint);
            serviceHost.AddServiceEndpoint(roundingEndpoint);
            
            //create the client endpoints the router will route messages to
            ServiceEndpoint RegularCalcEndpoint = new ServiceEndpoint(contract, new NetTcpBinding(), new EndpointAddress(calcDestinationAddress));
            ServiceEndpoint RoundingCalcEndpoint = new ServiceEndpoint(contract, new NetTcpBinding(), new EndpointAddress(roundingDestinationAddress));
            
            //create the endpoint lists that contains the service endpoints we want to route to
            List<ServiceEndpoint> RegularCalcs = new List<ServiceEndpoint>();
            List<ServiceEndpoint> RoundingCalcs = new List<ServiceEndpoint>();

            //add the endpoints in the order we want the Routing Service to try sending to them
            RegularCalcs.Add(RegularCalcEndpoint);
            RoundingCalcs.Add(RoundingCalcEndpoint);
            
            //create the default RoutingConfiguration 
            RoutingConfiguration rc = new RoutingConfiguration();

            //create all of the necessary filters

            //create a new XPathMessageFilter that will look for the custom header
            //Unfortunately, the default namespace manager doesn't have the custom namespace
            // that we use defined so we have to define that prefix ourselves.
            //Any message that shows up with this header will match this filter.
            XPathMessageContext namespaceManager = new XPathMessageContext();
            namespaceManager.AddNamespace("custom", "http://my.custom.namespace/");

            XPathMessageFilter xpathFilter = new XPathMessageFilter("sm:header()/custom:RoundingCalculator = 1", namespaceManager);

            //create a new Endpoint Name Message Filter, which will match any message that was received
            //on the calculator Endpoint.  The Endpoint name was defined when we created the service endpoint object
            EndpointNameMessageFilter endpointNameFilter = new EndpointNameMessageFilter("calculatorEndpoint");

            //Create a new Prefix Endpoint Address Message Filter.  This will match any message that showed up on an endpoint
            //with an address that matches the address -prefix- (or front portion) provided.  In this example we define
            //the address prefix as "http://localhost/routingservice/router/rounding/".  This means that any messages that arrive
            //addressed to http://localhost/routingservice/router/rounding/* will be matched by this filter.  In this case, that
            //will be messages that show up on the rounding calculator endpoint, which has the address of 
            //http://localhost/routingservice/router/rounding/calculator.
            PrefixEndpointAddressMessageFilter prefixAddressFilter = new PrefixEndpointAddressMessageFilter(new EndpointAddress("http://localhost/routingservice/router/rounding/"));

            //create two new Custom message filters.  In this example, we're going to use a "RoundRobin" message filter
            //this message filter is created in the provided RoundRobinMessageFilter.cs file.  These filters, when set
            //to the same group, will alternate between reporting that they match the message and that they don't, such that
            //only one of them will respond true at a time.
            RoundRobinMessageFilter roundRobinFilter1 = new RoundRobinMessageFilter("group1");
            RoundRobinMessageFilter roundRobinFilter2 = new RoundRobinMessageFilter("group1");

            
            //Now let's add all of those Message Filters to the Message Filter Table
            //note the use of priorities to influence the order in which the MessageFilter Table
            //executes the filters.  The higher the priority, the sooner the filter will be
            //executed, the lower the priority, the later a filter will be executed.  Thus a filter
            //at priority 2 runs before a filter at priority 1.  The default priority level
            //if one isn't specified is 0.  A Message Filter Table executes all of the filters
            //at a given priority level before moving to the next lowest priority level.
            //If a match is found at a particular priority, then the Message Filter Table doesn't
            //continue trying to find matches at the next lower priority.  
            //
            //While this example shows how to use Message Filter priorities, in general it is
            //more performant and better design to design and configure your filters such that they
            //don't require prioritization in order to function correctly.  
            

            //The first filter we add is the XPath filter, and we set its priority to 2.
            //Thus this will be the first MessageFilter that executes.  If it finds the custom
            //header, regardless of what the results of the other filters would be, the message
            //will be routed to the Rounding Calculator endpoint.
            
            //catch messages that showed up with the custom header
            rc.FilterTable.Add(xpathFilter, RoundingCalcs, 2);

            //At priority 1, we'll add two filters.  These will only run if the xpath filter
            //at priority 2 doesn't match the message.  These two filters show two different ways to 
            //determine where the message was addressed when it showed up.  Because they effectively check
            //to see if the message arrived at one of the two endpoints, we can run them 
            //at the same priority level since they're never going to both return true.

            //find messages that showed up addressed to the specific virtual endpoints
            rc.FilterTable.Add(endpointNameFilter, RegularCalcs, 1);
            rc.FilterTable.Add(prefixAddressFilter, RoundingCalcs, 1);

            //Finally, run the RoundRobin message filters.  Since we configured the filters
            //with the same group name, only one of them will match at a time.  Since we've already
            //Routed all the messages with the custom header, and then those addressed to the specific
            //virtualized endpoints, these will only be messages that showed up addressed to the
            //default router endpoint without the custom header.  Since these will switch based
            //on a per message call, half of the operations will go to the regular calculator, and 
            //half will go to the Rounding calculator.
            rc.FilterTable.Add(roundRobinFilter1, RegularCalcs, 0);
            rc.FilterTable.Add(roundRobinFilter2, RoundingCalcs, 0);
                        
            //create the Routing Behavior with the Routing Configuration and add it to the 
            //serviceHost's Description.
            serviceHost.Description.Behaviors.Add(new RoutingBehavior(rc));
                                 

        }
Пример #7
0
        // Remove a MessageFilter from the RouterTable
        void removeRouting(Filter filter)
        {
            lock (this.routingTableLock)
            {
                var table = deltaTable(filter);
                var config = new RoutingConfiguration(table, true);
                this.Router.Extension.ApplyConfiguration(config);
            }

            log.Info("A stale MessageFilter has been removed.");
        }
Пример #8
0
 public InstanceProvider(RoutingConfiguration config)
 {
     this.config = config;
 }
Пример #9
0
        private static void ConfigureRouterViaCode(ServiceHost host)
        {
                //configure a MSMQ Binding that is not very tolerant of failures.
                MsmqTransportBindingElement msmqbe = new MsmqTransportBindingElement();

                //Set the auth mode and protection levels to none so that we can run without
                //Active Directory using Private queues.
                msmqbe.MsmqTransportSecurity.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
                msmqbe.MsmqTransportSecurity.MsmqProtectionLevel = System.Net.Security.ProtectionLevel.None;

                //when the Routing Service receives a message and is unable to process it, we should reject it.
                //This will result in the message being placed in the "inbound" queue's System Dead Letter Queue.
                msmqbe.ReceiveErrorHandling = ReceiveErrorHandling.Reject;
                msmqbe.DeadLetterQueue = DeadLetterQueue.System;
                
                //Set the retry count, retry cycles, and delay to very unreasonable values
                //If the message cannot be delivered to the destination Queue on the first try
                //report an error. This error will be noticed by the Routing Service's error
                //handling code, which will automatically move the message to the backup endpoints
                //defined, if available.
                msmqbe.ReceiveRetryCount = 0;
                msmqbe.MaxRetryCycles = 0;
                msmqbe.RetryCycleDelay = TimeSpan.FromMilliseconds(1);
                
                //create the MSMQ Binding with our custom settings
                Binding QueueBinding = new CustomBinding(new BinaryMessageEncodingBindingElement(), msmqbe);

                //add a service endpoint to the host.  This is the endpoint on the Routing Service
                //that reads from the queue.
                host.AddServiceEndpoint(typeof(ISimplexDatagramRouter), QueueBinding, inboundQ);

                //create a new RoutingConfiguration object.
                RoutingConfiguration rc = new RoutingConfiguration();

                //create the service endpoints that the Routing Service will communicate with
                ServiceEndpoint primaryService = new ServiceEndpoint(cd, QueueBinding, new EndpointAddress(primaryServiceQueue));
                ServiceEndpoint backupService = new ServiceEndpoint(cd, QueueBinding, new EndpointAddress(backupServiceQueue));
                ServiceEndpoint primaryLogging = new ServiceEndpoint(cd, QueueBinding, new EndpointAddress(primaryLoggingQueue));
                ServiceEndpoint backupLogging = new ServiceEndpoint(cd, QueueBinding, new EndpointAddress(backupLoggingQueue));

                //we always want the message to go to both a service endpoint and a logging endpoint 
                //the way we achieve this is "multicasting" the message to both destinations at the same time
                //additionally, since we're both the inbound and outbound queues are transactional, if either none of the service queues 
                //or none of the logging queues are able to Transactionally recieve the message, then the Routing Service 
                //will report to the originating system that the message was unable to be delivered, at which point the 
                //originating queue will put the message in it's system Dead Letter Queue.

                //add the primary service queue and the backup service queue endpoint
                rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { primaryService, backupService });

                //add the primary logging queue and the backup logging queue endpoint
                rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { primaryLogging, backupLogging });

                //add the RoutingBehavior to the Service
                host.Description.Behaviors.Add(new RoutingBehavior(rc));
        }
Пример #10
0
 protected RoutingClientBase(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, object callbackInstance, bool impersonating)
     : base(new InstanceContext(callbackInstance), endpointTrait.Endpoint.Binding, endpointTrait.Endpoint.Address)
 {
     Initialize(endpointTrait, routingConfig, impersonating);
 }
Пример #11
0
 protected RoutingClientBase(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
     : base(endpointTrait.Endpoint.Binding, endpointTrait.Endpoint.Address)
 {
     Initialize(endpointTrait, routingConfig, impersonating);
 }
Пример #12
0
 public RequestReplyClient(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
     : base(endpointTrait, routingConfig, impersonating)
 {
 }
Пример #13
0
 public SimplexSessionClient(RoutingEndpointTrait endointTrait, RoutingConfiguration routingConfig, bool impersonating)
     : base(endointTrait, routingConfig, impersonating)
 {
 }
Пример #14
0
		// instance members

		public RoutingBehavior (RoutingConfiguration routingConfiguration)
		{
			if (routingConfiguration == null)
				throw new ArgumentNullException ("routingConfiguration");
			config = routingConfiguration;
		}