Example #1
0
        static int Main(string[] args)
        {
            // we assume the path are existed for simplicity.
            string path  = Directory.GetCurrentDirectory();
            string csdl  = path + "/../../../../../docs/csdl";
            string oas20 = path + "/../../../../../docs/oas_2_0";
            string oas30 = path + "/../../../../../docs/oas3_0_0";

            foreach (var filePath in Directory.GetFiles(csdl, "*.xml"))
            {
                IEdmModel model = LoadEdmModel(filePath);
                if (model == null)
                {
                    continue;
                }

                FileInfo fileInfo = new FileInfo(filePath);
                string   fileName = fileInfo.Name.Substring(0, fileInfo.Name.Length - 4);

                OpenApiConvertSettings settings = new OpenApiConvertSettings();
                if (fileName.Contains("graph.beta"))
                {
                    settings.PrefixEntityTypeNameBeforeKey = true;
                    settings.ServiceRoot = new Uri("https://graph.microsoft.com/beta");
                }
                else if (fileName.Contains("graph1.0"))
                {
                    settings.PrefixEntityTypeNameBeforeKey = true;
                    settings.ServiceRoot = new Uri("https://graph.microsoft.com/v1.0");
                }

                OpenApiDocument document = model.ConvertToOpenApi(settings);

                string output;/* = oas20 + "/" + fileName + ".yaml";
                               * File.WriteAllText(output, document.SerializeAsYaml(OpenApiSpecVersion.OpenApi2_0));
                               *
                               * output = oas20 + "/" + fileName + ".json";
                               * File.WriteAllText(output, document.SerializeAsJson(OpenApiSpecVersion.OpenApi2_0));
                               *
                               * output = oas30 + "/" + fileName + ".yaml";
                               * File.WriteAllText(output, document.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0));
                               *
                               * output = oas30 + "/" + fileName + ".json";
                               * File.WriteAllText(output, document.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0));
                               */
                settings.EnableKeyAsSegment    = true;
                settings.EnableUnqualifiedCall = true;
                output   = oas30 + "/" + fileName + ".json";
                document = model.ConvertToOpenApi(settings);
                File.WriteAllText(output, document.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0));

                output = oas20 + "/" + fileName + ".json";
                File.WriteAllText(output, document.SerializeAsJson(OpenApiSpecVersion.OpenApi2_0));

                Console.WriteLine("Output [ " + fileName + " ] Succeessful!");
            }

            Console.WriteLine("\n==> All Done!");
            return(0);
        }
        private OpenApiDocument CreateDocument(string prefixName)
        {
            IDictionary <string, ODataPath> tempateToPathDict = new Dictionary <string, ODataPath>();
            ODataOpenApiPathProvider        provider          = new ODataOpenApiPathProvider();
            IEdmModel model = null;

            foreach (var endpoint in _dataSource.Endpoints)
            {
                IODataRoutingMetadata metadata = endpoint.Metadata.GetMetadata <IODataRoutingMetadata>();
                if (metadata == null)
                {
                    continue;
                }

                if (metadata.Prefix != prefixName)
                {
                    continue;
                }
                model = metadata.Model;

                RouteEndpoint routeEndpoint = endpoint as RouteEndpoint;
                if (routeEndpoint == null)
                {
                    continue;
                }

                // get rid of the prefix
                int    length            = prefixName.Length;
                string routePathTemplate = routeEndpoint.RoutePattern.RawText.Substring(length);
                routePathTemplate = routePathTemplate.StartsWith("/") ? routePathTemplate : "/" + routePathTemplate;

                if (tempateToPathDict.TryGetValue(routePathTemplate, out ODataPath pathValue))
                {
                    string method = GetHttpMethod(metadata, endpoint);
                    pathValue.HttpMethods.Add(method);
                    continue;
                }

                var path = metadata.Template.Translate();
                if (path == null)
                {
                    continue;
                }

                path.PathTemplate = routePathTemplate;
                provider.Add(path);

                string method1 = GetHttpMethod(metadata, endpoint);
                path.HttpMethods.Add(method1);
                tempateToPathDict[routePathTemplate] = path;
            }

            OpenApiConvertSettings settings = new OpenApiConvertSettings
            {
                PathProvider = provider,
                ServiceRoot  = BuildAbsolute()
            };

            return(model.ConvertToOpenApi(settings));
        }
Example #3
0
        /// <summary>
        /// Generate the Open Api.
        /// </summary>
        public bool Generate()
        {
            try
            {
                IEdmModel edmModel = GetEdmModel();

                OpenApiConvertSettings settings = GetSettings();

                settings.OpenApiSpecVersion = Version;

                using (FileStream fs = File.Create(Output))
                {
                    OpenApiDocument document = edmModel.ConvertToOpenApi(settings);
                    document.Serialize(fs, settings.OpenApiSpecVersion, Format);
                    fs.Flush();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }

            return(true);
        }
        public void ConvertToOpenApiThrowsArgumentNullModel()
        {
            // Arrange
            IEdmModel model = null;

            // Act & Assert
            Assert.Throws <ArgumentNullException>("model", () => model.ConvertToOpenApi());
        }
Example #5
0
        public static string GenerateOpenApiDescription()
        {
            OpenApiConvertSettings settings = new OpenApiConvertSettings();

            settings.PrefixEntityTypeNameBeforeKey = false;

            IEdmModel       model      = GetEdmModel();
            OpenApiDocument document   = model.ConvertToOpenApi();
            var             outputJSON = document.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);

            return(outputJSON);
        }
        private static string WriteEdmModelAsOpenApi(IEdmModel model, OpenApiFormat target,
                                                     OpenApiConvertSettings settings = null)
        {
            settings = settings ?? new OpenApiConvertSettings();
            var document = model.ConvertToOpenApi(settings);

            Assert.NotNull(document); // guard

            MemoryStream stream = new MemoryStream();

            document.Serialize(stream, settings.OpenApiSpecVersion, target);
            stream.Flush();
            stream.Position = 0;
            return(new StreamReader(stream).ReadToEnd());
        }
Example #7
0
        /// <summary>
        /// Generate the Open Api.
        /// </summary>
        public static bool Run(Configuration config)
        {
            IEdmModelProvider modelProvider = new EdmModelProvider(config.InputCsdl, config.IsLocalFile);
            IEdmModel         edmModel      = modelProvider.GetEdmModel();

            IConvertSettingsProvider settingsProvider = new ConvertSettingsProvider(config);
            OpenApiConvertSettings   settings         = settingsProvider.GetConvertSettings();

            using (FileStream fs = File.Create(config.OutputFileName))
            {
                OpenApiDocument document = edmModel.ConvertToOpenApi(settings);
                document.Serialize(fs, OpenApi.OpenApiSpecVersion.OpenApi3_0, config.Format);
                fs.Flush();
            }

            return(true);
        }
Example #8
0
        public OpenApiDocument ConvertCsdlToOpenApi(IEdmModel edmModel)
        {
            var settings = new OpenApiConvertSettings()
            {
                EnableKeyAsSegment            = true,
                EnableOperationId             = true,
                PrefixEntityTypeNameBeforeKey = true,
                TagDepth                 = 2,
                EnablePagination         = true,
                EnableDiscriminatorValue = true,
                EnableDerivedTypesReferencesForRequestBody = true,
                EnableDerivedTypesReferencesForResponses   = true,
                ShowLinks = true
            };
            OpenApiDocument document = edmModel.ConvertToOpenApi(settings);

            return(document);
        }
Example #9
0
        public static async Task  GenerateOpenApiDescription(string version, string outputhPath)
        {
            string    url   = $"https://graph.microsoft.com/{version}/$metadata";
            IEdmModel model = await GetEdmModel(url);

            OpenApiConvertSettings settings = new OpenApiConvertSettings
            {
                VerifyEdmModel    = false,
                EnableOperationId = false,
            };
            OpenApiDocument document   = model.ConvertToOpenApi(settings);
            var             outputJSON = document.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);

            Directory.CreateDirectory(outputhPath);
            File.WriteAllText(Path.Join(outputhPath, $"{version}.json"), outputJSON);
            var outputYAML = document.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0);

            File.WriteAllText(Path.Join(outputhPath, $"{version}.yaml"), outputYAML);
        }
Example #10
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Please enter a solution prefix");
            }
            else
            {
                solutionPrefix = args[0];
            }

            bool generatePaths = false;

            if (args.Length > 1)
            {
                if (args[1] == "generatePaths")
                {
                    generatePaths = true;
                }
            }

            // Feature flags

            // True if we use the Autorest Odata extension
            bool enableOdataExtension = false;

            // True if we get metadata from Dynamics
            bool getMetadata = true;

            // True if we use strings instead of guids primary keys.
            bool useStringForGuid = true;

            bool disableCustomErrorClass = true;


            List <string> defsToKeep = new List <string>();



            // start by getting secrets.
            var builder = new ConfigurationBuilder()
                          .AddEnvironmentVariables();

            builder.AddUserSecrets <Program>();
            var    Configuration = builder.Build();
            string csdl;

            // get the metadata.
            if (getMetadata)
            {
                try
                {
                    csdl = GetDynamicsMetadata(Configuration);
                    File.WriteAllText("dynamics-metadata.xml", csdl);
                }
                catch (System.Net.WebException)
                {
                    csdl = File.ReadAllText("dynamics-metadata.xml");
                }
            }
            else
            {
                csdl = File.ReadAllText("dynamics-metadata.xml");
            }

            // fix the csdl.

            csdl = csdl.Replace("ConcurrencyMode=\"Fixed\"", "");

            IEdmModel model = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());

            // fix dates.

            /*
             * OpenApiTarget target = OpenApiTarget.Json;
             * OpenApiWriterSettings settings = new OpenApiWriterSettings
             * {
             *  BaseUri = new Uri(Configuration["DYNAMICS_ODATA_URI"])
             * };
             */

            string swagger = null;

            OpenApiConvertSettings openApiSettings = new OpenApiConvertSettings
            {
                // configuration
            };
            OpenApiDocument swaggerDocument = model.ConvertToOpenApi(openApiSettings);

            if (generatePaths)
            {
                List <string> paths = new List <string>();
                foreach (var path in swaggerDocument.Paths)
                {
                    string subPath = path.Key.Substring(path.Key.LastIndexOf("/") + 1);
                    if (subPath.Contains("("))
                    {
                        subPath = subPath.Substring(0, subPath.IndexOf("("));
                    }

                    string pathSample = path.Key.Substring(1, subPath.Length);
                    if (pathSample != subPath)
                    {
                        paths.Add(path.Key);
                    }
                }
                File.WriteAllText("paths-excluded.json", JsonConvert.SerializeObject(paths));
            }
            else
            {
                List <string> itemsToRemove = new List <string>();
                if (File.Exists("paths-excluded.json"))
                {
                    string pathsExcluded = File.ReadAllText("paths-excluded.json");
                    itemsToRemove = JsonConvert.DeserializeObject <List <string> >(pathsExcluded);
                }


                List <string> allops = new List <string>();

                // fix the operationIds.
                foreach (var path in swaggerDocument.Paths)
                {
                    if (itemsToRemove.Contains(path.Key))
                    {
                        continue;
                    }
                    if (path.Key.Contains("transactioncurrencyid"))
                    {
                        itemsToRemove.Add(path.Key);
                        continue;
                    }
                    if (path.Key.Contains("scheduledprocessexecution"))
                    {
                        itemsToRemove.Add(path.Key);
                        continue;
                    }

                    // determine if this is a get by key, or a get by key with additional .
                    string subPath = "";

                    string temp = path.Key.Substring(path.Key.LastIndexOf("/") + 1);
                    if (temp.Contains("("))
                    {
                        temp = temp.Substring(0, temp.IndexOf("("));
                        string pathSample = path.Key.Substring(1, temp.Length);
                        if (pathSample != temp)
                        {
                            subPath = temp;
                        }

                        subPath += "ByKey";
                    }

                    OpenApiTag firstTag      = null; // operation.Value.Tags.FirstOrDefault();
                    string     firstTagLower = "";

                    if (firstTag == null)
                    {
                        firstTag = new OpenApiTag()
                        {
                            Name = temp
                        };
                    }

                    string prefix = "Unknown";

                    if (firstTag != null)
                    {
                        bool ok2Delete = true;
                        firstTagLower = firstTag.Name.ToLower();
                        //Console.Out.WriteLine(firstTagLower);
                        if (firstTagLower.Equals("contacts") ||
                            firstTagLower.Equals("accounts") ||
                            firstTagLower.Equals("invoices") ||
                            firstTagLower.Equals("leads") ||
                            firstTagLower.Equals("lists") ||
                            firstTagLower.Equals("sharepointsites") ||
                            firstTagLower.Equals("savedqueries") ||
                            firstTagLower.Equals("sharepointdocumentlocations") ||
                            firstTagLower.Equals("entitydefinitions") ||
                            firstTagLower.Equals("globaloptionsetdefinitions") ||
                            firstTagLower.Equals("systemforms") ||
                            firstTagLower.Equals("workflows") ||
                            firstTagLower.Equals("eventschedules") ||
                            firstTagLower.Equals("inspector")


                            )
                        {
                            ok2Delete = false;
                            //Console.Out.WriteLine($"NOT ok to delete {firstTagLower}");
                        }

                        if (!firstTagLower.StartsWith("msdyn") && !firstTagLower.StartsWith("abs_") && firstTagLower.IndexOf(solutionPrefix) != -1)
                        {
                            //Console.Out.WriteLine($"NOT ok to delete {firstTagLower}");
                            ok2Delete = false;
                        }

                        if (ok2Delete)
                        {
                            //Console.Out.WriteLine($"ok to delete {firstTagLower}");
                            if (!itemsToRemove.Contains(path.Key))
                            {
                                itemsToRemove.Add(path.Key);
                            }
                            continue;
                        }

                        if (!allops.Contains(firstTag.Name))
                        {
                            allops.Add(firstTag.Name);
                        }
                        prefix = firstTagLower;
                        // Capitalize the first character.

                        if (prefix.Length > 0 && prefix.Length > solutionPrefix.Length)
                        {
                            if (prefix.ToUpper().Substring(0, solutionPrefix.Length) == solutionPrefix.ToUpper())
                            {
                                prefix = prefix.Substring(solutionPrefix.Length);
                            }
                            prefix = prefix.Substring(0, 1).ToUpper() + prefix.Substring(1);
                        }
                        // remove any underscores.
                        prefix = prefix.Replace("_", "");
                    }

                    foreach (var operation in path.Value.Operations)
                    {
                        if (!firstTagLower.StartsWith("msdyn") && !firstTagLower.StartsWith("abs_") && firstTagLower.IndexOf(solutionPrefix) != -1)
                        {
                            firstTagLower = firstTagLower.Replace($"{solutionPrefix}_", "");
                            firstTagLower = firstTagLower.Replace(solutionPrefix, "");
                            operation.Value.Tags.Clear();
                            operation.Value.Tags.Add(new OpenApiTag()
                            {
                                Name = firstTagLower
                            });
                        }

                        string suffix = "";


                        switch (operation.Key)
                        {
                        case OperationType.Post:
                            suffix = "Create";
                            // for creates we also want to add a header parameter to ensure we get the new object back.
                            OpenApiParameter swaggerParameter = new OpenApiParameter()
                            {
                                Schema = new OpenApiSchema()
                                {
                                    Type = "string", Default = new OpenApiString("return=representation")
                                },
                                Name        = "Prefer",
                                Description = "Required in order for the service to return a JSON representation of the object.",
                                In          = ParameterLocation.Header
                            };
                            operation.Value.Parameters.Add(swaggerParameter);
                            break;

                        case OperationType.Patch:
                            suffix = "Update";
                            if (subPath == "ByKey")
                            {
                                subPath = "";
                            }
                            break;

                        case OperationType.Put:
                            suffix = "Put";
                            if (subPath == "ByKey")
                            {
                                subPath = "";
                            }
                            break;

                        case OperationType.Delete:
                            suffix = "Delete";
                            if (subPath == "ByKey")
                            {
                                subPath = "";
                            }
                            break;

                        case OperationType.Get:
                            suffix = "Get";
                            break;
                        }

                        if (suffix.Length >= solutionPrefix.Length && suffix.ToUpper().Substring(0, solutionPrefix.Length) == solutionPrefix.ToUpper())
                        {
                            suffix = suffix.Substring(solutionPrefix.Length);
                        }

                        operation.Value.OperationId = prefix + "_" + suffix;

                        if (!firstTag.Name.Contains(subPath))
                        {
                            operation.Value.OperationId += subPath;
                        }

                        string operationDef = null;
                        // adjustments to response

                        foreach (var response in operation.Value.Responses)
                        {
                            var val = response.Value;
                            if (response.Key == "default")
                            {
                                if (string.IsNullOrEmpty(response.Value.Description))
                                {
                                    response.Value.Description = "OData Error";
                                }
                                ;

                                if (disableCustomErrorClass && response.Value.Reference != null)
                                {
                                    response.Value.Reference = null;
                                }
                            }

                            if (val != null)
                            {
                                bool hasValue = false;
                                foreach (var schema in val.Content)
                                {
                                    foreach (var property in schema.Value.Schema.Properties)
                                    {
                                        if (property.Key.Equals("value"))
                                        {
                                            hasValue = true;
                                            break;
                                        }
                                    }
                                    if (hasValue)
                                    {
                                        var    newSchema = schema.Value.Schema.Properties["value"];
                                        string resultName;
                                        string itemName;

                                        if (newSchema.Type == "array")
                                        {
                                            itemName     = newSchema.Items.Reference.Id;
                                            operationDef = itemName;
                                            resultName   = $"{itemName}Collection";
                                        }
                                        else
                                        {
                                            itemName   = "!ERR";
                                            resultName = "!ERR";
                                        }



                                        if (!swaggerDocument.Components.Schemas.ContainsKey(resultName))
                                        {
                                            // move the inline schema to defs.
                                            swaggerDocument.Components.Schemas.Add(resultName, schema.Value.Schema);

                                            //var newSchema = swaggerDocument.Components.Schemas[resultName].Properties["value"];
                                            if (newSchema.Type == "array")
                                            {
                                                newSchema.Items = new OpenApiSchema()
                                                {
                                                    Reference = new OpenApiReference()
                                                    {
                                                        Id = itemName, Type = ReferenceType.Schema
                                                    }, Type = "none"
                                                };
                                                AddSubItems(swaggerDocument, defsToKeep, itemName);
                                            }
                                            AddSubItems(swaggerDocument, defsToKeep, resultName);
                                        }

                                        schema.Value.Schema = new OpenApiSchema {
                                            Reference = new OpenApiReference()
                                            {
                                                Id = resultName, Type = ReferenceType.Schema
                                            }, Type = "none"
                                        };
                                        // val.Reference = new OpenApiReference() { Id = resultName, Type = ReferenceType.Schema, ExternalResource = null };
                                    }
                                    else
                                    {
                                        if (schema.Value.Schema.Reference != null)
                                        {
                                            operationDef = schema.Value.Schema.Reference.Id;
                                            AddSubItems(swaggerDocument, defsToKeep, operationDef);
                                        }
                                    }
                                }
                            }
                        }



                        // adjustments to operation parameters
                        if (enableOdataExtension)
                        {
                            string[] oDataParameters = { "top", "skip", "search", "filter", "count", "$orderby", "$select", "$expand" };

                            List <OpenApiParameter> parametersToRemove = new List <OpenApiParameter>();

                            foreach (var oDataParameter in oDataParameters)
                            {
                                foreach (var parameter in operation.Value.Parameters)
                                {
                                    if (parameter.Name == oDataParameter)
                                    {
                                        parametersToRemove.Add(parameter);
                                    }

                                    if (parameter.Reference != null && parameter.Reference.Id == oDataParameter)
                                    {
                                        parametersToRemove.Add(parameter);
                                    }
                                }
                            }
                            foreach (var parameter in parametersToRemove)
                            {
                                operation.Value.Parameters.Remove(parameter);
                            }
                        }


                        operation.Value.Extensions.Clear();


                        if (operationDef != null && enableOdataExtension)
                        {
                            operation.Value.Extensions.Add("x-ms-odata", new OpenApiString($"#/definitions/{operationDef}"));
                            AddSubItems(swaggerDocument, defsToKeep, operationDef);
                        }

                        foreach (var parameter in operation.Value.Parameters)
                        {
                            if (parameter.Reference != null)
                            {
                                if (parameter.Reference.Id == "top" || parameter.Reference.Id == "skip")
                                {
                                    parameter.Name      = $"${parameter.Reference.Id}";
                                    parameter.Reference = null;
                                    parameter.In        = ParameterLocation.Query;
                                    parameter.Schema    = new OpenApiSchema()
                                    {
                                        Type = "integer"
                                    };
                                }
                                else if (parameter.Reference.Id == "search" || parameter.Reference.Id == "filter")
                                {
                                    parameter.Name      = $"${parameter.Reference.Id}";
                                    parameter.Reference = null;
                                    parameter.In        = ParameterLocation.Query;
                                    parameter.Schema    = new OpenApiSchema()
                                    {
                                        Type = "string"
                                    };
                                }
                                else if (parameter.Reference.Id == "count")
                                {
                                    parameter.Name      = $"${parameter.Reference.Id}";
                                    parameter.Reference = null;
                                    parameter.In        = ParameterLocation.Query;
                                    parameter.Schema    = new OpenApiSchema()
                                    {
                                        Type = "boolean"
                                    };
                                }
                            }
                            else
                            {
                                string name = parameter.Name;
                                if (name == null)
                                {
                                    name = parameter.Name;
                                }

                                if (name != null)
                                {
                                    if (name == "$top" || name == "$skip")
                                    {
                                        parameter.In        = ParameterLocation.Query;
                                        parameter.Reference = null;
                                        parameter.Schema    = new OpenApiSchema()
                                        {
                                            Type = "integer"
                                        };
                                    }
                                    if (name == "$search" || name == "$filter")
                                    {
                                        parameter.In        = ParameterLocation.Query;
                                        parameter.Reference = null;
                                        parameter.Schema    = new OpenApiSchema()
                                        {
                                            Type = "string"
                                        };
                                    }
                                    if (name == "$orderby" || name == "$select" || name == "$expand")
                                    {
                                        parameter.In        = ParameterLocation.Query;
                                        parameter.Reference = null;
                                        parameter.Schema    = new OpenApiSchema()
                                        {
                                            Type  = "array",
                                            Items = new OpenApiSchema()
                                            {
                                                Type = "string"
                                            }
                                        };
                                        parameter.Extensions.Add("collectionFormat", new OpenApiString("csv"));
                                    }
                                    if (name == "$count")
                                    {
                                        parameter.In        = ParameterLocation.Query;
                                        parameter.Reference = null;
                                        parameter.Schema    = new OpenApiSchema()
                                        {
                                            Type = "boolean"
                                        };
                                    }
                                    if (name == "If-Match")
                                    {
                                        parameter.Reference = null;
                                        parameter.Schema    = new OpenApiSchema()
                                        {
                                            Type = "string"
                                        };
                                    }

                                    if (parameter.Extensions != null && parameter.Extensions.ContainsKey("x-ms-docs-key-type"))
                                    {
                                        parameter.Extensions.Remove("x-ms-docs-key-type");
                                    }

                                    if (string.IsNullOrEmpty(parameter.Name))
                                    {
                                        parameter.Name = name;
                                    }
                                }
                            }

                            // get rid of style if it exists.
                            if (parameter.Style != ParameterStyle.Simple)
                            {
                                parameter.Style = ParameterStyle.Simple;
                            }

                            // get rid of guid type if it exists

                            if (parameter.Schema?.Format != null && useStringForGuid && parameter.Schema.Format == "uuid")
                            {
                                parameter.Schema.Format  = null;
                                parameter.Schema.Pattern = null;
                            }

                            // may need to clear unique items here.

                            // align the schema if it exists.
                            if (parameter.Schema != null && parameter.Schema.Items != null)
                            {
                                var schema = parameter.Schema;
                                if (schema.Type == "array" && parameter.Style == null)
                                {
                                    // may be a good idea to set collectionFormat to csv here.  It is also set below.

                                    parameter.Style = ParameterStyle.Simple;
                                }
                            }
                        }
                    }
                }

                foreach (var opDelete in itemsToRemove)
                {
                    swaggerDocument.Paths.Remove(opDelete);
                }

                foreach (var path in swaggerDocument.Paths)
                {
                    foreach (var value in path.Value.Operations)
                    {
                        foreach (var response in value.Value.Responses)
                        {
                            if (response.Value.Reference != null)
                            {
                                var schema = response.Value.Reference;
                                if (!string.IsNullOrEmpty(schema.Id) && (schema.Type.Value.GetDisplayName() == "array" || schema.Type.Value.GetDisplayName() == "object"))
                                {
                                    string title = schema.Id;
                                    AddSubItems(swaggerDocument, defsToKeep, title);
                                }
                            }
                        }
                        foreach (var parameter in value.Value.Parameters)
                        {
                            if (parameter.Schema != null && parameter.Schema.Reference != null)
                            {
                                var schema = parameter.Schema.Reference;
                                if (!string.IsNullOrEmpty(schema.Id) && (schema.Type.Value.GetDisplayName() == "array" || schema.Type.Value.GetDisplayName() == "object"))
                                {
                                    AddSubItems(swaggerDocument, defsToKeep, schema.Id);
                                }
                            }
                        }
                    }
                }



                // reverse the items to keep.

                List <string> defsToRemove = new List <string>();


                foreach (var definition in swaggerDocument.Components.Schemas)
                {
                    if (
                        !definition.Key.Contains("odata.error") &&
                        !definition.Key.Contains("crmbaseentity") &&
                        !definition.Key.ToLower().Contains("optionmetadata") &&
                        !defsToKeep.Contains(definition.Key))
                    {
                        defsToRemove.Add(definition.Key);
                    }
                }

                foreach (string defToRemove in defsToRemove)
                {
                    //Console.Out.WriteLine($"Remove: {defToRemove}");
                    if (!string.IsNullOrEmpty(defToRemove) && swaggerDocument.Components.Schemas.ContainsKey(defToRemove))
                    {
                        swaggerDocument.Components.Schemas.Remove(defToRemove);
                    }
                }

                /*
                 * List<string> responsesToRemove = new List<string>();
                 *
                 *
                 * foreach (string responseToRemove in responsesToRemove)
                 * {
                 *  Console.Out.WriteLine($"Remove Response: {responseToRemove}");
                 *
                 *  if (!string.IsNullOrEmpty(responseToRemove) && swaggerDocument.Components.Responses.ContainsKey(responseToRemove))
                 *  {
                 *      swaggerDocument.Components.Responses.Remove(responseToRemove);
                 *  }
                 *
                 *
                 * }
                 *
                 */

                /*
                 * Cleanup definitions.
                 */

                foreach (var definition in swaggerDocument.Components.Schemas)
                {
                    if (definition.Value.Description == null)
                    {
                        definition.Value.Description = definition.Key;
                    }


                    // consolidate AllOf
                    if (definition.Value.AllOf != null && definition.Value.Type == null)
                    {
                        definition.Value.Type = "object";
                    }

                    var dictionary = new Dictionary <string, OpenApiSchema>();
                    MergeSubItems(dictionary, definition.Value);
                    definition.Value.Properties = dictionary;
                    if (definition.Value.AllOf != null)
                    {
                        definition.Value.AllOf.Clear();
                    }

                    // Clear out the example if it exists

                    if (definition.Value.Example != null)
                    {
                        definition.Value.Example = null;
                    }


                    if (definition.Value != null && definition.Value.Properties != null)
                    {
                        foreach (var property in definition.Value.Properties)
                        {
                            if (property.Value.Type == null)
                            {
                                Console.WriteLine($"Property has no type, forcing to string. {property.Key} - format - {property.Value.Format}");
                                property.Value.Type = "string";
                            }
                            // convert all dates to datetimeoffset.
                            // special handling of the Dynamics "DATE (YYYY-MM-DD)" fields will need to be done with extensions.
                            if (property.Value != null && property.Value.Format != null && property.Value.Format == "date")
                            {
                                property.Value.Format = "date-time";
                            }

                            // fix for doubles
                            else if (property.Value != null && property.Value.Format != null && property.Value.Format.Equals("double"))
                            {
                                property.Value.Format = "decimal";
                                property.Value.Type   = "number";
                            }
                            if (property.Key.Equals("totalamount"))
                            {
                                property.Value.Type   = "number";
                                property.Value.Format = "decimal";
                            }

                            if (property.Key.Equals("versionnumber"))
                            {
                                // clear oneof.
                                if (property.Value.OneOf != null)
                                {
                                    property.Value.OneOf.Clear();
                                }

                                // force to string.
                                property.Value.Type = "string";
                            }

                            if (property.Value.Minimum != null)
                            {
                                property.Value.Minimum = null;
                            }
                            if (property.Value.Maximum != null)
                            {
                                property.Value.Maximum = null;
                            }
                            if (property.Value.Pattern != null)
                            {
                                property.Value.Pattern = null;
                            }


                            if (property.Value.Format != null && property.Value.Format == "uuid" && useStringForGuid)
                            {
                                property.Value.Format = null;
                            }
                        }
                    }
                }


                // remove extra tags.
                swaggerDocument.Tags.Clear();

                // cleanup parameters.
                //swaggerDocument.Components.Parameters.Clear();


                //**************************************

                // fix for "odata.error.main" - innererror property.

                swaggerDocument.Components.Schemas["odata.error.main"].Properties.Remove("innererror");

                // fix for two entities that have links to everything else - this causes massive spikes in memory consumption.

                swaggerDocument.Components.Schemas.Remove("Microsoft.Dynamics.CRM.transactioncurrency");
                swaggerDocument.Components.Schemas.Remove("Microsoft.Dynamics.CRM.syncerror");

                Dictionary <string, OpenApiSchema> props = new Dictionary <string, OpenApiSchema>();
                props.Add("nil", new OpenApiSchema()
                {
                    Type = "string"
                });
                swaggerDocument.Components.Schemas.Add("Microsoft.Dynamics.CRM.transactioncurrency", new OpenApiSchema()
                {
                    Properties = props
                });
                swaggerDocument.Components.Schemas.Add("Microsoft.Dynamics.CRM.syncerror", new OpenApiSchema()
                {
                    Properties = props
                });


                // swagger = swaggerDocument.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0); // ToJson(SchemaType.Swagger2);
                swagger = swaggerDocument.SerializeAsJson(OpenApiSpecVersion.OpenApi2_0);
            }

            File.WriteAllText("dynamics-swagger.json", swagger);
        }
Example #11
0
 /// <summary>
 /// Convert <see cref="IEdmModel"/> to <see cref="OpenApiDocument"/> using default settings.
 /// </summary>
 /// <param name="model">The Edm model.</param>
 /// <returns>The converted Open API document object, <see cref="OpenApiDocument"/>.</returns>
 public static OpenApiDocument ConvertToOpenApi(this IEdmModel model)
 {
     return(model.ConvertToOpenApi(new OpenApiConvertSettings()));
 }