2010-06-18 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 18 Jun 2010 15:33:40 +0000 (15:33 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 18 Jun 2010 15:33:40 +0000 (15:33 -0000)
* ServiceHostBase.cs : Do not build more than one ChannelDispatcher
  for a Binding. Then check duplicate listen URIs, excluding mex ones.

* ChannelDispatcher.cs : add simple bool field to mark for mex channel.

* ServiceMetadataExtension.cs : use simple ChannelDispatcher.IsMex field.

* ServiceHostTest.cs : improved endpoint tests and enabled them.

* ChannelDispatcherTest.cs : had to disable a test that regressed from
  validating duplicate listen URI. Possible remedy is described too.

svn path=/trunk/mcs/; revision=159140

mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataExtension.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcherBase.cs
mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/ChangeLog
mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/ChannelDispatcherTest.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog
mcs/class/System.ServiceModel/Test/System.ServiceModel/ServiceHostTest.cs

index 7f380f236e04ca2f497f5df8ca79c2d266273e71..caa3f6e3916d52cebc2b3d9c6e746eb3498189e2 100644 (file)
@@ -1,3 +1,7 @@
+2010-06-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceMetadataExtension.cs : use simple ChannelDispatcher.IsMex field.
+
 2010-06-17  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ServiceMetadataExtension.cs : overwrite MessageVersion to use None.
index 4187806e81a822053e72ac070a88e9d8be4107d7..508d2f565c64084ab8aa9080d46328bfdd63d64d 100644 (file)
@@ -142,6 +142,7 @@ namespace System.ServiceModel.Description
                                listener.Properties.Add (new MetadataPublishingInfo () { SupportsMex = isMex, SupportsHelp = !isMex, Instance = instance });
                        else
                                throw new InvalidOperationException ("FIXME: attempt to use ServiceMetadataExtension to not-supported channel listener: " + listener.GetType ());
+                       channelDispatcher.IsMex = true;
                        channelDispatcher.Endpoints [0].DispatchRuntime.InstanceContextProvider = new SingletonInstanceContextProvider (new InstanceContext (owner, instance));
 
                        dispatchers.Add (uri, channelDispatcher);
index dd74ce2b252f8f57852e5c8d416ebb0269e09eeb..dc397f212c426260b0610fe4aa21778281c6eb76 100644 (file)
@@ -1,3 +1,7 @@
+2010-06-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ChannelDispatcher.cs : add simple bool field to mark for mex channel.
+
 2010-06-17  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ChannelDispatcher.cs : MessageVersion check is moved to
index d9130ab1497d6e72a2c1ba5372bc35ef60c28e34..a60976bd36977d1001c73dfcc049bfe336734008 100644 (file)
@@ -36,6 +36,8 @@ namespace System.ServiceModel.Dispatcher
 {
        public abstract class ChannelDispatcherBase : CommunicationObject
        {
+               internal bool IsMex { get; set; }
+
                public abstract IChannelListener Listener { get; }
 
                public abstract ServiceHostBase Host { get; }
index 84177d7a7db93451271bb918aae6da7ccf642133..f761a87b1259a41c3a75b7e5976370d3963434c3 100755 (executable)
@@ -1,3 +1,8 @@
+2010-06-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceHostBase.cs : Do not build more than one ChannelDispatcher
+         for a Binding. Then check duplicate listen URIs, excluding mex ones.
+
 2010-06-17  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ServiceHostBase.cs : retrieve MessageVersion and raise an error
index 2f5a10c247fa195714ca233cff09d8b2631bcaab..fe4cc247a181512e9d97365dec50393ab15042e8 100644 (file)
@@ -476,6 +476,18 @@ namespace System.ServiceModel
                {
                        DateTime start = DateTime.Now;
                        InitializeRuntime ();
+                       for (int i = 0; i < ChannelDispatchers.Count; i++) {
+                               // Skip ServiceMetadataExtension-based one. special case.
+                               for (int j = i + 1; j < ChannelDispatchers.Count; j++) {
+                                       var cd1 = ChannelDispatchers [i];
+                                       var cd2 = ChannelDispatchers [j];
+                                       if (cd1.IsMex || cd2.IsMex)
+                                               continue;
+                                       if (cd1.Listener.Uri.Equals (cd2.Listener.Uri))
+                                               throw new InvalidOperationException ("Two or more service endpoints with different Binding instance are bound to the same listen URI.");
+                               }
+                       }
+
                        var waits = new List<ManualResetEvent> ();
                        foreach (var cd in ChannelDispatchers) {
                                var wait = new ManualResetEvent (false);
@@ -613,7 +625,7 @@ namespace System.ServiceModel
                        this.host = host;
                }
 
-               List<ChannelDispatcher> built_dispatchers = new List<ChannelDispatcher> ();
+               Dictionary<Binding,ChannelDispatcher> built_dispatchers = new Dictionary<Binding,ChannelDispatcher> ();
                Dictionary<ServiceEndpoint, EndpointDispatcher> ep_to_dispatcher_ep = new Dictionary<ServiceEndpoint, EndpointDispatcher> ();
 
                internal static Action<ChannelDispatcher> ChannelDispatcherSetter;
@@ -646,7 +658,7 @@ namespace System.ServiceModel
                                        ServiceHostBase.CurrentServiceHostHack = null;
                                }
                                ep = cd.InitializeServiceEndpoint (serviceType, se);
-                               built_dispatchers.Add (cd);
+                               built_dispatchers.Add (se.Binding, cd);
                        }
                        ep_to_dispatcher_ep[se] = ep;
                        return cd;
@@ -654,7 +666,7 @@ namespace System.ServiceModel
                
                ChannelDispatcher FindExistingDispatcher (ServiceEndpoint se)
                {
-                       return built_dispatchers.FirstOrDefault ((ChannelDispatcher cd) => (cd.Listener.Uri.Equals (se.ListenUri)) && cd.MessageVersion.Equals (se.Binding.MessageVersion));
+                       return built_dispatchers.FirstOrDefault ((KeyValuePair<Binding,ChannelDispatcher> p) => se.Binding == p.Key).Value;
                }
 
                internal void ApplyDispatchBehaviors ()
index d24f785e2f7286ff663657be1760e0a97fc6bb33..c601ebcd48359bd26a4cc4f84c3d9800a005211d 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ChannelDispatcherTest.cs : had to disable a test that regressed from
+         validating duplicate listen URI. Possible remedy is described too.
+
 2010-04-05  Atsushi Enomoto  <atsushi@ximian.com>
 
        * EndpointAddressMessageFilterTest.cs :
index 08e64e675ac0b883baa1852d4f2b68a51108d57f..3718357513859af9bbf7e39c3a4febdb3401d2b4 100644 (file)
@@ -229,6 +229,12 @@ namespace MonoTests.System.ServiceModel.Dispatcher
                }
 
                [Test]
+               [Category ("NotWorking")]
+               // Validating duplicate listen URI causes this regression.
+               // Since it is niche, I rather fixed ServiceHostBase to introduce validation.
+               // It is probably because this code doesn't use ServiceEndpoint to build IChannelListener i.e. built without Binding.
+               // We can add an extra field to ChannelDispatcher to indicate that it is from ServiceEndpoint (i.e. with Binding),
+               // but it makes little sense especially for checking duplicate listen URIs. Duplicate listen URIs should be rejected anyways.
                public void EndpointDispatcherAddTest8 ()
                {
                        var uri = CreateAvailableUri ("http://localhost:37564");
@@ -253,6 +259,7 @@ namespace MonoTests.System.ServiceModel.Dispatcher
 
                        try {
                                h.Open (TimeSpan.FromSeconds (10));
+                               Assert.AreEqual (3, h.ChannelDispatchers.Count, "#0"); // TestContract, d, mex
                                Assert.IsTrue (listener.BeginAcceptChannelTried, "#1"); // while it throws NIE ...
                                Assert.IsFalse (listener.WaitForChannelTried, "#2");
                                Assert.IsNotNull (ed.DispatchRuntime, "#3");
index 38d53def881b48719b59b023b824e77b5cbaa401..60fe1b67bbeed0a94117446477fc3e2018d32e52 100755 (executable)
@@ -1,3 +1,7 @@
+2010-06-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceHostTest.cs : improved endpoint tests and enabled them.
+
 2010-06-18  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ServiceHostTest.cs : fix AddServiceEndpoint tests to make sense.
index d98e86302e9bc2deac24f932b3594a587ad45c0a..1bb87864f5224b7a22de8834f305779cb7930574 100644 (file)
@@ -130,7 +130,6 @@ namespace MonoTests.System.ServiceModel
 
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
-               [Category ("NotWorking")]
                public void AddServiceEndpoint2 ()
                {
                        ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
@@ -143,7 +142,6 @@ namespace MonoTests.System.ServiceModel
 
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
-               [Category ("NotWorking")]
                public void AddServiceEndpoint2_2 ()
                {
                        ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
@@ -157,12 +155,11 @@ namespace MonoTests.System.ServiceModel
 
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
-               [Category ("NotWorking")] // If I blindly reject things like this, it will block Service[Debug|Metadata]Behavior functionality.
                public void AddServiceEndpoint2_3 ()
                {
-                       ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
-                       host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (Foo)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
-                       host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IMetadataExchange)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
+                       ServiceHost host = new ServiceHost (typeof (HogeFuga), new Uri ("http://localhost/echo"));
+                       host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IHoge)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
+                       host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IFuga)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
 
                        // Different contracts unlike previous two cases.
                        // If two or more endpoints are bound to the same listen
@@ -172,9 +169,30 @@ namespace MonoTests.System.ServiceModel
                        host.Close (); // should not reach here. It is to make sure to close unexpectedly opened host.
                }
 
+               [Test]
+               public void AddServiceEndpoint2_4 ()
+               {
+                       ServiceHost host = new ServiceHost (typeof (HogeFuga), new Uri ("http://localhost:37564"));
+                       var binding = new BasicHttpBinding ();
+                       host.AddServiceEndpoint (typeof (IHoge), binding, new Uri ("http://localhost:37564"));
+                       host.AddServiceEndpoint (typeof (IFuga), binding, new Uri ("http://localhost:37564"));
+
+                       // Use the same binding, results in one ChannelDispatcher (actually two, for metadata/debug behavior).
+                       host.Open ();
+                       try {
+                               Assert.AreEqual (2, host.ChannelDispatchers.Count, "#1");
+                               foreach (ChannelDispatcher cd in host.ChannelDispatchers) {
+                                       if (cd.BindingName != binding.Name)
+                                               continue; // mex
+                                       Assert.AreEqual (2, cd.Endpoints.Count, "#2");
+                               }
+                       } finally {
+                               host.Close ();
+                       }
+               }
+
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
-               [Category ("NotWorking")]
                public void AddServiceEndpoint3 ()
                {
                        ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
@@ -313,6 +331,26 @@ namespace MonoTests.System.ServiceModel
                        [OperationContract]
                        string Echo (string source);
                }
+               
+               [ServiceContract]
+               interface IHoge
+               {
+                       [OperationContract]
+                       void DoX ();
+               }
+
+               [ServiceContract]
+               interface IFuga
+               {
+                       [OperationContract]
+                       void DoY ();
+               }
+               
+               class HogeFuga : IHoge, IFuga
+               {
+                       public void DoX () {}
+                       public void DoY () {}
+               }
 
                class Baz : IBaz
                {