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

Provides a JSON format for recovery when using server IDs. #207

Merged
merged 1 commit into from
May 4, 2017
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
52 changes: 52 additions & 0 deletions peersjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,55 @@ func ReadPeersJSON(path string) (Configuration, error) {
}
return configuration, nil
}

// configEntry is used when decoding a new-style peers.json.
type configEntry struct {
// ID is the ID of the server (a UUID, usually).
ID ServerID `json:"id"`

// Address is the host:port of the server.
Address ServerAddress `json:"address"`

// NonVoter controls the suffrage. We choose this sense so people
// can leave this out and get a Voter by default.
NonVoter bool `json:"non_voter"`
}

// ReadConfigJSON reads a new-style peers.json and returns a configuration
// structure. This can be used to perform manual recovery when running protocol
// versions that use server IDs.
func ReadConfigJSON(path string) (Configuration, error) {
// Read in the file.
buf, err := ioutil.ReadFile(path)
if err != nil {
return Configuration{}, err
}

// Parse it as JSON.
var peers []configEntry
dec := json.NewDecoder(bytes.NewReader(buf))
if err := dec.Decode(&peers); err != nil {
return Configuration{}, err
}

// Map it into the new-style configuration structure.
var configuration Configuration
for _, peer := range peers {
suffrage := Voter
if peer.NonVoter {
suffrage = Nonvoter
}
server := Server{
Suffrage: suffrage,
ID: peer.ID,
Address: peer.Address,
}
configuration.Servers = append(configuration.Servers, server)
}

// We should only ingest valid configurations.
if err := checkConfiguration(configuration); err != nil {
return Configuration{}, err
}
return configuration, nil
}
67 changes: 65 additions & 2 deletions peersjson_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,18 @@ func TestPeersJSON_BadConfiguration(t *testing.T) {
}
}

func Test_PeersJSON(t *testing.T) {
func TestPeersJSON_ReadPeersJSON(t *testing.T) {
base, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(base)

content := []byte("[\"127.0.0.1:123\", \"127.0.0.2:123\", \"127.0.0.3:123\"]")
content := []byte(`
["127.0.0.1:123",
"127.0.0.2:123",
"127.0.0.3:123"]
`)
peers := filepath.Join(base, "peers.json")
if err := ioutil.WriteFile(peers, content, 0666); err != nil {
t.Fatalf("err: %v", err)
Expand Down Expand Up @@ -68,3 +72,62 @@ func Test_PeersJSON(t *testing.T) {
t.Fatalf("bad configuration: %+v != %+v", configuration, expected)
}
}

func TestPeersJSON_ReadConfigJSON(t *testing.T) {
base, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(base)

content := []byte(`
[
{
"id": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
"address": "127.0.0.1:123",
"non_voter": false
},
{
"id": "8b6dda82-3103-11e7-93ae-92361f002671",
"address": "127.0.0.2:123"
},
{
"id": "97e17742-3103-11e7-93ae-92361f002671",
"address": "127.0.0.3:123",
"non_voter": true
}
]
`)
peers := filepath.Join(base, "peers.json")
if err := ioutil.WriteFile(peers, content, 0666); err != nil {
t.Fatalf("err: %v", err)
}

configuration, err := ReadConfigJSON(peers)
if err != nil {
t.Fatalf("err: %v", err)
}

expected := Configuration{
Servers: []Server{
Server{
Suffrage: Voter,
ID: ServerID("adf4238a-882b-9ddc-4a9d-5b6758e4159e"),
Address: ServerAddress("127.0.0.1:123"),
},
Server{
Suffrage: Voter,
ID: ServerID("8b6dda82-3103-11e7-93ae-92361f002671"),
Address: ServerAddress("127.0.0.2:123"),
},
Server{
Suffrage: Nonvoter,
ID: ServerID("97e17742-3103-11e7-93ae-92361f002671"),
Address: ServerAddress("127.0.0.3:123"),
},
},
}
if !reflect.DeepEqual(configuration, expected) {
t.Fatalf("bad configuration: %+v != %+v", configuration, expected)
}
}