From e72173459975a6b0b3796bd42d16daaea40e4418 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Fri, 13 Nov 2020 11:45:59 +0300 Subject: [PATCH] [#168] netmap: Implement binary and JSON encoders/decoders on Filter Signed-off-by: Leonard Lyubich --- pkg/netmap/filter.go | 31 +++++++ pkg/netmap/filter_test.go | 26 ++++++ pkg/netmap/node_info.go | 79 ++++++++++++---- pkg/netmap/node_info_test.go | 52 +++++++++-- pkg/netmap/policy.go | 47 ++++++---- pkg/netmap/policy_test.go | 24 +++++ pkg/netmap/replica.go | 32 +++++++ pkg/netmap/replica_test.go | 24 +++++ pkg/netmap/selector.go | 31 +++++++ pkg/netmap/selector_test.go | 24 +++++ v2/netmap/json.go | 156 ++++++++++++++++++++++---------- v2/netmap/json_test.go | 92 +++++++++++-------- v2/netmap/marshal.go | 170 ++++++++++++++++++++++++----------- v2/netmap/marshal_test.go | 36 +++----- 14 files changed, 628 insertions(+), 196 deletions(-) diff --git a/pkg/netmap/filter.go b/pkg/netmap/filter.go index fa4efc2a..c9b05152 100644 --- a/pkg/netmap/filter.go +++ b/pkg/netmap/filter.go @@ -229,3 +229,34 @@ func (f *Filter) SetInnerFilters(fs ...*Filter) { (*netmap.Filter)(f). 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) +} diff --git a/pkg/netmap/filter_test.go b/pkg/netmap/filter_test.go index 512e431a..4778432a 100644 --- a/pkg/netmap/filter_test.go +++ b/pkg/netmap/filter_test.go @@ -269,3 +269,29 @@ func TestFilter_InnerFilters(t *testing.T) { 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) + }) +} diff --git a/pkg/netmap/node_info.go b/pkg/netmap/node_info.go index 121eaba0..80ec7d10 100644 --- a/pkg/netmap/node_info.go +++ b/pkg/netmap/node_info.go @@ -193,6 +193,38 @@ func (a *NodeAttribute) SetParentKeys(keys ...string) { 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. func NewNodeInfo() *NodeInfo { return NewNodeInfoFromV2(new(netmap.NodeInfo)) @@ -203,21 +235,6 @@ func NewNodeInfoFromV2(i *netmap.NodeInfo) *NodeInfo { 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. func (i *NodeInfo) ToV2() *netmap.NodeInfo { return (*netmap.NodeInfo)(i) @@ -286,3 +303,35 @@ func (i *NodeInfo) SetState(s NodeState) { (*netmap.NodeInfo)(i). 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) +} diff --git a/pkg/netmap/node_info_test.go b/pkg/netmap/node_info_test.go index 92227a1c..9b50a9b2 100644 --- a/pkg/netmap/node_info_test.go +++ b/pkg/netmap/node_info_test.go @@ -128,18 +128,54 @@ func TestNodeInfo_Attributes(t *testing.T) { 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.SetPublicKey([]byte{1, 2, 3}) - i.SetAddress("some node address") + i.SetAddress("192.168.0.1") i.SetState(NodeStateOnline) - i.SetAttributes(testNodeAttribute(), testNodeAttribute()) + i.SetAttributes(testNodeAttribute()) - j, err := NodeInfoToJSON(i) - require.NoError(t, err) + t.Run("binary", func(t *testing.T) { + data, err := i.Marshal() + require.NoError(t, err) - i2, err := NodeInfoFromJSON(j) - require.NoError(t, err) + i2 := NewNodeInfo() + 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) + }) } diff --git a/pkg/netmap/policy.go b/pkg/netmap/policy.go index a592573d..84a5583f 100644 --- a/pkg/netmap/policy.go +++ b/pkg/netmap/policy.go @@ -7,21 +7,6 @@ import ( // PlacementPolicy represents v2-compatible placement policy. 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. func NewPlacementPolicy() *PlacementPolicy { return NewPlacementPolicyFromV2(new(netmap.PlacementPolicy)) @@ -114,3 +99,35 @@ func (p *PlacementPolicy) SetFilters(fs ...*Filter) { (*netmap.PlacementPolicy)(p). 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) +} diff --git a/pkg/netmap/policy_test.go b/pkg/netmap/policy_test.go index 705c875d..5db6d5bb 100644 --- a/pkg/netmap/policy_test.go +++ b/pkg/netmap/policy_test.go @@ -67,3 +67,27 @@ func TestPlacementPolicy_Filters(t *testing.T) { 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) + }) +} diff --git a/pkg/netmap/replica.go b/pkg/netmap/replica.go index 153a2691..95349e60 100644 --- a/pkg/netmap/replica.go +++ b/pkg/netmap/replica.go @@ -45,3 +45,35 @@ func (r *Replica) SetSelector(s string) { (*netmap.Replica)(r). 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) +} diff --git a/pkg/netmap/replica_test.go b/pkg/netmap/replica_test.go index bd7c368f..e366c2ee 100644 --- a/pkg/netmap/replica_test.go +++ b/pkg/netmap/replica_test.go @@ -42,3 +42,27 @@ func TestReplica_Selector(t *testing.T) { 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) + }) +} diff --git a/pkg/netmap/selector.go b/pkg/netmap/selector.go index 0217c415..c77e0620 100644 --- a/pkg/netmap/selector.go +++ b/pkg/netmap/selector.go @@ -198,3 +198,34 @@ func (s *Selector) SetFilter(f string) { (*netmap.Selector)(s). 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) +} diff --git a/pkg/netmap/selector_test.go b/pkg/netmap/selector_test.go index 5ee2682b..2c8abeeb 100644 --- a/pkg/netmap/selector_test.go +++ b/pkg/netmap/selector_test.go @@ -307,3 +307,27 @@ func TestSelector_Filter(t *testing.T) { 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) + }) +} diff --git a/v2/netmap/json.go b/v2/netmap/json.go index 03c79f79..72105017 100644 --- a/v2/netmap/json.go +++ b/v2/netmap/json.go @@ -1,60 +1,126 @@ package netmap import ( - "errors" - netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" "google.golang.org/protobuf/encoding/protojson" ) -var ( - errEmptyInput = errors.New("empty input") -) - -func NodeInfoToJSON(n *NodeInfo) ([]byte, error) { - if n == nil { - return nil, errEmptyInput - } - - msg := NodeInfoToGRPCMessage(n) - - return protojson.MarshalOptions{EmitUnpopulated: true}.Marshal(msg) +func (p *PlacementPolicy) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + EmitUnpopulated: true, + }.Marshal( + PlacementPolicyToGRPCMessage(p), + ) } -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) 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 } diff --git a/v2/netmap/json_test.go b/v2/netmap/json_test.go index 34abad15..561dbf12 100644 --- a/v2/netmap/json_test.go +++ b/v2/netmap/json_test.go @@ -7,46 +7,62 @@ import ( "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) { - exp := generateNodeInfo("public key", "/multi/addr", 2) + i := generateNodeInfo("key", "value", 3) - t.Run("non empty", func(t *testing.T) { - data, err := netmap.NodeInfoToJSON(exp) - require.NoError(t, err) + data, err := i.MarshalJSON() + require.NoError(t, err) - got, err := netmap.NodeInfoFromJSON(data) - require.NoError(t, err) + i2 := new(netmap.NodeInfo) + require.NoError(t, i2.UnmarshalJSON(data)) - require.Equal(t, exp, got) - }) - - 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) - }) + require.Equal(t, i, i2) } diff --git a/v2/netmap/marshal.go b/v2/netmap/marshal.go index d8b9a26b..b619628e 100644 --- a/v2/netmap/marshal.go +++ b/v2/netmap/marshal.go @@ -1,7 +1,9 @@ package netmap 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 ( @@ -52,28 +54,28 @@ func (f *Filter) StableMarshal(buf []byte) ([]byte, error) { err error ) - n, err = proto.StringMarshal(nameFilterField, buf[offset:], f.name) + n, err = protoutil.StringMarshal(nameFilterField, buf[offset:], f.name) if err != nil { return nil, err } offset += n - n, err = proto.StringMarshal(keyFilterField, buf[offset:], f.key) + n, err = protoutil.StringMarshal(keyFilterField, buf[offset:], f.key) if err != nil { return nil, err } 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 { return nil, err } offset += n - n, err = proto.StringMarshal(valueFilterField, buf[offset:], f.value) + n, err = protoutil.StringMarshal(valueFilterField, buf[offset:], f.value) if err != nil { return nil, err } @@ -81,7 +83,7 @@ func (f *Filter) StableMarshal(buf []byte) ([]byte, error) { offset += n 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 { return nil, err } @@ -93,17 +95,28 @@ func (f *Filter) StableMarshal(buf []byte) ([]byte, error) { } func (f *Filter) StableSize() (size int) { - size += proto.StringSize(nameFilterField, f.name) - size += proto.StringSize(keyFilterField, f.key) - size += proto.EnumSize(opFilterField, int32(f.op)) - size += proto.StringSize(valueFilterField, f.value) + size += protoutil.StringSize(nameFilterField, f.name) + size += protoutil.StringSize(keyFilterField, f.key) + size += protoutil.EnumSize(opFilterField, int32(f.op)) + size += protoutil.StringSize(valueFilterField, f.value) for i := range f.filters { - size += proto.NestedStructureSize(filtersFilterField, f.filters[i]) + size += protoutil.NestedStructureSize(filtersFilterField, f.filters[i]) } 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) { if s == nil { return []byte{}, nil @@ -118,35 +131,35 @@ func (s *Selector) StableMarshal(buf []byte) ([]byte, error) { err error ) - n, err = proto.StringMarshal(nameSelectorField, buf[offset:], s.name) + n, err = protoutil.StringMarshal(nameSelectorField, buf[offset:], s.name) if err != nil { return nil, err } offset += n - n, err = proto.UInt32Marshal(countSelectorField, buf[offset:], s.count) + n, err = protoutil.UInt32Marshal(countSelectorField, buf[offset:], s.count) if err != nil { return nil, err } 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 { return nil, err } offset += n - n, err = proto.StringMarshal(attributeSelectorField, buf[offset:], s.attribute) + n, err = protoutil.StringMarshal(attributeSelectorField, buf[offset:], s.attribute) if err != nil { return nil, err } offset += n - n, err = proto.StringMarshal(filterSelectorField, buf[offset:], s.filter) + n, err = protoutil.StringMarshal(filterSelectorField, buf[offset:], s.filter) if err != nil { return nil, err } @@ -155,15 +168,26 @@ func (s *Selector) StableMarshal(buf []byte) ([]byte, error) { } func (s *Selector) StableSize() (size int) { - size += proto.StringSize(nameSelectorField, s.name) - size += proto.UInt32Size(countSelectorField, s.count) - size += proto.EnumSize(countSelectorField, int32(s.clause)) - size += proto.StringSize(attributeSelectorField, s.attribute) - size += proto.StringSize(filterSelectorField, s.filter) + size += protoutil.StringSize(nameSelectorField, s.name) + size += protoutil.UInt32Size(countSelectorField, s.count) + size += protoutil.EnumSize(countSelectorField, int32(s.clause)) + size += protoutil.StringSize(attributeSelectorField, s.attribute) + size += protoutil.StringSize(filterSelectorField, s.filter) 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) { if r == nil { return []byte{}, nil @@ -178,14 +202,14 @@ func (r *Replica) StableMarshal(buf []byte) ([]byte, error) { err error ) - n, err = proto.UInt32Marshal(countReplicaField, buf[offset:], r.count) + n, err = protoutil.UInt32Marshal(countReplicaField, buf[offset:], r.count) if err != nil { return nil, err } offset += n - n, err = proto.StringMarshal(selectorReplicaField, buf[offset:], r.selector) + n, err = protoutil.StringMarshal(selectorReplicaField, buf[offset:], r.selector) if err != nil { return nil, err } @@ -194,12 +218,23 @@ func (r *Replica) StableMarshal(buf []byte) ([]byte, error) { } func (r *Replica) StableSize() (size int) { - size += proto.UInt32Size(countReplicaField, r.count) - size += proto.StringSize(selectorReplicaField, r.selector) + size += protoutil.UInt32Size(countReplicaField, r.count) + size += protoutil.StringSize(selectorReplicaField, r.selector) 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) { if p == nil { return []byte{}, nil @@ -215,7 +250,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { ) 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 { return nil, err } @@ -223,7 +258,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { offset += n } - n, err = proto.UInt32Marshal(backupPolicyField, buf[offset:], p.backupFactor) + n, err = protoutil.UInt32Marshal(backupPolicyField, buf[offset:], p.backupFactor) if err != nil { return nil, err } @@ -231,7 +266,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { offset += n 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 { return nil, err } @@ -240,7 +275,7 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { } 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 { return nil, err } @@ -253,22 +288,33 @@ func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { func (p *PlacementPolicy) StableSize() (size int) { 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 { - size += proto.NestedStructureSize(selectorsPolicyField, p.selectors[i]) + size += protoutil.NestedStructureSize(selectorsPolicyField, p.selectors[i]) } for i := range p.filters { - size += proto.NestedStructureSize(filtersPolicyField, p.filters[i]) + size += protoutil.NestedStructureSize(filtersPolicyField, p.filters[i]) } 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) { if a == nil { return []byte{}, nil @@ -283,14 +329,14 @@ func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) { err error ) - n, err = proto.StringMarshal(keyAttributeField, buf[offset:], a.key) + n, err = protoutil.StringMarshal(keyAttributeField, buf[offset:], a.key) if err != nil { return nil, err } offset += n - n, err = proto.StringMarshal(valueAttributeField, buf[offset:], a.value) + n, err = protoutil.StringMarshal(valueAttributeField, buf[offset:], a.value) if err != nil { return nil, err } @@ -298,7 +344,7 @@ func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) { offset += n 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 { return nil, err } @@ -314,16 +360,27 @@ func (a *Attribute) StableSize() (size int) { return 0 } - size += proto.StringSize(keyAttributeField, a.key) - size += proto.StringSize(valueAttributeField, a.value) + size += protoutil.StringSize(keyAttributeField, a.key) + size += protoutil.StringSize(valueAttributeField, a.value) for i := range a.parents { - size += proto.StringSize(parentsAttributeField, a.parents[i]) + size += protoutil.StringSize(parentsAttributeField, a.parents[i]) } 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) { if ni == nil { return []byte{}, nil @@ -338,14 +395,14 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) { err error ) - n, err = proto.BytesMarshal(keyNodeInfoField, buf[offset:], ni.publicKey) + n, err = protoutil.BytesMarshal(keyNodeInfoField, buf[offset:], ni.publicKey) if err != nil { return nil, err } offset += n - n, err = proto.StringMarshal(addressNodeInfoField, buf[offset:], ni.address) + n, err = protoutil.StringMarshal(addressNodeInfoField, buf[offset:], ni.address) if err != nil { return nil, err } @@ -353,7 +410,7 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) { offset += n 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 { return nil, err } @@ -361,7 +418,7 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) { 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 { return nil, err } @@ -374,17 +431,28 @@ func (ni *NodeInfo) StableSize() (size int) { return 0 } - size += proto.BytesSize(keyNodeInfoField, ni.publicKey) - size += proto.StringSize(addressNodeInfoField, ni.address) + size += protoutil.BytesSize(keyNodeInfoField, ni.publicKey) + size += protoutil.StringSize(addressNodeInfoField, ni.address) 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 } +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) { return nil, nil } @@ -407,14 +475,14 @@ func (l *LocalNodeInfoResponseBody) StableMarshal(buf []byte) ([]byte, error) { err error ) - n, err = proto.NestedStructureMarshal(versionInfoResponseBodyField, buf[offset:], l.version) + n, err = protoutil.NestedStructureMarshal(versionInfoResponseBodyField, buf[offset:], l.version) if err != nil { return nil, err } offset += n - _, err = proto.NestedStructureMarshal(nodeInfoResponseBodyField, buf[offset:], l.nodeInfo) + _, err = protoutil.NestedStructureMarshal(nodeInfoResponseBodyField, buf[offset:], l.nodeInfo) if err != nil { return nil, err } @@ -427,8 +495,8 @@ func (l *LocalNodeInfoResponseBody) StableSize() (size int) { return 0 } - size += proto.NestedStructureSize(versionInfoResponseBodyField, l.version) - size += proto.NestedStructureSize(nodeInfoResponseBodyField, l.nodeInfo) + size += protoutil.NestedStructureSize(versionInfoResponseBodyField, l.version) + size += protoutil.NestedStructureSize(nodeInfoResponseBodyField, l.nodeInfo) return size } diff --git a/v2/netmap/marshal_test.go b/v2/netmap/marshal_test.go index 361bc508..63347ad5 100644 --- a/v2/netmap/marshal_test.go +++ b/v2/netmap/marshal_test.go @@ -13,96 +13,84 @@ import ( func TestAttribute_StableMarshal(t *testing.T) { from := generateAttribute("key", "value") - transport := new(grpc.NodeInfo_Attribute) t.Run("non empty", func(t *testing.T) { wire, err := from.StableMarshal(nil) require.NoError(t, err) - err = goproto.Unmarshal(wire, transport) - require.NoError(t, err) + to := new(netmap.Attribute) + require.NoError(t, to.Unmarshal(wire)) - to := netmap.AttributeFromGRPCMessage(transport) require.Equal(t, from, to) }) } func TestNodeInfo_StableMarshal(t *testing.T) { from := generateNodeInfo("publicKey", "/multi/addr", 10) - transport := new(grpc.NodeInfo) t.Run("non empty", func(t *testing.T) { wire, err := from.StableMarshal(nil) require.NoError(t, err) - err = goproto.Unmarshal(wire, transport) - require.NoError(t, err) + to := new(netmap.NodeInfo) + require.NoError(t, to.Unmarshal(wire)) - to := netmap.NodeInfoFromGRPCMessage(transport) require.Equal(t, from, to) }) } func TestFilter_StableMarshal(t *testing.T) { from := generateFilter("key", "value", false) - transport := new(grpc.Filter) t.Run("non empty", func(t *testing.T) { wire, err := from.StableMarshal(nil) require.NoError(t, err) - err = goproto.Unmarshal(wire, transport) - require.NoError(t, err) + to := new(netmap.Filter) + require.NoError(t, to.Unmarshal(wire)) - to := netmap.FilterFromGRPCMessage(transport) require.Equal(t, from, to) }) } func TestSelector_StableMarshal(t *testing.T) { from := generateSelector("name") - transport := new(grpc.Selector) t.Run("non empty", func(t *testing.T) { wire, err := from.StableMarshal(nil) require.NoError(t, err) - err = goproto.Unmarshal(wire, transport) - require.NoError(t, err) + to := new(netmap.Selector) + require.NoError(t, to.Unmarshal(wire)) - to := netmap.SelectorFromGRPCMessage(transport) require.Equal(t, from, to) }) } func TestReplica_StableMarshal(t *testing.T) { from := generateReplica("selector") - transport := new(grpc.Replica) t.Run("non empty", func(t *testing.T) { wire, err := from.StableMarshal(nil) require.NoError(t, err) - err = goproto.Unmarshal(wire, transport) - require.NoError(t, err) + to := new(netmap.Replica) + require.NoError(t, to.Unmarshal(wire)) - to := netmap.ReplicaFromGRPCMessage(transport) require.Equal(t, from, to) }) } func TestPlacementPolicy_StableMarshal(t *testing.T) { from := generatePolicy(3) - transport := new(grpc.PlacementPolicy) t.Run("non empty", func(t *testing.T) { wire, err := from.StableMarshal(nil) require.NoError(t, err) - err = goproto.Unmarshal(wire, transport) - require.NoError(t, err) + to := new(netmap.PlacementPolicy) + require.NoError(t, to.Unmarshal(wire)) - to := netmap.PlacementPolicyFromGRPCMessage(transport) require.Equal(t, from, to) }) }