Browse Source

client: break dependency on httptypes pkg

Brian Waldon 11 years ago
parent
commit
4a77760f56

+ 24 - 0
client/error.go

@@ -0,0 +1,24 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package client
+
+type HTTPError struct {
+	Message string `json:"message"`
+	Code    int    `json:"-"`
+}
+
+func (e HTTPError) Error() string {
+	return e.Message
+}

+ 49 - 11
client/members.go

@@ -23,7 +23,7 @@ import (
 	"path"
 	"path"
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
 	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
-	"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
+
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/pkg/types"
 )
 )
 
 
@@ -31,7 +31,50 @@ var (
 	defaultV2MembersPrefix = "/v2/members"
 	defaultV2MembersPrefix = "/v2/members"
 )
 )
 
 
-type Member httptypes.Member
+type Member struct {
+	ID         string   `json:"id"`
+	Name       string   `json:"name"`
+	PeerURLs   []string `json:"peerURLs"`
+	ClientURLs []string `json:"clientURLs"`
+}
+
+type memberCollection []Member
+
+func (c *memberCollection) UnmarshalJSON(data []byte) error {
+	d := struct {
+		Members []Member
+	}{}
+
+	if err := json.Unmarshal(data, &d); err != nil {
+		return err
+	}
+
+	if d.Members == nil {
+		*c = make([]Member, 0)
+		return nil
+	}
+
+	*c = d.Members
+	return nil
+}
+
+type memberCreateRequest struct {
+	PeerURLs types.URLs
+}
+
+func (m *memberCreateRequest) MarshalJSON() ([]byte, error) {
+	s := struct {
+		PeerURLs []string `json:"peerURLs"`
+	}{
+		PeerURLs: make([]string, len(m.PeerURLs)),
+	}
+
+	for i, u := range m.PeerURLs {
+		s.PeerURLs[i] = u.String()
+	}
+
+	return json.Marshal(&s)
+}
 
 
 // NewMembersAPI constructs a new MembersAPI that uses HTTP to
 // NewMembersAPI constructs a new MembersAPI that uses HTTP to
 // interact with etcd's membership API.
 // interact with etcd's membership API.
@@ -67,17 +110,12 @@ func (m *httpMembersAPI) List(ctx context.Context) ([]Member, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	var mCollection httptypes.MemberCollection
+	var mCollection memberCollection
 	if err := json.Unmarshal(body, &mCollection); err != nil {
 	if err := json.Unmarshal(body, &mCollection); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	ms := make([]Member, len(mCollection))
-	for i, m := range mCollection {
-		m := Member(m)
-		ms[i] = m
-	}
-	return ms, nil
+	return []Member(mCollection), nil
 }
 }
 
 
 func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, error) {
 func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, error) {
@@ -97,7 +135,7 @@ func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, erro
 	}
 	}
 
 
 	if resp.StatusCode != http.StatusCreated {
 	if resp.StatusCode != http.StatusCreated {
-		var httperr httptypes.HTTPError
+		var httperr HTTPError
 		if err := json.Unmarshal(body, &httperr); err != nil {
 		if err := json.Unmarshal(body, &httperr); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -147,7 +185,7 @@ type membersAPIActionAdd struct {
 
 
 func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
 func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
 	u := v2MembersURL(ep)
 	u := v2MembersURL(ep)
-	m := httptypes.MemberCreateRequest{PeerURLs: a.peerURLs}
+	m := memberCreateRequest{PeerURLs: a.peerURLs}
 	b, _ := json.Marshal(&m)
 	b, _ := json.Marshal(&m)
 	req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(b))
 	req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(b))
 	req.Header.Set("Content-Type", "application/json")
 	req.Header.Set("Content-Type", "application/json")

+ 154 - 0
client/members_test.go

@@ -15,6 +15,7 @@
 package client
 package client
 
 
 import (
 import (
+	"encoding/json"
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
 	"reflect"
 	"reflect"
@@ -109,3 +110,156 @@ func TestV2MembersURL(t *testing.T) {
 		t.Fatalf("v2MembersURL got %#v, want %#v", got, want)
 		t.Fatalf("v2MembersURL got %#v, want %#v", got, want)
 	}
 	}
 }
 }
+
+func TestMemberUnmarshal(t *testing.T) {
+	tests := []struct {
+		body       []byte
+		wantMember Member
+		wantError  bool
+	}{
+		// no URLs, just check ID & Name
+		{
+			body:       []byte(`{"id": "c", "name": "dungarees"}`),
+			wantMember: Member{ID: "c", Name: "dungarees", PeerURLs: nil, ClientURLs: nil},
+		},
+
+		// both client and peer URLs
+		{
+			body: []byte(`{"peerURLs": ["http://127.0.0.1:4001"], "clientURLs": ["http://127.0.0.1:4001"]}`),
+			wantMember: Member{
+				PeerURLs: []string{
+					"http://127.0.0.1:4001",
+				},
+				ClientURLs: []string{
+					"http://127.0.0.1:4001",
+				},
+			},
+		},
+
+		// multiple peer URLs
+		{
+			body: []byte(`{"peerURLs": ["http://127.0.0.1:4001", "https://example.com"]}`),
+			wantMember: Member{
+				PeerURLs: []string{
+					"http://127.0.0.1:4001",
+					"https://example.com",
+				},
+				ClientURLs: nil,
+			},
+		},
+
+		// multiple client URLs
+		{
+			body: []byte(`{"clientURLs": ["http://127.0.0.1:4001", "https://example.com"]}`),
+			wantMember: Member{
+				PeerURLs: nil,
+				ClientURLs: []string{
+					"http://127.0.0.1:4001",
+					"https://example.com",
+				},
+			},
+		},
+
+		// invalid JSON
+		{
+			body:      []byte(`{"peerU`),
+			wantError: true,
+		},
+	}
+
+	for i, tt := range tests {
+		got := Member{}
+		err := json.Unmarshal(tt.body, &got)
+		if tt.wantError != (err != nil) {
+			t.Errorf("#%d: want error %t, got %v", i, tt.wantError, err)
+			continue
+		}
+
+		if !reflect.DeepEqual(tt.wantMember, got) {
+			t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.wantMember, got)
+		}
+	}
+}
+
+func TestMemberCollectionUnmarshal(t *testing.T) {
+	tests := []struct {
+		body []byte
+		want memberCollection
+	}{
+		{
+			body: []byte(`{"members":[]}`),
+			want: memberCollection([]Member{}),
+		},
+		{
+			body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`),
+			want: memberCollection(
+				[]Member{
+					{
+						ID:   "2745e2525fce8fe",
+						Name: "node3",
+						PeerURLs: []string{
+							"http://127.0.0.1:7003",
+						},
+						ClientURLs: []string{
+							"http://127.0.0.1:4003",
+						},
+					},
+					{
+						ID:   "42134f434382925",
+						Name: "node1",
+						PeerURLs: []string{
+							"http://127.0.0.1:2380",
+							"http://127.0.0.1:7001",
+						},
+						ClientURLs: []string{
+							"http://127.0.0.1:2379",
+							"http://127.0.0.1:4001",
+						},
+					},
+					{
+						ID:   "94088180e21eb87b",
+						Name: "node2",
+						PeerURLs: []string{
+							"http://127.0.0.1:7002",
+						},
+						ClientURLs: []string{
+							"http://127.0.0.1:4002",
+						},
+					},
+				},
+			),
+		},
+	}
+
+	for i, tt := range tests {
+		var got memberCollection
+		err := json.Unmarshal(tt.body, &got)
+		if err != nil {
+			t.Errorf("#%d: unexpected error: %v", i, err)
+			continue
+		}
+
+		if !reflect.DeepEqual(tt.want, got) {
+			t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.want, got)
+		}
+	}
+}
+
+func TestMemberCreateRequestMarshal(t *testing.T) {
+	req := memberCreateRequest{
+		PeerURLs: types.URLs([]url.URL{
+			url.URL{Scheme: "http", Host: "127.0.0.1:8081"},
+			url.URL{Scheme: "https", Host: "127.0.0.1:8080"},
+		}),
+	}
+	want := []byte(`{"peerURLs":["http://127.0.0.1:8081","https://127.0.0.1:8080"]}`)
+
+	got, err := json.Marshal(&req)
+	if err != nil {
+		t.Fatalf("Marshal returned unexpected err=%v", err)
+	}
+
+	if !reflect.DeepEqual(want, got) {
+		t.Fatalf("Failed to marshal memberCreateRequest: want=%s, got=%s", want, got)
+	}
+}

+ 0 - 32
etcdserver/etcdhttp/httptypes/member.go

@@ -35,20 +35,6 @@ type MemberUpdateRequest struct {
 	MemberCreateRequest
 	MemberCreateRequest
 }
 }
 
 
-func (m *MemberCreateRequest) MarshalJSON() ([]byte, error) {
-	s := struct {
-		PeerURLs []string `json:"peerURLs"`
-	}{
-		PeerURLs: make([]string, len(m.PeerURLs)),
-	}
-
-	for i, u := range m.PeerURLs {
-		s.PeerURLs[i] = u.String()
-	}
-
-	return json.Marshal(&s)
-}
-
 func (m *MemberCreateRequest) UnmarshalJSON(data []byte) error {
 func (m *MemberCreateRequest) UnmarshalJSON(data []byte) error {
 	s := struct {
 	s := struct {
 		PeerURLs []string `json:"peerURLs"`
 		PeerURLs []string `json:"peerURLs"`
@@ -79,21 +65,3 @@ func (c *MemberCollection) MarshalJSON() ([]byte, error) {
 
 
 	return json.Marshal(d)
 	return json.Marshal(d)
 }
 }
-
-func (c *MemberCollection) UnmarshalJSON(data []byte) error {
-	d := struct {
-		Members []Member
-	}{}
-
-	if err := json.Unmarshal(data, &d); err != nil {
-		return err
-	}
-
-	if d.Members == nil {
-		*c = make([]Member, 0)
-		return nil
-	}
-
-	*c = d.Members
-	return nil
-}

+ 0 - 83
etcdserver/etcdhttp/httptypes/member_test.go

@@ -93,70 +93,6 @@ func TestMemberUnmarshal(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func TestMemberCollectionUnmarshal(t *testing.T) {
-	tests := []struct {
-		body []byte
-		want MemberCollection
-	}{
-		{
-			body: []byte(`{"members":[]}`),
-			want: MemberCollection([]Member{}),
-		},
-		{
-			body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`),
-			want: MemberCollection(
-				[]Member{
-					{
-						ID:   "2745e2525fce8fe",
-						Name: "node3",
-						PeerURLs: []string{
-							"http://127.0.0.1:7003",
-						},
-						ClientURLs: []string{
-							"http://127.0.0.1:4003",
-						},
-					},
-					{
-						ID:   "42134f434382925",
-						Name: "node1",
-						PeerURLs: []string{
-							"http://127.0.0.1:2380",
-							"http://127.0.0.1:7001",
-						},
-						ClientURLs: []string{
-							"http://127.0.0.1:2379",
-							"http://127.0.0.1:4001",
-						},
-					},
-					{
-						ID:   "94088180e21eb87b",
-						Name: "node2",
-						PeerURLs: []string{
-							"http://127.0.0.1:7002",
-						},
-						ClientURLs: []string{
-							"http://127.0.0.1:4002",
-						},
-					},
-				},
-			),
-		},
-	}
-
-	for i, tt := range tests {
-		var got MemberCollection
-		err := json.Unmarshal(tt.body, &got)
-		if err != nil {
-			t.Errorf("#%d: unexpected error: %v", i, err)
-			continue
-		}
-
-		if !reflect.DeepEqual(tt.want, got) {
-			t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.want, got)
-		}
-	}
-}
-
 func TestMemberCreateRequestUnmarshal(t *testing.T) {
 func TestMemberCreateRequestUnmarshal(t *testing.T) {
 	body := []byte(`{"peerURLs": ["http://127.0.0.1:8081", "https://127.0.0.1:8080"]}`)
 	body := []byte(`{"peerURLs": ["http://127.0.0.1:8081", "https://127.0.0.1:8080"]}`)
 	want := MemberCreateRequest{
 	want := MemberCreateRequest{
@@ -197,22 +133,3 @@ func TestMemberCreateRequestUnmarshalFail(t *testing.T) {
 		}
 		}
 	}
 	}
 }
 }
-
-func TestMemberCreateRequestMarshal(t *testing.T) {
-	req := MemberCreateRequest{
-		PeerURLs: types.URLs([]url.URL{
-			url.URL{Scheme: "http", Host: "127.0.0.1:8081"},
-			url.URL{Scheme: "https", Host: "127.0.0.1:8080"},
-		}),
-	}
-	want := []byte(`{"peerURLs":["http://127.0.0.1:8081","https://127.0.0.1:8080"]}`)
-
-	got, err := json.Marshal(&req)
-	if err != nil {
-		t.Fatalf("Marshal returned unexpected err=%v", err)
-	}
-
-	if !reflect.DeepEqual(want, got) {
-		t.Fatalf("Failed to marshal MemberCreateRequest: want=%s, got=%s", want, got)
-	}
-}