From 824049897de27a37100839d99bf6385ec6827034 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 31 Oct 2014 14:24:14 -0700 Subject: [PATCH] client: export necessary interfaces/methods --- client/{cluster.go => client.go} | 25 +++++++++++++++++++++++-- client/http.go | 20 ++------------------ client/http_test.go | 10 +++++----- client/keys.go | 12 ++++++------ client/keys_test.go | 6 +++--- client/members.go | 12 ++++++------ client/members_test.go | 6 +++--- 7 files changed, 48 insertions(+), 43 deletions(-) rename client/{cluster.go => client.go} (71%) diff --git a/client/cluster.go b/client/client.go similarity index 71% rename from client/cluster.go rename to client/client.go index 56d92fe28..b9e4c9dbe 100644 --- a/client/cluster.go +++ b/client/client.go @@ -23,6 +23,27 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/go.net/context" ) +type HTTPClient interface { + Do(context.Context, HTTPAction) (*http.Response, []byte, error) + Sync() error +} + +type httpActionDo interface { + Do(context.Context, HTTPAction) (*http.Response, []byte, error) +} + +type HTTPAction interface { + HTTPRequest(url.URL) *http.Request +} + +// CancelableTransport mimics http.Transport to provide an interface which can be +// substituted for testing (since the RoundTripper interface alone does not +// require the CancelRequest method) +type CancelableTransport interface { + http.RoundTripper + CancelRequest(req *http.Request) +} + func NewHTTPClient(tr CancelableTransport, eps []string) (*httpClusterClient, error) { c := httpClusterClient{ transport: tr, @@ -49,9 +70,9 @@ type httpClusterClient struct { endpoints []httpActionDo } -func (c *httpClusterClient) do(ctx context.Context, act httpAction) (*http.Response, []byte, error) { +func (c *httpClusterClient) Do(ctx context.Context, act HTTPAction) (*http.Response, []byte, error) { //TODO(bcwaldon): introduce retry logic so all endpoints are attempted - return c.endpoints[0].do(ctx, act) + return c.endpoints[0].Do(ctx, act) } func (c *httpClusterClient) Sync() error { diff --git a/client/http.go b/client/http.go index 24b3b7dec..92c0a7dbc 100644 --- a/client/http.go +++ b/client/http.go @@ -30,22 +30,6 @@ var ( DefaultRequestTimeout = 5 * time.Second ) -// CancelableTransport mimics http.Transport to provide an interface which can be -// substituted for testing (since the RoundTripper interface alone does not -// require the CancelRequest method) -type CancelableTransport interface { - http.RoundTripper - CancelRequest(req *http.Request) -} - -type httpAction interface { - httpRequest(url.URL) *http.Request -} - -type httpActionDo interface { - do(context.Context, httpAction) (*http.Response, []byte, error) -} - type roundTripResponse struct { resp *http.Response err error @@ -57,8 +41,8 @@ type httpClient struct { timeout time.Duration } -func (c *httpClient) do(ctx context.Context, act httpAction) (*http.Response, []byte, error) { - req := act.httpRequest(c.endpoint) +func (c *httpClient) Do(ctx context.Context, act HTTPAction) (*http.Response, []byte, error) { + req := act.HTTPRequest(c.endpoint) rtchan := make(chan roundTripResponse, 1) go func() { diff --git a/client/http_test.go b/client/http_test.go index 16115958a..33062b51e 100644 --- a/client/http_test.go +++ b/client/http_test.go @@ -65,7 +65,7 @@ func (t *fakeTransport) CancelRequest(*http.Request) { type fakeAction struct{} -func (a *fakeAction) httpRequest(url.URL) *http.Request { +func (a *fakeAction) HTTPRequest(url.URL) *http.Request { return &http.Request{} } @@ -78,7 +78,7 @@ func TestHTTPClientDoSuccess(t *testing.T) { Body: ioutil.NopCloser(strings.NewReader("foo")), } - resp, body, err := c.do(context.Background(), &fakeAction{}) + resp, body, err := c.Do(context.Background(), &fakeAction{}) if err != nil { t.Fatalf("incorrect error value: want=nil got=%v", err) } @@ -100,7 +100,7 @@ func TestHTTPClientDoError(t *testing.T) { tr.errchan <- errors.New("fixture") - _, _, err := c.do(context.Background(), &fakeAction{}) + _, _, err := c.Do(context.Background(), &fakeAction{}) if err == nil { t.Fatalf("expected non-nil error, got nil") } @@ -113,7 +113,7 @@ func TestHTTPClientDoCancelContext(t *testing.T) { tr.startCancel <- struct{}{} tr.finishCancel <- struct{}{} - _, _, err := c.do(context.Background(), &fakeAction{}) + _, _, err := c.Do(context.Background(), &fakeAction{}) if err == nil { t.Fatalf("expected non-nil error, got nil") } @@ -126,7 +126,7 @@ func TestHTTPClientDoCancelContextWaitForRoundTrip(t *testing.T) { donechan := make(chan struct{}) ctx, cancel := context.WithCancel(context.Background()) go func() { - c.do(ctx, &fakeAction{}) + c.Do(ctx, &fakeAction{}) close(donechan) }() diff --git a/client/keys.go b/client/keys.go index fa3ed3cd5..2e921595a 100644 --- a/client/keys.go +++ b/client/keys.go @@ -105,7 +105,7 @@ func (k *httpKeysAPI) Create(key, val string, ttl time.Duration) (*Response, err } ctx, cancel := context.WithTimeout(context.Background(), k.timeout) - resp, body, err := k.client.do(ctx, create) + resp, body, err := k.client.Do(ctx, create) cancel() if err != nil { return nil, err @@ -122,7 +122,7 @@ func (k *httpKeysAPI) Get(key string) (*Response, error) { } ctx, cancel := context.WithTimeout(context.Background(), k.timeout) - resp, body, err := k.client.do(ctx, get) + resp, body, err := k.client.Do(ctx, get) cancel() if err != nil { return nil, err @@ -162,7 +162,7 @@ type httpWatcher struct { func (hw *httpWatcher) Next() (*Response, error) { //TODO(bcwaldon): This needs to be cancellable by the calling user - httpresp, body, err := hw.client.do(context.Background(), &hw.nextWait) + httpresp, body, err := hw.client.Do(context.Background(), &hw.nextWait) if err != nil { return nil, err } @@ -192,7 +192,7 @@ type getAction struct { Recursive bool } -func (g *getAction) httpRequest(ep url.URL) *http.Request { +func (g *getAction) HTTPRequest(ep url.URL) *http.Request { u := v2KeysURL(ep, g.Prefix, g.Key) params := u.Query() @@ -210,7 +210,7 @@ type waitAction struct { Recursive bool } -func (w *waitAction) httpRequest(ep url.URL) *http.Request { +func (w *waitAction) HTTPRequest(ep url.URL) *http.Request { u := v2KeysURL(ep, w.Prefix, w.Key) params := u.Query() @@ -230,7 +230,7 @@ type createAction struct { TTL *uint64 } -func (c *createAction) httpRequest(ep url.URL) *http.Request { +func (c *createAction) HTTPRequest(ep url.URL) *http.Request { u := v2KeysURL(ep, c.Prefix, c.Key) params := u.Query() diff --git a/client/keys_test.go b/client/keys_test.go index ad7b4b1c0..1b632e6b5 100644 --- a/client/keys_test.go +++ b/client/keys_test.go @@ -117,7 +117,7 @@ func TestGetAction(t *testing.T) { Key: "/foo/bar", Recursive: tt.recursive, } - got := *f.httpRequest(ep) + got := *f.HTTPRequest(ep) wantURL := wantURL wantURL.RawQuery = tt.wantQuery @@ -166,7 +166,7 @@ func TestWaitAction(t *testing.T) { WaitIndex: tt.waitIndex, Recursive: tt.recursive, } - got := *f.httpRequest(ep) + got := *f.HTTPRequest(ep) wantURL := wantURL wantURL.RawQuery = tt.wantQuery @@ -213,7 +213,7 @@ func TestCreateAction(t *testing.T) { Value: tt.value, TTL: tt.ttl, } - got := *f.httpRequest(ep) + got := *f.HTTPRequest(ep) err := assertResponse(got, wantURL, wantHeader, []byte(tt.wantBody)) if err != nil { diff --git a/client/members.go b/client/members.go index ff3ede08b..30c03ce74 100644 --- a/client/members.go +++ b/client/members.go @@ -55,7 +55,7 @@ type httpMembersAPI struct { func (m *httpMembersAPI) List() ([]httptypes.Member, error) { req := &membersAPIActionList{} ctx, cancel := context.WithTimeout(context.Background(), m.timeout) - resp, body, err := m.client.do(ctx, req) + resp, body, err := m.client.Do(ctx, req) cancel() if err != nil { return nil, err @@ -81,7 +81,7 @@ func (m *httpMembersAPI) Add(peerURL string) (*httptypes.Member, error) { req := &membersAPIActionAdd{peerURLs: urls} ctx, cancel := context.WithTimeout(context.Background(), m.timeout) - resp, body, err := m.client.do(ctx, req) + resp, body, err := m.client.Do(ctx, req) cancel() if err != nil { return nil, err @@ -102,7 +102,7 @@ func (m *httpMembersAPI) Add(peerURL string) (*httptypes.Member, error) { func (m *httpMembersAPI) Remove(memberID string) error { req := &membersAPIActionRemove{memberID: memberID} ctx, cancel := context.WithTimeout(context.Background(), m.timeout) - resp, _, err := m.client.do(ctx, req) + resp, _, err := m.client.Do(ctx, req) cancel() if err != nil { return err @@ -113,7 +113,7 @@ func (m *httpMembersAPI) Remove(memberID string) error { type membersAPIActionList struct{} -func (l *membersAPIActionList) httpRequest(ep url.URL) *http.Request { +func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request { u := v2MembersURL(ep) req, _ := http.NewRequest("GET", u.String(), nil) return req @@ -123,7 +123,7 @@ type membersAPIActionRemove struct { memberID string } -func (d *membersAPIActionRemove) httpRequest(ep url.URL) *http.Request { +func (d *membersAPIActionRemove) HTTPRequest(ep url.URL) *http.Request { u := v2MembersURL(ep) u.Path = path.Join(u.Path, d.memberID) req, _ := http.NewRequest("DELETE", u.String(), nil) @@ -134,7 +134,7 @@ type membersAPIActionAdd struct { peerURLs types.URLs } -func (a *membersAPIActionAdd) httpRequest(ep url.URL) *http.Request { +func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request { u := v2MembersURL(ep) m := httptypes.MemberCreateRequest{PeerURLs: a.peerURLs} b, _ := json.Marshal(&m) diff --git a/client/members_test.go b/client/members_test.go index 8d1534e49..bbc6c9221 100644 --- a/client/members_test.go +++ b/client/members_test.go @@ -35,7 +35,7 @@ func TestMembersAPIActionList(t *testing.T) { Path: "/v2/members", } - got := *act.httpRequest(ep) + got := *act.HTTPRequest(ep) err := assertResponse(got, wantURL, http.Header{}, nil) if err != nil { t.Error(err.Error()) @@ -61,7 +61,7 @@ func TestMembersAPIActionAdd(t *testing.T) { } wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`) - got := *act.httpRequest(ep) + got := *act.HTTPRequest(ep) err := assertResponse(got, wantURL, wantHeader, wantBody) if err != nil { t.Error(err.Error()) @@ -78,7 +78,7 @@ func TestMembersAPIActionRemove(t *testing.T) { Path: "/v2/members/XXX", } - got := *act.httpRequest(ep) + got := *act.HTTPRequest(ep) err := assertResponse(got, wantURL, http.Header{}, nil) if err != nil { t.Error(err.Error())