< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Description.WsdlHelper
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Description/WsdlHelper.cs
Line coverage
45%
Covered lines: 63
Uncovered lines: 75
Coverable lines: 138
Total lines: 328
Line coverage: 45.6%
Branch coverage
39%
Covered branches: 41
Total branches: 104
Branch coverage: 39.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
GetSingleWsdl(...)90%101093.75%
RemoveSchemaLocations(...)100%44100%
GetSingleWsdl(...)66.66%6681.81%
CopyServiceDescriptionCollection(...)100%22100%
MergeWsdl(...)0%14140%
UpdatePolicyKeys(...)0%18180%
UpdatePolicyReference(...)0%10100%
FindAllElements(...)0%660%
VerifyContractNamespace(...)50%2250%
EnsureSingleNamespace(...)75%282868.18%
IsBindingNameUsed(...)0%440%
CloneWsdl(...)100%11100%
CloneXsd(...)100%11100%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Description/WsdlHelper.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Globalization;
 7using System.IO;
 8using System.Linq;
 9using System.Xml;
 10using System.Xml.Schema;
 11using CoreWCF.Runtime;
 12using WsdlNS = System.Web.Services.Description;
 13
 14namespace CoreWCF.Description
 15{
 16    internal static class WsdlHelper
 17    {
 18        public static WsdlNS.ServiceDescription GetSingleWsdl(MetadataSet metadataSet)
 19        {
 1920            if (metadataSet.MetadataSections.Count < 1)
 21            {
 022                return null;
 23            }
 24
 1925            List<WsdlNS.ServiceDescription> wsdls = new List<WsdlNS.ServiceDescription>();
 1926            List<XmlSchema> xsds = new List<XmlSchema>();
 27
 18828            foreach (MetadataSection section in metadataSet.MetadataSections)
 29            {
 7530                if (section.Metadata is WsdlNS.ServiceDescription)
 31                {
 1932                    wsdls.Add((WsdlNS.ServiceDescription)section.Metadata);
 33                }
 34
 7535                if (section.Metadata is XmlSchema)
 36                {
 5637                    xsds.Add((XmlSchema)section.Metadata);
 38                }
 39            }
 40
 1941            VerifyContractNamespace(wsdls);
 1942            WsdlNS.ServiceDescription singleWsdl = GetSingleWsdl(CopyServiceDescriptionCollection(wsdls));
 43
 44            // Inline XML schemas
 15045            foreach (XmlSchema schema in xsds)
 46            {
 5647                XmlSchema newSchema = CloneXsd(schema);
 5648                RemoveSchemaLocations(newSchema);
 5649                singleWsdl.Types.Schemas.Add(newSchema);
 50            }
 51
 1952            return singleWsdl;
 53        }
 54
 55        private static void RemoveSchemaLocations(XmlSchema schema)
 56        {
 15457            foreach (XmlSchemaObject schemaObject in schema.Includes)
 58            {
 2159                XmlSchemaExternal external = schemaObject as XmlSchemaExternal;
 2160                if (external != null)
 61                {
 2162                    external.SchemaLocation = null;
 63                }
 64            }
 5665        }
 66
 67        private static WsdlNS.ServiceDescription GetSingleWsdl(List<WsdlNS.ServiceDescription> wsdls)
 68        {
 69            // Use WSDL that has the contracts as the base for single WSDL
 3870            WsdlNS.ServiceDescription singleWsdl = wsdls.First(wsdl => wsdl.PortTypes.Count > 0);
 1971            if (singleWsdl == null)
 72            {
 073                singleWsdl = new WsdlNS.ServiceDescription();
 74            }
 75            else
 76            {
 1977                singleWsdl.Types.Schemas.Clear();
 1978                singleWsdl.Imports.Clear();
 79            }
 80
 1981            Dictionary<XmlQualifiedName, XmlQualifiedName> bindingReferenceChanges = new Dictionary<XmlQualifiedName, Xm
 7682            foreach (WsdlNS.ServiceDescription wsdl in wsdls)
 83            {
 1984                if (wsdl != singleWsdl)
 85                {
 086                    MergeWsdl(singleWsdl, wsdl, bindingReferenceChanges);
 87                }
 88            }
 89
 1990            EnsureSingleNamespace(singleWsdl, bindingReferenceChanges);
 1991            return singleWsdl;
 92        }
 93
 94        private static List<WsdlNS.ServiceDescription> CopyServiceDescriptionCollection(List<WsdlNS.ServiceDescription> 
 95        {
 1996            List<WsdlNS.ServiceDescription> newWsdls = new List<WsdlNS.ServiceDescription>();
 7697            foreach (WsdlNS.ServiceDescription wsdl in wsdls)
 98            {
 1999                newWsdls.Add(CloneWsdl(wsdl));
 100            }
 101
 19102            return newWsdls;
 103        }
 104
 105        private static void MergeWsdl(WsdlNS.ServiceDescription singleWsdl, WsdlNS.ServiceDescription wsdl, Dictionary<X
 106        {
 0107            if (wsdl.Services.Count > 0)
 108            {
 0109                singleWsdl.Name = wsdl.Name;
 110            }
 111
 0112            foreach (WsdlNS.Binding binding in wsdl.Bindings)
 113            {
 0114                string uniqueBindingName = NamingHelper.GetUniqueName(binding.Name, IsBindingNameUsed, singleWsdl.Bindin
 0115                if (binding.Name != uniqueBindingName)
 116                {
 0117                    bindingReferenceChanges.Add(
 0118                        new XmlQualifiedName(binding.Name, binding.ServiceDescription.TargetNamespace),
 0119                        new XmlQualifiedName(uniqueBindingName, singleWsdl.TargetNamespace));
 0120                    UpdatePolicyKeys(binding, uniqueBindingName, wsdl);
 0121                    binding.Name = uniqueBindingName;
 122                }
 123
 0124                singleWsdl.Bindings.Add(binding);
 125            }
 126
 0127            foreach (object extension in wsdl.Extensions)
 128            {
 0129                singleWsdl.Extensions.Add(extension);
 130            }
 131
 0132            foreach (WsdlNS.Message message in wsdl.Messages)
 133            {
 0134                singleWsdl.Messages.Add(message);
 135            }
 136
 0137            foreach (WsdlNS.Service service in wsdl.Services)
 138            {
 0139                singleWsdl.Services.Add(service);
 140            }
 141
 0142            foreach (string warning in wsdl.ValidationWarnings)
 143            {
 0144                singleWsdl.ValidationWarnings.Add(warning);
 145            }
 0146        }
 147
 148        private static void UpdatePolicyKeys(WsdlNS.Binding binding, string newBindingName, WsdlNS.ServiceDescription ws
 149        {
 0150            string oldBindingName = binding.Name;
 151
 152            // policy
 0153            IEnumerable<XmlElement> bindingPolicies = FindAllElements(wsdl.Extensions, MetadataStrings.WSPolicy.Elements
 0154            string policyIdStringPrefixFormat = "{0}_";
 0155            foreach (XmlElement policyElement in bindingPolicies)
 156            {
 0157                XmlNode policyId = policyElement.Attributes.GetNamedItem(MetadataStrings.Wsu.Attributes.Id, MetadataStri
 0158                string policyIdString = policyId?.Value;
 0159                string policyIdStringWithOldBindingName = string.Format(CultureInfo.InvariantCulture, policyIdStringPref
 0160                string policyIdStringWithNewBindingName = string.Format(CultureInfo.InvariantCulture, policyIdStringPref
 0161                if (policyId != null && policyIdString != null && policyIdString.StartsWith(policyIdStringWithOldBinding
 162                {
 0163                    policyId.Value = policyIdStringWithNewBindingName + policyIdString.Substring(policyIdStringWithOldBi
 164                }
 165            }
 166
 167            // policy reference
 0168            UpdatePolicyReference(binding.Extensions, oldBindingName, newBindingName);
 0169            foreach (WsdlNS.OperationBinding operationBinding in binding.Operations)
 170            {
 0171                UpdatePolicyReference(operationBinding.Extensions, oldBindingName, newBindingName);
 0172                if (operationBinding.Input != null)
 173                {
 0174                    UpdatePolicyReference(operationBinding.Input.Extensions, oldBindingName, newBindingName);
 175                }
 176
 0177                if (operationBinding.Output != null)
 178                {
 0179                    UpdatePolicyReference(operationBinding.Output.Extensions, oldBindingName, newBindingName);
 180                }
 181
 0182                foreach (WsdlNS.FaultBinding fault in operationBinding.Faults)
 183                {
 0184                    UpdatePolicyReference(fault.Extensions, oldBindingName, newBindingName);
 185                }
 186            }
 0187        }
 188
 189        private static void UpdatePolicyReference(WsdlNS.ServiceDescriptionFormatExtensionCollection extensions, string 
 190        {
 0191            IEnumerable<XmlElement> bindingPolicyReferences = FindAllElements(extensions, MetadataStrings.WSPolicy.Eleme
 0192            string policyReferencePrefixFormat = "#{0}_";
 0193            foreach (XmlElement policyReferenceElement in bindingPolicyReferences)
 194            {
 0195                XmlNode policyReference = policyReferenceElement.Attributes.GetNamedItem(MetadataStrings.WSPolicy.Attrib
 0196                string policyReferenceValue = policyReference?.Value;
 0197                string policyReferenceValueWithOldBindingName = string.Format(CultureInfo.InvariantCulture, policyRefere
 0198                string policyReferenceValueWithNewBindingName = string.Format(CultureInfo.InvariantCulture, policyRefere
 0199                if (policyReference != null && policyReferenceValue != null && policyReferenceValue.StartsWith(policyRef
 200                {
 0201                    policyReference.Value = policyReferenceValueWithNewBindingName + policyReference.Value.Substring(pol
 202                }
 203            }
 0204        }
 205
 206        private static IEnumerable<XmlElement> FindAllElements(WsdlNS.ServiceDescriptionFormatExtensionCollection extens
 207        {
 0208            List<XmlElement> policyReferences = new List<XmlElement>();
 0209            for (int i = 0; i < extensions.Count; i++)
 210            {
 0211                XmlElement element = extensions[i] as XmlElement;
 0212                if (element != null && element.LocalName == elementName)
 213                {
 0214                    policyReferences.Add(element);
 215                }
 216            }
 217
 0218            return policyReferences;
 219        }
 220
 221        private static void VerifyContractNamespace(List<WsdlNS.ServiceDescription> wsdls)
 222        {
 38223            IEnumerable<WsdlNS.ServiceDescription> contractWsdls = wsdls.Where(serviceDescription => serviceDescription.
 19224            if (contractWsdls.Count() > 1)
 225            {
 0226                IEnumerable<string> namespaces = contractWsdls.Select<WsdlNS.ServiceDescription, string>(wsdl => wsdl.Ta
 0227                string contractNamespaces = string.Join(", ", namespaces);
 0228                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.SingleW
 229            }
 19230        }
 231
 232        private static void EnsureSingleNamespace(WsdlNS.ServiceDescription wsdl, Dictionary<XmlQualifiedName, XmlQualif
 233        {
 19234            string targetNamespace = wsdl.TargetNamespace;
 90235            foreach (WsdlNS.Binding binding in wsdl.Bindings)
 236            {
 26237                if (binding.Type.Namespace != targetNamespace)
 238                {
 0239                    binding.Type = new XmlQualifiedName(binding.Type.Name, targetNamespace);
 240                }
 241            }
 242
 76243            foreach (WsdlNS.PortType portType in wsdl.PortTypes)
 244            {
 226245                foreach (WsdlNS.Operation operation in portType.Operations)
 246                {
 94247                    WsdlNS.OperationInput messageInput = operation.Messages.Input;
 94248                    if (messageInput != null && messageInput.Message.Namespace != targetNamespace)
 249                    {
 0250                        messageInput.Message = new XmlQualifiedName(messageInput.Message.Name, targetNamespace);
 251                    }
 252
 94253                    WsdlNS.OperationOutput messageOutput = operation.Messages.Output;
 94254                    if (messageOutput != null && messageOutput.Message.Namespace != targetNamespace)
 255                    {
 0256                        messageOutput.Message = new XmlQualifiedName(messageOutput.Message.Name, targetNamespace);
 257                    }
 258
 188259                    foreach (WsdlNS.OperationFault fault in operation.Faults)
 260                    {
 0261                        if (fault.Message.Namespace != targetNamespace)
 262                        {
 0263                            fault.Message = new XmlQualifiedName(fault.Message.Name, targetNamespace);
 264                        }
 265                    }
 266                }
 267            }
 268
 76269            foreach (WsdlNS.Service service in wsdl.Services)
 270            {
 90271                foreach (WsdlNS.Port port in service.Ports)
 272                {
 273                    XmlQualifiedName newPortBinding;
 26274                    if (bindingReferenceChanges.TryGetValue(port.Binding, out newPortBinding))
 275                    {
 0276                        port.Binding = newPortBinding;
 277                    }
 26278                    else if (port.Binding.Namespace != targetNamespace)
 279                    {
 0280                        port.Binding = new XmlQualifiedName(port.Binding.Name, targetNamespace);
 281                    }
 282                }
 283            }
 19284        }
 285
 286        private static bool IsBindingNameUsed(string name, object collection)
 287        {
 0288            WsdlNS.BindingCollection bindings = (WsdlNS.BindingCollection)collection;
 0289            foreach (WsdlNS.Binding binding in bindings)
 290            {
 0291                if (binding.Name == name)
 292                {
 0293                    return true;
 294                }
 295            }
 296
 0297            return false;
 0298        }
 299
 300        private static WsdlNS.ServiceDescription CloneWsdl(WsdlNS.ServiceDescription originalWsdl)
 301        {
 302            Fx.Assert(originalWsdl != null, "originalWsdl must not be null");
 303            WsdlNS.ServiceDescription newWsdl;
 19304            using (MemoryStream memoryStream = new MemoryStream())
 305            {
 19306                originalWsdl.Write(memoryStream);
 19307                memoryStream.Seek(0, SeekOrigin.Begin);
 19308                newWsdl = WsdlNS.ServiceDescription.Read(memoryStream);
 19309            }
 310
 19311            return newWsdl;
 312        }
 313
 314        private static XmlSchema CloneXsd(XmlSchema originalXsd)
 315        {
 316            Fx.Assert(originalXsd != null, "originalXsd must not be null");
 317            XmlSchema newXsd;
 56318            using (MemoryStream memoryStream = new MemoryStream())
 319            {
 56320                originalXsd.Write(memoryStream);
 56321                memoryStream.Seek(0, SeekOrigin.Begin);
 56322                newXsd = XmlSchema.Read(new XmlTextReader(memoryStream) { DtdProcessing = DtdProcessing.Parse }, null);
 56323            }
 324
 56325            return newXsd;
 326        }
 327    }
 328}