client: export necessary interfaces/methods

This commit is contained in:
Brian Waldon 2014-10-31 14:24:14 -07:00
parent b47631b38f
commit 824049897d
7 changed files with 48 additions and 43 deletions

View File

@ -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 {

View File

@ -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() {

View File

@ -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)
}()

View File

@ -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()

View File

@ -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 {

View File

@ -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)

View File

@ -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())