Skip to content

Commit be9278c

Browse files
committed
Move the fields common to all structs implementing core.State to a common structure
Add ReadAll() method to the core.State Interface and provide a generic implementation for all States
1 parent c5f4d45 commit be9278c

28 files changed

+674
-646
lines changed

core/core.go

+2-13
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ type Address struct {
2727
addr string
2828
}
2929

30-
type State interface {
31-
Write() error
32-
Read(id string) error
33-
Clear() error
34-
}
35-
3630
type Config struct {
3731
// Config object parsed from a json styled config
3832
V interface{}
@@ -103,20 +97,15 @@ type StateDriver interface {
10397
marshal func(interface{}) ([]byte, error)) error
10498
ReadState(key string, value State,
10599
unmarshal func([]byte, interface{}) error) error
100+
ReadAllState(baseKey string, stateType State,
101+
unmarshal func([]byte, interface{}) error) ([]State, error)
106102
ClearState(key string) error
107103
}
108104

109105
type Resource interface {
110106
// Resource defines a allocatable unit. A resource is uniquely identified
111107
// by 'Id'. A resource description identifies the nature of the resource.
112108
State
113-
// XXX move following four APIs to State
114-
ReadAll() ([]State, error)
115-
SetId(id string)
116-
Id() string
117-
SetStateDriver(stateDriver StateDriver)
118-
StateDriver() StateDriver
119-
120109
Init(rsrcCfg interface{}) error
121110
Deinit()
122111
Description() string

core/state.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package core
2+
3+
type State interface {
4+
Read(id string) error
5+
ReadAll() ([]State, error)
6+
Write() error
7+
Clear() error
8+
}
9+
10+
// CommonState defines the fields common to all core.State implementations.
11+
// This struct shall be embedded as anonymous field in all structs that
12+
// implement core.State
13+
type CommonState struct {
14+
StateDriver StateDriver `json:"-"`
15+
Id string `json:"id"`
16+
}

drivers/etcdstatedriver.go

+44-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ package drivers
1717

1818
import (
1919
"fmt"
20-
"github.com/contiv/go-etcd/etcd"
20+
"reflect"
2121

22+
"github.com/contiv/go-etcd/etcd"
2223
"github.com/contiv/netplugin/core"
2324
)
2425

@@ -103,6 +104,48 @@ func (d *EtcdStateDriver) ReadState(key string, value core.State,
103104
return nil
104105
}
105106

107+
// XXX: move this to some common file
108+
func ReadAllStateCommon(d core.StateDriver, baseKey string, sType core.State,
109+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
110+
stateType := reflect.TypeOf(sType)
111+
sliceType := reflect.SliceOf(stateType)
112+
values := reflect.MakeSlice(sliceType, 0, 1)
113+
114+
byteValues, err := d.ReadAll(baseKey)
115+
if err != nil {
116+
return nil, err
117+
}
118+
for _, byteValue := range byteValues {
119+
value := reflect.New(stateType)
120+
err = unmarshal(byteValue, value.Interface())
121+
if err != nil {
122+
return nil, err
123+
}
124+
values = reflect.Append(values, value.Elem())
125+
}
126+
127+
stateValues := []core.State{}
128+
for i := 0; i < values.Len(); i++ {
129+
// sanity checks
130+
if !values.Index(i).Elem().FieldByName("CommonState").IsValid() {
131+
panic(fmt.Sprintf("The state structure %v is missing core.CommonState",
132+
stateType))
133+
return nil, &core.Error{Desc: fmt.Sprintf("The state structure %v is missing core.CommonState",
134+
stateType)}
135+
}
136+
//the following works as every core.State is expected to embed core.CommonState struct
137+
values.Index(i).Elem().FieldByName("CommonState").FieldByName("StateDriver").Set(reflect.ValueOf(d))
138+
stateValue := values.Index(i).Interface().(core.State)
139+
stateValues = append(stateValues, stateValue)
140+
}
141+
return stateValues, nil
142+
}
143+
144+
func (d *EtcdStateDriver) ReadAllState(baseKey string, sType core.State,
145+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
146+
return ReadAllStateCommon(d, baseKey, sType, unmarshal)
147+
}
148+
106149
func (d *EtcdStateDriver) WriteState(key string, value core.State,
107150
marshal func(interface{}) ([]byte, error)) error {
108151
encodedState, err := marshal(value)

drivers/etcdstatedriver_test.go

+4-20
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,6 @@ import (
2323
"github.com/contiv/netplugin/core"
2424
)
2525

26-
// setup a etcd cluster, run tests and then cleanup the cluster
27-
// XXX: enabled once I upgrade to golang 1.4
28-
//func TestMain(m *testing.M) {
29-
//
30-
// // start etcd
31-
// proc, err := os.StartProcess("etcd", []string{}, nil)
32-
// if err != nil {
33-
// log.Printf("failed to start etcd. Error: %s", err)
34-
// os.Exit(-1)
35-
// }
36-
//
37-
// //run the tests
38-
// exitC := m.Run()
39-
//
40-
// // stop etcd
41-
// proc.Kill()
42-
//
43-
// os.Exit(exitC)
44-
//}
45-
4626
func setupDriver(t *testing.T) *EtcdStateDriver {
4727
etcdConfig := &EtcdStateDriverConfig{}
4828
etcdConfig.Etcd.Machines = []string{"http://127.0.0.1:4001"}
@@ -125,6 +105,10 @@ func (s *testState) Read(id string) error {
125105
return &core.Error{Desc: "Should not be called!!"}
126106
}
127107

108+
func (s *testState) ReadAll() ([]core.State, error) {
109+
return nil, &core.Error{Desc: "Should not be called!!"}
110+
}
111+
128112
func (s *testState) Clear() error {
129113
return &core.Error{Desc: "Should not be called!!"}
130114
}

drivers/fakestatedriver.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ func (d *FakeStateDriver) ReadState(key string, value core.State,
7676
return nil
7777
}
7878

79+
func (d *FakeStateDriver) ReadAllState(baseKey string, sType core.State,
80+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
81+
return ReadAllStateCommon(d, baseKey, sType, unmarshal)
82+
}
83+
7984
func (d *FakeStateDriver) WriteState(key string, value core.State,
8085
marshal func(interface{}) ([]byte, error)) error {
8186
encodedState, err := marshal(value)
@@ -92,7 +97,7 @@ func (d *FakeStateDriver) WriteState(key string, value core.State,
9297
}
9398

9499
func (d *FakeStateDriver) DumpState() {
95-
for key, v := range d.TestState {
96-
log.Printf("key: %q value: %q\n", key, string(v.value))
100+
for key, _ := range d.TestState {
101+
log.Printf("key: %q\n", key)
97102
}
98103
}

drivers/ovsdriver.go

+22-16
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ func vxlanIfName(netId, vtepIp string) string {
328328
}
329329

330330
func (d *OvsDriver) createVtep(epCfg *OvsCfgEndpointState) error {
331-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
331+
cfgNw := OvsCfgNetworkState{}
332+
cfgNw.StateDriver = d.stateDriver
332333
err := cfgNw.Read(epCfg.NetId)
333334
if err != nil {
334335
return err
@@ -352,7 +353,8 @@ func (d *OvsDriver) createVtep(epCfg *OvsCfgEndpointState) error {
352353

353354
func (d *OvsDriver) deleteVtep(epOper *OvsOperEndpointState) error {
354355

355-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
356+
cfgNw := OvsCfgNetworkState{}
357+
cfgNw.StateDriver = d.stateDriver
356358
err := cfgNw.Read(epOper.NetId)
357359
if err != nil {
358360
return err
@@ -423,7 +425,8 @@ func (d *OvsDriver) Deinit() {
423425
}
424426

425427
func (d *OvsDriver) CreateNetwork(id string) error {
426-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
428+
cfgNw := OvsCfgNetworkState{}
429+
cfgNw.StateDriver = d.stateDriver
427430
err := cfgNw.Read(id)
428431
if err != nil {
429432
log.Printf("Failed to read net %s \n", cfgNw.Id)
@@ -450,7 +453,8 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
450453
intfName := portName
451454
intfType := "internal"
452455

453-
epCfg := OvsCfgEndpointState{StateDriver: d.stateDriver}
456+
epCfg := OvsCfgEndpointState{}
457+
epCfg.StateDriver = d.stateDriver
454458
err = epCfg.Read(id)
455459
if err != nil {
456460
return err
@@ -476,7 +480,8 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
476480
intfType = ""
477481
}
478482

479-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
483+
cfgNw := OvsCfgNetworkState{}
484+
cfgNw.StateDriver = d.stateDriver
480485
err = cfgNw.Read(epCfg.NetId)
481486
if err != nil {
482487
return err
@@ -495,16 +500,16 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
495500
}()
496501

497502
operEp := OvsOperEndpointState{
498-
StateDriver: d.stateDriver,
499-
Id: id,
500-
PortName: portName,
501-
NetId: epCfg.NetId,
502-
AttachUUID: epCfg.AttachUUID,
503-
ContName: epCfg.ContName,
504-
IpAddress: epCfg.IpAddress,
505-
IntfName: intfName,
506-
HomingHost: epCfg.HomingHost,
507-
VtepIp: epCfg.VtepIp}
503+
PortName: portName,
504+
NetId: epCfg.NetId,
505+
AttachUUID: epCfg.AttachUUID,
506+
ContName: epCfg.ContName,
507+
IpAddress: epCfg.IpAddress,
508+
IntfName: intfName,
509+
HomingHost: epCfg.HomingHost,
510+
VtepIp: epCfg.VtepIp}
511+
operEp.StateDriver = d.stateDriver
512+
operEp.Id = id
508513
err = operEp.Write()
509514
if err != nil {
510515
return err
@@ -520,7 +525,8 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
520525

521526
func (d *OvsDriver) DeleteEndpoint(id string) (err error) {
522527

523-
epOper := OvsOperEndpointState{StateDriver: d.stateDriver}
528+
epOper := OvsOperEndpointState{}
529+
epOper.StateDriver = d.stateDriver
524530
err = epOper.Read(id)
525531
if err != nil {
526532
return err

drivers/ovsdriver_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ func (d *testOvsStateDriver) ReadState(key string, value core.State,
172172
return &core.Error{Desc: fmt.Sprintf("unknown key! %s", key)}
173173
}
174174

175+
func (d *testOvsStateDriver) ReadAllState(key string, value core.State,
176+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
177+
return nil, &core.Error{Desc: "shouldn't be called!"}
178+
}
179+
175180
func (d *testOvsStateDriver) WriteState(key string, value core.State,
176181
marshal func(interface{}) ([]byte, error)) error {
177182
return nil

drivers/ovsendpointstate.go

+25-36
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@ import (
2626
// vlans with ovs. The state is stored as Json objects.
2727

2828
type OvsCfgEndpointState struct {
29-
StateDriver core.StateDriver `json:"-"`
30-
Id string `json:"id"`
31-
NetId string `json:"netId"`
32-
ContName string `json:"contName"`
33-
AttachUUID string `json:"attachUUID"`
34-
IpAddress string `json:"ipAddress"`
35-
HomingHost string `json:"homingHost"`
36-
IntfName string `json:"intfName"`
37-
VtepIp string `json:'vtepIP"`
29+
core.CommonState
30+
NetId string `json:"netId"`
31+
ContName string `json:"contName"`
32+
AttachUUID string `json:"attachUUID"`
33+
IpAddress string `json:"ipAddress"`
34+
HomingHost string `json:"homingHost"`
35+
IntfName string `json:"intfName"`
36+
VtepIp string `json:'vtepIP"`
3837
}
3938

4039
func (s *OvsCfgEndpointState) Write() error {
@@ -47,39 +46,25 @@ func (s *OvsCfgEndpointState) Read(id string) error {
4746
return s.StateDriver.ReadState(key, s, json.Unmarshal)
4847
}
4948

49+
func (s *OvsCfgEndpointState) ReadAll() ([]core.State, error) {
50+
return s.StateDriver.ReadAllState(EP_CFG_PATH_PREFIX, s, json.Unmarshal)
51+
}
52+
5053
func (s *OvsCfgEndpointState) Clear() error {
5154
key := fmt.Sprintf(EP_CFG_PATH, s.Id)
5255
return s.StateDriver.ClearState(key)
5356
}
5457

55-
func ReadAllOvsCfgEndpoints(d core.StateDriver) ([]*OvsCfgEndpointState, error) {
56-
values := []*OvsCfgEndpointState{}
57-
byteValues, err := d.ReadAll(EP_CFG_PATH_PREFIX)
58-
if err != nil {
59-
return nil, err
60-
}
61-
for _, byteValue := range byteValues {
62-
value := &OvsCfgEndpointState{StateDriver: d}
63-
err = json.Unmarshal(byteValue, value)
64-
if err != nil {
65-
return nil, err
66-
}
67-
values = append(values, value)
68-
}
69-
return values, nil
70-
}
71-
7258
type OvsOperEndpointState struct {
73-
StateDriver core.StateDriver `json:"-"`
74-
Id string `json:"id"`
75-
NetId string `json:"netId"`
76-
ContName string `json:"contName"`
77-
AttachUUID string `json:"attachUUID"`
78-
IpAddress string `json:"ipAddress"`
79-
PortName string `json:"portName"`
80-
HomingHost string `json:"homingHost"`
81-
IntfName string `json:"intfName"`
82-
VtepIp string `json:'vtepIP"`
59+
core.CommonState
60+
NetId string `json:"netId"`
61+
ContName string `json:"contName"`
62+
AttachUUID string `json:"attachUUID"`
63+
IpAddress string `json:"ipAddress"`
64+
PortName string `json:"portName"`
65+
HomingHost string `json:"homingHost"`
66+
IntfName string `json:"intfName"`
67+
VtepIp string `json:'vtepIP"`
8368
}
8469

8570
func (s *OvsOperEndpointState) Write() error {
@@ -92,6 +77,10 @@ func (s *OvsOperEndpointState) Read(id string) error {
9277
return s.StateDriver.ReadState(key, s, json.Unmarshal)
9378
}
9479

80+
func (s *OvsOperEndpointState) ReadAll() ([]core.State, error) {
81+
return s.StateDriver.ReadAllState(EP_OPER_PATH_PREFIX, s, json.Unmarshal)
82+
}
83+
9584
func (s *OvsOperEndpointState) Clear() error {
9685
key := fmt.Sprintf(EP_OPER_PATH, s.Id)
9786
return s.StateDriver.ClearState(key)

0 commit comments

Comments
 (0)