Skip to content

Commit

Permalink
CLOUDP-236398: Add validation logic for paths (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaangiolillo committed Mar 11, 2024
1 parent 61a4368 commit 3ed479c
Show file tree
Hide file tree
Showing 8 changed files with 1,968 additions and 3 deletions.
19 changes: 16 additions & 3 deletions tools/cli/internal/cli/merge/merge.go
Expand Up @@ -19,6 +19,7 @@ import (
"log"
"mongodb/openapi/tools/cli/internal/cli/flag"
"mongodb/openapi/tools/cli/internal/cli/usage"
"mongodb/openapi/tools/cli/internal/openapi"
"os"

"github.com/spf13/cobra"
Expand All @@ -29,14 +30,24 @@ const (
)

type Opts struct {
Merger openapi.Merger
basePath string
outputPath string
externalPaths []string
}

func (o *Opts) Run(_ []string) error {
// To add in follow up PR: CLOUDP-225849
return o.saveFile([]byte("test"))
federated, err := o.Merger.MergeOpenAPISpecs(o.externalPaths)
if err != nil {
return err
}

federatedBytes, err := federated.Spec.MarshalJSON()
if err != nil {
return err
}

return o.saveFile(federatedBytes)
}

func (o *Opts) PreRunE(_ []string) error {
Expand All @@ -48,7 +59,9 @@ func (o *Opts) PreRunE(_ []string) error {
return fmt.Errorf("no external OAS detected. Please, use the flag %s to include at least one OAS", flag.External)
}

return nil
m, err := openapi.NewOasDiff(o.basePath)
o.Merger = m
return err
}

func (o *Opts) saveFile(data []byte) error {
Expand Down
11 changes: 11 additions & 0 deletions tools/cli/internal/openapi/errors/path_conflict_error.go
@@ -0,0 +1,11 @@
package errors

import "fmt"

type PathConflictError struct {
Entry string
}

func (e PathConflictError) Error() string {
return fmt.Sprintf("there was a conflict with the path: %q", e.Entry)
}
78 changes: 78 additions & 0 deletions tools/cli/internal/openapi/oasdiff.go
@@ -0,0 +1,78 @@
package openapi

import (
"log"
"mongodb/openapi/tools/cli/internal/openapi/errors"

"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

type OasDiff struct {
base *load.SpecInfo
external *load.SpecInfo
config *diff.Config
specDiff *diff.Diff
parser Parser
}

func NewOasDiff(base string) (*OasDiff, error) {
parser := NewOpenAPI3()
baseSpec, err := parser.CreateOpenAPISpecFromPath(base)
if err != nil {
return nil, err
}

return &OasDiff{
base: baseSpec,
parser: parser,
config: &diff.Config{
IncludePathParams: true,
},
}, nil
}

func (o *OasDiff) MergeOpenAPISpecs(paths []string) (*load.SpecInfo, error) {
for _, p := range paths {
spec, err := o.parser.CreateOpenAPISpecFromPath(p)
if err != nil {
return nil, err
}

specDiff, err := diff.Get(o.config, o.base.Spec, spec.Spec)
if err != nil {
log.Fatalf("error in calculating the diff of the specs: %s", err)
return nil, err
}

o.specDiff = specDiff
o.external = spec
err = o.mergeSpecIntoBase()
if err != nil {
return nil, err
}
}

return o.base, nil
}

func (o OasDiff) mergeSpecIntoBase() error {
return o.mergePaths()
}

func (o OasDiff) mergePaths() error {
pathsToMerge := o.external.Spec.Paths
basePaths := o.base.Spec.Paths
for k, v := range pathsToMerge {
if _, ok := basePaths[k]; !ok {
basePaths[k] = v
} else {
return errors.PathConflictError{
Entry: k,
}
}
}

o.base.Spec.Paths = basePaths
return nil
}
13 changes: 13 additions & 0 deletions tools/cli/internal/openapi/openapi.go
@@ -0,0 +1,13 @@
package openapi

import (
"github.com/tufin/oasdiff/load"
)

type Merger interface {
MergeOpenAPISpecs([]string) (*load.SpecInfo, error)
}

type Parser interface {
CreateOpenAPISpecFromPath(string) (*load.SpecInfo, error)
}
31 changes: 31 additions & 0 deletions tools/cli/internal/openapi/openapi3.go
@@ -0,0 +1,31 @@
package openapi

import (
"github.com/getkin/kin-openapi/openapi3"
"github.com/tufin/oasdiff/load"
)

type OpenAPI3 struct {
IsExternalRefsAllowed bool
CircularReferenceCounter int
}

func NewOpenAPI3() *OpenAPI3 {
return &OpenAPI3{
IsExternalRefsAllowed: true,
CircularReferenceCounter: 10,
}
}

func (o *OpenAPI3) CreateOpenAPISpecFromPath(path string) (*load.SpecInfo, error) {
openapi3.CircularReferenceCounter = o.CircularReferenceCounter
loader := openapi3.NewLoader()
loader.IsExternalRefsAllowed = o.IsExternalRefsAllowed

spec, err := load.LoadSpecInfo(loader, load.NewSource(path))
if err != nil {
return nil, err
}

return spec, nil
}

0 comments on commit 3ed479c

Please sign in to comment.