From be6e5672913798f29e99014a2ccffb2d78a7eca6 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 9 Aug 2024 13:38:18 -0700 Subject: [PATCH] checkpoint Signed-off-by: Jeff Ortel --- api/file.go | 3 + binding/application.go | 6 +- binding/client.go | 173 ++++++++++++++++++++--------------------- binding/file.go | 16 +++- hack/add/file.sh | 2 +- migration/pkg.go | 2 + model/pkg.go | 2 +- 7 files changed, 110 insertions(+), 94 deletions(-) diff --git a/api/file.go b/api/file.go index 5e280172f..7030d6953 100644 --- a/api/file.go +++ b/api/file.go @@ -79,6 +79,7 @@ func (h FileHandler) Create(ctx *gin.Context) { } m := &model.File{} m.Name = ctx.Param(ID) + m.Encoding = input.Header.Get(ContentType) m.CreateUser = h.BaseHandler.CurrentUser(ctx) result := h.DB(ctx).Create(&m) if result.Error != nil { @@ -245,6 +246,7 @@ type File struct { Resource `yaml:",inline"` Name string `json:"name"` Path string `json:"path"` + Encoding string `yaml:"encoding"` Expiration *time.Time `json:"expiration,omitempty"` } @@ -253,5 +255,6 @@ func (r *File) With(m *model.File) { r.Resource.With(&m.Model) r.Name = m.Name r.Path = m.Path + r.Encoding = m.Encoding r.Expiration = m.Expiration } diff --git a/binding/application.go b/binding/application.go index 6ea9070ca..f65f743a1 100644 --- a/binding/application.go +++ b/binding/application.go @@ -333,7 +333,7 @@ func (h *Analysis) Create(commit, encoding, issues, deps string) (err error) { } r := api.AnalysisManifest{Commit: commit} file := File{client: h.client} - f, err := file.Post(issues) + f, err := file.PostEncoded(issues, encoding) if err != nil { return } @@ -341,7 +341,7 @@ func (h *Analysis) Create(commit, encoding, issues, deps string) (err error) { defer func() { _ = file.Delete(f.ID) }() - f, err = file.Post(deps) + f, err = file.PostEncoded(deps, encoding) if err != nil { return } @@ -350,7 +350,7 @@ func (h *Analysis) Create(commit, encoding, issues, deps string) (err error) { _ = file.Delete(f.ID) }() path := Path(api.AppAnalysesRoot).Inject(Params{api.ID: h.appId}) - err = h.client.Encoding(encoding).Post(path, r) + err = h.client.Post(path, r) if err != nil { return } diff --git a/binding/client.go b/binding/client.go index 4e6c0b08f..2cbca1689 100644 --- a/binding/client.go +++ b/binding/client.go @@ -21,7 +21,6 @@ import ( "github.com/konveyor/tackle2-hub/api" qf "github.com/konveyor/tackle2-hub/binding/filter" "github.com/konveyor/tackle2-hub/tar" - "gopkg.in/yaml.v2" ) const ( @@ -72,8 +71,7 @@ func (s Path) Inject(p Params) (out string) { // NewClient Constructs a new client func NewClient(baseURL string) (client *Client) { client = &Client{ - encoding: binding.MIMEJSON, - BaseURL: baseURL, + BaseURL: baseURL, } client.Retry = RetryLimit return @@ -81,8 +79,6 @@ func NewClient(baseURL string) (client *Client) { // Client provides a REST client. type Client struct { - // encoding - encoding string // transport transport http.RoundTripper // baseURL for the nub. @@ -100,17 +96,6 @@ func (r *Client) Reset() { r.Error = nil } -// Encoding returns a client with the specified encoding. -func (r *Client) Encoding(encoding string) (r2 *Client) { - r2 = &Client{ - encoding: encoding, - transport: r.transport, - BaseURL: r.BaseURL, - Login: r.Login, - } - return -} - // Get a resource. func (r *Client) Get(path string, object any, params ...Param) (err error) { request := func() (request *http.Request, err error) { @@ -119,6 +104,7 @@ func (r *Client) Get(path string, object any, params ...Param) (err error) { Method: http.MethodGet, URL: r.join(path), } + request.Header.Set(api.Accept, binding.MIMEJSON) if len(params) > 0 { q := request.URL.Query() for _, p := range params { @@ -138,7 +124,17 @@ func (r *Client) Get(path string, object any, params ...Param) (err error) { status := response.StatusCode switch status { case http.StatusOK: - err = r.decode(object, response) + var body []byte + body, err = io.ReadAll(response.Body) + if err != nil { + err = liberr.Wrap(err) + return + } + err = json.Unmarshal(body, object) + if err != nil { + err = liberr.Wrap(err) + return + } default: err = r.restError(response) } @@ -149,16 +145,19 @@ func (r *Client) Get(path string, object any, params ...Param) (err error) { // Post a resource. func (r *Client) Post(path string, object any) (err error) { request := func() (request *http.Request, err error) { - body, err := r.encode(object) + bfr, err := json.Marshal(object) if err != nil { + err = liberr.Wrap(err) return } + reader := bytes.NewReader(bfr) request = &http.Request{ Header: http.Header{}, Method: http.MethodPost, - Body: io.NopCloser(body), + Body: io.NopCloser(reader), URL: r.join(path), } + request.Header.Set(api.Accept, binding.MIMEJSON) return } response, err := r.send(request) @@ -171,7 +170,17 @@ func (r *Client) Post(path string, object any) (err error) { case http.StatusNoContent: case http.StatusOK, http.StatusCreated: - err = r.decode(object, response) + var body []byte + body, err = io.ReadAll(response.Body) + if err != nil { + err = liberr.Wrap(err) + return + } + err = json.Unmarshal(body, object) + if err != nil { + err = liberr.Wrap(err) + return + } default: err = r.restError(response) } @@ -181,16 +190,19 @@ func (r *Client) Post(path string, object any) (err error) { // Put a resource. func (r *Client) Put(path string, object any, params ...Param) (err error) { request := func() (request *http.Request, err error) { - body, err := r.encode(object) + bfr, err := json.Marshal(object) if err != nil { + err = liberr.Wrap(err) return } + reader := bytes.NewReader(bfr) request = &http.Request{ Header: http.Header{}, Method: http.MethodPut, - Body: io.NopCloser(body), + Body: io.NopCloser(reader), URL: r.join(path), } + request.Header.Set(api.Accept, binding.MIMEJSON) if len(params) > 0 { q := request.URL.Query() for _, p := range params { @@ -210,7 +222,17 @@ func (r *Client) Put(path string, object any, params ...Param) (err error) { case http.StatusNoContent: case http.StatusOK, http.StatusCreated: - err = r.decode(object, response) + var body []byte + body, err = io.ReadAll(response.Body) + if err != nil { + err = liberr.Wrap(err) + return + } + err = json.Unmarshal(body, object) + if err != nil { + err = liberr.Wrap(err) + return + } default: err = r.restError(response) } @@ -221,16 +243,19 @@ func (r *Client) Put(path string, object any, params ...Param) (err error) { // Patch a resource. func (r *Client) Patch(path string, object any, params ...Param) (err error) { request := func() (request *http.Request, err error) { - body, err := r.encode(object) + bfr, err := json.Marshal(object) if err != nil { + err = liberr.Wrap(err) return } + reader := bytes.NewReader(bfr) request = &http.Request{ Header: http.Header{}, Method: http.MethodPatch, - Body: io.NopCloser(body), + Body: io.NopCloser(reader), URL: r.join(path), } + request.Header.Set(api.Accept, binding.MIMEJSON) if len(params) > 0 { q := request.URL.Query() for _, p := range params { @@ -250,7 +275,17 @@ func (r *Client) Patch(path string, object any, params ...Param) (err error) { case http.StatusNoContent: case http.StatusOK, http.StatusCreated: - err = r.decode(object, response) + var body []byte + body, err = io.ReadAll(response.Body) + if err != nil { + err = liberr.Wrap(err) + return + } + err = json.Unmarshal(body, object) + if err != nil { + err = liberr.Wrap(err) + return + } default: err = r.restError(response) } @@ -266,6 +301,7 @@ func (r *Client) Delete(path string, params ...Param) (err error) { Method: http.MethodDelete, URL: r.join(path), } + request.Header.Set(api.Accept, binding.MIMEJSON) if len(params) > 0 { q := request.URL.Query() for _, p := range params { @@ -421,11 +457,19 @@ func (r *Client) FileGet(path, destination string) (err error) { // FilePost uploads a file. // Returns the created File resource. func (r *Client) FilePost(path, source string, object any) (err error) { + err = r.FilePostEncoded(path, source, object, "") + return +} + +// FilePostEncoded uploads a file. +// Returns the created File resource. +func (r *Client) FilePostEncoded(path, source string, object any, encoding string) (err error) { if source == "" { fields := []Field{ { - Name: api.FileField, - Reader: bytes.NewReader([]byte{}), + Name: api.FileField, + Reader: bytes.NewReader([]byte{}), + Encoding: encoding, }, } err = r.FileSend(path, http.MethodPost, fields, object) @@ -442,8 +486,9 @@ func (r *Client) FilePost(path, source string, object any) (err error) { } fields := []Field{ { - Name: api.FileField, - Path: source, + Name: api.FileField, + Path: source, + Encoding: encoding, }, } err = r.FileSend(path, http.MethodPost, fields, object) @@ -453,11 +498,19 @@ func (r *Client) FilePost(path, source string, object any) (err error) { // FilePut uploads a file. // Returns the created File resource. func (r *Client) FilePut(path, source string, object any) (err error) { + err = r.FilePutEncoded(path, source, object, "") + return +} + +// FilePutEncoded uploads a file. +// Returns the created File resource. +func (r *Client) FilePutEncoded(path, source string, object any, encoding string) (err error) { if source == "" { fields := []Field{ { - Name: api.FileField, - Reader: bytes.NewReader([]byte{}), + Name: api.FileField, + Reader: bytes.NewReader([]byte{}), + Encoding: encoding, }, } err = r.FileSend(path, http.MethodPut, fields, object) @@ -506,6 +559,7 @@ func (r *Client) FileSend(path, method string, fields []Field, object any) (err URL: r.join(path), } mp := multipart.NewWriter(pw) + request.Header.Set(api.Accept, binding.MIMEJSON) request.Header.Add(api.ContentType, mp.FormDataContentType()) go func() { var err error @@ -648,24 +702,6 @@ func (r *Client) send(rb func() (*http.Request, error)) (response *http.Response if err != nil { return } - switch r.encoding { - case "": - fallthrough - case binding.MIMEJSON, - binding.MIMEYAML: - h := request.Header - if h.Get(api.ContentType) == "" { - h.Set(api.ContentType, r.encoding) - } - if h.Get(api.Accept) == "" { - h.Set(api.Accept, r.encoding) - } - default: - err = liberr.New( - "Encoding: %s not supported.", - r.Encoding) - return - } request.Header.Set(api.Authorization, "Bearer "+r.Login.Token) client := http.Client{Transport: r.transport} response, err = client.Do(request) @@ -758,43 +794,6 @@ func (r *Client) restError(response *http.Response) (err error) { return } -// decode body into object. -func (r *Client) decode(object any, response *http.Response) (err error) { - encoding := response.Header.Get(api.ContentType) - encoding = strings.Split(encoding, ";")[0] - encoding = strings.TrimSpace(encoding) - switch encoding { - case "", binding.MIMEJSON: - d := json.NewDecoder(response.Body) - err = d.Decode(object) - err = liberr.Wrap(err) - case binding.MIMEYAML: - d := yaml.NewDecoder(response.Body) - err = d.Decode(object) - err = liberr.Wrap(err) - default: - err = liberr.New("Encoding: %s not supported.", encoding) - } - return -} - -// bind response. -func (r *Client) encode(object any) (reader io.Reader, err error) { - var b []byte - switch r.encoding { - case "", binding.MIMEJSON: - b, err = json.Marshal(object) - case binding.MIMEYAML: - b, err = yaml.Marshal(object) - default: - err = liberr.New("Encoding: %s not supported.", r.Encoding) - } - if err == nil { - reader = bytes.NewReader(b) - } - return -} - // Field file upload form field. type Field struct { Name string diff --git a/binding/file.go b/binding/file.go index 22bdcb80b..86bd3d94b 100644 --- a/binding/file.go +++ b/binding/file.go @@ -42,17 +42,29 @@ func (h *File) Touch(name string) (r *api.File, err error) { // Post uploads a file. func (h *File) Post(source string) (r *api.File, err error) { + r, err = h.PostEncoded(source, "") + return +} + +// PostEncoded uploads a file. +func (h *File) PostEncoded(source string, encoding string) (r *api.File, err error) { r = &api.File{} path := Path(api.FileRoot).Inject(Params{api.ID: pathlib.Base(source)}) - err = h.client.FilePost(path, source, r) + err = h.client.FilePostEncoded(path, source, r, encoding) return } // Put uploads a file. func (h *File) Put(source string) (r *api.File, err error) { + r, err = h.PutEncoded(source, "") + return +} + +// PutEncoded uploads a file. +func (h *File) PutEncoded(source string, encoding string) (r *api.File, err error) { r = &api.File{} path := Path(api.FileRoot).Inject(Params{api.ID: pathlib.Base(source)}) - err = h.client.FilePut(path, source, r) + err = h.client.FilePutEncoded(path, source, r, encoding) return } diff --git a/hack/add/file.sh b/hack/add/file.sh index 6c52fe4bf..b733babc6 100755 --- a/hack/add/file.sh +++ b/hack/add/file.sh @@ -4,5 +4,5 @@ host="${HOST:-localhost:8080}" path="${1:-/etc/hosts}" name=$(basename ${path}) -curl -F "file=@${path}" http://${host}/files/${name} | jq . +curl -F "file=@${path};type=application/x-yaml" http://${host}/files/${name} | jq . diff --git a/migration/pkg.go b/migration/pkg.go index f80ed8e48..5caaecbd8 100644 --- a/migration/pkg.go +++ b/migration/pkg.go @@ -7,6 +7,7 @@ import ( v12 "github.com/konveyor/tackle2-hub/migration/v12" v13 "github.com/konveyor/tackle2-hub/migration/v13" v14 "github.com/konveyor/tackle2-hub/migration/v14" + v15 "github.com/konveyor/tackle2-hub/migration/v15" v2 "github.com/konveyor/tackle2-hub/migration/v2" v3 "github.com/konveyor/tackle2-hub/migration/v3" v4 "github.com/konveyor/tackle2-hub/migration/v4" @@ -56,5 +57,6 @@ func All() []Migration { v12.Migration{}, v13.Migration{}, v14.Migration{}, + v15.Migration{}, } } diff --git a/model/pkg.go b/model/pkg.go index 2cb906e60..9395526e3 100644 --- a/model/pkg.go +++ b/model/pkg.go @@ -2,7 +2,7 @@ package model import ( "github.com/konveyor/tackle2-hub/migration/json" - "github.com/konveyor/tackle2-hub/migration/v14/model" + "github.com/konveyor/tackle2-hub/migration/v15/model" ) // Field (data) types.