[#168] netmap: Implement binary and JSON encoders/decoders on Filter

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-11-13 11:45:59 +03:00 committed by Alex Vanin
parent 874a4b937f
commit e721734599
14 changed files with 628 additions and 196 deletions

View file

@ -229,3 +229,34 @@ func (f *Filter) SetInnerFilters(fs ...*Filter) {
(*netmap.Filter)(f). (*netmap.Filter)(f).
SetFilters(filtersToV2(fs)) SetFilters(filtersToV2(fs))
} }
// Marshal marshals Filter into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (f *Filter) Marshal(b ...[]byte) ([]byte, error) {
var buf []byte
if len(b) > 0 {
buf = b[0]
}
return (*netmap.Filter)(f).StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of Filter.
func (f *Filter) Unmarshal(data []byte) error {
return (*netmap.Filter)(f).
Unmarshal(data)
}
// MarshalJSON encodes Filter to protobuf JSON format.
func (f *Filter) MarshalJSON() ([]byte, error) {
return (*netmap.Filter)(f).
MarshalJSON()
}
// UnmarshalJSON decodes Filter from protobuf JSON format.
func (f *Filter) UnmarshalJSON(data []byte) error {
return (*netmap.Filter)(f).
UnmarshalJSON(data)
}

View file

@ -269,3 +269,29 @@ func TestFilter_InnerFilters(t *testing.T) {
require.Equal(t, []*Filter{f1, f2}, f.InnerFilters()) require.Equal(t, []*Filter{f1, f2}, f.InnerFilters())
} }
func TestFilterEncoding(t *testing.T) {
f := newFilter("name", "key", "value", OpEQ,
newFilter("name2", "key2", "value", OpOR),
)
t.Run("binary", func(t *testing.T) {
data, err := f.Marshal()
require.NoError(t, err)
f2 := NewFilter()
require.NoError(t, f2.Unmarshal(data))
require.Equal(t, f, f2)
})
t.Run("json", func(t *testing.T) {
data, err := f.MarshalJSON()
require.NoError(t, err)
f2 := NewFilter()
require.NoError(t, f2.UnmarshalJSON(data))
require.Equal(t, f, f2)
})
}

View file

@ -193,6 +193,38 @@ func (a *NodeAttribute) SetParentKeys(keys ...string) {
SetParents(keys) SetParents(keys)
} }
// Marshal marshals NodeAttribute into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (a *NodeAttribute) Marshal(b ...[]byte) ([]byte, error) {
var buf []byte
if len(b) > 0 {
buf = b[0]
}
return (*netmap.Attribute)(a).
StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of NodeAttribute.
func (a *NodeAttribute) Unmarshal(data []byte) error {
return (*netmap.Attribute)(a).
Unmarshal(data)
}
// MarshalJSON encodes NodeAttribute to protobuf JSON format.
func (a *NodeAttribute) MarshalJSON() ([]byte, error) {
return (*netmap.Attribute)(a).
MarshalJSON()
}
// UnmarshalJSON decodes NodeAttribute from protobuf JSON format.
func (a *NodeAttribute) UnmarshalJSON(data []byte) error {
return (*netmap.Attribute)(a).
UnmarshalJSON(data)
}
// NewNodeInfo creates and returns new NodeInfo instance. // NewNodeInfo creates and returns new NodeInfo instance.
func NewNodeInfo() *NodeInfo { func NewNodeInfo() *NodeInfo {
return NewNodeInfoFromV2(new(netmap.NodeInfo)) return NewNodeInfoFromV2(new(netmap.NodeInfo))
@ -203,21 +235,6 @@ func NewNodeInfoFromV2(i *netmap.NodeInfo) *NodeInfo {
return (*NodeInfo)(i) return (*NodeInfo)(i)
} }
// NodeInfoToJSON encodes NodeInfo to JSON format.
func NodeInfoToJSON(i *NodeInfo) ([]byte, error) {
return netmap.NodeInfoToJSON(i.ToV2())
}
// NodeInfoFromJSON decodes NodeInfo from JSON-encoded data.
func NodeInfoFromJSON(data []byte) (*NodeInfo, error) {
i, err := netmap.NodeInfoFromJSON(data)
if err != nil {
return nil, err
}
return NewNodeInfoFromV2(i), nil
}
// ToV2 converts NodeInfo to v2 NodeInfo. // ToV2 converts NodeInfo to v2 NodeInfo.
func (i *NodeInfo) ToV2() *netmap.NodeInfo { func (i *NodeInfo) ToV2() *netmap.NodeInfo {
return (*netmap.NodeInfo)(i) return (*netmap.NodeInfo)(i)
@ -286,3 +303,35 @@ func (i *NodeInfo) SetState(s NodeState) {
(*netmap.NodeInfo)(i). (*netmap.NodeInfo)(i).
SetState(s.ToV2()) SetState(s.ToV2())
} }
// Marshal marshals NodeInfo into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (i *NodeInfo) Marshal(b ...[]byte) ([]byte, error) {
var buf []byte
if len(b) > 0 {
buf = b[0]
}
return (*netmap.NodeInfo)(i).
StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of NodeInfo.
func (i *NodeInfo) Unmarshal(data []byte) error {
return (*netmap.NodeInfo)(i).
Unmarshal(data)
}
// MarshalJSON encodes NodeInfo to protobuf JSON format.
func (i *NodeInfo) MarshalJSON() ([]byte, error) {
return (*netmap.NodeInfo)(i).
MarshalJSON()
}
// UnmarshalJSON decodes NodeInfo from protobuf JSON format.
func (i *NodeInfo) UnmarshalJSON(data []byte) error {
return (*netmap.NodeInfo)(i).
UnmarshalJSON(data)
}

View file

@ -128,18 +128,54 @@ func TestNodeInfo_Attributes(t *testing.T) {
require.Equal(t, as, i.Attributes()) require.Equal(t, as, i.Attributes())
} }
func TestNodeInfoJSON(t *testing.T) { func TestNodeAttributeEncoding(t *testing.T) {
a := testNodeAttribute()
t.Run("binary", func(t *testing.T) {
data, err := a.Marshal()
require.NoError(t, err)
a2 := NewNodeAttribute()
require.NoError(t, a2.Unmarshal(data))
require.Equal(t, a, a2)
})
t.Run("json", func(t *testing.T) {
data, err := a.MarshalJSON()
require.NoError(t, err)
a2 := NewNodeAttribute()
require.NoError(t, a2.UnmarshalJSON(data))
require.Equal(t, a, a2)
})
}
func TestNodeInfoEncoding(t *testing.T) {
i := NewNodeInfo() i := NewNodeInfo()
i.SetPublicKey([]byte{1, 2, 3}) i.SetPublicKey([]byte{1, 2, 3})
i.SetAddress("some node address") i.SetAddress("192.168.0.1")
i.SetState(NodeStateOnline) i.SetState(NodeStateOnline)
i.SetAttributes(testNodeAttribute(), testNodeAttribute()) i.SetAttributes(testNodeAttribute())
j, err := NodeInfoToJSON(i) t.Run("binary", func(t *testing.T) {
data, err := i.Marshal()
require.NoError(t, err) require.NoError(t, err)
i2, err := NodeInfoFromJSON(j) i2 := NewNodeInfo()
require.NoError(t, err) require.NoError(t, i2.Unmarshal(data))
require.Equal(t, i, i2) require.Equal(t, i, i2)
})
t.Run("json", func(t *testing.T) {
data, err := i.MarshalJSON()
require.NoError(t, err)
i2 := NewNodeInfo()
require.NoError(t, i2.UnmarshalJSON(data))
require.Equal(t, i, i2)
})
} }

View file

@ -7,21 +7,6 @@ import (
// PlacementPolicy represents v2-compatible placement policy. // PlacementPolicy represents v2-compatible placement policy.
type PlacementPolicy netmap.PlacementPolicy type PlacementPolicy netmap.PlacementPolicy
// PlacementPolicyToJSON encodes PlacementPolicy to JSON format.
func PlacementPolicyToJSON(p *PlacementPolicy) ([]byte, error) {
return netmap.PlacementPolicyToJSON(p.ToV2())
}
// PlacementPolicyFromJSON decodes PlacementPolicy from JSON format.
func PlacementPolicyFromJSON(data []byte) (*PlacementPolicy, error) {
p, err := netmap.PlacementPolicyFromJSON(data)
if err != nil {
return nil, err
}
return NewPlacementPolicyFromV2(p), nil
}
// NewPlacementPolicy creates and returns new PlacementPolicy instance. // NewPlacementPolicy creates and returns new PlacementPolicy instance.
func NewPlacementPolicy() *PlacementPolicy { func NewPlacementPolicy() *PlacementPolicy {
return NewPlacementPolicyFromV2(new(netmap.PlacementPolicy)) return NewPlacementPolicyFromV2(new(netmap.PlacementPolicy))
@ -114,3 +99,35 @@ func (p *PlacementPolicy) SetFilters(fs ...*Filter) {
(*netmap.PlacementPolicy)(p). (*netmap.PlacementPolicy)(p).
SetFilters(filtersToV2(fs)) SetFilters(filtersToV2(fs))
} }
// Marshal marshals PlacementPolicy into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (p *PlacementPolicy) Marshal(b ...[]byte) ([]byte, error) {
var buf []byte
if len(b) > 0 {
buf = b[0]
}
return (*netmap.PlacementPolicy)(p).
StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of PlacementPolicy.
func (p *PlacementPolicy) Unmarshal(data []byte) error {
return (*netmap.PlacementPolicy)(p).
Unmarshal(data)
}
// MarshalJSON encodes PlacementPolicy to protobuf JSON format.
func (p *PlacementPolicy) MarshalJSON() ([]byte, error) {
return (*netmap.PlacementPolicy)(p).
MarshalJSON()
}
// UnmarshalJSON decodes PlacementPolicy from protobuf JSON format.
func (p *PlacementPolicy) UnmarshalJSON(data []byte) error {
return (*netmap.PlacementPolicy)(p).
UnmarshalJSON(data)
}

View file

@ -67,3 +67,27 @@ func TestPlacementPolicy_Filters(t *testing.T) {
require.Equal(t, fs, p.Filters()) require.Equal(t, fs, p.Filters())
} }
func TestPlacementPolicyEncoding(t *testing.T) {
p := newPlacementPolicy(3, nil, nil, nil)
t.Run("binary", func(t *testing.T) {
data, err := p.Marshal()
require.NoError(t, err)
p2 := NewPlacementPolicy()
require.NoError(t, p2.Unmarshal(data))
require.Equal(t, p, p2)
})
t.Run("json", func(t *testing.T) {
data, err := p.MarshalJSON()
require.NoError(t, err)
p2 := NewPlacementPolicy()
require.NoError(t, p2.UnmarshalJSON(data))
require.Equal(t, p, p2)
})
}

View file

@ -45,3 +45,35 @@ func (r *Replica) SetSelector(s string) {
(*netmap.Replica)(r). (*netmap.Replica)(r).
SetSelector(s) SetSelector(s)
} }
// Marshal marshals Replica into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (r *Replica) Marshal(b ...[]byte) ([]byte, error) {
var buf []byte
if len(b) > 0 {
buf = b[0]
}
return (*netmap.Replica)(r).
StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of Replica.
func (r *Replica) Unmarshal(data []byte) error {
return (*netmap.Replica)(r).
Unmarshal(data)
}
// MarshalJSON encodes Replica to protobuf JSON format.
func (r *Replica) MarshalJSON() ([]byte, error) {
return (*netmap.Replica)(r).
MarshalJSON()
}
// UnmarshalJSON decodes Replica from protobuf JSON format.
func (r *Replica) UnmarshalJSON(data []byte) error {
return (*netmap.Replica)(r).
UnmarshalJSON(data)
}

View file

@ -42,3 +42,27 @@ func TestReplica_Selector(t *testing.T) {
require.Equal(t, s, r.Selector()) require.Equal(t, s, r.Selector())
} }
func TestReplicaEncoding(t *testing.T) {
r := newReplica(3, "selector")
t.Run("binary", func(t *testing.T) {
data, err := r.Marshal()
require.NoError(t, err)
r2 := NewReplica()
require.NoError(t, r2.Unmarshal(data))
require.Equal(t, r, r2)
})
t.Run("json", func(t *testing.T) {
data, err := r.MarshalJSON()
require.NoError(t, err)
r2 := NewReplica()
require.NoError(t, r2.UnmarshalJSON(data))
require.Equal(t, r, r2)
})
}

View file

@ -198,3 +198,34 @@ func (s *Selector) SetFilter(f string) {
(*netmap.Selector)(s). (*netmap.Selector)(s).
SetFilter(f) SetFilter(f)
} }
// Marshal marshals Selector into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
// Otherwise, the first buffer is used.
func (s *Selector) Marshal(b ...[]byte) ([]byte, error) {
var buf []byte
if len(b) > 0 {
buf = b[0]
}
return (*netmap.Selector)(s).StableMarshal(buf)
}
// Unmarshal unmarshals protobuf binary representation of Selector.
func (s *Selector) Unmarshal(data []byte) error {
return (*netmap.Selector)(s).
Unmarshal(data)
}
// MarshalJSON encodes Selector to protobuf JSON format.
func (s *Selector) MarshalJSON() ([]byte, error) {
return (*netmap.Selector)(s).
MarshalJSON()
}
// UnmarshalJSON decodes Selector from protobuf JSON format.
func (s *Selector) UnmarshalJSON(data []byte) error {
return (*netmap.Selector)(s).
UnmarshalJSON(data)
}

View file

@ -307,3 +307,27 @@ func TestSelector_Filter(t *testing.T) {
require.Equal(t, f, s.Filter()) require.Equal(t, f, s.Filter())
} }
func TestSelectorEncoding(t *testing.T) {
s := newSelector("name", "atte", ClauseSame, 1, "filter")
t.Run("binary", func(t *testing.T) {
data, err := s.Marshal()
require.NoError(t, err)
s2 := NewSelector()
require.NoError(t, s2.Unmarshal(data))
require.Equal(t, s, s2)
})
t.Run("json", func(t *testing.T) {
data, err := s.MarshalJSON()
require.NoError(t, err)
s2 := NewSelector()
require.NoError(t, s2.UnmarshalJSON(data))
require.Equal(t, s, s2)
})
}

View file

@ -1,60 +1,126 @@
package netmap package netmap
import ( import (
"errors"
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/encoding/protojson"
) )
var ( func (p *PlacementPolicy) MarshalJSON() ([]byte, error) {
errEmptyInput = errors.New("empty input") return protojson.MarshalOptions{
EmitUnpopulated: true,
}.Marshal(
PlacementPolicyToGRPCMessage(p),
) )
func NodeInfoToJSON(n *NodeInfo) ([]byte, error) {
if n == nil {
return nil, errEmptyInput
}
msg := NodeInfoToGRPCMessage(n)
return protojson.MarshalOptions{EmitUnpopulated: true}.Marshal(msg)
}
func NodeInfoFromJSON(data []byte) (*NodeInfo, error) {
if len(data) == 0 {
return nil, errEmptyInput
}
msg := new(netmap.NodeInfo)
if err := protojson.Unmarshal(data, msg); err != nil {
return nil, err
}
return NodeInfoFromGRPCMessage(msg), nil
}
func PlacementPolicyToJSON(n *PlacementPolicy) ([]byte, error) {
if n == nil {
return nil, errEmptyInput
}
msg := PlacementPolicyToGRPCMessage(n)
return protojson.MarshalOptions{EmitUnpopulated: true}.Marshal(msg)
}
func PlacementPolicyFromJSON(data []byte) (*PlacementPolicy, error) {
if len(data) == 0 {
return nil, errEmptyInput
} }
func (p *PlacementPolicy) UnmarshalJSON(data []byte) error {
msg := new(netmap.PlacementPolicy) msg := new(netmap.PlacementPolicy)
if err := protojson.Unmarshal(data, msg); err != nil { if err := protojson.Unmarshal(data, msg); err != nil {
return nil, err return err
} }
return PlacementPolicyFromGRPCMessage(msg), nil *p = *PlacementPolicyFromGRPCMessage(msg)
return nil
}
func (f *Filter) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{
EmitUnpopulated: true,
}.Marshal(
FilterToGRPCMessage(f),
)
}
func (f *Filter) UnmarshalJSON(data []byte) error {
msg := new(netmap.Filter)
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*f = *FilterFromGRPCMessage(msg)
return nil
}
func (s *Selector) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{
EmitUnpopulated: true,
}.Marshal(
SelectorToGRPCMessage(s),
)
}
func (s *Selector) UnmarshalJSON(data []byte) error {
msg := new(netmap.Selector)
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*s = *SelectorFromGRPCMessage(msg)
return nil
}
func (r *Replica) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{
EmitUnpopulated: true,
}.Marshal(
ReplicaToGRPCMessage(r),
)
}
func (r *Replica) UnmarshalJSON(data []byte) error {
msg := new(netmap.Replica)
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*r = *ReplicaFromGRPCMessage(msg)
return nil
}
func (a *Attribute) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{
EmitUnpopulated: true,
}.Marshal(
AttributeToGRPCMessage(a),
)
}
func (a *Attribute) UnmarshalJSON(data []byte) error {
msg := new(netmap.NodeInfo_Attribute)
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(msg)
return nil
}
func (ni *NodeInfo) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{
EmitUnpopulated: true,
}.Marshal(
NodeInfoToGRPCMessage(ni),
)
}
func (ni *NodeInfo) UnmarshalJSON(data []byte) error {
msg := new(netmap.NodeInfo)
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*ni = *NodeInfoFromGRPCMessage(msg)
return nil
} }

View file

@ -7,46 +7,62 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestFilterJSON(t *testing.T) {
f := generateFilter("key", "value", false)
d, err := f.MarshalJSON()
require.NoError(t, err)
f2 := new(netmap.Filter)
require.NoError(t, f2.UnmarshalJSON(d))
require.Equal(t, f, f2)
}
func TestSelectorJSON(t *testing.T) {
s := generateSelector("name")
data, err := s.MarshalJSON()
require.NoError(t, err)
s2 := new(netmap.Selector)
require.NoError(t, s2.UnmarshalJSON(data))
require.Equal(t, s, s2)
}
func TestReplicaJSON(t *testing.T) {
s := generateReplica("selector")
data, err := s.MarshalJSON()
require.NoError(t, err)
s2 := new(netmap.Replica)
require.NoError(t, s2.UnmarshalJSON(data))
require.Equal(t, s, s2)
}
func TestAttributeJSON(t *testing.T) {
a := generateAttribute("key", "value")
data, err := a.MarshalJSON()
require.NoError(t, err)
a2 := new(netmap.Attribute)
require.NoError(t, a2.UnmarshalJSON(data))
require.Equal(t, a, a2)
}
func TestNodeInfoJSON(t *testing.T) { func TestNodeInfoJSON(t *testing.T) {
exp := generateNodeInfo("public key", "/multi/addr", 2) i := generateNodeInfo("key", "value", 3)
t.Run("non empty", func(t *testing.T) { data, err := i.MarshalJSON()
data, err := netmap.NodeInfoToJSON(exp)
require.NoError(t, err) require.NoError(t, err)
got, err := netmap.NodeInfoFromJSON(data) i2 := new(netmap.NodeInfo)
require.NoError(t, err) require.NoError(t, i2.UnmarshalJSON(data))
require.Equal(t, exp, got) require.Equal(t, i, i2)
})
t.Run("empty", func(t *testing.T) {
_, err := netmap.NodeInfoToJSON(nil)
require.Error(t, err)
_, err = netmap.NodeInfoFromJSON(nil)
require.Error(t, err)
})
}
func TestPlacementPolicyJSON(t *testing.T) {
exp := generatePolicy(3)
t.Run("non empty", func(t *testing.T) {
data, err := netmap.PlacementPolicyToJSON(exp)
require.NoError(t, err)
got, err := netmap.PlacementPolicyFromJSON(data)
require.NoError(t, err)
require.Equal(t, exp, got)
})
t.Run("empty", func(t *testing.T) {
_, err := netmap.PlacementPolicyToJSON(nil)
require.Error(t, err)
_, err = netmap.PlacementPolicyFromJSON(nil)
require.Error(t, err)
})
} }

View file

@ -1,7 +1,9 @@
package netmap package netmap
import ( import (
"github.com/nspcc-dev/neofs-api-go/util/proto" protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"google.golang.org/protobuf/proto"
) )
const ( const (
@ -52,28 +54,28 @@ func (f *Filter) StableMarshal(buf []byte) ([]byte, error) {
err error err error
) )
n, err = proto.StringMarshal(nameFilterField, buf[offset:], f.name) n, err = protoutil.StringMarshal(nameFilterField, buf[offset:], f.name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(keyFilterField, buf[offset:], f.key) n, err = protoutil.StringMarshal(keyFilterField, buf[offset:], f.key)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.EnumMarshal(opFilterField, buf[offset:], int32(f.op)) n, err = protoutil.EnumMarshal(opFilterField, buf[offset:], int32(f.op))
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(valueFilterField, buf[offset:], f.value) n, err = protoutil.StringMarshal(valueFilterField, buf[offset:], f.value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -81,7 +83,7 @@ func (f *Filter) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
for i := range f.filters { for i := range f.filters {
n, err = proto.NestedStructureMarshal(filtersFilterField, buf[offset:], f.filters[i]) n, err = protoutil.NestedStructureMarshal(filtersFilterField, buf[offset:], f.filters[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -93,17 +95,28 @@ func (f *Filter) StableMarshal(buf []byte) ([]byte, error) {
} }
func (f *Filter) StableSize() (size int) { func (f *Filter) StableSize() (size int) {
size += proto.StringSize(nameFilterField, f.name) size += protoutil.StringSize(nameFilterField, f.name)
size += proto.StringSize(keyFilterField, f.key) size += protoutil.StringSize(keyFilterField, f.key)
size += proto.EnumSize(opFilterField, int32(f.op)) size += protoutil.EnumSize(opFilterField, int32(f.op))
size += proto.StringSize(valueFilterField, f.value) size += protoutil.StringSize(valueFilterField, f.value)
for i := range f.filters { for i := range f.filters {
size += proto.NestedStructureSize(filtersFilterField, f.filters[i]) size += protoutil.NestedStructureSize(filtersFilterField, f.filters[i])
} }
return size return size
} }
func (f *Filter) Unmarshal(data []byte) error {
m := new(netmap.Filter)
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*f = *FilterFromGRPCMessage(m)
return nil
}
func (s *Selector) StableMarshal(buf []byte) ([]byte, error) { func (s *Selector) StableMarshal(buf []byte) ([]byte, error) {
if s == nil { if s == nil {
return []byte{}, nil return []byte{}, nil
@ -118,35 +131,35 @@ func (s *Selector) StableMarshal(buf []byte) ([]byte, error) {
err error err error
) )
n, err = proto.StringMarshal(nameSelectorField, buf[offset:], s.name) n, err = protoutil.StringMarshal(nameSelectorField, buf[offset:], s.name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.UInt32Marshal(countSelectorField, buf[offset:], s.count) n, err = protoutil.UInt32Marshal(countSelectorField, buf[offset:], s.count)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.EnumMarshal(clauseSelectorField, buf[offset:], int32(s.clause)) n, err = protoutil.EnumMarshal(clauseSelectorField, buf[offset:], int32(s.clause))
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(attributeSelectorField, buf[offset:], s.attribute) n, err = protoutil.StringMarshal(attributeSelectorField, buf[offset:], s.attribute)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(filterSelectorField, buf[offset:], s.filter) n, err = protoutil.StringMarshal(filterSelectorField, buf[offset:], s.filter)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -155,15 +168,26 @@ func (s *Selector) StableMarshal(buf []byte) ([]byte, error) {
} }
func (s *Selector) StableSize() (size int) { func (s *Selector) StableSize() (size int) {
size += proto.StringSize(nameSelectorField, s.name) size += protoutil.StringSize(nameSelectorField, s.name)
size += proto.UInt32Size(countSelectorField, s.count) size += protoutil.UInt32Size(countSelectorField, s.count)
size += proto.EnumSize(countSelectorField, int32(s.clause)) size += protoutil.EnumSize(countSelectorField, int32(s.clause))
size += proto.StringSize(attributeSelectorField, s.attribute) size += protoutil.StringSize(attributeSelectorField, s.attribute)
size += proto.StringSize(filterSelectorField, s.filter) size += protoutil.StringSize(filterSelectorField, s.filter)
return size return size
} }
func (s *Selector) Unmarshal(data []byte) error {
m := new(netmap.Selector)
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*s = *SelectorFromGRPCMessage(m)
return nil
}
func (r *Replica) StableMarshal(buf []byte) ([]byte, error) { func (r *Replica) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -178,14 +202,14 @@ func (r *Replica) StableMarshal(buf []byte) ([]byte, error) {
err error err error
) )
n, err = proto.UInt32Marshal(countReplicaField, buf[offset:], r.count) n, err = protoutil.UInt32Marshal(countReplicaField, buf[offset:], r.count)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(selectorReplicaField, buf[offset:], r.selector) n, err = protoutil.StringMarshal(selectorReplicaField, buf[offset:], r.selector)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -194,12 +218,23 @@ func (r *Replica) StableMarshal(buf []byte) ([]byte, error) {
} }
func (r *Replica) StableSize() (size int) { func (r *Replica) StableSize() (size int) {
size += proto.UInt32Size(countReplicaField, r.count) size += protoutil.UInt32Size(countReplicaField, r.count)
size += proto.StringSize(selectorReplicaField, r.selector) size += protoutil.StringSize(selectorReplicaField, r.selector)
return size return size
} }
func (r *Replica) Unmarshal(data []byte) error {
m := new(netmap.Replica)
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*r = *ReplicaFromGRPCMessage(m)
return nil
}
func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
if p == nil { if p == nil {
return []byte{}, nil return []byte{}, nil
@ -215,7 +250,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
) )
for i := range p.replicas { for i := range p.replicas {
n, err = proto.NestedStructureMarshal(replicasPolicyField, buf[offset:], p.replicas[i]) n, err = protoutil.NestedStructureMarshal(replicasPolicyField, buf[offset:], p.replicas[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -223,7 +258,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
} }
n, err = proto.UInt32Marshal(backupPolicyField, buf[offset:], p.backupFactor) n, err = protoutil.UInt32Marshal(backupPolicyField, buf[offset:], p.backupFactor)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -231,7 +266,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
for i := range p.selectors { for i := range p.selectors {
n, err = proto.NestedStructureMarshal(selectorsPolicyField, buf[offset:], p.selectors[i]) n, err = protoutil.NestedStructureMarshal(selectorsPolicyField, buf[offset:], p.selectors[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -240,7 +275,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
} }
for i := range p.filters { for i := range p.filters {
n, err = proto.NestedStructureMarshal(filtersPolicyField, buf[offset:], p.filters[i]) n, err = protoutil.NestedStructureMarshal(filtersPolicyField, buf[offset:], p.filters[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -253,22 +288,33 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
func (p *PlacementPolicy) StableSize() (size int) { func (p *PlacementPolicy) StableSize() (size int) {
for i := range p.replicas { for i := range p.replicas {
size += proto.NestedStructureSize(replicasPolicyField, p.replicas[i]) size += protoutil.NestedStructureSize(replicasPolicyField, p.replicas[i])
} }
size += proto.UInt32Size(backupPolicyField, p.backupFactor) size += protoutil.UInt32Size(backupPolicyField, p.backupFactor)
for i := range p.selectors { for i := range p.selectors {
size += proto.NestedStructureSize(selectorsPolicyField, p.selectors[i]) size += protoutil.NestedStructureSize(selectorsPolicyField, p.selectors[i])
} }
for i := range p.filters { for i := range p.filters {
size += proto.NestedStructureSize(filtersPolicyField, p.filters[i]) size += protoutil.NestedStructureSize(filtersPolicyField, p.filters[i])
} }
return size return size
} }
func (p *PlacementPolicy) Unmarshal(data []byte) error {
m := new(netmap.PlacementPolicy)
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*p = *PlacementPolicyFromGRPCMessage(m)
return nil
}
func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) { func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
if a == nil { if a == nil {
return []byte{}, nil return []byte{}, nil
@ -283,14 +329,14 @@ func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
err error err error
) )
n, err = proto.StringMarshal(keyAttributeField, buf[offset:], a.key) n, err = protoutil.StringMarshal(keyAttributeField, buf[offset:], a.key)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(valueAttributeField, buf[offset:], a.value) n, err = protoutil.StringMarshal(valueAttributeField, buf[offset:], a.value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -298,7 +344,7 @@ func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
for i := range a.parents { for i := range a.parents {
n, err = proto.StringMarshal(parentsAttributeField, buf[offset:], a.parents[i]) n, err = protoutil.StringMarshal(parentsAttributeField, buf[offset:], a.parents[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -314,16 +360,27 @@ func (a *Attribute) StableSize() (size int) {
return 0 return 0
} }
size += proto.StringSize(keyAttributeField, a.key) size += protoutil.StringSize(keyAttributeField, a.key)
size += proto.StringSize(valueAttributeField, a.value) size += protoutil.StringSize(valueAttributeField, a.value)
for i := range a.parents { for i := range a.parents {
size += proto.StringSize(parentsAttributeField, a.parents[i]) size += protoutil.StringSize(parentsAttributeField, a.parents[i])
} }
return size return size
} }
func (a *Attribute) Unmarshal(data []byte) error {
m := new(netmap.NodeInfo_Attribute)
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(m)
return nil
}
func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) { func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) {
if ni == nil { if ni == nil {
return []byte{}, nil return []byte{}, nil
@ -338,14 +395,14 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) {
err error err error
) )
n, err = proto.BytesMarshal(keyNodeInfoField, buf[offset:], ni.publicKey) n, err = protoutil.BytesMarshal(keyNodeInfoField, buf[offset:], ni.publicKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
n, err = proto.StringMarshal(addressNodeInfoField, buf[offset:], ni.address) n, err = protoutil.StringMarshal(addressNodeInfoField, buf[offset:], ni.address)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -353,7 +410,7 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
for i := range ni.attributes { for i := range ni.attributes {
n, err = proto.NestedStructureMarshal(attributesNodeInfoField, buf[offset:], ni.attributes[i]) n, err = protoutil.NestedStructureMarshal(attributesNodeInfoField, buf[offset:], ni.attributes[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -361,7 +418,7 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
} }
n, err = proto.EnumMarshal(stateNodeInfoField, buf[offset:], int32(ni.state)) n, err = protoutil.EnumMarshal(stateNodeInfoField, buf[offset:], int32(ni.state))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -374,17 +431,28 @@ func (ni *NodeInfo) StableSize() (size int) {
return 0 return 0
} }
size += proto.BytesSize(keyNodeInfoField, ni.publicKey) size += protoutil.BytesSize(keyNodeInfoField, ni.publicKey)
size += proto.StringSize(addressNodeInfoField, ni.address) size += protoutil.StringSize(addressNodeInfoField, ni.address)
for i := range ni.attributes { for i := range ni.attributes {
size += proto.NestedStructureSize(attributesNodeInfoField, ni.attributes[i]) size += protoutil.NestedStructureSize(attributesNodeInfoField, ni.attributes[i])
} }
size += proto.EnumSize(stateNodeInfoField, int32(ni.state)) size += protoutil.EnumSize(stateNodeInfoField, int32(ni.state))
return size return size
} }
func (ni *NodeInfo) Unmarshal(data []byte) error {
m := new(netmap.NodeInfo)
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*ni = *NodeInfoFromGRPCMessage(m)
return nil
}
func (l *LocalNodeInfoRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (l *LocalNodeInfoRequestBody) StableMarshal(buf []byte) ([]byte, error) {
return nil, nil return nil, nil
} }
@ -407,14 +475,14 @@ func (l *LocalNodeInfoResponseBody) StableMarshal(buf []byte) ([]byte, error) {
err error err error
) )
n, err = proto.NestedStructureMarshal(versionInfoResponseBodyField, buf[offset:], l.version) n, err = protoutil.NestedStructureMarshal(versionInfoResponseBodyField, buf[offset:], l.version)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset += n offset += n
_, err = proto.NestedStructureMarshal(nodeInfoResponseBodyField, buf[offset:], l.nodeInfo) _, err = protoutil.NestedStructureMarshal(nodeInfoResponseBodyField, buf[offset:], l.nodeInfo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -427,8 +495,8 @@ func (l *LocalNodeInfoResponseBody) StableSize() (size int) {
return 0 return 0
} }
size += proto.NestedStructureSize(versionInfoResponseBodyField, l.version) size += protoutil.NestedStructureSize(versionInfoResponseBodyField, l.version)
size += proto.NestedStructureSize(nodeInfoResponseBodyField, l.nodeInfo) size += protoutil.NestedStructureSize(nodeInfoResponseBodyField, l.nodeInfo)
return size return size
} }

View file

@ -13,96 +13,84 @@ import (
func TestAttribute_StableMarshal(t *testing.T) { func TestAttribute_StableMarshal(t *testing.T) {
from := generateAttribute("key", "value") from := generateAttribute("key", "value")
transport := new(grpc.NodeInfo_Attribute)
t.Run("non empty", func(t *testing.T) { t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil) wire, err := from.StableMarshal(nil)
require.NoError(t, err) require.NoError(t, err)
err = goproto.Unmarshal(wire, transport) to := new(netmap.Attribute)
require.NoError(t, err) require.NoError(t, to.Unmarshal(wire))
to := netmap.AttributeFromGRPCMessage(transport)
require.Equal(t, from, to) require.Equal(t, from, to)
}) })
} }
func TestNodeInfo_StableMarshal(t *testing.T) { func TestNodeInfo_StableMarshal(t *testing.T) {
from := generateNodeInfo("publicKey", "/multi/addr", 10) from := generateNodeInfo("publicKey", "/multi/addr", 10)
transport := new(grpc.NodeInfo)
t.Run("non empty", func(t *testing.T) { t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil) wire, err := from.StableMarshal(nil)
require.NoError(t, err) require.NoError(t, err)
err = goproto.Unmarshal(wire, transport) to := new(netmap.NodeInfo)
require.NoError(t, err) require.NoError(t, to.Unmarshal(wire))
to := netmap.NodeInfoFromGRPCMessage(transport)
require.Equal(t, from, to) require.Equal(t, from, to)
}) })
} }
func TestFilter_StableMarshal(t *testing.T) { func TestFilter_StableMarshal(t *testing.T) {
from := generateFilter("key", "value", false) from := generateFilter("key", "value", false)
transport := new(grpc.Filter)
t.Run("non empty", func(t *testing.T) { t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil) wire, err := from.StableMarshal(nil)
require.NoError(t, err) require.NoError(t, err)
err = goproto.Unmarshal(wire, transport) to := new(netmap.Filter)
require.NoError(t, err) require.NoError(t, to.Unmarshal(wire))
to := netmap.FilterFromGRPCMessage(transport)
require.Equal(t, from, to) require.Equal(t, from, to)
}) })
} }
func TestSelector_StableMarshal(t *testing.T) { func TestSelector_StableMarshal(t *testing.T) {
from := generateSelector("name") from := generateSelector("name")
transport := new(grpc.Selector)
t.Run("non empty", func(t *testing.T) { t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil) wire, err := from.StableMarshal(nil)
require.NoError(t, err) require.NoError(t, err)
err = goproto.Unmarshal(wire, transport) to := new(netmap.Selector)
require.NoError(t, err) require.NoError(t, to.Unmarshal(wire))
to := netmap.SelectorFromGRPCMessage(transport)
require.Equal(t, from, to) require.Equal(t, from, to)
}) })
} }
func TestReplica_StableMarshal(t *testing.T) { func TestReplica_StableMarshal(t *testing.T) {
from := generateReplica("selector") from := generateReplica("selector")
transport := new(grpc.Replica)
t.Run("non empty", func(t *testing.T) { t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil) wire, err := from.StableMarshal(nil)
require.NoError(t, err) require.NoError(t, err)
err = goproto.Unmarshal(wire, transport) to := new(netmap.Replica)
require.NoError(t, err) require.NoError(t, to.Unmarshal(wire))
to := netmap.ReplicaFromGRPCMessage(transport)
require.Equal(t, from, to) require.Equal(t, from, to)
}) })
} }
func TestPlacementPolicy_StableMarshal(t *testing.T) { func TestPlacementPolicy_StableMarshal(t *testing.T) {
from := generatePolicy(3) from := generatePolicy(3)
transport := new(grpc.PlacementPolicy)
t.Run("non empty", func(t *testing.T) { t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil) wire, err := from.StableMarshal(nil)
require.NoError(t, err) require.NoError(t, err)
err = goproto.Unmarshal(wire, transport) to := new(netmap.PlacementPolicy)
require.NoError(t, err) require.NoError(t, to.Unmarshal(wire))
to := netmap.PlacementPolicyFromGRPCMessage(transport)
require.Equal(t, from, to) require.Equal(t, from, to)
}) })
} }