Skip to content

Commit

Permalink
Merge pull request #34 from FireTail-io/load-spec-from-bytes
Browse files Browse the repository at this point in the history
Load spec from bytes

Override merge b/c github does not respect my reviews!!!
  • Loading branch information
timoruppell authored Feb 7, 2024
2 parents df0ff9e + f7130da commit 5160c3f
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
56 changes: 41 additions & 15 deletions middlewares/http/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package firetail
import (
"bytes"
"context"
"errors"
"io"
"io/ioutil"
"net/http"
Expand All @@ -22,21 +23,9 @@ func GetMiddleware(options *Options) (func(next http.Handler) http.Handler, erro
options.setDefaults() // Fill in any defaults where apropriate

// Load in our appspec, validate it & create a router from it if we have an appspec to load
var router routers.Router
if options.OpenapiSpecPath != "" {
loader := &openapi3.Loader{Context: context.Background(), IsExternalRefsAllowed: true}
doc, err := loader.LoadFromFile(options.OpenapiSpecPath)
if err != nil {
return nil, ErrorInvalidConfiguration{err}
}
err = doc.Validate(context.Background())
if err != nil {
return nil, ErrorAppspecInvalid{err}
}
router, err = gorillamux.NewRouter(doc)
if err != nil {
return nil, err
}
router, err := getRouter(options)
if err != nil {
return nil, err
}

// Register any custom body decoders
Expand Down Expand Up @@ -239,3 +228,40 @@ func GetMiddleware(options *Options) (func(next http.Handler) http.Handler, erro

return middleware, nil
}

func getRouter(options *Options) (routers.Router, error) {
hasBytes := options.OpenapiBytes != nil && len(options.OpenapiBytes) > 0
hasSpecPath := options.OpenapiSpecPath != ""

if !hasBytes && !hasSpecPath {
return nil, nil
}

loader := &openapi3.Loader{Context: context.Background(), IsExternalRefsAllowed: true}

var doc *openapi3.T
var err error
if hasBytes {
doc, err = loader.LoadFromData(options.OpenapiBytes)
} else if hasSpecPath {
doc, err = loader.LoadFromFile(options.OpenapiSpecPath)
}
if err != nil {
return nil, ErrorInvalidConfiguration{err}
}
if doc == nil {
return nil, ErrorInvalidConfiguration{errors.New("OpenAPI doc was nil after loading from file or data")}
}

Check warning on line 254 in middlewares/http/middleware.go

View check run for this annotation

Codecov / codecov/patch

middlewares/http/middleware.go#L253-L254

Added lines #L253 - L254 were not covered by tests

err = doc.Validate(context.Background())
if err != nil {
return nil, ErrorAppspecInvalid{err}
}

router, err := gorillamux.NewRouter(doc)
if err != nil {
return nil, err
}

Check warning on line 264 in middlewares/http/middleware.go

View check run for this annotation

Codecov / codecov/patch

middlewares/http/middleware.go#L263-L264

Added lines #L263 - L264 were not covered by tests

return router, nil
}
13 changes: 13 additions & 0 deletions middlewares/http/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ import (
"net/http/httptest"
"testing"

_ "embed"

"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/sbabiv/xml2map"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

//go:embed test-spec.yaml
var openapiSpecBytes []byte

var healthHandler http.HandlerFunc = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Header().Add("Content-Type", "application/json")
Expand Down Expand Up @@ -124,6 +129,14 @@ func TestInvalidSpec(t *testing.T) {
require.Equal(t, "invalid appspec: invalid paths: invalid path /health: invalid operation GET: a short description of the response is required", err.Error())
}

func TestSpecFromBytes(t *testing.T) {
middleware, err := GetMiddleware(&Options{
OpenapiBytes: openapiSpecBytes,
})
require.Nil(t, err)
require.NotNil(t, middleware)
}

func TestRequestToInvalidRoute(t *testing.T) {
middleware, err := GetMiddleware(&Options{
OpenapiSpecPath: "./test-spec.yaml",
Expand Down
4 changes: 4 additions & 0 deletions middlewares/http/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ type Options struct {
// SpecPath is the path at which your openapi spec can be found. Supplying an empty string disables any validation.
OpenapiSpecPath string

// OpenapiBytes is the raw bytes of your openapi spec. Supplying an empty slice disables any validation. OpenapiBytes takes
// precedence over OpenapiSpecPath if both are provided. OpenapiSpecPath will be used if OpenapiBytes is nil or len() == 0
OpenapiBytes []byte

// LogsApiToken is the API token which will be used when sending logs to the Firetail logging API with the default batch callback.
// This value should typically be loaded in from an environment variable. If unset, the default batch callback will not forward
// logs to the Firetail SaaS
Expand Down

0 comments on commit 5160c3f

Please sign in to comment.