diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-03-16 13:43:51 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-03-23 12:13:16 +0100 |
commit | 5d83a7b7c3ecd8dc5f1bd4e307cb75d9b69bc170 (patch) | |
tree | bb3abb974fbb81fcfda8325642aeb878626ac813 /client | |
parent | 2e59f4598a3f487c6c73c4b2fbc247668841a14b (diff) |
Initial client
Diffstat (limited to 'client')
-rw-r--r-- | client/go/internal/vespa/feed/http.go | 65 | ||||
-rw-r--r-- | client/go/internal/vespa/feed/http_test.go | 41 |
2 files changed, 106 insertions, 0 deletions
diff --git a/client/go/internal/vespa/feed/http.go b/client/go/internal/vespa/feed/http.go new file mode 100644 index 00000000000..f0b7eb42aa6 --- /dev/null +++ b/client/go/internal/vespa/feed/http.go @@ -0,0 +1,65 @@ +package feed + +import ( + "bytes" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/vespa-engine/vespa/client/go/internal/util" +) + +// Client represents a HTTP client for the /document/v1/ API. +type Client struct { + options ClientOptions + httpClient util.HTTPClient +} + +// ClientOptions specifices the configuration options of a feed client. +type ClientOptions struct { + BaseURL string + Timeout time.Duration + Route string + TraceLevel *int +} + +// Result represents the result of a feeding operation +type Result struct{} + +func NewClient(options ClientOptions, httpClient util.HTTPClient) *Client { + return &Client{options: options, httpClient: httpClient} +} + +func (c *Client) queryParams() url.Values { + params := url.Values{} + if c.options.Timeout > 0 { + params.Set("timeout", strconv.FormatInt(c.options.Timeout.Milliseconds(), 10)+"ms") + } + if c.options.Route != "" { + params.Set("route", c.options.Route) + } + if c.options.TraceLevel != nil { + params.Set("tracelevel", strconv.Itoa(*c.options.TraceLevel)) + } + return params +} + +// Send given document the URL configured in this client. +func (c *Client) Send(document Document) (Result, error) { + method, url, err := document.FeedURL(c.options.BaseURL, c.queryParams()) + if err != nil { + return Result{}, err + } + body := document.Body() + req, err := http.NewRequest(method, url.String(), bytes.NewReader(body)) + if err != nil { + return Result{}, err + } + resp, err := c.httpClient.Do(req, c.options.Timeout) + if err != nil { + return Result{}, err + } + defer resp.Body.Close() + return Result{}, nil +} diff --git a/client/go/internal/vespa/feed/http_test.go b/client/go/internal/vespa/feed/http_test.go new file mode 100644 index 00000000000..5c9378ab5f7 --- /dev/null +++ b/client/go/internal/vespa/feed/http_test.go @@ -0,0 +1,41 @@ +package feed + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "testing" + "time" + + "github.com/vespa-engine/vespa/client/go/internal/mock" +) + +func TestClientSend(t *testing.T) { + doc := Document{Create: true, UpdateId: "id:ns:type::doc1", Fields: json.RawMessage(`{"foo": "123"}`)} + httpClient := mock.HTTPClient{} + client := NewClient(ClientOptions{ + BaseURL: "https://example.com:1337", + Timeout: time.Duration(5 * time.Second), + }, &httpClient) + _, err := client.Send(doc) + if err != nil { + t.Fatalf("got unexpected error %q", err) + } + r := httpClient.LastRequest + if r.Method != http.MethodPut { + t.Errorf("got r.Method = %q, want %q", r.Method, http.MethodPut) + } + wantURL := "https://example.com:1337/document/v1/ns/type/docid/doc1?create=true&timeout=5000ms" + if r.URL.String() != wantURL { + t.Errorf("got r.URL = %q, want %q", r.URL, wantURL) + } + body, err := io.ReadAll(r.Body) + if err != nil { + t.Fatalf("got unexpected error %q", err) + } + wantBody := []byte(`{"fields":{"foo": "123"}}`) + if !bytes.Equal(body, wantBody) { + t.Errorf("got r.Body = %q, want %q", string(body), string(wantBody)) + } +} |