Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add query params support #112

Merged
merged 2 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ linters:
- errorlint
- forbidigo
- forcetypeassert
- funlen
- gocognit
- goconst
- gocyclo
Expand All @@ -23,21 +22,18 @@ linters:
- govet
- importas
- ineffassign
- lll
- makezero
- misspell
- nakedret
- nestif
- nilerr
- nlreturn
- prealloc
- revive
- staticcheck
- typecheck
- unconvert
- unused
- whitespace
- wsl

linters-settings:
gocognit:
Expand Down
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ tasks:
cmds:
- rm -rf {{.GEN_OUT_DIR}}
- GEN_OUT_DIR={{.GEN_OUT_DIR}} go run -tags=generator ./generator/...
- task: fmt-imports
generate:
cmds:
- task: get-openapi-spec
- task: go-generate
- task: fmt-imports
test:
cmds:
- go test -v ./...
30 changes: 17 additions & 13 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,9 @@ type aivenClient struct {
// OperationIDKey is the key used to store the operation ID in the context.
type OperationIDKey struct{}

func (d *aivenClient) Do(ctx context.Context, operationID, method, path string, v any) ([]byte, error) {
func (d *aivenClient) Do(ctx context.Context, operationID, method, path string, in any, query ...[2]string) ([]byte, error) {
ctx = context.WithValue(ctx, OperationIDKey{}, operationID)

var rsp *http.Response

var err error

if d.Debug {
Expand All @@ -105,7 +103,7 @@ func (d *aivenClient) Do(ctx context.Context, operationID, method, path string,
}()
}

rsp, err = d.do(ctx, method, path, v)
rsp, err = d.do(ctx, method, path, in, query...)
if err != nil {
return nil, err
}
Expand All @@ -122,11 +120,11 @@ func (d *aivenClient) Do(ctx context.Context, operationID, method, path string,
return b, err
}

func (d *aivenClient) do(ctx context.Context, method, path string, v any) (*http.Response, error) {
func (d *aivenClient) do(ctx context.Context, method, path string, in any, query ...[2]string) (*http.Response, error) {
var body io.Reader

if !(v == nil || isEmpty(v)) {
b, err := json.Marshal(v)
if !(in == nil || isEmpty(in)) {
b, err := json.Marshal(in)
if err != nil {
return nil, err
}
Expand All @@ -143,13 +141,19 @@ func (d *aivenClient) do(ctx context.Context, method, path string, v any) (*http
req.Header.Set("User-Agent", d.UserAgent)
req.Header.Set("Authorization", "aivenv1 "+d.Token)

// TODO: BAD hack to get around pagination in most cases
// we should implement this properly at some point but for now
// that should be its own issue
query := req.URL.Query()
query.Add("limit", "999")
req.URL.RawQuery = query.Encode()
q := req.URL.Query()
for _, v := range query {
q.Set(v[0], v[1])
}

if !q.Has("limit") {
// TODO: BAD hack to get around pagination in most cases
// we should implement this properly at some point but for now
// that should be its own issue
q.Set("limit", "999")
}

req.URL.RawQuery = q.Encode()
return d.doer.Do(req)
}

Expand Down
3 changes: 2 additions & 1 deletion client_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 57 additions & 20 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import (
"net/http/httptest"
"os"
"strings"
"sync/atomic"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aiven/go-client-codegen/handler/clickhouse"
"github.com/aiven/go-client-codegen/handler/service"
)

Expand Down Expand Up @@ -41,24 +43,44 @@ func TestNewClient(t *testing.T) {
}

func TestServiceCreate(t *testing.T) {
var callCount int64

// Creates a test server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/v1/project/foo/service", r.URL.Path)

// Validates request
expectIn := new(service.ServiceCreateIn)
err := json.NewDecoder(r.Body).Decode(expectIn)
assert.NoError(t, err)
assert.Equal(t, "foo", expectIn.ServiceName)
assert.Equal(t, "kafka", expectIn.ServiceType)
assert.Regexp(t, `go-client-codegen/[0-9\.]+ unit-test`, r.Header["User-Agent"])

// Creates response
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, err = w.Write([]byte(`{"service": {"plan": "wow", "state": "RUNNING"}}`))
require.NoError(t, err)
}))
mux := http.NewServeMux()
mux.HandleFunc(
"/v1/project/aiven-project/service",
func(w http.ResponseWriter, r *http.Request) {
// Validates request
expectIn := new(service.ServiceCreateIn)
err := json.NewDecoder(r.Body).Decode(expectIn)
assert.NoError(t, err)
assert.Equal(t, "my-clickhouse", expectIn.ServiceName)
assert.Equal(t, "clickhouse", expectIn.ServiceType)
assert.Regexp(t, `go-client-codegen/[0-9\.]+ unit-test`, r.Header["User-Agent"])

// Creates response
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, err = w.Write([]byte(`{"service": {"plan": "wow", "state": "RUNNING"}}`))
require.NoError(t, err)
atomic.AddInt64(&callCount, 1)
},
)
mux.HandleFunc(
"/v1/project/aiven-project/service/my-clickhouse/clickhouse/query/stats",
func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.URL.RawQuery, "limit=1&order_by=max_time%3Aasc")

// Creates response
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(`{"queries": [{"calls": 1}]}`))
require.NoError(t, err)
atomic.AddInt64(&callCount, 1)
},
)

server := httptest.NewServer(mux)
defer server.Close()

// Points a new client to the server url
Expand All @@ -68,12 +90,27 @@ func TestServiceCreate(t *testing.T) {

// Makes create request
in := &service.ServiceCreateIn{
ServiceName: "foo",
ServiceType: "kafka",
ServiceName: "my-clickhouse",
ServiceType: "clickhouse",
}
out, err := c.ServiceCreate(context.Background(), "foo", in)

ctx := context.Background()
project := "aiven-project"
out, err := c.ServiceCreate(ctx, project, in)
require.NoError(t, err)
require.NotNil(t, out)
assert.Equal(t, "wow", out.Plan)
assert.Equal(t, service.ServiceStateTypeRunning, out.State)

// Validates query params
stats, err := c.ServiceClickHouseQueryStats(
ctx, project, in.ServiceName,
clickhouse.ServiceClickHouseQueryStatsLimit(1),
clickhouse.ServiceClickHouseQueryStatsOrderByType(clickhouse.OrderByTypeMaxTimeasc),
)
require.NoError(t, err)
assert.Len(t, stats, 1)

// All calls are received
assert.EqualValues(t, 2, callCount)
}
Loading
Loading