Пример #1
0
        public ChangedPathBO Diff(OpenApiPathItem left, OpenApiPathItem right, DiffContextBO context)
        {
            var oldOperationMap = left.Operations;
            var newOperationMap = right.Operations;
            var operationsDiff  =
                MapKeyDiff <OperationType, OpenApiOperation> .Diff(oldOperationMap, newOperationMap);

            var sharedMethods = operationsDiff.SharedKey;
            var changedPath   = new ChangedPathBO(context.URL, left, right, context)
            {
                Increased = operationsDiff.Increased,
                Missing   = operationsDiff.Missing
            };

            foreach (var operationType in sharedMethods)
            {
                var oldOperation = oldOperationMap[operationType];
                var newOperation = newOperationMap[operationType];

                var diff = _openApiDiff
                           .OperationDiff
                           .Diff(oldOperation, newOperation, context.CopyWithMethod(operationType));

                if (diff != null)
                {
                    changedPath.Changed.Add(diff);
                }
            }

            changedPath.Extensions = _openApiDiff
                                     .ExtensionsDiff
                                     .Diff(left.Extensions, right.Extensions, context);

            return(ChangedUtils.IsChanged(changedPath));
        }
Пример #2
0
        public TD CachedDiff(
            TC left,
            TC right,
            string leftRef,
            string rightRef,
            DiffContextBO context)
        {
            var areBothRefParameters = leftRef != null && rightRef != null;

            if (areBothRefParameters)
            {
                var key = new CacheKey(leftRef, rightRef, context);
                if (RefDiffMap.TryGetValue(key, out var changedFromRef))
                {
                    return(changedFromRef);
                }

                RefDiffMap.Add(key, null);
                var changed = ComputeDiff(left, right, context);
                RefDiffMap[key] = changed;
                return(changed);
            }

            return(ComputeDiff(left, right, context));
        }
Пример #3
0
        protected override ChangedHeaderBO ComputeDiff(OpenApiHeader left, OpenApiHeader right,
                                                       DiffContextBO context)
        {
            left  = RefPointer.ResolveRef(_leftComponents, left, left.Reference?.ReferenceV3);
            right = RefPointer.ResolveRef(_rightComponents, right, right.Reference?.ReferenceV3);

            var changedHeader =
                new ChangedHeaderBO(left, right, context)
            {
                Required    = GetBooleanDiff(left.Required, right.Required),
                Deprecated  = !left.Deprecated && right.Deprecated,
                Style       = left.Style != right.Style,
                Explode     = GetBooleanDiff(left.Explode, right.Explode),
                Description = _openApiDiff
                              .MetadataDiff
                              .Diff(left.Description, right.Description, context),
                Schema = _openApiDiff
                         .SchemaDiff
                         .Diff(left.Schema, right.Schema, context.CopyWithRequired(true)),
                Content = _openApiDiff
                          .ContentDiff
                          .Diff(left.Content, right.Content, context),
                Extensions = _openApiDiff
                             .ExtensionsDiff
                             .Diff(left.Extensions, right.Extensions, context)
            };

            return(ChangedUtils.IsChanged(changedHeader));
        }
Пример #4
0
        private void CompareAdditionalProperties(OpenApiSchema leftSchema,
                                                 OpenApiSchema rightSchema, DiffContextBO context)
        {
            var left  = leftSchema.AdditionalProperties;
            var right = rightSchema.AdditionalProperties;

            if (left != null || right != null)
            {
                var apChangedSchema = new ChangedSchemaBO
                {
                    Context   = context,
                    OldSchema = left,
                    NewSchema = right
                };
                if (left != null && right != null)
                {
                    var addPropChangedSchemaOp =
                        OpenApiDiff
                        .SchemaDiff
                        .Diff(left, right, context.CopyWithRequired(false));
                    apChangedSchema = addPropChangedSchemaOp ?? apChangedSchema;
                }

                var changed = ChangedUtils.IsChanged(apChangedSchema);
                if (changed != null)
                {
                    ChangedSchema.AddProp = changed;
                }
            }
        }
Пример #5
0
        public ChangedHeadersBO Diff(IDictionary <string, OpenApiHeader> left, IDictionary <string, OpenApiHeader> right,
                                     DiffContextBO context)
        {
            var headerMapDiff = MapKeyDiff <string, OpenApiHeader> .Diff(left, right);

            var sharedHeaderKeys = headerMapDiff.SharedKey;

            var changed = new Dictionary <string, ChangedHeaderBO>();

            foreach (var headerKey in sharedHeaderKeys)
            {
                var oldHeader      = left[headerKey];
                var newHeader      = right[headerKey];
                var changedHeaders = _openApiDiff
                                     .HeaderDiff
                                     .Diff(oldHeader, newHeader, context);
                if (changedHeaders != null)
                {
                    changed.Add(headerKey, changedHeaders);
                }
            }

            return(ChangedUtils.IsChanged(
                       new ChangedHeadersBO(left, right, context)
            {
                Increased = headerMapDiff.Increased,
                Missing = headerMapDiff.Missing,
                Changed = changed
            }));
        }
Пример #6
0
        public ChangedSchemaBO Diff(OpenApiSchema left, OpenApiSchema right,
                                    DiffContextBO context)
        {
            if (left == null && right == null)
            {
                return(null);
            }

            var leftRef  = GetSchemaRef(left);
            var rightRef = GetSchemaRef(right);

            if (left != null && left.AllOf.Any())
            {
                var result = ResolveComposedSchema(_leftComponents, left);
                leftRef = result.Key;
                left    = result.Value;
            }

            if (right != null && right.AllOf.Any())
            {
                var result = ResolveComposedSchema(_rightComponents, right);
                rightRef = result.Key;
                right    = result.Value;
            }

            return(CachedDiff(left, right, leftRef, rightRef, context));
        }
        public override ChangedSchemaBO Diff <T>(OpenApiComponents leftComponents,
                                                 OpenApiComponents rightComponents, T left,
                                                 T right, DiffContextBO context)
        {
            if (left.GetSchemaType() != SchemaTypeEnum.ArraySchema ||
                right.GetSchemaType() != SchemaTypeEnum.ArraySchema)
            {
                return(null);
            }

            base.Diff(leftComponents, rightComponents, left, right, context);

            var diff = OpenApiDiff
                       .SchemaDiff
                       .Diff(
                left.Items,
                right.Items,
                context.CopyWithRequired(true));

            if (diff != null)
            {
                ChangedSchema.Items = diff;
            }

            return(IsApplicable(context));
        }
Пример #8
0
        public ChangedRequestBodyBO Diff(
            OpenApiRequestBody left, OpenApiRequestBody right, DiffContextBO context)
        {
            var leftRef  = left.Reference?.ReferenceV3;
            var rightRef = right.Reference?.ReferenceV3;

            return(CachedDiff(left, right, leftRef, rightRef, context));
        }
Пример #9
0
        public ChangedPathsBO Diff(Dictionary <string, OpenApiPathItem> left, Dictionary <string, OpenApiPathItem> right)
        {
            var changedPaths = new ChangedPathsBO(left, right);

            foreach (var(key, value) in right)
            {
                changedPaths.Increased.Add(key, value);
            }

            foreach (var(key, value) in left)
            {
                var template = key.NormalizePath();
                var result   = right.Keys.FirstOrDefault(x => x.NormalizePath() == template);

                if (result != null)
                {
                    if (!changedPaths.Increased.ContainsKey(result))
                    {
                        throw new ArgumentException($"Two path items have the same signature: {template}");
                    }
                    var rightPath = changedPaths.Increased[result];
                    changedPaths.Increased.Remove(result);
                    var paramsDict = new Dictionary <string, string>();
                    if (key != result)
                    {
                        var oldParams = key.ExtractParametersFromPath();
                        var newParams = result.ExtractParametersFromPath();
                        for (var i = oldParams.Count - 1; i >= 0; i--)
                        {
                            paramsDict.Add(oldParams[i], newParams[i]);
                        }
                    }

                    var context = new DiffContextBO
                    {
                        URL        = key,
                        Parameters = paramsDict
                    };

                    var diff = _openApiDiff
                               .PathDiff
                               .Diff(value, rightPath, context);

                    if (diff != null)
                    {
                        changedPaths.Changed.Add(result, diff);
                    }
                }
                else
                {
                    changedPaths.Missing.Add(key, value);
                }
            }

            return(ChangedUtils.IsChanged(changedPaths));
        }
Пример #10
0
        protected override ChangedRequestBodyBO ComputeDiff(OpenApiRequestBody left,
                                                            OpenApiRequestBody right,
                                                            DiffContextBO context)
        {
            Dictionary <string, OpenApiMediaType> oldRequestContent = null;
            Dictionary <string, OpenApiMediaType> newRequestContent = null;
            OpenApiRequestBody oldRequestBody = null;
            OpenApiRequestBody newRequestBody = null;

            if (left != null)
            {
                oldRequestBody =
                    RefPointer.ResolveRef(
                        _openApiDiff.OldSpecOpenApi.Components, left, left.Reference?.ReferenceV3);
                if (oldRequestBody.Content != null)
                {
                    oldRequestContent = (Dictionary <string, OpenApiMediaType>)oldRequestBody.Content;
                }
            }

            if (right != null)
            {
                newRequestBody =
                    RefPointer.ResolveRef(
                        _openApiDiff.NewSpecOpenApi.Components, right, right.Reference?.ReferenceV3);
                if (newRequestBody.Content != null)
                {
                    newRequestContent = (Dictionary <string, OpenApiMediaType>)newRequestBody.Content;
                }
            }

            var leftRequired =
                oldRequestBody != null && oldRequestBody.Required;
            var rightRequired =
                newRequestBody != null && newRequestBody.Required;

            var changedRequestBody =
                new ChangedRequestBodyBO(oldRequestBody, newRequestBody, context)
            {
                ChangeRequired = leftRequired != rightRequired,
                Description    = _openApiDiff
                                 .MetadataDiff
                                 .Diff(
                    oldRequestBody?.Description,
                    newRequestBody?.Description,
                    context),
                Content = _openApiDiff
                          .ContentDiff
                          .Diff(oldRequestContent, newRequestContent, context),
                Extensions = _openApiDiff
                             .ExtensionsDiff
                             .Diff(GetExtensions(left), GetExtensions(right), context)
            };

            return(ChangedUtils.IsChanged(changedRequestBody));
        }
Пример #11
0
 protected ChangedSchemaBO IsApplicable(DiffContextBO context)
 {
     if (ChangedSchema.ReadOnly.IsUnchanged() &&
         ChangedSchema.WriteOnly.IsUnchanged() &&
         !IsPropertyApplicable(ChangedSchema.NewSchema, context))
     {
         return(null);
     }
     return(ChangedUtils.IsChanged(ChangedSchema));
 }
Пример #12
0
        public ChangedSchemaBO GetTypeChangedSchema(
            OpenApiSchema left, OpenApiSchema right, DiffContextBO context)
        {
            var schemaDiffResult = GetSchemaDiffResult(_openApiDiff);

            schemaDiffResult.ChangedSchema.OldSchema     = left;
            schemaDiffResult.ChangedSchema.NewSchema     = right;
            schemaDiffResult.ChangedSchema.IsChangedType = true;
            schemaDiffResult.ChangedSchema.Context       = context;

            return(schemaDiffResult.ChangedSchema);
        }
Пример #13
0
        public bool IsParentApplicable(TypeEnum type, object parent, IDictionary <string, IOpenApiExtension> extensions,
                                       DiffContextBO context)
        {
            if (extensions.IsNullOrEmpty())
            {
                return(true);
            }

            return(extensions.Select(x => ExecuteExtension(x.Key, y => y
                                                           .IsParentApplicable(type, parent, x.Value, context)))
                   .All(x => x));
        }
Пример #14
0
        private static string Properties(string propPrefix, string title, Dictionary <string, OpenApiSchema> properties,
                                         DiffContextBO context)
        {
            var sb = new StringBuilder();

            if (properties != null)
            {
                foreach (var(key, value) in properties)
                {
                    sb.Append(Property(propPrefix + key, title, Resolve(value)));
                }
            }
            return(sb.ToString());
        }
Пример #15
0
        protected override ChangedSecuritySchemeBO ComputeDiff(
            OpenApiSecurityScheme leftSecurityScheme,
            OpenApiSecurityScheme rightSecurityScheme,
            DiffContextBO context)
        {
            var changedSecurityScheme =
                new ChangedSecuritySchemeBO(leftSecurityScheme, rightSecurityScheme)
            {
                Description = _openApiDiff
                              .MetadataDiff
                              .Diff(leftSecurityScheme.Description, rightSecurityScheme.Description, context)
            };

            switch (leftSecurityScheme.Type)
            {
            case SecuritySchemeType.ApiKey:
                changedSecurityScheme.IsChangedIn =
                    !leftSecurityScheme.In.Equals(rightSecurityScheme.In);
                break;

            case SecuritySchemeType.Http:
                changedSecurityScheme.IsChangedScheme =
                    leftSecurityScheme.Scheme != rightSecurityScheme.Scheme;
                changedSecurityScheme.IsChangedBearerFormat =
                    leftSecurityScheme.BearerFormat != rightSecurityScheme.BearerFormat;
                break;

            case SecuritySchemeType.OAuth2:
                changedSecurityScheme.OAuthFlows = _openApiDiff
                                                   .OAuthFlowsDiff
                                                   .Diff(leftSecurityScheme.Flows, rightSecurityScheme.Flows);
                break;

            case SecuritySchemeType.OpenIdConnect:
                changedSecurityScheme.IsChangedOpenIdConnectUrl =
                    leftSecurityScheme.OpenIdConnectUrl != rightSecurityScheme.OpenIdConnectUrl;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            changedSecurityScheme.Extensions = _openApiDiff
                                               .ExtensionsDiff
                                               .Diff(leftSecurityScheme.Extensions, rightSecurityScheme.Extensions, context);

            return(changedSecurityScheme);
        }
        public ChangedSecurityRequirementBO Diff(
            OpenApiSecurityRequirement left, OpenApiSecurityRequirement right, DiffContextBO context)
        {
            var changedSecurityRequirement =
                new ChangedSecurityRequirementBO(left, right != null ? GetCopy(right) : null);

            left ??= new OpenApiSecurityRequirement();
            right ??= new OpenApiSecurityRequirement();

            foreach (var(key, value) in left)
            {
                var rightSec = Contains(right, key.Reference?.ReferenceV3);
                if (rightSec.IsNullOrEmpty())
                {
                    changedSecurityRequirement.Missing.Add(key, value);
                }
                else
                {
                    var rightSchemeRef = rightSec.Keys.First();
                    right.Remove(rightSchemeRef);
                    var diff =
                        _openApiDiff
                        .SecuritySchemeDiff
                        .Diff(
                            key.Reference?.ReferenceV3,
                            value.ToList(),
                            rightSchemeRef.Reference?.ReferenceV3,
                            rightSec[rightSchemeRef].ToList(),
                            context);
                    if (diff != null)
                    {
                        changedSecurityRequirement.Changed.Add(diff);
                    }
                }
            }

            foreach (var(key, value) in right)
            {
                changedSecurityRequirement.Increased.Add(key, value);
            }

            return(ChangedUtils.IsChanged(changedSecurityRequirement));
        }
Пример #17
0
        public ChangedParametersBO Diff(
            List <OpenApiParameter> left, List <OpenApiParameter> right, DiffContextBO context)
        {
            var changedParameters =
                new ChangedParametersBO(left, right, context);

            if (null == left)
            {
                left = new List <OpenApiParameter>();
            }
            if (null == right)
            {
                right = new List <OpenApiParameter>();
            }

            foreach (var openApiParameter in left)
            {
                var leftPara = openApiParameter;
                leftPara = RefPointer.ResolveRef(_leftComponents, leftPara, leftPara.Reference?.ReferenceV3);

                var rightParam = Contains(_rightComponents, right, leftPara);
                if (rightParam == null)
                {
                    changedParameters.Missing.Add(leftPara);
                }
                else
                {
                    right.Remove(rightParam);

                    var diff = _openApiDiff.ParameterDiff
                               .Diff(leftPara, rightParam, context);
                    if (diff != null)
                    {
                        changedParameters.Changed.Add(diff);
                    }
                }
            }

            changedParameters.Increased.AddRange(right);

            return(ChangedUtils.IsChanged(changedParameters));
        }
Пример #18
0
        public ChangedContentBO Diff(IDictionary <string, OpenApiMediaType> left,
                                     IDictionary <string, OpenApiMediaType> right, DiffContextBO context)
        {
            var leftDict  = (Dictionary <string, OpenApiMediaType>)left;
            var rightDict = (Dictionary <string, OpenApiMediaType>)right;


            var mediaTypeDiff = MapKeyDiff <string, OpenApiMediaType> .Diff(leftDict, rightDict);

            var sharedMediaTypes  = mediaTypeDiff.SharedKey;
            var changedMediaTypes = new Dictionary <string, ChangedMediaTypeBO>();

            foreach (var sharedMediaType in sharedMediaTypes)
            {
                var oldMediaType     = left[sharedMediaType];
                var newMediaType     = right[sharedMediaType];
                var changedMediaType =
                    new ChangedMediaTypeBO(oldMediaType?.Schema, newMediaType?.Schema, context)
                {
                    Schema = _openApiDiff
                             .SchemaDiff
                             .Diff(
                        oldMediaType?.Schema,
                        newMediaType?.Schema,
                        context.CopyWithRequired(true))
                };
                if (!ChangedUtils.IsUnchanged(changedMediaType))
                {
                    changedMediaTypes.Add(sharedMediaType, changedMediaType);
                }
            }

            return(ChangedUtils.IsChanged(new ChangedContentBO(leftDict, rightDict, context)
            {
                Increased = mediaTypeDiff.Increased,
                Missing = mediaTypeDiff.Missing,
                Changed = changedMediaTypes
            }));
        }
Пример #19
0
        public ChangedSecuritySchemeBO Diff(
            string leftSchemeRef,
            List <string> leftScopes,
            string rightSchemeRef,
            List <string> rightScopes,
            DiffContextBO context)
        {
            var leftSecurityScheme       = _leftComponents.SecuritySchemes[leftSchemeRef];
            var rightSecurityScheme      = _rightComponents.SecuritySchemes[rightSchemeRef];
            var changedSecuritySchemeOpt =
                CachedDiff(
                    leftSecurityScheme,
                    rightSecurityScheme,
                    leftSchemeRef,
                    rightSchemeRef,
                    context);
            var changedSecurityScheme =
                changedSecuritySchemeOpt ?? new ChangedSecuritySchemeBO(leftSecurityScheme, rightSecurityScheme);

            changedSecurityScheme = GetCopyWithoutScopes(changedSecurityScheme);

            if (changedSecurityScheme != null &&
                leftSecurityScheme.Type == SecuritySchemeType.OAuth2)
            {
                var changed = ChangedUtils.IsChanged(ListDiff.Diff(
                                                         new ChangedSecuritySchemeScopesBO(leftScopes, rightScopes)
                                                         ));

                if (changed != null)
                {
                    changedSecurityScheme.ChangedScopes = changed;
                }
            }

            return(ChangedUtils.IsChanged(changedSecurityScheme));
        }
Пример #20
0
        protected override ChangedResponseBO ComputeDiff(OpenApiResponse left,
                                                         OpenApiResponse right, DiffContextBO context)
        {
            left  = RefPointer.ResolveRef(_leftComponents, left, left.Reference?.ReferenceV3);
            right = RefPointer.ResolveRef(_rightComponents, right, right.Reference?.ReferenceV3);

            var changedResponse = new ChangedResponseBO(left, right, context)
            {
                Description = _openApiDiff
                              .MetadataDiff
                              .Diff(left.Description, right.Description, context),
                Content = _openApiDiff
                          .ContentDiff
                          .Diff(left.Content, right.Content, context),
                Headers = _openApiDiff
                          .HeadersDiff
                          .Diff(left.Headers, right.Headers, context),
                Extensions = _openApiDiff
                             .ExtensionsDiff
                             .Diff(left.Extensions, right.Extensions, context)
            };

            return(ChangedUtils.IsChanged(changedResponse));
        }
Пример #21
0
 public ChangedHeaderBO Diff(OpenApiHeader left, OpenApiHeader right, DiffContextBO context)
 {
     return(CachedDiff(left, right, left.Reference?.ReferenceV3,
                       right.Reference?.ReferenceV3, context));
 }
Пример #22
0
 private static DiffContextBO Required(DiffContextBO context, string key, ICollection <string> required)
 {
     return(context.CopyWithRequired(required != null && required.Contains(key)));
 }
Пример #23
0
        public ChangedAPIResponseBO Diff(OpenApiResponses left, OpenApiResponses right, DiffContextBO context)
        {
            var responseMapKeyDiff = MapKeyDiff <string, OpenApiResponse> .Diff(left, right);

            var sharedResponseCodes = responseMapKeyDiff.SharedKey;
            var responses           = new Dictionary <string, ChangedResponseBO>();

            foreach (var responseCode in sharedResponseCodes)
            {
                var diff = _openApiDiff
                           .ResponseDiff
                           .Diff(left[responseCode], right[responseCode], context);

                if (diff != null)
                {
                    responses.Add(responseCode, diff);
                }
            }

            var changedApiResponse =
                new ChangedAPIResponseBO(left, right, context)
            {
                Increased  = responseMapKeyDiff.Increased,
                Missing    = responseMapKeyDiff.Missing,
                Changed    = responses,
                Extensions = _openApiDiff
                             .ExtensionsDiff
                             .Diff(left.Extensions, right.Extensions, context)
            };

            return(ChangedUtils.IsChanged(changedApiResponse));
        }
Пример #24
0
        private Dictionary <string, OpenApiSchema> FilterProperties(TypeEnum type,
                                                                    Dictionary <string, OpenApiSchema> properties, DiffContextBO context)
        {
            var result = new Dictionary <string, OpenApiSchema>();

            foreach (var(key, value) in properties)
            {
                if (IsPropertyApplicable(value, context) &&
                    OpenApiDiff
                    .ExtensionsDiff.IsParentApplicable(type,
                                                       value,
                                                       value?.Extensions ?? new Dictionary <string, IOpenApiExtension>(),
                                                       context))
                {
                    result.Add(key, value);
                }
                else
                {
                    // Child property is not applicable, so required cannot be applied
                    ChangedSchema.Required.Increased.Remove(key);
                }
            }


            return(result);
        }
Пример #25
0
 protected abstract TD ComputeDiff(TC left, TC right, DiffContextBO context);
Пример #26
0
        public ChangedOperationBO Diff(
            OpenApiOperation oldOperation, OpenApiOperation newOperation, DiffContextBO context)
        {
            var changedOperation =
                new ChangedOperationBO(context.URL, context.Method, oldOperation, newOperation)
            {
                Summary = _openApiDiff
                          .MetadataDiff
                          .Diff(oldOperation.Summary, newOperation.Summary, context),
                Description = _openApiDiff
                              .MetadataDiff
                              .Diff(oldOperation.Description, newOperation.Description, context),
                IsDeprecated = !oldOperation.Deprecated && newOperation.Deprecated
            };

            if (oldOperation.RequestBody != null || newOperation.RequestBody != null)
            {
                changedOperation.RequestBody = _openApiDiff
                                               .RequestBodyDiff
                                               .Diff(
                    oldOperation.RequestBody, newOperation.RequestBody, context.CopyAsRequest());
            }

            var parametersDiff = _openApiDiff
                                 .ParametersDiff
                                 .Diff(oldOperation.Parameters.ToList(), newOperation.Parameters.ToList(), context);

            if (parametersDiff != null)
            {
                RemovePathParameters(context.Parameters, parametersDiff);
                changedOperation.Parameters = parametersDiff;
            }


            if (oldOperation.Responses != null || newOperation.Responses != null)
            {
                var diff = _openApiDiff
                           .APIResponseDiff
                           .Diff(oldOperation.Responses, newOperation.Responses, context.CopyAsResponse());

                if (diff != null)
                {
                    changedOperation.APIResponses = diff;
                }
            }

            if (oldOperation.Security != null || newOperation.Security != null)
            {
                var diff = _openApiDiff
                           .SecurityRequirementsDiff
                           .Diff(oldOperation.Security, newOperation.Security, context);

                if (diff != null)
                {
                    changedOperation.SecurityRequirements = diff;
                }
            }

            changedOperation.Extensions =
                _openApiDiff
                .ExtensionsDiff
                .Diff(oldOperation.Extensions, newOperation.Extensions, context);

            return(ChangedUtils.IsChanged(changedOperation));
        }
Пример #27
0
 public CacheKey(string left, string right, DiffContextBO context)
 {
     this.left    = left;
     this.right   = right;
     this.context = context;
 }
Пример #28
0
        public virtual ChangedSchemaBO Diff <T>(
            OpenApiComponents leftComponents,
            OpenApiComponents rightComponents,
            T left,
            T right,
            DiffContextBO context)
            where T : OpenApiSchema
        {
            var leftEnumStrings  = left.Enum.Select(x => ((IOpenApiPrimitive)x)?.GetValueString()).ToList();
            var rightEnumStrings = right.Enum.Select(x => ((IOpenApiPrimitive)x)?.GetValueString()).ToList();
            var leftDefault      = (IOpenApiPrimitive)left.Default;
            var rightDefault     = (IOpenApiPrimitive)right.Default;

            var changedEnum =
                ListDiff.Diff(new ChangedEnumBO(leftEnumStrings, rightEnumStrings, context));

            ChangedSchema.Context            = context;
            ChangedSchema.OldSchema          = left;
            ChangedSchema.NewSchema          = right;
            ChangedSchema.IsChangeDeprecated = !left.Deprecated && right.Deprecated;
            ChangedSchema.IsChangeTitle      = left.Title != right.Title;
            ChangedSchema.Required           =
                ListDiff.Diff(new ChangedRequiredBO(left.Required.ToList(), right.Required.ToList(), context));
            ChangedSchema.IsChangeDefault = leftDefault?.GetValueString() != rightDefault?.GetValueString();
            ChangedSchema.Enumeration     = changedEnum;
            ChangedSchema.IsChangeFormat  = left.Format != right.Format;
            ChangedSchema.ReadOnly        = new ChangedReadOnlyBO(left.ReadOnly, right.ReadOnly, context);
            ChangedSchema.WriteOnly       = new ChangedWriteOnlyBO(left.WriteOnly, right.WriteOnly, context);
            ChangedSchema.MinLength       = new ChangedMinLengthBO(left.MinLength, right.MinLength, context);
            ChangedSchema.MaxLength       = new ChangedMaxLengthBO(left.MaxLength, right.MaxLength, context);

            var extendedDiff = OpenApiDiff.ExtensionsDiff.Diff(left.Extensions, right.Extensions, context);

            if (extendedDiff != null)
            {
                ChangedSchema.Extensions = extendedDiff;
            }
            var metaDataDiff = OpenApiDiff.MetadataDiff.Diff(left.Description, right.Description, context);

            if (metaDataDiff != null)
            {
                ChangedSchema.Description = metaDataDiff;
            }

            var leftProperties  = left.Properties;
            var rightProperties = right.Properties;
            var propertyDiff    = MapKeyDiff <string, OpenApiSchema> .Diff(leftProperties, rightProperties);

            foreach (var s in propertyDiff.SharedKey)
            {
                var diff = OpenApiDiff
                           .SchemaDiff
                           .Diff(leftProperties[s], rightProperties[s], Required(context, s, right.Required));

                if (diff != null)
                {
                    ChangedSchema.ChangedProperties.Add(s, diff);
                }
            }

            CompareAdditionalProperties(left, right, context);

            var allIncreasedProperties = FilterProperties(TypeEnum.Added, propertyDiff.Increased, context);

            foreach (var(key, value) in allIncreasedProperties)
            {
                ChangedSchema.IncreasedProperties.Add(key, value);
            }
            var allMissingProperties = FilterProperties(TypeEnum.Removed, propertyDiff.Missing, context);

            foreach (var(key, value) in allMissingProperties)
            {
                ChangedSchema.MissingProperties.Add(key, value);
            }

            return(IsApplicable(context));
        }
Пример #29
0
        protected override ChangedSchemaBO ComputeDiff(OpenApiSchema left, OpenApiSchema right, DiffContextBO context)
        {
            var leftRef  = GetSchemaRef(left);
            var rightRef = GetSchemaRef(right);

            left  = RefPointer.ResolveRef(_leftComponents, left, GetSchemaRef(left));
            right = RefPointer.ResolveRef(_rightComponents, right, GetSchemaRef(right));

            // If type of schemas are different, just set old & new schema, set changedType to true in
            // SchemaDiffResult and
            // return the object
            if (left == null || right == null ||
                left.Type != right.Type ||
                left.Format != right.Format)
            {
                return(GetTypeChangedSchema(left, right, context));
            }

            // If schema type is same then get specific SchemaDiffResult and compare the properties
            var result = GetSchemaDiffResult(right, _openApiDiff);

            return(result.Diff(_leftComponents, _rightComponents, left, right, context));
        }
Пример #30
0
 private static bool IsPropertyApplicable(OpenApiSchema schema, DiffContextBO context)
 {
     return(!(context.IsResponse && schema.WriteOnly) && !(context.IsRequest && schema.ReadOnly));
 }