Ejemplo n.º 1
0
        /// <summary>
        /// Serialize to OpenAPI V3 document without using reference.
        /// </summary>
        public void SerializeAsV3WithoutReference(IOpenApiWriter writer)
        {
            writer.WriteStartObject();

            // title
            writer.WriteProperty(OpenApiConstants.Title, Title);

            // multipleOf
            writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf);

            // maximum
            writer.WriteProperty(OpenApiConstants.Maximum, Maximum);

            // exclusiveMaximum
            writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum);

            // minimum
            writer.WriteProperty(OpenApiConstants.Minimum, Minimum);

            // exclusiveMinimum
            writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum);

            // maxLength
            writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength);

            // minLength
            writer.WriteProperty(OpenApiConstants.MinLength, MinLength);

            // pattern
            writer.WriteProperty(OpenApiConstants.Pattern, Pattern);

            // maxItems
            writer.WriteProperty(OpenApiConstants.MaxItems, MaxItems);

            // minItems
            writer.WriteProperty(OpenApiConstants.MinItems, MinItems);

            // uniqueItems
            writer.WriteProperty(OpenApiConstants.UniqueItems, UniqueItems);

            // maxProperties
            writer.WriteProperty(OpenApiConstants.MaxProperties, MaxProperties);

            // minProperties
            writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties);

            // required
            writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => w.WriteValue(s));

            // enum
            writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (nodeWriter, s) => nodeWriter.WriteAny(s));

            // type
            writer.WriteProperty(OpenApiConstants.Type, Type);

            // allOf
            writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, (w, s) => s.SerializeAsV3(w));

            // anyOf
            writer.WriteOptionalCollection(OpenApiConstants.AnyOf, AnyOf, (w, s) => s.SerializeAsV3(w));

            // oneOf
            writer.WriteOptionalCollection(OpenApiConstants.OneOf, OneOf, (w, s) => s.SerializeAsV3(w));

            // not
            writer.WriteOptionalObject(OpenApiConstants.Not, Not, (w, s) => s.SerializeAsV3(w));

            // items
            writer.WriteOptionalObject(OpenApiConstants.Items, Items, (w, s) => s.SerializeAsV3(w));

            // properties
            writer.WriteOptionalMap(OpenApiConstants.Properties, Properties, (w, s) => s.SerializeAsV3(w));

            // additionalProperties
            writer.WriteOptionalObject(
                OpenApiConstants.AdditionalProperties,
                AdditionalProperties,
                (w, s) => s.SerializeAsV3(w));

            // description
            writer.WriteProperty(OpenApiConstants.Description, Description);

            // format
            writer.WriteProperty(OpenApiConstants.Format, Format);

            // default
            writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d));

            // nullable
            writer.WriteProperty(OpenApiConstants.Nullable, Nullable, false);

            // discriminator
            writer.WriteOptionalObject(OpenApiConstants.Discriminator, Discriminator, (w, s) => s.SerializeAsV3(w));

            // readOnly
            writer.WriteProperty(OpenApiConstants.ReadOnly, ReadOnly, false);

            // writeOnly
            writer.WriteProperty(OpenApiConstants.WriteOnly, WriteOnly, false);

            // xml
            writer.WriteOptionalObject(OpenApiConstants.Xml, Xml, (w, s) => s.SerializeAsV2(w));

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, s) => s.SerializeAsV3(w));

            // example
            writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e));

            // deprecated
            writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false);

            // extensions
            writer.WriteExtensions(Extensions);

            writer.WriteEndObject();
        }
 /// <summary>
 /// Writes an optional Open API object.
 /// </summary>
 /// <typeparam name="T">The Open API element type. <see cref="IOpenApiElement"/></typeparam>
 /// <param name="writer">The Open API writer.</param>
 /// <param name="name">The property name.</param>
 /// <param name="value">The property value.</param>
 /// <param name="specVersion">The OpenAPI Spec version.</param>
 public static void WriteOptionalObject <T>(this IOpenApiWriter writer, string name, T?value, OpenApiSpecVersion specVersion)
     where T : class, IOpenApiSerializable
 => writer.WriteOptionalObject(name, value, (w, v) => v.Serialize(w, specVersion));
Ejemplo n.º 3
0
 /// <summary>
 /// Serialize <see cref="OpenApiLicense"/> to Open Api v2.0
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     WriteInternal(writer, OpenApiSpecVersion.OpenApi2_0);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Serialize <see cref="OpenApiDocument"/> to OpenAPI object V2.0.
        /// </summary>
        public void SerializeAsV2(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            writer.WriteStartObject();

            // swagger
            writer.WriteProperty(OpenApiConstants.Swagger, "2.0");

            // info
            writer.WriteRequiredObject(OpenApiConstants.Info, Info, (w, i) => i.SerializeAsV2(w));

            // host, basePath, schemes, consumes, produces
            WriteHostInfoV2(writer, Servers);

            // paths
            writer.WriteRequiredObject(OpenApiConstants.Paths, Paths, (w, p) => p.SerializeAsV2(w));

            // If references have been inlined we don't need the to render the components section
            // however if they have cycles, then we will need a component rendered
            if (writer.GetSettings().ReferenceInline != ReferenceInlineSetting.DoNotInlineReferences)
            {
                var loops = writer.GetSettings().LoopDetector.Loops;

                if (loops.TryGetValue(typeof(OpenApiSchema), out List <object> schemas))
                {
                    var openApiSchemas = schemas.Cast <OpenApiSchema>().Distinct().ToList()
                                         .ToDictionary <OpenApiSchema, string>(k => k.Reference.Id);

                    foreach (var schema in openApiSchemas.Values.ToList())
                    {
                        FindSchemaReferences.ResolveSchemas(Components, openApiSchemas);
                    }

                    writer.WriteOptionalMap(
                        OpenApiConstants.Definitions,
                        openApiSchemas,
                        (w, key, component) =>
                    {
                        component.SerializeAsV2WithoutReference(w);
                    });
                }
            }
            else
            {
                // Serialize each referenceable object as full object without reference if the reference in the object points to itself.
                // If the reference exists but points to other objects, the object is serialized to just that reference.
                // definitions
                writer.WriteOptionalMap(
                    OpenApiConstants.Definitions,
                    Components?.Schemas,
                    (w, key, component) =>
                {
                    if (component.Reference != null &&
                        component.Reference.Type == ReferenceType.Schema &&
                        component.Reference.Id == key)
                    {
                        component.SerializeAsV2WithoutReference(w);
                    }
                    else
                    {
                        component.SerializeAsV2(w);
                    }
                });
            }
            // parameters
            writer.WriteOptionalMap(
                OpenApiConstants.Parameters,
                Components?.Parameters,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Parameter &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // responses
            writer.WriteOptionalMap(
                OpenApiConstants.Responses,
                Components?.Responses,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Response &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // securityDefinitions
            writer.WriteOptionalMap(
                OpenApiConstants.SecurityDefinitions,
                Components?.SecuritySchemes,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.SecurityScheme &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // security
            writer.WriteOptionalCollection(
                OpenApiConstants.Security,
                SecurityRequirements,
                (w, s) => s.SerializeAsV2(w));

            // tags
            writer.WriteOptionalCollection(OpenApiConstants.Tags, Tags, (w, t) => t.SerializeAsV2WithoutReference(w));

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w));

            // extensions
            writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0);

            writer.WriteEndObject();
        }
        /// <summary>
        /// Serialize <see cref="OpenApiOperation"/> to Open Api v2.0.
        /// </summary>
        public void SerializeAsV2(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            writer.WriteStartObject();

            // tags
            writer.WriteOptionalCollection(
                OpenApiConstants.Tags,
                Tags,
                (w, t) =>
            {
                t.SerializeAsV2(w);
            });

            // summary
            writer.WriteProperty(OpenApiConstants.Summary, Summary);

            // description
            writer.WriteProperty(OpenApiConstants.Description, Description);

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w));

            // operationId
            writer.WriteProperty(OpenApiConstants.OperationId, OperationId);

            IList <OpenApiParameter> parameters;

            if (Parameters == null)
            {
                parameters = new List <OpenApiParameter>();
            }
            else
            {
                parameters = new List <OpenApiParameter>(Parameters);
            }

            if (RequestBody != null)
            {
                // consumes
                writer.WritePropertyName(OpenApiConstants.Consumes);
                writer.WriteStartArray();
                var consumes = RequestBody.Content.Keys.Distinct().ToList();
                foreach (var mediaType in consumes)
                {
                    writer.WriteValue(mediaType);
                }

                writer.WriteEndArray();

                // This is form data. We need to split the request body into multiple parameters.
                if (consumes.Contains("application/x-www-form-urlencoded") ||
                    consumes.Contains("multipart/form-data"))
                {
                    foreach (var property in RequestBody.Content.First().Value.Schema.Properties)
                    {
                        parameters.Add(
                            new OpenApiFormDataParameter
                        {
                            Description = property.Value.Description,
                            Name        = property.Key,
                            Schema      = property.Value,
                            Required    = RequestBody.Content.First().Value.Schema.Required.Contains(property.Key)
                        });
                    }
                }
                else
                {
                    var content       = RequestBody.Content.Values.FirstOrDefault();
                    var bodyParameter = new OpenApiBodyParameter
                    {
                        Description = RequestBody.Description,
                        // V2 spec actually allows the body to have custom name.
                        // Our library does not support this at the moment.
                        Name     = "body",
                        Schema   = content?.Schema ?? new OpenApiSchema(),
                        Required = RequestBody.Required
                    };

                    parameters.Add(bodyParameter);
                }
            }

            if (Responses != null)
            {
                var produces = Responses.Where(r => r.Value.Content != null)
                               .SelectMany(r => r.Value.Content?.Keys)
                               .Distinct()
                               .ToList();

                if (produces.Any())
                {
                    // produces
                    writer.WritePropertyName(OpenApiConstants.Produces);
                    writer.WriteStartArray();
                    foreach (var mediaType in produces)
                    {
                        writer.WriteValue(mediaType);
                    }

                    writer.WriteEndArray();
                }
            }

            // parameters
            // Use the parameters created locally to include request body if exists.
            writer.WriteOptionalCollection(OpenApiConstants.Parameters, parameters, (w, p) => p.SerializeAsV2(w));

            // responses
            writer.WriteRequiredObject(OpenApiConstants.Responses, Responses, (w, r) => r.SerializeAsV2(w));

            // schemes
            // All schemes in the Servers are extracted, regardless of whether the host matches
            // the host defined in the outermost Swagger object. This is due to the
            // inaccessibility of information for that host in the context of an inner object like this Operation.
            if (Servers != null)
            {
                var schemes = Servers.Select(
                    s =>
                {
                    Uri.TryCreate(s.Url, UriKind.RelativeOrAbsolute, out var url);
                    return(url?.Scheme);
                })
                              .Where(s => s != null)
                              .Distinct()
                              .ToList();

                writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s));
            }

            // deprecated
            writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false);

            // security
            writer.WriteOptionalCollection(OpenApiConstants.Security, Security, (w, s) => s.SerializeAsV2(w));

            // specification extensions
            writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0);

            writer.WriteEndObject();
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Serialize <see cref="OpenApiCallback"/> to Open Api v2.0
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     // Callback object does not exist in V2.
 }
Ejemplo n.º 7
0
        protected override void WriteBody(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
        {
            base.WriteBody(writer, specVersion);

            writer.WriteProperty("form-field", FormField);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Write out content of primitive element
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="specVersion"></param>
        public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
        {
            switch (this.PrimitiveType)
            {
            case PrimitiveType.Integer:
                var intValue = (OpenApiInteger)(IOpenApiPrimitive)this;
                writer.WriteValue(intValue.Value);
                break;

            case PrimitiveType.Long:
                var longValue = (OpenApiLong)(IOpenApiPrimitive)this;
                writer.WriteValue(longValue.Value);
                break;

            case PrimitiveType.Float:
                var floatValue = (OpenApiFloat)(IOpenApiPrimitive)this;
                writer.WriteValue(floatValue.Value);
                break;

            case PrimitiveType.Double:
                var doubleValue = (OpenApiDouble)(IOpenApiPrimitive)this;
                writer.WriteValue(doubleValue.Value);
                break;

            case PrimitiveType.String:
                var stringValue = (OpenApiString)(IOpenApiPrimitive)this;
                writer.WriteValue(stringValue.Value);
                break;

            case PrimitiveType.Byte:
                var byteValue = (OpenApiByte)(IOpenApiPrimitive)this;
                if (byteValue.Value == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(Convert.ToBase64String(byteValue.Value));
                }

                break;

            case PrimitiveType.Binary:
                var binaryValue = (OpenApiBinary)(IOpenApiPrimitive)this;
                if (binaryValue.Value == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(Encoding.UTF8.GetString(binaryValue.Value));
                }

                break;

            case PrimitiveType.Boolean:
                var boolValue = (OpenApiBoolean)(IOpenApiPrimitive)this;
                writer.WriteValue(boolValue.Value);
                break;

            case PrimitiveType.Date:
                var dateValue = (OpenApiDate)(IOpenApiPrimitive)this;
                writer.WriteValue(dateValue.Value);
                break;

            case PrimitiveType.DateTime:
                var dateTimeValue = (OpenApiDateTime)(IOpenApiPrimitive)this;
                writer.WriteValue(dateTimeValue.Value);
                break;

            case PrimitiveType.Password:
                var passwordValue = (OpenApiPassword)(IOpenApiPrimitive)this;
                writer.WriteValue(passwordValue.Value);
                break;

            default:
                throw new OpenApiWriterException(
                          string.Format(
                              SRResource.PrimitiveTypeNotSupported,
                              this.PrimitiveType));
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Serialize <see cref="OpenApiDocument"/> to OpenAPI object V2.0.
        /// </summary>
        public void SerializeAsV2(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            writer.WriteStartObject();

            // swagger
            writer.WriteProperty(OpenApiConstants.Swagger, "2.0");

            // info
            writer.WriteRequiredObject(OpenApiConstants.Info, Info, (w, i) => i.SerializeAsV2(w));

            // host, basePath, schemes, consumes, produces
            WriteHostInfoV2(writer, Servers);

            // paths
            writer.WriteRequiredObject(OpenApiConstants.Paths, Paths, (w, p) => p.SerializeAsV2(w));

            // Serialize each referenceable object as full object without reference if the reference in the object points to itself.
            // If the reference exists but points to other objects, the object is serialized to just that reference.

            // definitions
            writer.WriteOptionalMap(
                OpenApiConstants.Definitions,
                Components?.Schemas,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Schema &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // parameters
            writer.WriteOptionalMap(
                OpenApiConstants.Parameters,
                Components?.Parameters,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Parameter &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // responses
            writer.WriteOptionalMap(
                OpenApiConstants.Responses,
                Components?.Responses,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Response &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // securityDefinitions
            writer.WriteOptionalMap(
                OpenApiConstants.SecurityDefinitions,
                Components?.SecuritySchemes,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.SecurityScheme &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // security
            writer.WriteOptionalCollection(
                OpenApiConstants.Security,
                SecurityRequirements,
                (w, s) => s.SerializeAsV2(w));

            // tags
            writer.WriteOptionalCollection(OpenApiConstants.Tags, Tags, (w, t) => t.SerializeAsV2WithoutReference(w));

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w));

            // extensions
            writer.WriteExtensions(Extensions);

            writer.WriteEndObject();
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Serialize <see cref="OpenApiServerVariable"/> to Open Api v2.0
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     // ServerVariable does not exist in V2.
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Serialize <see cref="OpenApiLicense"/> to Open Api v2.0
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     WriteInternal(writer);
 }
Ejemplo n.º 12
0
        internal void WriteAsSchemaProperties(
            IOpenApiWriter writer,
            IList <string> parentRequiredProperties,
            string propertyName)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            // format
            writer.WriteProperty(OpenApiConstants.Format, Format);

            // title
            writer.WriteProperty(OpenApiConstants.Title, Title);

            // description
            writer.WriteProperty(OpenApiConstants.Description, Description);

            // default
            writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d));

            // multipleOf
            writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf);

            // maximum
            writer.WriteProperty(OpenApiConstants.Maximum, Maximum);

            // exclusiveMaximum
            writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum);

            // minimum
            writer.WriteProperty(OpenApiConstants.Minimum, Minimum);

            // exclusiveMinimum
            writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum);

            // maxLength
            writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength);

            // minLength
            writer.WriteProperty(OpenApiConstants.MinLength, MinLength);

            // pattern
            writer.WriteProperty(OpenApiConstants.Pattern, Pattern);

            // maxItems
            writer.WriteProperty(OpenApiConstants.MaxItems, MaxItems);

            // minItems
            writer.WriteProperty(OpenApiConstants.MinItems, MinItems);

            // uniqueItems
            writer.WriteProperty(OpenApiConstants.UniqueItems, UniqueItems);

            // maxProperties
            writer.WriteProperty(OpenApiConstants.MaxProperties, MaxProperties);

            // minProperties
            writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties);

            // required
            writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => w.WriteValue(s));

            // enum
            writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => w.WriteAny(s));

            // type
            writer.WriteProperty(OpenApiConstants.Type, Type);

            // items
            writer.WriteOptionalObject(OpenApiConstants.Items, Items, (w, s) => s.SerializeAsV2(w));

            // allOf
            writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, (w, s) => s.SerializeAsV2(w));

            // properties
            writer.WriteOptionalMap(OpenApiConstants.Properties, Properties, (w, key, s) =>
                                    s.SerializeAsV2(w, Required, key));

            // additionalProperties
            writer.WriteOptionalObject(
                OpenApiConstants.AdditionalProperties,
                AdditionalProperties,
                (w, s) => s.SerializeAsV2(w));

            // discriminator
            writer.WriteProperty(OpenApiConstants.Discriminator, Discriminator?.PropertyName);

            // readOnly
            // In V2 schema if a property is part of required properties of parent schema,
            // it cannot be marked as readonly.
            if (!parentRequiredProperties.Contains(propertyName))
            {
                writer.WriteProperty(name: OpenApiConstants.ReadOnly, value: ReadOnly, defaultValue: false);
            }

            // xml
            writer.WriteOptionalObject(OpenApiConstants.Xml, Xml, (w, s) => s.SerializeAsV2(w));

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, s) => s.SerializeAsV2(w));

            // example
            writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e));

            // extensions
            writer.WriteExtensions(Extensions);
        }
Ejemplo n.º 13
0
        internal void WriteAsItemsProperties(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            // type
            writer.WriteProperty(OpenApiConstants.Type, Type);

            // format
            writer.WriteProperty(OpenApiConstants.Format, Format);

            // items
            writer.WriteOptionalObject(OpenApiConstants.Items, Items, (w, s) => s.SerializeAsV2(w));

            // collectionFormat
            // We need information from style in parameter to populate this.
            // The best effort we can make is to pull this information from the first parameter
            // that leverages this schema. However, that in itself may not be as simple
            // as the schema directly under parameter might be referencing one in the Components,
            // so we will need to do a full scan of the object before we can write the value for
            // this property. This is not supported yet, so we will skip this property at the moment.

            // default
            writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d));

            // maximum
            writer.WriteProperty(OpenApiConstants.Maximum, Maximum);

            // exclusiveMaximum
            writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum);

            // minimum
            writer.WriteProperty(OpenApiConstants.Minimum, Minimum);

            // exclusiveMinimum
            writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum);

            // maxLength
            writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength);

            // minLength
            writer.WriteProperty(OpenApiConstants.MinLength, MinLength);

            // pattern
            writer.WriteProperty(OpenApiConstants.Pattern, Pattern);

            // maxItems
            writer.WriteProperty(OpenApiConstants.MaxItems, MaxItems);

            // minItems
            writer.WriteProperty(OpenApiConstants.MinItems, MinItems);

            // enum
            writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => w.WriteAny(s));

            // multipleOf
            writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf);

            // extensions
            writer.WriteExtensions(Extensions);
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Serialize <see cref="OpenApiSchema"/> to Open Api v2.0
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     SerializeAsV2(writer: writer, parentRequiredProperties: new List <string>(), propertyName: null);
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Serialize <see cref="OpenApiXml"/> to Open Api v3.0
 /// </summary>
 public void SerializeAsV3(IOpenApiWriter writer)
 {
     Write(writer, OpenApiSpecVersion.OpenApi3_0);
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Serialize to OpenAPI V2 document without using reference.
        /// </summary>
        public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
        {
            writer.WriteStartObject();

            // in
            if (this is OpenApiFormDataParameter)
            {
                writer.WriteProperty(OpenApiConstants.In, "formData");
            }
            else if (this is OpenApiBodyParameter)
            {
                writer.WriteProperty(OpenApiConstants.In, "body");
            }
            else
            {
                writer.WriteProperty(OpenApiConstants.In, In?.GetDisplayName());
            }

            // name
            writer.WriteProperty(OpenApiConstants.Name, Name);

            // description
            writer.WriteProperty(OpenApiConstants.Description, Description);

            // required
            writer.WriteProperty(OpenApiConstants.Required, Required, false);

            // deprecated
            writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false);

            // schema
            if (this is OpenApiBodyParameter)
            {
                writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => s.SerializeAsV2(w));
            }
            // In V2 parameter's type can't be a reference to a custom object schema or can't be of type object
            // So in that case map the type as string.
            else
            if (Schema?.UnresolvedReference == true || Schema?.Type == "object")
            {
                writer.WriteProperty(OpenApiConstants.Type, "string");
            }
            else
            {
                // type
                // format
                // items
                // collectionFormat
                // default
                // maximum
                // exclusiveMaximum
                // minimum
                // exclusiveMinimum
                // maxLength
                // minLength
                // pattern
                // maxItems
                // minItems
                // uniqueItems
                // enum
                // multipleOf
                Schema?.WriteAsItemsProperties(writer);

                // allowEmptyValue
                writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false);

                if (this.In == ParameterLocation.Query)
                {
                    if (this.Style == ParameterStyle.Form && this.Explode == true)
                    {
                        writer.WriteProperty("collectionFormat", "multi");
                    }
                    else if (this.Style == ParameterStyle.PipeDelimited)
                    {
                        writer.WriteProperty("collectionFormat", "pipes");
                    }
                    else if (this.Style == ParameterStyle.SpaceDelimited)
                    {
                        writer.WriteProperty("collectionFormat", "ssv");
                    }
                }
            }


            // extensions
            writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0);

            writer.WriteEndObject();
        }
Ejemplo n.º 17
0
 public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
 {
     writer.WriteValue(Name);
 }
 public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) => writer.WriteValue(Value.ToString(Format));
Ejemplo n.º 19
0
        /// <summary>
        /// Serialize to OpenAPI V2 document without using reference.
        /// </summary>

        public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
        {
            // Callback object does not exist in V2.
        }
 /// <summary>
 /// Serialize <see cref="OpenApiComponents"/> to Open Api v2.0.
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     // Components object does not exist in V2.
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Serialize <see cref="OpenApiServer"/> to Open Api v2.0
 /// </summary>
 public void SerializeAsV2(IOpenApiWriter writer)
 {
     // Server object does not exist in V2.
 }
        /// <summary>
        /// Serialize <see cref="OpenApiComponents"/> to Open Api v3.0.
        /// </summary>
        public void SerializeAsV3(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            writer.WriteStartObject();

            // Serialize each referenceable object as full object without reference if the reference in the object points to itself.
            // If the reference exists but points to other objects, the object is serialized to just that reference.

            // schemas
            writer.WriteOptionalMap(
                OpenApiConstants.Schemas,
                Schemas,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Schema &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // responses
            writer.WriteOptionalMap(
                OpenApiConstants.Responses,
                Responses,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Response &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // parameters
            writer.WriteOptionalMap(
                OpenApiConstants.Parameters,
                Parameters,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Parameter &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // examples
            writer.WriteOptionalMap(
                OpenApiConstants.Examples,
                Examples,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Example &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // requestBodies
            writer.WriteOptionalMap(
                OpenApiConstants.RequestBodies,
                RequestBodies,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.RequestBody &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // headers
            writer.WriteOptionalMap(
                OpenApiConstants.Headers,
                Headers,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Header &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // securitySchemes
            writer.WriteOptionalMap(
                OpenApiConstants.SecuritySchemes,
                SecuritySchemes,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.SecurityScheme &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // links
            writer.WriteOptionalMap(
                OpenApiConstants.Links,
                Links,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Link &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // callbacks
            writer.WriteOptionalMap(
                OpenApiConstants.Callbacks,
                Callbacks,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Callback &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // extensions
            writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi3_0);

            writer.WriteEndObject();
        }
Ejemplo n.º 23
0
        private static void WriteHostInfoV2(IOpenApiWriter writer, IList <OpenApiServer> servers)
        {
            if (servers == null || !servers.Any())
            {
                return;
            }

            // Arbitrarily choose the first server given that V2 only allows
            // one host, port, and base path.
            var firstServer = servers.First();

            // Divide the URL in the Url property into host and basePath required in OpenAPI V2
            // The Url property cannotcontain path templating to be valid for V2 serialization.
            var firstServerUrl = new Uri(firstServer.Url, UriKind.RelativeOrAbsolute);

            // host
            if (firstServerUrl.IsAbsoluteUri)
            {
                writer.WriteProperty(
                    OpenApiConstants.Host,
                    firstServerUrl.GetComponents(UriComponents.Host | UriComponents.Port, UriFormat.SafeUnescaped));

                // basePath
                if (firstServerUrl.AbsolutePath != "/")
                {
                    writer.WriteProperty(OpenApiConstants.BasePath, firstServerUrl.AbsolutePath);
                }
            }
            else
            {
                var relativeUrl = firstServerUrl.OriginalString;
                if (relativeUrl.StartsWith("//"))
                {
                    var pathPosition = relativeUrl.IndexOf('/', 3);
                    writer.WriteProperty(OpenApiConstants.Host, relativeUrl.Substring(0, pathPosition));
                    relativeUrl = relativeUrl.Substring(pathPosition);
                }
                if (!String.IsNullOrEmpty(relativeUrl) && relativeUrl != "/")
                {
                    writer.WriteProperty(OpenApiConstants.BasePath, relativeUrl);
                }
            }

            // Consider all schemes of the URLs in the server list that have the same
            // host, port, and base path as the first server.
            var schemes = servers.Select(
                s =>
            {
                Uri.TryCreate(s.Url, UriKind.RelativeOrAbsolute, out var url);
                return(url);
            })
                          .Where(
                u => Uri.Compare(
                    u,
                    firstServerUrl,
                    UriComponents.Host | UriComponents.Port | UriComponents.Path,
                    UriFormat.SafeUnescaped,
                    StringComparison.OrdinalIgnoreCase) ==
                0 && u.IsAbsoluteUri)
                          .Select(u => u.Scheme)
                          .Distinct()
                          .ToList();

            // schemes
            writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s));
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Serialize <see cref="OpenApiOperation"/> to Open Api v2.0.
        /// </summary>
        public void SerializeAsV2(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            writer.WriteStartObject();

            // tags
            writer.WriteOptionalCollection(
                OpenApiConstants.Tags,
                Tags,
                (w, t) =>
            {
                t.SerializeAsV3(w);
            });

            // summary
            writer.WriteProperty(OpenApiConstants.Summary, Summary);

            // description
            writer.WriteProperty(OpenApiConstants.Description, Description);

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w));

            // operationId
            writer.WriteProperty(OpenApiConstants.OperationId, OperationId);

            IList <OpenApiParameter> parameters;

            if (Parameters == null)
            {
                parameters = new List <OpenApiParameter>();
            }
            else
            {
                parameters = new List <OpenApiParameter>(Parameters);
            }

            if (RequestBody != null)
            {
                // consumes
                writer.WritePropertyName(OpenApiConstants.Consumes);
                writer.WriteStartArray();
                var consumes = RequestBody.Content.Keys.Distinct().ToList();
                foreach (var mediaType in consumes)
                {
                    writer.WriteValue(mediaType);
                }

                writer.WriteEndArray();

                // Create a parameter as BodyParameter type and add to Parameters.
                // This type will be used to populate the In property as "body" when Parameters is serialized.
                var bodyParameter = new BodyParameter
                {
                    Description = RequestBody.Description,
                    Schema      = RequestBody.Content.First().Value.Schema,
                    Format      = new List <string>(consumes)
                };

                parameters.Add(bodyParameter);
            }

            if (Responses != null)
            {
                var produces = Responses.Where(r => r.Value.Content != null)
                               .SelectMany(r => r.Value.Content?.Keys)
                               .Distinct()
                               .ToList();

                if (produces.Any())
                {
                    // produces
                    writer.WritePropertyName(OpenApiConstants.Produces);
                    writer.WriteStartArray();
                    foreach (var mediaType in produces)
                    {
                        writer.WriteValue(mediaType);
                    }

                    writer.WriteEndArray();
                }
            }

            // parameters
            // Use the parameters created locally to include request body if exists.
            writer.WriteOptionalCollection(OpenApiConstants.Parameters, parameters, (w, p) => p.SerializeAsV2(w));

            // responses
            writer.WriteRequiredObject(OpenApiConstants.Responses, Responses, (w, r) => r.SerializeAsV2(w));

            // schemes
            // All schemes in the Servers are extracted, regardless of whether the host matches
            // the host defined in the outermost Swagger object. This is due to the
            // inaccessibility of information for that host in the context of an inner object like this Operation.
            if (Servers != null)
            {
                var schemes = Servers.Select(
                    s =>
                {
                    Uri.TryCreate(s.Url, UriKind.RelativeOrAbsolute, out var url);
                    return(url?.Scheme);
                })
                              .Where(s => s != null)
                              .Distinct()
                              .ToList();

                writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s));
            }

            // deprecated
            writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false);

            // security
            writer.WriteOptionalCollection(OpenApiConstants.Security, Security, (w, s) => s.SerializeAsV2(w));

            // specification extensions
            writer.WriteExtensions(Extensions);

            writer.WriteEndObject();
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Serialize to OpenAPI V2 document without using reference.
        /// </summary>
        public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
        {
            writer.WriteStartObject();

            // in
            if (this is OpenApiFormDataParameter)
            {
                writer.WriteProperty(OpenApiConstants.In, "formData");
            }
            else if (this is OpenApiBodyParameter)
            {
                writer.WriteProperty(OpenApiConstants.In, "body");
            }
            else
            {
                writer.WriteProperty(OpenApiConstants.In, In.GetDisplayName());
            }

            // name
            writer.WriteProperty(OpenApiConstants.Name, Name);

            // description
            writer.WriteProperty(OpenApiConstants.Description, Description);

            // required
            writer.WriteProperty(OpenApiConstants.Required, Required, false);

            // deprecated
            writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false);

            // schema
            if (this is OpenApiBodyParameter)
            {
                writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => s.SerializeAsV2(w));
            }
            else
            {
                // type
                // format
                // items
                // collectionFormat
                // default
                // maximum
                // exclusiveMaximum
                // minimum
                // exclusiveMinimum
                // maxLength
                // minLength
                // pattern
                // maxItems
                // minItems
                // uniqueItems
                // enum
                // multipleOf
                Schema?.WriteAsItemsProperties(writer);

                // allowEmptyValue
                writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false);
            }

            // extensions
            writer.WriteExtensions(Extensions);

            writer.WriteEndObject();
        }
 public void Write(IOpenApiWriter writer)
 {
 }
 /// <summary>
 /// Writes an optional Open API element map.
 /// </summary>
 /// <typeparam name="T">The Open API element type. <see cref="IOpenApiElement"/></typeparam>
 /// <param name="writer">The Open API writer.</param>
 /// <param name="name">The property name.</param>
 /// <param name="elements">The map values.</param>
 /// <param name="specVersion">The OpenAPI Spec version.</param>
 public static void WriteOptionalMap <T>(this IOpenApiWriter writer, string name, IDictionary <string, T> elements, OpenApiSpecVersion specVersion)
     where T : IOpenApiSerializable
 => writer.WriteOptionalMap(name, elements, (w, v) => v.Serialize(w, specVersion));
Ejemplo n.º 28
0
 /// <summary>
 /// Serialize to OpenAPI V2 document without using reference.
 /// </summary>
 public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
 {
     // Example object of this form does not exist in V2.
     // V2 Example object requires knowledge of media type and exists only
     // in Response object, so it will be serialized as a part of the Response object.
 }
Ejemplo n.º 29
0
 public static bool TryWriteValue(this IEnumerable <IMockDataProvider> providers,
                                  IOpenApiWriter writer,
                                  JSchema schema)
 {
     return(providers.Any(x => x.TryWriteValue(writer, schema)));
 }
Ejemplo n.º 30
0
        public static async void ProcessOpenApiDocument(
            string openapi,
            FileInfo output,
            OpenApiSpecVersion?version,
            OpenApiFormat?format,
            LogLevel loglevel,
            bool inline,
            bool resolveexternal,
            string filterbyoperationids,
            string filterbytags,
            string filterbycollection
            )
        {
            var logger = ConfigureLoggerInstance(loglevel);

            try
            {
                if (string.IsNullOrEmpty(openapi))
                {
                    throw new ArgumentNullException(nameof(openapi));
                }
            }
            catch (ArgumentNullException ex)
            {
                logger.LogError(ex.Message);
                return;
            }
            try
            {
                if (output == null)
                {
                    throw new ArgumentException(nameof(output));
                }
            }
            catch (ArgumentException ex)
            {
                logger.LogError(ex.Message);
                return;
            }
            try
            {
                if (output.Exists)
                {
                    throw new IOException("The file you're writing to already exists. Please input a new file path.");
                }
            }
            catch (IOException ex)
            {
                logger.LogError(ex.Message);
                return;
            }

            var stream = await GetStream(openapi, logger);

            // Parsing OpenAPI file
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            logger.LogTrace("Parsing OpenApi file");
            var result = new OpenApiStreamReader(new OpenApiReaderSettings
            {
                ReferenceResolution = resolveexternal ? ReferenceResolutionSetting.ResolveAllReferences : ReferenceResolutionSetting.ResolveLocalReferences,
                RuleSet             = ValidationRuleSet.GetDefaultRuleSet()
            }
                                                 ).ReadAsync(stream).GetAwaiter().GetResult();
            var document = result.OpenApiDocument;

            stopwatch.Stop();

            var context = result.OpenApiDiagnostic;

            if (context.Errors.Count > 0)
            {
                var errorReport = new StringBuilder();

                foreach (var error in context.Errors)
                {
                    errorReport.AppendLine(error.ToString());
                }
                logger.LogError($"{stopwatch.ElapsedMilliseconds}ms: OpenApi Parsing errors {string.Join(Environment.NewLine, context.Errors.Select(e => e.Message).ToArray())}");
            }
            else
            {
                logger.LogTrace("{timestamp}ms: Parsed OpenApi successfully. {count} paths found.", stopwatch.ElapsedMilliseconds, document.Paths.Count);
            }

            Func <string, OperationType?, OpenApiOperation, bool> predicate;

            // Check if filter options are provided, then slice the OpenAPI document
            if (!string.IsNullOrEmpty(filterbyoperationids) && !string.IsNullOrEmpty(filterbytags))
            {
                throw new InvalidOperationException("Cannot filter by operationIds and tags at the same time.");
            }
            if (!string.IsNullOrEmpty(filterbyoperationids))
            {
                logger.LogTrace("Creating predicate based on the operationIds supplied.");
                predicate = OpenApiFilterService.CreatePredicate(operationIds: filterbyoperationids);

                logger.LogTrace("Creating subset OpenApi document.");
                document = OpenApiFilterService.CreateFilteredDocument(document, predicate);
            }
            if (!string.IsNullOrEmpty(filterbytags))
            {
                logger.LogTrace("Creating predicate based on the tags supplied.");
                predicate = OpenApiFilterService.CreatePredicate(tags: filterbytags);

                logger.LogTrace("Creating subset OpenApi document.");
                document = OpenApiFilterService.CreateFilteredDocument(document, predicate);
            }
            if (!string.IsNullOrEmpty(filterbycollection))
            {
                var fileStream = await GetStream(filterbycollection, logger);

                var requestUrls = ParseJsonCollectionFile(fileStream, logger);

                logger.LogTrace("Creating predicate based on the paths and Http methods defined in the Postman collection.");
                predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: document);

                logger.LogTrace("Creating subset OpenApi document.");
                document = OpenApiFilterService.CreateFilteredDocument(document, predicate);
            }

            logger.LogTrace("Creating a new file");
            using var outputStream = output?.Create();
            var textWriter = outputStream != null ? new StreamWriter(outputStream) : Console.Out;

            var settings = new OpenApiWriterSettings()
            {
                ReferenceInline = inline ? ReferenceInlineSetting.InlineLocalReferences : ReferenceInlineSetting.DoNotInlineReferences
            };

            var            openApiFormat  = format ?? GetOpenApiFormat(openapi, logger);
            var            openApiVersion = version ?? result.OpenApiDiagnostic.SpecificationVersion;
            IOpenApiWriter writer         = openApiFormat switch
            {
                OpenApiFormat.Json => new OpenApiJsonWriter(textWriter, settings),
                OpenApiFormat.Yaml => new OpenApiYamlWriter(textWriter, settings),
                _ => throw new ArgumentException("Unknown format"),
            };

            logger.LogTrace("Serializing to OpenApi document using the provided spec version and writer");

            stopwatch.Start();
            document.Serialize(writer, openApiVersion);
            stopwatch.Stop();

            logger.LogTrace($"Finished serializing in {stopwatch.ElapsedMilliseconds}ms");

            textWriter.Flush();
        }