Пример #1
0
        public OpenApiDocument Build(string documentVersion)
        {
            OpenApiGeneratorConfig input = new OpenApiGeneratorConfig(
                annotationXmlDocuments: new List <XDocument>()
            {
                XDocument.Load(XDOCUMENT_PATH)
            },
                assemblyPaths: new List <string>()
            {
                ASSEMBLY_PATH
            },
                openApiDocumentVersion: documentVersion,
                filterSetVersion: FilterSetVersion.V1
                );

            GenerationDiagnostic result;
            OpenApiGenerator     generator = new OpenApiGenerator();
            IDictionary <DocumentVariantInfo, OpenApiDocument> documents = generator.GenerateDocuments(input, out result);

            foreach (OperationGenerationDiagnostic diagnostic in result.OperationGenerationDiagnostics)
            {
                foreach (GenerationError error in diagnostic.Errors)
                {
                    Console.Write("OpenAPI Document Generation Error in " + diagnostic.OperationMethod + " " + diagnostic.Path);
                    Console.Error.WriteLine(error.Message);
                }
            }

            return(documents[DocumentVariantInfo.Default]);
        }
        public async Task <HttpResponseData> RunSwagger2([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestData req, FunctionContext executionContext)
        {
            var input = new OpenApiGeneratorConfig(
                annotationXmlDocuments: new List <XDocument>()
            {
                XDocument.Load(@"AzureFunctionsOpenAPIDemo.xml"),
            },
                assemblyPaths: new List <string>()
            {
                @"AzureFunctionsOpenAPIDemo.dll"
            },
                openApiDocumentVersion: "V1",
                filterSetVersion: FilterSetVersion.V1
                );

            input.OpenApiInfoDescription = "This is a sample description...";

            var generator        = new OpenApiGenerator();
            var openApiDocuments = generator.GenerateDocuments(
                openApiGeneratorConfig: input,
                generationDiagnostic: out GenerationDiagnostic result
                );

            var response = req.CreateResponse(HttpStatusCode.OK);

            response.Headers.Add("Content", "Content-Type: application/json; charset=utf-8");
            response.WriteString(openApiDocuments.First().Value.SerializeAsJson(OpenApiSpecVersion.OpenApi2_0));

            return(response);
        }
Пример #3
0
        public static async Task <HttpResponseMessage> RunSwagger([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
        {
            var input = new OpenApiGeneratorConfig(
                annotationXmlDocuments: new List <XDocument>()
            {
                XDocument.Load(@"AzureFunctionsOpenAPIDemo.xml"),
            },
                assemblyPaths: new List <string>()
            {
                @"bin\AzureFunctionsOpenAPIDemo.dll"
            },
                openApiDocumentVersion: "V1",
                filterSetVersion: FilterSetVersion.V1
                );

            input.OpenApiInfoDescription = "This is a sample description...";

            var generator        = new OpenApiGenerator();
            var openApiDocuments = generator.GenerateDocuments(
                openApiGeneratorConfig: input,
                generationDiagnostic: out GenerationDiagnostic result
                );

            return(new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(openApiDocuments.First().Value.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0), Encoding.UTF8, "application/json")
            });
        }
        public void InvalidDocumentationShouldYieldFailure(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            int expectedOperationGenerationResultsCount,
            string expectedJsonFile,
            DocumentGenerationDiagnostic expectedDocumentGenerationResult,
            IList <OperationGenerationDiagnostic> expectedFailureOperationGenerationResults)
        {
            _output.WriteLine(testCaseName);

            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));

            var input = new OpenApiGeneratorConfig(documents, inputBinaryFiles, "1.0.0", FilterSetVersion.V1);

            GenerationDiagnostic result;

            var generator = new OpenApiGenerator();

            var openApiDocuments = generator.GenerateDocuments(input, out result);

            openApiDocuments.Should().NotBeNull();

            result.DocumentGenerationDiagnostic.Should().BeEquivalentTo(expectedDocumentGenerationResult);
            result.OperationGenerationDiagnostics.Count.Should().Be(expectedOperationGenerationResultsCount);

            openApiDocuments[DocumentVariantInfo.Default].Should().NotBeNull();

            var failurePaths = result.OperationGenerationDiagnostics.Where(
                p => p.Errors.Count > 0)
                               .ToList();

            var actualDocument = openApiDocuments[DocumentVariantInfo.Default]
                                 .SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            var expectedDocument = File.ReadAllText(expectedJsonFile);


            _output.WriteLine(actualDocument);

            failurePaths.Should().BeEquivalentTo(expectedFailureOperationGenerationResults);

            // We are doing serialization and deserialization to force the resulting actual document
            // to have the exact fields we will see in the resulting document based on the contract resolver.
            // Without serialization and deserialization, the actual document may have fields that should
            // not be present, such as empty list fields.
            var openApiStringReader = new OpenApiStringReader();

            var actualDeserializedDocument = openApiStringReader.Read(
                actualDocument,
                out OpenApiDiagnostic diagnostic);

            diagnostic.Errors.Count.Should().Be(0);

            actualDeserializedDocument
            .Should()
            .BeEquivalentTo(openApiStringReader.Read(expectedDocument, out var _));
        }
Пример #5
0
        public void GenerateDocumentWithOperationConfigShouldSucceed(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            string configXmlFile,
            int expectedOperationGenerationResultsCount,
            string expectedJsonFile)
        {
            _output.WriteLine(testCaseName);

            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));
            var configDocument = XDocument.Load(configXmlFile);

            var generator = new OpenApiGenerator();
            var input     = new OpenApiGeneratorConfig(documents, inputBinaryFiles, "1.0.0", FilterSetVersion.V1)
            {
                AdvancedConfigurationXmlDocument = configDocument
            };

            GenerationDiagnostic result;

            var openApiDocuments = generator.GenerateDocuments(
                input,
                out result);

            result.Should().NotBeNull();
            result.DocumentGenerationDiagnostic.Errors.Count.Should().Be(0);
            openApiDocuments[DocumentVariantInfo.Default].Should().NotBeNull();
            result.OperationGenerationDiagnostics.Count.Should().Be(expectedOperationGenerationResultsCount);

            var actualDocument = openApiDocuments[DocumentVariantInfo.Default]
                                 .SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            var expectedDocument = File.ReadAllText(expectedJsonFile);

            _output.WriteLine(actualDocument);

            var openApiStringReader = new OpenApiStringReader();

            var actualDeserializedDocument = openApiStringReader.Read(
                actualDocument,
                out OpenApiDiagnostic diagnostic);

            diagnostic.Errors.Count.Should().Be(0);

            actualDeserializedDocument
            .Should()
            .BeEquivalentTo(
                openApiStringReader.Read(expectedDocument, out var _),
                o => o.WithStrictOrdering());
        }
        public void ValidDocumentationShouldReturnCorrectDocument(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            string openApiDocumentVersion,
            int expectedOperationGenerationResultsCount,
            string expectedJsonFile)
        {
            _output.WriteLine(testCaseName);

            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));

            var input = new OpenApiGeneratorConfig(
                documents,
                inputBinaryFiles,
                openApiDocumentVersion,
                FilterSetVersion.V1);

            GenerationDiagnostic result;

            var generator        = new OpenApiGenerator();
            var openApiDocuments = generator.GenerateDocuments(input, out result);

            result.Should().NotBeNull();

            result.DocumentGenerationDiagnostic.Errors.Count.Should().Be(0);

            openApiDocuments[DocumentVariantInfo.Default].Should().NotBeNull();

            result.OperationGenerationDiagnostics.Count(p => p.Errors.Count > 0).Should().Be(0);
            result.OperationGenerationDiagnostics.Count.Should().Be(expectedOperationGenerationResultsCount);

            var actualDocument = openApiDocuments[DocumentVariantInfo.Default]
                                 .SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            var expectedDocument = File.ReadAllText(expectedJsonFile);

            _output.WriteLine(actualDocument);

            var openApiStringReader = new OpenApiStringReader();

            var actualDeserializedDocument = openApiStringReader.Read(
                actualDocument,
                out OpenApiDiagnostic diagnostic);

            diagnostic.Errors.Count.Should().Be(0);

            actualDeserializedDocument
            .Should()
            .BeEquivalentTo(openApiStringReader.Read(expectedDocument, out var _));
        }
Пример #7
0
        public async Task <JObject> Get()
        {
            var reference = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            var g         = new OpenApiGenerator <BaseController, OrderCloudIntegrationsAuthAttribute>()
                            .CollectMetaData(Path.Combine(reference, "reference.md"), ErrorCodes.All)
                            .DefineSpec(new SwaggerConfig()
            {
                Name         = "Headstart",
                ContactEmail = "*****@*****.**",
                Description  = "Headstart API",
                Host         = _settings.EnvironmentSettings.MiddlewareBaseUrl,
                Title        = "Headstart API",
                Url          = "https://ordercloud.io",
                Version      = "1.0"
            });

            return(await Task.FromResult(g.Specification()));
        }
Пример #8
0
    private static OpenApiOperation?GetOperationForEndpoint(RouteEndpointBuilder routeEndpointBuilder)
    {
        var pattern         = routeEndpointBuilder.RoutePattern;
        var metadata        = new EndpointMetadataCollection(routeEndpointBuilder.Metadata);
        var methodInfo      = metadata.OfType <MethodInfo>().SingleOrDefault();
        var serviceProvider = routeEndpointBuilder.ServiceProvider;

        if (methodInfo == null || serviceProvider == null)
        {
            return(null);
        }

        var hostEnvironment          = serviceProvider.GetService <IHostEnvironment>();
        var serviceProviderIsService = serviceProvider.GetService <IServiceProviderIsService>();
        var generator = new OpenApiGenerator(hostEnvironment, serviceProviderIsService);

        return(generator.GetOpenApiOperation(methodInfo, metadata, pattern));
    }
        public void NoOperationsToParseShouldReturnEmptyDocument(string openApiDocumentVersion)
        {
            var path = Path.Combine(InputDirectory, "AnnotationNoOperationsToParse.xml");

            var document = XDocument.Load(path);

            var input = new OpenApiGeneratorConfig(
                new List <XDocument>()
            {
                document
            },
                new List <string>(),
                openApiDocumentVersion,
                FilterSetVersion.V1);

            GenerationDiagnostic result;

            var generator       = new OpenApiGenerator();
            var openApiDocument = generator.GenerateDocument(input, out result);

            result.Should().NotBeNull();
            openApiDocument.Should().BeNull();
            result.DocumentGenerationDiagnostic.Should()
            .BeEquivalentTo(
                new DocumentGenerationDiagnostic
            {
                Errors =
                {
                    new GenerationError
                    {
                        Message = SpecificationGenerationMessages.NoOperationElementFoundToParse,
                    }
                }
            }
                );
        }
Пример #10
0
    private static void AddAndConfigureOperationForEndpoint(EndpointBuilder endpointBuilder, Func<OpenApiOperation, OpenApiOperation>? configure = null)
    {
        foreach (var item in endpointBuilder.Metadata)
        {
            if (item is OpenApiOperation existingOperation)
            {
                if (configure is not null)
                {
                    var configuredOperation = configure(existingOperation);

                    if (!ReferenceEquals(configuredOperation, existingOperation))
                    {
                        endpointBuilder.Metadata.Remove(existingOperation);

                        // The only way configureOperation could be null here is if configureOperation violated it's signature and returned null.
                        // We could throw or something, removing the previous metadata seems fine.
                        if (configuredOperation is not null)
                        {
                            endpointBuilder.Metadata.Add(configuredOperation);
                        }
                    }
                }

                return;
            }
        }

        // We cannot generate an OpenApiOperation without routeEndpointBuilder.RoutePattern.
        if (endpointBuilder is not RouteEndpointBuilder routeEndpointBuilder)
        {
            return;
        }

        var pattern = routeEndpointBuilder.RoutePattern;
        var metadata = new EndpointMetadataCollection(routeEndpointBuilder.Metadata);
        var methodInfo = metadata.OfType<MethodInfo>().SingleOrDefault();

        if (methodInfo is null)
        {
            return;
        }

        var applicationServices = routeEndpointBuilder.ApplicationServices;
        var hostEnvironment = applicationServices.GetService<IHostEnvironment>();
        var serviceProviderIsService = applicationServices.GetService<IServiceProviderIsService>();
        var generator = new OpenApiGenerator(hostEnvironment, serviceProviderIsService);
        var newOperation = generator.GetOpenApiOperation(methodInfo, metadata, pattern);

        if (newOperation is not null)
        {
            if (configure is not null)
            {
                newOperation = configure(newOperation);
            }

            if (newOperation is not null)
            {
                routeEndpointBuilder.Metadata.Add(newOperation);
            }
        }
    }
        public void GenerateDocumentMultipleVariantsShouldSucceed(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            string configXmlFile,
            int expectedOperationGenerationResultsCount,
            IDictionary <DocumentVariantInfo, string> documentVariantInfoToExpectedJsonFileMap)
        {
            _output.WriteLine(testCaseName);

            // Arrange
            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));

            var configPath     = configXmlFile;
            var configDocument = XDocument.Load(configPath);

            var generator = new OpenApiGenerator();
            var input     = new OpenApiGeneratorConfig(documents, inputBinaryFiles, "1.0.0", FilterSetVersion.V1)
            {
                AdvancedConfigurationXmlDocument = configDocument
            };
            GenerationDiagnostic result;

            // Act
            var openApiDocuments = generator.GenerateDocuments(input, out result);

            result.Should().NotBeNull();
            result.DocumentGenerationDiagnostic.Errors.Count.Should().Be(0);
            result.OperationGenerationDiagnostics.Count(r => r.Errors.Count == 0)
            .Should()
            .Be(expectedOperationGenerationResultsCount);

            openApiDocuments.Keys.Should()
            .BeEquivalentTo(documentVariantInfoToExpectedJsonFileMap.Keys);

            var actualDocuments   = new List <OpenApiDocument>();
            var expectedDocuments = new List <OpenApiDocument>();

            foreach (var documentVariantInfoToExpectedJsonFile in documentVariantInfoToExpectedJsonFileMap)
            {
                // Verify each document variant against a json file content.
                var documentVariantInfo = documentVariantInfoToExpectedJsonFile.Key;
                var expectedJsonFile    = documentVariantInfoToExpectedJsonFile.Value;

                openApiDocuments.TryGetValue(documentVariantInfo, out var specificationDocument);

                var actualDocumentAsString = specificationDocument.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);

                _output.WriteLine(actualDocumentAsString);

                var openApiStringReader = new OpenApiStringReader();

                var actualDeserializedDocument = openApiStringReader.Read(
                    actualDocumentAsString,
                    out OpenApiDiagnostic diagnostic);

                diagnostic.Errors.Count.Should().Be(0);

                actualDeserializedDocument
                .Should()
                .BeEquivalentTo(openApiStringReader.Read(File.ReadAllText(expectedJsonFile), out var _));

                // Bug in fluent assertion method. Comparing the array of documents yields incorrect result.
                // Root cause unknown. This should be enabled once that bug is resolved.
                //actualDocuments.Add(actualDocument);

                //expectedDocuments.Add(expectedDocument);
            }

            //actualDocuments.Should().BeEquivalentTo(expectedDocuments);
        }
        public static IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "openapi")] HttpRequestMessage req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            var httpClient = new HttpClient()
            {
                BaseAddress = new Uri("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/")
            };

            //var openApiDocument = GenerateOpenApiDocument();
            var openApiInfo = new OpenApiInfo()
            {
                Title       = "ComplexOpenApiExample",
                Description = "A complex open api example",
                Version     = "1.0.0",
            };

            var restEndpoints = new List <RestEndpoint>()
            {
                new RestEndpoint()
                {
                    Path            = "/FetchOrders",
                    InputOperations = new List <InputOperation>()
                    {
                        new InputOperation()
                        {
                            OperationType  = OperationType.Get,
                            Description    = "Get an order",
                            ResponseValues = new List <ResponseValue>()
                            {
                                new ResponseValue()
                                {
                                    Name              = "200",
                                    Description       = "A good response",
                                    MediaType         = "application/json",
                                    ResponseModelType = typeof(Order),
                                    StatusCode        = HttpStatusCode.OK,
                                }
                            }
                        }
                    },
                    InputParameters = new List <InputParameter>()
                    {
                        new InputParameter()
                        {
                            Name              = "QueryString",
                            Description       = "A querystring",
                            ParameterLocation = ParameterLocation.Query,
                        }
                    },
                },
            };

            var responseValues = restEndpoints.SelectMany(re => re.InputOperations)
                                 .SelectMany(io => io.ResponseValues);

            var types = responseValues
                        .Select(rv => rv.ResponseModelType);

            var openApiGenerator = new OpenApiGenerator();
            var openApiDocument  = openApiGenerator.GenerateDocument(openApiInfo, restEndpoints, responseValues, types);
            var openApiString    = openApiDocument.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json);

            return(new OkObjectResult(openApiString));
        }
        public HttpResponseMessage GenerateSwagger([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log, ExecutionContext ctx)
        {
            try
            {
                log.LogInformation("Starting Swagger Retrieval");

                var documentPath = Path.GetFullPath(Path.Combine(ctx.FunctionAppDirectory, $"{FunctionConstants.FunctionName}.xml"));
                var binaryPath   = Path.GetFullPath(Path.Combine(ctx.FunctionAppDirectory, $"bin\\{FunctionConstants.FunctionName}.dll"));

                log.LogDebug($"Looking for Documentation : {documentPath}");
                log.LogDebug($"Looking for Binary : {binaryPath}");

                var input = new OpenApiGeneratorConfig(
                    annotationXmlDocuments: new List <XDocument>()
                {
                    XDocument.Load(documentPath),
                },
                    assemblyPaths: new List <string>()
                {
                    binaryPath
                },
                    openApiDocumentVersion: "V1",
                    filterSetVersion: FilterSetVersion.V1
                    );
                input.OpenApiInfoDescription = _options.ServiceDescription ?? FunctionConstants.FunctionName;

                var generator        = new OpenApiGenerator();
                var openApiDocuments = generator.GenerateDocuments(
                    openApiGeneratorConfig: input,
                    generationDiagnostic: out GenerationDiagnostic result
                    );

                OpenApiSpecVersion openApiVersion;

                switch (_options.OpenApiVersion)
                {
                default:
                    openApiVersion = OpenApiSpecVersion.OpenApi2_0;
                    break;

                case "V3":
                    openApiVersion = OpenApiSpecVersion.OpenApi3_0;
                    break;
                }

                //switch the hostname for current known
                var definition = openApiDocuments.First().Value;
                definition.Info.Title = _options.ServiceTitle ?? FunctionConstants.FunctionName;

                if (definition.Servers.Any())
                {
                    var hostname = $"https://{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME")}";

                    //string hostname = "";
                    //bool.TryParse(Environment.GetEnvironmentVariable("HTTPS"), out bool sslOn);

                    //if (sslOn)
                    //{
                    //    hostname = $"https://{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME")}";
                    //}
                    //else
                    //    hostname = $"http://{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME")}";

                    log.LogInformation($"Server Name Switch : Swapping [{definition.Servers.First().Url}] for [{hostname}]");
                    definition.Servers.First().Url = hostname;
                }

                return(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(definition.SerializeAsJson(openApiVersion), Encoding.UTF8, "application/json")
                });
            }
            catch (Exception ex)
            {
                log.LogCritical("Exception Encountered", ex);
                throw;
            }
        }