From f44c6133fc844e4e9baf2cf9d0a72025ce16a664 Mon Sep 17 00:00:00 2001 From: Artyom Kartasov Date: Thu, 6 Apr 2023 04:56:27 +0700 Subject: [PATCH] fix: adjust API protocols (#17) * adjust Dalibo API protocol * update name of the plan field in Tensor's API requests --- client/client.go | 13 ++++++- visualizer/dalibo/dalibo.go | 67 +++++++++++++++++++++++++++++++------ visualizer/tensor/tensor.go | 2 +- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/client/client.go b/client/client.go index ba3c89b..9a1eb03 100644 --- a/client/client.go +++ b/client/client.go @@ -3,11 +3,12 @@ package client import ( "fmt" + "io" "net/http" "net/url" ) -// MakeRequest performs the request and returns the redirected request URL. +// MakeRequest performs request and returns the redirected request URL. func MakeRequest(targetURL string, formVal url.Values) (string, error) { response, err := http.PostForm(targetURL, formVal) // nolint:gosec if err != nil { @@ -20,3 +21,13 @@ func MakeRequest(targetURL string, formVal url.Values) (string, error) { return response.Request.URL.String(), nil } + +// MakeRequestWithBody performs request and returns response. +func MakeRequestWithBody(targetURL string, formVal url.Values) (io.ReadCloser, error) { + response, err := http.PostForm(targetURL, formVal) // nolint:gosec + if err != nil { + return nil, fmt.Errorf("failed to post form: %w", err) + } + + return response.Body, nil +} diff --git a/visualizer/dalibo/dalibo.go b/visualizer/dalibo/dalibo.go index de8cabd..d9d1c7d 100644 --- a/visualizer/dalibo/dalibo.go +++ b/visualizer/dalibo/dalibo.go @@ -2,17 +2,26 @@ package dalibo import ( + "encoding/json" "fmt" + "io" "net/url" + "strings" + "time" "github.com/agneum/plan-exporter/client" ) // Visualizer constants. const ( - VisualizerType = "dalibo" - defaultPostURL = "https://explain.dalibo.com/new" - planKey = "plan" + VisualizerType = "dalibo" + defaultPostURL = "https://explain.dalibo.com" + newPlanRoute = "new.json" + planResponseRoute = "plan" + + planKey = "plan" + titleKey = "title" + queryKey = "query" ) // Dalibo defines a query plan exporter for the Dalibo visualizer. @@ -20,28 +29,66 @@ type Dalibo struct { postURL string } +// PlanResponse represents response body. +type PlanResponse struct { + ID string `json:"id"` + DeleteKey string `json:"deleteKey"` +} + // New creates a new Dalibo exporter. func New(postURL string) *Dalibo { if postURL == "" { postURL = defaultPostURL } - return &Dalibo{postURL: postURL} + return &Dalibo{ + postURL: postURL, + } +} + +// Target returns a post URL. +func (d *Dalibo) Target() string { + return d.postURL } // Export posts plan to a visualizer and returns link to the visualization plan page. func (d *Dalibo) Export(plan string) (string, error) { - formVal := url.Values{planKey: []string{plan}} + formVal := url.Values{ + planKey: []string{strings.TrimSpace(plan)}, + titleKey: []string{fmt.Sprintf("Plan created on %s", time.Now().Format(time.RFC1123))}, + queryKey: []string{""}, + } + + requestURL, err := url.JoinPath(d.postURL, newPlanRoute) + if err != nil { + return "", fmt.Errorf("failed to build request URL: %w", err) + } - explainURL, err := client.MakeRequest(d.postURL, formVal) + planBody, err := client.MakeRequestWithBody(requestURL, formVal) + if err != nil { + return "", fmt.Errorf("failed to build request URL: %w", err) + } + + defer func() { _ = planBody.Close() }() + + planResponse, err := d.parseBody(planBody) if err != nil { return "", fmt.Errorf("failed to make a request: %w", err) } - return explainURL, nil + return d.buildShareLink(planResponse.ID) } -// Target returns a post URL. -func (d *Dalibo) Target() string { - return d.postURL +func (d *Dalibo) parseBody(body io.ReadCloser) (*PlanResponse, error) { + var plan PlanResponse + + if err := json.NewDecoder(body).Decode(&plan); err != nil { + return nil, err + } + + return &plan, nil +} + +func (d *Dalibo) buildShareLink(id string) (string, error) { + return url.JoinPath(d.postURL, planResponseRoute, id) } diff --git a/visualizer/tensor/tensor.go b/visualizer/tensor/tensor.go index e38d21a..f0cba13 100644 --- a/visualizer/tensor/tensor.go +++ b/visualizer/tensor/tensor.go @@ -12,7 +12,7 @@ import ( const ( VisualizerType = "tensor" defaultPostURL = "https://explain.tensor.ru/explain" - planKey = "explain" + planKey = "plan" ) // Tensor defines a query plan exporter for the Tensor visualizer.