private WsdlFileInfo GetMainWsdl() { var importedWsdl = new List <string>(); var wsdlFiles = this.MetadataFiles.OfType <WsdlFileInfo>(); // record imported wsld files to be able to identify the core wsdl file. foreach (var wsdl in wsdlFiles.Select(f => f.Wsdl)) { foreach (WsdlNS.Import import in wsdl.Imports) { var filePath = Path.Combine(this.DirectoryPath, import.Location); importedWsdl.Add(filePath); } } var mainWsdlFile = wsdlFiles.Where(w => !importedWsdl.Any(i => MetadataFileNameManager.UriEqual(i, w.FilePath))).FirstOrDefault(); if (mainWsdlFile == null) { // this may be the case of docs with circular dependencies, this is ok as they are not imported multiple times, select the first one (if any). mainWsdlFile = wsdlFiles.FirstOrDefault(); } return(mainWsdlFile); }
/// <summary> /// </summary> /// <param name="uri">The service Uri to load service metadata from.</param> /// <param name="httpCredentialsProvider"></param> /// <param name="clientCertificatesProvider"></param> /// <param name="serverCertificateValidationProvider"></param> public MetadataDocumentLoader(string uri, IHttpCredentialsProvider httpCredentialsProvider, IClientCertificateProvider clientCertificatesProvider, IServerCertificateValidationProvider serverCertificateValidationProvider) { _httpCredentialsProvider = httpCredentialsProvider; _clientCertificatesProvider = clientCertificatesProvider; _serverCertificateValidationProvider = serverCertificateValidationProvider; if (string.IsNullOrEmpty(uri)) { throw new ArgumentNullException(nameof(uri)); } if (!CanLoad(uri, string.Empty, Directory.GetCurrentDirectory(), out Uri metadataUri)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MetadataResources.ErrInvalidUriFormat, uri)); } if (metadataUri.IsFile) { // the input could be a reference to a list of files specified with wildcards, let's check. var fileInfoList = MetadataFileNameManager.ResolveFiles(metadataUri.LocalPath); // when only the wsdl file is specified, we need to resolve any schema references. _resolveExternalDocs = fileInfoList.Length == 1; this.metadataSourceFiles.AddRange(fileInfoList.Select(fi => new Uri(fi.FullName, UriKind.Absolute))); } else { _resolveExternalDocs = true; this.MetadataSourceUrl = metadataUri; } }
private MetadataFileInfo AddSchema(XmlSchema schema) { MetadataFileInfo metadataFileInfo = null; if (schema != null && !this.MetadataFiles.Any(mi => mi.Metadata == schema) /*&& schema.Items.Count > 0*/) { var sourceUrl = schema.SourceUri; var filePath = AddFilePath(schema.SourceUri, schema.TargetNamespace, ".xsd"); schema.SourceUri = Path.GetFileName(filePath); metadataFileInfo = new SchemaFileInfo(schema, filePath, sourceUrl, schema.Write); this.MetadataFiles.Add(metadataFileInfo); var unresolvedRefs = UnresolvedReferences.Where(u => (MetadataFileNameManager.UriEqual(u.SchemaExternal?.SchemaLocation, sourceUrl) || (!string.IsNullOrEmpty(u.Namespace) && u.Namespace == schema.TargetNamespace))).ToList(); foreach (var unresolvedRef in unresolvedRefs) { unresolvedRef.SchemaExternal.SchemaLocation = schema.SourceUri; UnresolvedReferences.Remove(unresolvedRef); } } return(metadataFileInfo); }
private bool AddUnresolvedSchemaRefs(XmlNS.Schema.XmlSchema schema) { if (schema != null) { foreach (XmlNS.Schema.XmlSchemaExternal schemaExternal in schema.Includes) { if (!this.UnresolvedReferences.Any(r => r.SchemaExternal == schemaExternal)) { if (!string.IsNullOrEmpty(schemaExternal.SchemaLocation)) { schemaExternal.SchemaLocation = MetadataFileNameManager.GetComposedUri(schema.SourceUri, schemaExternal.SchemaLocation); UnresolvedReferences.Add(new UnresolvedUri { Schema = schema, SchemaExternal = schemaExternal }); } else if (schemaExternal.Schema == null) { // the MetadataExchangeClient when using MEX protocol downloads wsdl-embedded schemas separately, // need to gather namespace-only imports (which are valid w/o any schema) to be able to connect // the docs if it is the case. var schemaImport = schemaExternal as XmlNS.Schema.XmlSchemaImport; if (schemaImport != null && !string.IsNullOrEmpty(schemaImport.Namespace)) { UnresolvedReferences.Add(new UnresolvedUri { Schema = schema, SchemaExternal = schemaExternal, Namespace = schemaImport.Namespace }); } } } } return(true); } return(false); }
/// <summary> /// </summary> /// <param name="metadataFiles">A collection containing the location of wsdl/schema documents to load service metadata from.</param> /// <param name="resolveExternalDocuments">if true, WSDL imports and XmlSchema Includes will be attempted to be resolved.</param> /// <param name="httpCredentialsProvider"></param> /// <param name="clientCertificatesProvider"></param> /// <param name="serverCertificateValidationProvider"></param> public MetadataDocumentLoader(IEnumerable <string> metadataFiles, bool resolveExternalDocuments, IHttpCredentialsProvider httpCredentialsProvider, IClientCertificateProvider clientCertificatesProvider, IServerCertificateValidationProvider serverCertificateValidationProvider) { _httpCredentialsProvider = httpCredentialsProvider; _clientCertificatesProvider = clientCertificatesProvider; _serverCertificateValidationProvider = serverCertificateValidationProvider; if (metadataFiles == null) { throw new ArgumentNullException(nameof(metadataFiles)); } foreach (var uri in metadataFiles) { if (!CanLoad(uri, string.Empty, Directory.GetCurrentDirectory(), out Uri metadataUri)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MetadataResources.ErrInvalidUriFormat, uri)); } if (!metadataUri.IsFile) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MetadataResources.ErrUrlNotAllowedOnMultipleInputsFormat, metadataUri)); } var fileInfoList = MetadataFileNameManager.ResolveFiles(metadataUri.LocalPath); this.metadataSourceFiles.AddRange(fileInfoList.Select(fi => new Uri(fi.FullName, UriKind.Absolute))); } _resolveExternalDocs = resolveExternalDocuments; }
/// <summary> /// Attempts to resolve a metadata document in disk (wsdl/schema file). /// </summary> /// <param name="schemaUri">The resolved URI for the specified schema file.</param> /// <param name="schemaLocation">The original location of the schema file, this could be a relative path.</param> /// <param name="basePath">The wsdl docs path in disk.</param> /// <param name="specNamespace">The namespace for the file document (schema/wsdl)</param> /// <param name="extension">The extension of the document file in disk (.xsd/.wsdl)</param> /// <param name="schemaFile">The resolved URI for the document file.</param> /// <returns>True, if the file exists; false otherwise.</returns> private bool TryGetExistingSchemaFile(Uri schemaUri, string schemaLocation, string basePath, string specNamespace, string extension, out Uri schemaFile) { // Try to get the file name. string fullFileName = schemaUri.IsFile ? schemaUri.LocalPath : schemaLocation; schemaFile = null; // check if the file has already been downloaded using some heuristics. if (!File.Exists(fullFileName)) { if (schemaUri.Segments.Length > 0) { // the URI may contain the file name. fullFileName = Path.Combine(basePath, schemaUri.Segments[schemaUri.Segments.Length - 1]); } if (!File.Exists(fullFileName) && !string.IsNullOrWhiteSpace(specNamespace)) { // reconstruct the local file name for the remote location (assuming files downloaded by MetadataDocumentSaver): // <xsd:import schemaLocation="http://serverhost/servcicename.svc?xsd=xsd0" namespace="http://tempuri.org/" /> // observe that schema include specs are not processed because on download they are made part of the container schema (must belong to the same namespace). // <xsd:include schemaLocation="xsd1.xsd" /> fullFileName = MetadataFileNameManager.GetFilePathFromNamespace(basePath, specNamespace, extension); } if (!File.Exists(fullFileName) && !Path.IsPathRooted(schemaLocation)) { fullFileName = Path.Combine(basePath, schemaLocation); if (!File.Exists(fullFileName)) { fullFileName = Path.Combine(basePath, Path.GetFileName(schemaLocation)); } } } if (File.Exists(fullFileName)) { Uri.TryCreate(fullFileName, UriKind.Absolute, out schemaFile); } return(schemaFile != null); }
private async Task LoadAsync(string uri, string baseUrl, string basePath, CancellationToken cancellationToken) { if (CanLoad(uri, baseUrl, basePath, out Uri serviceUri)) { if (serviceUri.Scheme == MetadataConstants.Uri.UriSchemeFile) { var fileInfoList = MetadataFileNameManager.ResolveFiles(serviceUri.LocalPath); foreach (var fileInfo in fileInfoList) { if (!IsUriProcessed(fileInfo.FullName)) { using (var fileStream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) { await LoadFromStreamAsync(fileStream, fileInfo.FullName, fileInfo.DirectoryName, cancellationToken).ConfigureAwait(false); } } } } else { if (!IsUriProcessed(serviceUri.AbsoluteUri)) { // Clone providers as they may be in use for a different URI. MetadataExchangeResolver metadataExchangeResolver = MetadataExchangeResolver.Create( new EndpointAddress(serviceUri), _httpCredentialsProvider?.Clone() as IHttpCredentialsProvider, _clientCertificatesProvider?.Clone() as IClientCertificateProvider, _serverCertificateValidationProvider?.Clone() as IServerCertificateValidationProvider); var metadataSections = await metadataExchangeResolver.ResolveMetadataAsync(cancellationToken).ConfigureAwait(false); _metadataSections.AddRange(metadataSections); } } } else { throw new MetadataExchangeException(MetadataResources.ErrInvalidUriFormat, uri); } }
private MetadataFileInfo AddWsdl(WsdlNS.ServiceDescription wsdl) { MetadataFileInfo metadataFileInfo = null; if (wsdl != null && !this.MetadataFiles.Any(mi => mi.Metadata == wsdl)) { var sourceUrl = wsdl.RetrievalUrl; var filePath = AddFilePath(wsdl.RetrievalUrl, wsdl.TargetNamespace, ".wsdl"); wsdl.RetrievalUrl = Path.GetFileName(filePath); metadataFileInfo = new WsdlFileInfo(wsdl, filePath, sourceUrl, wsdl.Write); this.MetadataFiles.Add(metadataFileInfo); var unresolvedRefs = UnresolvedReferences.Where(u => MetadataFileNameManager.UriEqual(u.WsdlImport?.Location, sourceUrl)).ToList(); foreach (var unresolvedRef in unresolvedRefs) { unresolvedRef.WsdlImport.Location = wsdl.RetrievalUrl; UnresolvedReferences.Remove(unresolvedRef); } } return(metadataFileInfo); }
private bool AddUnresolvedWsdlRefs(WsdlNS.ServiceDescription wsdl) { if (wsdl != null) { foreach (WsdlNS.Import import in wsdl.Imports) { if (!string.IsNullOrEmpty(import.Location) && !this.UnresolvedReferences.Any(r => r.WsdlImport == import)) { import.Location = MetadataFileNameManager.GetComposedUri(wsdl.RetrievalUrl, import.Location); UnresolvedReferences.Add(new UnresolvedUri { WsdlImport = import, Wsdl = wsdl }); } } foreach (XmlNS.Schema.XmlSchema schema in wsdl.Types.Schemas) { AddUnresolvedSchemaRefs(schema); } return(true); } return(false); }
public override bool Equals(object obj) { UnresolvedUri other = obj as UnresolvedUri; return(other != null && MetadataFileNameManager.UriEqual(this.Uri, other.Uri)); }
private void AddMetadataFiles(IEnumerable <MetadataSection> documents) { if (documents == null) { throw new ArgumentNullException(nameof(documents)); } // prepopulate schema/wsdl includes/imports so references can be resolved/updated when resolving document paths. foreach (var doc in documents) { if (!AddUnresolvedSchemaRefs(doc.Metadata as XmlNS.Schema.XmlSchema)) { AddUnresolvedWsdlRefs(doc.Metadata as WsdlNS.ServiceDescription); } } // compute document paths. foreach (var doc in documents) { if (AddWsdl(doc.Metadata as WsdlNS.ServiceDescription) == null) { if (AddSchema(doc.Metadata as XmlNS.Schema.XmlSchema) == null) { if (AddXmlDocument(doc.Metadata as XmlNS.XmlElement, doc.Dialect) == null) { #if DEBUG string typeName = doc.Metadata.GetType().ToString(); Debug.Fail("Unknown metadata found: " + typeName); #endif } } } } for (int idx = UnresolvedReferences.Count - 1; idx >= 0; idx--) { var unresolvedRef = UnresolvedReferences[idx]; if (unresolvedRef.Namespace != null) { // remove namespace-only schema references as they are still valid UnresolvedReferences.RemoveAt(idx); } else { // remove schema references for which multiple files are resolved (wildcards). var location = unresolvedRef.WsdlImport != null ? unresolvedRef.WsdlImport.Location : unresolvedRef.SchemaExternal?.SchemaLocation; if (MetadataFileNameManager.TryCreateUri(location, out Uri locationUri) && MetadataFileNameManager.TryResolveFiles(locationUri.LocalPath, out var files)) { var missingRefs = files.Where(file => !this.MetadataFiles.Any(metaFile => MetadataFileNameManager.UriEqual(file.FullName, metaFile.SourceUri))); if (missingRefs.Count() == 0) { var updatedLocation = Path.Combine(this.DirectoryPath, Path.GetFileName(location)); if (unresolvedRef.WsdlImport != null) { unresolvedRef.WsdlImport.Location = updatedLocation; } else { unresolvedRef.SchemaExternal.SchemaLocation = updatedLocation; } UnresolvedReferences.Remove(unresolvedRef); } } } } }
public bool Equals(string otherFilePath) { return(otherFilePath != null && MetadataFileNameManager.UriEqual(this.FilePath, otherFilePath)); }
private static void FixupChameleonSchemas(IEnumerable <MetadataSection> metadataSections) { // Chameleon schemas are those w/o a target namespace, types from these schemas become part of the namespace of the enclosing schema. var documents = metadataSections.Select((s) => s.Metadata); var schemas = documents.OfType <XmlNS.Schema.XmlSchema>(); var chameleonSchemas = schemas.Where(s => string.IsNullOrEmpty(s.TargetNamespace)); foreach (var schema in schemas) { foreach (XmlNS.Schema.XmlSchemaExternal include in schema.Includes) { var chameleonSchema = chameleonSchemas.FirstOrDefault(c => c != schema && MetadataFileNameManager.UriEqual(MetadataFileNameManager.GetComposedUri(c.SourceUri, null), MetadataFileNameManager.GetComposedUri(schema.SourceUri, include.SchemaLocation))); if (chameleonSchema != null) { include.Schema = chameleonSchema; } } } }