Exemplo n.º 1
0
        public override CodeModel Build()
        {
            var compositeSwaggerModel = Parse(Settings.Input);

            if (compositeSwaggerModel == null)
            {
                throw ErrorManager.CreateError(Resources.ErrorParsingSpec);
            }

            if (!compositeSwaggerModel.Documents.Any())
            {
                throw ErrorManager.CreateError(string.Format(CultureInfo.InvariantCulture, "{0}. {1}",
                                                             Resources.ErrorParsingSpec, "Documents collection can not be empty."));
            }

            if (compositeSwaggerModel.Info == null)
            {
                throw ErrorManager.CreateError(Resources.InfoSectionMissing);
            }

            // Ensure all the docs are absolute URIs or rooted paths
            for (var i = 0; i < compositeSwaggerModel.Documents.Count; i++)
            {
                var compositeDocument = compositeSwaggerModel.Documents[i];
                if (!Settings.FileSystemInput.IsCompletePath(compositeDocument) || !Settings.FileSystemInput.FileExists(compositeDocument))
                {
                    // Otherwise, root it from the current path
                    compositeSwaggerModel.Documents[i] = Settings.FileSystemInput.MakePathRooted(Settings.FileSystemInput.GetParentDir(Settings.Input), compositeDocument);
                }
            }

            // construct merged swagger document
            var mergedSwagger = new YamlMappingNode();

            mergedSwagger.Set("info", (Settings.FileSystemInput.ReadAllText(Settings.Input).ParseYaml() as YamlMappingNode)?.Get("info") as YamlMappingNode);

            // merge child swaggers
            foreach (var childSwaggerPath in compositeSwaggerModel.Documents)
            {
                var childSwaggerRaw = Settings.FileSystemInput.ReadAllText(childSwaggerPath);
                childSwaggerRaw = SwaggerParser.Normalize(childSwaggerPath, childSwaggerRaw);
                var childSwagger = childSwaggerRaw.ParseYaml() as YamlMappingNode;
                if (childSwagger == null)
                {
                    throw ErrorManager.CreateError("Failed parsing referenced Swagger file {0}.", childSwaggerPath);
                }

                // remove info
                var info    = childSwagger.Get("info") as YamlMappingNode;
                var version = info.Get("version");
                info.Remove("title");
                info.Remove("description");
                info.Remove("version");

                // fix up api version
                var apiVersionParam     = (childSwagger.Get("parameters") as YamlMappingNode)?.Children?.FirstOrDefault(param => ((param.Value as YamlMappingNode)?.Get("name") as YamlScalarNode)?.Value == "api-version");
                var apiVersionParamName = (apiVersionParam?.Key as YamlScalarNode)?.Value;
                if (apiVersionParamName != null)
                {
                    var paths =
                        ((childSwagger.Get("paths") as YamlMappingNode)?.Children?.Values ?? Enumerable.Empty <YamlNode>()).Concat
                            ((childSwagger.Get("x-ms-paths") as YamlMappingNode)?.Children?.Values ?? Enumerable.Empty <YamlNode>());
                    var methods          = paths.OfType <YamlMappingNode>().SelectMany(path => path.Children.Values.OfType <YamlMappingNode>());
                    var parameters       = methods.SelectMany(method => (method.Get("parameters") as YamlSequenceNode)?.Children?.OfType <YamlMappingNode>() ?? Enumerable.Empty <YamlMappingNode>());
                    var apiVersionParams = parameters.Where(param => (param.Get("$ref") as YamlScalarNode)?.Value == $"#/parameters/{apiVersionParamName}");
                    foreach (var param in apiVersionParams)
                    {
                        param.Remove("$ref");
                        foreach (var child in (apiVersionParam?.Value as YamlMappingNode).Children)
                        {
                            param.Children.Add(child);
                        }
                        param.Set("enum", new YamlSequenceNode(version));
                    }
                }

                // merge
                mergedSwagger = mergedSwagger.MergeWith(childSwagger);
            }
            // remove apiVersion client property
            var mergedSwaggerApiVersionParam     = (mergedSwagger.Get("parameters") as YamlMappingNode)?.Children?.FirstOrDefault(param => ((param.Value as YamlMappingNode)?.Get("name") as YamlScalarNode)?.Value == "api-version");
            var mergedSwaggerApiVersionParamName = (mergedSwaggerApiVersionParam?.Key as YamlScalarNode)?.Value;

            if (mergedSwaggerApiVersionParamName != null)
            {
                (mergedSwagger.Get("parameters") as YamlMappingNode).Remove(mergedSwaggerApiVersionParamName);
            }

            // CodeModel compositeClient = InitializeServiceClient(compositeSwaggerModel);
            using (NewContext)
            {
                var swaggerModeler = new SwaggerModeler();
                return(swaggerModeler.Build(SwaggerParser.Parse(Settings.Input, mergedSwagger.Serialize())));
            }
        }