Ejemplo n.º 1
0
        private void WriteValueRecursive(OpenApiYamlWriter writer, object value)
        {
            if (value == null ||
                value.GetType().IsPrimitive ||
                value is decimal ||
                value is string ||
                value is DateTimeOffset ||
                value is DateTime)
            {
                writer.WriteValue(value);
            }
            else if (value.GetType().IsGenericType&&
                     (typeof(IDictionary <,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition()) ||
                      typeof(Dictionary <,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition())))
            {
                writer.WriteStartObject();
                foreach (var elementValue in (dynamic)(value))
                {
                    writer.WritePropertyName(elementValue.Key);
                    WriteValueRecursive(writer, elementValue.Value);
                }

                writer.WriteEndObject();
            }
            else if (typeof(IEnumerable).IsAssignableFrom(value.GetType()))
            {
                writer.WriteStartArray();
                foreach (var elementValue in (IEnumerable)value)
                {
                    WriteValueRecursive(writer, elementValue);
                }

                writer.WriteEndArray();
            }
        }
Ejemplo n.º 2
0
        private static IActionResult CreateResult(string openApiVersion, OpenApiDocument subset, string format)
        {
            var sr = new StringWriter();
            OpenApiWriterBase writer;

            if (format == "yaml")
            {
                writer = new OpenApiYamlWriter(sr);
            }
            else
            {
                writer = new OpenApiJsonWriter(sr);
            }

            if (openApiVersion == "2")
            {
                subset.SerializeAsV2(writer);
            }
            else
            {
                subset.SerializeAsV3(writer);
            }
            var output = sr.GetStringBuilder().ToString();

            return(new ContentResult()
            {
                Content = output,
                ContentType = "application/json"
            });
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Create a representation of the OpenApiDocument to return from an API
        /// </summary>
        /// <param name="subset">OpenAPI document</param>
        /// <param name="openApiVersion"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static MemoryStream SerializeOpenApiDocument(OpenApiDocument subset, string openApiVersion, string format)
        {
            var stream = new MemoryStream();
            var sr     = new StreamWriter(stream);
            OpenApiWriterBase writer;

            if (format == "yaml")
            {
                writer = new OpenApiYamlWriter(sr);
            }
            else
            {
                writer = new OpenApiJsonWriter(sr);
            }

            if (openApiVersion == "2")
            {
                subset.SerializeAsV2(writer);
            }
            else
            {
                subset.SerializeAsV3(writer);
            }
            sr.Flush();
            stream.Position = 0;
            return(stream);
        }
        /// <summary>
        /// Serializes the <see cref="IOpenApiSerializable"/> to the Open API document using
        /// the given stream, specification version and the format.
        /// </summary>
        /// <typeparam name="T">the <see cref="IOpenApiSerializable"/></typeparam>
        /// <param name="element">The Open API element.</param>
        /// <param name="stream">The given stream.</param>
        /// <param name="specVersion">The Open API specification version.</param>
        /// <param name="format">The output format (JSON or YAML).</param>
        public static void Serialize <T>(
            this T element,
            Stream stream,
            OpenApiSpecVersion specVersion,
            OpenApiFormat format)
            where T : IOpenApiSerializable
        {
            if (stream == null)
            {
                throw Error.ArgumentNull(nameof(stream));
            }

            IOpenApiWriter writer;

            switch (format)
            {
            case OpenApiFormat.Json:
                writer = new OpenApiJsonWriter(new StreamWriter(stream));
                break;

            case OpenApiFormat.Yaml:
                writer = new OpenApiYamlWriter(new StreamWriter(stream));
                break;

            default:
                throw new OpenApiException(string.Format(SRResource.OpenApiFormatNotSupported, format));
            }

            element.Serialize(writer, specVersion);
        }
Ejemplo n.º 5
0
        public void WriteInlineSchemaV2()
        {
            var doc = CreateDocWithSimpleSchemaToInline();

            var expected =
                @"swagger: '2.0'
info:
  title: Demo
  version: 1.0.0
paths:
  /:
    get:
      produces:
        - application/json
      responses:
        '200':
          description: OK
          schema:
            type: object";

            var outputString = new StringWriter(CultureInfo.InvariantCulture);
            var writer       = new OpenApiYamlWriter(outputString, new OpenApiWriterSettings {
                ReferenceInline = ReferenceInlineSetting.InlineLocalReferences
            });

            // Act
            doc.SerializeAsV2(writer);
            var actual = outputString.GetStringBuilder().ToString();

            // Assert
            actual   = actual.MakeLineBreaksEnvironmentNeutral();
            expected = expected.MakeLineBreaksEnvironmentNeutral();
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 6
0
        public void WriteStringListAsYamlShouldMatchExpected(string[] stringValues, string expectedYaml)
        {
            // Arrange
            var outputString = new StringWriter(CultureInfo.InvariantCulture);
            var writer       = new OpenApiYamlWriter(outputString);

            // Act
            writer.WriteStartArray();
            foreach (var stringValue in stringValues)
            {
                writer.WriteValue(stringValue);
            }

            writer.WriteEndArray();
            writer.Flush();

            var actualYaml = outputString.GetStringBuilder()
                             .ToString()
                             .MakeLineBreaksEnvironmentNeutral();

            expectedYaml = expectedYaml.MakeLineBreaksEnvironmentNeutral();

            // Assert
            actualYaml.Should().Be(expectedYaml);
        }
        public static string GetValueString(this IOpenApiPrimitive primitive)
        {
            using var sb = new StringWriter();
            var writer = new OpenApiYamlWriter(sb);

            primitive.Write(writer, OpenApiSpecVersion.OpenApi3_0);
            return(sb.ToString());
        }
Ejemplo n.º 8
0
        public string AsYaml(OpenApiDocument document)
        {
            StringWriter      writer     = new StringWriter();
            OpenApiYamlWriter yamlWriter = new OpenApiYamlWriter(writer);

            document.SerializeAsV3(yamlWriter);
            return(writer.ToString());
        }
Ejemplo n.º 9
0
        public void WriteInlineRecursiveSchema()
        {
            // Arrange
            var doc = CreateDocWithRecursiveSchemaReference();

            var expected =
                @"openapi: 3.0.1
info:
  title: Demo
  version: 1.0.0
paths:
  /:
    get:
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  children:
                    $ref: '#/components/schemas/thing'
                  related:
                    type: integer
components:
  schemas:
    thing:
      type: object
      properties:
        children:
          type: object
          properties:
            children:
              $ref: '#/components/schemas/thing'
            related:
              type: integer
        related:
          type: integer";
            // Component schemas that are there due to cycles are still inlined because the items they reference may not exist in the components because they don't have cycles.

            var outputString = new StringWriter(CultureInfo.InvariantCulture);
            var writer       = new OpenApiYamlWriter(outputString, new OpenApiWriterSettings {
                ReferenceInline = ReferenceInlineSetting.InlineLocalReferences
            });

            // Act
            doc.SerializeAsV3(writer);
            var actual = outputString.GetStringBuilder().ToString();

            // Assert
            actual   = actual.MakeLineBreaksEnvironmentNeutral();
            expected = expected.MakeLineBreaksEnvironmentNeutral();
            Assert.Equal(expected, actual);
        }
        private static string Write(Action <OpenApiYamlWriter> action)
        {
            MemoryStream      stream = new MemoryStream();
            OpenApiYamlWriter writer = new OpenApiYamlWriter(new StreamWriter(stream));

            action(writer);

            writer.Flush();
            stream.Position = 0;
            return(new StreamReader(stream).ReadToEnd());
        }
Ejemplo n.º 11
0
        private static OpenApiDocument Clone(OpenApiDocument subsetOpenApiDocument)
        {
            var stream = new MemoryStream();
            var writer = new OpenApiYamlWriter(new StreamWriter(stream));

            subsetOpenApiDocument.SerializeAsV3(writer);
            writer.Flush();
            stream.Position = 0;
            var reader = new OpenApiStreamReader();

            return(reader.Read(stream, out OpenApiDiagnostic diag));
        }
Ejemplo n.º 12
0
        private static void CreateOpenApiDocument(IEnumerable <ApiMethod> identifiedMethods, string filepath)
        {
            var fi = new FileInfo(filepath);

            Console.WriteLine($"Creating OpenAPI document at {fi.FullName}…");
            var document   = CreateOpenApiDocument(identifiedMethods);
            var targetYaml = File.CreateText(fi.FullName);
            var w          = new OpenApiYamlWriter(targetYaml);

            document.SerializeAsV3(w);
            targetYaml.Flush();
        }
Ejemplo n.º 13
0
        public RestResponse OpenApiYaml()
        {
            var doc          = GetAPIDoc();
            var outputString = new StringWriter(CultureInfo.InvariantCulture);
            var writer       = new OpenApiYamlWriter(outputString);

            doc.SerializeAsV3(writer);

            return(new RestResponse()
            {
                Content = Encoding.UTF8.GetBytes(outputString.ToString()), ContentType = "text/yaml"
            });
        }
Ejemplo n.º 14
0
        public void WriteStringWithSpecialCharactersAsYamlWorks(string input, string expected)
        {
            // Arrange
            var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
            var writer             = new OpenApiYamlWriter(outputStringWriter);

            // Act
            writer.WriteValue(input);
            var actual = outputStringWriter.GetStringBuilder().ToString();

            // Assert
            actual.Should().Be(expected);
        }
        public void CanWriterYaml()
        {
            OpenApiDocument doc = new OpenApiDocument();

            var            builder = new StringBuilder();
            StringWriter   sw      = new StringWriter(builder);
            IOpenApiWriter writer  = new OpenApiYamlWriter(sw, new OpenApiWriterSettings());

            doc.Write(writer);

            sw.Flush();

            output.WriteLine(sw.ToString());
        }
Ejemplo n.º 16
0
        public void WriteDateTimeAsJsonShouldMatchExpected(DateTimeOffset dateTimeOffset)
        {
            // Arrange
            var outputString = new StringWriter(CultureInfo.InvariantCulture);
            var writer       = new OpenApiYamlWriter(outputString);

            // Act
            writer.WriteValue(dateTimeOffset);

            var writtenString  = outputString.GetStringBuilder().ToString();
            var expectedString = " '" + dateTimeOffset.ToString("o") + "'";

            // Assert
            writtenString.Should().Be(expectedString);
        }
Ejemplo n.º 17
0
        public void WriteMapAsYamlShouldMatchExpected(IDictionary <string, object> inputMap, string expectedYaml)
        {
            // Arrange
            var outputString = new StringWriter(CultureInfo.InvariantCulture);
            var writer       = new OpenApiYamlWriter(outputString);

            // Act
            WriteValueRecursive(writer, inputMap);
            var actualYaml = outputString.ToString();

            // Assert
            actualYaml   = actualYaml.MakeLineBreaksEnvironmentNeutral();
            expectedYaml = expectedYaml.MakeLineBreaksEnvironmentNeutral();
            actualYaml.Should().Be(expectedYaml);
        }
Ejemplo n.º 18
0
        public void SerializeBasicTagAsV3YamlWithoutReferenceWorks()
        {
            // Arrange
            var outputStringWriter = new StringWriter();
            var writer             = new OpenApiYamlWriter(outputStringWriter);
            var expected           = "{ }";

            // Act
            BasicTag.SerializeAsV3WithoutReference(writer);
            var actual = outputStringWriter.GetStringBuilder().ToString();

            // Assert
            actual   = actual.MakeLineBreaksEnvironmentNeutral();
            expected = expected.MakeLineBreaksEnvironmentNeutral();
            actual.Should().Be(expected);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Create a representation of the OpenApiDocument to return from an API
        /// </summary>
        /// <param name="subset">OpenAPI document.</param>
        /// <param name="styleOptions">The modal object containing the required styling options.</param>
        /// <returns>A memory stream.</returns>
        public static MemoryStream SerializeOpenApiDocument(OpenApiDocument subset, OpenApiStyleOptions styleOptions)
        {
            var stream = new MemoryStream();
            var sr     = new StreamWriter(stream);
            OpenApiWriterBase writer;

            if (styleOptions.OpenApiFormat == Constants.OpenApiConstants.Format_Yaml)
            {
                if (styleOptions.InlineLocalReferences)
                {
                    writer = new OpenApiYamlWriter(sr,
                                                   new OpenApiWriterSettings {
                        ReferenceInline = ReferenceInlineSetting.InlineLocalReferences
                    });
                }
                else
                {
                    writer = new OpenApiYamlWriter(sr);
                }
            }
            else // json
            {
                if (styleOptions.InlineLocalReferences)
                {
                    writer = new OpenApiJsonWriter(sr,
                                                   new OpenApiWriterSettings {
                        ReferenceInline = ReferenceInlineSetting.InlineLocalReferences
                    });
                }
                else
                {
                    writer = new OpenApiJsonWriter(sr);
                }
            }

            if (styleOptions.OpenApiVersion == Constants.OpenApiConstants.OpenApiVersion_2)
            {
                subset.SerializeAsV2(writer);
            }
            else
            {
                subset.SerializeAsV3(writer);
            }
            sr.Flush();
            stream.Position = 0;
            return(stream);
        }
        /// <summary>
        /// Create a representation of the OpenApiDocument to return from an API
        /// </summary>
        /// <param name="subset">OpenAPI document</param>
        /// <param name="openApiVersion"></param>
        /// <param name="format">The format of the OpenAPI doc.</param>
        /// <param name="style">The styling preference of the OpenAPI doc.</param>
        /// <returns></returns>
        public static MemoryStream SerializeOpenApiDocument(OpenApiDocument subset, string openApiVersion, string format, OpenApiStyle style)
        {
            var stream = new MemoryStream();
            var sr     = new StreamWriter(stream);
            OpenApiWriterBase writer;

            if (format == "yaml")
            {
                if (style == OpenApiStyle.PowerPlatform)
                {
                    writer = new OpenApiYamlWriter(sr,
                                                   new OpenApiWriterSettings {
                        ReferenceInline = ReferenceInlineSetting.InlineLocalReferences
                    });
                }
                else
                {
                    writer = new OpenApiYamlWriter(sr);
                }
            }
            else
            {
                if (style == OpenApiStyle.PowerPlatform)
                {
                    writer = new OpenApiJsonWriter(sr,
                                                   new OpenApiWriterSettings {
                        ReferenceInline = ReferenceInlineSetting.InlineLocalReferences
                    });
                }
                else
                {
                    writer = new OpenApiJsonWriter(sr);
                }
            }

            if (openApiVersion == "2")
            {
                subset.SerializeAsV2(writer);
            }
            else
            {
                subset.SerializeAsV3(writer);
            }
            sr.Flush();
            stream.Position = 0;
            return(stream);
        }
Ejemplo n.º 21
0
        public void SerializeReferencedTagAsV2YamlWorks()
        {
            // Arrange
            var outputStringWriter = new StringWriter();
            var writer             = new OpenApiYamlWriter(outputStringWriter);

            var expected = @" pet";

            // Act
            ReferencedTag.SerializeAsV2(writer);
            writer.Flush();
            var actual = outputStringWriter.GetStringBuilder().ToString();

            // Assert
            actual   = actual.MakeLineBreaksEnvironmentNeutral();
            expected = expected.MakeLineBreaksEnvironmentNeutral();
            actual.Should().Be(expected);
        }
Ejemplo n.º 22
0
        internal static string Write(OpenApiTarget target, Action <IOpenApiWriter> action)
        {
            MemoryStream   stream = new MemoryStream();
            IOpenApiWriter writer;

            if (target == OpenApiTarget.Yaml)
            {
                writer = new OpenApiYamlWriter(new StreamWriter(stream));
            }
            else
            {
                writer = new OpenApiJsonWriter(new StreamWriter(stream));
            }

            action(writer);
            writer.Flush();
            stream.Position = 0;
            return(new StreamReader(stream).ReadToEnd());
        }
Ejemplo n.º 23
0
        public void WriteStringWithNewlineCharactersInArrayAsYamlWorks(string input, string expected)
        {
            // Arrange
            var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
            var writer             = new OpenApiYamlWriter(outputStringWriter)
            {
                UseLiteralStyle = true,
            };

            // Act
            writer.WriteStartArray();
            writer.WriteValue(input);
            var actual = outputStringWriter.GetStringBuilder().ToString()
                         // Normalize newline for cross platform
                         .Replace("\r", "");

            // Assert
            actual.Should().Be(expected);
        }
        private async Task RespondWithSwaggerYaml(HttpResponse response, OpenApiDocument swagger)
        {
            response.StatusCode  = 200;
            response.ContentType = "text/yaml;charset=utf-8";

            using (var textWriter = new StringWriter(CultureInfo.InvariantCulture))
            {
                var yamlWriter = new OpenApiYamlWriter(textWriter);
                if (_options.SerializeAsV2)
                {
                    swagger.SerializeAsV2(yamlWriter);
                }
                else
                {
                    swagger.SerializeAsV3(yamlWriter);
                }

                await response.WriteAsync(textWriter.ToString(), new UTF8Encoding(false));
            }
        }
Ejemplo n.º 25
0
        public void SerializeAdvancedTagAsV2YamlWithoutReferenceWorks()
        {
            // Arrange
            var outputStringWriter = new StringWriter();
            var writer             = new OpenApiYamlWriter(outputStringWriter);
            var expected           =
                @"name: pet
description: Pets operations
externalDocs:
  description: Find more info here
  url: https://example.com
x-tag-extension: ";

            // Act
            AdvancedTag.SerializeAsV2WithoutReference(writer);
            writer.Flush();
            var actual = outputStringWriter.GetStringBuilder().ToString();

            // Assert
            actual   = actual.MakeLineBreaksEnvironmentNeutral();
            expected = expected.MakeLineBreaksEnvironmentNeutral();
            actual.Should().Be(expected);
        }
Ejemplo n.º 26
0
        static int Main(string[] args)
        {
            // Helper to simplify command line parsing etc.
            var runner = new CommandRunner("dotnet swagger", "Swashbuckle (Swagger) Command Line Tools", Console.Out);

            // NOTE: The "dotnet swagger tofile" command does not serve the request directly. Instead, it invokes a corresponding
            // command (called _tofile) via "dotnet exec" so that the runtime configuration (*.runtimeconfig & *.deps.json) of the
            // provided startupassembly can be used instead of the tool's. This is neccessary to successfully load the
            // startupassembly and it's transitive dependencies. See https://github.com/dotnet/coreclr/issues/13277 for more.

            // > dotnet swagger tofile ...
            runner.SubCommand("tofile", "retrieves Swagger from a startup assembly, and writes to file ", c =>
            {
                c.Argument("startupassembly", "relative path to the application's startup assembly");
                c.Argument("swaggerdoc", "name of the swagger doc you want to retrieve, as configured in your startup class");
                c.Option("--output", "relative path where the Swagger will be output, defaults to stdout");
                c.Option("--host", "a specific host to include in the Swagger output");
                c.Option("--basepath", "a specific basePath to include in the Swagger output");
                c.Option("--serializeasv2", "output Swagger in the V2 format rather than V3", true);
                c.Option("--yaml", "exports swagger in a yaml format", true);
                c.OnRun((namedArgs) =>
                {
                    var depsFile      = namedArgs["startupassembly"].Replace(".dll", ".deps.json");
                    var runtimeConfig = namedArgs["startupassembly"].Replace(".dll", ".runtimeconfig.json");

                    var subProcess = Process.Start("dotnet", string.Format(
                                                       "exec --depsfile {0} --runtimeconfig {1} {2} _{3}", // note the underscore
                                                       EscapePath(depsFile),
                                                       EscapePath(runtimeConfig),
                                                       EscapePath(typeof(Program).GetTypeInfo().Assembly.Location),
                                                       string.Join(" ", args)
                                                       ));

                    subProcess.WaitForExit();
                    return(subProcess.ExitCode);
                });
            });

            // > dotnet swagger _tofile ... (* should only be invoked via "dotnet exec")
            runner.SubCommand("_tofile", "", c =>
            {
                c.Argument("startupassembly", "");
                c.Argument("swaggerdoc", "");
                c.Option("--output", "");
                c.Option("--host", "");
                c.Option("--basepath", "");
                c.Option("--serializeasv2", "", true);
                c.Option("--yaml", "", true);
                c.OnRun((namedArgs) =>
                {
                    // 1) Configure host with provided startupassembly
                    var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(
                        Path.Combine(Directory.GetCurrentDirectory(), namedArgs["startupassembly"]));

                    // 2) Build a web host to serve the request
                    var serviceProvider = GetServiceProvider(startupAssembly);

                    // 3) Retrieve Swagger via configured provider
                    var swaggerProvider = serviceProvider.GetRequiredService <ISwaggerProvider>();
                    var swagger         = swaggerProvider.GetSwagger(
                        namedArgs["swaggerdoc"],
                        namedArgs.ContainsKey("--host") ? namedArgs["--host"] : null,
                        namedArgs.ContainsKey("--basepath") ? namedArgs["--basepath"] : null);

                    // 4) Serialize to specified output location or stdout
                    var outputPath = namedArgs.ContainsKey("--output")
                        ? Path.Combine(Directory.GetCurrentDirectory(), namedArgs["--output"])
                        : null;

                    using (var streamWriter = (outputPath != null ? File.CreateText(outputPath) : Console.Out))
                    {
                        IOpenApiWriter writer;
                        if (namedArgs.ContainsKey("--yaml"))
                        {
                            writer = new OpenApiYamlWriter(streamWriter);
                        }
                        else
                        {
                            writer = new OpenApiJsonWriter(streamWriter);
                        }

                        if (namedArgs.ContainsKey("--serializeasv2"))
                        {
                            swagger.SerializeAsV2(writer);
                        }
                        else
                        {
                            swagger.SerializeAsV3(writer);
                        }

                        if (outputPath != null)
                        {
                            Console.WriteLine($"Swagger JSON/YAML succesfully written to {outputPath}");
                        }
                    }

                    return(0);
                });
            });

            return(runner.Run(args));
        }
Ejemplo n.º 27
0
        public static void ProcessOpenApiDocument(
            FileInfo input,
            FileInfo output,
            OpenApiSpecVersion version,
            OpenApiFormat format,
            bool inline)
        {
            OpenApiDocument document;

            using (Stream stream = input.OpenRead())
            {
                document = new OpenApiStreamReader(new OpenApiReaderSettings
                {
                    ReferenceResolution = ReferenceResolutionSetting.ResolveLocalReferences,
                    RuleSet             = ValidationRuleSet.GetDefaultRuleSet()
                }
                                                   ).Read(stream, out var context);
                if (context.Errors.Count != 0)
                {
                    var errorReport = new StringBuilder();

                    foreach (var error in context.Errors)
                    {
                        errorReport.AppendLine(error.ToString());
                    }

                    throw new ArgumentException(String.Join(Environment.NewLine, context.Errors.Select(e => e.Message).ToArray()));
                }
            }

            using (var outputStream = output?.Create())
            {
                TextWriter textWriter;

                if (outputStream != null)
                {
                    textWriter = new StreamWriter(outputStream);
                }
                else
                {
                    textWriter = Console.Out;
                }

                var settings = new OpenApiWriterSettings()
                {
                    ReferenceInline = inline == true ? ReferenceInlineSetting.InlineLocalReferences : ReferenceInlineSetting.DoNotInlineReferences
                };
                IOpenApiWriter writer;
                switch (format)
                {
                case OpenApiFormat.Json:
                    writer = new OpenApiJsonWriter(textWriter, settings);
                    break;

                case OpenApiFormat.Yaml:
                    writer = new OpenApiYamlWriter(textWriter, settings);
                    break;

                default:
                    throw new ArgumentException("Unknown format");
                }

                document.Serialize(writer, version);

                textWriter.Flush();
            }
        }