diff --git a/v2/accounting/accounting.go b/accounting/accounting.go similarity index 100% rename from v2/accounting/accounting.go rename to accounting/accounting.go diff --git a/v2/accounting/convert.go b/accounting/convert.go similarity index 96% rename from v2/accounting/convert.go rename to accounting/convert.go index 2a842f8..1d32210 100644 --- a/v2/accounting/convert.go +++ b/accounting/convert.go @@ -1,11 +1,11 @@ package accounting import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (b *BalanceRequestBody) ToGRPCMessage() grpc.Message { diff --git a/v2/accounting/grpc/service.go b/accounting/grpc/service.go similarity index 100% rename from v2/accounting/grpc/service.go rename to accounting/grpc/service.go diff --git a/v2/accounting/grpc/service.pb.go b/accounting/grpc/service.pb.go similarity index 100% rename from v2/accounting/grpc/service.pb.go rename to accounting/grpc/service.pb.go diff --git a/v2/accounting/grpc/service_grpc.pb.go b/accounting/grpc/service_grpc.pb.go similarity index 100% rename from v2/accounting/grpc/service_grpc.pb.go rename to accounting/grpc/service_grpc.pb.go diff --git a/v2/accounting/grpc/types.go b/accounting/grpc/types.go similarity index 100% rename from v2/accounting/grpc/types.go rename to accounting/grpc/types.go diff --git a/v2/accounting/grpc/types.pb.go b/accounting/grpc/types.pb.go similarity index 100% rename from v2/accounting/grpc/types.pb.go rename to accounting/grpc/types.pb.go diff --git a/v2/accounting/json.go b/accounting/json.go similarity index 85% rename from v2/accounting/json.go rename to accounting/json.go index 6229885..5b4378e 100644 --- a/v2/accounting/json.go +++ b/accounting/json.go @@ -1,8 +1,8 @@ package accounting import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (d *Decimal) MarshalJSON() ([]byte, error) { diff --git a/v2/accounting/marshal.go b/accounting/marshal.go similarity index 95% rename from v2/accounting/marshal.go rename to accounting/marshal.go index 11ae796..8c2e06f 100644 --- a/v2/accounting/marshal.go +++ b/accounting/marshal.go @@ -1,9 +1,9 @@ package accounting import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/accounting/message_test.go b/accounting/message_test.go similarity index 84% rename from v2/accounting/message_test.go rename to accounting/message_test.go index baf71fa..16e6d30 100644 --- a/v2/accounting/message_test.go +++ b/accounting/message_test.go @@ -3,9 +3,9 @@ package accounting_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" accountingtest "github.com/nspcc-dev/neofs-api-go/v2/accounting/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessage(t *testing.T) { diff --git a/v2/accounting/test/generate.go b/accounting/test/generate.go similarity index 100% rename from v2/accounting/test/generate.go rename to accounting/test/generate.go diff --git a/v2/acl/convert.go b/acl/convert.go similarity index 99% rename from v2/acl/convert.go rename to acl/convert.go index d501b56..55b333a 100644 --- a/v2/acl/convert.go +++ b/acl/convert.go @@ -1,11 +1,11 @@ package acl import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) // RoleToGRPCField converts unified role enum into grpc enum. diff --git a/v2/acl/filters.go b/acl/filters.go similarity index 100% rename from v2/acl/filters.go rename to acl/filters.go diff --git a/v2/acl/grpc/types.go b/acl/grpc/types.go similarity index 100% rename from v2/acl/grpc/types.go rename to acl/grpc/types.go diff --git a/v2/acl/grpc/types.pb.go b/acl/grpc/types.pb.go similarity index 100% rename from v2/acl/grpc/types.pb.go rename to acl/grpc/types.pb.go diff --git a/v2/acl/json.go b/acl/json.go similarity index 96% rename from v2/acl/json.go rename to acl/json.go index 1a3cacd..8144954 100644 --- a/v2/acl/json.go +++ b/acl/json.go @@ -1,8 +1,8 @@ package acl import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (f *HeaderFilter) MarshalJSON() ([]byte, error) { diff --git a/v2/acl/marshal.go b/acl/marshal.go similarity index 98% rename from v2/acl/marshal.go rename to acl/marshal.go index 15a317d..cfa4470 100644 --- a/v2/acl/marshal.go +++ b/acl/marshal.go @@ -1,9 +1,9 @@ package acl import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/acl/message_test.go b/acl/message_test.go similarity index 85% rename from v2/acl/message_test.go rename to acl/message_test.go index bb6d991..ac1b369 100644 --- a/v2/acl/message_test.go +++ b/acl/message_test.go @@ -3,9 +3,9 @@ package acl_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/acl/string.go b/acl/string.go similarity index 100% rename from v2/acl/string.go rename to acl/string.go diff --git a/v2/acl/test/generate.go b/acl/test/generate.go similarity index 100% rename from v2/acl/test/generate.go rename to acl/test/generate.go diff --git a/v2/acl/types.go b/acl/types.go similarity index 100% rename from v2/acl/types.go rename to acl/types.go diff --git a/v2/audit/convert.go b/audit/convert.go similarity index 95% rename from v2/audit/convert.go rename to audit/convert.go index 1b2a998..a8b18fa 100644 --- a/v2/audit/convert.go +++ b/audit/convert.go @@ -1,11 +1,11 @@ package audit import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (a *DataAuditResult) ToGRPCMessage() grpc.Message { diff --git a/v2/audit/grpc/types.go b/audit/grpc/types.go similarity index 100% rename from v2/audit/grpc/types.go rename to audit/grpc/types.go diff --git a/v2/audit/grpc/types.pb.go b/audit/grpc/types.pb.go similarity index 100% rename from v2/audit/grpc/types.pb.go rename to audit/grpc/types.pb.go diff --git a/v2/audit/json.go b/audit/json.go similarity index 85% rename from v2/audit/json.go rename to audit/json.go index b119aa1..be46491 100644 --- a/v2/audit/json.go +++ b/audit/json.go @@ -1,8 +1,8 @@ package audit import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (a *DataAuditResult) MarshalJSON() ([]byte, error) { diff --git a/v2/audit/marshal.go b/audit/marshal.go similarity index 97% rename from v2/audit/marshal.go rename to audit/marshal.go index e1c1b53..dc46a21 100644 --- a/v2/audit/marshal.go +++ b/audit/marshal.go @@ -1,10 +1,10 @@ package audit import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - "github.com/nspcc-dev/neofs-api-go/util/proto" audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/audit/message_test.go b/audit/message_test.go similarity index 68% rename from v2/audit/message_test.go rename to audit/message_test.go index dbfc7b7..1e0d485 100644 --- a/v2/audit/message_test.go +++ b/audit/message_test.go @@ -3,9 +3,9 @@ package audit_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" audittest "github.com/nspcc-dev/neofs-api-go/v2/audit/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/audit/test/generate.go b/audit/test/generate.go similarity index 100% rename from v2/audit/test/generate.go rename to audit/test/generate.go diff --git a/v2/audit/types.go b/audit/types.go similarity index 100% rename from v2/audit/types.go rename to audit/types.go diff --git a/v2/container/attributes.go b/container/attributes.go similarity index 100% rename from v2/container/attributes.go rename to container/attributes.go diff --git a/v2/container/convert.go b/container/convert.go similarity index 99% rename from v2/container/convert.go rename to container/convert.go index be0bb10..977ad77 100644 --- a/v2/container/convert.go +++ b/container/convert.go @@ -1,8 +1,6 @@ package container import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/acl" aclGRPC "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" @@ -10,6 +8,8 @@ import ( netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/session" sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" ) diff --git a/v2/container/grpc/service.go b/container/grpc/service.go similarity index 100% rename from v2/container/grpc/service.go rename to container/grpc/service.go diff --git a/v2/container/grpc/service.pb.go b/container/grpc/service.pb.go similarity index 100% rename from v2/container/grpc/service.pb.go rename to container/grpc/service.pb.go diff --git a/v2/container/grpc/service_grpc.pb.go b/container/grpc/service_grpc.pb.go similarity index 100% rename from v2/container/grpc/service_grpc.pb.go rename to container/grpc/service_grpc.pb.go diff --git a/v2/container/grpc/types.go b/container/grpc/types.go similarity index 100% rename from v2/container/grpc/types.go rename to container/grpc/types.go diff --git a/v2/container/grpc/types.pb.go b/container/grpc/types.pb.go similarity index 100% rename from v2/container/grpc/types.pb.go rename to container/grpc/types.pb.go diff --git a/v2/container/json.go b/container/json.go similarity index 90% rename from v2/container/json.go rename to container/json.go index c681540..b354585 100644 --- a/v2/container/json.go +++ b/container/json.go @@ -1,8 +1,8 @@ package container import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (a *Attribute) MarshalJSON() ([]byte, error) { diff --git a/v2/container/marshal.go b/container/marshal.go similarity index 99% rename from v2/container/marshal.go rename to container/marshal.go index a53661d..69160ab 100644 --- a/v2/container/marshal.go +++ b/container/marshal.go @@ -1,9 +1,9 @@ package container import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/container/message_test.go b/container/message_test.go similarity index 96% rename from v2/container/message_test.go rename to container/message_test.go index 9d2786b..3f7b076 100644 --- a/v2/container/message_test.go +++ b/container/message_test.go @@ -3,9 +3,9 @@ package container_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" containertest "github.com/nspcc-dev/neofs-api-go/v2/container/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/container/test/generate.go b/container/test/generate.go similarity index 100% rename from v2/container/test/generate.go rename to container/test/generate.go diff --git a/v2/container/types.go b/container/types.go similarity index 100% rename from v2/container/types.go rename to container/types.go diff --git a/go.mod b/go.mod index cfcdf6e..27739f3 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,10 @@ -module github.com/nspcc-dev/neofs-api-go +module github.com/nspcc-dev/neofs-api-go/v2 go 1.16 require ( - github.com/google/uuid v1.1.2 - github.com/mr-tron/base58 v1.1.2 - github.com/nspcc-dev/hrw v1.0.9 - github.com/nspcc-dev/neo-go v0.95.3 github.com/nspcc-dev/neofs-crypto v0.3.0 github.com/stretchr/testify v1.7.0 - golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b // indirect - golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 // indirect google.golang.org/grpc v1.41.0 google.golang.org/protobuf v1.27.1 ) diff --git a/go.sum b/go.sum index 4ebb679..daed05b 100644 --- a/go.sum +++ b/go.sum @@ -1,85 +1,25 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/CityOfZion/neo-go v0.62.1-pre.0.20191114145240-e740fbe708f8/go.mod h1:MJCkWUBhi9pn/CrYO1Q3P687y2KeahrOPS9BD9LDGb0= -github.com/CityOfZion/neo-go v0.70.1-pre.0.20191209120015-fccb0085941e/go.mod h1:0enZl0az8xA6PVkwzEOwPWVJGqlt/GO4hA4kmQ5Xzig= -github.com/CityOfZion/neo-go v0.70.1-pre.0.20191212173117-32ac01130d4c/go.mod h1:JtlHfeqLywZLswKIKFnAp+yzezY4Dji9qlfQKB2OD/I= -github.com/CityOfZion/neo-go v0.71.1-pre.0.20200129171427-f773ec69fb84/go.mod h1:FLI526IrRWHmcsO+mHsCbj64pJZhwQFTLJZu+A4PGOA= -github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= -github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg= -github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM= -github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= -github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -90,12 +30,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -103,135 +39,27 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nspcc-dev/dbft v0.0.0-20191205084618-dacb1a30c254/go.mod h1:w1Ln2aT+dBlPhLnuZhBV+DfPEdS2CHWWLp5JTScY3bw= -github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae/go.mod h1:3FjXOoHmA51EGfb5GS/HOv7VdmngNRTssSeQ729dvGY= -github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk= -github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ= -github.com/nspcc-dev/dbft v0.0.0-20200711144034-c526ccc6f570/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= -github.com/nspcc-dev/dbft v0.0.0-20210302103605-cc75991b7cfb/go.mod h1:U8MSnEShH+o5hexfWJdze6uMFJteP0ko7J2frO7Yu1Y= -github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y= -github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU= -github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg= -github.com/nspcc-dev/neo-go v0.91.0/go.mod h1:G6HdOWvzQ6tlvFdvFSN/PgCzLPN/X/X4d5hTjFRUDcc= -github.com/nspcc-dev/neo-go v0.95.1/go.mod h1:bW07ge1WFXsBgqrcPpLUr6OcyQxHqM26MZNesWMdH0c= -github.com/nspcc-dev/neo-go v0.95.3 h1:RxBKcmmatbSM2cETGhv3ritmrkU0gUnWItNZvtrBtI0= -github.com/nspcc-dev/neo-go v0.95.3/go.mod h1:t15xRFDVhz5o/pstptdoW9N9JJBNn1hZ6APMNiC6MrY= -github.com/nspcc-dev/neofs-api-go v1.24.0/go.mod h1:G7dqincfdjBrAbL5nxVp82emF05fSVEqe59ICsoRDI8= -github.com/nspcc-dev/neofs-api-go v1.27.1/go.mod h1:i0Cwgvcu9A4M4e58pydbXFisUhSxpfljmuWFPIp2btE= -github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA= -github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw= github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM= github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw= -github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE= github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/syndtr/goleveldb v0.0.0-20180307113352-169b1b37be73/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= -github.com/yuin/gopher-lua v0.0.0-20191128022950-c6266f4fe8d7/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -239,18 +67,12 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo= -golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -258,37 +80,12 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/tools v0.0.0-20180318012157-96caea41033d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -301,17 +98,14 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 h1:XTH066D35LyHehRwlYhoK3qA+Hcgvg5xREG4kFQEW1Y= -google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -324,20 +118,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/abiosoft/ishell.v2 v2.0.0/go.mod h1:sFp+cGtH6o4s1FtpVPTMcHq2yue+c4DGOVohJCPUzwY= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/v2/netmap/convert.go b/netmap/convert.go similarity index 99% rename from v2/netmap/convert.go rename to netmap/convert.go index 59c5e60..e059592 100644 --- a/v2/netmap/convert.go +++ b/netmap/convert.go @@ -1,11 +1,11 @@ package netmap import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (f *Filter) ToGRPCMessage() grpc.Message { diff --git a/v2/netmap/grpc/service.go b/netmap/grpc/service.go similarity index 100% rename from v2/netmap/grpc/service.go rename to netmap/grpc/service.go diff --git a/v2/netmap/grpc/service.pb.go b/netmap/grpc/service.pb.go similarity index 100% rename from v2/netmap/grpc/service.pb.go rename to netmap/grpc/service.pb.go diff --git a/v2/netmap/grpc/service_grpc.pb.go b/netmap/grpc/service_grpc.pb.go similarity index 100% rename from v2/netmap/grpc/service_grpc.pb.go rename to netmap/grpc/service_grpc.pb.go diff --git a/v2/netmap/grpc/types.go b/netmap/grpc/types.go similarity index 100% rename from v2/netmap/grpc/types.go rename to netmap/grpc/types.go diff --git a/v2/netmap/grpc/types.pb.go b/netmap/grpc/types.pb.go similarity index 100% rename from v2/netmap/grpc/types.pb.go rename to netmap/grpc/types.pb.go diff --git a/v2/netmap/json.go b/netmap/json.go similarity index 96% rename from v2/netmap/json.go rename to netmap/json.go index 64f2f6d..05979ba 100644 --- a/v2/netmap/json.go +++ b/netmap/json.go @@ -1,8 +1,8 @@ package netmap import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (p *PlacementPolicy) MarshalJSON() ([]byte, error) { diff --git a/v2/netmap/marshal.go b/netmap/marshal.go similarity index 99% rename from v2/netmap/marshal.go rename to netmap/marshal.go index 4f818e5..d252111 100644 --- a/v2/netmap/marshal.go +++ b/netmap/marshal.go @@ -1,9 +1,9 @@ package netmap import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/netmap/message_test.go b/netmap/message_test.go similarity index 91% rename from v2/netmap/message_test.go rename to netmap/message_test.go index 1c921e0..bbe6368 100644 --- a/v2/netmap/message_test.go +++ b/netmap/message_test.go @@ -3,9 +3,9 @@ package netmap_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" netmaptest "github.com/nspcc-dev/neofs-api-go/v2/netmap/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/netmap/string.go b/netmap/string.go similarity index 100% rename from v2/netmap/string.go rename to netmap/string.go diff --git a/v2/netmap/test/generate.go b/netmap/test/generate.go similarity index 100% rename from v2/netmap/test/generate.go rename to netmap/test/generate.go diff --git a/v2/netmap/types.go b/netmap/types.go similarity index 100% rename from v2/netmap/types.go rename to netmap/types.go diff --git a/v2/object/attributes.go b/object/attributes.go similarity index 100% rename from v2/object/attributes.go rename to object/attributes.go diff --git a/v2/object/convert.go b/object/convert.go similarity index 99% rename from v2/object/convert.go rename to object/convert.go index 0d2d142..d7c0a28 100644 --- a/v2/object/convert.go +++ b/object/convert.go @@ -3,11 +3,11 @@ package object import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/session" sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" ) diff --git a/v2/object/filters.go b/object/filters.go similarity index 100% rename from v2/object/filters.go rename to object/filters.go diff --git a/v2/object/grpc/client.go b/object/grpc/client.go similarity index 100% rename from v2/object/grpc/client.go rename to object/grpc/client.go diff --git a/v2/object/grpc/service.go b/object/grpc/service.go similarity index 100% rename from v2/object/grpc/service.go rename to object/grpc/service.go diff --git a/v2/object/grpc/service.pb.go b/object/grpc/service.pb.go similarity index 100% rename from v2/object/grpc/service.pb.go rename to object/grpc/service.pb.go diff --git a/v2/object/grpc/service_grpc.pb.go b/object/grpc/service_grpc.pb.go similarity index 100% rename from v2/object/grpc/service_grpc.pb.go rename to object/grpc/service_grpc.pb.go diff --git a/v2/object/grpc/types.go b/object/grpc/types.go similarity index 100% rename from v2/object/grpc/types.go rename to object/grpc/types.go diff --git a/v2/object/grpc/types.pb.go b/object/grpc/types.pb.go similarity index 100% rename from v2/object/grpc/types.pb.go rename to object/grpc/types.pb.go diff --git a/v2/object/json.go b/object/json.go similarity index 97% rename from v2/object/json.go rename to object/json.go index b80253e..1555005 100644 --- a/v2/object/json.go +++ b/object/json.go @@ -1,8 +1,8 @@ package object import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (h *ShortHeader) MarshalJSON() ([]byte, error) { diff --git a/v2/object/marshal.go b/object/marshal.go similarity index 99% rename from v2/object/marshal.go rename to object/marshal.go index 9897489..44783f0 100644 --- a/v2/object/marshal.go +++ b/object/marshal.go @@ -1,10 +1,10 @@ package object import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - "github.com/nspcc-dev/neofs-api-go/util/proto" object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/object/message_test.go b/object/message_test.go similarity index 96% rename from v2/object/message_test.go rename to object/message_test.go index 1639f35..145c22c 100644 --- a/v2/object/message_test.go +++ b/object/message_test.go @@ -3,9 +3,9 @@ package object_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" objecttest "github.com/nspcc-dev/neofs-api-go/v2/object/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/object/string.go b/object/string.go similarity index 100% rename from v2/object/string.go rename to object/string.go diff --git a/v2/object/test/generate.go b/object/test/generate.go similarity index 100% rename from v2/object/test/generate.go rename to object/test/generate.go diff --git a/v2/object/types.go b/object/types.go similarity index 100% rename from v2/object/types.go rename to object/types.go diff --git a/pkg/.gitkeep b/pkg/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/pkg/accounting/decimal.go b/pkg/accounting/decimal.go deleted file mode 100644 index 07b11d6..0000000 --- a/pkg/accounting/decimal.go +++ /dev/null @@ -1,74 +0,0 @@ -package accounting - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/accounting" -) - -// Decimal represents v2-compatible decimal number. -type Decimal accounting.Decimal - -// NewDecimal creates, initializes and returns blank Decimal instance. -func NewDecimal() *Decimal { - return NewDecimalFromV2(new(accounting.Decimal)) -} - -// NewDecimalFromV2 converts v2 Decimal to Decimal. -func NewDecimalFromV2(d *accounting.Decimal) *Decimal { - return (*Decimal)(d) -} - -// Value returns value of the decimal number. -func (d *Decimal) Value() int64 { - return (*accounting.Decimal)(d). - GetValue() -} - -// SetValue sets value of the decimal number. -func (d *Decimal) SetValue(v int64) { - (*accounting.Decimal)(d). - SetValue(v) -} - -// Precision returns precision of the decimal number. -func (d *Decimal) Precision() uint32 { - return (*accounting.Decimal)(d). - GetPrecision() -} - -// SetPrecision sets precision of the decimal number. -func (d *Decimal) SetPrecision(p uint32) { - (*accounting.Decimal)(d). - SetPrecision(p) -} - -// Marshal marshals Decimal into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (d *Decimal) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*accounting.Decimal)(d). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Decimal. -func (d *Decimal) Unmarshal(data []byte) error { - return (*accounting.Decimal)(d). - Unmarshal(data) -} - -// MarshalJSON encodes Decimal to protobuf JSON format. -func (d *Decimal) MarshalJSON() ([]byte, error) { - return (*accounting.Decimal)(d). - MarshalJSON() -} - -// UnmarshalJSON decodes Decimal from protobuf JSON format. -func (d *Decimal) UnmarshalJSON(data []byte) error { - return (*accounting.Decimal)(d). - UnmarshalJSON(data) -} diff --git a/pkg/accounting/decimal_test.go b/pkg/accounting/decimal_test.go deleted file mode 100644 index 7591097..0000000 --- a/pkg/accounting/decimal_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package accounting_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/accounting" - accountingtest "github.com/nspcc-dev/neofs-api-go/pkg/accounting/test" - "github.com/stretchr/testify/require" -) - -func TestDecimal_Value(t *testing.T) { - d := accounting.NewDecimal() - - v := int64(3) - d.SetValue(v) - - require.Equal(t, v, d.Value()) -} - -func TestDecimal_Precision(t *testing.T) { - d := accounting.NewDecimal() - - p := uint32(3) - d.SetPrecision(p) - - require.Equal(t, p, d.Precision()) -} - -func TestDecimalEncoding(t *testing.T) { - d := accountingtest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := d.Marshal() - require.NoError(t, err) - - d2 := accounting.NewDecimal() - require.NoError(t, d2.Unmarshal(data)) - - require.Equal(t, d, d2) - }) - - t.Run("json", func(t *testing.T) { - data, err := d.MarshalJSON() - require.NoError(t, err) - - d2 := accounting.NewDecimal() - require.NoError(t, d2.UnmarshalJSON(data)) - - require.Equal(t, d, d2) - }) -} diff --git a/pkg/accounting/test/decimal.go b/pkg/accounting/test/decimal.go deleted file mode 100644 index 80014d8..0000000 --- a/pkg/accounting/test/decimal.go +++ /dev/null @@ -1,14 +0,0 @@ -package accountingtest - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/accounting" -) - -// Generate returns random accounting.Decimal. -func Generate() *accounting.Decimal { - d := accounting.NewDecimal() - d.SetValue(1) - d.SetPrecision(2) - - return d -} diff --git a/pkg/acl/eacl/enums.go b/pkg/acl/eacl/enums.go deleted file mode 100644 index 2e8fc1f..0000000 --- a/pkg/acl/eacl/enums.go +++ /dev/null @@ -1,396 +0,0 @@ -package eacl - -import ( - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" -) - -// Action taken if EACL record matched request. -// Action is compatible with v2 acl.Action enum. -type Action uint32 - -const ( - // ActionUnknown is an Action value used to mark action as undefined. - ActionUnknown Action = iota - - // ActionAllow is an Action value that allows access to the operation from context. - ActionAllow - - // ActionDeny is an Action value that denies access to the operation from context. - ActionDeny -) - -// Operation is a object service method to match request. -// Operation is compatible with v2 acl.Operation enum. -type Operation uint32 - -const ( - // OperationUnknown is an Operation value used to mark operation as undefined. - OperationUnknown Operation = iota - - // OperationGet is an object get Operation. - OperationGet - - // OperationHead is an Operation of getting the object header. - OperationHead - - // OperationPut is an object put Operation. - OperationPut - - // OperationDelete is an object delete Operation. - OperationDelete - - // OperationSearch is an object search Operation. - OperationSearch - - // OperationRange is an object payload range retrieval Operation. - OperationRange - - // OperationRangeHash is an object payload range hashing Operation. - OperationRangeHash -) - -// Role is a group of request senders to match request. -// Role is compatible with v2 acl.Role enum. -type Role uint32 - -const ( - // RoleUnknown is a Role value used to mark role as undefined. - RoleUnknown Role = iota - - // RoleUser is a group of senders that contains only key of container owner. - RoleUser - - // RoleSystem is a group of senders that contains keys of container nodes and - // inner ring nodes. - RoleSystem - - // RoleOthers is a group of senders that contains none of above keys. - RoleOthers -) - -// Match is binary operation on filer name and value to check if request is matched. -// Match is compatible with v2 acl.MatchType enum. -type Match uint32 - -const ( - // MatchUnknown is a Match value used to mark matcher as undefined. - MatchUnknown Match = iota - - // MatchStringEqual is a Match of string equality. - MatchStringEqual - - // MatchStringNotEqual is a Match of string inequality. - MatchStringNotEqual -) - -// FilterHeaderType indicates source of headers to make matches. -// FilterHeaderType is compatible with v2 acl.HeaderType enum. -type FilterHeaderType uint32 - -const ( - // HeaderTypeUnknown is a FilterHeaderType value used to mark header type as undefined. - HeaderTypeUnknown FilterHeaderType = iota - - // HeaderFromRequest is a FilterHeaderType for request X-Header. - HeaderFromRequest - - // HeaderFromObject is a FilterHeaderType for object header. - HeaderFromObject - - // HeaderFromService is a FilterHeaderType for service header. - HeaderFromService -) - -// ToV2 converts Action to v2 Action enum value. -func (a Action) ToV2() v2acl.Action { - switch a { - case ActionAllow: - return v2acl.ActionAllow - case ActionDeny: - return v2acl.ActionDeny - default: - return v2acl.ActionUnknown - } -} - -// ActionFromV2 converts v2 Action enum value to Action. -func ActionFromV2(action v2acl.Action) (a Action) { - switch action { - case v2acl.ActionAllow: - a = ActionAllow - case v2acl.ActionDeny: - a = ActionDeny - default: - a = ActionUnknown - } - - return a -} - -// String returns string representation of Action. -// -// String mapping: -// * ActionAllow: ALLOW; -// * ActionDeny: DENY; -// * ActionUnknown, default: ACTION_UNSPECIFIED. -func (a Action) String() string { - return a.ToV2().String() -} - -// FromString parses Action from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (a *Action) FromString(s string) bool { - var g v2acl.Action - - ok := g.FromString(s) - - if ok { - *a = ActionFromV2(g) - } - - return ok -} - -// ToV2 converts Operation to v2 Operation enum value. -func (o Operation) ToV2() v2acl.Operation { - switch o { - case OperationGet: - return v2acl.OperationGet - case OperationHead: - return v2acl.OperationHead - case OperationPut: - return v2acl.OperationPut - case OperationDelete: - return v2acl.OperationDelete - case OperationSearch: - return v2acl.OperationSearch - case OperationRange: - return v2acl.OperationRange - case OperationRangeHash: - return v2acl.OperationRangeHash - default: - return v2acl.OperationUnknown - } -} - -// OperationFromV2 converts v2 Operation enum value to Operation. -func OperationFromV2(operation v2acl.Operation) (o Operation) { - switch operation { - case v2acl.OperationGet: - o = OperationGet - case v2acl.OperationHead: - o = OperationHead - case v2acl.OperationPut: - o = OperationPut - case v2acl.OperationDelete: - o = OperationDelete - case v2acl.OperationSearch: - o = OperationSearch - case v2acl.OperationRange: - o = OperationRange - case v2acl.OperationRangeHash: - o = OperationRangeHash - default: - o = OperationUnknown - } - - return o -} - -// String returns string representation of Operation. -// -// String mapping: -// * OperationGet: GET; -// * OperationHead: HEAD; -// * OperationPut: PUT; -// * OperationDelete: DELETE; -// * OperationSearch: SEARCH; -// * OperationRange: GETRANGE; -// * OperationRangeHash: GETRANGEHASH; -// * OperationUnknown, default: OPERATION_UNSPECIFIED. -func (o Operation) String() string { - return o.ToV2().String() -} - -// FromString parses Operation from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (o *Operation) FromString(s string) bool { - var g v2acl.Operation - - ok := g.FromString(s) - - if ok { - *o = OperationFromV2(g) - } - - return ok -} - -// ToV2 converts Role to v2 Role enum value. -func (r Role) ToV2() v2acl.Role { - switch r { - case RoleUser: - return v2acl.RoleUser - case RoleSystem: - return v2acl.RoleSystem - case RoleOthers: - return v2acl.RoleOthers - default: - return v2acl.RoleUnknown - } -} - -// RoleFromV2 converts v2 Role enum value to Role. -func RoleFromV2(role v2acl.Role) (r Role) { - switch role { - case v2acl.RoleUser: - r = RoleUser - case v2acl.RoleSystem: - r = RoleSystem - case v2acl.RoleOthers: - r = RoleOthers - default: - r = RoleUnknown - } - - return r -} - -// String returns string representation of Role. -// -// String mapping: -// * RoleUser: USER; -// * RoleSystem: SYSTEM; -// * RoleOthers: OTHERS; -// * RoleUnknown, default: ROLE_UNKNOWN. -func (r Role) String() string { - return r.ToV2().String() -} - -// FromString parses Role from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (r *Role) FromString(s string) bool { - var g v2acl.Role - - ok := g.FromString(s) - - if ok { - *r = RoleFromV2(g) - } - - return ok -} - -// ToV2 converts Match to v2 MatchType enum value. -func (m Match) ToV2() v2acl.MatchType { - switch m { - case MatchStringEqual: - return v2acl.MatchTypeStringEqual - case MatchStringNotEqual: - return v2acl.MatchTypeStringNotEqual - default: - return v2acl.MatchTypeUnknown - } -} - -// MatchFromV2 converts v2 MatchType enum value to Match. -func MatchFromV2(match v2acl.MatchType) (m Match) { - switch match { - case v2acl.MatchTypeStringEqual: - m = MatchStringEqual - case v2acl.MatchTypeStringNotEqual: - m = MatchStringNotEqual - default: - m = MatchUnknown - } - - return m -} - -// String returns string representation of Match. -// -// String mapping: -// * MatchStringEqual: STRING_EQUAL; -// * MatchStringNotEqual: STRING_NOT_EQUAL; -// * MatchUnknown, default: MATCH_TYPE_UNSPECIFIED. -func (m Match) String() string { - return m.ToV2().String() -} - -// FromString parses Match from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (m *Match) FromString(s string) bool { - var g v2acl.MatchType - - ok := g.FromString(s) - - if ok { - *m = MatchFromV2(g) - } - - return ok -} - -// ToV2 converts FilterHeaderType to v2 HeaderType enum value. -func (h FilterHeaderType) ToV2() v2acl.HeaderType { - switch h { - case HeaderFromRequest: - return v2acl.HeaderTypeRequest - case HeaderFromObject: - return v2acl.HeaderTypeObject - case HeaderFromService: - return v2acl.HeaderTypeService - default: - return v2acl.HeaderTypeUnknown - } -} - -// FilterHeaderTypeFromV2 converts v2 HeaderType enum value to FilterHeaderType. -func FilterHeaderTypeFromV2(header v2acl.HeaderType) (h FilterHeaderType) { - switch header { - case v2acl.HeaderTypeRequest: - h = HeaderFromRequest - case v2acl.HeaderTypeObject: - h = HeaderFromObject - case v2acl.HeaderTypeService: - h = HeaderFromService - default: - h = HeaderTypeUnknown - } - - return h -} - -// String returns string representation of FilterHeaderType. -// -// String mapping: -// * HeaderFromRequest: REQUEST; -// * HeaderFromObject: OBJECT; -// * HeaderTypeUnknown, default: HEADER_UNSPECIFIED. -func (h FilterHeaderType) String() string { - return h.ToV2().String() -} - -// FromString parses FilterHeaderType from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (h *FilterHeaderType) FromString(s string) bool { - var g v2acl.HeaderType - - ok := g.FromString(s) - - if ok { - *h = FilterHeaderTypeFromV2(g) - } - - return ok -} diff --git a/pkg/acl/eacl/enums_test.go b/pkg/acl/eacl/enums_test.go deleted file mode 100644 index d077a89..0000000 --- a/pkg/acl/eacl/enums_test.go +++ /dev/null @@ -1,214 +0,0 @@ -package eacl_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" - "github.com/stretchr/testify/require" -) - -var ( - eqV2Actions = map[eacl.Action]v2acl.Action{ - eacl.ActionUnknown: v2acl.ActionUnknown, - eacl.ActionAllow: v2acl.ActionAllow, - eacl.ActionDeny: v2acl.ActionDeny, - } - - eqV2Operations = map[eacl.Operation]v2acl.Operation{ - eacl.OperationUnknown: v2acl.OperationUnknown, - eacl.OperationGet: v2acl.OperationGet, - eacl.OperationHead: v2acl.OperationHead, - eacl.OperationPut: v2acl.OperationPut, - eacl.OperationDelete: v2acl.OperationDelete, - eacl.OperationSearch: v2acl.OperationSearch, - eacl.OperationRange: v2acl.OperationRange, - eacl.OperationRangeHash: v2acl.OperationRangeHash, - } - - eqV2Roles = map[eacl.Role]v2acl.Role{ - eacl.RoleUnknown: v2acl.RoleUnknown, - eacl.RoleUser: v2acl.RoleUser, - eacl.RoleSystem: v2acl.RoleSystem, - eacl.RoleOthers: v2acl.RoleOthers, - } - - eqV2Matches = map[eacl.Match]v2acl.MatchType{ - eacl.MatchUnknown: v2acl.MatchTypeUnknown, - eacl.MatchStringEqual: v2acl.MatchTypeStringEqual, - eacl.MatchStringNotEqual: v2acl.MatchTypeStringNotEqual, - } - - eqV2HeaderTypes = map[eacl.FilterHeaderType]v2acl.HeaderType{ - eacl.HeaderTypeUnknown: v2acl.HeaderTypeUnknown, - eacl.HeaderFromRequest: v2acl.HeaderTypeRequest, - eacl.HeaderFromObject: v2acl.HeaderTypeObject, - eacl.HeaderFromService: v2acl.HeaderTypeService, - } -) - -func TestAction(t *testing.T) { - t.Run("known actions", func(t *testing.T) { - for i := eacl.ActionUnknown; i <= eacl.ActionDeny; i++ { - require.Equal(t, eqV2Actions[i], i.ToV2()) - require.Equal(t, eacl.ActionFromV2(i.ToV2()), i) - } - }) - - t.Run("unknown actions", func(t *testing.T) { - require.Equal(t, (eacl.ActionDeny + 1).ToV2(), v2acl.ActionUnknown) - require.Equal(t, eacl.ActionFromV2(v2acl.ActionDeny+1), eacl.ActionUnknown) - }) -} - -func TestOperation(t *testing.T) { - t.Run("known operations", func(t *testing.T) { - for i := eacl.OperationUnknown; i <= eacl.OperationRangeHash; i++ { - require.Equal(t, eqV2Operations[i], i.ToV2()) - require.Equal(t, eacl.OperationFromV2(i.ToV2()), i) - } - }) - - t.Run("unknown operations", func(t *testing.T) { - require.Equal(t, (eacl.OperationRangeHash + 1).ToV2(), v2acl.OperationUnknown) - require.Equal(t, eacl.OperationFromV2(v2acl.OperationRangeHash+1), eacl.OperationUnknown) - }) -} - -func TestRole(t *testing.T) { - t.Run("known roles", func(t *testing.T) { - for i := eacl.RoleUnknown; i <= eacl.RoleOthers; i++ { - require.Equal(t, eqV2Roles[i], i.ToV2()) - require.Equal(t, eacl.RoleFromV2(i.ToV2()), i) - } - }) - - t.Run("unknown roles", func(t *testing.T) { - require.Equal(t, (eacl.RoleOthers + 1).ToV2(), v2acl.RoleUnknown) - require.Equal(t, eacl.RoleFromV2(v2acl.RoleOthers+1), eacl.RoleUnknown) - }) -} - -func TestMatch(t *testing.T) { - t.Run("known matches", func(t *testing.T) { - for i := eacl.MatchUnknown; i <= eacl.MatchStringNotEqual; i++ { - require.Equal(t, eqV2Matches[i], i.ToV2()) - require.Equal(t, eacl.MatchFromV2(i.ToV2()), i) - } - }) - - t.Run("unknown matches", func(t *testing.T) { - require.Equal(t, (eacl.MatchStringNotEqual + 1).ToV2(), v2acl.MatchTypeUnknown) - require.Equal(t, eacl.MatchFromV2(v2acl.MatchTypeStringNotEqual+1), eacl.MatchUnknown) - }) -} - -func TestFilterHeaderType(t *testing.T) { - t.Run("known header types", func(t *testing.T) { - for i := eacl.HeaderTypeUnknown; i <= eacl.HeaderFromService; i++ { - require.Equal(t, eqV2HeaderTypes[i], i.ToV2()) - require.Equal(t, eacl.FilterHeaderTypeFromV2(i.ToV2()), i) - } - }) - - t.Run("unknown header types", func(t *testing.T) { - require.Equal(t, (eacl.HeaderFromService + 1).ToV2(), v2acl.HeaderTypeUnknown) - require.Equal(t, eacl.FilterHeaderTypeFromV2(v2acl.HeaderTypeService+1), eacl.HeaderTypeUnknown) - }) -} - -type enumIface interface { - FromString(string) bool - String() string -} - -type enumStringItem struct { - val enumIface - str string -} - -func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { - for _, item := range items { - require.Equal(t, item.str, item.val.String()) - - s := item.val.String() - - require.True(t, e.FromString(s), s) - - require.EqualValues(t, item.val, e, item.val) - } - - // incorrect strings - for _, str := range []string{ - "some string", - "UNSPECIFIED", - } { - require.False(t, e.FromString(str)) - } -} - -func TestAction_String(t *testing.T) { - toPtr := func(v eacl.Action) *eacl.Action { - return &v - } - - testEnumStrings(t, new(eacl.Action), []enumStringItem{ - {val: toPtr(eacl.ActionAllow), str: "ALLOW"}, - {val: toPtr(eacl.ActionDeny), str: "DENY"}, - {val: toPtr(eacl.ActionUnknown), str: "ACTION_UNSPECIFIED"}, - }) -} - -func TestRole_String(t *testing.T) { - toPtr := func(v eacl.Role) *eacl.Role { - return &v - } - - testEnumStrings(t, new(eacl.Role), []enumStringItem{ - {val: toPtr(eacl.RoleUser), str: "USER"}, - {val: toPtr(eacl.RoleSystem), str: "SYSTEM"}, - {val: toPtr(eacl.RoleOthers), str: "OTHERS"}, - {val: toPtr(eacl.RoleUnknown), str: "ROLE_UNSPECIFIED"}, - }) -} - -func TestOperation_String(t *testing.T) { - toPtr := func(v eacl.Operation) *eacl.Operation { - return &v - } - - testEnumStrings(t, new(eacl.Operation), []enumStringItem{ - {val: toPtr(eacl.OperationGet), str: "GET"}, - {val: toPtr(eacl.OperationPut), str: "PUT"}, - {val: toPtr(eacl.OperationHead), str: "HEAD"}, - {val: toPtr(eacl.OperationDelete), str: "DELETE"}, - {val: toPtr(eacl.OperationSearch), str: "SEARCH"}, - {val: toPtr(eacl.OperationRange), str: "GETRANGE"}, - {val: toPtr(eacl.OperationRangeHash), str: "GETRANGEHASH"}, - {val: toPtr(eacl.OperationUnknown), str: "OPERATION_UNSPECIFIED"}, - }) -} - -func TestMatch_String(t *testing.T) { - toPtr := func(v eacl.Match) *eacl.Match { - return &v - } - - testEnumStrings(t, new(eacl.Match), []enumStringItem{ - {val: toPtr(eacl.MatchStringEqual), str: "STRING_EQUAL"}, - {val: toPtr(eacl.MatchStringNotEqual), str: "STRING_NOT_EQUAL"}, - {val: toPtr(eacl.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"}, - }) -} - -func TestFilterHeaderType_String(t *testing.T) { - toPtr := func(v eacl.FilterHeaderType) *eacl.FilterHeaderType { - return &v - } - - testEnumStrings(t, new(eacl.FilterHeaderType), []enumStringItem{ - {val: toPtr(eacl.HeaderFromRequest), str: "REQUEST"}, - {val: toPtr(eacl.HeaderFromObject), str: "OBJECT"}, - {val: toPtr(eacl.HeaderTypeUnknown), str: "HEADER_UNSPECIFIED"}, - }) -} diff --git a/pkg/acl/eacl/filter.go b/pkg/acl/eacl/filter.go deleted file mode 100644 index 23e7677..0000000 --- a/pkg/acl/eacl/filter.go +++ /dev/null @@ -1,186 +0,0 @@ -package eacl - -import ( - "fmt" - "strconv" - - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" -) - -// Filter defines check conditions if request header is matched or not. Matched -// header means that request should be processed according to EACL action. -// -// Filter is compatible with v2 acl.EACLRecord.Filter message. -type Filter struct { - from FilterHeaderType - matcher Match - key filterKey - value fmt.Stringer -} - -type staticStringer string - -type u64Stringer uint64 - -type filterKey struct { - typ filterKeyType - - str string -} - -// enumeration of reserved filter keys. -type filterKeyType int - -const ( - _ filterKeyType = iota - fKeyObjVersion - fKeyObjID - fKeyObjContainerID - fKeyObjOwnerID - fKeyObjCreationEpoch - fKeyObjPayloadLength - fKeyObjPayloadHash - fKeyObjType - fKeyObjHomomorphicHash -) - -func (s staticStringer) String() string { - return string(s) -} - -func (u u64Stringer) String() string { - return strconv.FormatUint(uint64(u), 10) -} - -// Value returns filtered string value. -func (f Filter) Value() string { - return f.value.String() -} - -// Matcher returns filter Match type. -func (f Filter) Matcher() Match { - return f.matcher -} - -// Key returns key to the filtered header. -func (f Filter) Key() string { - return f.key.String() -} - -// From returns FilterHeaderType that defined which header will be filtered. -func (f Filter) From() FilterHeaderType { - return f.from -} - -// ToV2 converts Filter to v2 acl.EACLRecord.Filter message. -// -// Nil Filter converts to nil. -func (f *Filter) ToV2() *v2acl.HeaderFilter { - if f == nil { - return nil - } - - filter := new(v2acl.HeaderFilter) - filter.SetValue(f.value.String()) - filter.SetKey(f.key.String()) - filter.SetMatchType(f.matcher.ToV2()) - filter.SetHeaderType(f.from.ToV2()) - - return filter -} - -func (k filterKey) String() string { - switch k.typ { - default: - return k.str - case fKeyObjVersion: - return v2acl.FilterObjectVersion - case fKeyObjID: - return v2acl.FilterObjectID - case fKeyObjContainerID: - return v2acl.FilterObjectContainerID - case fKeyObjOwnerID: - return v2acl.FilterObjectOwnerID - case fKeyObjCreationEpoch: - return v2acl.FilterObjectCreationEpoch - case fKeyObjPayloadLength: - return v2acl.FilterObjectPayloadLength - case fKeyObjPayloadHash: - return v2acl.FilterObjectPayloadHash - case fKeyObjType: - return v2acl.FilterObjectType - case fKeyObjHomomorphicHash: - return v2acl.FilterObjectHomomorphicHash - } -} - -// NewFilter creates, initializes and returns blank Filter instance. -// -// Defaults: -// - header type: HeaderTypeUnknown; -// - matcher: MatchUnknown; -// - key: ""; -// - value: "". -func NewFilter() *Filter { - return NewFilterFromV2(new(v2acl.HeaderFilter)) -} - -// NewFilterFromV2 converts v2 acl.EACLRecord.Filter message to Filter. -func NewFilterFromV2(filter *v2acl.HeaderFilter) *Filter { - f := new(Filter) - - if filter == nil { - return f - } - - f.from = FilterHeaderTypeFromV2(filter.GetHeaderType()) - f.matcher = MatchFromV2(filter.GetMatchType()) - f.key.str = filter.GetKey() - f.value = staticStringer(filter.GetValue()) - - return f -} - -// 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 f.ToV2(). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Filter. -func (f *Filter) Unmarshal(data []byte) error { - fV2 := new(v2acl.HeaderFilter) - if err := fV2.Unmarshal(data); err != nil { - return err - } - - *f = *NewFilterFromV2(fV2) - - return nil -} - -// MarshalJSON encodes Filter to protobuf JSON format. -func (f *Filter) MarshalJSON() ([]byte, error) { - return f.ToV2(). - MarshalJSON() -} - -// UnmarshalJSON decodes Filter from protobuf JSON format. -func (f *Filter) UnmarshalJSON(data []byte) error { - fV2 := new(v2acl.HeaderFilter) - if err := fV2.UnmarshalJSON(data); err != nil { - return err - } - - *f = *NewFilterFromV2(fV2) - - return nil -} diff --git a/pkg/acl/eacl/filter_test.go b/pkg/acl/eacl/filter_test.go deleted file mode 100644 index 9a471d0..0000000 --- a/pkg/acl/eacl/filter_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package eacl - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/acl" - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" - "github.com/stretchr/testify/require" -) - -func newObjectFilter(match Match, key, val string) *Filter { - return &Filter{ - from: HeaderFromObject, - key: filterKey{ - str: key, - }, - matcher: match, - value: staticStringer(val), - } -} - -func TestFilter(t *testing.T) { - filter := newObjectFilter(MatchStringEqual, "some name", "200") - - v2 := filter.ToV2() - require.NotNil(t, v2) - require.Equal(t, v2acl.HeaderTypeObject, v2.GetHeaderType()) - require.EqualValues(t, v2acl.MatchTypeStringEqual, v2.GetMatchType()) - require.Equal(t, filter.Key(), v2.GetKey()) - require.Equal(t, filter.Value(), v2.GetValue()) - - newFilter := NewFilterFromV2(v2) - require.Equal(t, filter, newFilter) - - t.Run("from nil v2 filter", func(t *testing.T) { - require.Equal(t, new(Filter), NewFilterFromV2(nil)) - }) -} - -func TestFilterEncoding(t *testing.T) { - f := newObjectFilter(MatchStringEqual, "key", "value") - - 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) - - d2 := NewFilter() - require.NoError(t, d2.UnmarshalJSON(data)) - - require.Equal(t, f, d2) - }) -} - -func TestFilter_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Filter - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - filter := NewFilter() - - // check initial values - require.Empty(t, filter.Key()) - require.Empty(t, filter.Value()) - require.Equal(t, HeaderTypeUnknown, filter.From()) - require.Equal(t, MatchUnknown, filter.Matcher()) - - // convert to v2 message - filterV2 := filter.ToV2() - - require.Empty(t, filterV2.GetKey()) - require.Empty(t, filterV2.GetValue()) - require.Equal(t, acl.HeaderTypeUnknown, filterV2.GetHeaderType()) - require.Equal(t, acl.MatchTypeUnknown, filterV2.GetMatchType()) - }) -} diff --git a/pkg/acl/eacl/record.go b/pkg/acl/eacl/record.go deleted file mode 100644 index b12d52a..0000000 --- a/pkg/acl/eacl/record.go +++ /dev/null @@ -1,284 +0,0 @@ -package eacl - -import ( - "crypto/ecdsa" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" -) - -// Record of the EACL rule, that defines EACL action, targets for this action, -// object service operation and filters for request headers. -// -// Record is compatible with v2 acl.EACLRecord message. -type Record struct { - action Action - operation Operation - filters []*Filter - targets []*Target -} - -// Targets returns list of target subjects to apply ACL rule to. -func (r Record) Targets() []*Target { - return r.targets -} - -// SetTargets sets list of target subjects to apply ACL rule to. -func (r *Record) SetTargets(targets ...*Target) { - r.targets = targets -} - -// Filters returns list of filters to match and see if rule is applicable. -func (r Record) Filters() []*Filter { - return r.filters -} - -// Operation returns NeoFS request verb to match. -func (r Record) Operation() Operation { - return r.operation -} - -// SetOperation sets NeoFS request verb to match. -func (r *Record) SetOperation(operation Operation) { - r.operation = operation -} - -// Action returns rule execution result. -func (r Record) Action() Action { - return r.action -} - -// SetAction sets rule execution result. -func (r *Record) SetAction(action Action) { - r.action = action -} - -// AddTarget adds target subject with specified Role and key list. -// -// Deprecated: use AddFormedTarget instead. -func (r *Record) AddTarget(role Role, keys ...ecdsa.PublicKey) { - AddFormedTarget(r, role, keys...) -} - -// AddRecordTarget adds single Target to the Record. -func AddRecordTarget(r *Record, t *Target) { - r.SetTargets(append(r.Targets(), t)...) -} - -// AddFormedTarget forms Target with specified Role and list of -// ECDSA public keys and adds it to the Record. -func AddFormedTarget(r *Record, role Role, keys ...ecdsa.PublicKey) { - t := NewTarget() - t.SetRole(role) - SetTargetECDSAKeys(t, ecdsaKeysToPtrs(keys)...) - - AddRecordTarget(r, t) -} - -func (r *Record) addFilter(from FilterHeaderType, m Match, keyTyp filterKeyType, key string, val fmt.Stringer) { - filter := &Filter{ - from: from, - key: filterKey{ - typ: keyTyp, - str: key, - }, - matcher: m, - value: val, - } - - r.filters = append(r.filters, filter) -} - -func (r *Record) addObjectFilter(m Match, keyTyp filterKeyType, key string, val fmt.Stringer) { - r.addFilter(HeaderFromObject, m, keyTyp, key, val) -} - -func (r *Record) addObjectReservedFilter(m Match, typ filterKeyType, val fmt.Stringer) { - r.addObjectFilter(m, typ, "", val) -} - -// AddFilter adds generic filter. -func (r *Record) AddFilter(from FilterHeaderType, matcher Match, name, value string) { - r.addFilter(from, matcher, 0, name, staticStringer(value)) -} - -// AddObjectAttributeFilter adds filter by object attribute. -func (r *Record) AddObjectAttributeFilter(m Match, key, value string) { - r.addObjectFilter(m, 0, key, staticStringer(value)) -} - -// AddObjectVersionFilter adds filter by object version. -func (r *Record) AddObjectVersionFilter(m Match, v *pkg.Version) { - r.addObjectReservedFilter(m, fKeyObjVersion, v) -} - -// AddObjectIDFilter adds filter by object ID. -func (r *Record) AddObjectIDFilter(m Match, id *object.ID) { - r.addObjectReservedFilter(m, fKeyObjID, id) -} - -// AddObjectContainerIDFilter adds filter by object container ID. -func (r *Record) AddObjectContainerIDFilter(m Match, id *cid.ID) { - r.addObjectReservedFilter(m, fKeyObjContainerID, id) -} - -// AddObjectOwnerIDFilter adds filter by object owner ID. -func (r *Record) AddObjectOwnerIDFilter(m Match, id *owner.ID) { - r.addObjectReservedFilter(m, fKeyObjOwnerID, id) -} - -// AddObjectCreationEpoch adds filter by object creation epoch. -func (r *Record) AddObjectCreationEpoch(m Match, epoch uint64) { - r.addObjectReservedFilter(m, fKeyObjCreationEpoch, u64Stringer(epoch)) -} - -// AddObjectPayloadLengthFilter adds filter by object payload length. -func (r *Record) AddObjectPayloadLengthFilter(m Match, size uint64) { - r.addObjectReservedFilter(m, fKeyObjPayloadLength, u64Stringer(size)) -} - -// AddObjectPayloadHashFilter adds filter by object payload hash value. -func (r *Record) AddObjectPayloadHashFilter(m Match, h *pkg.Checksum) { - r.addObjectReservedFilter(m, fKeyObjPayloadHash, h) -} - -// AddObjectTypeFilter adds filter by object type. -func (r *Record) AddObjectTypeFilter(m Match, t object.Type) { - r.addObjectReservedFilter(m, fKeyObjType, t) -} - -// AddObjectHomomorphicHashFilter adds filter by object payload homomorphic hash value. -func (r *Record) AddObjectHomomorphicHashFilter(m Match, h *pkg.Checksum) { - r.addObjectReservedFilter(m, fKeyObjHomomorphicHash, h) -} - -// ToV2 converts Record to v2 acl.EACLRecord message. -// -// Nil Record converts to nil. -func (r *Record) ToV2() *v2acl.Record { - if r == nil { - return nil - } - - v2 := new(v2acl.Record) - - if r.targets != nil { - targets := make([]*v2acl.Target, 0, len(r.targets)) - for _, target := range r.targets { - targets = append(targets, target.ToV2()) - } - - v2.SetTargets(targets) - } - - if r.filters != nil { - filters := make([]*v2acl.HeaderFilter, 0, len(r.filters)) - for _, filter := range r.filters { - filters = append(filters, filter.ToV2()) - } - - v2.SetFilters(filters) - } - - v2.SetAction(r.action.ToV2()) - v2.SetOperation(r.operation.ToV2()) - - return v2 -} - -// NewRecord creates and returns blank Record instance. -// -// Defaults: -// - action: ActionUnknown; -// - operation: OperationUnknown; -// - targets: nil, -// - filters: nil. -func NewRecord() *Record { - return new(Record) -} - -// CreateRecord creates, initializes with parameters and returns Record instance. -func CreateRecord(action Action, operation Operation) *Record { - r := NewRecord() - r.action = action - r.operation = operation - r.targets = []*Target{} - r.filters = []*Filter{} - - return r -} - -// NewRecordFromV2 converts v2 acl.EACLRecord message to Record. -func NewRecordFromV2(record *v2acl.Record) *Record { - r := NewRecord() - - if record == nil { - return r - } - - r.action = ActionFromV2(record.GetAction()) - r.operation = OperationFromV2(record.GetOperation()) - - v2targets := record.GetTargets() - v2filters := record.GetFilters() - - r.targets = make([]*Target, 0, len(v2targets)) - for i := range v2targets { - r.targets = append(r.targets, NewTargetFromV2(v2targets[i])) - } - - r.filters = make([]*Filter, 0, len(v2filters)) - for i := range v2filters { - r.filters = append(r.filters, NewFilterFromV2(v2filters[i])) - } - - return r -} - -// Marshal marshals Record into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (r *Record) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return r.ToV2(). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Record. -func (r *Record) Unmarshal(data []byte) error { - fV2 := new(v2acl.Record) - if err := fV2.Unmarshal(data); err != nil { - return err - } - - *r = *NewRecordFromV2(fV2) - - return nil -} - -// MarshalJSON encodes Record to protobuf JSON format. -func (r *Record) MarshalJSON() ([]byte, error) { - return r.ToV2(). - MarshalJSON() -} - -// UnmarshalJSON decodes Record from protobuf JSON format. -func (r *Record) UnmarshalJSON(data []byte) error { - tV2 := new(v2acl.Record) - if err := tV2.UnmarshalJSON(data); err != nil { - return err - } - - *r = *NewRecordFromV2(tV2) - - return nil -} diff --git a/pkg/acl/eacl/record_test.go b/pkg/acl/eacl/record_test.go deleted file mode 100644 index 1baaf4a..0000000 --- a/pkg/acl/eacl/record_test.go +++ /dev/null @@ -1,250 +0,0 @@ -package eacl - -import ( - "crypto/ecdsa" - "fmt" - "testing" - - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -func TestRecord(t *testing.T) { - record := NewRecord() - record.SetOperation(OperationRange) - record.SetAction(ActionAllow) - record.AddFilter(HeaderFromRequest, MatchStringEqual, "A", "B") - record.AddFilter(HeaderFromRequest, MatchStringNotEqual, "C", "D") - - target := NewTarget() - target.SetRole(RoleSystem) - AddRecordTarget(record, target) - - v2 := record.ToV2() - require.NotNil(t, v2) - require.Equal(t, v2acl.OperationRange, v2.GetOperation()) - require.Equal(t, v2acl.ActionAllow, v2.GetAction()) - require.Len(t, v2.GetFilters(), len(record.Filters())) - require.Len(t, v2.GetTargets(), len(record.Targets())) - - newRecord := NewRecordFromV2(v2) - require.Equal(t, record, newRecord) - - t.Run("create record", func(t *testing.T) { - record := CreateRecord(ActionAllow, OperationGet) - require.Equal(t, ActionAllow, record.Action()) - require.Equal(t, OperationGet, record.Operation()) - }) - - t.Run("new from nil v2 record", func(t *testing.T) { - require.Equal(t, new(Record), NewRecordFromV2(nil)) - }) -} - -func TestAddFormedTarget(t *testing.T) { - items := []struct { - role Role - keys []ecdsa.PublicKey - }{ - { - role: RoleUnknown, - keys: []ecdsa.PublicKey{test.DecodeKey(1).PublicKey}, - }, - { - role: RoleSystem, - keys: []ecdsa.PublicKey{}, - }, - } - - targets := make([]*Target, 0, len(items)) - - r := NewRecord() - - for _, item := range items { - tgt := NewTarget() - tgt.SetRole(item.role) - SetTargetECDSAKeys(tgt, ecdsaKeysToPtrs(item.keys)...) - - targets = append(targets, tgt) - - AddFormedTarget(r, item.role, item.keys...) - } - - tgts := r.Targets() - require.Len(t, tgts, len(targets)) - - for _, tgt := range targets { - require.Contains(t, tgts, tgt) - } -} - -func TestRecord_AddFilter(t *testing.T) { - filters := []*Filter{ - newObjectFilter(MatchStringEqual, "some name", "ContainerID"), - newObjectFilter(MatchStringNotEqual, "X-Header-Name", "X-Header-Value"), - } - - r := NewRecord() - for _, filter := range filters { - r.AddFilter(filter.From(), filter.Matcher(), filter.Key(), filter.Value()) - } - - require.Equal(t, filters, r.Filters()) -} - -func TestRecordEncoding(t *testing.T) { - r := NewRecord() - r.SetOperation(OperationHead) - r.SetAction(ActionDeny) - r.AddObjectAttributeFilter(MatchStringEqual, "key", "value") - AddFormedTarget(r, RoleSystem, test.DecodeKey(-1).PublicKey) - - t.Run("binary", func(t *testing.T) { - data, err := r.Marshal() - require.NoError(t, err) - - r2 := NewRecord() - 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 := NewRecord() - require.NoError(t, r2.UnmarshalJSON(data)) - - require.Equal(t, r, r2) - }) -} - -func TestRecord_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Record - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - record := NewRecord() - - // check initial values - require.Equal(t, OperationUnknown, record.Operation()) - require.Equal(t, ActionUnknown, record.Action()) - require.Nil(t, record.Targets()) - require.Nil(t, record.Filters()) - - // convert to v2 message - recordV2 := record.ToV2() - - require.Equal(t, v2acl.OperationUnknown, recordV2.GetOperation()) - require.Equal(t, v2acl.ActionUnknown, recordV2.GetAction()) - require.Nil(t, recordV2.GetTargets()) - require.Nil(t, recordV2.GetFilters()) - }) -} - -func TestReservedRecords(t *testing.T) { - var ( - v = refstest.Version() - oid = objecttest.ID() - cid = cidtest.Generate() - ownerid = ownertest.Generate() - h = refstest.Checksum() - typ = new(object.Type) - ) - - testSuit := []struct { - f func(r *Record) - key string - value string - }{ - { - f: func(r *Record) { r.AddObjectAttributeFilter(MatchStringEqual, "foo", "bar") }, - key: "foo", - value: "bar", - }, - { - f: func(r *Record) { r.AddObjectVersionFilter(MatchStringEqual, v) }, - key: v2acl.FilterObjectVersion, - value: v.String(), - }, - { - f: func(r *Record) { r.AddObjectIDFilter(MatchStringEqual, oid) }, - key: v2acl.FilterObjectID, - value: oid.String(), - }, - { - f: func(r *Record) { r.AddObjectContainerIDFilter(MatchStringEqual, cid) }, - key: v2acl.FilterObjectContainerID, - value: cid.String(), - }, - { - f: func(r *Record) { r.AddObjectOwnerIDFilter(MatchStringEqual, ownerid) }, - key: v2acl.FilterObjectOwnerID, - value: ownerid.String(), - }, - { - f: func(r *Record) { r.AddObjectCreationEpoch(MatchStringEqual, 100) }, - key: v2acl.FilterObjectCreationEpoch, - value: "100", - }, - { - f: func(r *Record) { r.AddObjectPayloadLengthFilter(MatchStringEqual, 5000) }, - key: v2acl.FilterObjectPayloadLength, - value: "5000", - }, - { - f: func(r *Record) { r.AddObjectPayloadHashFilter(MatchStringEqual, h) }, - key: v2acl.FilterObjectPayloadHash, - value: h.String(), - }, - { - f: func(r *Record) { r.AddObjectHomomorphicHashFilter(MatchStringEqual, h) }, - key: v2acl.FilterObjectHomomorphicHash, - value: h.String(), - }, - { - f: func(r *Record) { - require.True(t, typ.FromString("REGULAR")) - r.AddObjectTypeFilter(MatchStringEqual, *typ) - }, - key: v2acl.FilterObjectType, - value: "REGULAR", - }, - { - f: func(r *Record) { - require.True(t, typ.FromString("TOMBSTONE")) - r.AddObjectTypeFilter(MatchStringEqual, *typ) - }, - key: v2acl.FilterObjectType, - value: "TOMBSTONE", - }, - { - f: func(r *Record) { - require.True(t, typ.FromString("STORAGE_GROUP")) - r.AddObjectTypeFilter(MatchStringEqual, *typ) - }, - key: v2acl.FilterObjectType, - value: "STORAGE_GROUP", - }, - } - - for n, testCase := range testSuit { - desc := fmt.Sprintf("case #%d", n) - record := NewRecord() - testCase.f(record) - require.Len(t, record.Filters(), 1, desc) - f := record.Filters()[0] - require.Equal(t, f.Key(), testCase.key, desc) - require.Equal(t, f.Value(), testCase.value, desc) - } -} diff --git a/pkg/acl/eacl/table.go b/pkg/acl/eacl/table.go deleted file mode 100644 index 81bee1a..0000000 --- a/pkg/acl/eacl/table.go +++ /dev/null @@ -1,210 +0,0 @@ -package eacl - -import ( - "crypto/sha256" - - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" -) - -// Table is a group of EACL records for single container. -// -// Table is compatible with v2 acl.EACLTable message. -type Table struct { - version pkg.Version - cid *cid.ID - token *session.Token - sig *pkg.Signature - records []*Record -} - -// CID returns identifier of the container that should use given access control rules. -func (t Table) CID() *cid.ID { - return t.cid -} - -// SetCID sets identifier of the container that should use given access control rules. -func (t *Table) SetCID(cid *cid.ID) { - t.cid = cid -} - -// Version returns version of eACL format. -func (t Table) Version() pkg.Version { - return t.version -} - -// SetVersion sets version of eACL format. -func (t *Table) SetVersion(version pkg.Version) { - t.version = version -} - -// Records returns list of extended ACL rules. -func (t Table) Records() []*Record { - return t.records -} - -// AddRecord adds single eACL rule. -func (t *Table) AddRecord(r *Record) { - if r != nil { - t.records = append(t.records, r) - } -} - -// SessionToken returns token of the session -// within which Table was set. -func (t Table) SessionToken() *session.Token { - return t.token -} - -// SetSessionToken sets token of the session -// within which Table was set. -func (t *Table) SetSessionToken(tok *session.Token) { - t.token = tok -} - -// Signature returns Table signature. -func (t Table) Signature() *pkg.Signature { - return t.sig -} - -// SetSignature sets Table signature. -func (t *Table) SetSignature(sig *pkg.Signature) { - t.sig = sig -} - -// ToV2 converts Table to v2 acl.EACLTable message. -// -// Nil Table converts to nil. -func (t *Table) ToV2() *v2acl.Table { - if t == nil { - return nil - } - - v2 := new(v2acl.Table) - - if t.cid != nil { - v2.SetContainerID(t.cid.ToV2()) - } - - if t.records != nil { - records := make([]*v2acl.Record, 0, len(t.records)) - for _, record := range t.records { - records = append(records, record.ToV2()) - } - - v2.SetRecords(records) - } - - v2.SetVersion(t.version.ToV2()) - - return v2 -} - -// NewTable creates, initializes and returns blank Table instance. -// -// Defaults: -// - version: pkg.SDKVersion(); -// - container ID: nil; -// - records: nil; -// - session token: nil; -// - signature: nil. -func NewTable() *Table { - t := new(Table) - t.SetVersion(*pkg.SDKVersion()) - - return t -} - -// CreateTable creates, initializes with parameters and returns Table instance. -func CreateTable(cid cid.ID) *Table { - t := NewTable() - t.SetCID(&cid) - - return t -} - -// NewTableFromV2 converts v2 acl.EACLTable message to Table. -func NewTableFromV2(table *v2acl.Table) *Table { - t := new(Table) - - if table == nil { - return t - } - - // set version - if v := table.GetVersion(); v != nil { - version := pkg.Version{} - version.SetMajor(v.GetMajor()) - version.SetMinor(v.GetMinor()) - - t.SetVersion(version) - } - - // set container id - if id := table.GetContainerID(); id != nil { - if t.cid == nil { - t.cid = new(cid.ID) - } - - var h [sha256.Size]byte - - copy(h[:], id.GetValue()) - t.cid.SetSHA256(h) - } - - // set eacl records - v2records := table.GetRecords() - t.records = make([]*Record, 0, len(v2records)) - - for i := range v2records { - t.records = append(t.records, NewRecordFromV2(v2records[i])) - } - - return t -} - -// Marshal marshals Table into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (t *Table) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return t.ToV2(). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Table. -func (t *Table) Unmarshal(data []byte) error { - fV2 := new(v2acl.Table) - if err := fV2.Unmarshal(data); err != nil { - return err - } - - *t = *NewTableFromV2(fV2) - - return nil -} - -// MarshalJSON encodes Table to protobuf JSON format. -func (t *Table) MarshalJSON() ([]byte, error) { - return t.ToV2(). - MarshalJSON() -} - -// UnmarshalJSON decodes Table from protobuf JSON format. -func (t *Table) UnmarshalJSON(data []byte) error { - tV2 := new(v2acl.Table) - if err := tV2.UnmarshalJSON(data); err != nil { - return err - } - - *t = *NewTableFromV2(tV2) - - return nil -} diff --git a/pkg/acl/eacl/table_test.go b/pkg/acl/eacl/table_test.go deleted file mode 100644 index 6dcf062..0000000 --- a/pkg/acl/eacl/table_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package eacl_test - -import ( - "crypto/sha256" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" - eacltest "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl/test" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test" - "github.com/stretchr/testify/require" -) - -func TestTable(t *testing.T) { - var ( - v pkg.Version - ) - - sha := sha256.Sum256([]byte("container id")) - id := cidtest.GenerateWithChecksum(sha) - - v.SetMajor(3) - v.SetMinor(2) - - table := eacl.NewTable() - table.SetVersion(v) - table.SetCID(id) - table.AddRecord(eacl.CreateRecord(eacl.ActionAllow, eacl.OperationPut)) - - v2 := table.ToV2() - require.NotNil(t, v2) - require.Equal(t, uint32(3), v2.GetVersion().GetMajor()) - require.Equal(t, uint32(2), v2.GetVersion().GetMinor()) - require.Equal(t, sha[:], v2.GetContainerID().GetValue()) - require.Len(t, v2.GetRecords(), 1) - - newTable := eacl.NewTableFromV2(v2) - require.Equal(t, table, newTable) - - t.Run("new from nil v2 table", func(t *testing.T) { - require.Equal(t, new(eacl.Table), eacl.NewTableFromV2(nil)) - }) - - t.Run("create table", func(t *testing.T) { - id := cidtest.Generate() - - table := eacl.CreateTable(*id) - require.Equal(t, id, table.CID()) - require.Equal(t, *pkg.SDKVersion(), table.Version()) - }) -} - -func TestTable_AddRecord(t *testing.T) { - records := []*eacl.Record{ - eacl.CreateRecord(eacl.ActionDeny, eacl.OperationDelete), - eacl.CreateRecord(eacl.ActionAllow, eacl.OperationPut), - } - - table := eacl.NewTable() - for _, record := range records { - table.AddRecord(record) - } - - require.Equal(t, records, table.Records()) -} - -func TestTableEncoding(t *testing.T) { - tab := eacltest.Table() - - t.Run("binary", func(t *testing.T) { - data, err := tab.Marshal() - require.NoError(t, err) - - tab2 := eacl.NewTable() - require.NoError(t, tab2.Unmarshal(data)) - - // FIXME: we compare v2 messages because - // Filter contains fmt.Stringer interface - require.Equal(t, tab.ToV2(), tab2.ToV2()) - }) - - t.Run("json", func(t *testing.T) { - data, err := tab.MarshalJSON() - require.NoError(t, err) - - tab2 := eacl.NewTable() - require.NoError(t, tab2.UnmarshalJSON(data)) - - require.Equal(t, tab.ToV2(), tab2.ToV2()) - }) -} - -func TestTable_SessionToken(t *testing.T) { - tok := sessiontest.Generate() - - table := eacl.NewTable() - table.SetSessionToken(tok) - - require.Equal(t, tok, table.SessionToken()) -} - -func TestTable_Signature(t *testing.T) { - sig := pkg.NewSignature() - sig.SetKey([]byte{1, 2, 3}) - sig.SetSign([]byte{4, 5, 6}) - - table := eacl.NewTable() - table.SetSignature(sig) - - require.Equal(t, sig, table.Signature()) -} - -func TestTable_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *eacl.Table - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - table := eacl.NewTable() - - // check initial values - require.Equal(t, *pkg.SDKVersion(), table.Version()) - require.Nil(t, table.Records()) - require.Nil(t, table.CID()) - require.Nil(t, table.SessionToken()) - require.Nil(t, table.Signature()) - - // convert to v2 message - tableV2 := table.ToV2() - - require.Equal(t, pkg.SDKVersion().ToV2(), tableV2.GetVersion()) - require.Nil(t, tableV2.GetRecords()) - require.Nil(t, tableV2.GetContainerID()) - }) -} diff --git a/pkg/acl/eacl/target.go b/pkg/acl/eacl/target.go deleted file mode 100644 index 22a2af6..0000000 --- a/pkg/acl/eacl/target.go +++ /dev/null @@ -1,191 +0,0 @@ -package eacl - -import ( - "crypto/ecdsa" - - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" - crypto "github.com/nspcc-dev/neofs-crypto" -) - -// Target is a group of request senders to match EACL. Defined by role enum -// and set of public keys. -// -// Target is compatible with v2 acl.EACLRecord.Target message. -type Target struct { - role Role - keys [][]byte -} - -func ecdsaKeysToPtrs(keys []ecdsa.PublicKey) []*ecdsa.PublicKey { - keysPtr := make([]*ecdsa.PublicKey, len(keys)) - - for i := range keys { - keysPtr[i] = &keys[i] - } - - return keysPtr -} - -// SetKeys sets list of ECDSA public keys to identify target subject. -// -// Deprecated: use SetTargetECDSAKeys instead. -func (t *Target) SetKeys(keys ...ecdsa.PublicKey) { - SetTargetECDSAKeys(t, ecdsaKeysToPtrs(keys)...) -} - -// Keys returns list of ECDSA public keys to identify target subject. -// If some key has a different format, it is ignored. -// -// Deprecated: use TargetECDSAKeys instead. -func (t *Target) Keys() []ecdsa.PublicKey { - keysPtr := TargetECDSAKeys(t) - keys := make([]ecdsa.PublicKey, 0, len(keysPtr)) - - for i := range keysPtr { - if keysPtr[i] != nil { - keys = append(keys, *keysPtr[i]) - } - } - - return keys -} - -// BinaryKeys returns list of public keys to identify -// target subject in a binary format. -func (t *Target) BinaryKeys() [][]byte { - return t.keys -} - -// SetBinaryKeys sets list of binary public keys to identify -// target subject. -func (t *Target) SetBinaryKeys(keys [][]byte) { - t.keys = keys -} - -// SetTargetECDSAKeys converts ECDSA public keys to a binary -// format and stores them in Target. -func SetTargetECDSAKeys(t *Target, keys ...*ecdsa.PublicKey) { - binKeys := t.BinaryKeys() - ln := len(keys) - - if cap(binKeys) >= ln { - binKeys = binKeys[:0] - } else { - binKeys = make([][]byte, 0, ln) - } - - for i := 0; i < ln; i++ { - binKeys = append(binKeys, crypto.MarshalPublicKey(keys[i])) - } - - t.SetBinaryKeys(binKeys) -} - -// TargetECDSAKeys interprets binary public keys of Target -// as ECDSA public keys. If any key has a different format, -// the corresponding element will be nil. -func TargetECDSAKeys(t *Target) []*ecdsa.PublicKey { - binKeys := t.BinaryKeys() - ln := len(binKeys) - - keys := make([]*ecdsa.PublicKey, ln) - - for i := 0; i < ln; i++ { - keys[i] = crypto.UnmarshalPublicKey(binKeys[i]) - } - - return keys -} - -// SetRole sets target subject's role class. -func (t *Target) SetRole(r Role) { - t.role = r -} - -// Role returns target subject's role class. -func (t Target) Role() Role { - return t.role -} - -// ToV2 converts Target to v2 acl.EACLRecord.Target message. -// -// Nil Target converts to nil. -func (t *Target) ToV2() *v2acl.Target { - if t == nil { - return nil - } - - target := new(v2acl.Target) - - target.SetRole(t.role.ToV2()) - target.SetKeys(t.keys) - - return target -} - -// NewTarget creates, initializes and returns blank Target instance. -// -// Defaults: -// - role: RoleUnknown; -// - keys: nil. -func NewTarget() *Target { - return NewTargetFromV2(new(v2acl.Target)) -} - -// NewTargetFromV2 converts v2 acl.EACLRecord.Target message to Target. -func NewTargetFromV2(target *v2acl.Target) *Target { - t := new(Target) - - if target == nil { - return t - } - - t.role = RoleFromV2(target.GetRole()) - t.keys = target.GetKeys() - - return t -} - -// Marshal marshals Target into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (t *Target) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return t.ToV2(). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Target. -func (t *Target) Unmarshal(data []byte) error { - fV2 := new(v2acl.Target) - if err := fV2.Unmarshal(data); err != nil { - return err - } - - *t = *NewTargetFromV2(fV2) - - return nil -} - -// MarshalJSON encodes Target to protobuf JSON format. -func (t *Target) MarshalJSON() ([]byte, error) { - return t.ToV2(). - MarshalJSON() -} - -// UnmarshalJSON decodes Target from protobuf JSON format. -func (t *Target) UnmarshalJSON(data []byte) error { - tV2 := new(v2acl.Target) - if err := tV2.UnmarshalJSON(data); err != nil { - return err - } - - *t = *NewTargetFromV2(tV2) - - return nil -} diff --git a/pkg/acl/eacl/target_test.go b/pkg/acl/eacl/target_test.go deleted file mode 100644 index 5fd0e70..0000000 --- a/pkg/acl/eacl/target_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package eacl - -import ( - "crypto/ecdsa" - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/acl" - v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" - crypto "github.com/nspcc-dev/neofs-crypto" - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -func TestTarget(t *testing.T) { - keys := []*ecdsa.PublicKey{ - &test.DecodeKey(1).PublicKey, - &test.DecodeKey(2).PublicKey, - } - - target := NewTarget() - target.SetRole(RoleSystem) - SetTargetECDSAKeys(target, keys...) - - v2 := target.ToV2() - require.NotNil(t, v2) - require.Equal(t, v2acl.RoleSystem, v2.GetRole()) - require.Len(t, v2.GetKeys(), len(keys)) - for i, key := range v2.GetKeys() { - require.Equal(t, key, crypto.MarshalPublicKey(keys[i])) - } - - newTarget := NewTargetFromV2(v2) - require.Equal(t, target, newTarget) - - t.Run("from nil v2 target", func(t *testing.T) { - require.Equal(t, new(Target), NewTargetFromV2(nil)) - }) -} - -func TestTargetEncoding(t *testing.T) { - tar := NewTarget() - tar.SetRole(RoleSystem) - SetTargetECDSAKeys(tar, &test.DecodeKey(-1).PublicKey) - - t.Run("binary", func(t *testing.T) { - data, err := tar.Marshal() - require.NoError(t, err) - - tar2 := NewTarget() - require.NoError(t, tar2.Unmarshal(data)) - - require.Equal(t, tar, tar2) - }) - - t.Run("json", func(t *testing.T) { - data, err := tar.MarshalJSON() - require.NoError(t, err) - - tar2 := NewTarget() - require.NoError(t, tar2.UnmarshalJSON(data)) - - require.Equal(t, tar, tar2) - }) -} - -func TestTarget_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Target - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - target := NewTarget() - - // check initial values - require.Equal(t, RoleUnknown, target.Role()) - require.Nil(t, target.BinaryKeys()) - - // convert to v2 message - targetV2 := target.ToV2() - - require.Equal(t, acl.RoleUnknown, targetV2.GetRole()) - require.Nil(t, targetV2.GetKeys()) - }) -} diff --git a/pkg/acl/eacl/test/generate.go b/pkg/acl/eacl/test/generate.go deleted file mode 100644 index 4eda92a..0000000 --- a/pkg/acl/eacl/test/generate.go +++ /dev/null @@ -1,45 +0,0 @@ -package eacltest - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" -) - -// Target returns random eacl.Target. -func Target() *eacl.Target { - x := eacl.NewTarget() - - x.SetRole(eacl.RoleSystem) - x.SetBinaryKeys([][]byte{ - {1, 2, 3}, - {4, 5, 6}, - }) - - return x -} - -// Record returns random eacl.Record. -func Record() *eacl.Record { - x := eacl.NewRecord() - - x.SetAction(eacl.ActionAllow) - x.SetOperation(eacl.OperationRangeHash) - x.SetTargets(Target(), Target()) - x.AddObjectContainerIDFilter(eacl.MatchStringEqual, cidtest.Generate()) - x.AddObjectOwnerIDFilter(eacl.MatchStringNotEqual, ownertest.Generate()) - - return x -} - -func Table() *eacl.Table { - x := eacl.NewTable() - - x.SetCID(cidtest.Generate()) - x.AddRecord(Record()) - x.AddRecord(Record()) - x.SetVersion(*refstest.Version()) - - return x -} diff --git a/pkg/acl/types.go b/pkg/acl/types.go deleted file mode 100644 index 6a7b428..0000000 --- a/pkg/acl/types.go +++ /dev/null @@ -1,15 +0,0 @@ -package acl - -const ( - // PublicBasicRule is a basic ACL value for public-read-write container. - PublicBasicRule = 0x1FBFBFFF - - // PrivateBasicRule is a basic ACL value for private container. - PrivateBasicRule = 0x1C8C8CCC - - // ReadOnlyBasicRule is a basic ACL value for public-read container. - ReadOnlyBasicRule = 0x1FBF8CFF - - // PublicAppendRule is a basic ACL value for public-append container. - PublicAppendRule = 0x1FBF9FFF -) diff --git a/pkg/audit/result.go b/pkg/audit/result.go deleted file mode 100644 index e334e99..0000000 --- a/pkg/audit/result.go +++ /dev/null @@ -1,330 +0,0 @@ -package audit - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - "github.com/nspcc-dev/neofs-api-go/v2/audit" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// Result represents v2-compatible data audit result. -type Result audit.DataAuditResult - -// NewFromV2 wraps v2 DataAuditResult message to Result. -// -// Nil audit.DataAuditResult converts to nil. -func NewResultFromV2(aV2 *audit.DataAuditResult) *Result { - return (*Result)(aV2) -} - -// New creates and initializes blank Result. -// -// Defaults: -// - version: pkg.SDKVersion(); -// - complete: false; -// - cid: nil; -// - pubKey: nil; -// - passSG, failSG: nil; -// - failNodes, passNodes: nil; -// - hit, miss, fail: 0; -// - requests, retries: 0; -// - auditEpoch: 0. -func NewResult() *Result { - r := NewResultFromV2(new(audit.DataAuditResult)) - r.SetVersion(pkg.SDKVersion()) - - return r -} - -// ToV2 converts Result to v2 DataAuditResult message. -// -// Nil Result converts to nil. -func (r *Result) ToV2() *audit.DataAuditResult { - return (*audit.DataAuditResult)(r) -} - -// Marshal marshals Result into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (r *Result) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*audit.DataAuditResult)(r). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Result. -func (r *Result) Unmarshal(data []byte) error { - return (*audit.DataAuditResult)(r). - Unmarshal(data) -} - -// MarshalJSON encodes Result to protobuf JSON format. -func (r *Result) MarshalJSON() ([]byte, error) { - return (*audit.DataAuditResult)(r). - MarshalJSON() -} - -// UnmarshalJSON decodes Result from protobuf JSON format. -func (r *Result) UnmarshalJSON(data []byte) error { - return (*audit.DataAuditResult)(r). - UnmarshalJSON(data) -} - -// Version returns Data Audit structure version. -func (r *Result) Version() *pkg.Version { - return pkg.NewVersionFromV2( - (*audit.DataAuditResult)(r).GetVersion(), - ) -} - -// SetVersion sets Data Audit structure version. -func (r *Result) SetVersion(v *pkg.Version) { - (*audit.DataAuditResult)(r). - SetVersion(v.ToV2()) -} - -// AuditEpoch returns epoch number when the Data Audit was conducted. -func (r *Result) AuditEpoch() uint64 { - return (*audit.DataAuditResult)(r). - GetAuditEpoch() -} - -// SetAuditEpoch sets epoch number when the Data Audit was conducted. -func (r *Result) SetAuditEpoch(epoch uint64) { - (*audit.DataAuditResult)(r). - SetAuditEpoch(epoch) -} - -// ContainerID returns container under audit. -func (r *Result) ContainerID() *cid.ID { - return cid.NewFromV2( - (*audit.DataAuditResult)(r). - GetContainerID(), - ) -} - -// SetContainerID sets container under audit. -func (r *Result) SetContainerID(id *cid.ID) { - (*audit.DataAuditResult)(r). - SetContainerID(id.ToV2()) -} - -// PublicKey returns public key of the auditing InnerRing node in a binary format. -func (r *Result) PublicKey() []byte { - return (*audit.DataAuditResult)(r). - GetPublicKey() -} - -// SetPublicKey sets public key of the auditing InnerRing node in a binary format. -func (r *Result) SetPublicKey(key []byte) { - (*audit.DataAuditResult)(r). - SetPublicKey(key) -} - -// Complete returns completion state of audit result. -func (r *Result) Complete() bool { - return (*audit.DataAuditResult)(r). - GetComplete() -} - -// SetComplete sets completion state of audit result. -func (r *Result) SetComplete(v bool) { - (*audit.DataAuditResult)(r). - SetComplete(v) -} - -// Requests returns number of requests made by PoR audit check to get -// all headers of the objects inside storage groups. -func (r *Result) Requests() uint32 { - return (*audit.DataAuditResult)(r). - GetRequests() -} - -// SetRequests sets number of requests made by PoR audit check to get -// all headers of the objects inside storage groups. -func (r *Result) SetRequests(v uint32) { - (*audit.DataAuditResult)(r). - SetRequests(v) -} - -// Retries returns number of retries made by PoR audit check to get -// all headers of the objects inside storage groups. -func (r *Result) Retries() uint32 { - return (*audit.DataAuditResult)(r). - GetRetries() -} - -// SetRetries sets number of retries made by PoR audit check to get -// all headers of the objects inside storage groups. -func (r *Result) SetRetries(v uint32) { - (*audit.DataAuditResult)(r). - SetRetries(v) -} - -// PassSG returns list of Storage Groups that passed audit PoR stage. -func (r *Result) PassSG() []*object.ID { - mV2 := (*audit.DataAuditResult)(r). - GetPassSG() - - if mV2 == nil { - return nil - } - - m := make([]*object.ID, len(mV2)) - - for i := range mV2 { - m[i] = object.NewIDFromV2(mV2[i]) - } - - return m -} - -// SetPassSG sets list of Storage Groups that passed audit PoR stage. -func (r *Result) SetPassSG(list []*object.ID) { - mV2 := (*audit.DataAuditResult)(r). - GetPassSG() - - if list == nil { - mV2 = nil - } else { - ln := len(list) - - if cap(mV2) >= ln { - mV2 = mV2[:0] - } else { - mV2 = make([]*refs.ObjectID, 0, ln) - } - - for i := 0; i < ln; i++ { - mV2 = append(mV2, list[i].ToV2()) - } - } - - (*audit.DataAuditResult)(r). - SetPassSG(mV2) -} - -// FailSG returns list of Storage Groups that failed audit PoR stage. -func (r *Result) FailSG() []*object.ID { - mV2 := (*audit.DataAuditResult)(r). - GetFailSG() - - if mV2 == nil { - return nil - } - - m := make([]*object.ID, len(mV2)) - - for i := range mV2 { - m[i] = object.NewIDFromV2(mV2[i]) - } - - return m -} - -// SetFailSG sets list of Storage Groups that failed audit PoR stage. -func (r *Result) SetFailSG(list []*object.ID) { - mV2 := (*audit.DataAuditResult)(r). - GetFailSG() - - if list == nil { - mV2 = nil - } else { - ln := len(list) - - if cap(mV2) >= ln { - mV2 = mV2[:0] - } else { - mV2 = make([]*refs.ObjectID, 0, ln) - } - - for i := 0; i < ln; i++ { - mV2 = append(mV2, list[i].ToV2()) - } - } - - (*audit.DataAuditResult)(r). - SetFailSG(mV2) -} - -// Hit returns number of sampled objects under audit placed -// in an optimal way according to the containers placement policy -// when checking PoP. -func (r *Result) Hit() uint32 { - return (*audit.DataAuditResult)(r). - GetHit() -} - -// SetHit sets number of sampled objects under audit placed -// in an optimal way according to the containers placement policy -// when checking PoP. -func (r *Result) SetHit(hit uint32) { - (*audit.DataAuditResult)(r). - SetHit(hit) -} - -// Miss returns number of sampled objects under audit placed -// in suboptimal way according to the containers placement policy, -// but still at a satisfactory level when checking PoP. -func (r *Result) Miss() uint32 { - return (*audit.DataAuditResult)(r). - GetMiss() -} - -// SetMiss sets number of sampled objects under audit placed -// in suboptimal way according to the containers placement policy, -// but still at a satisfactory level when checking PoP. -func (r *Result) SetMiss(miss uint32) { - (*audit.DataAuditResult)(r). - SetMiss(miss) -} - -// Fail returns number of sampled objects under audit stored -// in a way not confirming placement policy or not found at all -// when checking PoP. -func (r *Result) Fail() uint32 { - return (*audit.DataAuditResult)(r). - GetFail() -} - -// SetFail sets number of sampled objects under audit stored -// in a way not confirming placement policy or not found at all -// when checking PoP. -func (r *Result) SetFail(fail uint32) { - (*audit.DataAuditResult)(r). - SetFail(fail) -} - -// PassNodes returns list of storage node public keys that -// passed at least one PDP. -func (r *Result) PassNodes() [][]byte { - return (*audit.DataAuditResult)(r). - GetPassNodes() -} - -// SetPassNodes sets list of storage node public keys that -// passed at least one PDP. -func (r *Result) SetPassNodes(list [][]byte) { - (*audit.DataAuditResult)(r). - SetPassNodes(list) -} - -// FailNodes returns list of storage node public keys that -// failed at least one PDP. -func (r *Result) FailNodes() [][]byte { - return (*audit.DataAuditResult)(r). - GetFailNodes() -} - -// SetFailNodes sets list of storage node public keys that -// failed at least one PDP. -func (r *Result) SetFailNodes(list [][]byte) { - (*audit.DataAuditResult)(r). - SetFailNodes(list) -} diff --git a/pkg/audit/result_test.go b/pkg/audit/result_test.go deleted file mode 100644 index 23f8fcf..0000000 --- a/pkg/audit/result_test.go +++ /dev/null @@ -1,154 +0,0 @@ -package audit_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/audit" - audittest "github.com/nspcc-dev/neofs-api-go/pkg/audit/test" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test" - auditv2 "github.com/nspcc-dev/neofs-api-go/v2/audit" - "github.com/stretchr/testify/require" -) - -func TestResult(t *testing.T) { - r := audit.NewResult() - require.Equal(t, pkg.SDKVersion(), r.Version()) - - epoch := uint64(13) - r.SetAuditEpoch(epoch) - require.Equal(t, epoch, r.AuditEpoch()) - - cid := cidtest.Generate() - r.SetContainerID(cid) - require.Equal(t, cid, r.ContainerID()) - - key := []byte{1, 2, 3} - r.SetPublicKey(key) - require.Equal(t, key, r.PublicKey()) - - r.SetComplete(true) - require.True(t, r.Complete()) - - requests := uint32(2) - r.SetRequests(requests) - require.Equal(t, requests, r.Requests()) - - retries := uint32(1) - r.SetRetries(retries) - require.Equal(t, retries, r.Retries()) - - passSG := []*object.ID{objecttest.ID(), objecttest.ID()} - r.SetPassSG(passSG) - require.Equal(t, passSG, r.PassSG()) - - failSG := []*object.ID{objecttest.ID(), objecttest.ID()} - r.SetFailSG(failSG) - require.Equal(t, failSG, r.FailSG()) - - hit := uint32(1) - r.SetHit(hit) - require.Equal(t, hit, r.Hit()) - - miss := uint32(2) - r.SetMiss(miss) - require.Equal(t, miss, r.Miss()) - - fail := uint32(3) - r.SetFail(fail) - require.Equal(t, fail, r.Fail()) - - passNodes := [][]byte{{1}, {2}} - r.SetPassNodes(passNodes) - require.Equal(t, passNodes, r.PassNodes()) - - failNodes := [][]byte{{3}, {4}} - r.SetFailNodes(failNodes) - require.Equal(t, failNodes, r.FailNodes()) -} - -func TestStorageGroupEncoding(t *testing.T) { - r := audittest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := r.Marshal() - require.NoError(t, err) - - r2 := audit.NewResult() - 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 := audit.NewResult() - require.NoError(t, r2.UnmarshalJSON(data)) - - require.Equal(t, r, r2) - }) -} - -func TestResult_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *audit.Result - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - result := audit.NewResult() - - // check initial values - require.Equal(t, pkg.SDKVersion(), result.Version()) - - require.False(t, result.Complete()) - - require.Nil(t, result.ContainerID()) - require.Nil(t, result.PublicKey()) - require.Nil(t, result.PassSG()) - require.Nil(t, result.FailSG()) - require.Nil(t, result.PassNodes()) - require.Nil(t, result.FailNodes()) - - require.Zero(t, result.Hit()) - require.Zero(t, result.Miss()) - require.Zero(t, result.Fail()) - require.Zero(t, result.Requests()) - require.Zero(t, result.Retries()) - require.Zero(t, result.AuditEpoch()) - - // convert to v2 message - resultV2 := result.ToV2() - - require.Equal(t, pkg.SDKVersion().ToV2(), resultV2.GetVersion()) - - require.False(t, resultV2.GetComplete()) - - require.Nil(t, resultV2.GetContainerID()) - require.Nil(t, resultV2.GetPublicKey()) - require.Nil(t, resultV2.GetPassSG()) - require.Nil(t, resultV2.GetFailSG()) - require.Nil(t, resultV2.GetPassNodes()) - require.Nil(t, resultV2.GetFailNodes()) - - require.Zero(t, resultV2.GetHit()) - require.Zero(t, resultV2.GetMiss()) - require.Zero(t, resultV2.GetFail()) - require.Zero(t, resultV2.GetRequests()) - require.Zero(t, resultV2.GetRetries()) - require.Zero(t, resultV2.GetAuditEpoch()) - }) -} - -func TestNewResultFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *auditv2.DataAuditResult - - require.Nil(t, audit.NewResultFromV2(x)) - }) -} diff --git a/pkg/audit/test/generate.go b/pkg/audit/test/generate.go deleted file mode 100644 index 84b2f8f..0000000 --- a/pkg/audit/test/generate.go +++ /dev/null @@ -1,37 +0,0 @@ -package audittest - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/audit" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" -) - -// Generate returns random audit.Result. -func Generate() *audit.Result { - x := audit.NewResult() - - x.SetVersion(refstest.Version()) - x.SetContainerID(cidtest.Generate()) - x.SetPublicKey([]byte("key")) - x.SetComplete(true) - x.SetAuditEpoch(44) - x.SetHit(55) - x.SetMiss(66) - x.SetFail(77) - x.SetRetries(88) - x.SetRequests(99) - x.SetFailNodes([][]byte{ - []byte("node1"), - []byte("node2"), - }) - x.SetPassNodes([][]byte{ - []byte("node3"), - []byte("node4"), - }) - x.SetPassSG([]*object.ID{objecttest.ID(), objecttest.ID()}) - x.SetFailSG([]*object.ID{objecttest.ID(), objecttest.ID()}) - - return x -} diff --git a/pkg/checksum.go b/pkg/checksum.go deleted file mode 100644 index b02ae0d..0000000 --- a/pkg/checksum.go +++ /dev/null @@ -1,198 +0,0 @@ -package pkg - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// Checksum represents v2-compatible checksum. -type Checksum refs.Checksum - -// ChecksumType represents the enumeration -// of checksum types. -type ChecksumType uint8 - -const ( - // ChecksumUnknown is an undefined checksum type. - ChecksumUnknown ChecksumType = iota - - // ChecksumSHA256 is a SHA256 checksum type. - ChecksumSHA256 - - // ChecksumTZ is a Tillich-Zemor checksum type. - ChecksumTZ -) - -// NewChecksumFromV2 wraps v2 Checksum message to Checksum. -// -// Nil refs.Checksum converts to nil. -func NewChecksumFromV2(cV2 *refs.Checksum) *Checksum { - return (*Checksum)(cV2) -} - -// NewChecksum creates and initializes blank Checksum. -// -// Works similar as NewChecksumFromV2(new(Checksum)). -// -// Defaults: -// - sum: nil; -// - type: ChecksumUnknown. -func NewChecksum() *Checksum { - return NewChecksumFromV2(new(refs.Checksum)) -} - -// Type returns checksum type. -func (c *Checksum) Type() ChecksumType { - switch (*refs.Checksum)(c).GetType() { - case refs.SHA256: - return ChecksumSHA256 - case refs.TillichZemor: - return ChecksumTZ - default: - return ChecksumUnknown - } -} - -// Sum returns checksum bytes. -func (c *Checksum) Sum() []byte { - return (*refs.Checksum)(c).GetSum() -} - -// SetSHA256 sets checksum to SHA256 hash. -func (c *Checksum) SetSHA256(v [sha256.Size]byte) { - checksum := (*refs.Checksum)(c) - - checksum.SetType(refs.SHA256) - checksum.SetSum(v[:]) -} - -// SetTillichZemor sets checksum to Tillich-Zemor hash. -func (c *Checksum) SetTillichZemor(v [64]byte) { - checksum := (*refs.Checksum)(c) - - checksum.SetType(refs.TillichZemor) - checksum.SetSum(v[:]) -} - -// ToV2 converts Checksum to v2 Checksum message. -// -// Nil Checksum converts to nil. -func (c *Checksum) ToV2() *refs.Checksum { - return (*refs.Checksum)(c) -} - -func EqualChecksums(cs1, cs2 *Checksum) bool { - return cs1.Type() == cs2.Type() && bytes.Equal(cs1.Sum(), cs2.Sum()) -} - -// Marshal marshals Checksum into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (c *Checksum) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.Checksum)(c). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Checksum. -func (c *Checksum) Unmarshal(data []byte) error { - return (*refs.Checksum)(c). - Unmarshal(data) -} - -// MarshalJSON encodes Checksum to protobuf JSON format. -func (c *Checksum) MarshalJSON() ([]byte, error) { - return (*refs.Checksum)(c). - MarshalJSON() -} - -// UnmarshalJSON decodes Checksum from protobuf JSON format. -func (c *Checksum) UnmarshalJSON(data []byte) error { - return (*refs.Checksum)(c). - UnmarshalJSON(data) -} - -func (c *Checksum) String() string { - return hex.EncodeToString( - (*refs.Checksum)(c). - GetSum(), - ) -} - -// Parse parses Checksum from its string representation. -func (c *Checksum) Parse(s string) error { - data, err := hex.DecodeString(s) - if err != nil { - return err - } - - var typ refs.ChecksumType - - switch ln := len(data); ln { - default: - return fmt.Errorf("unsupported checksum length %d", ln) - case sha256.Size: - typ = refs.SHA256 - case 64: - typ = refs.TillichZemor - } - - cV2 := (*refs.Checksum)(c) - cV2.SetType(typ) - cV2.SetSum(data) - - return nil -} - -// String returns string representation of ChecksumType. -// -// String mapping: -// * ChecksumTZ: TZ; -// * ChecksumSHA256: SHA256; -// * ChecksumUnknown, default: CHECKSUM_TYPE_UNSPECIFIED. -func (m ChecksumType) String() string { - var m2 refs.ChecksumType - - switch m { - default: - m2 = refs.UnknownChecksum - case ChecksumTZ: - m2 = refs.TillichZemor - case ChecksumSHA256: - m2 = refs.SHA256 - } - - return m2.String() -} - -// FromString parses ChecksumType from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (m *ChecksumType) FromString(s string) bool { - var g refs.ChecksumType - - ok := g.FromString(s) - - if ok { - switch g { - default: - *m = ChecksumUnknown - case refs.TillichZemor: - *m = ChecksumTZ - case refs.SHA256: - *m = ChecksumSHA256 - } - } - - return ok -} diff --git a/pkg/checksum_test.go b/pkg/checksum_test.go deleted file mode 100644 index b5a0600..0000000 --- a/pkg/checksum_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package pkg - -import ( - "crypto/rand" - "crypto/sha256" - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func randSHA256(t *testing.T) [sha256.Size]byte { - cSHA256 := [sha256.Size]byte{} - _, err := rand.Read(cSHA256[:]) - require.NoError(t, err) - - return cSHA256 -} - -func TestChecksum(t *testing.T) { - c := NewChecksum() - - cSHA256 := [sha256.Size]byte{} - _, _ = rand.Read(cSHA256[:]) - - c.SetSHA256(cSHA256) - - require.Equal(t, ChecksumSHA256, c.Type()) - require.Equal(t, cSHA256[:], c.Sum()) - - cV2 := c.ToV2() - - require.Equal(t, refs.SHA256, cV2.GetType()) - require.Equal(t, cSHA256[:], cV2.GetSum()) - - cTZ := [64]byte{} - _, _ = rand.Read(cSHA256[:]) - - c.SetTillichZemor(cTZ) - - require.Equal(t, ChecksumTZ, c.Type()) - require.Equal(t, cTZ[:], c.Sum()) - - cV2 = c.ToV2() - - require.Equal(t, refs.TillichZemor, cV2.GetType()) - require.Equal(t, cTZ[:], cV2.GetSum()) -} - -func TestEqualChecksums(t *testing.T) { - require.True(t, EqualChecksums(nil, nil)) - - csSHA := [sha256.Size]byte{} - _, _ = rand.Read(csSHA[:]) - - cs1 := NewChecksum() - cs1.SetSHA256(csSHA) - - cs2 := NewChecksum() - cs2.SetSHA256(csSHA) - - require.True(t, EqualChecksums(cs1, cs2)) - - csSHA[0]++ - cs2.SetSHA256(csSHA) - - require.False(t, EqualChecksums(cs1, cs2)) -} - -func TestChecksumEncoding(t *testing.T) { - cs := NewChecksum() - cs.SetSHA256(randSHA256(t)) - - t.Run("binary", func(t *testing.T) { - data, err := cs.Marshal() - require.NoError(t, err) - - c2 := NewChecksum() - require.NoError(t, c2.Unmarshal(data)) - - require.Equal(t, cs, c2) - }) - - t.Run("json", func(t *testing.T) { - data, err := cs.MarshalJSON() - require.NoError(t, err) - - cs2 := NewChecksum() - require.NoError(t, cs2.UnmarshalJSON(data)) - - require.Equal(t, cs, cs2) - }) - - t.Run("string", func(t *testing.T) { - cs2 := NewChecksum() - - require.NoError(t, cs2.Parse(cs.String())) - - require.Equal(t, cs, cs2) - }) -} - -func TestNewChecksumFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.Checksum - - require.Nil(t, NewChecksumFromV2(x)) - }) -} - -func TestChecksum_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Checksum - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewChecksum(t *testing.T) { - t.Run("default values", func(t *testing.T) { - chs := NewChecksum() - - // check initial values - require.Equal(t, ChecksumUnknown, chs.Type()) - require.Nil(t, chs.Sum()) - - // convert to v2 message - chsV2 := chs.ToV2() - - require.Equal(t, refs.UnknownChecksum, chsV2.GetType()) - require.Nil(t, chsV2.GetSum()) - }) -} - -type enumIface interface { - FromString(string) bool - String() string -} - -type enumStringItem struct { - val enumIface - str string -} - -func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { - for _, item := range items { - require.Equal(t, item.str, item.val.String()) - - s := item.val.String() - - require.True(t, e.FromString(s), s) - - require.EqualValues(t, item.val, e, item.val) - } - - // incorrect strings - for _, str := range []string{ - "some string", - "undefined", - } { - require.False(t, e.FromString(str)) - } -} - -func TestChecksumType_String(t *testing.T) { - toPtr := func(v ChecksumType) *ChecksumType { - return &v - } - - testEnumStrings(t, new(ChecksumType), []enumStringItem{ - {val: toPtr(ChecksumTZ), str: "TZ"}, - {val: toPtr(ChecksumSHA256), str: "SHA256"}, - {val: toPtr(ChecksumUnknown), str: "CHECKSUM_TYPE_UNSPECIFIED"}, - }) -} diff --git a/pkg/client/accounting.go b/pkg/client/accounting.go deleted file mode 100644 index db1f8a4..0000000 --- a/pkg/client/accounting.go +++ /dev/null @@ -1,57 +0,0 @@ -package client - -import ( - "context" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg/accounting" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Accounting contains methods related to balance querying. -type Accounting interface { - // GetBalance returns balance of provided account. - GetBalance(context.Context, *owner.ID, ...CallOption) (*accounting.Decimal, error) -} - -func (c *clientImpl) GetBalance(ctx context.Context, owner *owner.ID, opts ...CallOption) (*accounting.Decimal, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2accounting.BalanceRequestBody) - reqBody.SetOwnerID(owner.ToV2()) - - req := new(v2accounting.BalanceRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.Balance(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - return accounting.NewDecimalFromV2(resp.GetBody().GetBalance()), nil -} diff --git a/pkg/client/client.go b/pkg/client/client.go deleted file mode 100644 index 4ffbd30..0000000 --- a/pkg/client/client.go +++ /dev/null @@ -1,47 +0,0 @@ -package client - -import ( - "io" - "sync" - - "github.com/nspcc-dev/neofs-api-go/rpc/client" -) - -// Client represents NeoFS client. -type Client interface { - Accounting - Container - Netmap - Object - Session - Reputation - - // Raw must return underlying raw protobuf client. - Raw() *client.Client - - // Conn must return underlying connection. - // - // Must return a non-nil result after the first RPC call - // completed without a connection error. - Conn() io.Closer -} - -type clientImpl struct { - onceInit sync.Once - - raw *client.Client - - opts *clientOptions -} - -func New(opts ...Option) (Client, error) { - clientOptions := defaultClientOptions() - - for i := range opts { - opts[i](clientOptions) - } - - return &clientImpl{ - opts: clientOptions, - }, nil -} diff --git a/pkg/client/container.go b/pkg/client/container.go deleted file mode 100644 index 02c7993..0000000 --- a/pkg/client/container.go +++ /dev/null @@ -1,477 +0,0 @@ -package client - -import ( - "context" - "errors" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" - "github.com/nspcc-dev/neofs-api-go/pkg/container" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/util/signature" - v2container "github.com/nspcc-dev/neofs-api-go/v2/container" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Container contains methods related to container and ACL. -type Container interface { - // PutContainer creates new container in the NeoFS network. - PutContainer(context.Context, *container.Container, ...CallOption) (*cid.ID, error) - - // GetContainer returns container by ID. - GetContainer(context.Context, *cid.ID, ...CallOption) (*container.Container, error) - - // ListContainers return container list with the provided owner. - ListContainers(context.Context, *owner.ID, ...CallOption) ([]*cid.ID, error) - - // DeleteContainer removes container from NeoFS network. - DeleteContainer(context.Context, *cid.ID, ...CallOption) error - - // GetEACL returns extended ACL for a given container. - GetEACL(context.Context, *cid.ID, ...CallOption) (*EACLWithSignature, error) - - // SetEACL sets extended ACL. - SetEACL(context.Context, *eacl.Table, ...CallOption) error - - // AnnounceContainerUsedSpace announces amount of space which is taken by stored objects. - AnnounceContainerUsedSpace(context.Context, []container.UsedSpaceAnnouncement, ...CallOption) error -} - -type delContainerSignWrapper struct { - body *v2container.DeleteRequestBody -} - -// EACLWithSignature represents eACL table/signature pair. -type EACLWithSignature struct { - table *eacl.Table -} - -func (c delContainerSignWrapper) ReadSignedData(bytes []byte) ([]byte, error) { - return c.body.GetContainerID().GetValue(), nil -} - -func (c delContainerSignWrapper) SignedDataSize() int { - return len(c.body.GetContainerID().GetValue()) -} - -// EACL returns eACL table. -func (e EACLWithSignature) EACL() *eacl.Table { - return e.table -} - -// Signature returns table signature. -// -// Deprecated: use EACL().Signature() instead. -func (e EACLWithSignature) Signature() *pkg.Signature { - return e.table.Signature() -} - -func (c *clientImpl) PutContainer(ctx context.Context, cnr *container.Container, opts ...CallOption) (*cid.ID, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - // set transport version - cnr.SetVersion(pkg.SDKVersion()) - - // if container owner is not set, then use client key as owner - if cnr.OwnerID() == nil { - w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey) - if err != nil { - return nil, err - } - - ownerID := new(owner.ID) - ownerID.SetNeo3Wallet(w) - - cnr.SetOwnerID(ownerID) - } - - reqBody := new(v2container.PutRequestBody) - reqBody.SetContainer(cnr.ToV2()) - - // sign container - signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()} - - err := signature.SignDataWithHandler(callOptions.key, signWrapper, func(key []byte, sig []byte) { - containerSignature := new(refs.Signature) - containerSignature.SetKey(key) - containerSignature.SetSign(sig) - reqBody.SetSignature(containerSignature) - }, signature.SignWithRFC6979()) - if err != nil { - return nil, err - } - - req := new(v2container.PutRequest) - req.SetBody(reqBody) - - meta := v2MetaHeaderFromOpts(callOptions) - meta.SetSessionToken(cnr.SessionToken().ToV2()) - - req.SetMetaHeader(meta) - - err = v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.PutContainer(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, err - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - return cid.NewFromV2(resp.GetBody().GetContainerID()), nil -} - -// GetContainer receives container structure through NeoFS API call. -// -// Returns error if container structure is received but does not meet NeoFS API specification. -func (c *clientImpl) GetContainer(ctx context.Context, id *cid.ID, opts ...CallOption) (*container.Container, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2container.GetRequestBody) - reqBody.SetContainerID(id.ToV2()) - - req := new(v2container.GetRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.GetContainer(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - body := resp.GetBody() - - cnr := container.NewContainerFromV2(body.GetContainer()) - - cnr.SetSessionToken( - session.NewTokenFromV2(body.GetSessionToken()), - ) - - cnr.SetSignature( - pkg.NewSignatureFromV2(body.GetSignature()), - ) - - return cnr, nil -} - -// GetVerifiedContainerStructure is a wrapper over Client.GetContainer method -// which checks if the structure of the resulting container matches its identifier. -// -// Returns an error if container does not match the identifier. -func GetVerifiedContainerStructure(ctx context.Context, c Client, id *cid.ID, opts ...CallOption) (*container.Container, error) { - cnr, err := c.GetContainer(ctx, id, opts...) - if err != nil { - return nil, err - } - - if !container.CalculateID(cnr).Equal(id) { - return nil, errors.New("container structure does not match the identifier") - } - - return cnr, nil -} - -func (c *clientImpl) ListContainers(ctx context.Context, ownerID *owner.ID, opts ...CallOption) ([]*cid.ID, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - if ownerID == nil { - w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey) - if err != nil { - return nil, err - } - - ownerID = new(owner.ID) - ownerID.SetNeo3Wallet(w) - } - - reqBody := new(v2container.ListRequestBody) - reqBody.SetOwnerID(ownerID.ToV2()) - - req := new(v2container.ListRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.ListContainers(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - result := make([]*cid.ID, 0, len(resp.GetBody().GetContainerIDs())) - for _, cidV2 := range resp.GetBody().GetContainerIDs() { - result = append(result, cid.NewFromV2(cidV2)) - } - - return result, nil -} - -func (c *clientImpl) DeleteContainer(ctx context.Context, id *cid.ID, opts ...CallOption) error { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2container.DeleteRequestBody) - reqBody.SetContainerID(id.ToV2()) - - // sign container - err := signature.SignDataWithHandler(callOptions.key, - delContainerSignWrapper{ - body: reqBody, - }, - func(key []byte, sig []byte) { - containerSignature := new(refs.Signature) - containerSignature.SetKey(key) - containerSignature.SetSign(sig) - reqBody.SetSignature(containerSignature) - }, - signature.SignWithRFC6979()) - if err != nil { - return err - } - - req := new(v2container.DeleteRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err = v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return err - } - - resp, err := rpcapi.DeleteContainer(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return err - } - - if err := v2signature.VerifyServiceMessage(resp); err != nil { - return fmt.Errorf("can't verify response message: %w", err) - } - - return nil -} - -func (c *clientImpl) GetEACL(ctx context.Context, id *cid.ID, opts ...CallOption) (*EACLWithSignature, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2container.GetExtendedACLRequestBody) - reqBody.SetContainerID(id.ToV2()) - - req := new(v2container.GetExtendedACLRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.GetEACL(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - body := resp.GetBody() - - table := eacl.NewTableFromV2(body.GetEACL()) - - table.SetSessionToken( - session.NewTokenFromV2(body.GetSessionToken()), - ) - - table.SetSignature( - pkg.NewSignatureFromV2(body.GetSignature()), - ) - - return &EACLWithSignature{ - table: table, - }, nil -} - -func (c *clientImpl) SetEACL(ctx context.Context, eacl *eacl.Table, opts ...CallOption) error { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2container.SetExtendedACLRequestBody) - reqBody.SetEACL(eacl.ToV2()) - reqBody.GetEACL().SetVersion(pkg.SDKVersion().ToV2()) - - signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()} - - err := signature.SignDataWithHandler(callOptions.key, signWrapper, func(key []byte, sig []byte) { - eaclSignature := new(refs.Signature) - eaclSignature.SetKey(key) - eaclSignature.SetSign(sig) - reqBody.SetSignature(eaclSignature) - }, signature.SignWithRFC6979()) - if err != nil { - return err - } - - req := new(v2container.SetExtendedACLRequest) - req.SetBody(reqBody) - - meta := v2MetaHeaderFromOpts(callOptions) - meta.SetSessionToken(eacl.SessionToken().ToV2()) - - req.SetMetaHeader(meta) - - err = v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return err - } - - resp, err := rpcapi.SetEACL(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return fmt.Errorf("can't verify response message: %w", err) - } - - return nil -} - -// AnnounceContainerUsedSpace used by storage nodes to estimate their container -// sizes during lifetime. Use it only in storage node applications. -func (c *clientImpl) AnnounceContainerUsedSpace( - ctx context.Context, - announce []container.UsedSpaceAnnouncement, - opts ...CallOption) error { - callOptions := c.defaultCallOptions() // apply all available options - - for i := range opts { - opts[i](callOptions) - } - - // convert list of SDK announcement structures into NeoFS-API v2 list - v2announce := make([]*v2container.UsedSpaceAnnouncement, 0, len(announce)) - for i := range announce { - v2announce = append(v2announce, announce[i].ToV2()) - } - - // prepare body of the NeoFS-API v2 request and request itself - reqBody := new(v2container.AnnounceUsedSpaceRequestBody) - reqBody.SetAnnouncements(v2announce) - - req := new(v2container.AnnounceUsedSpaceRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - // sign the request - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return err - } - - resp, err := rpcapi.AnnounceUsedSpace(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return fmt.Errorf("can't verify response message: %w", err) - } - - return nil -} diff --git a/pkg/client/netmap.go b/pkg/client/netmap.go deleted file mode 100644 index 6f3291c..0000000 --- a/pkg/client/netmap.go +++ /dev/null @@ -1,124 +0,0 @@ -package client - -import ( - "context" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - v2netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Netmap contains methods related to netmap. -type Netmap interface { - // EndpointInfo returns attributes, address and public key of the node, specified - // in client constructor via address or open connection. This can be used as a - // health check to see if node is alive and responses to requests. - EndpointInfo(context.Context, ...CallOption) (*EndpointInfo, error) - - // NetworkInfo returns information about the NeoFS network of which the remote server is a part. - NetworkInfo(context.Context, ...CallOption) (*netmap.NetworkInfo, error) -} - -// EACLWithSignature represents eACL table/signature pair. -type EndpointInfo struct { - version *pkg.Version - - ni *netmap.NodeInfo -} - -// LatestVersion returns latest NeoFS API version in use. -func (e *EndpointInfo) LatestVersion() *pkg.Version { - return e.version -} - -// NodeInfo returns returns information about the NeoFS node. -func (e *EndpointInfo) NodeInfo() *netmap.NodeInfo { - return e.ni -} - -// EndpointInfo returns attributes, address and public key of the node, specified -// in client constructor via address or open connection. This can be used as a -// health check to see if node is alive and responses to requests. -func (c *clientImpl) EndpointInfo(ctx context.Context, opts ...CallOption) (*EndpointInfo, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2netmap.LocalNodeInfoRequestBody) - - req := new(v2netmap.LocalNodeInfoRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.LocalNodeInfo(c.Raw(), req) - if err != nil { - return nil, fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - body := resp.GetBody() - - return &EndpointInfo{ - version: pkg.NewVersionFromV2(body.GetVersion()), - ni: netmap.NewNodeInfoFromV2(body.GetNodeInfo()), - }, nil -} - -// NetworkInfo returns information about the NeoFS network of which the remote server is a part. -func (c *clientImpl) NetworkInfo(ctx context.Context, opts ...CallOption) (*netmap.NetworkInfo, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2netmap.NetworkInfoRequestBody) - - req := new(v2netmap.NetworkInfoRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.NetworkInfo(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("v2 NetworkInfo RPC failure: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("response message verification failed: %w", err) - } - - return netmap.NewNetworkInfoFromV2(resp.GetBody().GetNetworkInfo()), nil -} diff --git a/pkg/client/object.go b/pkg/client/object.go deleted file mode 100644 index bc0f2e5..0000000 --- a/pkg/client/object.go +++ /dev/null @@ -1,1373 +0,0 @@ -package client - -import ( - "bytes" - "context" - "crypto/ecdsa" - "crypto/sha256" - "errors" - "fmt" - "io" - - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - signer "github.com/nspcc-dev/neofs-api-go/util/signature" - v2object "github.com/nspcc-dev/neofs-api-go/v2/object" - v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" - v2session "github.com/nspcc-dev/neofs-api-go/v2/session" - "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Object contains methods for working with objects. -type Object interface { - // PutObject puts new object to NeoFS. - PutObject(context.Context, *PutObjectParams, ...CallOption) (*object.ID, error) - - // DeleteObject deletes object to NeoFS. - DeleteObject(context.Context, *DeleteObjectParams, ...CallOption) error - - // GetObject returns object stored in NeoFS. - GetObject(context.Context, *GetObjectParams, ...CallOption) (*object.Object, error) - - // GetObjectHeader returns object header. - GetObjectHeader(context.Context, *ObjectHeaderParams, ...CallOption) (*object.Object, error) - - // ObjectPayloadRangeData returns range of object payload. - ObjectPayloadRangeData(context.Context, *RangeDataParams, ...CallOption) ([]byte, error) - - // ObjectPayloadRangeSHA256 returns sha-256 hashes of object sub-ranges from NeoFS. - ObjectPayloadRangeSHA256(context.Context, *RangeChecksumParams, ...CallOption) ([][sha256.Size]byte, error) - - // ObjectPayloadRangeTZ returns homomorphic hashes of object sub-ranges from NeoFS. - ObjectPayloadRangeTZ(context.Context, *RangeChecksumParams, ...CallOption) ([][TZSize]byte, error) - - // SearchObject searches for objects in NeoFS using provided parameters. - SearchObject(context.Context, *SearchObjectParams, ...CallOption) ([]*object.ID, error) -} - -type PutObjectParams struct { - obj *object.Object - - r io.Reader -} - -// ObjectAddressWriter is an interface of the -// component that writes the object address. -type ObjectAddressWriter interface { - SetAddress(*object.Address) -} - -type objectAddressWriter struct { - addr *object.Address -} - -type DeleteObjectParams struct { - addr *object.Address - - tombTgt ObjectAddressWriter -} - -type GetObjectParams struct { - addr *object.Address - - raw bool - - w io.Writer - - readerHandler ReaderHandler -} - -type ObjectHeaderParams struct { - addr *object.Address - - raw bool - - short bool -} - -type RangeDataParams struct { - addr *object.Address - - raw bool - - r *object.Range - - w io.Writer -} - -type RangeChecksumParams struct { - typ checksumType - - addr *object.Address - - rs []*object.Range - - salt []byte -} - -type SearchObjectParams struct { - cid *cid.ID - - filters object.SearchFilters -} - -type putObjectV2Reader struct { - r io.Reader -} - -type putObjectV2Writer struct { - key *ecdsa.PrivateKey - - chunkPart *v2object.PutObjectPartChunk - - req *v2object.PutRequest - - stream *rpcapi.PutRequestWriter -} - -type checksumType int - -const ( - _ checksumType = iota - checksumSHA256 - checksumTZ -) - -const chunkSize = 3 * (1 << 20) - -const TZSize = 64 - -const searchQueryVersion uint32 = 1 - -var errNilObjectPart = errors.New("received nil object part") - -func (w *objectAddressWriter) SetAddress(addr *object.Address) { - w.addr = addr -} - -func rangesToV2(rs []*object.Range) []*v2object.Range { - r2 := make([]*v2object.Range, 0, len(rs)) - - for i := range rs { - r2 = append(r2, rs[i].ToV2()) - } - - return r2 -} - -func (t checksumType) toV2() v2refs.ChecksumType { - switch t { - case checksumSHA256: - return v2refs.SHA256 - case checksumTZ: - return v2refs.TillichZemor - default: - panic(fmt.Sprintf("invalid checksum type %d", t)) - } -} - -func (w *putObjectV2Reader) Read(p []byte) (int, error) { - return w.r.Read(p) -} - -func (w *putObjectV2Writer) Write(p []byte) (int, error) { - w.chunkPart.SetChunk(p) - - w.req.SetVerificationHeader(nil) - - if err := signature.SignServiceMessage(w.key, w.req); err != nil { - return 0, fmt.Errorf("could not sign chunk request message: %w", err) - } - - if err := w.stream.Write(w.req); err != nil { - return 0, fmt.Errorf("could not send chunk request message: %w", err) - } - - return len(p), nil -} - -func (p *PutObjectParams) WithObject(v *object.Object) *PutObjectParams { - if p != nil { - p.obj = v - } - - return p -} - -func (p *PutObjectParams) Object() *object.Object { - if p != nil { - return p.obj - } - - return nil -} - -func (p *PutObjectParams) WithPayloadReader(v io.Reader) *PutObjectParams { - if p != nil { - p.r = v - } - - return p -} - -func (p *PutObjectParams) PayloadReader() io.Reader { - if p != nil { - return p.r - } - - return nil -} - -func (c *clientImpl) PutObject(ctx context.Context, p *PutObjectParams, opts ...CallOption) (*object.ID, error) { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.PutRequest) - - // initialize request body - body := new(v2object.PutRequestBody) - req.SetBody(body) - - v2Addr := new(v2refs.Address) - v2Addr.SetObjectID(p.obj.ID().ToV2()) - v2Addr.SetContainerID(p.obj.ContainerID().ToV2()) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: v2Addr, - verb: v2session.ObjectVerbPut, - }); err != nil { - return nil, fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // initialize init part - initPart := new(v2object.PutObjectPartInit) - body.SetObjectPart(initPart) - - obj := p.obj.ToV2() - - // set init part fields - initPart.SetObjectID(obj.GetObjectID()) - initPart.SetSignature(obj.GetSignature()) - initPart.SetHeader(obj.GetHeader()) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return nil, fmt.Errorf("signing the request failed: %w", err) - } - - // open stream - resp := new(v2object.PutResponse) - - stream, err := rpcapi.PutObject(c.Raw(), resp, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("stream opening failed: %w", err) - } - - // send init part - err = stream.Write(req) - if err != nil { - return nil, fmt.Errorf("sending the initial message to stream failed: %w", err) - } - - // create payload bytes reader - var rPayload io.Reader = bytes.NewReader(obj.GetPayload()) - if p.r != nil { - rPayload = io.MultiReader(rPayload, p.r) - } - - // create v2 payload stream writer - chunkPart := new(v2object.PutObjectPartChunk) - body.SetObjectPart(chunkPart) - - w := &putObjectV2Writer{ - key: callOpts.key, - chunkPart: chunkPart, - req: req, - stream: stream, - } - - r := &putObjectV2Reader{r: rPayload} - - // copy payload from reader to stream writer - _, err = io.CopyBuffer(w, r, make([]byte, chunkSize)) - if err != nil && !errors.Is(err, io.EOF) { - return nil, fmt.Errorf("payload streaming failed: %w", err) - } - - // close object stream and receive response from remote node - err = stream.Close() - if err != nil { - return nil, fmt.Errorf("closing the stream failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return nil, fmt.Errorf("response verification failed: %w", err) - } - - // convert object identifier - id := object.NewIDFromV2(resp.GetBody().GetObjectID()) - - return id, nil -} - -func (p *DeleteObjectParams) WithAddress(v *object.Address) *DeleteObjectParams { - if p != nil { - p.addr = v - } - - return p -} - -func (p *DeleteObjectParams) Address() *object.Address { - if p != nil { - return p.addr - } - - return nil -} - -// WithTombstoneAddressTarget sets target component to write tombstone address. -func (p *DeleteObjectParams) WithTombstoneAddressTarget(v ObjectAddressWriter) *DeleteObjectParams { - if p != nil { - p.tombTgt = v - } - - return p -} - -// TombstoneAddressTarget returns target component to write tombstone address. -func (p *DeleteObjectParams) TombstoneAddressTarget() ObjectAddressWriter { - if p != nil { - return p.tombTgt - } - - return nil -} - -// DeleteObject is a wrapper over Client.DeleteObject method -// that provides the ability to receive tombstone address -// without setting a target in the parameters. -func DeleteObject(ctx context.Context, c Client, p *DeleteObjectParams, opts ...CallOption) (*object.Address, error) { - w := new(objectAddressWriter) - - err := c.DeleteObject(ctx, p.WithTombstoneAddressTarget(w), opts...) - if err != nil { - return nil, err - } - - return w.addr, nil -} - -// DeleteObject removes object by address. -// -// If target of tombstone address is not set, the address is ignored. -func (c *clientImpl) DeleteObject(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) error { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.DeleteRequest) - - // initialize request body - body := new(v2object.DeleteRequestBody) - req.SetBody(body) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: p.addr.ToV2(), - verb: v2session.ObjectVerbDelete, - }); err != nil { - return fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // fill body fields - body.SetAddress(p.addr.ToV2()) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return fmt.Errorf("signing the request failed: %w", err) - } - - // send request - resp, err := rpcapi.DeleteObject(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return fmt.Errorf("sending the request failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return fmt.Errorf("response verification failed: %w", err) - } - - if p.tombTgt != nil { - p.tombTgt.SetAddress(object.NewAddressFromV2(resp.GetBody().GetTombstone())) - } - - return nil -} - -func (p *GetObjectParams) WithAddress(v *object.Address) *GetObjectParams { - if p != nil { - p.addr = v - } - - return p -} - -func (p *GetObjectParams) Address() *object.Address { - if p != nil { - return p.addr - } - - return nil -} - -func (p *GetObjectParams) WithPayloadWriter(w io.Writer) *GetObjectParams { - if p != nil { - p.w = w - } - - return p -} - -func (p *GetObjectParams) PayloadWriter() io.Writer { - if p != nil { - return p.w - } - - return nil -} - -func (p *GetObjectParams) WithRawFlag(v bool) *GetObjectParams { - if p != nil { - p.raw = v - } - - return p -} - -func (p *GetObjectParams) RawFlag() bool { - if p != nil { - return p.raw - } - - return false -} - -// ReaderHandler is a function over io.Reader. -type ReaderHandler func(io.Reader) - -// WithPayloadReaderHandler sets handler of the payload reader. -// -// If provided, payload reader is composed after receiving the header. -// In this case payload writer set via WithPayloadWriter is ignored. -// -// Handler should not be nil. -func (p *GetObjectParams) WithPayloadReaderHandler(f ReaderHandler) *GetObjectParams { - if p != nil { - p.readerHandler = f - } - - return p -} - -// wrapper over the Object Get stream that provides io.Reader. -type objectPayloadReader struct { - stream interface { - Read(*v2object.GetResponse) error - } - - resp v2object.GetResponse - - tail []byte -} - -func (x *objectPayloadReader) Read(p []byte) (read int, err error) { - // read remaining tail - read = copy(p, x.tail) - - x.tail = x.tail[read:] - - if len(p)-read == 0 { - return - } - - // receive message from server stream - err = x.stream.Read(&x.resp) - if err != nil { - if errors.Is(err, io.EOF) { - err = io.EOF - return - } - - err = fmt.Errorf("reading the response failed: %w", err) - return - } - - // get chunk part message - part := x.resp.GetBody().GetObjectPart() - - chunkPart, ok := part.(*v2object.GetObjectPartChunk) - if !ok { - err = errWrongMessageSeq - return - } - - // verify response structure - if err = signature.VerifyServiceMessage(&x.resp); err != nil { - err = fmt.Errorf("response verification failed: %w", err) - return - } - - // read new chunk - chunk := chunkPart.GetChunk() - - tailOffset := copy(p[read:], chunk) - - read += tailOffset - - // save the tail - x.tail = append(x.tail, chunk[tailOffset:]...) - - return -} - -var errWrongMessageSeq = errors.New("incorrect message sequence") - -func (c *clientImpl) GetObject(ctx context.Context, p *GetObjectParams, opts ...CallOption) (*object.Object, error) { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.GetRequest) - - // initialize request body - body := new(v2object.GetRequestBody) - req.SetBody(body) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: p.addr.ToV2(), - verb: v2session.ObjectVerbGet, - }); err != nil { - return nil, fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // fill body fields - body.SetAddress(p.addr.ToV2()) - body.SetRaw(p.raw) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return nil, fmt.Errorf("signing the request failed: %w", err) - } - - // open stream - stream, err := rpcapi.GetObject(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("stream opening failed: %w", err) - } - - var ( - headWas bool - payload []byte - obj = new(v2object.Object) - resp = new(v2object.GetResponse) - ) - -loop: - for { - // receive message from server stream - err := stream.Read(resp) - if err != nil { - if errors.Is(err, io.EOF) { - if !headWas { - return nil, io.ErrUnexpectedEOF - } - - break - } - - return nil, fmt.Errorf("reading the response failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return nil, fmt.Errorf("response verification failed: %w", err) - } - - switch v := resp.GetBody().GetObjectPart().(type) { - default: - return nil, fmt.Errorf("unexpected object part %T", v) - case *v2object.GetObjectPartInit: - if headWas { - return nil, errWrongMessageSeq - } - - headWas = true - - obj.SetObjectID(v.GetObjectID()) - obj.SetSignature(v.GetSignature()) - - hdr := v.GetHeader() - obj.SetHeader(hdr) - - if p.readerHandler != nil { - p.readerHandler(&objectPayloadReader{ - stream: stream, - }) - - break loop - } - - if p.w == nil { - payload = make([]byte, 0, hdr.GetPayloadLength()) - } - case *v2object.GetObjectPartChunk: - if !headWas { - return nil, errWrongMessageSeq - } - - if p.w != nil { - if _, err := p.w.Write(v.GetChunk()); err != nil { - return nil, fmt.Errorf("could not write payload chunk: %w", err) - } - } else { - payload = append(payload, v.GetChunk()...) - } - case *v2object.SplitInfo: - si := object.NewSplitInfoFromV2(v) - return nil, object.NewSplitInfoError(si) - } - } - - obj.SetPayload(payload) - - // convert the object - return object.NewFromV2(obj), nil -} - -func (p *ObjectHeaderParams) WithAddress(v *object.Address) *ObjectHeaderParams { - if p != nil { - p.addr = v - } - - return p -} - -func (p *ObjectHeaderParams) Address() *object.Address { - if p != nil { - return p.addr - } - - return nil -} - -func (p *ObjectHeaderParams) WithAllFields() *ObjectHeaderParams { - if p != nil { - p.short = false - } - - return p -} - -// AllFields return true if parameter set to return all header fields, returns -// false if parameter set to return only main fields of header. -func (p *ObjectHeaderParams) AllFields() bool { - if p != nil { - return !p.short - } - - return false -} - -func (p *ObjectHeaderParams) WithMainFields() *ObjectHeaderParams { - if p != nil { - p.short = true - } - - return p -} - -func (p *ObjectHeaderParams) WithRawFlag(v bool) *ObjectHeaderParams { - if p != nil { - p.raw = v - } - - return p -} - -func (p *ObjectHeaderParams) RawFlag() bool { - if p != nil { - return p.raw - } - - return false -} - -func (c *clientImpl) GetObjectHeader(ctx context.Context, p *ObjectHeaderParams, opts ...CallOption) (*object.Object, error) { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.HeadRequest) - - // initialize request body - body := new(v2object.HeadRequestBody) - req.SetBody(body) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: p.addr.ToV2(), - verb: v2session.ObjectVerbHead, - }); err != nil { - return nil, fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // fill body fields - body.SetAddress(p.addr.ToV2()) - body.SetMainOnly(p.short) - body.SetRaw(p.raw) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return nil, fmt.Errorf("signing the request failed: %w", err) - } - - // send Head request - resp, err := rpcapi.HeadObject(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("sending the request failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return nil, fmt.Errorf("response verification failed: %w", err) - } - - var ( - hdr *v2object.Header - idSig *v2refs.Signature - ) - - switch v := resp.GetBody().GetHeaderPart().(type) { - case nil: - return nil, fmt.Errorf("unexpected header type %T", v) - case *v2object.ShortHeader: - if !p.short { - return nil, fmt.Errorf("wrong header part type: expected %T, received %T", - (*v2object.ShortHeader)(nil), (*v2object.HeaderWithSignature)(nil), - ) - } - - h := v - - hdr = new(v2object.Header) - hdr.SetPayloadLength(h.GetPayloadLength()) - hdr.SetVersion(h.GetVersion()) - hdr.SetOwnerID(h.GetOwnerID()) - hdr.SetObjectType(h.GetObjectType()) - hdr.SetCreationEpoch(h.GetCreationEpoch()) - hdr.SetPayloadHash(h.GetPayloadHash()) - hdr.SetHomomorphicHash(h.GetHomomorphicHash()) - case *v2object.HeaderWithSignature: - if p.short { - return nil, fmt.Errorf("wrong header part type: expected %T, received %T", - (*v2object.HeaderWithSignature)(nil), (*v2object.ShortHeader)(nil), - ) - } - - hdrWithSig := v - if hdrWithSig == nil { - return nil, errNilObjectPart - } - - hdr = hdrWithSig.GetHeader() - idSig = hdrWithSig.GetSignature() - - if err := signer.VerifyDataWithSource( - signature.StableMarshalerWrapper{ - SM: p.addr.ObjectID().ToV2(), - }, - func() (key, sig []byte) { - return idSig.GetKey(), idSig.GetSign() - }, - ); err != nil { - return nil, fmt.Errorf("incorrect object header signature: %w", err) - } - case *v2object.SplitInfo: - si := object.NewSplitInfoFromV2(v) - - return nil, object.NewSplitInfoError(si) - } - - obj := new(v2object.Object) - obj.SetHeader(hdr) - obj.SetSignature(idSig) - - raw := object.NewRawFromV2(obj) - raw.SetID(p.addr.ObjectID()) - - // convert the object - return raw.Object(), nil -} - -func (p *RangeDataParams) WithAddress(v *object.Address) *RangeDataParams { - if p != nil { - p.addr = v - } - - return p -} - -func (p *RangeDataParams) Address() *object.Address { - if p != nil { - return p.addr - } - - return nil -} - -func (p *RangeDataParams) WithRaw(v bool) *RangeDataParams { - if p != nil { - p.raw = v - } - - return p -} - -func (p *RangeDataParams) Raw() bool { - if p != nil { - return p.raw - } - - return false -} - -func (p *RangeDataParams) WithRange(v *object.Range) *RangeDataParams { - if p != nil { - p.r = v - } - - return p -} - -func (p *RangeDataParams) Range() *object.Range { - if p != nil { - return p.r - } - - return nil -} - -func (p *RangeDataParams) WithDataWriter(v io.Writer) *RangeDataParams { - if p != nil { - p.w = v - } - - return p -} - -func (p *RangeDataParams) DataWriter() io.Writer { - if p != nil { - return p.w - } - - return nil -} - -func (c *clientImpl) ObjectPayloadRangeData(ctx context.Context, p *RangeDataParams, opts ...CallOption) ([]byte, error) { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.GetRangeRequest) - - // initialize request body - body := new(v2object.GetRangeRequestBody) - req.SetBody(body) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: p.addr.ToV2(), - verb: v2session.ObjectVerbRange, - }); err != nil { - return nil, fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // fill body fields - body.SetAddress(p.addr.ToV2()) - body.SetRange(p.r.ToV2()) - body.SetRaw(p.raw) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return nil, fmt.Errorf("signing the request failed: %w", err) - } - - // open stream - stream, err := rpcapi.GetObjectRange(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("could not create Get payload range stream: %w", err) - } - - var payload []byte - if p.w != nil { - payload = make([]byte, 0, p.r.GetLength()) - } - - resp := new(v2object.GetRangeResponse) - - for { - // receive message from server stream - err := stream.Read(resp) - if err != nil { - if errors.Is(err, io.EOF) { - break - } - - return nil, fmt.Errorf("reading the response failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return nil, fmt.Errorf("could not verify %T: %w", resp, err) - } - - switch v := resp.GetBody().GetRangePart().(type) { - case nil: - return nil, fmt.Errorf("unexpected range type %T", v) - case *v2object.GetRangePartChunk: - if p.w != nil { - if _, err = p.w.Write(v.GetChunk()); err != nil { - return nil, fmt.Errorf("could not write payload chunk: %w", err) - } - } else { - payload = append(payload, v.GetChunk()...) - } - case *v2object.SplitInfo: - si := object.NewSplitInfoFromV2(v) - - return nil, object.NewSplitInfoError(si) - } - } - - return payload, nil -} - -func (p *RangeChecksumParams) WithAddress(v *object.Address) *RangeChecksumParams { - if p != nil { - p.addr = v - } - - return p -} - -func (p *RangeChecksumParams) Address() *object.Address { - if p != nil { - return p.addr - } - - return nil -} - -func (p *RangeChecksumParams) WithRangeList(rs ...*object.Range) *RangeChecksumParams { - if p != nil { - p.rs = rs - } - - return p -} - -func (p *RangeChecksumParams) RangeList() []*object.Range { - if p != nil { - return p.rs - } - - return nil -} - -func (p *RangeChecksumParams) WithSalt(v []byte) *RangeChecksumParams { - if p != nil { - p.salt = v - } - - return p -} - -func (p *RangeChecksumParams) Salt() []byte { - if p != nil { - return p.salt - } - - return nil -} - -func (p *RangeChecksumParams) withChecksumType(t checksumType) *RangeChecksumParams { - if p != nil { - p.typ = t - } - - return p -} - -func (c *clientImpl) ObjectPayloadRangeSHA256(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) ([][sha256.Size]byte, error) { - res, err := c.objectPayloadRangeHash(ctx, p.withChecksumType(checksumSHA256), opts...) - if err != nil { - return nil, err - } - - return res.([][sha256.Size]byte), nil -} - -func (c *clientImpl) ObjectPayloadRangeTZ(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) ([][TZSize]byte, error) { - res, err := c.objectPayloadRangeHash(ctx, p.withChecksumType(checksumTZ), opts...) - if err != nil { - return nil, err - } - - return res.([][TZSize]byte), nil -} - -func (c *clientImpl) objectPayloadRangeHash(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) (interface{}, error) { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.GetRangeHashRequest) - - // initialize request body - body := new(v2object.GetRangeHashRequestBody) - req.SetBody(body) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: p.addr.ToV2(), - verb: v2session.ObjectVerbRangeHash, - }); err != nil { - return nil, fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // fill body fields - body.SetAddress(p.addr.ToV2()) - body.SetSalt(p.salt) - - typV2 := p.typ.toV2() - body.SetType(typV2) - - rsV2 := rangesToV2(p.rs) - body.SetRanges(rsV2) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return nil, fmt.Errorf("signing the request failed: %w", err) - } - - // send request - resp, err := rpcapi.HashObjectRange(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("sending the request failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return nil, fmt.Errorf("response verification failed: %w", err) - } - - respBody := resp.GetBody() - respType := respBody.GetType() - respHashes := respBody.GetHashList() - - if t := p.typ.toV2(); respType != t { - return nil, fmt.Errorf("invalid checksum type: expected %v, received %v", t, respType) - } else if reqLn, respLn := len(rsV2), len(respHashes); reqLn != respLn { - return nil, fmt.Errorf("wrong checksum number: expected %d, received %d", reqLn, respLn) - } - - var res interface{} - - switch p.typ { - case checksumSHA256: - r := make([][sha256.Size]byte, 0, len(respHashes)) - - for i := range respHashes { - if ln := len(respHashes[i]); ln != sha256.Size { - return nil, fmt.Errorf("invalid checksum length: expected %d, received %d", sha256.Size, ln) - } - - cs := [sha256.Size]byte{} - copy(cs[:], respHashes[i]) - - r = append(r, cs) - } - - res = r - case checksumTZ: - r := make([][TZSize]byte, 0, len(respHashes)) - - for i := range respHashes { - if ln := len(respHashes[i]); ln != TZSize { - return nil, fmt.Errorf("invalid checksum length: expected %d, received %d", TZSize, ln) - } - - cs := [TZSize]byte{} - copy(cs[:], respHashes[i]) - - r = append(r, cs) - } - - res = r - } - - return res, nil -} - -func (p *SearchObjectParams) WithContainerID(v *cid.ID) *SearchObjectParams { - if p != nil { - p.cid = v - } - - return p -} - -func (p *SearchObjectParams) ContainerID() *cid.ID { - if p != nil { - return p.cid - } - - return nil -} - -func (p *SearchObjectParams) WithSearchFilters(v object.SearchFilters) *SearchObjectParams { - if p != nil { - p.filters = v - } - - return p -} - -func (p *SearchObjectParams) SearchFilters() object.SearchFilters { - if p != nil { - return p.filters - } - - return nil -} - -func (c *clientImpl) SearchObject(ctx context.Context, p *SearchObjectParams, opts ...CallOption) ([]*object.ID, error) { - callOpts := c.defaultCallOptions() - - for i := range opts { - if opts[i] != nil { - opts[i](callOpts) - } - } - - // create request - req := new(v2object.SearchRequest) - - // initialize request body - body := new(v2object.SearchRequestBody) - req.SetBody(body) - - v2Addr := new(v2refs.Address) - v2Addr.SetContainerID(p.cid.ToV2()) - - // set meta header - meta := v2MetaHeaderFromOpts(callOpts) - - if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{ - addr: v2Addr, - verb: v2session.ObjectVerbSearch, - }); err != nil { - return nil, fmt.Errorf("could not attach session token: %w", err) - } - - req.SetMetaHeader(meta) - - // fill body fields - body.SetContainerID(v2Addr.GetContainerID()) - body.SetVersion(searchQueryVersion) - body.SetFilters(p.filters.ToV2()) - - // sign the request - if err := signature.SignServiceMessage(callOpts.key, req); err != nil { - return nil, fmt.Errorf("signing the request failed: %w", err) - } - - // create search stream - stream, err := rpcapi.SearchObjects(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("stream opening failed: %w", err) - } - - var ( - searchResult []*object.ID - resp = new(v2object.SearchResponse) - ) - - for { - // receive message from server stream - err := stream.Read(resp) - if err != nil { - if errors.Is(err, io.EOF) { - break - } - - return nil, fmt.Errorf("reading the response failed: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOpts, resp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(resp); err != nil { - return nil, fmt.Errorf("could not verify %T: %w", resp, err) - } - - chunk := resp.GetBody().GetIDList() - for i := range chunk { - searchResult = append(searchResult, object.NewIDFromV2(chunk[i])) - } - } - - return searchResult, nil -} - -func (c *clientImpl) attachV2SessionToken(opts *callOptions, hdr *v2session.RequestMetaHeader, info v2SessionReqInfo) error { - if opts.session == nil { - return nil - } - - // Do not resign already prepared session token - if opts.session.Signature() != nil { - hdr.SetSessionToken(opts.session.ToV2()) - return nil - } - - opCtx := new(v2session.ObjectSessionContext) - opCtx.SetAddress(info.addr) - opCtx.SetVerb(info.verb) - - lt := new(v2session.TokenLifetime) - lt.SetIat(info.iat) - lt.SetNbf(info.nbf) - lt.SetExp(info.exp) - - body := new(v2session.SessionTokenBody) - body.SetID(opts.session.ID()) - body.SetOwnerID(opts.session.OwnerID().ToV2()) - body.SetSessionKey(opts.session.SessionKey()) - body.SetContext(opCtx) - body.SetLifetime(lt) - - token := new(v2session.SessionToken) - token.SetBody(body) - - signWrapper := signature.StableMarshalerWrapper{SM: token.GetBody()} - - err := signer.SignDataWithHandler(opts.key, signWrapper, func(key []byte, sig []byte) { - sessionTokenSignature := new(v2refs.Signature) - sessionTokenSignature.SetKey(key) - sessionTokenSignature.SetSign(sig) - token.SetSignature(sessionTokenSignature) - }) - if err != nil { - return err - } - - hdr.SetSessionToken(token) - - return nil -} diff --git a/pkg/client/object_test.go b/pkg/client/object_test.go deleted file mode 100644 index 4c7d296..0000000 --- a/pkg/client/object_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package client - -import ( - "io" - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/nspcc-dev/neofs-api-go/v2/signature" - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -type singleResponseStream struct { - called bool - resp object.GetResponse -} - -func (x *singleResponseStream) Read(r *object.GetResponse) error { - if x.called { - return io.EOF - } - - x.called = true - - *r = x.resp - - return nil -} - -var key = test.DecodeKey(0) - -func chunkResponse(c []byte) (r object.GetResponse) { - chunkPart := new(object.GetObjectPartChunk) - chunkPart.SetChunk(c) - - body := new(object.GetResponseBody) - body.SetObjectPart(chunkPart) - - r.SetBody(body) - - if err := signature.SignServiceMessage(key, &r); err != nil { - panic(err) - } - - return -} - -func data(sz int) []byte { - data := make([]byte, sz) - - for i := range data { - data[i] = byte(i) % ^byte(0) - } - - return data -} - -func checkFullRead(t *testing.T, r io.Reader, buf, payload []byte) { - var ( - restored []byte - read int - ) - - for { - n, err := r.Read(buf) - - read += n - restored = append(restored, buf[:n]...) - - if err != nil { - require.Equal(t, err, io.EOF) - break - - } - } - - require.Equal(t, payload, restored) - require.EqualValues(t, len(payload), read) -} - -func TestObjectPayloadReader_Read(t *testing.T) { - t.Run("read with tail", func(t *testing.T) { - payload := data(10) - - buf := make([]byte, len(payload)-1) - - var r io.Reader = &objectPayloadReader{ - stream: &singleResponseStream{ - resp: chunkResponse(payload), - }, - } - - checkFullRead(t, r, buf, payload) - }) -} diff --git a/pkg/client/opts.go b/pkg/client/opts.go deleted file mode 100644 index af9cedf..0000000 --- a/pkg/client/opts.go +++ /dev/null @@ -1,189 +0,0 @@ -package client - -import ( - "crypto/ecdsa" - "crypto/tls" - "time" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - "github.com/nspcc-dev/neofs-api-go/pkg/token" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - v2session "github.com/nspcc-dev/neofs-api-go/v2/session" - "google.golang.org/grpc" -) - -type ( - CallOption func(*callOptions) - - Option func(*clientOptions) - - callOptions struct { - version *pkg.Version - xHeaders []*pkg.XHeader - ttl uint32 - epoch uint64 - key *ecdsa.PrivateKey - session *session.Token - bearer *token.BearerToken - } - - clientOptions struct { - key *ecdsa.PrivateKey - - rawOpts []client.Option - - cbRespInfo func(ResponseMetaInfo) error - } - - v2SessionReqInfo struct { - addr *refs.Address - verb v2session.ObjectSessionVerb - - exp, nbf, iat uint64 - } -) - -func (c *clientImpl) defaultCallOptions() *callOptions { - return &callOptions{ - version: pkg.SDKVersion(), - ttl: 2, - key: c.opts.key, - } -} - -func WithXHeader(x *pkg.XHeader) CallOption { - return func(opts *callOptions) { - opts.xHeaders = append(opts.xHeaders, x) - } -} - -func WithTTL(ttl uint32) CallOption { - return func(opts *callOptions) { - opts.ttl = ttl - } -} - -// WithKey sets client's key for the next request. -func WithKey(key *ecdsa.PrivateKey) CallOption { - return func(opts *callOptions) { - opts.key = key - } -} - -func WithEpoch(epoch uint64) CallOption { - return func(opts *callOptions) { - opts.epoch = epoch - } -} - -func WithSession(token *session.Token) CallOption { - return func(opts *callOptions) { - opts.session = token - } -} - -func WithBearer(token *token.BearerToken) CallOption { - return func(opts *callOptions) { - opts.bearer = token - } -} - -func v2MetaHeaderFromOpts(options *callOptions) *v2session.RequestMetaHeader { - meta := new(v2session.RequestMetaHeader) - meta.SetVersion(options.version.ToV2()) - meta.SetTTL(options.ttl) - meta.SetEpoch(options.epoch) - - xhdrs := make([]*v2session.XHeader, len(options.xHeaders)) - for i := range options.xHeaders { - xhdrs[i] = options.xHeaders[i].ToV2() - } - - meta.SetXHeaders(xhdrs) - - if options.bearer != nil { - meta.SetBearerToken(options.bearer.ToV2()) - } - - meta.SetSessionToken(options.session.ToV2()) - - return meta -} - -func defaultClientOptions() *clientOptions { - return &clientOptions{ - rawOpts: make([]client.Option, 0, 4), - } -} - -// WithAddress returns option to specify -// network address of the remote server. -// -// Ignored if WithGRPCConnection is provided. -func WithAddress(addr string) Option { - return func(opts *clientOptions) { - opts.rawOpts = append(opts.rawOpts, client.WithNetworkAddress(addr)) - } -} - -// WithDialTimeout returns option to set connection timeout to the remote node. -// -// Ignored if WithGRPCConn is provided. -func WithDialTimeout(dur time.Duration) Option { - return func(opts *clientOptions) { - opts.rawOpts = append(opts.rawOpts, client.WithDialTimeout(dur)) - } -} - -// WithTLSConfig returns option to set connection's TLS config to the remote node. -// -// Ignored if WithGRPCConnection is provided. -func WithTLSConfig(cfg *tls.Config) Option { - return func(opts *clientOptions) { - opts.rawOpts = append(opts.rawOpts, client.WithTLSCfg(cfg)) - } -} - -// WithDefaultPrivateKey returns option to set default private key -// used for the work. -func WithDefaultPrivateKey(key *ecdsa.PrivateKey) Option { - return func(opts *clientOptions) { - opts.key = key - } -} - -// WithURIAddress returns option to specify -// network address of a remote server and connection -// scheme for it. -// -// Format of the URI: -// -// [scheme://]host:port -// -// Supported schemes: -// - grpc; -// - grpcs. -// -// tls.Cfg second argument is optional and is taken into -// account only in case of `grpcs` scheme. -// -// Falls back to WithNetworkAddress if address is not a valid URI. -// -// Do not use along with WithAddress and WithTLSConfig. -// -// Ignored if WithGRPCConnection is provided. -func WithURIAddress(addr string, tlsCfg *tls.Config) Option { - return func(opts *clientOptions) { - opts.rawOpts = append(opts.rawOpts, client.WithNetworkURIAddress(addr, tlsCfg)...) - } -} - -// WithGRPCConnection returns option to set GRPC connection to -// the remote node. -func WithGRPCConnection(grpcConn *grpc.ClientConn) Option { - return func(opts *clientOptions) { - opts.rawOpts = append(opts.rawOpts, client.WithGRPCConn(grpcConn)) - } -} diff --git a/pkg/client/raw.go b/pkg/client/raw.go deleted file mode 100644 index aebe143..0000000 --- a/pkg/client/raw.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "io" - - "github.com/nspcc-dev/neofs-api-go/rpc/client" -) - -// Raw returns underlying raw protobuf client. -func (c *clientImpl) Raw() *client.Client { - c.onceInit.Do(func() { - c.raw = client.New(c.opts.rawOpts...) - }) - - return c.raw -} - -// implements Client.Conn method. -func (c *clientImpl) Conn() io.Closer { - return c.raw.Conn() -} diff --git a/pkg/client/reputation.go b/pkg/client/reputation.go deleted file mode 100644 index ff82496..0000000 --- a/pkg/client/reputation.go +++ /dev/null @@ -1,171 +0,0 @@ -package client - -import ( - "context" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg/reputation" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - v2reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Reputation contains methods for working with Reputation system values. -type Reputation interface { - // AnnounceLocalTrust announces local trust values of local peer. - AnnounceLocalTrust(context.Context, AnnounceLocalTrustPrm, ...CallOption) (*AnnounceLocalTrustRes, error) - - // AnnounceIntermediateTrust announces the intermediate result of the iterative algorithm for calculating - // the global reputation of the node. - AnnounceIntermediateTrust(context.Context, AnnounceIntermediateTrustPrm, ...CallOption) (*AnnounceIntermediateTrustRes, error) -} - -// AnnounceLocalTrustPrm groups parameters of AnnounceLocalTrust operation. -type AnnounceLocalTrustPrm struct { - epoch uint64 - - trusts []*reputation.Trust -} - -// Epoch returns epoch in which the trust was assessed. -func (x AnnounceLocalTrustPrm) Epoch() uint64 { - return x.epoch -} - -// SetEpoch sets epoch in which the trust was assessed. -func (x *AnnounceLocalTrustPrm) SetEpoch(epoch uint64) { - x.epoch = epoch -} - -// Trusts returns list of local trust values. -func (x AnnounceLocalTrustPrm) Trusts() []*reputation.Trust { - return x.trusts -} - -// SetTrusts sets list of local trust values. -func (x *AnnounceLocalTrustPrm) SetTrusts(trusts []*reputation.Trust) { - x.trusts = trusts -} - -// AnnounceLocalTrustRes groups results of AnnounceLocalTrust operation. -type AnnounceLocalTrustRes struct{} - -func (c *clientImpl) AnnounceLocalTrust(ctx context.Context, prm AnnounceLocalTrustPrm, opts ...CallOption) (*AnnounceLocalTrustRes, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2reputation.AnnounceLocalTrustRequestBody) - reqBody.SetEpoch(prm.Epoch()) - reqBody.SetTrusts(reputation.TrustsToV2(prm.Trusts())) - - req := new(v2reputation.AnnounceLocalTrustRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.AnnounceLocalTrust(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, err - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - return new(AnnounceLocalTrustRes), nil -} - -// AnnounceIntermediateTrustPrm groups parameters of AnnounceIntermediateTrust operation. -type AnnounceIntermediateTrustPrm struct { - epoch uint64 - - iter uint32 - - trust *reputation.PeerToPeerTrust -} - -func (x *AnnounceIntermediateTrustPrm) Epoch() uint64 { - return x.epoch -} - -func (x *AnnounceIntermediateTrustPrm) SetEpoch(epoch uint64) { - x.epoch = epoch -} - -// Iteration returns sequence number of the iteration. -func (x AnnounceIntermediateTrustPrm) Iteration() uint32 { - return x.iter -} - -// SetIteration sets sequence number of the iteration. -func (x *AnnounceIntermediateTrustPrm) SetIteration(iter uint32) { - x.iter = iter -} - -// Trust returns current global trust value computed at the specified iteration. -func (x AnnounceIntermediateTrustPrm) Trust() *reputation.PeerToPeerTrust { - return x.trust -} - -// SetTrust sets current global trust value computed at the specified iteration. -func (x *AnnounceIntermediateTrustPrm) SetTrust(trust *reputation.PeerToPeerTrust) { - x.trust = trust -} - -// AnnounceIntermediateTrustRes groups results of AnnounceIntermediateTrust operation. -type AnnounceIntermediateTrustRes struct{} - -func (c *clientImpl) AnnounceIntermediateTrust(ctx context.Context, prm AnnounceIntermediateTrustPrm, opts ...CallOption) (*AnnounceIntermediateTrustRes, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - reqBody := new(v2reputation.AnnounceIntermediateResultRequestBody) - reqBody.SetEpoch(prm.Epoch()) - reqBody.SetIteration(prm.Iteration()) - reqBody.SetTrust(prm.Trust().ToV2()) - - req := new(v2reputation.AnnounceIntermediateResultRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err := v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.AnnounceIntermediateResult(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, err - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - return new(AnnounceIntermediateTrustRes), nil -} diff --git a/pkg/client/response.go b/pkg/client/response.go deleted file mode 100644 index 6948844..0000000 --- a/pkg/client/response.go +++ /dev/null @@ -1,37 +0,0 @@ -package client - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/session" -) - -// ResponseMetaInfo groups meta information about any NeoFS API response. -type ResponseMetaInfo struct { - key []byte -} - -// ResponderKey returns responder's public key in a binary format. -// -// Result must not be mutated. -func (x ResponseMetaInfo) ResponderKey() []byte { - return x.key -} - -// WithResponseInfoHandler allows to specify handler of response meta information for the all Client operations. -// The handler is called right after the response is received. Client returns handler's error immediately. -func WithResponseInfoHandler(f func(ResponseMetaInfo) error) Option { - return func(opts *clientOptions) { - opts.cbRespInfo = f - } -} - -func (c *clientImpl) handleResponseInfoV2(opts *callOptions, resp interface { - GetVerificationHeader() *session.ResponseVerificationHeader -}) error { - if c.opts.cbRespInfo == nil { - return nil - } - - return c.opts.cbRespInfo(ResponseMetaInfo{ - key: resp.GetVerificationHeader().GetBodySignature().GetKey(), - }) -} diff --git a/pkg/client/session.go b/pkg/client/session.go deleted file mode 100644 index 46ec399..0000000 --- a/pkg/client/session.go +++ /dev/null @@ -1,79 +0,0 @@ -package client - -import ( - "context" - "errors" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - "github.com/nspcc-dev/neofs-api-go/rpc/client" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" - v2session "github.com/nspcc-dev/neofs-api-go/v2/session" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Session contains session-related methods. -type Session interface { - // CreateSession creates session using provided expiration time. - CreateSession(context.Context, uint64, ...CallOption) (*session.Token, error) -} - -var errMalformedResponseBody = errors.New("malformed response body") - -func (c *clientImpl) CreateSession(ctx context.Context, expiration uint64, opts ...CallOption) (*session.Token, error) { - // apply all available options - callOptions := c.defaultCallOptions() - - for i := range opts { - opts[i](callOptions) - } - - w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey) - if err != nil { - return nil, err - } - - ownerID := new(owner.ID) - ownerID.SetNeo3Wallet(w) - - reqBody := new(v2session.CreateRequestBody) - reqBody.SetOwnerID(ownerID.ToV2()) - reqBody.SetExpiration(expiration) - - req := new(v2session.CreateRequest) - req.SetBody(reqBody) - req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions)) - - err = v2signature.SignServiceMessage(callOptions.key, req) - if err != nil { - return nil, err - } - - resp, err := rpcapi.CreateSession(c.Raw(), req, client.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("transport error: %w", err) - } - - // handle response meta info - if err := c.handleResponseInfoV2(callOptions, resp); err != nil { - return nil, err - } - - err = v2signature.VerifyServiceMessage(resp) - if err != nil { - return nil, fmt.Errorf("can't verify response message: %w", err) - } - - body := resp.GetBody() - if body == nil { - return nil, errMalformedResponseBody - } - - sessionToken := session.NewToken() - sessionToken.SetID(body.GetID()) - sessionToken.SetSessionKey(body.GetSessionKey()) - sessionToken.SetOwnerID(ownerID) - - return sessionToken, nil -} diff --git a/pkg/container/announcement.go b/pkg/container/announcement.go deleted file mode 100644 index cfa9510..0000000 --- a/pkg/container/announcement.go +++ /dev/null @@ -1,87 +0,0 @@ -package container - -import ( - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/v2/container" -) - -// UsedSpaceAnnouncement is an announcement message used by storage nodes to -// estimate actual container sizes. -type UsedSpaceAnnouncement container.UsedSpaceAnnouncement - -// NewAnnouncement initialize empty UsedSpaceAnnouncement message. -// -// Defaults: -// - epoch: 0; -// - usedSpace: 0; -// - cid: nil. -func NewAnnouncement() *UsedSpaceAnnouncement { - return NewAnnouncementFromV2(new(container.UsedSpaceAnnouncement)) -} - -// NewAnnouncementFromV2 wraps protocol dependent version of -// UsedSpaceAnnouncement message. -// -// Nil container.UsedSpaceAnnouncement converts to nil. -func NewAnnouncementFromV2(v *container.UsedSpaceAnnouncement) *UsedSpaceAnnouncement { - return (*UsedSpaceAnnouncement)(v) -} - -// Epoch of the announcement. -func (a *UsedSpaceAnnouncement) Epoch() uint64 { - return (*container.UsedSpaceAnnouncement)(a).GetEpoch() -} - -// SetEpoch sets announcement epoch value. -func (a *UsedSpaceAnnouncement) SetEpoch(epoch uint64) { - (*container.UsedSpaceAnnouncement)(a).SetEpoch(epoch) -} - -// ContainerID of the announcement. -func (a *UsedSpaceAnnouncement) ContainerID() *cid.ID { - return cid.NewFromV2( - (*container.UsedSpaceAnnouncement)(a).GetContainerID(), - ) -} - -// SetContainerID sets announcement container value. -func (a *UsedSpaceAnnouncement) SetContainerID(cid *cid.ID) { - (*container.UsedSpaceAnnouncement)(a).SetContainerID(cid.ToV2()) -} - -// UsedSpace in container. -func (a *UsedSpaceAnnouncement) UsedSpace() uint64 { - return (*container.UsedSpaceAnnouncement)(a).GetUsedSpace() -} - -// SetUsedSpace sets used space value by specified container. -func (a *UsedSpaceAnnouncement) SetUsedSpace(value uint64) { - (*container.UsedSpaceAnnouncement)(a).SetUsedSpace(value) -} - -// ToV2 returns protocol dependent version of UsedSpaceAnnouncement message. -// -// Nil UsedSpaceAnnouncement converts to nil. -func (a *UsedSpaceAnnouncement) ToV2() *container.UsedSpaceAnnouncement { - return (*container.UsedSpaceAnnouncement)(a) -} - -// Marshal marshals UsedSpaceAnnouncement into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (a *UsedSpaceAnnouncement) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return a.ToV2(). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of UsedSpaceAnnouncement. -func (a *UsedSpaceAnnouncement) Unmarshal(data []byte) error { - return a.ToV2(). - Unmarshal(data) -} diff --git a/pkg/container/announcement_test.go b/pkg/container/announcement_test.go deleted file mode 100644 index dc669b8..0000000 --- a/pkg/container/announcement_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package container_test - -import ( - "crypto/sha256" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/container" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - containertest "github.com/nspcc-dev/neofs-api-go/pkg/container/test" - containerv2 "github.com/nspcc-dev/neofs-api-go/v2/container" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func TestAnnouncement(t *testing.T) { - const epoch, usedSpace uint64 = 10, 100 - - cidValue := [sha256.Size]byte{1, 2, 3} - id := cidtest.GenerateWithChecksum(cidValue) - - a := container.NewAnnouncement() - a.SetEpoch(epoch) - a.SetContainerID(id) - a.SetUsedSpace(usedSpace) - - require.Equal(t, epoch, a.Epoch()) - require.Equal(t, usedSpace, a.UsedSpace()) - require.Equal(t, id, a.ContainerID()) - - t.Run("test v2", func(t *testing.T) { - const newEpoch, newUsedSpace uint64 = 20, 200 - - newCidValue := [32]byte{4, 5, 6} - newCID := new(refs.ContainerID) - newCID.SetValue(newCidValue[:]) - - v2 := a.ToV2() - require.Equal(t, usedSpace, v2.GetUsedSpace()) - require.Equal(t, epoch, v2.GetEpoch()) - require.Equal(t, cidValue[:], v2.GetContainerID().GetValue()) - - v2.SetEpoch(newEpoch) - v2.SetUsedSpace(newUsedSpace) - v2.SetContainerID(newCID) - - newA := container.NewAnnouncementFromV2(v2) - - require.Equal(t, newEpoch, newA.Epoch()) - require.Equal(t, newUsedSpace, newA.UsedSpace()) - require.Equal(t, cid.NewFromV2(newCID), newA.ContainerID()) - }) -} - -func TestUsedSpaceEncoding(t *testing.T) { - a := containertest.UsedSpaceAnnouncement() - - t.Run("binary", func(t *testing.T) { - data, err := a.Marshal() - require.NoError(t, err) - - a2 := container.NewAnnouncement() - require.NoError(t, a2.Unmarshal(data)) - - require.Equal(t, a, a2) - }) -} - -func TestUsedSpaceAnnouncement_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *container.UsedSpaceAnnouncement - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - announcement := container.NewAnnouncement() - - // check initial values - require.Zero(t, announcement.Epoch()) - require.Zero(t, announcement.UsedSpace()) - require.Nil(t, announcement.ContainerID()) - - // convert to v2 message - announcementV2 := announcement.ToV2() - - require.Zero(t, announcementV2.GetEpoch()) - require.Zero(t, announcementV2.GetUsedSpace()) - require.Nil(t, announcementV2.GetContainerID()) - }) -} - -func TestNewAnnouncementFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *containerv2.UsedSpaceAnnouncement - - require.Nil(t, container.NewAnnouncementFromV2(x)) - }) -} diff --git a/pkg/container/attribute.go b/pkg/container/attribute.go deleted file mode 100644 index fc87062..0000000 --- a/pkg/container/attribute.go +++ /dev/null @@ -1,137 +0,0 @@ -package container - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/container" -) - -type ( - Attribute container.Attribute - Attributes []*Attribute -) - -// NewAttribute creates and initializes blank Attribute. -// -// Defaults: -// - key: ""; -// - value: "". -func NewAttribute() *Attribute { - return NewAttributeFromV2(new(container.Attribute)) -} - -func (a *Attribute) SetKey(v string) { - (*container.Attribute)(a).SetKey(v) -} - -func (a *Attribute) SetValue(v string) { - (*container.Attribute)(a).SetValue(v) -} - -func (a *Attribute) Key() string { - return (*container.Attribute)(a).GetKey() -} - -func (a *Attribute) Value() string { - return (*container.Attribute)(a).GetValue() -} - -// NewAttributeFromV2 wraps protocol dependent version of -// Attribute message. -// -// Nil container.Attribute converts to nil. -func NewAttributeFromV2(v *container.Attribute) *Attribute { - return (*Attribute)(v) -} - -// ToV2 converts Attribute to v2 Attribute message. -// -// Nil Attribute converts to nil. -func (a *Attribute) ToV2() *container.Attribute { - return (*container.Attribute)(a) -} - -func NewAttributesFromV2(v []*container.Attribute) Attributes { - if v == nil { - return nil - } - - attrs := make(Attributes, 0, len(v)) - for i := range v { - attrs = append(attrs, NewAttributeFromV2(v[i])) - } - - return attrs -} - -func (a Attributes) ToV2() []*container.Attribute { - if a == nil { - return nil - } - - attrs := make([]*container.Attribute, 0, len(a)) - for i := range a { - attrs = append(attrs, a[i].ToV2()) - } - - return attrs -} - -// sets value of the attribute by key. -func setAttribute(c *Container, key, value string) { - var a *Attribute - - iterateAttributes(c, func(a_ *Attribute) bool { - if a_.Key() == key { - a = a_ - } - - return a != nil - }) - - if a == nil { - a = NewAttribute() - a.SetKey(key) - - c.SetAttributes(append(c.Attributes(), a)) - } - - a.SetValue(value) -} - -// iterates over container attributes. Stops at f's true return. -// -// Handler must not be nil. -func iterateAttributes(c *Container, f func(*Attribute) bool) { - for _, a := range c.Attributes() { - if f(a) { - return - } - } -} - -// SetNativeNameWithZone sets container native name and its zone. -// -// Use SetNativeName to set default zone. -func SetNativeNameWithZone(c *Container, name, zone string) { - setAttribute(c, container.SysAttributeName, name) - setAttribute(c, container.SysAttributeZone, zone) -} - -// SetNativeName sets container native name with default zone (container). -func SetNativeName(c *Container, name string) { - SetNativeNameWithZone(c, name, container.SysAttributeZoneDefault) -} - -// GetNativeNameWithZone returns container native name and its zone. -func GetNativeNameWithZone(c *Container) (name string, zone string) { - iterateAttributes(c, func(a *Attribute) bool { - if key := a.Key(); key == container.SysAttributeName { - name = a.Value() - } else if key == container.SysAttributeZone { - zone = a.Value() - } - - return name != "" && zone != "" - }) - - return -} diff --git a/pkg/container/attribute_test.go b/pkg/container/attribute_test.go deleted file mode 100644 index 4078c64..0000000 --- a/pkg/container/attribute_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package container_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/container" - containerv2 "github.com/nspcc-dev/neofs-api-go/v2/container" - "github.com/stretchr/testify/require" -) - -func TestAttribute(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *container.Attribute - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - attr := container.NewAttribute() - - // check initial values - require.Empty(t, attr.Key()) - require.Empty(t, attr.Value()) - - // convert to v2 message - attrV2 := attr.ToV2() - require.Empty(t, attrV2.GetKey()) - require.Empty(t, attrV2.GetValue()) - }) - - const ( - key = "key" - value = "value" - ) - - attr := container.NewAttribute() - attr.SetKey(key) - attr.SetValue(value) - - require.Equal(t, key, attr.Key()) - require.Equal(t, value, attr.Value()) - - t.Run("test v2", func(t *testing.T) { - const ( - newKey = "newKey" - newValue = "newValue" - ) - - v2 := attr.ToV2() - require.Equal(t, key, v2.GetKey()) - require.Equal(t, value, v2.GetValue()) - - v2.SetKey(newKey) - v2.SetValue(newValue) - - newAttr := container.NewAttributeFromV2(v2) - - require.Equal(t, newKey, newAttr.Key()) - require.Equal(t, newValue, newAttr.Value()) - }) -} - -func TestAttributes(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x container.Attributes - - require.Nil(t, x.ToV2()) - - require.Nil(t, container.NewAttributesFromV2(nil)) - }) - - var ( - keys = []string{"key1", "key2", "key3"} - vals = []string{"val1", "val2", "val3"} - ) - - attrs := make(container.Attributes, 0, len(keys)) - - for i := range keys { - attr := container.NewAttribute() - attr.SetKey(keys[i]) - attr.SetValue(vals[i]) - - attrs = append(attrs, attr) - } - - t.Run("test v2", func(t *testing.T) { - const postfix = "x" - - v2 := attrs.ToV2() - require.Len(t, v2, len(keys)) - - for i := range v2 { - k := v2[i].GetKey() - v := v2[i].GetValue() - - require.Equal(t, keys[i], k) - require.Equal(t, vals[i], v) - - v2[i].SetKey(k + postfix) - v2[i].SetValue(v + postfix) - } - - newAttrs := container.NewAttributesFromV2(v2) - require.Len(t, newAttrs, len(keys)) - - for i := range newAttrs { - require.Equal(t, keys[i]+postfix, newAttrs[i].Key()) - require.Equal(t, vals[i]+postfix, newAttrs[i].Value()) - } - }) -} - -func TestNewAttributeFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *containerv2.Attribute - - require.Nil(t, container.NewAttributeFromV2(x)) - }) -} - -func TestGetNameWithZone(t *testing.T) { - c := container.New() - - for _, item := range [...]struct { - name, zone string - }{ - {"name1", ""}, - {"name1", "zone1"}, - {"name2", "zone1"}, - {"name2", "zone2"}, - {"", "zone2"}, - {"", ""}, - } { - container.SetNativeNameWithZone(c, item.name, item.zone) - - name, zone := container.GetNativeNameWithZone(c) - - require.Equal(t, item.name, name, item.name) - require.Equal(t, item.zone, zone, item.zone) - } -} - -func TestSetNativeName(t *testing.T) { - c := container.New() - - const nameDefZone = "some name" - - container.SetNativeName(c, nameDefZone) - - name, zone := container.GetNativeNameWithZone(c) - - require.Equal(t, nameDefZone, name) - require.Equal(t, containerv2.SysAttributeZoneDefault, zone) -} diff --git a/pkg/container/container.go b/pkg/container/container.go deleted file mode 100644 index 7ae7fe4..0000000 --- a/pkg/container/container.go +++ /dev/null @@ -1,231 +0,0 @@ -package container - -import ( - "crypto/sha256" - - "github.com/google/uuid" - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - "github.com/nspcc-dev/neofs-api-go/v2/container" -) - -type Container struct { - v2 container.Container - - token *session.Token - - sig *pkg.Signature -} - -// New creates, initializes and returns blank Container instance. -// -// Defaults: -// - token: nil; -// - sig: nil; -// - basicACL: acl.PrivateBasicRule; -// - version: nil; -// - nonce: random UUID; -// - attr: nil; -// - policy: nil; -// - ownerID: nil. -func New(opts ...NewOption) *Container { - cnrOptions := defaultContainerOptions() - - for i := range opts { - opts[i].apply(&cnrOptions) - } - - cnr := new(Container) - cnr.SetNonceUUID(cnrOptions.nonce) - cnr.SetBasicACL(cnrOptions.acl) - - if cnrOptions.owner != nil { - cnr.SetOwnerID(cnrOptions.owner) - } - - if cnrOptions.policy != nil { - cnr.SetPlacementPolicy(cnrOptions.policy) - } - - cnr.SetAttributes(cnrOptions.attributes) - - return cnr -} - -// ToV2 returns the v2 Container message. -// -// Nil Container converts to nil. -func (c *Container) ToV2() *container.Container { - if c == nil { - return nil - } - - return &c.v2 -} - -// NewVerifiedFromV2 constructs Container from NeoFS API V2 Container message. -// -// Does not perform if message meets NeoFS API V2 specification. To do this -// use NewVerifiedFromV2 constructor. -func NewContainerFromV2(c *container.Container) *Container { - cnr := new(Container) - - if c != nil { - cnr.v2 = *c - } - - return cnr -} - -// CalculateID calculates container identifier -// based on its structure. -func CalculateID(c *Container) *cid.ID { - data, err := c.ToV2().StableMarshal(nil) - if err != nil { - panic(err) - } - - id := cid.New() - id.SetSHA256(sha256.Sum256(data)) - - return id -} - -func (c *Container) Version() *pkg.Version { - return pkg.NewVersionFromV2(c.v2.GetVersion()) -} - -func (c *Container) SetVersion(v *pkg.Version) { - c.v2.SetVersion(v.ToV2()) -} - -func (c *Container) OwnerID() *owner.ID { - return owner.NewIDFromV2(c.v2.GetOwnerID()) -} - -func (c *Container) SetOwnerID(v *owner.ID) { - c.v2.SetOwnerID(v.ToV2()) -} - -// Nonce returns container nonce in a binary format. -// -// Returns nil if container nonce is not a valid UUID. -// -// Deprecated: use NonceUUID instead. -func (c *Container) Nonce() []byte { - uid, err := c.NonceUUID() - if err == nil { - data, _ := uid.MarshalBinary() - return data - } - - return nil -} - -// SetNonce sets container nonce in a binary format. -// -// If slice length is less than UUID size, than -// value is padded with a sequence of zeros. -// If slice length is more than UUID size, than -// value is cut. -// -// Deprecated: use SetNonceUUID instead. -func (c *Container) SetNonce(v []byte) { - u := uuid.UUID{} - copy(u[:], v) - c.v2.SetNonce(u[:]) -} - -// Returns container nonce in UUID format. -// -// Returns error if container nonce is not a valid UUID. -func (c *Container) NonceUUID() (uuid.UUID, error) { - return uuid.FromBytes(c.v2.GetNonce()) -} - -// SetNonceUUID sets container nonce as UUID. -func (c *Container) SetNonceUUID(v uuid.UUID) { - data, _ := v.MarshalBinary() - c.v2.SetNonce(data) -} - -func (c *Container) BasicACL() uint32 { - return c.v2.GetBasicACL() -} - -func (c *Container) SetBasicACL(v uint32) { - c.v2.SetBasicACL(v) -} - -func (c *Container) Attributes() Attributes { - return NewAttributesFromV2(c.v2.GetAttributes()) -} - -func (c *Container) SetAttributes(v Attributes) { - c.v2.SetAttributes(v.ToV2()) -} - -func (c *Container) PlacementPolicy() *netmap.PlacementPolicy { - return netmap.NewPlacementPolicyFromV2(c.v2.GetPlacementPolicy()) -} - -func (c *Container) SetPlacementPolicy(v *netmap.PlacementPolicy) { - c.v2.SetPlacementPolicy(v.ToV2()) -} - -// SessionToken returns token of the session within -// which container was created. -func (c Container) SessionToken() *session.Token { - return c.token -} - -// SetSessionToken sets token of the session within -// which container was created. -func (c *Container) SetSessionToken(t *session.Token) { - c.token = t -} - -// Signature returns signature of the marshaled container. -func (c Container) Signature() *pkg.Signature { - return c.sig -} - -// SetSignature sets signature of the marshaled container. -func (c *Container) SetSignature(sig *pkg.Signature) { - c.sig = sig -} - -// Marshal marshals Container into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (c *Container) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return c.v2. - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Container. -func (c *Container) Unmarshal(data []byte) error { - return c.v2. - Unmarshal(data) -} - -// MarshalJSON encodes Container to protobuf JSON format. -func (c *Container) MarshalJSON() ([]byte, error) { - return c.v2. - MarshalJSON() -} - -// UnmarshalJSON decodes Container from protobuf JSON format. -func (c *Container) UnmarshalJSON(data []byte) error { - return c.v2. - UnmarshalJSON(data) -} diff --git a/pkg/container/container_test.go b/pkg/container/container_test.go deleted file mode 100644 index a5175b5..0000000 --- a/pkg/container/container_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package container_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/nspcc-dev/neofs-api-go/pkg/acl" - "github.com/nspcc-dev/neofs-api-go/pkg/container" - containertest "github.com/nspcc-dev/neofs-api-go/pkg/container/test" - netmaptest "github.com/nspcc-dev/neofs-api-go/pkg/netmap/test" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" - "github.com/stretchr/testify/require" -) - -func TestNewContainer(t *testing.T) { - c := container.New() - - nonce := uuid.New() - - ownerID := ownertest.Generate() - policy := netmaptest.PlacementPolicy() - - c.SetBasicACL(acl.PublicBasicRule) - - attrs := containertest.Attributes() - c.SetAttributes(attrs) - - c.SetPlacementPolicy(policy) - c.SetNonceUUID(nonce) - c.SetOwnerID(ownerID) - - ver := refstest.Version() - c.SetVersion(ver) - - v2 := c.ToV2() - newContainer := container.NewContainerFromV2(v2) - - require.EqualValues(t, newContainer.PlacementPolicy(), policy) - require.EqualValues(t, newContainer.Attributes(), attrs) - require.EqualValues(t, newContainer.BasicACL(), acl.PublicBasicRule) - - newNonce, err := newContainer.NonceUUID() - require.NoError(t, err) - - require.EqualValues(t, newNonce, nonce) - require.EqualValues(t, newContainer.OwnerID(), ownerID) - require.EqualValues(t, newContainer.Version(), ver) -} - -func TestContainerEncoding(t *testing.T) { - c := containertest.Container() - - t.Run("binary", func(t *testing.T) { - data, err := c.Marshal() - require.NoError(t, err) - - c2 := container.New() - require.NoError(t, c2.Unmarshal(data)) - - require.Equal(t, c, c2) - }) - - t.Run("json", func(t *testing.T) { - data, err := c.MarshalJSON() - require.NoError(t, err) - - c2 := container.New() - require.NoError(t, c2.UnmarshalJSON(data)) - - require.Equal(t, c, c2) - }) -} - -func TestContainer_SessionToken(t *testing.T) { - tok := sessiontest.Generate() - - cnr := container.New() - - cnr.SetSessionToken(tok) - - require.Equal(t, tok, cnr.SessionToken()) -} - -func TestContainer_Signature(t *testing.T) { - sig := refstest.Signature() - - cnr := container.New() - cnr.SetSignature(sig) - - require.Equal(t, sig, cnr.Signature()) -} - -func TestContainer_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *container.Container - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - cnt := container.New() - - // check initial values - require.Nil(t, cnt.SessionToken()) - require.Nil(t, cnt.Signature()) - require.Nil(t, cnt.Version()) - require.Nil(t, cnt.Attributes()) - require.Nil(t, cnt.PlacementPolicy()) - require.Nil(t, cnt.OwnerID()) - - require.EqualValues(t, acl.PrivateBasicRule, cnt.BasicACL()) - - nonce, err := cnt.NonceUUID() - require.NoError(t, err) - require.NotNil(t, nonce) - - // convert to v2 message - cntV2 := cnt.ToV2() - - nonceV2, err := uuid.FromBytes(cntV2.GetNonce()) - require.NoError(t, err) - - require.Equal(t, nonce.String(), nonceV2.String()) - - require.Nil(t, cntV2.GetVersion()) - require.Nil(t, cntV2.GetAttributes()) - require.Nil(t, cntV2.GetPlacementPolicy()) - require.Nil(t, cntV2.GetOwnerID()) - - require.Equal(t, uint32(acl.PrivateBasicRule), cntV2.GetBasicACL()) - }) -} diff --git a/pkg/container/id.go b/pkg/container/id.go deleted file mode 100644 index 96a6483..0000000 --- a/pkg/container/id.go +++ /dev/null @@ -1,22 +0,0 @@ -package container - -import ( - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" -) - -// ID represents v2-compatible container identifier. -// -// Deprecated: use cid.ID instead. -type ID = cid.ID - -// NewIDFromV2 wraps v2 ContainerID message to ID. -// -// Deprecated: use cid.NewFromV2 instead. -var NewIDFromV2 = cid.NewFromV2 - -// NewID creates and initializes blank ID. -// -// Works similar to NewIDFromV2(new(ContainerID)). -// -// Deprecated: use cid.New instead. -var NewID = cid.New diff --git a/pkg/container/id/id.go b/pkg/container/id/id.go deleted file mode 100644 index 351c9b3..0000000 --- a/pkg/container/id/id.go +++ /dev/null @@ -1,102 +0,0 @@ -package cid - -import ( - "bytes" - "crypto/sha256" - "errors" - - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// ID represents v2-compatible container identifier. -type ID refs.ContainerID - -// NewFromV2 wraps v2 ContainerID message to ID. -// -// Nil refs.ContainerID converts to nil. -func NewFromV2(idV2 *refs.ContainerID) *ID { - return (*ID)(idV2) -} - -// New creates and initializes blank ID. -// -// Defaults: -// - value: nil. -func New() *ID { - return NewFromV2(new(refs.ContainerID)) -} - -// SetSHA256 sets container identifier value to SHA256 checksum. -func (id *ID) SetSHA256(v [sha256.Size]byte) { - (*refs.ContainerID)(id).SetValue(v[:]) -} - -// ToV2 returns the v2 container ID message. -// -// Nil ID converts to nil. -func (id *ID) ToV2() *refs.ContainerID { - return (*refs.ContainerID)(id) -} - -// Equal returns true if identifiers are identical. -func (id *ID) Equal(id2 *ID) bool { - return bytes.Equal( - (*refs.ContainerID)(id).GetValue(), - (*refs.ContainerID)(id2).GetValue(), - ) -} - -// Parse parses string representation of ID. -// -// Returns error if s is not a base58 encoded -// ID data. -func (id *ID) Parse(s string) error { - data, err := base58.Decode(s) - if err != nil { - return err - } else if len(data) != sha256.Size { - return errors.New("incorrect format of the string container ID") - } - - (*refs.ContainerID)(id).SetValue(data) - - return nil -} - -// String returns base58 string representation of ID. -func (id *ID) String() string { - return base58.Encode((*refs.ContainerID)(id).GetValue()) -} - -// Marshal marshals ID into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (id *ID) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.ContainerID)(id). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of ID. -func (id *ID) Unmarshal(data []byte) error { - return (*refs.ContainerID)(id). - Unmarshal(data) -} - -// MarshalJSON encodes ID to protobuf JSON format. -func (id *ID) MarshalJSON() ([]byte, error) { - return (*refs.ContainerID)(id). - MarshalJSON() -} - -// UnmarshalJSON decodes ID from protobuf JSON format. -func (id *ID) UnmarshalJSON(data []byte) error { - return (*refs.ContainerID)(id). - UnmarshalJSON(data) -} diff --git a/pkg/container/id/id_test.go b/pkg/container/id/id_test.go deleted file mode 100644 index b633cb4..0000000 --- a/pkg/container/id/id_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package cid_test - -import ( - "crypto/sha256" - "math/rand" - "testing" - - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func randSHA256Checksum() (cs [sha256.Size]byte) { - rand.Read(cs[:]) - return -} - -func TestID_ToV2(t *testing.T) { - t.Run("non-nil", func(t *testing.T) { - checksum := randSHA256Checksum() - - id := cidtest.GenerateWithChecksum(checksum) - - idV2 := id.ToV2() - - require.Equal(t, id, cid.NewFromV2(idV2)) - require.Equal(t, checksum[:], idV2.GetValue()) - }) - - t.Run("nil", func(t *testing.T) { - var x *cid.ID - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - cid := cid.New() - - // convert to v2 message - cidV2 := cid.ToV2() - require.Nil(t, cidV2.GetValue()) - }) -} - -func TestID_Equal(t *testing.T) { - cs := randSHA256Checksum() - - id1 := cidtest.GenerateWithChecksum(cs) - id2 := cidtest.GenerateWithChecksum(cs) - - require.True(t, id1.Equal(id2)) - - id3 := cidtest.Generate() - - require.False(t, id1.Equal(id3)) -} - -func TestID_String(t *testing.T) { - t.Run("Parse/String", func(t *testing.T) { - id := cidtest.Generate() - id2 := cid.New() - - require.NoError(t, id2.Parse(id.String())) - require.Equal(t, id, id2) - }) - - t.Run("nil", func(t *testing.T) { - id := cid.New() - - require.Empty(t, id.String()) - }) -} - -func TestContainerIDEncoding(t *testing.T) { - id := cidtest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := id.Marshal() - require.NoError(t, err) - - id2 := cid.New() - require.NoError(t, id2.Unmarshal(data)) - - require.Equal(t, id, id2) - }) - - t.Run("json", func(t *testing.T) { - data, err := id.MarshalJSON() - require.NoError(t, err) - - a2 := cid.New() - require.NoError(t, a2.UnmarshalJSON(data)) - - require.Equal(t, id, a2) - }) -} - -func TestNewFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.ContainerID - - require.Nil(t, cid.NewFromV2(x)) - }) -} diff --git a/pkg/container/id/test/id.go b/pkg/container/id/test/id.go deleted file mode 100644 index 58eca65..0000000 --- a/pkg/container/id/test/id.go +++ /dev/null @@ -1,26 +0,0 @@ -package cidtest - -import ( - "crypto/sha256" - "math/rand" - - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" -) - -// Generate returns random cid.ID. -func Generate() *cid.ID { - checksum := [sha256.Size]byte{} - - rand.Read(checksum[:]) - - return GenerateWithChecksum(checksum) -} - -// GenerateWithChecksum returns cid.ID initialized -// with specified checksum. -func GenerateWithChecksum(cs [sha256.Size]byte) *cid.ID { - id := cid.New() - id.SetSHA256(cs) - - return id -} diff --git a/pkg/container/opts.go b/pkg/container/opts.go deleted file mode 100644 index 8c15ed1..0000000 --- a/pkg/container/opts.go +++ /dev/null @@ -1,104 +0,0 @@ -package container - -import ( - "github.com/google/uuid" - "github.com/nspcc-dev/neofs-api-go/pkg/acl" - "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" -) - -type ( - NewOption interface { - apply(*containerOptions) - } - - containerOptions struct { - acl uint32 - policy *netmap.PlacementPolicy - attributes Attributes - owner *owner.ID - nonce uuid.UUID - } -) - -func defaultContainerOptions() containerOptions { - rand, err := uuid.NewRandom() - if err != nil { - panic("can't create new random " + err.Error()) - } - - return containerOptions{ - acl: acl.PrivateBasicRule, - nonce: rand, - } -} - -type funcContainerOption struct { - f func(*containerOptions) -} - -func (fco *funcContainerOption) apply(co *containerOptions) { - fco.f(co) -} - -func newFuncContainerOption(f func(option *containerOptions)) *funcContainerOption { - return &funcContainerOption{ - f: f, - } -} - -func WithPublicBasicACL() NewOption { - return newFuncContainerOption(func(option *containerOptions) { - option.acl = acl.PublicBasicRule - }) -} - -func WithReadOnlyBasicACL() NewOption { - return newFuncContainerOption(func(option *containerOptions) { - option.acl = acl.ReadOnlyBasicRule - }) -} - -func WithCustomBasicACL(acl uint32) NewOption { - return newFuncContainerOption(func(option *containerOptions) { - option.acl = acl - }) -} - -func WithNonce(nonce uuid.UUID) NewOption { - return newFuncContainerOption(func(option *containerOptions) { - option.nonce = nonce - }) -} - -func WithOwnerID(id *owner.ID) NewOption { - return newFuncContainerOption(func(option *containerOptions) { - option.owner = id - }) -} - -func WithNEO3Wallet(w *owner.NEO3Wallet) NewOption { - return newFuncContainerOption(func(option *containerOptions) { - if option.owner == nil { - option.owner = new(owner.ID) - } - - option.owner.SetNeo3Wallet(w) - }) -} - -func WithPolicy(policy *netmap.PlacementPolicy) NewOption { - return newFuncContainerOption(func(option *containerOptions) { - option.policy = policy - }) -} - -func WithAttribute(key, value string) NewOption { - return newFuncContainerOption(func(option *containerOptions) { - attr := NewAttribute() - attr.SetKey(key) - attr.SetValue(value) - - option.attributes = append(option.attributes, attr) - }) -} diff --git a/pkg/container/test/generate.go b/pkg/container/test/generate.go deleted file mode 100644 index 0f5f9b0..0000000 --- a/pkg/container/test/generate.go +++ /dev/null @@ -1,48 +0,0 @@ -package containertest - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/container" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - netmaptest "github.com/nspcc-dev/neofs-api-go/pkg/netmap/test" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" -) - -// Attribute returns random container.Attribute. -func Attribute() *container.Attribute { - x := container.NewAttribute() - - x.SetKey("key") - x.SetValue("value") - - return x -} - -// Attributes returns random container.Attributes. -func Attributes() container.Attributes { - return container.Attributes{Attribute(), Attribute()} -} - -// Container returns random container.Container. -func Container() *container.Container { - x := container.New() - - x.SetVersion(refstest.Version()) - x.SetAttributes(Attributes()) - x.SetOwnerID(ownertest.Generate()) - x.SetBasicACL(123) - x.SetPlacementPolicy(netmaptest.PlacementPolicy()) - - return x -} - -// UsedSpaceAnnouncement returns random container.UsedSpaceAnnouncement. -func UsedSpaceAnnouncement() *container.UsedSpaceAnnouncement { - x := container.NewAnnouncement() - - x.SetContainerID(cidtest.Generate()) - x.SetEpoch(55) - x.SetUsedSpace(999) - - return x -} diff --git a/pkg/container/wellknown_attributes.go b/pkg/container/wellknown_attributes.go deleted file mode 100644 index 241c745..0000000 --- a/pkg/container/wellknown_attributes.go +++ /dev/null @@ -1,11 +0,0 @@ -package container - -const ( - // AttributeName is an attribute key that is commonly used to denote - // human-friendly name. - AttributeName = "Name" - - // AttributeTimestamp is an attribute key that is commonly used to denote - // user-defined local time of container creation in Unix Timestamp format. - AttributeTimestamp = "Timestamp" -) diff --git a/pkg/netmap/aggregator.go b/pkg/netmap/aggregator.go deleted file mode 100644 index d1c6061..0000000 --- a/pkg/netmap/aggregator.go +++ /dev/null @@ -1,223 +0,0 @@ -package netmap - -import ( - "sort" -) - -type ( - // aggregator can calculate some value across all netmap - // such as median, minimum or maximum. - aggregator interface { - Add(float64) - Compute() float64 - } - - // normalizer normalizes weight. - normalizer interface { - Normalize(w float64) float64 - } - - meanSumAgg struct { - sum float64 - count int - } - - meanAgg struct { - mean float64 - count int - } - - minAgg struct { - min float64 - } - - maxAgg struct { - max float64 - } - - meanIQRAgg struct { - k float64 - arr []float64 - } - - reverseMinNorm struct { - min float64 - } - - maxNorm struct { - max float64 - } - - sigmoidNorm struct { - scale float64 - } - - constNorm struct { - value float64 - } - - // weightFunc calculates n's weight. - weightFunc = func(n *Node) float64 -) - -var ( - _ aggregator = (*meanSumAgg)(nil) - _ aggregator = (*meanAgg)(nil) - _ aggregator = (*minAgg)(nil) - _ aggregator = (*maxAgg)(nil) - _ aggregator = (*meanIQRAgg)(nil) - - _ normalizer = (*reverseMinNorm)(nil) - _ normalizer = (*maxNorm)(nil) - _ normalizer = (*sigmoidNorm)(nil) - _ normalizer = (*constNorm)(nil) -) - -// newWeightFunc returns weightFunc which multiplies normalized -// capacity and price. -func newWeightFunc(capNorm, priceNorm normalizer) weightFunc { - return func(n *Node) float64 { - return capNorm.Normalize(float64(n.Capacity)) * priceNorm.Normalize(float64(n.Price)) - } -} - -// newMeanAgg returns an aggregator which -// computes mean value by recalculating it on -// every addition. -func newMeanAgg() aggregator { - return new(meanAgg) -} - -// newMinAgg returns an aggregator which -// computes min value. -func newMinAgg() aggregator { - return new(minAgg) -} - -// newMeanIQRAgg returns an aggregator which -// computes mean value of values from IQR interval. -func newMeanIQRAgg() aggregator { - return new(meanIQRAgg) -} - -// newReverseMinNorm returns a normalizer which -// normalize values in range of 0.0 to 1.0 to a minimum value. -func newReverseMinNorm(min float64) normalizer { - return &reverseMinNorm{min: min} -} - -// newSigmoidNorm returns a normalizer which -// normalize values in range of 0.0 to 1.0 to a scaled sigmoid. -func newSigmoidNorm(scale float64) normalizer { - return &sigmoidNorm{scale: scale} -} - -func (a *meanSumAgg) Add(n float64) { - a.sum += n - a.count++ -} - -func (a *meanSumAgg) Compute() float64 { - if a.count == 0 { - return 0 - } - - return a.sum / float64(a.count) -} - -func (a *meanAgg) Add(n float64) { - c := a.count + 1 - a.mean = a.mean*(float64(a.count)/float64(c)) + n/float64(c) - a.count++ -} - -func (a *meanAgg) Compute() float64 { - return a.mean -} - -func (a *minAgg) Add(n float64) { - if a.min == 0 || n < a.min { - a.min = n - } -} - -func (a *minAgg) Compute() float64 { - return a.min -} - -func (a *maxAgg) Add(n float64) { - if n > a.max { - a.max = n - } -} - -func (a *maxAgg) Compute() float64 { - return a.max -} - -func (a *meanIQRAgg) Add(n float64) { - a.arr = append(a.arr, n) -} - -func (a *meanIQRAgg) Compute() float64 { - l := len(a.arr) - if l == 0 { - return 0 - } - - sort.Slice(a.arr, func(i, j int) bool { return a.arr[i] < a.arr[j] }) - - var min, max float64 - - const minLn = 4 - - if l < minLn { - min, max = a.arr[0], a.arr[l-1] - } else { - start, end := l/minLn, l*3/minLn-1 - iqr := a.k * (a.arr[end] - a.arr[start]) - min, max = a.arr[start]-iqr, a.arr[end]+iqr - } - - count := 0 - sum := float64(0) - - for _, e := range a.arr { - if e >= min && e <= max { - sum += e - count++ - } - } - - return sum / float64(count) -} - -func (r *reverseMinNorm) Normalize(w float64) float64 { - if w == 0 { - return 0 - } - - return r.min / w -} - -func (r *maxNorm) Normalize(w float64) float64 { - if r.max == 0 { - return 0 - } - - return w / r.max -} - -func (r *sigmoidNorm) Normalize(w float64) float64 { - if r.scale == 0 { - return 0 - } - - x := w / r.scale - - return x / (1 + x) -} - -func (r *constNorm) Normalize(_ float64) float64 { - return r.value -} diff --git a/pkg/netmap/clause.go b/pkg/netmap/clause.go deleted file mode 100644 index d2b5c40..0000000 --- a/pkg/netmap/clause.go +++ /dev/null @@ -1,69 +0,0 @@ -package netmap - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// Clause is an enumeration of selector modifiers -// that shows how the node set will be formed. -type Clause uint32 - -const ( - ClauseUnspecified Clause = iota - - // ClauseSame is a selector modifier to select only nodes having the same value of bucket attribute. - ClauseSame - - // ClauseDistinct is a selector modifier to select nodes having different values of bucket attribute. - ClauseDistinct -) - -// ClauseFromV2 converts v2 Clause to Clause. -func ClauseFromV2(c netmap.Clause) Clause { - switch c { - default: - return ClauseUnspecified - case netmap.Same: - return ClauseSame - case netmap.Distinct: - return ClauseDistinct - } -} - -// ToV2 converts Clause to v2 Clause. -func (c Clause) ToV2() netmap.Clause { - switch c { - default: - return netmap.UnspecifiedClause - case ClauseDistinct: - return netmap.Distinct - case ClauseSame: - return netmap.Same - } -} - -// String returns string representation of Clause. -// -// String mapping: -// * ClauseDistinct: DISTINCT; -// * ClauseSame: SAME; -// * ClauseUnspecified, default: CLAUSE_UNSPECIFIED. -func (c Clause) String() string { - return c.ToV2().String() -} - -// FromString parses Clause from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (c *Clause) FromString(s string) bool { - var g netmap.Clause - - ok := g.FromString(s) - - if ok { - *c = ClauseFromV2(g) - } - - return ok -} diff --git a/pkg/netmap/clause_test.go b/pkg/netmap/clause_test.go deleted file mode 100644 index 6ce5e82..0000000 --- a/pkg/netmap/clause_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package netmap - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - "github.com/stretchr/testify/require" -) - -func TestClauseFromV2(t *testing.T) { - for _, item := range []struct { - c Clause - cV2 netmap.Clause - }{ - { - c: ClauseUnspecified, - cV2: netmap.UnspecifiedClause, - }, - { - c: ClauseSame, - cV2: netmap.Same, - }, - { - c: ClauseDistinct, - cV2: netmap.Distinct, - }, - } { - require.Equal(t, item.c, ClauseFromV2(item.cV2)) - require.Equal(t, item.cV2, item.c.ToV2()) - } -} - -func TestClause_String(t *testing.T) { - toPtr := func(v Clause) *Clause { - return &v - } - - testEnumStrings(t, new(Clause), []enumStringItem{ - {val: toPtr(ClauseDistinct), str: "DISTINCT"}, - {val: toPtr(ClauseSame), str: "SAME"}, - {val: toPtr(ClauseUnspecified), str: "CLAUSE_UNSPECIFIED"}, - }) -} diff --git a/pkg/netmap/container.go b/pkg/netmap/container.go deleted file mode 100644 index 00875a9..0000000 --- a/pkg/netmap/container.go +++ /dev/null @@ -1,19 +0,0 @@ -package netmap - -// ContainerNodes represents nodes in the container. -type ContainerNodes interface { - Replicas() []Nodes - Flatten() Nodes -} - -type containerNodes []Nodes - -// Flatten returns list of all nodes from the container. -func (c containerNodes) Flatten() Nodes { - return flattenNodes(c) -} - -// Replicas return list of container replicas. -func (c containerNodes) Replicas() []Nodes { - return c -} diff --git a/pkg/netmap/context.go b/pkg/netmap/context.go deleted file mode 100644 index 29b8167..0000000 --- a/pkg/netmap/context.go +++ /dev/null @@ -1,94 +0,0 @@ -package netmap - -import ( - "errors" - - "github.com/nspcc-dev/hrw" -) - -// Context contains references to named filters and cached numeric values. -type Context struct { - // Netmap is a netmap structure to operate on. - Netmap *Netmap - // Filters stores processed filters. - Filters map[string]*Filter - // Selectors stores processed selectors. - Selectors map[string]*Selector - // Selections stores result of selector processing. - Selections map[string][]Nodes - - // numCache stores parsed numeric values. - numCache map[*Filter]uint64 - // pivot is a seed for HRW. - pivot []byte - // pivotHash is a saved HRW hash of pivot - pivotHash uint64 - // aggregator is returns aggregator determining bucket weight. - // By default it returns mean value from IQR interval. - aggregator func() aggregator - // weightFunc is a weighting function for determining node priority. - // By default in combines favours low price and high capacity. - weightFunc weightFunc - // container backup factor is a factor for selector counters that expand - // amount of chosen nodes. - cbf uint32 -} - -// Various validation errors. -var ( - ErrMissingField = errors.New("netmap: nil field") - ErrInvalidFilterName = errors.New("netmap: filter name is invalid") - ErrInvalidNumber = errors.New("netmap: number value expected") - ErrInvalidFilterOp = errors.New("netmap: invalid filter operation") - ErrFilterNotFound = errors.New("netmap: filter not found") - ErrNonEmptyFilters = errors.New("netmap: simple filter must no contain sub-filters") - ErrNotEnoughNodes = errors.New("netmap: not enough nodes to SELECT from") - ErrSelectorNotFound = errors.New("netmap: selector not found") - ErrUnnamedTopFilter = errors.New("netmap: all filters on top level must be named") -) - -// NewContext creates new context. It contains various caches. -// In future it may create hierarchical netmap structure to work with. -func NewContext(nm *Netmap) *Context { - return &Context{ - Netmap: nm, - Filters: make(map[string]*Filter), - Selectors: make(map[string]*Selector), - Selections: make(map[string][]Nodes), - - numCache: make(map[*Filter]uint64), - aggregator: newMeanIQRAgg, - weightFunc: GetDefaultWeightFunc(nm.Nodes), - cbf: defaultCBF, - } -} - -func (c *Context) setPivot(pivot []byte) { - if len(pivot) != 0 { - c.pivot = pivot - c.pivotHash = hrw.Hash(pivot) - } -} - -func (c *Context) setCBF(cbf uint32) { - if cbf == 0 { - c.cbf = defaultCBF - } else { - c.cbf = cbf - } -} - -// GetDefaultWeightFunc returns default weighting function. -func GetDefaultWeightFunc(ns Nodes) weightFunc { - mean := newMeanAgg() - min := newMinAgg() - - for i := range ns { - mean.Add(float64(ns[i].Capacity)) - min.Add(float64(ns[i].Price)) - } - - return newWeightFunc( - newSigmoidNorm(mean.Compute()), - newReverseMinNorm(min.Compute())) -} diff --git a/pkg/netmap/doc.go b/pkg/netmap/doc.go deleted file mode 100644 index a38e985..0000000 --- a/pkg/netmap/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -/* -Package netmap provides routines for working with netmap and placement policy. -Work is done in 4 steps: -1. Create context containing results shared between steps. -2. Processing filters. -3. Processing selectors. -4. Processing replicas. - -Each step depends only on previous ones. -*/ -package netmap diff --git a/pkg/netmap/filter.go b/pkg/netmap/filter.go deleted file mode 100644 index 4beb1f5..0000000 --- a/pkg/netmap/filter.go +++ /dev/null @@ -1,295 +0,0 @@ -package netmap - -import ( - "fmt" - "strconv" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// Filter represents v2-compatible netmap filter. -type Filter netmap.Filter - -// MainFilterName is a name of the filter -// which points to the whole netmap. -const MainFilterName = "*" - -// applyFilter applies named filter to b. -func (c *Context) applyFilter(name string, b *Node) bool { - return name == MainFilterName || c.match(c.Filters[name], b) -} - -// processFilters processes filters and returns error is any of them is invalid. -func (c *Context) processFilters(p *PlacementPolicy) error { - for _, f := range p.Filters() { - if err := c.processFilter(f, true); err != nil { - return err - } - } - - return nil -} - -func (c *Context) processFilter(f *Filter, top bool) error { - if f == nil { - return fmt.Errorf("%w: FILTER", ErrMissingField) - } - - if f.Name() == MainFilterName { - return fmt.Errorf("%w: '*' is reserved", ErrInvalidFilterName) - } - - if top && f.Name() == "" { - return ErrUnnamedTopFilter - } - - if !top && f.Name() != "" && c.Filters[f.Name()] == nil { - return fmt.Errorf("%w: '%s'", ErrFilterNotFound, f.Name()) - } - - switch f.Operation() { - case OpAND, OpOR: - for _, flt := range f.InnerFilters() { - if err := c.processFilter(flt, false); err != nil { - return err - } - } - default: - if len(f.InnerFilters()) != 0 { - return ErrNonEmptyFilters - } else if !top && f.Name() != "" { // named reference - return nil - } - - switch f.Operation() { - case OpEQ, OpNE: - case OpGT, OpGE, OpLT, OpLE: - n, err := strconv.ParseUint(f.Value(), 10, 64) - if err != nil { - return fmt.Errorf("%w: '%s'", ErrInvalidNumber, f.Value()) - } - - c.numCache[f] = n - default: - return fmt.Errorf("%w: %s", ErrInvalidFilterOp, f.Operation()) - } - } - - if top { - c.Filters[f.Name()] = f - } - - return nil -} - -// match matches f against b. It returns no errors because -// filter should have been parsed during context creation -// and missing node properties are considered as a regular fail. -func (c *Context) match(f *Filter, b *Node) bool { - switch f.Operation() { - case OpAND, OpOR: - for _, lf := range f.InnerFilters() { - if lf.Name() != "" { - lf = c.Filters[lf.Name()] - } - - ok := c.match(lf, b) - if ok == (f.Operation() == OpOR) { - return ok - } - } - - return f.Operation() == OpAND - default: - return c.matchKeyValue(f, b) - } -} - -func (c *Context) matchKeyValue(f *Filter, b *Node) bool { - switch f.Operation() { - case OpEQ: - return b.Attribute(f.Key()) == f.Value() - case OpNE: - return b.Attribute(f.Key()) != f.Value() - default: - var attr uint64 - - switch f.Key() { - case AttrPrice: - attr = b.Price - case AttrCapacity: - attr = b.Capacity - default: - var err error - - attr, err = strconv.ParseUint(b.Attribute(f.Key()), 10, 64) - if err != nil { - // Note: because filters are somewhat independent from nodes attributes, - // We don't report an error here, and fail filter instead. - return false - } - } - - switch f.Operation() { - case OpGT: - return attr > c.numCache[f] - case OpGE: - return attr >= c.numCache[f] - case OpLT: - return attr < c.numCache[f] - case OpLE: - return attr <= c.numCache[f] - default: - // do nothing and return false - } - } - // will not happen if context was created from f (maybe panic?) - return false -} - -// NewFilter creates and returns new Filter instance. -// -// Defaults: -// - name: ""; -// - key: ""; -// - value: ""; -// - operation: 0; -// - filters: nil. -func NewFilter() *Filter { - return NewFilterFromV2(new(netmap.Filter)) -} - -// NewFilterFromV2 converts v2 Filter to Filter. -// -// Nil netmap.Filter converts to nil. -func NewFilterFromV2(f *netmap.Filter) *Filter { - return (*Filter)(f) -} - -// ToV2 converts Filter to v2 Filter. -// -// Nil Filter converts to nil. -func (f *Filter) ToV2() *netmap.Filter { - return (*netmap.Filter)(f) -} - -// Key returns key to filter. -func (f *Filter) Key() string { - return (*netmap.Filter)(f). - GetKey() -} - -// SetKey sets key to filter. -func (f *Filter) SetKey(key string) { - (*netmap.Filter)(f). - SetKey(key) -} - -// Value returns value to match. -func (f *Filter) Value() string { - return (*netmap.Filter)(f). - GetValue() -} - -// SetValue sets value to match. -func (f *Filter) SetValue(val string) { - (*netmap.Filter)(f). - SetValue(val) -} - -// Name returns filter name. -func (f *Filter) Name() string { - return (*netmap.Filter)(f). - GetName() -} - -// SetName sets filter name. -func (f *Filter) SetName(name string) { - (*netmap.Filter)(f). - SetName(name) -} - -// Operation returns filtering operation. -func (f *Filter) Operation() Operation { - return OperationFromV2( - (*netmap.Filter)(f). - GetOp(), - ) -} - -// SetOperation sets filtering operation. -func (f *Filter) SetOperation(op Operation) { - (*netmap.Filter)(f). - SetOp(op.ToV2()) -} - -func filtersFromV2(fs []*netmap.Filter) []*Filter { - if fs == nil { - return nil - } - - res := make([]*Filter, 0, len(fs)) - - for i := range fs { - res = append(res, NewFilterFromV2(fs[i])) - } - - return res -} - -// InnerFilters returns list of inner filters. -func (f *Filter) InnerFilters() []*Filter { - return filtersFromV2( - (*netmap.Filter)(f). - GetFilters(), - ) -} - -func filtersToV2(fs []*Filter) (fsV2 []*netmap.Filter) { - if fs != nil { - fsV2 = make([]*netmap.Filter, 0, len(fs)) - - for i := range fs { - fsV2 = append(fsV2, fs[i].ToV2()) - } - } - - return -} - -// SetInnerFilters sets list of inner filters. -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 deleted file mode 100644 index c9103e1..0000000 --- a/pkg/netmap/filter_test.go +++ /dev/null @@ -1,331 +0,0 @@ -package netmap - -import ( - "errors" - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - "github.com/stretchr/testify/require" -) - -func TestContext_ProcessFilters(t *testing.T) { - fs := []*Filter{ - newFilter("StorageSSD", "Storage", "SSD", OpEQ), - newFilter("GoodRating", "Rating", "4", OpGE), - newFilter("Main", "", "", OpAND, - newFilter("StorageSSD", "", "", 0), - newFilter("", "IntField", "123", OpLT), - newFilter("GoodRating", "", "", 0)), - } - nm, err := NewNetmap(nil) - require.NoError(t, err) - c := NewContext(nm) - p := newPlacementPolicy(1, nil, nil, fs) - require.NoError(t, c.processFilters(p)) - require.Equal(t, 3, len(c.Filters)) - for _, f := range fs { - require.Equal(t, f, c.Filters[f.Name()]) - } - - require.Equal(t, uint64(4), c.numCache[fs[1]]) - require.Equal(t, uint64(123), c.numCache[fs[2].InnerFilters()[1]]) -} - -func TestContext_ProcessFiltersInvalid(t *testing.T) { - errTestCases := []struct { - name string - filter *Filter - err error - }{ - { - "UnnamedTop", - newFilter("", "Storage", "SSD", OpEQ), - ErrUnnamedTopFilter, - }, - { - "InvalidReference", - newFilter("Main", "", "", OpAND, - newFilter("StorageSSD", "", "", 0)), - ErrFilterNotFound, - }, - { - "NonEmptyKeyed", - newFilter("Main", "Storage", "SSD", OpEQ, - newFilter("StorageSSD", "", "", 0)), - ErrNonEmptyFilters, - }, - { - "InvalidNumber", - newFilter("Main", "Rating", "three", OpGE), - ErrInvalidNumber, - }, - { - "InvalidOp", - newFilter("Main", "Rating", "3", 0), - ErrInvalidFilterOp, - }, - { - "InvalidName", - newFilter("*", "Rating", "3", OpGE), - ErrInvalidFilterName, - }, - { - "MissingFilter", - nil, - ErrMissingField, - }, - } - for _, tc := range errTestCases { - t.Run(tc.name, func(t *testing.T) { - c := NewContext(new(Netmap)) - p := newPlacementPolicy(1, nil, nil, []*Filter{tc.filter}) - err := c.processFilters(p) - require.True(t, errors.Is(err, tc.err), "got: %v", err) - }) - } -} - -func TestFilter_MatchSimple(t *testing.T) { - b := &Node{AttrMap: map[string]string{ - "Rating": "4", - "Country": "Germany", - }} - testCases := []struct { - name string - ok bool - f *Filter - }{ - { - "GE_true", true, - newFilter("Main", "Rating", "4", OpGE), - }, - { - "GE_false", false, - newFilter("Main", "Rating", "5", OpGE), - }, - { - "GT_true", true, - newFilter("Main", "Rating", "3", OpGT), - }, - { - "GT_false", false, - newFilter("Main", "Rating", "4", OpGT), - }, - { - "LE_true", true, - newFilter("Main", "Rating", "4", OpLE), - }, - { - "LE_false", false, - newFilter("Main", "Rating", "3", OpLE), - }, - { - "LT_true", true, - newFilter("Main", "Rating", "5", OpLT), - }, - { - "LT_false", false, - newFilter("Main", "Rating", "4", OpLT), - }, - { - "EQ_true", true, - newFilter("Main", "Country", "Germany", OpEQ), - }, - { - "EQ_false", false, - newFilter("Main", "Country", "China", OpEQ), - }, - { - "NE_true", true, - newFilter("Main", "Country", "France", OpNE), - }, - { - "NE_false", false, - newFilter("Main", "Country", "Germany", OpNE), - }, - } - for _, tc := range testCases { - c := NewContext(new(Netmap)) - p := newPlacementPolicy(1, nil, nil, []*Filter{tc.f}) - require.NoError(t, c.processFilters(p)) - require.Equal(t, tc.ok, c.match(tc.f, b)) - } - - t.Run("InvalidOp", func(t *testing.T) { - f := newFilter("Main", "Rating", "5", OpEQ) - c := NewContext(new(Netmap)) - p := newPlacementPolicy(1, nil, nil, []*Filter{f}) - require.NoError(t, c.processFilters(p)) - - // just for the coverage - f.SetOperation(0) - require.False(t, c.match(f, b)) - }) -} - -func TestFilter_Match(t *testing.T) { - fs := []*Filter{ - newFilter("StorageSSD", "Storage", "SSD", OpEQ), - newFilter("GoodRating", "Rating", "4", OpGE), - newFilter("Main", "", "", OpAND, - newFilter("StorageSSD", "", "", 0), - newFilter("", "IntField", "123", OpLT), - newFilter("GoodRating", "", "", 0), - newFilter("", "", "", OpOR, - newFilter("", "Param", "Value1", OpEQ), - newFilter("", "Param", "Value2", OpEQ), - )), - } - c := NewContext(new(Netmap)) - p := newPlacementPolicy(1, nil, nil, fs) - require.NoError(t, c.processFilters(p)) - - t.Run("Good", func(t *testing.T) { - n := getTestNode("Storage", "SSD", "Rating", "10", "IntField", "100", "Param", "Value1") - require.True(t, c.applyFilter("Main", n)) - }) - t.Run("InvalidStorage", func(t *testing.T) { - n := getTestNode("Storage", "HDD", "Rating", "10", "IntField", "100", "Param", "Value1") - require.False(t, c.applyFilter("Main", n)) - }) - t.Run("InvalidRating", func(t *testing.T) { - n := getTestNode("Storage", "SSD", "Rating", "3", "IntField", "100", "Param", "Value1") - require.False(t, c.applyFilter("Main", n)) - }) - t.Run("InvalidIntField", func(t *testing.T) { - n := getTestNode("Storage", "SSD", "Rating", "3", "IntField", "str", "Param", "Value1") - require.False(t, c.applyFilter("Main", n)) - }) - t.Run("InvalidParam", func(t *testing.T) { - n := getTestNode("Storage", "SSD", "Rating", "3", "IntField", "100", "Param", "NotValue") - require.False(t, c.applyFilter("Main", n)) - }) -} - -func testFilter() *Filter { - f := NewFilter() - f.SetOperation(OpGE) - f.SetName("name") - f.SetKey("key") - f.SetValue("value") - - return f -} - -func TestFilterFromV2(t *testing.T) { - t.Run("nil from V2", func(t *testing.T) { - var x *netmap.Filter - - require.Nil(t, NewFilterFromV2(x)) - }) - - t.Run("nil to V2", func(t *testing.T) { - var x *Filter - - require.Nil(t, x.ToV2()) - }) - - fV2 := new(netmap.Filter) - fV2.SetOp(netmap.GE) - fV2.SetName("name") - fV2.SetKey("key") - fV2.SetValue("value") - - f := NewFilterFromV2(fV2) - - require.Equal(t, fV2, f.ToV2()) -} - -func TestFilter_Key(t *testing.T) { - f := NewFilter() - key := "some key" - - f.SetKey(key) - - require.Equal(t, key, f.Key()) -} - -func TestFilter_Value(t *testing.T) { - f := NewFilter() - val := "some value" - - f.SetValue(val) - - require.Equal(t, val, f.Value()) -} - -func TestFilter_Name(t *testing.T) { - f := NewFilter() - name := "some name" - - f.SetName(name) - - require.Equal(t, name, f.Name()) -} - -func TestFilter_Operation(t *testing.T) { - f := NewFilter() - op := OpGE - - f.SetOperation(op) - - require.Equal(t, op, f.Operation()) -} - -func TestFilter_InnerFilters(t *testing.T) { - f := NewFilter() - - f1, f2 := testFilter(), testFilter() - - f.SetInnerFilters(f1, f2) - - 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) - }) -} - -func TestNewFilter(t *testing.T) { - t.Run("default values", func(t *testing.T) { - filter := NewFilter() - - // check initial values - require.Empty(t, filter.Name()) - require.Empty(t, filter.Key()) - require.Empty(t, filter.Value()) - require.Zero(t, filter.Operation()) - require.Nil(t, filter.InnerFilters()) - - // convert to v2 message - filterV2 := filter.ToV2() - - require.Empty(t, filterV2.GetName()) - require.Empty(t, filterV2.GetKey()) - require.Empty(t, filterV2.GetValue()) - require.Equal(t, netmap.UnspecifiedOperation, filterV2.GetOp()) - require.Nil(t, filterV2.GetFilters()) - }) -} diff --git a/pkg/netmap/helper_test.go b/pkg/netmap/helper_test.go deleted file mode 100644 index 73b82ae..0000000 --- a/pkg/netmap/helper_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package netmap - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func newFilter(name string, k, v string, op Operation, fs ...*Filter) *Filter { - f := NewFilter() - f.SetName(name) - f.SetKey(k) - f.SetOperation(op) - f.SetValue(v) - f.SetInnerFilters(fs...) - return f -} - -func newSelector(name string, attr string, c Clause, count uint32, filter string) *Selector { - s := NewSelector() - s.SetName(name) - s.SetAttribute(attr) - s.SetCount(count) - s.SetClause(c) - s.SetFilter(filter) - return s -} - -func newPlacementPolicy(bf uint32, rs []*Replica, ss []*Selector, fs []*Filter) *PlacementPolicy { - p := NewPlacementPolicy() - p.SetContainerBackupFactor(bf) - p.SetReplicas(rs...) - p.SetSelectors(ss...) - p.SetFilters(fs...) - return p -} - -func newReplica(c uint32, s string) *Replica { - r := NewReplica() - r.SetCount(c) - r.SetSelector(s) - return r -} - -func nodeInfoFromAttributes(props ...string) NodeInfo { - attrs := make([]*NodeAttribute, len(props)/2) - for i := range attrs { - attrs[i] = NewNodeAttribute() - attrs[i].SetKey(props[i*2]) - attrs[i].SetValue(props[i*2+1]) - } - n := NewNodeInfo() - n.SetAttributes(attrs...) - return *n -} - -func getTestNode(props ...string) *Node { - m := make(map[string]string, len(props)/2) - for i := 0; i < len(props); i += 2 { - m[props[i]] = props[i+1] - } - return &Node{AttrMap: m} -} - -type enumIface interface { - FromString(string) bool - String() string -} - -type enumStringItem struct { - val enumIface - str string -} - -func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { - for _, item := range items { - require.Equal(t, item.str, item.val.String()) - - s := item.val.String() - - require.True(t, e.FromString(s), s) - - require.EqualValues(t, item.val, e, item.val) - } - - // incorrect strings - for _, str := range []string{ - "some string", - "undefined", - } { - require.False(t, e.FromString(str)) - } -} diff --git a/pkg/netmap/netmap.go b/pkg/netmap/netmap.go deleted file mode 100644 index 369d9ac..0000000 --- a/pkg/netmap/netmap.go +++ /dev/null @@ -1,100 +0,0 @@ -package netmap - -import ( - "fmt" - - "github.com/nspcc-dev/hrw" -) - -const defaultCBF = 3 - -// Netmap represents netmap which contains preprocessed nodes. -type Netmap struct { - Nodes Nodes -} - -// NewNetmap constructs netmap from the list of raw nodes. -func NewNetmap(nodes Nodes) (*Netmap, error) { - return &Netmap{ - Nodes: nodes, - }, nil -} - -func flattenNodes(ns []Nodes) Nodes { - result := make(Nodes, 0, len(ns)) - for i := range ns { - result = append(result, ns[i]...) - } - - return result -} - -// GetPlacementVectors returns placement vectors for an object given containerNodes cnt. -func (m *Netmap) GetPlacementVectors(cnt ContainerNodes, pivot []byte) ([]Nodes, error) { - h := hrw.Hash(pivot) - wf := GetDefaultWeightFunc(m.Nodes) - result := make([]Nodes, len(cnt.Replicas())) - - for i, rep := range cnt.Replicas() { - result[i] = make(Nodes, len(rep)) - copy(result[i], rep) - hrw.SortSliceByWeightValue(result[i], result[i].Weights(wf), h) - } - - return result, nil -} - -// GetContainerNodes returns nodes corresponding to each replica. -// Order of returned nodes corresponds to order of replicas in p. -// pivot is a seed for HRW sorting. -func (m *Netmap) GetContainerNodes(p *PlacementPolicy, pivot []byte) (ContainerNodes, error) { - c := NewContext(m) - c.setPivot(pivot) - c.setCBF(p.ContainerBackupFactor()) - - if err := c.processFilters(p); err != nil { - return nil, err - } - - if err := c.processSelectors(p); err != nil { - return nil, err - } - - result := make([]Nodes, len(p.Replicas())) - - for i, r := range p.Replicas() { - if r == nil { - return nil, fmt.Errorf("%w: REPLICA", ErrMissingField) - } - - if r.Selector() == "" { - if len(p.Selectors()) == 0 { - s := new(Selector) - s.SetCount(r.Count()) - s.SetFilter(MainFilterName) - - nodes, err := c.getSelection(p, s) - if err != nil { - return nil, err - } - - result[i] = flattenNodes(nodes) - } - - for _, s := range p.Selectors() { - result[i] = append(result[i], flattenNodes(c.Selections[s.Name()])...) - } - - continue - } - - nodes, ok := c.Selections[r.Selector()] - if !ok { - return nil, fmt.Errorf("%w: REPLICA '%s'", ErrSelectorNotFound, r.Selector()) - } - - result[i] = append(result[i], flattenNodes(nodes)...) - } - - return containerNodes(result), nil -} diff --git a/pkg/netmap/network_info.go b/pkg/netmap/network_info.go deleted file mode 100644 index e8a8a94..0000000 --- a/pkg/netmap/network_info.go +++ /dev/null @@ -1,225 +0,0 @@ -package netmap - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// NetworkInfo represents v2-compatible structure -// with information about NeoFS network. -type NetworkInfo netmap.NetworkInfo - -// NewNetworkInfoFromV2 wraps v2 NetworkInfo message to NetworkInfo. -// -// Nil netmap.NetworkInfo converts to nil. -func NewNetworkInfoFromV2(iV2 *netmap.NetworkInfo) *NetworkInfo { - return (*NetworkInfo)(iV2) -} - -// NewNetworkInfo creates and initializes blank NetworkInfo. -// -// Defaults: -// - curEpoch: 0; -// - magicNum: 0; -// - msPerBlock: 0; -// - network config: nil. -func NewNetworkInfo() *NetworkInfo { - return NewNetworkInfoFromV2(new(netmap.NetworkInfo)) -} - -// ToV2 converts NetworkInfo to v2 NetworkInfo. -// -// Nil NetworkInfo converts to nil. -func (i *NetworkInfo) ToV2() *netmap.NetworkInfo { - return (*netmap.NetworkInfo)(i) -} - -// CurrentEpoch returns current epoch of the NeoFS network. -func (i *NetworkInfo) CurrentEpoch() uint64 { - return (*netmap.NetworkInfo)(i). - GetCurrentEpoch() -} - -// SetCurrentEpoch sets current epoch of the NeoFS network. -func (i *NetworkInfo) SetCurrentEpoch(epoch uint64) { - (*netmap.NetworkInfo)(i). - SetCurrentEpoch(epoch) -} - -// MagicNumber returns magic number of the sidechain. -func (i *NetworkInfo) MagicNumber() uint64 { - return (*netmap.NetworkInfo)(i). - GetMagicNumber() -} - -// SetMagicNumber sets magic number of the sidechain. -func (i *NetworkInfo) SetMagicNumber(epoch uint64) { - (*netmap.NetworkInfo)(i). - SetMagicNumber(epoch) -} - -// MsPerBlock returns MillisecondsPerBlock network parameter. -func (i *NetworkInfo) MsPerBlock() int64 { - return (*netmap.NetworkInfo)(i). - GetMsPerBlock() -} - -// SetMsPerBlock sets MillisecondsPerBlock network parameter. -func (i *NetworkInfo) SetMsPerBlock(v int64) { - (*netmap.NetworkInfo)(i). - SetMsPerBlock(v) -} - -// NetworkConfig returns NeoFS network configuration. -func (i *NetworkInfo) NetworkConfig() *NetworkConfig { - return NewNetworkConfigFromV2( - (*netmap.NetworkInfo)(i). - GetNetworkConfig(), - ) -} - -// SetNetworkConfig sets NeoFS network configuration. -func (i *NetworkInfo) SetNetworkConfig(v *NetworkConfig) { - (*netmap.NetworkInfo)(i). - SetNetworkConfig(v.ToV2()) -} - -// Marshal marshals NetworkInfo into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (i *NetworkInfo) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*netmap.NetworkInfo)(i). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of NetworkInfo. -func (i *NetworkInfo) Unmarshal(data []byte) error { - return (*netmap.NetworkInfo)(i). - Unmarshal(data) -} - -// MarshalJSON encodes NetworkInfo to protobuf JSON format. -func (i *NetworkInfo) MarshalJSON() ([]byte, error) { - return (*netmap.NetworkInfo)(i). - MarshalJSON() -} - -// UnmarshalJSON decodes NetworkInfo from protobuf JSON format. -func (i *NetworkInfo) UnmarshalJSON(data []byte) error { - return (*netmap.NetworkInfo)(i). - UnmarshalJSON(data) -} - -// NetworkParameter represents v2-compatible NeoFS network parameter. -type NetworkParameter netmap.NetworkParameter - -// NewNetworkParameterFromV2 wraps v2 NetworkParameter message to NetworkParameter. -// -// Nil netmap.NetworkParameter converts to nil. -func NewNetworkParameterFromV2(pv2 *netmap.NetworkParameter) *NetworkParameter { - return (*NetworkParameter)(pv2) -} - -// NewNetworkParameter creates and initializes blank NetworkParameter. -// -// Defaults: -// - key: nil; -// - value: nil. -func NewNetworkParameter() *NetworkParameter { - return NewNetworkParameterFromV2(new(netmap.NetworkParameter)) -} - -// ToV2 converts NetworkParameter to v2 NetworkParameter. -// -// Nil NetworkParameter converts to nil. -func (x *NetworkParameter) ToV2() *netmap.NetworkParameter { - return (*netmap.NetworkParameter)(x) -} - -// Key returns key to network parameter. -func (x *NetworkParameter) Key() []byte { - return (*netmap.NetworkParameter)(x). - GetKey() -} - -// SetKey sets key to the network parameter. -func (x *NetworkParameter) SetKey(key []byte) { - (*netmap.NetworkParameter)(x). - SetKey(key) -} - -// Value returns value of the network parameter. -func (x *NetworkParameter) Value() []byte { - return (*netmap.NetworkParameter)(x). - GetValue() -} - -// SetValue sets value of the network parameter. -func (x *NetworkParameter) SetValue(val []byte) { - (*netmap.NetworkParameter)(x). - SetValue(val) -} - -// NetworkConfig represents v2-compatible NeoFS network configuration. -type NetworkConfig netmap.NetworkConfig - -// NewNetworkConfigFromV2 wraps v2 NetworkConfig message to NetworkConfig. -// -// Nil netmap.NetworkConfig converts to nil. -func NewNetworkConfigFromV2(cv2 *netmap.NetworkConfig) *NetworkConfig { - return (*NetworkConfig)(cv2) -} - -// NewNetworkConfig creates and initializes blank NetworkConfig. -// -// Defaults: -// - parameters num: 0. -func NewNetworkConfig() *NetworkConfig { - return NewNetworkConfigFromV2(new(netmap.NetworkConfig)) -} - -// ToV2 converts NetworkConfig to v2 NetworkConfig. -// -// Nil NetworkConfig converts to nil. -func (x *NetworkConfig) ToV2() *netmap.NetworkConfig { - return (*netmap.NetworkConfig)(x) -} - -// NumberOfParameters returns number of network parameters. -func (x *NetworkConfig) NumberOfParameters() int { - return (*netmap.NetworkConfig)(x).NumberOfParameters() -} - -// IterateAddresses iterates over network parameters. -// Breaks iteration on f's true return. -// -// Handler should not be nil. -func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) { - (*netmap.NetworkConfig)(x). - IterateParameters(func(p *netmap.NetworkParameter) bool { - return f(NewNetworkParameterFromV2(p)) - }) -} - -// Value returns value of the network parameter. -func (x *NetworkConfig) SetParameters(ps ...*NetworkParameter) { - var psV2 []*netmap.NetworkParameter - - if ps != nil { - ln := len(ps) - - psV2 = make([]*netmap.NetworkParameter, 0, ln) - - for i := 0; i < ln; i++ { - psV2 = append(psV2, ps[i].ToV2()) - } - } - - (*netmap.NetworkConfig)(x). - SetParameters(psV2...) -} diff --git a/pkg/netmap/network_info_test.go b/pkg/netmap/network_info_test.go deleted file mode 100644 index c36b614..0000000 --- a/pkg/netmap/network_info_test.go +++ /dev/null @@ -1,215 +0,0 @@ -package netmap_test - -import ( - "testing" - - . "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - netmaptest "github.com/nspcc-dev/neofs-api-go/pkg/netmap/test" - "github.com/stretchr/testify/require" -) - -func TestNetworkParameter_Key(t *testing.T) { - i := NewNetworkParameter() - - k := []byte("key") - - i.SetKey(k) - - require.Equal(t, k, i.Key()) - require.Equal(t, k, i.ToV2().GetKey()) -} - -func TestNetworkParameter_Value(t *testing.T) { - i := NewNetworkParameter() - - v := []byte("value") - - i.SetValue(v) - - require.Equal(t, v, i.Value()) - require.Equal(t, v, i.ToV2().GetValue()) -} - -func TestNewNetworkParameterFromV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - require.Nil(t, NewNetworkParameterFromV2(nil)) - }) -} - -func TestNetworkParameter_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *NetworkParameter - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewNetworkParameter(t *testing.T) { - x := NewNetworkParameter() - - // check initial values - require.Nil(t, x.Key()) - require.Nil(t, x.Value()) - - // convert to v2 message - xV2 := x.ToV2() - - require.Nil(t, xV2.GetKey()) - require.Nil(t, xV2.GetValue()) -} - -func TestNetworkConfig_SetParameters(t *testing.T) { - x := NewNetworkConfig() - - require.Zero(t, x.NumberOfParameters()) - - called := 0 - - x.IterateParameters(func(p *NetworkParameter) bool { - called++ - return false - }) - - require.Zero(t, called) - - pps := []*NetworkParameter{ - netmaptest.NetworkParameter(), - netmaptest.NetworkParameter(), - } - - x.SetParameters(pps...) - - require.EqualValues(t, len(pps), x.NumberOfParameters()) - - var dst []*NetworkParameter - - x.IterateParameters(func(p *NetworkParameter) bool { - dst = append(dst, p) - called++ - return false - }) - - require.Equal(t, pps, dst) - require.Equal(t, len(pps), called) -} - -func TestNewNetworkConfigFromV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - require.Nil(t, NewNetworkConfigFromV2(nil)) - }) -} - -func TestNetworkConfig_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - - var x *NetworkConfig - require.Nil(t, x.ToV2()) - }) -} - -func TestNewNetworkConfig(t *testing.T) { - x := NewNetworkConfig() - - // check initial values - require.Zero(t, x.NumberOfParameters()) - - // convert to v2 message - xV2 := x.ToV2() - - require.Zero(t, xV2.NumberOfParameters()) -} - -func TestNetworkInfo_CurrentEpoch(t *testing.T) { - i := NewNetworkInfo() - e := uint64(13) - - i.SetCurrentEpoch(e) - - require.Equal(t, e, i.CurrentEpoch()) - require.Equal(t, e, i.ToV2().GetCurrentEpoch()) -} - -func TestNetworkInfo_MagicNumber(t *testing.T) { - i := NewNetworkInfo() - m := uint64(666) - - i.SetMagicNumber(m) - - require.Equal(t, m, i.MagicNumber()) - require.Equal(t, m, i.ToV2().GetMagicNumber()) -} - -func TestNetworkInfo_MsPerBlock(t *testing.T) { - i := NewNetworkInfo() - - const ms = 987 - - i.SetMsPerBlock(ms) - - require.EqualValues(t, ms, i.MsPerBlock()) - require.EqualValues(t, ms, i.ToV2().GetMsPerBlock()) -} - -func TestNetworkInfo_Config(t *testing.T) { - i := NewNetworkInfo() - - c := netmaptest.NetworkConfig() - - i.SetNetworkConfig(c) - - require.Equal(t, c, i.NetworkConfig()) -} - -func TestNetworkInfoEncoding(t *testing.T) { - i := netmaptest.NetworkInfo() - - t.Run("binary", func(t *testing.T) { - data, err := i.Marshal() - require.NoError(t, err) - - i2 := NewNetworkInfo() - require.NoError(t, i2.Unmarshal(data)) - - require.Equal(t, i, i2) - }) - - t.Run("json", func(t *testing.T) { - data, err := i.MarshalJSON() - require.NoError(t, err) - - i2 := NewNetworkInfo() - require.NoError(t, i2.UnmarshalJSON(data)) - - require.Equal(t, i, i2) - }) -} - -func TestNewNetworkInfoFromV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - require.Nil(t, NewNetworkInfoFromV2(nil)) - }) -} - -func TestNetworkInfo_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *NetworkInfo - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewNetworkInfo(t *testing.T) { - ni := NewNetworkInfo() - - // check initial values - require.Zero(t, ni.CurrentEpoch()) - require.Zero(t, ni.MagicNumber()) - require.Zero(t, ni.MsPerBlock()) - - // convert to v2 message - niV2 := ni.ToV2() - - require.Zero(t, niV2.GetCurrentEpoch()) - require.Zero(t, niV2.GetMagicNumber()) - require.Zero(t, niV2.GetMsPerBlock()) -} diff --git a/pkg/netmap/node_info.go b/pkg/netmap/node_info.go deleted file mode 100644 index 3e62bbd..0000000 --- a/pkg/netmap/node_info.go +++ /dev/null @@ -1,461 +0,0 @@ -package netmap - -import ( - "strconv" - - "github.com/nspcc-dev/hrw" - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -type ( - // Node is a wrapper over NodeInfo. - Node struct { - ID uint64 - Index int - Capacity uint64 - Price uint64 - AttrMap map[string]string - - *NodeInfo - } - - // Nodes represents slice of graph leafs. - Nodes []*Node -) - -// NodeState is an enumeration of various states of the NeoFS node. -type NodeState uint32 - -// NodeAttribute represents v2 compatible attribute of the NeoFS Storage Node. -type NodeAttribute netmap.Attribute - -// NodeInfo represents v2 compatible descriptor of the NeoFS node. -type NodeInfo netmap.NodeInfo - -const ( - _ NodeState = iota - - // NodeStateOffline is network unavailable state. - NodeStateOffline - - // NodeStateOnline is an active state in the network. - NodeStateOnline -) - -// Enumeration of well-known attributes. -const ( - // AttrPrice is a key to the node attribute that indicates the - // price in GAS tokens for storing one GB of data during one Epoch. - AttrPrice = "Price" - - // AttrCapacity is a key to the node attribute that indicates the - // total available disk space in Gigabytes. - AttrCapacity = "Capacity" - - // AttrSubnet is a key to the node attribute that indicates the - // string ID of node's storage subnet. - AttrSubnet = "Subnet" - - // AttrUNLOCODE is a key to the node attribute that indicates the - // node's geographic location in UN/LOCODE format. - AttrUNLOCODE = "UN-LOCODE" - - // AttrCountryCode is a key to the node attribute that indicates the - // Country code in ISO 3166-1_alpha-2 format. - AttrCountryCode = "CountryCode" - - // AttrCountry is a key to the node attribute that indicates the - // country short name in English, as defined in ISO-3166. - AttrCountry = "Country" - - // AttrLocation is a key to the node attribute that indicates the - // place name of the node location. - AttrLocation = "Location" - - // AttrSubDivCode is a key to the node attribute that indicates the - // country's administrative subdivision where node is located - // in ISO 3166-2 format. - AttrSubDivCode = "SubDivCode" - - // AttrSubDiv is a key to the node attribute that indicates the - // country's administrative subdivision name, as defined in - // ISO 3166-2. - AttrSubDiv = "SubDiv" - - // AttrContinent is a key to the node attribute that indicates the - // node's continent name according to the Seven-Continent model. - AttrContinent = "Continent" -) - -var _ hrw.Hasher = (*Node)(nil) - -// Hash is a function from hrw.Hasher interface. It is implemented -// to support weighted hrw therefore sort function sorts nodes -// based on their `N` value. -func (n Node) Hash() uint64 { - return n.ID -} - -// NodesFromInfo converts slice of NodeInfo to a generic node slice. -func NodesFromInfo(infos []NodeInfo) Nodes { - nodes := make(Nodes, len(infos)) - for i := range infos { - nodes[i] = newNodeV2(i, &infos[i]) - } - - return nodes -} - -func newNodeV2(index int, ni *NodeInfo) *Node { - n := &Node{ - ID: hrw.Hash(ni.PublicKey()), - Index: index, - AttrMap: make(map[string]string, len(ni.Attributes())), - NodeInfo: ni, - } - - for _, attr := range ni.Attributes() { - switch attr.Key() { - case AttrCapacity: - n.Capacity, _ = strconv.ParseUint(attr.Value(), 10, 64) - case AttrPrice: - n.Price, _ = strconv.ParseUint(attr.Value(), 10, 64) - } - - n.AttrMap[attr.Key()] = attr.Value() - } - - return n -} - -// Weights returns slice of nodes weights W. -func (n Nodes) Weights(wf weightFunc) []float64 { - w := make([]float64, 0, len(n)) - for i := range n { - w = append(w, wf(n[i])) - } - - return w -} - -// Attribute returns value of attribute k. -func (n *Node) Attribute(k string) string { - return n.AttrMap[k] -} - -// GetBucketWeight computes weight for a Bucket. -func GetBucketWeight(ns Nodes, a aggregator, wf weightFunc) float64 { - for i := range ns { - a.Add(wf(ns[i])) - } - - return a.Compute() -} - -// NodeStateFromV2 converts v2 NodeState to NodeState. -func NodeStateFromV2(s netmap.NodeState) NodeState { - switch s { - default: - return 0 - case netmap.Online: - return NodeStateOnline - case netmap.Offline: - return NodeStateOffline - } -} - -// ToV2 converts NodeState to v2 NodeState. -func (s NodeState) ToV2() netmap.NodeState { - switch s { - default: - return netmap.UnspecifiedState - case NodeStateOffline: - return netmap.Offline - case NodeStateOnline: - return netmap.Online - } -} - -// String returns string representation of NodeState. -// -// String mapping: -// * NodeStateOnline: ONLINE; -// * NodeStateOffline: OFFLINE; -// * default: UNSPECIFIED. -func (s NodeState) String() string { - return s.ToV2().String() -} - -// FromString parses NodeState from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (s *NodeState) FromString(str string) bool { - var g netmap.NodeState - - ok := g.FromString(str) - - if ok { - *s = NodeStateFromV2(g) - } - - return ok -} - -// NewNodeAttribute creates and returns new NodeAttribute instance. -// -// Defaults: -// - key: ""; -// - value: ""; -// - parents: nil. -func NewNodeAttribute() *NodeAttribute { - return NewNodeAttributeFromV2(new(netmap.Attribute)) -} - -// NodeAttributeFromV2 converts v2 node Attribute to NodeAttribute. -// -// Nil netmap.Attribute converts to nil. -func NewNodeAttributeFromV2(a *netmap.Attribute) *NodeAttribute { - return (*NodeAttribute)(a) -} - -// ToV2 converts NodeAttribute to v2 node Attribute. -// -// Nil NodeAttribute converts to nil. -func (a *NodeAttribute) ToV2() *netmap.Attribute { - return (*netmap.Attribute)(a) -} - -// Key returns key to the node attribute. -func (a *NodeAttribute) Key() string { - return (*netmap.Attribute)(a). - GetKey() -} - -// SetKey sets key to the node attribute. -func (a *NodeAttribute) SetKey(key string) { - (*netmap.Attribute)(a). - SetKey(key) -} - -// Value returns value of the node attribute. -func (a *NodeAttribute) Value() string { - return (*netmap.Attribute)(a). - GetValue() -} - -// SetValue sets value of the node attribute. -func (a *NodeAttribute) SetValue(val string) { - (*netmap.Attribute)(a). - SetValue(val) -} - -// ParentKeys returns list of parent keys. -func (a *NodeAttribute) ParentKeys() []string { - return (*netmap.Attribute)(a). - GetParents() -} - -// SetParentKeys sets list of parent keys. -func (a *NodeAttribute) SetParentKeys(keys ...string) { - (*netmap.Attribute)(a). - 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. -// -// Defaults: -// - publicKey: nil; -// - address: ""; -// - attributes nil; -// - state: 0. -func NewNodeInfo() *NodeInfo { - return NewNodeInfoFromV2(new(netmap.NodeInfo)) -} - -// NewNodeInfoFromV2 converts v2 NodeInfo to NodeInfo. -// -// Nil netmap.NodeInfo converts to nil. -func NewNodeInfoFromV2(i *netmap.NodeInfo) *NodeInfo { - return (*NodeInfo)(i) -} - -// ToV2 converts NodeInfo to v2 NodeInfo. -// -// Nil NodeInfo converts to nil. -func (i *NodeInfo) ToV2() *netmap.NodeInfo { - return (*netmap.NodeInfo)(i) -} - -// PublicKey returns public key of the node in a binary format. -func (i *NodeInfo) PublicKey() []byte { - return (*netmap.NodeInfo)(i). - GetPublicKey() -} - -// SetPublicKey sets public key of the node in a binary format. -func (i *NodeInfo) SetPublicKey(key []byte) { - (*netmap.NodeInfo)(i). - SetPublicKey(key) -} - -// Address returns network endpoint address of the node. -// -// Deprecated: use IterateAddresses method. -func (i *NodeInfo) Address() (addr string) { - i.IterateAddresses(func(s string) bool { - addr = s - return true - }) - - return -} - -// SetAddress sets network endpoint address of the node. -// -// Deprecated: use SetAddresses method. -func (i *NodeInfo) SetAddress(addr string) { - i.SetAddresses(addr) -} - -// NumberOfAddresses returns number of network addresses of the node. -func (i *NodeInfo) NumberOfAddresses() int { - return (*netmap.NodeInfo)(i). - NumberOfAddresses() -} - -// IterateAddresses iterates over network addresses of the node. -// Breaks iteration on f's true return. -// -// Handler should not be nil. -func (i *NodeInfo) IterateAddresses(f func(string) bool) { - (*netmap.NodeInfo)(i). - IterateAddresses(f) -} - -// IterateAllAddresses is a helper function to unconditionally -// iterate over all node addresses. -func IterateAllAddresses(i *NodeInfo, f func(string)) { - i.IterateAddresses(func(addr string) bool { - f(addr) - return false - }) -} - -// SetAddresses sets list of network addresses of the node. -func (i *NodeInfo) SetAddresses(v ...string) { - (*netmap.NodeInfo)(i). - SetAddresses(v...) -} - -// Attributes returns list of the node attributes. -func (i *NodeInfo) Attributes() []*NodeAttribute { - if i == nil { - return nil - } - - as := (*netmap.NodeInfo)(i). - GetAttributes() - - if as == nil { - return nil - } - - res := make([]*NodeAttribute, 0, len(as)) - - for i := range as { - res = append(res, NewNodeAttributeFromV2(as[i])) - } - - return res -} - -// SetAttributes sets list of the node attributes. -func (i *NodeInfo) SetAttributes(as ...*NodeAttribute) { - asV2 := make([]*netmap.Attribute, 0, len(as)) - - for i := range as { - asV2 = append(asV2, as[i].ToV2()) - } - - (*netmap.NodeInfo)(i). - SetAttributes(asV2) -} - -// State returns node state. -func (i *NodeInfo) State() NodeState { - return NodeStateFromV2( - (*netmap.NodeInfo)(i). - GetState(), - ) -} - -// SetState sets node state. -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 deleted file mode 100644 index ebcd393..0000000 --- a/pkg/netmap/node_info_test.go +++ /dev/null @@ -1,263 +0,0 @@ -package netmap - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - testv2 "github.com/nspcc-dev/neofs-api-go/v2/netmap/test" - "github.com/stretchr/testify/require" -) - -func TestNodeStateFromV2(t *testing.T) { - for _, item := range []struct { - s NodeState - sV2 netmap.NodeState - }{ - { - s: 0, - sV2: netmap.UnspecifiedState, - }, - { - s: NodeStateOnline, - sV2: netmap.Online, - }, - { - s: NodeStateOffline, - sV2: netmap.Offline, - }, - } { - require.Equal(t, item.s, NodeStateFromV2(item.sV2)) - require.Equal(t, item.sV2, item.s.ToV2()) - } -} - -func TestNodeAttributeFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *netmap.Attribute - - require.Nil(t, NewNodeAttributeFromV2(x)) - }) - - t.Run("from non-nil", func(t *testing.T) { - aV2 := testv2.GenerateAttribute(false) - - a := NewNodeAttributeFromV2(aV2) - - require.Equal(t, aV2, a.ToV2()) - }) -} - -func TestNodeAttribute_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *NodeAttribute - - require.Nil(t, x.ToV2()) - }) -} - -func TestNodeAttribute_Key(t *testing.T) { - a := NewNodeAttribute() - key := "some key" - - a.SetKey(key) - - require.Equal(t, key, a.Key()) -} - -func TestNodeAttribute_Value(t *testing.T) { - a := NewNodeAttribute() - val := "some value" - - a.SetValue(val) - - require.Equal(t, val, a.Value()) -} - -func TestNodeAttribute_ParentKeys(t *testing.T) { - a := NewNodeAttribute() - keys := []string{"par1", "par2"} - - a.SetParentKeys(keys...) - - require.Equal(t, keys, a.ParentKeys()) -} - -func testNodeAttribute() *NodeAttribute { - a := new(NodeAttribute) - a.SetKey("key") - a.SetValue("value") - a.SetParentKeys("par1", "par2") - - return a -} - -func TestNodeInfoFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *netmap.NodeInfo - - require.Nil(t, NewNodeInfoFromV2(x)) - }) - - t.Run("from non-nil", func(t *testing.T) { - iV2 := testv2.GenerateNodeInfo(false) - - i := NewNodeInfoFromV2(iV2) - - require.Equal(t, iV2, i.ToV2()) - }) -} - -func TestNodeInfo_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *NodeInfo - - require.Nil(t, x.ToV2()) - }) -} - -func TestNodeInfo_PublicKey(t *testing.T) { - i := new(NodeInfo) - key := []byte{1, 2, 3} - - i.SetPublicKey(key) - - require.Equal(t, key, i.PublicKey()) -} - -func TestNodeInfo_IterateAddresses(t *testing.T) { - i := new(NodeInfo) - - as := []string{"127.0.0.1:8080", "127.0.0.1:8081"} - - i.SetAddresses(as...) - - as2 := make([]string, 0, i.NumberOfAddresses()) - - IterateAllAddresses(i, func(addr string) { - as2 = append(as2, addr) - }) - - require.Equal(t, as, as2) - require.EqualValues(t, len(as), i.NumberOfAddresses()) -} - -func TestNodeInfo_State(t *testing.T) { - i := new(NodeInfo) - s := NodeStateOnline - - i.SetState(s) - - require.Equal(t, s, i.State()) -} - -func TestNodeInfo_Attributes(t *testing.T) { - i := new(NodeInfo) - as := []*NodeAttribute{testNodeAttribute(), testNodeAttribute()} - - i.SetAttributes(as...) - - require.Equal(t, as, i.Attributes()) -} - -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.SetAddresses("192.168.0.1", "192.168.0.2") - i.SetState(NodeStateOnline) - i.SetAttributes(testNodeAttribute()) - - t.Run("binary", func(t *testing.T) { - data, err := i.Marshal() - require.NoError(t, err) - - i2 := NewNodeInfo() - require.NoError(t, i2.Unmarshal(data)) - - 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) - }) -} - -func TestNewNodeAttribute(t *testing.T) { - t.Run("default values", func(t *testing.T) { - attr := NewNodeAttribute() - - // check initial values - require.Empty(t, attr.Key()) - require.Empty(t, attr.Value()) - require.Nil(t, attr.ParentKeys()) - - // convert to v2 message - attrV2 := attr.ToV2() - - require.Empty(t, attrV2.GetKey()) - require.Empty(t, attrV2.GetValue()) - require.Nil(t, attrV2.GetParents()) - }) -} - -func TestNewNodeInfo(t *testing.T) { - t.Run("default values", func(t *testing.T) { - ni := NewNodeInfo() - - // check initial values - require.Nil(t, ni.PublicKey()) - - require.Zero(t, ni.NumberOfAddresses()) - require.Nil(t, ni.Attributes()) - require.Zero(t, ni.State()) - - // convert to v2 message - niV2 := ni.ToV2() - - require.Nil(t, niV2.GetPublicKey()) - require.Zero(t, niV2.NumberOfAddresses()) - require.Nil(t, niV2.GetAttributes()) - require.EqualValues(t, netmap.UnspecifiedState, niV2.GetState()) - }) -} - -func TestNodeState_String(t *testing.T) { - toPtr := func(v NodeState) *NodeState { - return &v - } - - testEnumStrings(t, new(NodeState), []enumStringItem{ - {val: toPtr(NodeStateOnline), str: "ONLINE"}, - {val: toPtr(NodeStateOffline), str: "OFFLINE"}, - {val: toPtr(0), str: "UNSPECIFIED"}, - }) -} diff --git a/pkg/netmap/operation.go b/pkg/netmap/operation.go deleted file mode 100644 index af3e042..0000000 --- a/pkg/netmap/operation.go +++ /dev/null @@ -1,116 +0,0 @@ -package netmap - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// Operation is an enumeration of v2-compatible filtering operations. -type Operation uint32 - -const ( - _ Operation = iota - - // OpEQ is an "Equal" operation. - OpEQ - - // OpNE is a "Not equal" operation. - OpNE - - // OpGT is a "Greater than" operation. - OpGT - - // OpGE is a "Greater than or equal to" operation. - OpGE - - // OpLT is a "Less than" operation. - OpLT - - // OpLE is a "Less than or equal to" operation. - OpLE - - // OpOR is an "OR" operation. - OpOR - - // OpAND is an "AND" operation. - OpAND -) - -// OperationFromV2 converts v2 Operation to Operation. -func OperationFromV2(op netmap.Operation) Operation { - switch op { - default: - return 0 - case netmap.OR: - return OpOR - case netmap.AND: - return OpAND - case netmap.GE: - return OpGE - case netmap.GT: - return OpGT - case netmap.LE: - return OpLE - case netmap.LT: - return OpLT - case netmap.EQ: - return OpEQ - case netmap.NE: - return OpNE - } -} - -// ToV2 converts Operation to v2 Operation. -func (op Operation) ToV2() netmap.Operation { - switch op { - default: - return netmap.UnspecifiedOperation - case OpOR: - return netmap.OR - case OpAND: - return netmap.AND - case OpGE: - return netmap.GE - case OpGT: - return netmap.GT - case OpLE: - return netmap.LE - case OpLT: - return netmap.LT - case OpEQ: - return netmap.EQ - case OpNE: - return netmap.NE - } -} - -// String returns string representation of Operation. -// -// String mapping: -// * OpNE: NE; -// * OpEQ: EQ; -// * OpLT: LT; -// * OpLE: LE; -// * OpGT: GT; -// * OpGE: GE; -// * OpAND: AND; -// * OpOR: OR; -// * default: OPERATION_UNSPECIFIED. -func (op Operation) String() string { - return op.ToV2().String() -} - -// FromString parses Operation from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (op *Operation) FromString(s string) bool { - var g netmap.Operation - - ok := g.FromString(s) - - if ok { - *op = OperationFromV2(g) - } - - return ok -} diff --git a/pkg/netmap/operation_test.go b/pkg/netmap/operation_test.go deleted file mode 100644 index e8b74e3..0000000 --- a/pkg/netmap/operation_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package netmap - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - "github.com/stretchr/testify/require" -) - -func TestOperationFromV2(t *testing.T) { - for _, item := range []struct { - op Operation - opV2 netmap.Operation - }{ - { - op: 0, - opV2: netmap.UnspecifiedOperation, - }, - { - op: OpEQ, - opV2: netmap.EQ, - }, - { - op: OpNE, - opV2: netmap.NE, - }, - { - op: OpOR, - opV2: netmap.OR, - }, - { - op: OpAND, - opV2: netmap.AND, - }, - { - op: OpLE, - opV2: netmap.LE, - }, - { - op: OpLT, - opV2: netmap.LT, - }, - { - op: OpGT, - opV2: netmap.GT, - }, - { - op: OpGE, - opV2: netmap.GE, - }, - } { - require.Equal(t, item.op, OperationFromV2(item.opV2)) - require.Equal(t, item.opV2, item.op.ToV2()) - } -} - -func TestOperation_String(t *testing.T) { - toPtr := func(v Operation) *Operation { - return &v - } - - testEnumStrings(t, new(Operation), []enumStringItem{ - {val: toPtr(OpEQ), str: "EQ"}, - {val: toPtr(OpNE), str: "NE"}, - {val: toPtr(OpGT), str: "GT"}, - {val: toPtr(OpGE), str: "GE"}, - {val: toPtr(OpLT), str: "LT"}, - {val: toPtr(OpLE), str: "LE"}, - {val: toPtr(OpAND), str: "AND"}, - {val: toPtr(OpOR), str: "OR"}, - {val: toPtr(0), str: "OPERATION_UNSPECIFIED"}, - }) -} diff --git a/pkg/netmap/policy.go b/pkg/netmap/policy.go deleted file mode 100644 index dc2e54e..0000000 --- a/pkg/netmap/policy.go +++ /dev/null @@ -1,159 +0,0 @@ -package netmap - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// PlacementPolicy represents v2-compatible placement policy. -type PlacementPolicy netmap.PlacementPolicy - -// NewPlacementPolicy creates and returns new PlacementPolicy instance. -// -// Defaults: -// - backupFactor: 0; -// - replicas nil; -// - selectors nil; -// - filters nil. -func NewPlacementPolicy() *PlacementPolicy { - return NewPlacementPolicyFromV2(new(netmap.PlacementPolicy)) -} - -// NewPlacementPolicyFromV2 converts v2 PlacementPolicy to PlacementPolicy. -// -// Nil netmap.PlacementPolicy converts to nil. -func NewPlacementPolicyFromV2(f *netmap.PlacementPolicy) *PlacementPolicy { - return (*PlacementPolicy)(f) -} - -// ToV2 converts PlacementPolicy to v2 PlacementPolicy. -// -// Nil PlacementPolicy converts to nil. -func (p *PlacementPolicy) ToV2() *netmap.PlacementPolicy { - return (*netmap.PlacementPolicy)(p) -} - -// Replicas returns list of object replica descriptors. -func (p *PlacementPolicy) Replicas() []*Replica { - rs := (*netmap.PlacementPolicy)(p). - GetReplicas() - - if rs == nil { - return nil - } - - res := make([]*Replica, 0, len(rs)) - - for i := range rs { - res = append(res, NewReplicaFromV2(rs[i])) - } - - return res -} - -// SetReplicas sets list of object replica descriptors. -func (p *PlacementPolicy) SetReplicas(rs ...*Replica) { - var rsV2 []*netmap.Replica - - if rs != nil { - rsV2 = make([]*netmap.Replica, 0, len(rs)) - - for i := range rs { - rsV2 = append(rsV2, rs[i].ToV2()) - } - } - - (*netmap.PlacementPolicy)(p). - SetReplicas(rsV2) -} - -// ContainerBackupFactor returns container backup factor. -func (p *PlacementPolicy) ContainerBackupFactor() uint32 { - return (*netmap.PlacementPolicy)(p). - GetContainerBackupFactor() -} - -// SetContainerBackupFactor sets container backup factor. -func (p *PlacementPolicy) SetContainerBackupFactor(f uint32) { - (*netmap.PlacementPolicy)(p). - SetContainerBackupFactor(f) -} - -// Selector returns set of selectors to form the container's nodes subset. -func (p *PlacementPolicy) Selectors() []*Selector { - rs := (*netmap.PlacementPolicy)(p). - GetSelectors() - - if rs == nil { - return nil - } - - res := make([]*Selector, 0, len(rs)) - - for i := range rs { - res = append(res, NewSelectorFromV2(rs[i])) - } - - return res -} - -// SetSelectors sets set of selectors to form the container's nodes subset. -func (p *PlacementPolicy) SetSelectors(ss ...*Selector) { - var ssV2 []*netmap.Selector - - if ss != nil { - ssV2 = make([]*netmap.Selector, 0, len(ss)) - - for i := range ss { - ssV2 = append(ssV2, ss[i].ToV2()) - } - } - - (*netmap.PlacementPolicy)(p). - SetSelectors(ssV2) -} - -// Filters returns list of named filters to reference in selectors. -func (p *PlacementPolicy) Filters() []*Filter { - return filtersFromV2( - (*netmap.PlacementPolicy)(p). - GetFilters(), - ) -} - -// SetFilters sets list of named filters to reference in selectors. -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 deleted file mode 100644 index 43b45ed..0000000 --- a/pkg/netmap/policy_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package netmap - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestPlacementPolicy_CBFWithEmptySelector(t *testing.T) { - nodes := []NodeInfo{ - nodeInfoFromAttributes("ID", "1", "Attr", "Same"), - nodeInfoFromAttributes("ID", "2", "Attr", "Same"), - nodeInfoFromAttributes("ID", "3", "Attr", "Same"), - nodeInfoFromAttributes("ID", "4", "Attr", "Same"), - } - - p1 := newPlacementPolicy(0, - []*Replica{newReplica(2, "")}, - nil, // selectors - nil, // filters - ) - - p2 := newPlacementPolicy(3, - []*Replica{newReplica(2, "")}, - nil, // selectors - nil, // filters - ) - - p3 := newPlacementPolicy(3, - []*Replica{newReplica(2, "X")}, - []*Selector{newSelector("X", "", ClauseDistinct, 2, "*")}, - nil, // filters - ) - - p4 := newPlacementPolicy(3, - []*Replica{newReplica(2, "X")}, - []*Selector{newSelector("X", "Attr", ClauseSame, 2, "*")}, - nil, // filters - ) - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - - v, err := nm.GetContainerNodes(p1, nil) - require.NoError(t, err) - assert.Len(t, v.Flatten(), 4) - - v, err = nm.GetContainerNodes(p2, nil) - require.NoError(t, err) - assert.Len(t, v.Flatten(), 4) - - v, err = nm.GetContainerNodes(p3, nil) - require.NoError(t, err) - assert.Len(t, v.Flatten(), 4) - - v, err = nm.GetContainerNodes(p4, nil) - require.NoError(t, err) - assert.Len(t, v.Flatten(), 4) -} - -func TestPlacementPolicyFromV2(t *testing.T) { - pV2 := new(netmap.PlacementPolicy) - - pV2.SetReplicas([]*netmap.Replica{ - testReplica().ToV2(), - testReplica().ToV2(), - }) - - pV2.SetContainerBackupFactor(3) - - pV2.SetSelectors([]*netmap.Selector{ - testSelector().ToV2(), - testSelector().ToV2(), - }) - - pV2.SetFilters([]*netmap.Filter{ - testFilter().ToV2(), - testFilter().ToV2(), - }) - - p := NewPlacementPolicyFromV2(pV2) - - require.Equal(t, pV2, p.ToV2()) -} - -func TestPlacementPolicy_Replicas(t *testing.T) { - p := NewPlacementPolicy() - rs := []*Replica{testReplica(), testReplica()} - - p.SetReplicas(rs...) - - require.Equal(t, rs, p.Replicas()) -} - -func TestPlacementPolicy_ContainerBackupFactor(t *testing.T) { - p := NewPlacementPolicy() - f := uint32(3) - - p.SetContainerBackupFactor(f) - - require.Equal(t, f, p.ContainerBackupFactor()) -} - -func TestPlacementPolicy_Selectors(t *testing.T) { - p := NewPlacementPolicy() - ss := []*Selector{testSelector(), testSelector()} - - p.SetSelectors(ss...) - - require.Equal(t, ss, p.Selectors()) -} - -func TestPlacementPolicy_Filters(t *testing.T) { - p := NewPlacementPolicy() - fs := []*Filter{testFilter(), testFilter()} - - p.SetFilters(fs...) - - 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) - }) -} - -func TestNewPlacementPolicy(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *PlacementPolicy - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - pp := NewPlacementPolicy() - - // check initial values - require.Nil(t, pp.Replicas()) - require.Nil(t, pp.Filters()) - require.Nil(t, pp.Selectors()) - require.Zero(t, pp.ContainerBackupFactor()) - - // convert to v2 message - ppV2 := pp.ToV2() - - require.Nil(t, ppV2.GetReplicas()) - require.Nil(t, ppV2.GetFilters()) - require.Nil(t, ppV2.GetSelectors()) - require.Zero(t, ppV2.GetContainerBackupFactor()) - }) -} - -func TestNewPlacementPolicyFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *netmap.PlacementPolicy - - require.Nil(t, NewPlacementPolicyFromV2(x)) - }) -} diff --git a/pkg/netmap/replica.go b/pkg/netmap/replica.go deleted file mode 100644 index 9bceb7f..0000000 --- a/pkg/netmap/replica.go +++ /dev/null @@ -1,87 +0,0 @@ -package netmap - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// Replica represents v2-compatible object replica descriptor. -type Replica netmap.Replica - -// NewReplica creates and returns new Replica instance. -// -// Defaults: -// - count: 0; -// - selector: "". -func NewReplica() *Replica { - return NewReplicaFromV2(new(netmap.Replica)) -} - -// NewReplicaFromV2 converts v2 Replica to Replica. -// -// Nil netmap.Replica converts to nil. -func NewReplicaFromV2(f *netmap.Replica) *Replica { - return (*Replica)(f) -} - -// ToV2 converts Replica to v2 Replica. -// -// Nil Replica converts to nil. -func (r *Replica) ToV2() *netmap.Replica { - return (*netmap.Replica)(r) -} - -// Count returns number of object replicas. -func (r *Replica) Count() uint32 { - return (*netmap.Replica)(r). - GetCount() -} - -// SetCount sets number of object replicas. -func (r *Replica) SetCount(c uint32) { - (*netmap.Replica)(r). - SetCount(c) -} - -// Selector returns name of selector bucket to put replicas. -func (r *Replica) Selector() string { - return (*netmap.Replica)(r). - GetSelector() -} - -// SetSelector sets name of selector bucket to put replicas. -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 deleted file mode 100644 index c1b0dba..0000000 --- a/pkg/netmap/replica_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package netmap - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - testv2 "github.com/nspcc-dev/neofs-api-go/v2/netmap/test" - "github.com/stretchr/testify/require" -) - -func testReplica() *Replica { - r := new(Replica) - r.SetCount(3) - r.SetSelector("selector") - - return r -} - -func TestReplicaFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *netmap.Replica - - require.Nil(t, NewReplicaFromV2(x)) - }) - - t.Run("from non-nil", func(t *testing.T) { - rV2 := testv2.GenerateReplica(false) - - r := NewReplicaFromV2(rV2) - - require.Equal(t, rV2, r.ToV2()) - }) -} - -func TestReplica_Count(t *testing.T) { - r := NewReplica() - c := uint32(3) - - r.SetCount(c) - - require.Equal(t, c, r.Count()) -} - -func TestReplica_Selector(t *testing.T) { - r := NewReplica() - s := "some selector" - - r.SetSelector(s) - - 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) - }) -} - -func TestReplica_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Replica - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewReplica(t *testing.T) { - t.Run("default values", func(t *testing.T) { - r := NewReplica() - - // check initial values - require.Zero(t, r.Count()) - require.Empty(t, r.Selector()) - - // convert to v2 message - rV2 := r.ToV2() - - require.Zero(t, rV2.GetCount()) - require.Empty(t, rV2.GetSelector()) - }) -} diff --git a/pkg/netmap/selector.go b/pkg/netmap/selector.go deleted file mode 100644 index b4100d4..0000000 --- a/pkg/netmap/selector.go +++ /dev/null @@ -1,275 +0,0 @@ -package netmap - -import ( - "fmt" - "sort" - - "github.com/nspcc-dev/hrw" - "github.com/nspcc-dev/neofs-api-go/v2/netmap" -) - -// Selector represents v2-compatible netmap selector. -type Selector netmap.Selector - -// processSelectors processes selectors and returns error is any of them is invalid. -func (c *Context) processSelectors(p *PlacementPolicy) error { - for _, s := range p.Selectors() { - if s == nil { - return fmt.Errorf("%w: SELECT", ErrMissingField) - } else if s.Filter() != MainFilterName { - _, ok := c.Filters[s.Filter()] - if !ok { - return fmt.Errorf("%w: SELECT FROM '%s'", ErrFilterNotFound, s.Filter()) - } - } - - c.Selectors[s.Name()] = s - - result, err := c.getSelection(p, s) - if err != nil { - return err - } - - c.Selections[s.Name()] = result - } - - return nil -} - -// GetNodesCount returns amount of buckets and minimum number of nodes in every bucket -// for the given selector. -func GetNodesCount(_ *PlacementPolicy, s *Selector) (int, int) { - switch s.Clause() { - case ClauseSame: - return 1, int(s.Count()) - default: - return int(s.Count()), 1 - } -} - -// getSelection returns nodes grouped by s.attribute. -// Last argument specifies if more buckets can be used to fullfill CBF. -func (c *Context) getSelection(p *PlacementPolicy, s *Selector) ([]Nodes, error) { - bucketCount, nodesInBucket := GetNodesCount(p, s) - buckets := c.getSelectionBase(s) - - if len(buckets) < bucketCount { - return nil, fmt.Errorf("%w: '%s'", ErrNotEnoughNodes, s.Name()) - } - - if len(c.pivot) == 0 { - // Deterministic order in case of zero seed. - if s.Attribute() == "" { - sort.Slice(buckets, func(i, j int) bool { - return buckets[i].nodes[0].ID < buckets[j].nodes[0].ID - }) - } else { - sort.Slice(buckets, func(i, j int) bool { - return buckets[i].attr < buckets[j].attr - }) - } - } - - maxNodesInBucket := nodesInBucket * int(c.cbf) - nodes := make([]Nodes, 0, len(buckets)) - fallback := make([]Nodes, 0, len(buckets)) - - for i := range buckets { - ns := buckets[i].nodes - if len(ns) >= maxNodesInBucket { - nodes = append(nodes, ns[:maxNodesInBucket]) - } else if len(ns) >= nodesInBucket { - fallback = append(fallback, ns) - } - } - - if len(nodes) < bucketCount { - // Fallback to using minimum allowed backup factor (1). - nodes = append(nodes, fallback...) - if len(nodes) < bucketCount { - return nil, fmt.Errorf("%w: '%s'", ErrNotEnoughNodes, s.Name()) - } - } - - if len(c.pivot) != 0 { - weights := make([]float64, len(nodes)) - for i := range nodes { - weights[i] = GetBucketWeight(nodes[i], c.aggregator(), c.weightFunc) - } - - hrw.SortSliceByWeightIndex(nodes, weights, c.pivotHash) - } - - if s.Attribute() == "" { - nodes, fallback = nodes[:bucketCount], nodes[bucketCount:] - for i := range fallback { - index := i % bucketCount - if len(nodes[index]) >= maxNodesInBucket { - break - } - nodes[index] = append(nodes[index], fallback[i]...) - } - } - - return nodes[:bucketCount], nil -} - -type nodeAttrPair struct { - attr string - nodes Nodes -} - -// getSelectionBase returns nodes grouped by selector attribute. -// It it guaranteed that each pair will contain at least one node. -func (c *Context) getSelectionBase(s *Selector) []nodeAttrPair { - f := c.Filters[s.Filter()] - isMain := s.Filter() == MainFilterName - result := []nodeAttrPair{} - nodeMap := map[string]Nodes{} - attr := s.Attribute() - - for i := range c.Netmap.Nodes { - if isMain || c.match(f, c.Netmap.Nodes[i]) { - if attr == "" { - // Default attribute is transparent identifier which is different for every node. - result = append(result, nodeAttrPair{attr: "", nodes: Nodes{c.Netmap.Nodes[i]}}) - } else { - v := c.Netmap.Nodes[i].Attribute(attr) - nodeMap[v] = append(nodeMap[v], c.Netmap.Nodes[i]) - } - } - } - - if attr != "" { - for k, ns := range nodeMap { - result = append(result, nodeAttrPair{attr: k, nodes: ns}) - } - } - - if len(c.pivot) != 0 { - for i := range result { - hrw.SortSliceByWeightValue(result[i].nodes, result[i].nodes.Weights(c.weightFunc), c.pivotHash) - } - } - - return result -} - -// NewSelector creates and returns new Selector instance. -// -// Defaults: -// - name: ""; -// - attribute: ""; -// - filter: ""; -// - clause: ClauseUnspecified; -// - count: 0. -func NewSelector() *Selector { - return NewSelectorFromV2(new(netmap.Selector)) -} - -// NewSelectorFromV2 converts v2 Selector to Selector. -// -// Nil netmap.Selector converts to nil. -func NewSelectorFromV2(f *netmap.Selector) *Selector { - return (*Selector)(f) -} - -// ToV2 converts Selector to v2 Selector. -// -// Nil Selector converts to nil. -func (s *Selector) ToV2() *netmap.Selector { - return (*netmap.Selector)(s) -} - -// Name returns selector name. -func (s *Selector) Name() string { - return (*netmap.Selector)(s). - GetName() -} - -// SetName sets selector name. -func (s *Selector) SetName(name string) { - (*netmap.Selector)(s). - SetName(name) -} - -// Count returns count of nodes to select from bucket. -func (s *Selector) Count() uint32 { - return (*netmap.Selector)(s). - GetCount() -} - -// SetCount sets count of nodes to select from bucket. -func (s *Selector) SetCount(c uint32) { - (*netmap.Selector)(s). - SetCount(c) -} - -// Clause returns modifier showing how to form a bucket. -func (s *Selector) Clause() Clause { - return ClauseFromV2( - (*netmap.Selector)(s). - GetClause(), - ) -} - -// SetClause sets modifier showing how to form a bucket. -func (s *Selector) SetClause(c Clause) { - (*netmap.Selector)(s). - SetClause(c.ToV2()) -} - -// Attribute returns attribute bucket to select from. -func (s *Selector) Attribute() string { - return (*netmap.Selector)(s). - GetAttribute() -} - -// SetAttribute sets attribute bucket to select from. -func (s *Selector) SetAttribute(a string) { - (*netmap.Selector)(s). - SetAttribute(a) -} - -// Filter returns filter reference to select from. -func (s *Selector) Filter() string { - return (*netmap.Selector)(s). - GetFilter() -} - -// SetFilter sets filter reference to select from. -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 deleted file mode 100644 index 6854288..0000000 --- a/pkg/netmap/selector_test.go +++ /dev/null @@ -1,531 +0,0 @@ -package netmap - -import ( - "errors" - "fmt" - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/netmap" - testv2 "github.com/nspcc-dev/neofs-api-go/v2/netmap/test" - "github.com/stretchr/testify/require" -) - -func TestPlacementPolicy_UnspecifiedClause(t *testing.T) { - p := newPlacementPolicy(1, - []*Replica{newReplica(1, "X")}, - []*Selector{ - newSelector("X", "", ClauseDistinct, 4, "*"), - }, - nil, - ) - nodes := []NodeInfo{ - nodeInfoFromAttributes("ID", "1", "Country", "RU", "City", "St.Petersburg", "SSD", "0"), - nodeInfoFromAttributes("ID", "2", "Country", "RU", "City", "St.Petersburg", "SSD", "1"), - nodeInfoFromAttributes("ID", "3", "Country", "RU", "City", "Moscow", "SSD", "1"), - nodeInfoFromAttributes("ID", "4", "Country", "RU", "City", "Moscow", "SSD", "1"), - } - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - v, err := nm.GetContainerNodes(p, nil) - require.NoError(t, err) - require.Equal(t, 4, len(v.Flatten())) -} - -func TestPlacementPolicy_Minimal(t *testing.T) { - nodes := []NodeInfo{ - nodeInfoFromAttributes("City", "Saint-Petersburg"), - nodeInfoFromAttributes("City", "Moscow"), - nodeInfoFromAttributes("City", "Berlin"), - nodeInfoFromAttributes("City", "Paris"), - } - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - - runTest := func(t *testing.T, rep uint32, expectError bool) { - p := newPlacementPolicy(0, - []*Replica{newReplica(rep, "")}, - nil, nil) - - v, err := nm.GetContainerNodes(p, nil) - - if expectError { - require.Error(t, err) - return - } - - require.NoError(t, err) - count := int(rep * defaultCBF) - if count > len(nm.Nodes) { - count = len(nm.Nodes) - } - require.EqualValues(t, count, len(v.Flatten())) - } - - t.Run("REP 1", func(t *testing.T) { - runTest(t, 1, false) - }) - t.Run("REP 3", func(t *testing.T) { - runTest(t, 3, false) - }) - t.Run("REP 5", func(t *testing.T) { - runTest(t, 5, true) - }) -} - -// Issue #215. -func TestPlacementPolicy_MultipleREP(t *testing.T) { - p := newPlacementPolicy(1, - []*Replica{ - newReplica(1, "LOC_SPB_PLACE"), - newReplica(1, "LOC_MSK_PLACE"), - }, - []*Selector{ - newSelector("LOC_SPB_PLACE", "", ClauseUnspecified, 1, "LOC_SPB"), - newSelector("LOC_MSK_PLACE", "", ClauseUnspecified, 1, "LOC_MSK"), - }, - []*Filter{ - newFilter("LOC_SPB", "City", "Saint-Petersburg", OpEQ), - newFilter("LOC_MSK", "City", "Moscow", OpEQ), - }, - ) - nodes := []NodeInfo{ - nodeInfoFromAttributes("City", "Saint-Petersburg"), - nodeInfoFromAttributes("City", "Moscow"), - nodeInfoFromAttributes("City", "Berlin"), - nodeInfoFromAttributes("City", "Paris"), - } - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - - v, err := nm.GetContainerNodes(p, nil) - require.NoError(t, err) - - rs := v.Replicas() - require.Equal(t, 2, len(rs)) - require.Equal(t, 1, len(rs[0])) - require.Equal(t, "Saint-Petersburg", rs[0][0].Attribute("City")) - require.Equal(t, 1, len(rs[1])) - require.Equal(t, "Moscow", rs[1][0].Attribute("City")) -} - -func TestPlacementPolicy_DefaultCBF(t *testing.T) { - p := newPlacementPolicy(0, - []*Replica{ - newReplica(1, "EU"), - }, - []*Selector{ - newSelector("EU", "Location", ClauseSame, 1, "*"), - }, - nil) - nodes := []NodeInfo{ - nodeInfoFromAttributes("Location", "Europe", "Country", "RU", "City", "St.Petersburg"), - nodeInfoFromAttributes("Location", "Europe", "Country", "RU", "City", "Moscow"), - nodeInfoFromAttributes("Location", "Europe", "Country", "DE", "City", "Berlin"), - nodeInfoFromAttributes("Location", "Europe", "Country", "FR", "City", "Paris"), - } - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - v, err := nm.GetContainerNodes(p, nil) - require.NoError(t, err) - require.Equal(t, defaultCBF, len(v.Flatten())) -} - -func TestPlacementPolicy_GetPlacementVectors(t *testing.T) { - p := newPlacementPolicy(2, - []*Replica{ - newReplica(1, "SPB"), - newReplica(2, "Americas"), - }, - []*Selector{ - newSelector("SPB", "City", ClauseSame, 1, "SPBSSD"), - newSelector("Americas", "City", ClauseDistinct, 2, "Americas"), - }, - []*Filter{ - newFilter("SPBSSD", "", "", OpAND, - newFilter("", "Country", "RU", OpEQ), - newFilter("", "City", "St.Petersburg", OpEQ), - newFilter("", "SSD", "1", OpEQ)), - newFilter("Americas", "", "", OpOR, - newFilter("", "Continent", "NA", OpEQ), - newFilter("", "Continent", "SA", OpEQ)), - }) - nodes := []NodeInfo{ - nodeInfoFromAttributes("ID", "1", "Country", "RU", "City", "St.Petersburg", "SSD", "0"), - nodeInfoFromAttributes("ID", "2", "Country", "RU", "City", "St.Petersburg", "SSD", "1"), - nodeInfoFromAttributes("ID", "3", "Country", "RU", "City", "Moscow", "SSD", "1"), - nodeInfoFromAttributes("ID", "4", "Country", "RU", "City", "Moscow", "SSD", "1"), - nodeInfoFromAttributes("ID", "5", "Country", "RU", "City", "St.Petersburg", "SSD", "1"), - nodeInfoFromAttributes("ID", "6", "Continent", "NA", "City", "NewYork"), - nodeInfoFromAttributes("ID", "7", "Continent", "AF", "City", "Cairo"), - nodeInfoFromAttributes("ID", "8", "Continent", "AF", "City", "Cairo"), - nodeInfoFromAttributes("ID", "9", "Continent", "SA", "City", "Lima"), - nodeInfoFromAttributes("ID", "10", "Continent", "AF", "City", "Cairo"), - nodeInfoFromAttributes("ID", "11", "Continent", "NA", "City", "NewYork"), - nodeInfoFromAttributes("ID", "12", "Continent", "NA", "City", "LosAngeles"), - nodeInfoFromAttributes("ID", "13", "Continent", "SA", "City", "Lima"), - } - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - v, err := nm.GetContainerNodes(p, nil) - require.NoError(t, err) - require.Equal(t, 2, len(v.Replicas())) - require.Equal(t, 6, len(v.Flatten())) - - require.Equal(t, 2, len(v.Replicas()[0])) - ids := map[string]struct{}{} - for _, ni := range v.Replicas()[0] { - require.Equal(t, "RU", ni.Attribute("Country")) - require.Equal(t, "St.Petersburg", ni.Attribute("City")) - require.Equal(t, "1", ni.Attribute("SSD")) - ids[ni.Attribute("ID")] = struct{}{} - } - require.Equal(t, len(v.Replicas()[0]), len(ids), "not all nodes we distinct") - - require.Equal(t, 4, len(v.Replicas()[1])) // 2 cities * 2 HRWB - ids = map[string]struct{}{} - for _, ni := range v.Replicas()[1] { - require.Contains(t, []string{"NA", "SA"}, ni.Attribute("Continent")) - ids[ni.Attribute("ID")] = struct{}{} - } - require.Equal(t, len(v.Replicas()[1]), len(ids), "not all nodes we distinct") -} - -func TestPlacementPolicy_LowerBound(t *testing.T) { - p := newPlacementPolicy( - 2, // backup factor - []*Replica{ - newReplica(1, "X"), - }, - []*Selector{ - newSelector("X", "Country", ClauseSame, 2, "*"), - }, - nil, // filters - ) - - nodes := []NodeInfo{ - nodeInfoFromAttributes("ID", "1", "Country", "DE"), - nodeInfoFromAttributes("ID", "2", "Country", "DE"), - nodeInfoFromAttributes("ID", "3", "Country", "DE"), - } - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - - v, err := nm.GetContainerNodes(p, nil) - require.NoError(t, err) - - require.Equal(t, 3, len(v.Flatten())) -} - -func TestIssue213(t *testing.T) { - p := newPlacementPolicy(1, - []*Replica{ - newReplica(4, ""), - }, - []*Selector{ - newSelector("", "", ClauseDistinct, 4, "LOC_EU"), - }, - []*Filter{ - newFilter("LOC_EU", "Location", "Europe", OpEQ), - }) - nodes := []NodeInfo{ - nodeInfoFromAttributes("Location", "Europe", "Country", "Russia", "City", "Moscow"), - nodeInfoFromAttributes("Location", "Europe", "Country", "Russia", "City", "Saint-Petersburg"), - nodeInfoFromAttributes("Location", "Europe", "Country", "Sweden", "City", "Stockholm"), - nodeInfoFromAttributes("Location", "Europe", "Country", "Finalnd", "City", "Helsinki"), - } - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - - v, err := nm.GetContainerNodes(p, nil) - require.NoError(t, err) - require.Equal(t, 4, len(v.Flatten())) -} - -func TestPlacementPolicy_ProcessSelectors(t *testing.T) { - p := newPlacementPolicy(2, nil, - []*Selector{ - newSelector("SameRU", "City", ClauseSame, 2, "FromRU"), - newSelector("DistinctRU", "City", ClauseDistinct, 2, "FromRU"), - newSelector("Good", "Country", ClauseDistinct, 2, "Good"), - newSelector("Main", "Country", ClauseDistinct, 3, "*"), - }, - []*Filter{ - newFilter("FromRU", "Country", "Russia", OpEQ), - newFilter("Good", "Rating", "4", OpGE), - }) - nodes := []NodeInfo{ - nodeInfoFromAttributes("Country", "Russia", "Rating", "1", "City", "SPB"), - nodeInfoFromAttributes("Country", "Germany", "Rating", "5", "City", "Berlin"), - nodeInfoFromAttributes("Country", "Russia", "Rating", "6", "City", "Moscow"), - nodeInfoFromAttributes("Country", "France", "Rating", "4", "City", "Paris"), - nodeInfoFromAttributes("Country", "France", "Rating", "1", "City", "Lyon"), - nodeInfoFromAttributes("Country", "Russia", "Rating", "5", "City", "SPB"), - nodeInfoFromAttributes("Country", "Russia", "Rating", "7", "City", "Moscow"), - nodeInfoFromAttributes("Country", "Germany", "Rating", "3", "City", "Darmstadt"), - nodeInfoFromAttributes("Country", "Germany", "Rating", "7", "City", "Frankfurt"), - nodeInfoFromAttributes("Country", "Russia", "Rating", "9", "City", "SPB"), - nodeInfoFromAttributes("Country", "Russia", "Rating", "9", "City", "SPB"), - } - - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - c := NewContext(nm) - c.setCBF(p.ContainerBackupFactor()) - require.NoError(t, c.processFilters(p)) - require.NoError(t, c.processSelectors(p)) - - for _, s := range p.Selectors() { - sel := c.Selections[s.Name()] - s := c.Selectors[s.Name()] - bucketCount, nodesInBucket := GetNodesCount(p, s) - nodesInBucket *= int(c.cbf) - targ := fmt.Sprintf("selector '%s'", s.Name()) - require.Equal(t, bucketCount, len(sel), targ) - for _, res := range sel { - require.Equal(t, nodesInBucket, len(res), targ) - for j := range res { - require.True(t, c.applyFilter(s.Filter(), res[j]), targ) - } - } - } - -} - -func TestPlacementPolicy_ProcessSelectorsHRW(t *testing.T) { - p := newPlacementPolicy(1, nil, - []*Selector{ - newSelector("Main", "Country", ClauseDistinct, 3, "*"), - }, nil) - - // bucket weight order: RU > DE > FR - nodes := []NodeInfo{ - nodeInfoFromAttributes("Country", "Germany", AttrPrice, "2", AttrCapacity, "10000"), - nodeInfoFromAttributes("Country", "Germany", AttrPrice, "4", AttrCapacity, "1"), - nodeInfoFromAttributes("Country", "France", AttrPrice, "3", AttrCapacity, "10"), - nodeInfoFromAttributes("Country", "Russia", AttrPrice, "2", AttrCapacity, "10000"), - nodeInfoFromAttributes("Country", "Russia", AttrPrice, "1", AttrCapacity, "10000"), - nodeInfoFromAttributes("Country", "Russia", AttrCapacity, "10000"), - nodeInfoFromAttributes("Country", "France", AttrPrice, "100", AttrCapacity, "1"), - nodeInfoFromAttributes("Country", "France", AttrPrice, "7", AttrCapacity, "10000"), - nodeInfoFromAttributes("Country", "Russia", AttrPrice, "2", AttrCapacity, "1"), - } - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - c := NewContext(nm) - c.setPivot([]byte("containerID")) - c.setCBF(p.ContainerBackupFactor()) - c.weightFunc = newWeightFunc(newMaxNorm(10000), newReverseMinNorm(1)) - c.aggregator = func() aggregator { - return new(maxAgg) - } - - require.NoError(t, c.processFilters(p)) - require.NoError(t, c.processSelectors(p)) - - cnt := c.Selections["Main"] - expected := []Nodes{ - {{Index: 4, Capacity: 10000, Price: 1}}, // best RU - {{Index: 0, Capacity: 10000, Price: 2}}, // best DE - {{Index: 7, Capacity: 10000, Price: 7}}, // best FR - } - require.Equal(t, len(expected), len(cnt)) - for i := range expected { - require.Equal(t, len(expected[i]), len(cnt[i])) - require.Equal(t, expected[i][0].Index, cnt[i][0].Index) - require.Equal(t, expected[i][0].Capacity, cnt[i][0].Capacity) - require.Equal(t, expected[i][0].Price, cnt[i][0].Price) - } - - res, err := nm.GetPlacementVectors(containerNodes(cnt), []byte("objectID")) - require.NoError(t, err) - require.Equal(t, res, cnt) -} - -func newMaxNorm(max float64) normalizer { - return &maxNorm{max: max} -} - -func TestPlacementPolicy_ProcessSelectorsInvalid(t *testing.T) { - testCases := []struct { - name string - p *PlacementPolicy - err error - }{ - { - "MissingSelector", - newPlacementPolicy(2, nil, - []*Selector{nil}, - []*Filter{}), - ErrMissingField, - }, - { - "InvalidFilterReference", - newPlacementPolicy(1, nil, - []*Selector{newSelector("MyStore", "Country", ClauseDistinct, 1, "FromNL")}, - []*Filter{newFilter("FromRU", "Country", "Russia", OpEQ)}), - ErrFilterNotFound, - }, - { - "NotEnoughNodes (backup factor)", - newPlacementPolicy(2, nil, - []*Selector{newSelector("MyStore", "Country", ClauseDistinct, 2, "FromRU")}, - []*Filter{newFilter("FromRU", "Country", "Russia", OpEQ)}), - ErrNotEnoughNodes, - }, - { - "NotEnoughNodes (buckets)", - newPlacementPolicy(1, nil, - []*Selector{newSelector("MyStore", "Country", ClauseDistinct, 2, "FromRU")}, - []*Filter{newFilter("FromRU", "Country", "Russia", OpEQ)}), - ErrNotEnoughNodes, - }, - } - nodes := []NodeInfo{ - nodeInfoFromAttributes("Country", "Russia"), - nodeInfoFromAttributes("Country", "Germany"), - nodeInfoFromAttributes(), - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - nm, err := NewNetmap(NodesFromInfo(nodes)) - require.NoError(t, err) - c := NewContext(nm) - c.setCBF(tc.p.ContainerBackupFactor()) - require.NoError(t, c.processFilters(tc.p)) - - err = c.processSelectors(tc.p) - require.True(t, errors.Is(err, tc.err), "got: %v", err) - }) - } -} - -func testSelector() *Selector { - s := new(Selector) - s.SetName("name") - s.SetCount(3) - s.SetFilter("filter") - s.SetAttribute("attribute") - s.SetClause(ClauseDistinct) - - return s -} - -func TestSelector_Name(t *testing.T) { - s := NewSelector() - name := "some name" - - s.SetName(name) - - require.Equal(t, name, s.Name()) -} - -func TestSelector_Count(t *testing.T) { - s := NewSelector() - c := uint32(3) - - s.SetCount(c) - - require.Equal(t, c, s.Count()) -} - -func TestSelector_Clause(t *testing.T) { - s := NewSelector() - c := ClauseSame - - s.SetClause(c) - - require.Equal(t, c, s.Clause()) -} - -func TestSelector_Attribute(t *testing.T) { - s := NewSelector() - a := "some attribute" - - s.SetAttribute(a) - - require.Equal(t, a, s.Attribute()) -} - -func TestSelector_Filter(t *testing.T) { - s := NewSelector() - f := "some filter" - - s.SetFilter(f) - - 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) - }) -} - -func TestSelector_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Selector - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewSelectorFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *netmap.Selector - - require.Nil(t, NewSelectorFromV2(x)) - }) - - t.Run("from non-nil", func(t *testing.T) { - sV2 := testv2.GenerateSelector(false) - - s := NewSelectorFromV2(sV2) - - require.Equal(t, sV2, s.ToV2()) - }) -} - -func TestNewSelector(t *testing.T) { - t.Run("default values", func(t *testing.T) { - s := NewSelector() - - // check initial values - require.Zero(t, s.Count()) - require.Equal(t, ClauseUnspecified, s.Clause()) - require.Empty(t, s.Attribute()) - require.Empty(t, s.Name()) - require.Empty(t, s.Filter()) - - // convert to v2 message - sV2 := s.ToV2() - - require.Zero(t, sV2.GetCount()) - require.Equal(t, netmap.UnspecifiedClause, sV2.GetClause()) - require.Empty(t, sV2.GetAttribute()) - require.Empty(t, sV2.GetName()) - require.Empty(t, sV2.GetFilter()) - }) -} diff --git a/pkg/netmap/test/generate.go b/pkg/netmap/test/generate.go deleted file mode 100644 index d8d431d..0000000 --- a/pkg/netmap/test/generate.go +++ /dev/null @@ -1,147 +0,0 @@ -package netmaptest - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/netmap" -) - -func filter(withInner bool) *netmap.Filter { - x := netmap.NewFilter() - - x.SetName("name") - x.SetKey("key") - x.SetValue("value") - x.SetOperation(netmap.OpAND) - - if withInner { - x.SetInnerFilters(filter(false), filter(false)) - } - - return x -} - -// Filter returns random netmap.Filter. -func Filter() *netmap.Filter { - return filter(true) -} - -// Replica returns random netmap.Replica. -func Replica() *netmap.Replica { - x := netmap.NewReplica() - - x.SetCount(666) - x.SetSelector("selector") - - return x -} - -// Selector returns random netmap.Selector. -func Selector() *netmap.Selector { - x := netmap.NewSelector() - - x.SetCount(11) - x.SetName("name") - x.SetFilter("filter") - x.SetAttribute("attribute") - x.SetClause(netmap.ClauseDistinct) - - return x -} - -// PlacementPolicy returns random netmap.PlacementPolicy. -func PlacementPolicy() *netmap.PlacementPolicy { - x := netmap.NewPlacementPolicy() - - x.SetContainerBackupFactor(9) - x.SetFilters(Filter(), Filter()) - x.SetReplicas(Replica(), Replica()) - x.SetSelectors(Selector(), Selector()) - - return x -} - -// NetworkParameter returns random netmap.NetworkParameter. -func NetworkParameter() *netmap.NetworkParameter { - x := netmap.NewNetworkParameter() - - x.SetKey([]byte("key")) - x.SetValue([]byte("value")) - - return x -} - -// NetworkConfig returns random netmap.NetworkConfig. -func NetworkConfig() *netmap.NetworkConfig { - x := netmap.NewNetworkConfig() - - x.SetParameters( - NetworkParameter(), - NetworkParameter(), - ) - - return x -} - -// NetworkInfo returns random netmap.NetworkInfo. -func NetworkInfo() *netmap.NetworkInfo { - x := netmap.NewNetworkInfo() - - x.SetCurrentEpoch(21) - x.SetMagicNumber(32) - x.SetMsPerBlock(43) - x.SetNetworkConfig(NetworkConfig()) - - return x -} - -// NodeAttribute returns random netmap.NodeAttribute. -func NodeAttribute() *netmap.NodeAttribute { - x := netmap.NewNodeAttribute() - - x.SetKey("key") - x.SetValue("value") - x.SetParentKeys("parent1", "parent2") - - return x -} - -// NodeInfo returns random netmap.NodeInfo. -func NodeInfo() *netmap.NodeInfo { - x := netmap.NewNodeInfo() - - x.SetAddresses("address 1", "address 2") - x.SetPublicKey([]byte("public key")) - x.SetState(netmap.NodeStateOnline) - x.SetAttributes(NodeAttribute(), NodeAttribute()) - - return x -} - -// Node returns random netmap.Node. -func Node() *netmap.Node { - return &netmap.Node{ - ID: 1, - Index: 2, - Capacity: 3, - Price: 4, - AttrMap: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - NodeInfo: NodeInfo(), - } -} - -// Nodes returns random netmap.Nodes. -func Nodes() netmap.Nodes { - return netmap.Nodes{Node(), Node()} -} - -// Netmap returns random netmap.Netmap. -func Netmap() *netmap.Netmap { - nm, err := netmap.NewNetmap(Nodes()) - if err != nil { - panic(err) - } - - return nm -} diff --git a/pkg/object/address.go b/pkg/object/address.go deleted file mode 100644 index f1072a9..0000000 --- a/pkg/object/address.go +++ /dev/null @@ -1,131 +0,0 @@ -package object - -import ( - "errors" - "strings" - - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// Address represents v2-compatible object address. -type Address refs.Address - -var errInvalidAddressString = errors.New("incorrect format of the string object address") - -const ( - addressParts = 2 - addressSeparator = "/" -) - -// NewAddressFromV2 converts v2 Address message to Address. -// -// Nil refs.Address converts to nil. -func NewAddressFromV2(aV2 *refs.Address) *Address { - return (*Address)(aV2) -} - -// NewAddress creates and initializes blank Address. -// -// Works similar as NewAddressFromV2(new(Address)). -// -// Defaults: -// - cid: nil; -// - oid: nil. -func NewAddress() *Address { - return NewAddressFromV2(new(refs.Address)) -} - -// ToV2 converts Address to v2 Address message. -// -// Nil Address converts to nil. -func (a *Address) ToV2() *refs.Address { - return (*refs.Address)(a) -} - -// ContainerID returns container identifier. -func (a *Address) ContainerID() *cid.ID { - return cid.NewFromV2( - (*refs.Address)(a).GetContainerID(), - ) -} - -// SetContainerID sets container identifier. -func (a *Address) SetContainerID(id *cid.ID) { - (*refs.Address)(a).SetContainerID(id.ToV2()) -} - -// ObjectID returns object identifier. -func (a *Address) ObjectID() *ID { - return NewIDFromV2( - (*refs.Address)(a).GetObjectID(), - ) -} - -// SetObjectID sets object identifier. -func (a *Address) SetObjectID(id *ID) { - (*refs.Address)(a).SetObjectID(id.ToV2()) -} - -// Parse converts base58 string representation into Address. -func (a *Address) Parse(s string) error { - var ( - err error - oid = NewID() - id = cid.New() - parts = strings.Split(s, addressSeparator) - ) - - if len(parts) != addressParts { - return errInvalidAddressString - } else if err = id.Parse(parts[0]); err != nil { - return err - } else if err = oid.Parse(parts[1]); err != nil { - return err - } - - a.SetObjectID(oid) - a.SetContainerID(id) - - return nil -} - -// String returns string representation of Object.Address. -func (a *Address) String() string { - return strings.Join([]string{ - a.ContainerID().String(), - a.ObjectID().String(), - }, addressSeparator) -} - -// Marshal marshals Address into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (a *Address) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.Address)(a). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Address. -func (a *Address) Unmarshal(data []byte) error { - return (*refs.Address)(a). - Unmarshal(data) -} - -// MarshalJSON encodes Address to protobuf JSON format. -func (a *Address) MarshalJSON() ([]byte, error) { - return (*refs.Address)(a). - MarshalJSON() -} - -// UnmarshalJSON decodes Address from protobuf JSON format. -func (a *Address) UnmarshalJSON(data []byte) error { - return (*refs.Address)(a). - UnmarshalJSON(data) -} diff --git a/pkg/object/address_test.go b/pkg/object/address_test.go deleted file mode 100644 index 6d97cb7..0000000 --- a/pkg/object/address_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package object - -import ( - "strings" - "testing" - - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func TestAddress_SetContainerID(t *testing.T) { - a := NewAddress() - - id := cidtest.Generate() - - a.SetContainerID(id) - - require.Equal(t, id, a.ContainerID()) -} - -func TestAddress_SetObjectID(t *testing.T) { - a := NewAddress() - - oid := randID(t) - - a.SetObjectID(oid) - - require.Equal(t, oid, a.ObjectID()) -} - -func TestAddress_Parse(t *testing.T) { - cid := cidtest.Generate() - - oid := NewID() - oid.SetSHA256(randSHA256Checksum(t)) - - t.Run("should parse successful", func(t *testing.T) { - s := strings.Join([]string{cid.String(), oid.String()}, addressSeparator) - a := NewAddress() - - require.NoError(t, a.Parse(s)) - require.Equal(t, oid, a.ObjectID()) - require.Equal(t, cid, a.ContainerID()) - }) - - t.Run("should fail for bad address", func(t *testing.T) { - s := strings.Join([]string{cid.String()}, addressSeparator) - require.EqualError(t, NewAddress().Parse(s), errInvalidAddressString.Error()) - }) - - t.Run("should fail on container.ID", func(t *testing.T) { - s := strings.Join([]string{"1", "2"}, addressSeparator) - require.Error(t, NewAddress().Parse(s)) - }) - - t.Run("should fail on object.ID", func(t *testing.T) { - s := strings.Join([]string{cid.String(), "2"}, addressSeparator) - require.Error(t, NewAddress().Parse(s)) - }) -} - -func TestAddressEncoding(t *testing.T) { - a := NewAddress() - a.SetObjectID(randID(t)) - a.SetContainerID(cidtest.Generate()) - - t.Run("binary", func(t *testing.T) { - data, err := a.Marshal() - require.NoError(t, err) - - a2 := NewAddress() - 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 := NewAddress() - require.NoError(t, a2.UnmarshalJSON(data)) - - require.Equal(t, a, a2) - }) -} - -func TestNewAddressFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.Address - - require.Nil(t, NewAddressFromV2(x)) - }) -} - -func TestAddress_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Address - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewAddress(t *testing.T) { - t.Run("default values", func(t *testing.T) { - a := NewAddress() - - // check initial values - require.Nil(t, a.ContainerID()) - require.Nil(t, a.ObjectID()) - - // convert to v2 message - aV2 := a.ToV2() - - require.Nil(t, aV2.GetContainerID()) - require.Nil(t, aV2.GetObjectID()) - }) -} diff --git a/pkg/object/attribute.go b/pkg/object/attribute.go deleted file mode 100644 index 7f36686..0000000 --- a/pkg/object/attribute.go +++ /dev/null @@ -1,85 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -// Attribute represents v2-compatible object attribute. -type Attribute object.Attribute - -// NewAttributeFromV2 wraps v2 Attribute message to Attribute. -// -// Nil object.Attribute converts to nil. -func NewAttributeFromV2(aV2 *object.Attribute) *Attribute { - return (*Attribute)(aV2) -} - -// NewAttribute creates and initializes blank Attribute. -// -// Works similar as NewAttributeFromV2(new(Attribute)). -// -// Defaults: -// - key: ""; -// - value: "". -func NewAttribute() *Attribute { - return NewAttributeFromV2(new(object.Attribute)) -} - -// Key returns key to the object attribute. -func (a *Attribute) Key() string { - return (*object.Attribute)(a).GetKey() -} - -// SetKey sets key to the object attribute. -func (a *Attribute) SetKey(v string) { - (*object.Attribute)(a).SetKey(v) -} - -// Value return value of the object attribute. -func (a *Attribute) Value() string { - return (*object.Attribute)(a).GetValue() -} - -// SetValue sets value of the object attribute. -func (a *Attribute) SetValue(v string) { - (*object.Attribute)(a).SetValue(v) -} - -// ToV2 converts Attribute to v2 Attribute message. -// -// Nil Attribute converts to nil. -func (a *Attribute) ToV2() *object.Attribute { - return (*object.Attribute)(a) -} - -// Marshal marshals Attribute into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (a *Attribute) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*object.Attribute)(a). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Attribute. -func (a *Attribute) Unmarshal(data []byte) error { - return (*object.Attribute)(a). - Unmarshal(data) -} - -// MarshalJSON encodes Attribute to protobuf JSON format. -func (a *Attribute) MarshalJSON() ([]byte, error) { - return (*object.Attribute)(a). - MarshalJSON() -} - -// UnmarshalJSON decodes Attribute from protobuf JSON format. -func (a *Attribute) UnmarshalJSON(data []byte) error { - return (*object.Attribute)(a). - UnmarshalJSON(data) -} diff --git a/pkg/object/attribute_test.go b/pkg/object/attribute_test.go deleted file mode 100644 index d5f1b3f..0000000 --- a/pkg/object/attribute_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package object - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/stretchr/testify/require" -) - -func TestAttribute(t *testing.T) { - key, val := "some key", "some value" - - a := NewAttribute() - a.SetKey(key) - a.SetValue(val) - - require.Equal(t, key, a.Key()) - require.Equal(t, val, a.Value()) - - aV2 := a.ToV2() - - require.Equal(t, key, aV2.GetKey()) - require.Equal(t, val, aV2.GetValue()) -} - -func TestAttributeEncoding(t *testing.T) { - a := NewAttribute() - a.SetKey("key") - a.SetValue("value") - - t.Run("binary", func(t *testing.T) { - data, err := a.Marshal() - require.NoError(t, err) - - a2 := NewAttribute() - 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 := NewAttribute() - require.NoError(t, a2.UnmarshalJSON(data)) - - require.Equal(t, a, a2) - }) -} - -func TestNewAttributeFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *object.Attribute - - require.Nil(t, NewAttributeFromV2(x)) - }) -} - -func TestAttribute_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Attribute - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewAttribute(t *testing.T) { - t.Run("default values", func(t *testing.T) { - a := NewAttribute() - - // check initial values - require.Empty(t, a.Key()) - require.Empty(t, a.Value()) - - // convert to v2 message - aV2 := a.ToV2() - - require.Empty(t, aV2.GetKey()) - require.Empty(t, aV2.GetValue()) - }) -} diff --git a/pkg/object/error.go b/pkg/object/error.go deleted file mode 100644 index 96048c2..0000000 --- a/pkg/object/error.go +++ /dev/null @@ -1,19 +0,0 @@ -package object - -type SplitInfoError struct { - si *SplitInfo -} - -const splitInfoErrorMsg = "object not found, split info has been provided" - -func (s *SplitInfoError) Error() string { - return splitInfoErrorMsg -} - -func (s *SplitInfoError) SplitInfo() *SplitInfo { - return s.si -} - -func NewSplitInfoError(v *SplitInfo) *SplitInfoError { - return &SplitInfoError{si: v} -} diff --git a/pkg/object/error_test.go b/pkg/object/error_test.go deleted file mode 100644 index 870c2d6..0000000 --- a/pkg/object/error_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package object_test - -import ( - "errors" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/object" - "github.com/stretchr/testify/require" -) - -func TestNewSplitInfoError(t *testing.T) { - var ( - si = generateSplitInfo() - - err error = object.NewSplitInfoError(si) - expectedErr *object.SplitInfoError - ) - - require.True(t, errors.As(err, &expectedErr)) - - siErr, ok := err.(*object.SplitInfoError) - require.True(t, ok) - require.Equal(t, si, siErr.SplitInfo()) -} - -func generateSplitInfo() *object.SplitInfo { - si := object.NewSplitInfo() - si.SetSplitID(object.NewSplitID()) - si.SetLastPart(generateID()) - si.SetLink(generateID()) - - return si -} diff --git a/pkg/object/fmt.go b/pkg/object/fmt.go deleted file mode 100644 index d99a2c6..0000000 --- a/pkg/object/fmt.go +++ /dev/null @@ -1,176 +0,0 @@ -package object - -import ( - "crypto/ecdsa" - "crypto/sha256" - "errors" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/util/signature" - signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -var errCheckSumMismatch = errors.New("payload checksum mismatch") - -var errIncorrectID = errors.New("incorrect object identifier") - -// CalculatePayloadChecksum calculates and returns checksum of -// object payload bytes. -func CalculatePayloadChecksum(payload []byte) *pkg.Checksum { - res := pkg.NewChecksum() - res.SetSHA256(sha256.Sum256(payload)) - - return res -} - -// CalculateAndSetPayloadChecksum calculates checksum of current -// object payload and writes it to the object. -func CalculateAndSetPayloadChecksum(obj *RawObject) { - obj.SetPayloadChecksum( - CalculatePayloadChecksum(obj.Payload()), - ) -} - -// VerifyPayloadChecksum checks if payload checksum in the object -// corresponds to its payload. -func VerifyPayloadChecksum(obj *Object) error { - if !pkg.EqualChecksums( - obj.PayloadChecksum(), - CalculatePayloadChecksum(obj.Payload()), - ) { - return errCheckSumMismatch - } - - return nil -} - -// CalculateID calculates identifier for the object. -func CalculateID(obj *Object) (*ID, error) { - data, err := obj.ToV2().GetHeader().StableMarshal(nil) - if err != nil { - return nil, err - } - - id := NewID() - id.SetSHA256(sha256.Sum256(data)) - - return id, nil -} - -// CalculateAndSetID calculates identifier for the object -// and writes the result to it. -func CalculateAndSetID(obj *RawObject) error { - id, err := CalculateID(obj.Object()) - if err != nil { - return err - } - - obj.SetID(id) - - return nil -} - -// VerifyID checks if identifier in the object corresponds to -// its structure. -func VerifyID(obj *Object) error { - id, err := CalculateID(obj) - if err != nil { - return err - } - - if !id.Equal(obj.ID()) { - return errIncorrectID - } - - return nil -} - -func CalculateIDSignature(key *ecdsa.PrivateKey, id *ID) (*pkg.Signature, error) { - sig := pkg.NewSignature() - - if err := signature.SignDataWithHandler( - key, - signatureV2.StableMarshalerWrapper{ - SM: id.ToV2(), - }, - func(key, sign []byte) { - sig.SetKey(key) - sig.SetSign(sign) - }, - ); err != nil { - return nil, err - } - - return sig, nil -} - -func CalculateAndSetSignature(key *ecdsa.PrivateKey, obj *RawObject) error { - sig, err := CalculateIDSignature(key, obj.ID()) - if err != nil { - return err - } - - obj.SetSignature(sig) - - return nil -} - -func VerifyIDSignature(obj *Object) error { - return signature.VerifyDataWithSource( - signatureV2.StableMarshalerWrapper{ - SM: obj.ID().ToV2(), - }, - func() ([]byte, []byte) { - sig := obj.Signature() - - return sig.Key(), sig.Sign() - }, - ) -} - -// SetIDWithSignature sets object identifier and signature. -func SetIDWithSignature(key *ecdsa.PrivateKey, obj *RawObject) error { - if err := CalculateAndSetID(obj); err != nil { - return fmt.Errorf("could not set identifier: %w", err) - } - - if err := CalculateAndSetSignature(key, obj); err != nil { - return fmt.Errorf("could not set signature: %w", err) - } - - return nil -} - -// SetVerificationFields calculates and sets all verification fields of the object. -func SetVerificationFields(key *ecdsa.PrivateKey, obj *RawObject) error { - CalculateAndSetPayloadChecksum(obj) - - return SetIDWithSignature(key, obj) -} - -// CheckVerificationFields checks all verification fields of the object. -func CheckVerificationFields(obj *Object) error { - if err := CheckHeaderVerificationFields(obj); err != nil { - return fmt.Errorf("invalid header structure: %w", err) - } - - if err := VerifyPayloadChecksum(obj); err != nil { - return fmt.Errorf("invalid payload checksum: %w", err) - } - - return nil -} - -// CheckHeaderVerificationFields checks all verification fields except payload. -func CheckHeaderVerificationFields(obj *Object) error { - if err := VerifyIDSignature(obj); err != nil { - return fmt.Errorf("invalid signature: %w", err) - } - - if err := VerifyID(obj); err != nil { - return fmt.Errorf("invalid identifier: %w", err) - } - - return nil -} diff --git a/pkg/object/fmt_test.go b/pkg/object/fmt_test.go deleted file mode 100644 index b1731c9..0000000 --- a/pkg/object/fmt_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package object - -import ( - "crypto/rand" - "testing" - - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -func TestVerificationFields(t *testing.T) { - obj := NewRaw() - - payload := make([]byte, 10) - _, _ = rand.Read(payload) - - obj.SetPayload(payload) - obj.SetPayloadSize(uint64(len(payload))) - - require.NoError(t, SetVerificationFields(test.DecodeKey(-1), obj)) - - require.NoError(t, CheckVerificationFields(obj.Object())) - - items := []struct { - corrupt func() - restore func() - }{ - { - corrupt: func() { - payload[0]++ - }, - restore: func() { - payload[0]-- - }, - }, - { - corrupt: func() { - obj.SetPayloadSize(obj.PayloadSize() + 1) - }, - restore: func() { - obj.SetPayloadSize(obj.PayloadSize() - 1) - }, - }, - { - corrupt: func() { - obj.ID().ToV2().GetValue()[0]++ - }, - restore: func() { - obj.ID().ToV2().GetValue()[0]-- - }, - }, - { - corrupt: func() { - obj.Signature().Key()[0]++ - }, - restore: func() { - obj.Signature().Key()[0]-- - }, - }, - { - corrupt: func() { - obj.Signature().Sign()[0]++ - }, - restore: func() { - obj.Signature().Sign()[0]-- - }, - }, - } - - for _, item := range items { - item.corrupt() - - require.Error(t, CheckVerificationFields(obj.Object())) - - item.restore() - - require.NoError(t, CheckVerificationFields(obj.Object())) - } -} diff --git a/pkg/object/id.go b/pkg/object/id.go deleted file mode 100644 index 26e70f7..0000000 --- a/pkg/object/id.go +++ /dev/null @@ -1,104 +0,0 @@ -package object - -import ( - "bytes" - "crypto/sha256" - "errors" - "fmt" - - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// ID represents v2-compatible object identifier. -type ID refs.ObjectID - -var errInvalidIDString = errors.New("incorrect format of the string object ID") - -// NewIDFromV2 wraps v2 ObjectID message to ID. -// -// Nil refs.ObjectID converts to nil. -func NewIDFromV2(idV2 *refs.ObjectID) *ID { - return (*ID)(idV2) -} - -// NewID creates and initializes blank ID. -// -// Works similar as NewIDFromV2(new(ObjectID)). -// -// Defaults: -// - value: nil. -func NewID() *ID { - return NewIDFromV2(new(refs.ObjectID)) -} - -// SetSHA256 sets object identifier value to SHA256 checksum. -func (id *ID) SetSHA256(v [sha256.Size]byte) { - (*refs.ObjectID)(id).SetValue(v[:]) -} - -// Equal returns true if identifiers are identical. -func (id *ID) Equal(id2 *ID) bool { - return bytes.Equal( - (*refs.ObjectID)(id).GetValue(), - (*refs.ObjectID)(id2).GetValue(), - ) -} - -// ToV2 converts ID to v2 ObjectID message. -// -// Nil ID converts to nil. -func (id *ID) ToV2() *refs.ObjectID { - return (*refs.ObjectID)(id) -} - -// Parse converts base58 string representation into ID. -func (id *ID) Parse(s string) error { - data, err := base58.Decode(s) - if err != nil { - return fmt.Errorf("could not parse object.ID from string: %w", err) - } else if len(data) != sha256.Size { - return errInvalidIDString - } - - (*refs.ObjectID)(id).SetValue(data) - - return nil -} - -// String returns base58 string representation of ID. -func (id *ID) String() string { - return base58.Encode((*refs.ObjectID)(id).GetValue()) -} - -// Marshal marshals ID into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (id *ID) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.ObjectID)(id). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of ID. -func (id *ID) Unmarshal(data []byte) error { - return (*refs.ObjectID)(id). - Unmarshal(data) -} - -// MarshalJSON encodes ID to protobuf JSON format. -func (id *ID) MarshalJSON() ([]byte, error) { - return (*refs.ObjectID)(id). - MarshalJSON() -} - -// UnmarshalJSON decodes ID from protobuf JSON format. -func (id *ID) UnmarshalJSON(data []byte) error { - return (*refs.ObjectID)(id). - UnmarshalJSON(data) -} diff --git a/pkg/object/id_test.go b/pkg/object/id_test.go deleted file mode 100644 index e4086d8..0000000 --- a/pkg/object/id_test.go +++ /dev/null @@ -1,142 +0,0 @@ -package object - -import ( - "crypto/rand" - "crypto/sha256" - "strconv" - "testing" - - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func TestIDV2(t *testing.T) { - id := NewID() - - checksum := [sha256.Size]byte{} - - _, err := rand.Read(checksum[:]) - require.NoError(t, err) - - id.SetSHA256(checksum) - - idV2 := id.ToV2() - - require.Equal(t, checksum[:], idV2.GetValue()) -} - -func TestID_Equal(t *testing.T) { - cs := randSHA256Checksum(t) - - id1 := NewID() - id1.SetSHA256(cs) - - id2 := NewID() - id2.SetSHA256(cs) - - id3 := NewID() - id3.SetSHA256(randSHA256Checksum(t)) - - require.True(t, id1.Equal(id2)) - require.False(t, id1.Equal(id3)) -} - -func TestID_Parse(t *testing.T) { - t.Run("should parse successful", func(t *testing.T) { - for i := 0; i < 10; i++ { - t.Run(strconv.Itoa(i), func(t *testing.T) { - cs := randSHA256Checksum(t) - str := base58.Encode(cs[:]) - oid := NewID() - - require.NoError(t, oid.Parse(str)) - require.Equal(t, cs[:], oid.ToV2().GetValue()) - }) - } - }) - - t.Run("should failure on parse", func(t *testing.T) { - for i := 0; i < 10; i++ { - j := i - t.Run(strconv.Itoa(j), func(t *testing.T) { - cs := []byte{1, 2, 3, 4, 5, byte(j)} - str := base58.Encode(cs) - oid := NewID() - - require.Error(t, oid.Parse(str)) - }) - } - }) -} - -func TestID_String(t *testing.T) { - t.Run("nil", func(t *testing.T) { - id := NewID() - require.Empty(t, id.String()) - }) - - t.Run("should be equal", func(t *testing.T) { - for i := 0; i < 10; i++ { - t.Run(strconv.Itoa(i), func(t *testing.T) { - cs := randSHA256Checksum(t) - str := base58.Encode(cs[:]) - oid := NewID() - - require.NoError(t, oid.Parse(str)) - require.Equal(t, str, oid.String()) - }) - } - }) -} - -func TestObjectIDEncoding(t *testing.T) { - id := randID(t) - - t.Run("binary", func(t *testing.T) { - data, err := id.Marshal() - require.NoError(t, err) - - id2 := NewID() - require.NoError(t, id2.Unmarshal(data)) - - require.Equal(t, id, id2) - }) - - t.Run("json", func(t *testing.T) { - data, err := id.MarshalJSON() - require.NoError(t, err) - - a2 := NewID() - require.NoError(t, a2.UnmarshalJSON(data)) - - require.Equal(t, id, a2) - }) -} - -func TestNewIDFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.ObjectID - - require.Nil(t, NewIDFromV2(x)) - }) -} - -func TestID_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *ID - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewID(t *testing.T) { - t.Run("default values", func(t *testing.T) { - id := NewID() - - // convert to v2 message - idV2 := id.ToV2() - - require.Nil(t, idV2.GetValue()) - }) -} diff --git a/pkg/object/object.go b/pkg/object/object.go deleted file mode 100644 index 55000dc..0000000 --- a/pkg/object/object.go +++ /dev/null @@ -1,45 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -// Object represents v2-compatible NeoFS object that provides -// a convenient interface for working in isolation -// from the internal structure of an object. -// -// Object allows to work with the object in read-only -// mode as a reflection of the immutability of objects -// in the system. -type Object struct { - *rwObject -} - -// NewFromV2 wraps v2 Object message to Object. -func NewFromV2(oV2 *object.Object) *Object { - return &Object{ - rwObject: (*rwObject)(oV2), - } -} - -// New creates and initializes blank Object. -// -// Works similar as NewFromV2(new(Object)). -func New() *Object { - return NewFromV2(new(object.Object)) -} - -// ToV2 converts Object to v2 Object message. -func (o *Object) ToV2() *object.Object { - if o != nil { - return (*object.Object)(o.rwObject) - } - - return nil -} - -// MarshalHeaderJSON marshals object's header -// into JSON format. -func (o *Object) MarshalHeaderJSON() ([]byte, error) { - return (*object.Object)(o.rwObject).GetHeader().MarshalJSON() -} diff --git a/pkg/object/range.go b/pkg/object/range.go deleted file mode 100644 index 4979aee..0000000 --- a/pkg/object/range.go +++ /dev/null @@ -1,55 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -// Range represents v2-compatible object payload range. -type Range object.Range - -// NewRangeFromV2 wraps v2 Range message to Range. -// -// Nil object.Range converts to nil. -func NewRangeFromV2(rV2 *object.Range) *Range { - return (*Range)(rV2) -} - -// NewRange creates and initializes blank Range. -// -// Defaults: -// - offset: 0; -// - length: 0. -func NewRange() *Range { - return NewRangeFromV2(new(object.Range)) -} - -// ToV2 converts Range to v2 Range message. -// -// Nil Range converts to nil. -func (r *Range) ToV2() *object.Range { - return (*object.Range)(r) -} - -// GetLength returns payload range size. -func (r *Range) GetLength() uint64 { - return (*object.Range)(r). - GetLength() -} - -// SetLength sets payload range size. -func (r *Range) SetLength(v uint64) { - (*object.Range)(r). - SetLength(v) -} - -// GetOffset sets payload range offset from start. -func (r *Range) GetOffset() uint64 { - return (*object.Range)(r). - GetOffset() -} - -// SetOffset gets payload range offset from start. -func (r *Range) SetOffset(v uint64) { - (*object.Range)(r). - SetOffset(v) -} diff --git a/pkg/object/range_test.go b/pkg/object/range_test.go deleted file mode 100644 index e14d360..0000000 --- a/pkg/object/range_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package object - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/stretchr/testify/require" -) - -func TestRange_SetOffset(t *testing.T) { - r := NewRange() - - off := uint64(13) - r.SetOffset(off) - - require.Equal(t, off, r.GetOffset()) -} - -func TestRange_SetLength(t *testing.T) { - r := NewRange() - - ln := uint64(7) - r.SetLength(ln) - - require.Equal(t, ln, r.GetLength()) -} - -func TestNewRangeFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *object.Range - - require.Nil(t, NewRangeFromV2(x)) - }) -} - -func TestRange_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Range - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewRange(t *testing.T) { - t.Run("default values", func(t *testing.T) { - r := NewRange() - - // check initial values - require.Zero(t, r.GetLength()) - require.Zero(t, r.GetOffset()) - - // convert to v2 message - rV2 := r.ToV2() - - require.Zero(t, rV2.GetLength()) - require.Zero(t, rV2.GetOffset()) - }) -} diff --git a/pkg/object/raw.go b/pkg/object/raw.go deleted file mode 100644 index 88ac076..0000000 --- a/pkg/object/raw.go +++ /dev/null @@ -1,160 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -// RawObject represents v2-compatible NeoFS object that provides -// a convenient interface to fill in the fields of -// an object in isolation from its internal structure. -type RawObject struct { - *rwObject -} - -// NewRawFromV2 wraps v2 Object message to RawObject. -func NewRawFromV2(oV2 *object.Object) *RawObject { - return &RawObject{ - rwObject: (*rwObject)(oV2), - } -} - -// NewRawFrom wraps Object instance to RawObject. -func NewRawFrom(obj *Object) *RawObject { - return NewRawFromV2(obj.ToV2()) -} - -// NewRaw creates and initializes blank RawObject. -// -// Works similar as NewRawFromV2(new(Object)). -func NewRaw() *RawObject { - return NewRawFromV2(new(object.Object)) -} - -// Object returns read-only object instance. -func (o *RawObject) Object() *Object { - if o != nil { - return &Object{ - rwObject: o.rwObject, - } - } - - return nil -} - -// SetID sets object identifier. -func (o *RawObject) SetID(v *ID) { - o.setID(v) -} - -// SetSignature sets signature of the object identifier. -func (o *RawObject) SetSignature(v *pkg.Signature) { - o.setSignature(v) -} - -// SetPayload sets payload bytes. -func (o *RawObject) SetPayload(v []byte) { - o.setPayload(v) -} - -// SetVersion sets version of the object. -func (o *RawObject) SetVersion(v *pkg.Version) { - o.setVersion(v) -} - -// SetPayloadSize sets payload length of the object. -func (o *RawObject) SetPayloadSize(v uint64) { - o.setPayloadSize(v) -} - -// SetContainerID sets identifier of the related container. -func (o *RawObject) SetContainerID(v *cid.ID) { - o.setContainerID(v) -} - -// SetOwnerID sets identifier of the object owner. -func (o *RawObject) SetOwnerID(v *owner.ID) { - o.setOwnerID(v) -} - -// SetCreationEpoch sets epoch number in which object was created. -func (o *RawObject) SetCreationEpoch(v uint64) { - o.setCreationEpoch(v) -} - -// SetPayloadChecksum sets checksum of the object payload. -func (o *RawObject) SetPayloadChecksum(v *pkg.Checksum) { - o.setPayloadChecksum(v) -} - -// SetPayloadHomomorphicHash sets homomorphic hash of the object payload. -func (o *RawObject) SetPayloadHomomorphicHash(v *pkg.Checksum) { - o.setPayloadHomomorphicHash(v) -} - -// SetAttributes sets object attributes. -func (o *RawObject) SetAttributes(v ...*Attribute) { - o.setAttributes(v...) -} - -// SetPreviousID sets identifier of the previous sibling object. -func (o *RawObject) SetPreviousID(v *ID) { - o.setPreviousID(v) -} - -// SetChildren sets list of the identifiers of the child objects. -func (o *RawObject) SetChildren(v ...*ID) { - o.setChildren(v...) -} - -// SetSplitID sets split identifier for the split object. -func (o *RawObject) SetSplitID(id *SplitID) { - o.setSplitID(id) -} - -// SetParentID sets identifier of the parent object. -func (o *RawObject) SetParentID(v *ID) { - o.setParentID(v) -} - -// SetParent sets parent object w/o payload. -func (o *RawObject) SetParent(v *Object) { - o.setParent(v) -} - -// SetSessionToken sets token of the session -// within which object was created. -func (o *RawObject) SetSessionToken(v *session.Token) { - o.setSessionToken(v) -} - -// SetType sets type of the object. -func (o *RawObject) SetType(v Type) { - o.setType(v) -} - -// CutPayload returns RawObject w/ empty payload. -// -// Changes of non-payload fields affect source object. -func (o *RawObject) CutPayload() *RawObject { - if o != nil { - return &RawObject{ - rwObject: o.rwObject.cutPayload(), - } - } - - return nil -} - -// ResetRelations removes all fields of links with other objects. -func (o *RawObject) ResetRelations() { - o.resetRelations() -} - -// InitRelations initializes relation field. -func (o *RawObject) InitRelations() { - o.initRelations() -} diff --git a/pkg/object/raw_test.go b/pkg/object/raw_test.go deleted file mode 100644 index d9febfd..0000000 --- a/pkg/object/raw_test.go +++ /dev/null @@ -1,317 +0,0 @@ -package object - -import ( - "crypto/rand" - "crypto/sha256" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test" - "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/stretchr/testify/require" -) - -func randID(t *testing.T) *ID { - id := NewID() - id.SetSHA256(randSHA256Checksum(t)) - - return id -} - -func randSHA256Checksum(t *testing.T) (cs [sha256.Size]byte) { - _, err := rand.Read(cs[:]) - require.NoError(t, err) - - return -} - -func randTZChecksum(t *testing.T) (cs [64]byte) { - _, err := rand.Read(cs[:]) - require.NoError(t, err) - - return -} - -func TestRawObject_SetID(t *testing.T) { - obj := NewRaw() - - id := randID(t) - - obj.SetID(id) - - require.Equal(t, id, obj.ID()) -} - -func TestRawObject_SetSignature(t *testing.T) { - obj := NewRaw() - - sig := pkg.NewSignature() - sig.SetKey([]byte{1, 2, 3}) - sig.SetSign([]byte{4, 5, 6}) - - obj.SetSignature(sig) - - require.Equal(t, sig, obj.Signature()) -} - -func TestRawObject_SetPayload(t *testing.T) { - obj := NewRaw() - - payload := make([]byte, 10) - _, _ = rand.Read(payload) - - obj.SetPayload(payload) - - require.Equal(t, payload, obj.Payload()) -} - -func TestRawObject_SetVersion(t *testing.T) { - obj := NewRaw() - - ver := pkg.NewVersion() - ver.SetMajor(1) - ver.SetMinor(2) - - obj.SetVersion(ver) - - require.Equal(t, ver, obj.Version()) -} - -func TestRawObject_SetPayloadSize(t *testing.T) { - obj := NewRaw() - - sz := uint64(133) - obj.SetPayloadSize(sz) - - require.Equal(t, sz, obj.PayloadSize()) -} - -func TestRawObject_SetContainerID(t *testing.T) { - obj := NewRaw() - - cid := cidtest.Generate() - - obj.SetContainerID(cid) - - require.Equal(t, cid, obj.ContainerID()) -} - -func TestRawObject_SetOwnerID(t *testing.T) { - obj := NewRaw() - - ownerID := ownertest.Generate() - - obj.SetOwnerID(ownerID) - - require.Equal(t, ownerID, obj.OwnerID()) -} - -func TestRawObject_SetCreationEpoch(t *testing.T) { - obj := NewRaw() - - creat := uint64(228) - obj.setCreationEpoch(creat) - - require.Equal(t, creat, obj.CreationEpoch()) -} - -func TestRawObject_SetPayloadChecksum(t *testing.T) { - obj := NewRaw() - - cs := pkg.NewChecksum() - cs.SetSHA256(randSHA256Checksum(t)) - - obj.SetPayloadChecksum(cs) - - require.Equal(t, cs, obj.PayloadChecksum()) -} - -func TestRawObject_SetPayloadHomomorphicHash(t *testing.T) { - obj := NewRaw() - - cs := pkg.NewChecksum() - cs.SetTillichZemor(randTZChecksum(t)) - - obj.SetPayloadHomomorphicHash(cs) - - require.Equal(t, cs, obj.PayloadHomomorphicHash()) -} - -func TestRawObject_SetAttributes(t *testing.T) { - obj := NewRaw() - - a1 := NewAttribute() - a1.SetKey("key1") - a1.SetValue("val1") - - a2 := NewAttribute() - a2.SetKey("key2") - a2.SetValue("val2") - - obj.SetAttributes(a1, a2) - - require.Equal(t, []*Attribute{a1, a2}, obj.Attributes()) -} - -func TestRawObject_SetPreviousID(t *testing.T) { - obj := NewRaw() - - prev := randID(t) - - obj.SetPreviousID(prev) - - require.Equal(t, prev, obj.PreviousID()) -} - -func TestRawObject_SetChildren(t *testing.T) { - obj := NewRaw() - - id1 := randID(t) - id2 := randID(t) - - obj.SetChildren(id1, id2) - - require.Equal(t, []*ID{id1, id2}, obj.Children()) -} - -func TestRawObject_SetSplitID(t *testing.T) { - obj := NewRaw() - - require.Nil(t, obj.SplitID()) - - splitID := NewSplitID() - obj.SetSplitID(splitID) - - require.Equal(t, obj.SplitID(), splitID) -} - -func TestRawObject_SetParent(t *testing.T) { - obj := NewRaw() - - require.Nil(t, obj.Parent()) - - par := NewRaw() - par.SetID(randID(t)) - par.SetContainerID(cidtest.Generate()) - par.SetSignature(pkg.NewSignature()) - - parObj := par.Object() - - obj.SetParent(parObj) - - require.Equal(t, parObj, obj.Parent()) -} - -func TestRawObject_ToV2(t *testing.T) { - objV2 := new(object.Object) - objV2.SetPayload([]byte{1, 2, 3}) - - obj := NewRawFromV2(objV2) - - require.Equal(t, objV2, obj.ToV2()) -} - -func TestRawObject_SetSessionToken(t *testing.T) { - obj := NewRaw() - - tok := sessiontest.Generate() - - obj.SetSessionToken(tok) - - require.Equal(t, tok, obj.SessionToken()) -} - -func TestRawObject_SetType(t *testing.T) { - obj := NewRaw() - - typ := TypeStorageGroup - - obj.SetType(typ) - - require.Equal(t, typ, obj.Type()) -} - -func TestRawObject_CutPayload(t *testing.T) { - o1 := NewRaw() - - p1 := []byte{12, 3} - o1.SetPayload(p1) - - sz := uint64(13) - o1.SetPayloadSize(sz) - - o2 := o1.CutPayload() - - require.Equal(t, sz, o2.PayloadSize()) - require.Empty(t, o2.Payload()) - - sz++ - o1.SetPayloadSize(sz) - - require.Equal(t, sz, o1.PayloadSize()) - require.Equal(t, sz, o2.PayloadSize()) - - p2 := []byte{4, 5, 6} - o2.SetPayload(p2) - - require.Equal(t, p2, o2.Payload()) - require.Equal(t, p1, o1.Payload()) -} - -func TestRawObject_SetParentID(t *testing.T) { - obj := NewRaw() - - id := randID(t) - obj.setParentID(id) - - require.Equal(t, id, obj.ParentID()) -} - -func TestRawObject_ResetRelations(t *testing.T) { - obj := NewRaw() - - obj.SetPreviousID(randID(t)) - - obj.ResetRelations() - - require.Nil(t, obj.PreviousID()) -} - -func TestRwObject_HasParent(t *testing.T) { - obj := NewRaw() - - obj.InitRelations() - - require.True(t, obj.HasParent()) - - obj.ResetRelations() - - require.False(t, obj.HasParent()) -} - -func TestRWObjectEncoding(t *testing.T) { - o := NewRaw() - o.SetID(randID(t)) - - t.Run("binary", func(t *testing.T) { - data, err := o.Marshal() - require.NoError(t, err) - - o2 := NewRaw() - require.NoError(t, o2.Unmarshal(data)) - - require.Equal(t, o, o2) - }) - - t.Run("json", func(t *testing.T) { - data, err := o.MarshalJSON() - require.NoError(t, err) - - o2 := NewRaw() - require.NoError(t, o2.UnmarshalJSON(data)) - - require.Equal(t, o, o2) - }) -} diff --git a/pkg/object/rw.go b/pkg/object/rw.go deleted file mode 100644 index 52c24d6..0000000 --- a/pkg/object/rw.go +++ /dev/null @@ -1,403 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// wrapper over v2 Object that provides -// public getter and private setters. -type rwObject object.Object - -// ToV2 converts Object to v2 Object message. -func (o *rwObject) ToV2() *object.Object { - return (*object.Object)(o) -} - -func (o *rwObject) setHeaderField(setter func(*object.Header)) { - obj := (*object.Object)(o) - h := obj.GetHeader() - - if h == nil { - h = new(object.Header) - obj.SetHeader(h) - } - - setter(h) -} - -func (o *rwObject) setSplitFields(setter func(*object.SplitHeader)) { - o.setHeaderField(func(h *object.Header) { - split := h.GetSplit() - if split == nil { - split = new(object.SplitHeader) - h.SetSplit(split) - } - - setter(split) - }) -} - -// ID returns object identifier. -func (o *rwObject) ID() *ID { - return NewIDFromV2( - (*object.Object)(o). - GetObjectID(), - ) -} - -func (o *rwObject) setID(v *ID) { - (*object.Object)(o). - SetObjectID(v.ToV2()) -} - -// Signature returns signature of the object identifier. -func (o *rwObject) Signature() *pkg.Signature { - return pkg.NewSignatureFromV2( - (*object.Object)(o). - GetSignature(), - ) -} - -func (o *rwObject) setSignature(v *pkg.Signature) { - (*object.Object)(o). - SetSignature(v.ToV2()) -} - -// Payload returns payload bytes. -func (o *rwObject) Payload() []byte { - return (*object.Object)(o). - GetPayload() -} - -func (o *rwObject) setPayload(v []byte) { - (*object.Object)(o). - SetPayload(v) -} - -// Version returns version of the object. -func (o *rwObject) Version() *pkg.Version { - return pkg.NewVersionFromV2( - (*object.Object)(o). - GetHeader(). - GetVersion(), - ) -} - -func (o *rwObject) setVersion(v *pkg.Version) { - o.setHeaderField(func(h *object.Header) { - h.SetVersion(v.ToV2()) - }) -} - -// PayloadSize returns payload length of the object. -func (o *rwObject) PayloadSize() uint64 { - return (*object.Object)(o). - GetHeader(). - GetPayloadLength() -} - -func (o *rwObject) setPayloadSize(v uint64) { - o.setHeaderField(func(h *object.Header) { - h.SetPayloadLength(v) - }) -} - -// ContainerID returns identifier of the related container. -func (o *rwObject) ContainerID() *cid.ID { - return cid.NewFromV2( - (*object.Object)(o). - GetHeader(). - GetContainerID(), - ) -} - -func (o *rwObject) setContainerID(v *cid.ID) { - o.setHeaderField(func(h *object.Header) { - h.SetContainerID(v.ToV2()) - }) -} - -// OwnerID returns identifier of the object owner. -func (o *rwObject) OwnerID() *owner.ID { - return owner.NewIDFromV2( - (*object.Object)(o). - GetHeader(). - GetOwnerID(), - ) -} - -func (o *rwObject) setOwnerID(v *owner.ID) { - o.setHeaderField(func(h *object.Header) { - h.SetOwnerID(v.ToV2()) - }) -} - -// CreationEpoch returns epoch number in which object was created. -func (o *rwObject) CreationEpoch() uint64 { - return (*object.Object)(o). - GetHeader(). - GetCreationEpoch() -} - -func (o *rwObject) setCreationEpoch(v uint64) { - o.setHeaderField(func(h *object.Header) { - h.SetCreationEpoch(v) - }) -} - -// PayloadChecksum returns checksum of the object payload. -func (o *rwObject) PayloadChecksum() *pkg.Checksum { - return pkg.NewChecksumFromV2( - (*object.Object)(o). - GetHeader(). - GetPayloadHash(), - ) -} - -func (o *rwObject) setPayloadChecksum(v *pkg.Checksum) { - o.setHeaderField(func(h *object.Header) { - h.SetPayloadHash(v.ToV2()) - }) -} - -// PayloadHomomorphicHash returns homomorphic hash of the object payload. -func (o *rwObject) PayloadHomomorphicHash() *pkg.Checksum { - return pkg.NewChecksumFromV2( - (*object.Object)(o). - GetHeader(). - GetHomomorphicHash(), - ) -} - -func (o *rwObject) setPayloadHomomorphicHash(v *pkg.Checksum) { - o.setHeaderField(func(h *object.Header) { - h.SetHomomorphicHash(v.ToV2()) - }) -} - -// Attributes returns object attributes. -func (o *rwObject) Attributes() []*Attribute { - attrs := (*object.Object)(o). - GetHeader(). - GetAttributes() - - res := make([]*Attribute, 0, len(attrs)) - - for i := range attrs { - res = append(res, NewAttributeFromV2(attrs[i])) - } - - return res -} - -func (o *rwObject) setAttributes(v ...*Attribute) { - attrs := make([]*object.Attribute, 0, len(v)) - - for i := range v { - attrs = append(attrs, v[i].ToV2()) - } - - o.setHeaderField(func(h *object.Header) { - h.SetAttributes(attrs) - }) -} - -// PreviousID returns identifier of the previous sibling object. -func (o *rwObject) PreviousID() *ID { - return NewIDFromV2( - (*object.Object)(o). - GetHeader(). - GetSplit(). - GetPrevious(), - ) -} - -func (o *rwObject) setPreviousID(v *ID) { - o.setSplitFields(func(split *object.SplitHeader) { - split.SetPrevious(v.ToV2()) - }) -} - -// Children return list of the identifiers of the child objects. -func (o *rwObject) Children() []*ID { - ids := (*object.Object)(o). - GetHeader(). - GetSplit(). - GetChildren() - - res := make([]*ID, 0, len(ids)) - - for i := range ids { - res = append(res, NewIDFromV2(ids[i])) - } - - return res -} - -func (o *rwObject) setChildren(v ...*ID) { - ids := make([]*refs.ObjectID, 0, len(v)) - - for i := range v { - ids = append(ids, v[i].ToV2()) - } - - o.setSplitFields(func(split *object.SplitHeader) { - split.SetChildren(ids) - }) -} - -// SplitID return split identity of split object. If object is not split -// returns nil. -func (o *rwObject) SplitID() *SplitID { - return NewSplitIDFromV2( - (*object.Object)(o). - GetHeader(). - GetSplit(). - GetSplitID(), - ) -} - -func (o *rwObject) setSplitID(id *SplitID) { - o.setSplitFields(func(split *object.SplitHeader) { - split.SetSplitID(id.ToV2()) - }) -} - -// ParentID returns identifier of the parent object. -func (o *rwObject) ParentID() *ID { - return NewIDFromV2( - (*object.Object)(o). - GetHeader(). - GetSplit(). - GetParent(), - ) -} - -func (o *rwObject) setParentID(v *ID) { - o.setSplitFields(func(split *object.SplitHeader) { - split.SetParent(v.ToV2()) - }) -} - -// Parent returns parent object w/o payload. -func (o *rwObject) Parent() *Object { - h := (*object.Object)(o). - GetHeader(). - GetSplit() - - parSig := h.GetParentSignature() - parHdr := h.GetParentHeader() - - if parSig == nil && parHdr == nil { - return nil - } - - oV2 := new(object.Object) - oV2.SetObjectID(h.GetParent()) - oV2.SetSignature(parSig) - oV2.SetHeader(parHdr) - - return NewFromV2(oV2) -} - -func (o *rwObject) setParent(v *Object) { - o.setSplitFields(func(split *object.SplitHeader) { - split.SetParent((*object.Object)(v.rwObject).GetObjectID()) - split.SetParentSignature((*object.Object)(v.rwObject).GetSignature()) - split.SetParentHeader((*object.Object)(v.rwObject).GetHeader()) - }) -} - -func (o *rwObject) initRelations() { - o.setHeaderField(func(h *object.Header) { - h.SetSplit(new(object.SplitHeader)) - }) -} - -func (o *rwObject) resetRelations() { - o.setHeaderField(func(h *object.Header) { - h.SetSplit(nil) - }) -} - -// SessionToken returns token of the session -// within which object was created. -func (o *rwObject) SessionToken() *session.Token { - return session.NewTokenFromV2( - (*object.Object)(o). - GetHeader(). - GetSessionToken(), - ) -} - -func (o *rwObject) setSessionToken(v *session.Token) { - o.setHeaderField(func(h *object.Header) { - h.SetSessionToken(v.ToV2()) - }) -} - -// Type returns type of the object. -func (o *rwObject) Type() Type { - return TypeFromV2( - (*object.Object)(o). - GetHeader(). - GetObjectType(), - ) -} - -func (o *rwObject) setType(t Type) { - o.setHeaderField(func(h *object.Header) { - h.SetObjectType(t.ToV2()) - }) -} - -func (o *rwObject) cutPayload() *rwObject { - ov2 := new(object.Object) - *ov2 = *(*object.Object)(o) - ov2.SetPayload(nil) - - return (*rwObject)(ov2) -} - -func (o *rwObject) HasParent() bool { - return (*object.Object)(o). - GetHeader(). - GetSplit() != nil -} - -// Marshal marshals object into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (o *rwObject) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*object.Object)(o). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of object. -func (o *rwObject) Unmarshal(data []byte) error { - return (*object.Object)(o). - Unmarshal(data) -} - -// MarshalJSON encodes object to protobuf JSON format. -func (o *rwObject) MarshalJSON() ([]byte, error) { - return (*object.Object)(o). - MarshalJSON() -} - -// UnmarshalJSON decodes object from protobuf JSON format. -func (o *rwObject) UnmarshalJSON(data []byte) error { - return (*object.Object)(o). - UnmarshalJSON(data) -} diff --git a/pkg/object/search.go b/pkg/object/search.go deleted file mode 100644 index cf703f5..0000000 --- a/pkg/object/search.go +++ /dev/null @@ -1,309 +0,0 @@ -package object - -import ( - "encoding/json" - "fmt" - - "github.com/nspcc-dev/neofs-api-go/pkg" - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - v2object "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -// SearchMatchType indicates match operation on specified header. -type SearchMatchType uint32 - -const ( - MatchUnknown SearchMatchType = iota - MatchStringEqual - MatchStringNotEqual - MatchNotPresent - MatchCommonPrefix -) - -func (m SearchMatchType) ToV2() v2object.MatchType { - switch m { - case MatchStringEqual: - return v2object.MatchStringEqual - case MatchStringNotEqual: - return v2object.MatchStringNotEqual - case MatchNotPresent: - return v2object.MatchNotPresent - case MatchCommonPrefix: - return v2object.MatchCommonPrefix - default: - return v2object.MatchUnknown - } -} - -func SearchMatchFromV2(t v2object.MatchType) (m SearchMatchType) { - switch t { - case v2object.MatchStringEqual: - m = MatchStringEqual - case v2object.MatchStringNotEqual: - m = MatchStringNotEqual - case v2object.MatchNotPresent: - m = MatchNotPresent - case v2object.MatchCommonPrefix: - m = MatchCommonPrefix - default: - m = MatchUnknown - } - - return m -} - -// String returns string representation of SearchMatchType. -// -// String mapping: -// * MatchStringEqual: STRING_EQUAL; -// * MatchStringNotEqual: STRING_NOT_EQUAL; -// * MatchNotPresent: NOT_PRESENT; -// * MatchCommonPrefix: COMMON_PREFIX; -// * MatchUnknown, default: MATCH_TYPE_UNSPECIFIED. -func (m SearchMatchType) String() string { - return m.ToV2().String() -} - -// FromString parses SearchMatchType from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (m *SearchMatchType) FromString(s string) bool { - var g v2object.MatchType - - ok := g.FromString(s) - - if ok { - *m = SearchMatchFromV2(g) - } - - return ok -} - -type SearchFilter struct { - header filterKey - value fmt.Stringer - op SearchMatchType -} - -type staticStringer string - -type filterKey struct { - typ filterKeyType - - str string -} - -// enumeration of reserved filter keys. -type filterKeyType int - -type boolStringer bool - -type SearchFilters []SearchFilter - -const ( - _ filterKeyType = iota - fKeyVersion - fKeyObjectID - fKeyContainerID - fKeyOwnerID - fKeyCreationEpoch - fKeyPayloadLength - fKeyPayloadHash - fKeyType - fKeyHomomorphicHash - fKeyParent - fKeySplitID - fKeyPropRoot - fKeyPropPhy -) - -func (k filterKey) String() string { - switch k.typ { - default: - return k.str - case fKeyVersion: - return v2object.FilterHeaderVersion - case fKeyObjectID: - return v2object.FilterHeaderObjectID - case fKeyContainerID: - return v2object.FilterHeaderContainerID - case fKeyOwnerID: - return v2object.FilterHeaderOwnerID - case fKeyCreationEpoch: - return v2object.FilterHeaderCreationEpoch - case fKeyPayloadLength: - return v2object.FilterHeaderPayloadLength - case fKeyPayloadHash: - return v2object.FilterHeaderPayloadHash - case fKeyType: - return v2object.FilterHeaderObjectType - case fKeyHomomorphicHash: - return v2object.FilterHeaderHomomorphicHash - case fKeyParent: - return v2object.FilterHeaderParent - case fKeySplitID: - return v2object.FilterHeaderSplitID - case fKeyPropRoot: - return v2object.FilterPropertyRoot - case fKeyPropPhy: - return v2object.FilterPropertyPhy - } -} - -func (s staticStringer) String() string { - return string(s) -} - -func (s boolStringer) String() string { - if s { - return v2object.BooleanPropertyValueTrue - } - - return v2object.BooleanPropertyValueFalse -} - -func (f *SearchFilter) Header() string { - return f.header.String() -} - -func (f *SearchFilter) Value() string { - return f.value.String() -} - -func (f *SearchFilter) Operation() SearchMatchType { - return f.op -} - -func NewSearchFilters() SearchFilters { - return SearchFilters{} -} - -func NewSearchFiltersFromV2(v2 []*v2object.SearchFilter) SearchFilters { - filters := make(SearchFilters, 0, len(v2)) - - for i := range v2 { - if v2[i] == nil { - continue - } - - filters.AddFilter( - v2[i].GetKey(), - v2[i].GetValue(), - SearchMatchFromV2(v2[i].GetMatchType()), - ) - } - - return filters -} - -func (f *SearchFilters) addFilter(op SearchMatchType, keyTyp filterKeyType, key string, val fmt.Stringer) { - if *f == nil { - *f = make(SearchFilters, 0, 1) - } - - *f = append(*f, SearchFilter{ - header: filterKey{ - typ: keyTyp, - str: key, - }, - value: val, - op: op, - }) -} - -func (f *SearchFilters) AddFilter(header, value string, op SearchMatchType) { - f.addFilter(op, 0, header, staticStringer(value)) -} - -func (f *SearchFilters) addReservedFilter(op SearchMatchType, keyTyp filterKeyType, val fmt.Stringer) { - f.addFilter(op, keyTyp, "", val) -} - -// addFlagFilters adds filters that works like flags: they don't need to have -// specific match type or value. They processed by NeoFS nodes by the fact -// of presence in search query. E.g.: PHY, ROOT. -func (f *SearchFilters) addFlagFilter(keyTyp filterKeyType) { - f.addFilter(MatchUnknown, keyTyp, "", staticStringer("")) -} - -func (f *SearchFilters) AddObjectVersionFilter(op SearchMatchType, v *pkg.Version) { - f.addReservedFilter(op, fKeyVersion, v) -} - -func (f *SearchFilters) AddObjectContainerIDFilter(m SearchMatchType, id *cid.ID) { - f.addReservedFilter(m, fKeyContainerID, id) -} - -func (f *SearchFilters) AddObjectOwnerIDFilter(m SearchMatchType, id *owner.ID) { - f.addReservedFilter(m, fKeyOwnerID, id) -} - -func (f SearchFilters) ToV2() []*v2object.SearchFilter { - result := make([]*v2object.SearchFilter, 0, len(f)) - - for i := range f { - v2 := new(v2object.SearchFilter) - v2.SetKey(f[i].header.String()) - v2.SetValue(f[i].value.String()) - v2.SetMatchType(f[i].op.ToV2()) - - result = append(result, v2) - } - - return result -} - -func (f *SearchFilters) addRootFilter() { - f.addFlagFilter(fKeyPropRoot) -} - -func (f *SearchFilters) AddRootFilter() { - f.addRootFilter() -} - -func (f *SearchFilters) addPhyFilter() { - f.addFlagFilter(fKeyPropPhy) -} - -func (f *SearchFilters) AddPhyFilter() { - f.addPhyFilter() -} - -// AddParentIDFilter adds filter by parent identifier. -func (f *SearchFilters) AddParentIDFilter(m SearchMatchType, id *ID) { - f.addReservedFilter(m, fKeyParent, id) -} - -// AddObjectIDFilter adds filter by object identifier. -func (f *SearchFilters) AddObjectIDFilter(m SearchMatchType, id *ID) { - f.addReservedFilter(m, fKeyObjectID, id) -} - -func (f *SearchFilters) AddSplitIDFilter(m SearchMatchType, id *SplitID) { - f.addReservedFilter(m, fKeySplitID, id) -} - -// AddTypeFilter adds filter by object type. -func (f *SearchFilters) AddTypeFilter(m SearchMatchType, typ Type) { - f.addReservedFilter(m, fKeyType, typ) -} - -// MarshalJSON encodes SearchFilters to protobuf JSON format. -func (f *SearchFilters) MarshalJSON() ([]byte, error) { - return json.Marshal(f.ToV2()) -} - -// UnmarshalJSON decodes SearchFilters from protobuf JSON format. -func (f *SearchFilters) UnmarshalJSON(data []byte) error { - var fsV2 []*v2object.SearchFilter - - if err := json.Unmarshal(data, &fsV2); err != nil { - return err - } - - *f = NewSearchFiltersFromV2(fsV2) - - return nil -} diff --git a/pkg/object/search_test.go b/pkg/object/search_test.go deleted file mode 100644 index 33b52e9..0000000 --- a/pkg/object/search_test.go +++ /dev/null @@ -1,208 +0,0 @@ -package object_test - -import ( - "crypto/rand" - "crypto/sha256" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/object" - v2object "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/stretchr/testify/require" -) - -var eqV2Matches = map[object.SearchMatchType]v2object.MatchType{ - object.MatchUnknown: v2object.MatchUnknown, - object.MatchStringEqual: v2object.MatchStringEqual, - object.MatchStringNotEqual: v2object.MatchStringNotEqual, - object.MatchNotPresent: v2object.MatchNotPresent, - object.MatchCommonPrefix: v2object.MatchCommonPrefix, -} - -func TestMatch(t *testing.T) { - t.Run("known matches", func(t *testing.T) { - for matchType, matchTypeV2 := range eqV2Matches { - require.Equal(t, matchTypeV2, matchType.ToV2()) - require.Equal(t, object.SearchMatchFromV2(matchTypeV2), matchType) - } - }) - - t.Run("unknown matches", func(t *testing.T) { - var unknownMatchType object.SearchMatchType - - for matchType := range eqV2Matches { - unknownMatchType += matchType - } - - unknownMatchType++ - - require.Equal(t, unknownMatchType.ToV2(), v2object.MatchUnknown) - - var unknownMatchTypeV2 v2object.MatchType - - for _, matchTypeV2 := range eqV2Matches { - unknownMatchTypeV2 += matchTypeV2 - } - - unknownMatchTypeV2++ - - require.Equal(t, object.SearchMatchFromV2(unknownMatchTypeV2), object.MatchUnknown) - }) -} - -func TestFilter(t *testing.T) { - inputs := [][]string{ - {"user-header", "user-value"}, - } - - filters := object.NewSearchFilters() - for i := range inputs { - filters.AddFilter(inputs[i][0], inputs[i][1], object.MatchStringEqual) - } - - require.Len(t, filters, len(inputs)) - for i := range inputs { - require.Equal(t, inputs[i][0], filters[i].Header()) - require.Equal(t, inputs[i][1], filters[i].Value()) - require.Equal(t, object.MatchStringEqual, filters[i].Operation()) - } - - v2 := filters.ToV2() - newFilters := object.NewSearchFiltersFromV2(v2) - require.Equal(t, filters, newFilters) -} - -func TestSearchFilters_AddRootFilter(t *testing.T) { - fs := new(object.SearchFilters) - - fs.AddRootFilter() - - require.Len(t, *fs, 1) - - f := (*fs)[0] - - require.Equal(t, object.MatchUnknown, f.Operation()) - require.Equal(t, v2object.FilterPropertyRoot, f.Header()) - require.Equal(t, "", f.Value()) -} - -func TestSearchFilters_AddPhyFilter(t *testing.T) { - fs := new(object.SearchFilters) - - fs.AddPhyFilter() - - require.Len(t, *fs, 1) - - f := (*fs)[0] - - require.Equal(t, object.MatchUnknown, f.Operation()) - require.Equal(t, v2object.FilterPropertyPhy, f.Header()) - require.Equal(t, "", f.Value()) -} - -func testOID() *object.ID { - cs := [sha256.Size]byte{} - - rand.Read(cs[:]) - - id := object.NewID() - id.SetSHA256(cs) - - return id -} - -func TestSearchFilters_AddParentIDFilter(t *testing.T) { - par := testOID() - - fs := object.SearchFilters{} - fs.AddParentIDFilter(object.MatchStringEqual, par) - - fsV2 := fs.ToV2() - - require.Len(t, fsV2, 1) - - require.Equal(t, v2object.FilterHeaderParent, fsV2[0].GetKey()) - require.Equal(t, par.String(), fsV2[0].GetValue()) - require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) -} - -func TestSearchFilters_AddObjectIDFilter(t *testing.T) { - id := testOID() - - fs := new(object.SearchFilters) - fs.AddObjectIDFilter(object.MatchStringEqual, id) - - t.Run("v2", func(t *testing.T) { - fsV2 := fs.ToV2() - - require.Len(t, fsV2, 1) - - require.Equal(t, v2object.FilterHeaderObjectID, fsV2[0].GetKey()) - require.Equal(t, id.String(), fsV2[0].GetValue()) - require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) - }) -} - -func TestSearchFilters_AddSplitIDFilter(t *testing.T) { - id := object.NewSplitID() - - fs := new(object.SearchFilters) - fs.AddSplitIDFilter(object.MatchStringEqual, id) - - t.Run("v2", func(t *testing.T) { - fsV2 := fs.ToV2() - - require.Len(t, fsV2, 1) - - require.Equal(t, v2object.FilterHeaderSplitID, fsV2[0].GetKey()) - require.Equal(t, id.String(), fsV2[0].GetValue()) - require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) - }) -} - -func TestSearchFilters_AddTypeFilter(t *testing.T) { - typ := object.TypeTombstone - - fs := new(object.SearchFilters) - fs.AddTypeFilter(object.MatchStringEqual, typ) - - t.Run("v2", func(t *testing.T) { - fsV2 := fs.ToV2() - - require.Len(t, fsV2, 1) - - require.Equal(t, v2object.FilterHeaderObjectType, fsV2[0].GetKey()) - require.Equal(t, typ.String(), fsV2[0].GetValue()) - require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) - }) -} - -func TestSearchFiltersEncoding(t *testing.T) { - fs := object.NewSearchFilters() - fs.AddFilter("key 1", "value 2", object.MatchStringEqual) - fs.AddFilter("key 2", "value 2", object.MatchStringNotEqual) - fs.AddFilter("key 2", "value 2", object.MatchCommonPrefix) - - t.Run("json", func(t *testing.T) { - data, err := fs.MarshalJSON() - require.NoError(t, err) - - fs2 := object.NewSearchFilters() - require.NoError(t, fs2.UnmarshalJSON(data)) - - require.Equal(t, fs, fs2) - }) -} - -func TestSearchMatchType_String(t *testing.T) { - toPtr := func(v object.SearchMatchType) *object.SearchMatchType { - return &v - } - - testEnumStrings(t, new(object.SearchMatchType), []enumStringItem{ - {val: toPtr(object.MatchCommonPrefix), str: "COMMON_PREFIX"}, - {val: toPtr(object.MatchStringEqual), str: "STRING_EQUAL"}, - {val: toPtr(object.MatchStringNotEqual), str: "STRING_NOT_EQUAL"}, - {val: toPtr(object.MatchNotPresent), str: "NOT_PRESENT"}, - {val: toPtr(object.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"}, - }) -} diff --git a/pkg/object/splitid.go b/pkg/object/splitid.go deleted file mode 100644 index 84288f2..0000000 --- a/pkg/object/splitid.go +++ /dev/null @@ -1,80 +0,0 @@ -package object - -import ( - "github.com/google/uuid" -) - -// SplitID is a UUIDv4 used as attribute in split objects. -type SplitID struct { - uuid uuid.UUID -} - -// NewSplitID returns UUID representation of splitID attribute. -// -// Defaults: -// - id: random UUID. -func NewSplitID() *SplitID { - return &SplitID{ - uuid: uuid.New(), - } -} - -// NewSplitIDFromV2 returns parsed UUID from bytes. -// If v is invalid UUIDv4 byte sequence, then function returns nil. -// -// Nil converts to nil. -func NewSplitIDFromV2(v []byte) *SplitID { - if v == nil { - return nil - } - - id := uuid.New() - - err := id.UnmarshalBinary(v) - if err != nil { - return nil - } - - return &SplitID{ - uuid: id, - } -} - -// Parse converts UUIDv4 string representation into SplitID. -func (id *SplitID) Parse(s string) (err error) { - id.uuid, err = uuid.Parse(s) - if err != nil { - return err - } - - return nil -} - -// String returns UUIDv4 string representation of SplitID. -func (id *SplitID) String() string { - if id == nil { - return "" - } - - return id.uuid.String() -} - -// SetUUID sets pre created UUID structure as SplitID. -func (id *SplitID) SetUUID(v uuid.UUID) { - if id != nil { - id.uuid = v - } -} - -// ToV2 converts SplitID to a representation of SplitID in neofs-api v2. -// -// Nil SplitID converts to nil. -func (id *SplitID) ToV2() []byte { - if id == nil { - return nil - } - - data, _ := id.uuid.MarshalBinary() // err is always nil - - return data -} diff --git a/pkg/object/splitid_test.go b/pkg/object/splitid_test.go deleted file mode 100644 index 7371ed3..0000000 --- a/pkg/object/splitid_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package object_test - -import ( - "testing" - - "github.com/google/uuid" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - "github.com/stretchr/testify/require" -) - -func TestSplitID(t *testing.T) { - id := object.NewSplitID() - - t.Run("toV2/fromV2", func(t *testing.T) { - data := id.ToV2() - - newID := object.NewSplitIDFromV2(data) - require.NotNil(t, newID) - - require.Equal(t, id, newID) - }) - - t.Run("string/parse", func(t *testing.T) { - idStr := id.String() - - newID := object.NewSplitID() - require.NoError(t, newID.Parse(idStr)) - - require.Equal(t, id, newID) - }) - - t.Run("set UUID", func(t *testing.T) { - newUUID := uuid.New() - id.SetUUID(newUUID) - - require.Equal(t, newUUID.String(), id.String()) - }) - - t.Run("nil value", func(t *testing.T) { - var newID *object.SplitID - - require.NotPanics(t, func() { - require.Nil(t, newID.ToV2()) - require.Equal(t, "", newID.String()) - }) - }) -} - -func TestSplitID_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *object.SplitID - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewIDFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x []byte - - require.Nil(t, object.NewSplitIDFromV2(x)) - }) -} diff --git a/pkg/object/splitinfo.go b/pkg/object/splitinfo.go deleted file mode 100644 index 38ae308..0000000 --- a/pkg/object/splitinfo.go +++ /dev/null @@ -1,74 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -type SplitInfo object.SplitInfo - -// NewSplitInfoFromV2 wraps v2 SplitInfo message to SplitInfo. -// -// Nil object.SplitInfo converts to nil. -func NewSplitInfoFromV2(v2 *object.SplitInfo) *SplitInfo { - return (*SplitInfo)(v2) -} - -// NewSplitInfo creates and initializes blank SplitInfo. -// -// Defaults: -// - splitID: nil; -// - lastPart nil; -// - link: nil. -func NewSplitInfo() *SplitInfo { - return NewSplitInfoFromV2(new(object.SplitInfo)) -} - -// ToV2 converts SplitInfo to v2 SplitInfo message. -// -// Nil SplitInfo converts to nil. -func (s *SplitInfo) ToV2() *object.SplitInfo { - return (*object.SplitInfo)(s) -} - -func (s *SplitInfo) SplitID() *SplitID { - return NewSplitIDFromV2( - (*object.SplitInfo)(s).GetSplitID(), - ) -} - -func (s *SplitInfo) SetSplitID(v *SplitID) { - (*object.SplitInfo)(s).SetSplitID(v.ToV2()) -} - -func (s *SplitInfo) LastPart() *ID { - return NewIDFromV2( - (*object.SplitInfo)(s).GetLastPart(), - ) -} - -func (s *SplitInfo) SetLastPart(v *ID) { - (*object.SplitInfo)(s).SetLastPart(v.ToV2()) -} - -func (s *SplitInfo) Link() *ID { - return NewIDFromV2( - (*object.SplitInfo)(s).GetLink(), - ) -} - -func (s *SplitInfo) SetLink(v *ID) { - (*object.SplitInfo)(s).SetLink(v.ToV2()) -} - -func (s *SplitInfo) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*object.SplitInfo)(s).StableMarshal(buf) -} - -func (s *SplitInfo) Unmarshal(data []byte) error { - return (*object.SplitInfo)(s).Unmarshal(data) -} diff --git a/pkg/object/splitinfo_test.go b/pkg/object/splitinfo_test.go deleted file mode 100644 index 500f5ba..0000000 --- a/pkg/object/splitinfo_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package object_test - -import ( - "crypto/rand" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/object" - objv2 "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/stretchr/testify/require" -) - -func TestSplitInfo(t *testing.T) { - s := object.NewSplitInfo() - splitID := object.NewSplitID() - lastPart := generateID() - link := generateID() - - s.SetSplitID(splitID) - require.Equal(t, splitID, s.SplitID()) - - s.SetLastPart(lastPart) - require.Equal(t, lastPart, s.LastPart()) - - s.SetLink(link) - require.Equal(t, link, s.Link()) - - t.Run("to and from v2", func(t *testing.T) { - v2 := s.ToV2() - newS := object.NewSplitInfoFromV2(v2) - - require.Equal(t, s, newS) - }) - - t.Run("marshal and unmarshal", func(t *testing.T) { - data, err := s.Marshal() - require.NoError(t, err) - - newS := object.NewSplitInfo() - - err = newS.Unmarshal(data) - require.NoError(t, err) - require.Equal(t, s, newS) - }) -} - -func generateID() *object.ID { - var buf [32]byte - _, _ = rand.Read(buf[:]) - - id := object.NewID() - id.SetSHA256(buf) - - return id -} - -func TestNewSplitInfoFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *objv2.SplitInfo - - require.Nil(t, object.NewSplitInfoFromV2(x)) - }) -} - -func TestSplitInfo_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *object.SplitInfo - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewSplitInfo(t *testing.T) { - t.Run("default values", func(t *testing.T) { - si := object.NewSplitInfo() - - // check initial values - require.Nil(t, si.SplitID()) - require.Nil(t, si.LastPart()) - require.Nil(t, si.Link()) - - // convert to v2 message - siV2 := si.ToV2() - - require.Nil(t, siV2.GetSplitID()) - require.Nil(t, siV2.GetLastPart()) - require.Nil(t, siV2.GetLink()) - }) -} diff --git a/pkg/object/test/generate.go b/pkg/object/test/generate.go deleted file mode 100644 index bb8d0c2..0000000 --- a/pkg/object/test/generate.go +++ /dev/null @@ -1,141 +0,0 @@ -package objecttest - -import ( - "crypto/sha256" - "math/rand" - - "github.com/google/uuid" - "github.com/nspcc-dev/neofs-api-go/pkg" - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" -) - -// ID returns random object.ID. -func ID() *object.ID { - checksum := [sha256.Size]byte{} - - rand.Read(checksum[:]) - - return IDWithChecksum(checksum) -} - -// IDWithChecksum returns object.ID initialized -// with specified checksum. -func IDWithChecksum(cs [sha256.Size]byte) *object.ID { - id := object.NewID() - id.SetSHA256(cs) - - return id -} - -// Address returns random object.Address. -func Address() *object.Address { - x := object.NewAddress() - - x.SetContainerID(cidtest.Generate()) - x.SetObjectID(ID()) - - return x -} - -// Range returns random object.Range. -func Range() *object.Range { - x := object.NewRange() - - x.SetOffset(1024) - x.SetLength(2048) - - return x -} - -// Attribute returns random object.Attribute. -func Attribute() *object.Attribute { - x := object.NewAttribute() - - x.SetKey("key") - x.SetValue("value") - - return x -} - -// SplitID returns random object.SplitID. -func SplitID() *object.SplitID { - x := object.NewSplitID() - - x.SetUUID(uuid.New()) - - return x -} - -func generateRaw(withParent bool) *object.RawObject { - x := object.NewRaw() - - x.SetID(ID()) - x.SetSessionToken(sessiontest.Generate()) - x.SetPayload([]byte{1, 2, 3}) - x.SetOwnerID(ownertest.Generate()) - x.SetContainerID(cidtest.Generate()) - x.SetType(object.TypeTombstone) - x.SetVersion(pkg.SDKVersion()) - x.SetPayloadSize(111) - x.SetCreationEpoch(222) - x.SetPreviousID(ID()) - x.SetParentID(ID()) - x.SetChildren(ID(), ID()) - x.SetAttributes(Attribute(), Attribute()) - x.SetSplitID(SplitID()) - x.SetPayloadChecksum(refstest.Checksum()) - x.SetPayloadHomomorphicHash(refstest.Checksum()) - x.SetSignature(refstest.Signature()) - - if withParent { - x.SetParent(generateRaw(false).Object()) - } - - return x -} - -// Raw returns random object.RawObject. -func Raw() *object.RawObject { - return generateRaw(true) -} - -// Object returns random object.Object. -func Object() *object.Object { - return Raw().Object() -} - -// Tombstone returns random object.Tombstone. -func Tombstone() *object.Tombstone { - x := object.NewTombstone() - - x.SetSplitID(SplitID()) - x.SetExpirationEpoch(13) - x.SetMembers([]*object.ID{ID(), ID()}) - - return x -} - -// SplitInfo returns random object.SplitInfo. -func SplitInfo() *object.SplitInfo { - x := object.NewSplitInfo() - - x.SetSplitID(SplitID()) - x.SetLink(ID()) - x.SetLastPart(ID()) - - return x -} - -// SearchFilters returns random object.SearchFilters. -func SearchFilters() object.SearchFilters { - x := object.NewSearchFilters() - - x.AddObjectIDFilter(object.MatchStringEqual, ID()) - x.AddObjectContainerIDFilter(object.MatchStringNotEqual, cidtest.Generate()) - - return x -} diff --git a/pkg/object/tombstone.go b/pkg/object/tombstone.go deleted file mode 100644 index 2d8ca65..0000000 --- a/pkg/object/tombstone.go +++ /dev/null @@ -1,132 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/nspcc-dev/neofs-api-go/v2/tombstone" -) - -// Tombstone represents v2-compatible tombstone structure. -type Tombstone tombstone.Tombstone - -// NewTombstoneFromV2 wraps v2 Tombstone message to Tombstone. -// -// Nil tombstone.Tombstone converts to nil. -func NewTombstoneFromV2(tV2 *tombstone.Tombstone) *Tombstone { - return (*Tombstone)(tV2) -} - -// NewTombstone creates and initializes blank Tombstone. -// -// Defaults: -// - exp: 0; -// - splitID: nil; -// - members: nil. -func NewTombstone() *Tombstone { - return NewTombstoneFromV2(new(tombstone.Tombstone)) -} - -// ToV2 converts Tombstone to v2 Tombstone message. -// -// Nil Tombstone converts to nil. -func (t *Tombstone) ToV2() *tombstone.Tombstone { - return (*tombstone.Tombstone)(t) -} - -// ExpirationEpoch return number of tombstone expiration epoch. -func (t *Tombstone) ExpirationEpoch() uint64 { - return (*tombstone.Tombstone)(t). - GetExpirationEpoch() -} - -// SetExpirationEpoch sets number of tombstone expiration epoch. -func (t *Tombstone) SetExpirationEpoch(v uint64) { - (*tombstone.Tombstone)(t). - SetExpirationEpoch(v) -} - -// SplitID returns identifier of object split hierarchy. -func (t *Tombstone) SplitID() *SplitID { - return NewSplitIDFromV2( - (*tombstone.Tombstone)(t). - GetSplitID(), - ) -} - -// SetSplitID sets identifier of object split hierarchy. -func (t *Tombstone) SetSplitID(v *SplitID) { - (*tombstone.Tombstone)(t). - SetSplitID(v.ToV2()) -} - -// Members returns list of objects to be deleted. -func (t *Tombstone) Members() []*ID { - msV2 := (*tombstone.Tombstone)(t). - GetMembers() - - if msV2 == nil { - return nil - } - - ms := make([]*ID, 0, len(msV2)) - - for i := range msV2 { - ms = append(ms, NewIDFromV2(msV2[i])) - } - - return ms -} - -// SetMembers sets list of objects to be deleted. -func (t *Tombstone) SetMembers(v []*ID) { - var ms []*refs.ObjectID - - if v != nil { - ms = (*tombstone.Tombstone)(t). - GetMembers() - - if ln := len(v); cap(ms) >= ln { - ms = ms[:0] - } else { - ms = make([]*refs.ObjectID, 0, ln) - } - - for i := range v { - ms = append(ms, v[i].ToV2()) - } - } - - (*tombstone.Tombstone)(t). - SetMembers(ms) -} - -// Marshal marshals Tombstone into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (t *Tombstone) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*tombstone.Tombstone)(t). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Tombstone. -func (t *Tombstone) Unmarshal(data []byte) error { - return (*tombstone.Tombstone)(t). - Unmarshal(data) -} - -// MarshalJSON encodes Tombstone to protobuf JSON format. -func (t *Tombstone) MarshalJSON() ([]byte, error) { - return (*tombstone.Tombstone)(t). - MarshalJSON() -} - -// UnmarshalJSON decodes Tombstone from protobuf JSON format. -func (t *Tombstone) UnmarshalJSON(data []byte) error { - return (*tombstone.Tombstone)(t). - UnmarshalJSON(data) -} diff --git a/pkg/object/tombstone_test.go b/pkg/object/tombstone_test.go deleted file mode 100644 index 340fa2a..0000000 --- a/pkg/object/tombstone_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package object - -import ( - "crypto/rand" - "crypto/sha256" - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/tombstone" - "github.com/stretchr/testify/require" -) - -func generateIDList(sz int) []*ID { - res := make([]*ID, sz) - cs := [sha256.Size]byte{} - - for i := 0; i < sz; i++ { - res[i] = NewID() - rand.Read(cs[:]) - res[i].SetSHA256(cs) - } - - return res -} - -func TestTombstone(t *testing.T) { - ts := NewTombstone() - - exp := uint64(13) - ts.SetExpirationEpoch(exp) - require.Equal(t, exp, ts.ExpirationEpoch()) - - splitID := NewSplitID() - ts.SetSplitID(splitID) - require.Equal(t, splitID, ts.SplitID()) - - members := generateIDList(3) - ts.SetMembers(members) - require.Equal(t, members, ts.Members()) -} - -func TestTombstoneEncoding(t *testing.T) { - ts := NewTombstone() - ts.SetExpirationEpoch(13) - ts.SetSplitID(NewSplitID()) - ts.SetMembers(generateIDList(5)) - - t.Run("binary", func(t *testing.T) { - data, err := ts.Marshal() - require.NoError(t, err) - - ts2 := NewTombstone() - require.NoError(t, ts2.Unmarshal(data)) - - require.Equal(t, ts, ts2) - }) - - t.Run("json", func(t *testing.T) { - data, err := ts.MarshalJSON() - require.NoError(t, err) - - ts2 := NewTombstone() - require.NoError(t, ts2.UnmarshalJSON(data)) - - require.Equal(t, ts, ts2) - }) -} - -func TestNewTombstoneFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *tombstone.Tombstone - - require.Nil(t, NewTombstoneFromV2(x)) - }) -} - -func TestNewTombstone(t *testing.T) { - t.Run("default values", func(t *testing.T) { - ts := NewTombstone() - - // check initial values - require.Nil(t, ts.SplitID()) - require.Nil(t, ts.Members()) - require.Zero(t, ts.ExpirationEpoch()) - - // convert to v2 message - tsV2 := ts.ToV2() - - require.Nil(t, tsV2.GetSplitID()) - require.Nil(t, tsV2.GetMembers()) - require.Zero(t, tsV2.GetExpirationEpoch()) - }) -} diff --git a/pkg/object/type.go b/pkg/object/type.go deleted file mode 100644 index 82d7c00..0000000 --- a/pkg/object/type.go +++ /dev/null @@ -1,69 +0,0 @@ -package object - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/object" -) - -type Type uint8 - -const ( - TypeRegular Type = iota - TypeTombstone - TypeStorageGroup -) - -func (t Type) ToV2() object.Type { - switch t { - case TypeTombstone: - return object.TypeTombstone - case TypeStorageGroup: - return object.TypeStorageGroup - default: - return object.TypeRegular - } -} - -func TypeFromV2(t object.Type) Type { - switch t { - case object.TypeTombstone: - return TypeTombstone - case object.TypeStorageGroup: - return TypeStorageGroup - default: - return TypeRegular - } -} - -// String returns string representation of Type. -// -// String mapping: -// * TypeTombstone: TOMBSTONE; -// * TypeStorageGroup: STORAGE_GROUP; -// * TypeRegular, default: REGULAR. -func (t Type) String() string { - return t.ToV2().String() -} - -// FromString parses Type from a string representation. -// It is a reverse action to String(). -// -// Returns true if s was parsed successfully. -func (t *Type) FromString(s string) bool { - var g object.Type - - ok := g.FromString(s) - - if ok { - *t = TypeFromV2(g) - } - - return ok -} - -// TypeFromString parses Type from its string representation. -// -// Deprecated: use FromString method. -func TypeFromString(s string) (t Type) { - t.FromString(s) - return -} diff --git a/pkg/object/type_test.go b/pkg/object/type_test.go deleted file mode 100644 index cb8a268..0000000 --- a/pkg/object/type_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package object_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/object" - v2object "github.com/nspcc-dev/neofs-api-go/v2/object" - "github.com/stretchr/testify/require" -) - -func TestType_ToV2(t *testing.T) { - typs := []struct { - t object.Type - t2 v2object.Type - }{ - { - t: object.TypeRegular, - t2: v2object.TypeRegular, - }, - { - t: object.TypeTombstone, - t2: v2object.TypeTombstone, - }, - { - t: object.TypeStorageGroup, - t2: v2object.TypeStorageGroup, - }, - } - - for _, item := range typs { - t2 := item.t.ToV2() - - require.Equal(t, item.t2, t2) - - require.Equal(t, item.t, object.TypeFromV2(item.t2)) - } -} - -func TestType_String(t *testing.T) { - toPtr := func(v object.Type) *object.Type { - return &v - } - - testEnumStrings(t, new(object.Type), []enumStringItem{ - {val: toPtr(object.TypeTombstone), str: "TOMBSTONE"}, - {val: toPtr(object.TypeStorageGroup), str: "STORAGE_GROUP"}, - {val: toPtr(object.TypeRegular), str: "REGULAR"}, - }) -} - -type enumIface interface { - FromString(string) bool - String() string -} - -type enumStringItem struct { - val enumIface - str string -} - -func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { - for _, item := range items { - require.Equal(t, item.str, item.val.String()) - - s := item.val.String() - - require.True(t, e.FromString(s), s) - - require.EqualValues(t, item.val, e, item.val) - } - - // incorrect strings - for _, str := range []string{ - "some string", - "undefined", - } { - require.False(t, e.FromString(str)) - } -} diff --git a/pkg/object/wellknown_attributes.go b/pkg/object/wellknown_attributes.go deleted file mode 100644 index 9e1793e..0000000 --- a/pkg/object/wellknown_attributes.go +++ /dev/null @@ -1,19 +0,0 @@ -package object - -const ( - // AttributeName is an attribute key that is commonly used to denote - // human-friendly name. - AttributeName = "Name" - - // AttributeFileName is an attribute key that is commonly used to denote - // file name to be associated with the object on saving. - AttributeFileName = "FileName" - - // AttributeTimestamp is an attribute key that is commonly used to denote - // user-defined local time of object creation in Unix Timestamp format. - AttributeTimestamp = "Timestamp" - - // AttributeTimestamp is an attribute key that is commonly used to denote - // MIME Content Type of object's payload. - AttributeContentType = "Content-Type" -) diff --git a/pkg/owner/id.go b/pkg/owner/id.go deleted file mode 100644 index 3ba5300..0000000 --- a/pkg/owner/id.go +++ /dev/null @@ -1,122 +0,0 @@ -package owner - -import ( - "bytes" - "errors" - "fmt" - - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// ID represents v2-compatible owner identifier. -type ID refs.OwnerID - -var errInvalidIDString = errors.New("incorrect format of the string owner ID") - -// NewIDFromV2 wraps v2 OwnerID message to ID. -// -// Nil refs.OwnerID converts to nil. -func NewIDFromV2(idV2 *refs.OwnerID) *ID { - return (*ID)(idV2) -} - -// NewID creates and initializes blank ID. -// -// Works similar as NewIDFromV2(new(OwnerID)). -// -// Defaults: -// - value: nil. -func NewID() *ID { - return NewIDFromV2(new(refs.OwnerID)) -} - -// SetNeo3Wallet sets owner identifier value to NEO3 wallet address. -func (id *ID) SetNeo3Wallet(v *NEO3Wallet) { - (*refs.OwnerID)(id).SetValue(v.Bytes()) -} - -// ToV2 returns the v2 owner ID message. -// -// Nil ID converts to nil. -func (id *ID) ToV2() *refs.OwnerID { - return (*refs.OwnerID)(id) -} - -func (id *ID) String() string { - return base58.Encode((*refs.OwnerID)(id).GetValue()) -} - -// Equal defines a comparison relation on ID's. -// -// ID's are equal if they have the same binary representation. -func (id *ID) Equal(id2 *ID) bool { - return bytes.Equal( - (*refs.ObjectID)(id).GetValue(), - (*refs.ObjectID)(id2).GetValue(), - ) -} - -func ScriptHashBE(id fmt.Stringer) ([]byte, error) { - addr, err := address.StringToUint160(id.String()) - if err != nil { - return nil, err - } - - return addr.BytesBE(), nil -} - -// NewIDFromNeo3Wallet creates new owner identity from 25-byte neo wallet. -func NewIDFromNeo3Wallet(v *NEO3Wallet) *ID { - id := NewID() - id.SetNeo3Wallet(v) - - return id -} - -// Parse converts base58 string representation into ID. -func (id *ID) Parse(s string) error { - data, err := base58.Decode(s) - if err != nil { - return fmt.Errorf("could not parse owner.ID from string: %w", err) - } else if len(data) != NEO3WalletSize { - return errInvalidIDString - } - - (*refs.OwnerID)(id).SetValue(data) - - return nil -} - -// Marshal marshals ID into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (id *ID) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.OwnerID)(id). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of ID. -func (id *ID) Unmarshal(data []byte) error { - return (*refs.OwnerID)(id). - Unmarshal(data) -} - -// MarshalJSON encodes ID to protobuf JSON format. -func (id *ID) MarshalJSON() ([]byte, error) { - return (*refs.OwnerID)(id). - MarshalJSON() -} - -// UnmarshalJSON decodes ID from protobuf JSON format. -func (id *ID) UnmarshalJSON(data []byte) error { - return (*refs.OwnerID)(id). - UnmarshalJSON(data) -} diff --git a/pkg/owner/id_test.go b/pkg/owner/id_test.go deleted file mode 100644 index f5cff06..0000000 --- a/pkg/owner/id_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package owner_test - -import ( - "strconv" - "testing" - - "github.com/mr-tron/base58" - . "github.com/nspcc-dev/neofs-api-go/pkg/owner" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -func TestIDV2(t *testing.T) { - id := ownertest.Generate() - - idV2 := id.ToV2() - - require.Equal(t, id, NewIDFromV2(idV2)) -} - -func TestNewIDFromNeo3Wallet(t *testing.T) { - wallet, err := NEO3WalletFromPublicKey(&test.DecodeKey(1).PublicKey) - require.NoError(t, err) - - id := NewIDFromNeo3Wallet(wallet) - require.Equal(t, id.ToV2().GetValue(), wallet.Bytes()) -} - -func TestID_Parse(t *testing.T) { - t.Run("should parse successful", func(t *testing.T) { - for i := 0; i < 10; i++ { - j := i - t.Run(strconv.Itoa(j), func(t *testing.T) { - wallet, err := NEO3WalletFromPublicKey(&test.DecodeKey(j).PublicKey) - require.NoError(t, err) - - eid := NewIDFromNeo3Wallet(wallet) - aid := NewID() - - require.NoError(t, aid.Parse(eid.String())) - require.Equal(t, eid, aid) - }) - } - }) - - t.Run("should failure on parse", func(t *testing.T) { - for i := 0; i < 10; i++ { - j := i - t.Run(strconv.Itoa(j), func(t *testing.T) { - cs := []byte{1, 2, 3, 4, 5, byte(j)} - str := base58.Encode(cs) - cid := NewID() - - require.Error(t, cid.Parse(str)) - }) - } - }) -} - -func TestIDEncoding(t *testing.T) { - id := ownertest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := id.Marshal() - require.NoError(t, err) - - id2 := NewID() - require.NoError(t, id2.Unmarshal(data)) - - require.Equal(t, id, id2) - }) - - t.Run("json", func(t *testing.T) { - data, err := id.MarshalJSON() - require.NoError(t, err) - - a2 := NewID() - require.NoError(t, a2.UnmarshalJSON(data)) - - require.Equal(t, id, a2) - }) -} - -func TestID_Equal(t *testing.T) { - var ( - data1 = []byte{1, 2, 3} - data2 = data1 - data3 = append(data1, 255) - ) - - id1 := ownertest.GenerateFromBytes(data1) - - require.True(t, id1.Equal( - ownertest.GenerateFromBytes(data2), - )) - - require.False(t, id1.Equal( - ownertest.GenerateFromBytes(data3), - )) -} - -func TestNewIDFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.OwnerID - - require.Nil(t, NewIDFromV2(x)) - }) -} - -func TestID_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *ID - - require.Nil(t, x.ToV2()) - }) -} - -func TestID_String(t *testing.T) { - t.Run("nil", func(t *testing.T) { - id := NewID() - - require.Empty(t, id.String()) - }) -} - -func TestNewID(t *testing.T) { - t.Run("default values", func(t *testing.T) { - id := NewID() - - // convert to v2 message - idV2 := id.ToV2() - - require.Nil(t, idV2.GetValue()) - }) -} diff --git a/pkg/owner/test/id.go b/pkg/owner/test/id.go deleted file mode 100644 index f542cf1..0000000 --- a/pkg/owner/test/id.go +++ /dev/null @@ -1,27 +0,0 @@ -package ownertest - -import ( - "math/rand" - - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// Generate returns owner.ID calculated -// from a random owner.NEO3Wallet. -func Generate() *owner.ID { - data := make([]byte, owner.NEO3WalletSize) - - rand.Read(data) - - return GenerateFromBytes(data) -} - -// GenerateFromBytes returns owner.ID generated -// from a passed byte slice. -func GenerateFromBytes(val []byte) *owner.ID { - idV2 := new(refs.OwnerID) - idV2.SetValue(val) - - return owner.NewIDFromV2(idV2) -} diff --git a/pkg/owner/wallet.go b/pkg/owner/wallet.go deleted file mode 100644 index 83d3b47..0000000 --- a/pkg/owner/wallet.go +++ /dev/null @@ -1,57 +0,0 @@ -package owner - -import ( - "crypto/ecdsa" - "fmt" - - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - crypto "github.com/nspcc-dev/neofs-crypto" -) - -// NEO3Wallet represents NEO3 wallet address. -type NEO3Wallet [NEO3WalletSize]byte - -// NEO3WalletSize contains size of neo3 wallet. -const NEO3WalletSize = 25 - -// NEO3WalletFromPublicKey converts public key to NEO3 wallet address. -func NEO3WalletFromPublicKey(key *ecdsa.PublicKey) (*NEO3Wallet, error) { - if key == nil { - return nil, crypto.ErrEmptyPublicKey - } - - neoPublicKey := keys.PublicKey{ - Curve: key.Curve, - X: key.X, - Y: key.Y, - } - - d, err := base58.Decode(neoPublicKey.Address()) - if err != nil { - return nil, fmt.Errorf("can't decode neo3 address from key: %w", err) - } - - w := new(NEO3Wallet) - - copy(w.Bytes(), d) - - return w, nil -} - -func (w *NEO3Wallet) String() string { - if w != nil { - return base58.Encode(w[:]) - } - - return "" -} - -// Bytes returns slice of NEO3 wallet address bytes. -func (w *NEO3Wallet) Bytes() []byte { - if w != nil { - return w[:] - } - - return nil -} diff --git a/pkg/reputation/peer.go b/pkg/reputation/peer.go deleted file mode 100644 index cdbfce1..0000000 --- a/pkg/reputation/peer.go +++ /dev/null @@ -1,100 +0,0 @@ -package reputation - -import ( - "bytes" - - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neofs-api-go/v2/reputation" - crypto "github.com/nspcc-dev/neofs-crypto" -) - -// PeerID represents peer ID compatible with NeoFS API v2. -type PeerID reputation.PeerID - -// NewPeerID creates and returns blank PeerID. -// -// Defaults: -// - publicKey: nil. -func NewPeerID() *PeerID { - return PeerIDFromV2(new(reputation.PeerID)) -} - -// PeerIDFromV2 converts NeoFS API v2 reputation.PeerID message to PeerID. -// -// Nil reputation.PeerID converts to nil. -func PeerIDFromV2(id *reputation.PeerID) *PeerID { - return (*PeerID)(id) -} - -// SetPublicKey sets peer ID as a compressed public key. -func (x *PeerID) SetPublicKey(v [crypto.PublicKeyCompressedSize]byte) { - (*reputation.PeerID)(x). - SetPublicKey(v[:]) -} - -// ToV2 converts PeerID to NeoFS API v2 reputation.PeerID message. -// -// Nil PeerID converts to nil. -func (x *PeerID) ToV2() *reputation.PeerID { - return (*reputation.PeerID)(x) -} - -// Equal returns true if identifiers are identical. -func (x *PeerID) Equal(x2 *PeerID) bool { - return bytes.Equal( - (*reputation.PeerID)(x).GetPublicKey(), - (*reputation.PeerID)(x2).GetPublicKey(), - ) -} - -// Parse parses PeerID from base58 string. -func (x *PeerID) Parse(s string) error { - data, err := base58.Decode(s) - if err != nil { - return err - } - - (*reputation.PeerID)(x).SetPublicKey(data) - - return nil -} - -// String returns base58 string representation of PeerID. -func (x *PeerID) String() string { - return base58.Encode( - (*reputation.PeerID)(x). - GetPublicKey(), - ) -} - -// Marshal marshals PeerID into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (x *PeerID) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*reputation.PeerID)(x). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of PeerID. -func (x *PeerID) Unmarshal(data []byte) error { - return (*reputation.PeerID)(x). - Unmarshal(data) -} - -// MarshalJSON encodes PeerID to protobuf JSON format. -func (x *PeerID) MarshalJSON() ([]byte, error) { - return (*reputation.PeerID)(x). - MarshalJSON() -} - -// UnmarshalJSON decodes PeerID from protobuf JSON format. -func (x *PeerID) UnmarshalJSON(data []byte) error { - return (*reputation.PeerID)(x). - UnmarshalJSON(data) -} diff --git a/pkg/reputation/peer_test.go b/pkg/reputation/peer_test.go deleted file mode 100644 index d3463a5..0000000 --- a/pkg/reputation/peer_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package reputation_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/reputation" - reputationtest "github.com/nspcc-dev/neofs-api-go/pkg/reputation/test" - reputationV2 "github.com/nspcc-dev/neofs-api-go/v2/reputation" - "github.com/stretchr/testify/require" -) - -func TestPeerID_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *reputation.PeerID - - require.Nil(t, x.ToV2()) - }) - - t.Run("nil", func(t *testing.T) { - peerID := reputationtest.GeneratePeerID() - - require.Equal(t, peerID, reputation.PeerIDFromV2(peerID.ToV2())) - }) -} - -func TestPeerID_String(t *testing.T) { - t.Run("Parse/String", func(t *testing.T) { - id := reputationtest.GeneratePeerID() - - strID := id.String() - - id2 := reputation.NewPeerID() - - err := id2.Parse(strID) - require.NoError(t, err) - - require.Equal(t, id, id2) - }) - - t.Run("nil", func(t *testing.T) { - id := reputation.NewPeerID() - - require.Empty(t, id.String()) - }) -} - -func TestPeerIDEncoding(t *testing.T) { - id := reputationtest.GeneratePeerID() - - t.Run("binary", func(t *testing.T) { - data, err := id.Marshal() - require.NoError(t, err) - - id2 := reputation.NewPeerID() - require.NoError(t, id2.Unmarshal(data)) - - require.Equal(t, id, id2) - }) - - t.Run("json", func(t *testing.T) { - data, err := id.MarshalJSON() - require.NoError(t, err) - - id2 := reputation.NewPeerID() - require.NoError(t, id2.UnmarshalJSON(data)) - - require.Equal(t, id, id2) - }) -} - -func TestPeerIDFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *reputationV2.PeerID - - require.Nil(t, reputation.PeerIDFromV2(x)) - }) -} - -func TestNewPeerID(t *testing.T) { - t.Run("default values", func(t *testing.T) { - id := reputation.NewPeerID() - - // convert to v2 message - idV2 := id.ToV2() - - require.Nil(t, idV2.GetPublicKey()) - }) -} diff --git a/pkg/reputation/test/generate.go b/pkg/reputation/test/generate.go deleted file mode 100644 index c103800..0000000 --- a/pkg/reputation/test/generate.go +++ /dev/null @@ -1,53 +0,0 @@ -package reputationtest - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/reputation" - crypto "github.com/nspcc-dev/neofs-crypto" - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -func GeneratePeerID() *reputation.PeerID { - v := reputation.NewPeerID() - - key := [crypto.PublicKeyCompressedSize]byte{} - copy(key[:], crypto.MarshalPublicKey(&test.DecodeKey(-1).PublicKey)) - - v.SetPublicKey(key) - - return v -} - -func GenerateTrust() *reputation.Trust { - v := reputation.NewTrust() - v.SetPeer(GeneratePeerID()) - v.SetValue(1.5) - - return v -} - -func GeneratePeerToPeerTrust() *reputation.PeerToPeerTrust { - v := reputation.NewPeerToPeerTrust() - v.SetTrustingPeer(GeneratePeerID()) - v.SetTrust(GenerateTrust()) - - return v -} - -func GenerateGlobalTrust() *reputation.GlobalTrust { - v := reputation.NewGlobalTrust() - v.SetManager(GeneratePeerID()) - v.SetTrust(GenerateTrust()) - - return v -} - -func GenerateSignedGlobalTrust(t testing.TB) *reputation.GlobalTrust { - gt := GenerateGlobalTrust() - - require.NoError(t, gt.Sign(test.DecodeKey(0))) - - return gt -} diff --git a/pkg/reputation/trust.go b/pkg/reputation/trust.go deleted file mode 100644 index e3dd5e5..0000000 --- a/pkg/reputation/trust.go +++ /dev/null @@ -1,357 +0,0 @@ -package reputation - -import ( - "crypto/ecdsa" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/util/signature" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/nspcc-dev/neofs-api-go/v2/reputation" - signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Trust represents peer's trust compatible with NeoFS API v2. -type Trust reputation.Trust - -// NewTrust creates and returns blank Trust. -// -// Defaults: -// - value: 0; -// - PeerID: nil. -func NewTrust() *Trust { - return TrustFromV2(new(reputation.Trust)) -} - -// TrustFromV2 converts NeoFS API v2 -// reputation.Trust message structure to Trust. -// -// Nil reputation.Trust converts to nil. -func TrustFromV2(t *reputation.Trust) *Trust { - return (*Trust)(t) -} - -// ToV2 converts Trust to NeoFS API v2 -// reputation.Trust message structure. -// -// Nil Trust converts to nil. -func (x *Trust) ToV2() *reputation.Trust { - return (*reputation.Trust)(x) -} - -// TrustsToV2 converts slice of Trust's to slice of -// NeoFS API v2 reputation.Trust message structures. -func TrustsToV2(xs []*Trust) (res []*reputation.Trust) { - if xs != nil { - res = make([]*reputation.Trust, 0, len(xs)) - - for i := range xs { - res = append(res, xs[i].ToV2()) - } - } - - return -} - -// SetPeer sets trusted peer ID. -func (x *Trust) SetPeer(id *PeerID) { - (*reputation.Trust)(x). - SetPeer(id.ToV2()) -} - -// Peer returns trusted peer ID. -func (x *Trust) Peer() *PeerID { - return PeerIDFromV2( - (*reputation.Trust)(x).GetPeer(), - ) -} - -// SetValue sets trust value. -func (x *Trust) SetValue(val float64) { - (*reputation.Trust)(x). - SetValue(val) -} - -// Value returns trust value. -func (x *Trust) Value() float64 { - return (*reputation.Trust)(x). - GetValue() -} - -// Marshal marshals Trust into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (x *Trust) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*reputation.Trust)(x).StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Trust. -func (x *Trust) Unmarshal(data []byte) error { - return (*reputation.Trust)(x). - Unmarshal(data) -} - -// MarshalJSON encodes Trust to protobuf JSON format. -func (x *Trust) MarshalJSON() ([]byte, error) { - return (*reputation.Trust)(x). - MarshalJSON() -} - -// UnmarshalJSON decodes Trust from protobuf JSON format. -func (x *Trust) UnmarshalJSON(data []byte) error { - return (*reputation.Trust)(x). - UnmarshalJSON(data) -} - -// PeerToPeerTrust represents directed peer-to-peer trust -// compatible with NeoFS API v2. -type PeerToPeerTrust reputation.PeerToPeerTrust - -// NewPeerToPeerTrust creates and returns blank PeerToPeerTrust. -// -// Defaults: -// - trusting: nil; -// - trust: nil. -func NewPeerToPeerTrust() *PeerToPeerTrust { - return PeerToPeerTrustFromV2(new(reputation.PeerToPeerTrust)) -} - -// PeerToPeerTrustFromV2 converts NeoFS API v2 -// reputation.PeerToPeerTrust message structure to PeerToPeerTrust. -// -// Nil reputation.PeerToPeerTrust converts to nil. -func PeerToPeerTrustFromV2(t *reputation.PeerToPeerTrust) *PeerToPeerTrust { - return (*PeerToPeerTrust)(t) -} - -// ToV2 converts PeerToPeerTrust to NeoFS API v2 -// reputation.PeerToPeerTrust message structure. -// -// Nil PeerToPeerTrust converts to nil. -func (x *PeerToPeerTrust) ToV2() *reputation.PeerToPeerTrust { - return (*reputation.PeerToPeerTrust)(x) -} - -// SetTrustingPeer sets trusting peer ID. -func (x *PeerToPeerTrust) SetTrustingPeer(id *PeerID) { - (*reputation.PeerToPeerTrust)(x). - SetTrustingPeer(id.ToV2()) -} - -// TrustingPeer returns trusting peer ID. -func (x *PeerToPeerTrust) TrustingPeer() *PeerID { - return PeerIDFromV2( - (*reputation.PeerToPeerTrust)(x). - GetTrustingPeer(), - ) -} - -// SetTrust sets trust value of the trusting peer to the trusted one. -func (x *PeerToPeerTrust) SetTrust(t *Trust) { - (*reputation.PeerToPeerTrust)(x). - SetTrust(t.ToV2()) -} - -// Trust returns trust value of the trusting peer to the trusted one. -func (x *PeerToPeerTrust) Trust() *Trust { - return TrustFromV2( - (*reputation.PeerToPeerTrust)(x). - GetTrust(), - ) -} - -// Marshal marshals PeerToPeerTrust into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (x *PeerToPeerTrust) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*reputation.PeerToPeerTrust)(x).StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of PeerToPeerTrust. -func (x *PeerToPeerTrust) Unmarshal(data []byte) error { - return (*reputation.PeerToPeerTrust)(x). - Unmarshal(data) -} - -// MarshalJSON encodes PeerToPeerTrust to protobuf JSON format. -func (x *PeerToPeerTrust) MarshalJSON() ([]byte, error) { - return (*reputation.PeerToPeerTrust)(x). - MarshalJSON() -} - -// UnmarshalJSON decodes PeerToPeerTrust from protobuf JSON format. -func (x *PeerToPeerTrust) UnmarshalJSON(data []byte) error { - return (*reputation.PeerToPeerTrust)(x). - UnmarshalJSON(data) -} - -// GlobalTrust represents peer's global trust compatible with NeoFS API v2. -type GlobalTrust reputation.GlobalTrust - -// NewGlobalTrust creates and returns blank GlobalTrust. -// -// Defaults: -// - version: pkg.SDKVersion(); -// - manager: nil; -// - trust: nil. -func NewGlobalTrust() *GlobalTrust { - gt := GlobalTrustFromV2(new(reputation.GlobalTrust)) - gt.SetVersion(pkg.SDKVersion()) - - return gt -} - -// GlobalTrustFromV2 converts NeoFS API v2 -// reputation.GlobalTrust message structure to GlobalTrust. -// -// Nil reputation.GlobalTrust converts to nil. -func GlobalTrustFromV2(t *reputation.GlobalTrust) *GlobalTrust { - return (*GlobalTrust)(t) -} - -// ToV2 converts GlobalTrust to NeoFS API v2 -// reputation.GlobalTrust message structure. -// -// Nil GlobalTrust converts to nil. -func (x *GlobalTrust) ToV2() *reputation.GlobalTrust { - return (*reputation.GlobalTrust)(x) -} - -// SetVersion sets GlobalTrust's protocol version. -func (x *GlobalTrust) SetVersion(version *pkg.Version) { - (*reputation.GlobalTrust)(x). - SetVersion(version.ToV2()) -} - -// Version returns GlobalTrust's protocol version. -func (x *GlobalTrust) Version() *pkg.Version { - return pkg.NewVersionFromV2( - (*reputation.GlobalTrust)(x). - GetVersion(), - ) -} - -func (x *GlobalTrust) setBodyField(setter func(*reputation.GlobalTrustBody)) { - if x != nil { - v2 := (*reputation.GlobalTrust)(x) - - body := v2.GetBody() - if body == nil { - body = new(reputation.GlobalTrustBody) - v2.SetBody(body) - } - - setter(body) - } -} - -// SetManager sets node manager ID. -func (x *GlobalTrust) SetManager(id *PeerID) { - x.setBodyField(func(body *reputation.GlobalTrustBody) { - body.SetManager(id.ToV2()) - }) -} - -// Manager returns node manager ID. -func (x *GlobalTrust) Manager() *PeerID { - return PeerIDFromV2( - (*reputation.GlobalTrust)(x). - GetBody(). - GetManager(), - ) -} - -// SetTrust sets global trust value. -func (x *GlobalTrust) SetTrust(trust *Trust) { - x.setBodyField(func(body *reputation.GlobalTrustBody) { - body.SetTrust(trust.ToV2()) - }) -} - -// Trust returns global trust value. -func (x *GlobalTrust) Trust() *Trust { - return TrustFromV2( - (*reputation.GlobalTrust)(x). - GetBody(). - GetTrust(), - ) -} - -// Sign signs global trust value with key. -func (x *GlobalTrust) Sign(key *ecdsa.PrivateKey) error { - v2 := (*reputation.GlobalTrust)(x) - - sigV2 := v2.GetSignature() - if sigV2 == nil { - sigV2 = new(refs.Signature) - v2.SetSignature(sigV2) - } - - return signature.SignDataWithHandler( - key, - signatureV2.StableMarshalerWrapper{SM: v2.GetBody()}, - func(key, sig []byte) { - sigV2.SetKey(key) - sigV2.SetSign(sig) - }, - ) -} - -// VerifySignature verifies global trust signature. -func (x *GlobalTrust) VerifySignature() error { - v2 := (*reputation.GlobalTrust)(x) - - sigV2 := v2.GetSignature() - if sigV2 == nil { - sigV2 = new(refs.Signature) - } - - return signature.VerifyDataWithSource( - signatureV2.StableMarshalerWrapper{SM: v2.GetBody()}, - func() ([]byte, []byte) { - return sigV2.GetKey(), sigV2.GetSign() - }, - ) -} - -// Marshal marshals GlobalTrust into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (x *GlobalTrust) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*reputation.GlobalTrust)(x).StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of GlobalTrust. -func (x *GlobalTrust) Unmarshal(data []byte) error { - return (*reputation.GlobalTrust)(x). - Unmarshal(data) -} - -// MarshalJSON encodes GlobalTrust to protobuf JSON format. -func (x *GlobalTrust) MarshalJSON() ([]byte, error) { - return (*reputation.GlobalTrust)(x). - MarshalJSON() -} - -// UnmarshalJSON decodes GlobalTrust from protobuf JSON format. -func (x *GlobalTrust) UnmarshalJSON(data []byte) error { - return (*reputation.GlobalTrust)(x). - UnmarshalJSON(data) -} diff --git a/pkg/reputation/trust_test.go b/pkg/reputation/trust_test.go deleted file mode 100644 index 41072e9..0000000 --- a/pkg/reputation/trust_test.go +++ /dev/null @@ -1,250 +0,0 @@ -package reputation_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/reputation" - reputationtest "github.com/nspcc-dev/neofs-api-go/pkg/reputation/test" - reputationV2 "github.com/nspcc-dev/neofs-api-go/v2/reputation" - reputationtestV2 "github.com/nspcc-dev/neofs-api-go/v2/reputation/test" - "github.com/stretchr/testify/require" -) - -func TestTrust(t *testing.T) { - trust := reputation.NewTrust() - - id := reputationtest.GeneratePeerID() - trust.SetPeer(id) - require.Equal(t, id, trust.Peer()) - - val := 1.5 - trust.SetValue(val) - require.Equal(t, val, trust.Value()) - - t.Run("binary encoding", func(t *testing.T) { - trust := reputationtest.GenerateTrust() - data, err := trust.Marshal() - require.NoError(t, err) - - trust2 := reputation.NewTrust() - require.NoError(t, trust2.Unmarshal(data)) - require.Equal(t, trust, trust2) - }) - - t.Run("JSON encoding", func(t *testing.T) { - trust := reputationtest.GenerateTrust() - data, err := trust.MarshalJSON() - require.NoError(t, err) - - trust2 := reputation.NewTrust() - require.NoError(t, trust2.UnmarshalJSON(data)) - require.Equal(t, trust, trust2) - }) -} - -func TestPeerToPeerTrust(t *testing.T) { - t.Run("v2", func(t *testing.T) { - p2ptV2 := reputationtestV2.GeneratePeerToPeerTrust(false) - - p2pt := reputation.PeerToPeerTrustFromV2(p2ptV2) - - require.Equal(t, p2ptV2, p2pt.ToV2()) - }) - - t.Run("getters+setters", func(t *testing.T) { - p2pt := reputation.NewPeerToPeerTrust() - - require.Nil(t, p2pt.TrustingPeer()) - require.Nil(t, p2pt.Trust()) - - trusting := reputationtest.GeneratePeerID() - p2pt.SetTrustingPeer(trusting) - require.Equal(t, trusting, p2pt.TrustingPeer()) - - trust := reputationtest.GenerateTrust() - p2pt.SetTrust(trust) - require.Equal(t, trust, p2pt.Trust()) - }) - - t.Run("encoding", func(t *testing.T) { - p2pt := reputationtest.GeneratePeerToPeerTrust() - - t.Run("binary", func(t *testing.T) { - data, err := p2pt.Marshal() - require.NoError(t, err) - - p2pt2 := reputation.NewPeerToPeerTrust() - require.NoError(t, p2pt2.Unmarshal(data)) - require.Equal(t, p2pt, p2pt2) - }) - - t.Run("JSON", func(t *testing.T) { - data, err := p2pt.MarshalJSON() - require.NoError(t, err) - - p2pt2 := reputation.NewPeerToPeerTrust() - require.NoError(t, p2pt2.UnmarshalJSON(data)) - require.Equal(t, p2pt, p2pt2) - }) - }) -} - -func TestGlobalTrust(t *testing.T) { - t.Run("v2", func(t *testing.T) { - gtV2 := reputationtestV2.GenerateGlobalTrust(false) - - gt := reputation.GlobalTrustFromV2(gtV2) - - require.Equal(t, gtV2, gt.ToV2()) - }) - - t.Run("getters+setters", func(t *testing.T) { - gt := reputation.NewGlobalTrust() - - require.Equal(t, pkg.SDKVersion(), gt.Version()) - require.Nil(t, gt.Manager()) - require.Nil(t, gt.Trust()) - - version := pkg.NewVersion() - version.SetMajor(13) - version.SetMinor(31) - gt.SetVersion(version) - require.Equal(t, version, gt.Version()) - - mngr := reputationtest.GeneratePeerID() - gt.SetManager(mngr) - require.Equal(t, mngr, gt.Manager()) - - trust := reputationtest.GenerateTrust() - gt.SetTrust(trust) - require.Equal(t, trust, gt.Trust()) - }) - - t.Run("sign+verify", func(t *testing.T) { - gt := reputationtest.GenerateSignedGlobalTrust(t) - - err := gt.VerifySignature() - require.NoError(t, err) - }) - - t.Run("encoding", func(t *testing.T) { - t.Run("binary", func(t *testing.T) { - gt := reputationtest.GenerateSignedGlobalTrust(t) - - data, err := gt.Marshal() - require.NoError(t, err) - - gt2 := reputation.NewGlobalTrust() - require.NoError(t, gt2.Unmarshal(data)) - require.Equal(t, gt, gt2) - }) - - t.Run("JSON", func(t *testing.T) { - gt := reputationtest.GenerateSignedGlobalTrust(t) - data, err := gt.MarshalJSON() - require.NoError(t, err) - - gt2 := reputation.NewGlobalTrust() - require.NoError(t, gt2.UnmarshalJSON(data)) - require.Equal(t, gt, gt2) - }) - }) -} - -func TestTrustFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *reputationV2.Trust - - require.Nil(t, reputation.TrustFromV2(x)) - }) -} - -func TestPeerToPeerTrustFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *reputationV2.PeerToPeerTrust - - require.Nil(t, reputation.PeerToPeerTrustFromV2(x)) - }) -} - -func TestGlobalTrustFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *reputationV2.GlobalTrust - - require.Nil(t, reputation.GlobalTrustFromV2(x)) - }) -} - -func TestTrust_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *reputation.Trust - - require.Nil(t, x.ToV2()) - }) -} - -func TestPeerToPeerTrust_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *reputation.PeerToPeerTrust - - require.Nil(t, x.ToV2()) - }) -} - -func TestGlobalTrust_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *reputation.GlobalTrust - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewTrust(t *testing.T) { - t.Run("default values", func(t *testing.T) { - trust := reputation.NewTrust() - - // check initial values - require.Zero(t, trust.Value()) - require.Nil(t, trust.Peer()) - - // convert to v2 message - trustV2 := trust.ToV2() - - require.Zero(t, trustV2.GetValue()) - require.Nil(t, trustV2.GetPeer()) - }) -} - -func TestNewPeerToPeerTrust(t *testing.T) { - t.Run("default values", func(t *testing.T) { - trust := reputation.NewPeerToPeerTrust() - - // check initial values - require.Nil(t, trust.Trust()) - require.Nil(t, trust.TrustingPeer()) - - // convert to v2 message - trustV2 := trust.ToV2() - - require.Nil(t, trustV2.GetTrust()) - require.Nil(t, trustV2.GetTrustingPeer()) - }) -} - -func TestNewGlobalTrust(t *testing.T) { - t.Run("default values", func(t *testing.T) { - trust := reputation.NewGlobalTrust() - - // check initial values - require.Nil(t, trust.Manager()) - require.Nil(t, trust.Trust()) - - require.Equal(t, pkg.SDKVersion().String(), trust.Version().String()) - - // convert to v2 message - trustV2 := trust.ToV2() - - require.Nil(t, trustV2.GetBody()) - }) -} diff --git a/pkg/session/container.go b/pkg/session/container.go deleted file mode 100644 index a3d2d91..0000000 --- a/pkg/session/container.go +++ /dev/null @@ -1,139 +0,0 @@ -package session - -import ( - cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" - "github.com/nspcc-dev/neofs-api-go/v2/session" -) - -// ContainerContext represents NeoFS API v2-compatible -// context of the container session. -// -// It is a wrapper over session.ContainerSessionContext -// which allows to abstract from details of the message -// structure. -type ContainerContext session.ContainerSessionContext - -// NewContainerContext creates and returns blank ContainerSessionContext. -// -// Defaults: -// - not bound to any operation; -// - applied to all containers. -func NewContainerContext() *ContainerContext { - v2 := new(session.ContainerSessionContext) - v2.SetWildcard(true) - - return ContainerContextFromV2(v2) -} - -// ContainerContextFromV2 wraps session.ContainerSessionContext -// into ContainerContext. -func ContainerContextFromV2(v *session.ContainerSessionContext) *ContainerContext { - return (*ContainerContext)(v) -} - -// ToV2 converts ContainerContext to session.ContainerSessionContext -// message structure. -func (x *ContainerContext) ToV2() *session.ContainerSessionContext { - return (*session.ContainerSessionContext)(x) -} - -// ApplyTo specifies which container the ContainerContext applies to. -// -// If id is nil, ContainerContext is applied to all containers. -func (x *ContainerContext) ApplyTo(id *cid.ID) { - v2 := (*session.ContainerSessionContext)(x) - - v2.SetWildcard(id == nil) - v2.SetContainerID(id.ToV2()) -} - -// ActOnAllContainers is a helper function that conveniently -// applies ContainerContext to all containers. -func ApplyToAllContainers(c *ContainerContext) { - c.ApplyTo(nil) -} - -// Container returns identifier of the container -// to which the ContainerContext applies. -// -// Returns nil if ContainerContext is applied to -// all containers. -func (x *ContainerContext) Container() *cid.ID { - v2 := (*session.ContainerSessionContext)(x) - - if v2.Wildcard() { - return nil - } - - return cid.NewFromV2(v2.ContainerID()) -} - -func (x *ContainerContext) forVerb(v session.ContainerSessionVerb) { - (*session.ContainerSessionContext)(x). - SetVerb(v) -} - -func (x *ContainerContext) isForVerb(v session.ContainerSessionVerb) bool { - return (*session.ContainerSessionContext)(x). - Verb() == v -} - -// ForPut binds the ContainerContext to -// PUT operation. -func (x *ContainerContext) ForPut() { - x.forVerb(session.ContainerVerbPut) -} - -// IsForPut checks if ContainerContext is bound to -// PUT operation. -func (x *ContainerContext) IsForPut() bool { - return x.isForVerb(session.ContainerVerbPut) -} - -// ForDelete binds the ContainerContext to -// DELETE operation. -func (x *ContainerContext) ForDelete() { - x.forVerb(session.ContainerVerbDelete) -} - -// IsForDelete checks if ContainerContext is bound to -// DELETE operation. -func (x *ContainerContext) IsForDelete() bool { - return x.isForVerb(session.ContainerVerbDelete) -} - -// ForSetEACL binds the ContainerContext to -// SETEACL operation. -func (x *ContainerContext) ForSetEACL() { - x.forVerb(session.ContainerVerbSetEACL) -} - -// IsForSetEACL checks if ContainerContext is bound to -// SETEACL operation. -func (x *ContainerContext) IsForSetEACL() bool { - return x.isForVerb(session.ContainerVerbSetEACL) -} - -// Marshal marshals ContainerContext into a protobuf binary form. -func (x *ContainerContext) Marshal(bs ...[]byte) ([]byte, error) { - var buf []byte - if len(bs) > 0 { - buf = bs[0] - } - return x.ToV2().StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of ContainerContext. -func (x *ContainerContext) Unmarshal(data []byte) error { - return x.ToV2().Unmarshal(data) -} - -// MarshalJSON encodes ContainerContext to protobuf JSON format. -func (x *ContainerContext) MarshalJSON() ([]byte, error) { - return x.ToV2().MarshalJSON() -} - -// UnmarshalJSON decodes ContainerContext from protobuf JSON format. -func (x *ContainerContext) UnmarshalJSON(data []byte) error { - return x.ToV2().UnmarshalJSON(data) -} diff --git a/pkg/session/container_test.go b/pkg/session/container_test.go deleted file mode 100644 index 38c97ee..0000000 --- a/pkg/session/container_test.go +++ /dev/null @@ -1,112 +0,0 @@ -package session_test - -import ( - "testing" - - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test" - v2session "github.com/nspcc-dev/neofs-api-go/v2/session" - "github.com/stretchr/testify/require" -) - -func TestContainerContextVerbs(t *testing.T) { - c := session.NewContainerContext() - - assert := func(setter func(), getter func() bool, verb v2session.ContainerSessionVerb) { - setter() - - require.True(t, getter()) - - require.Equal(t, verb, c.ToV2().Verb()) - } - - t.Run("PUT", func(t *testing.T) { - assert(c.ForPut, c.IsForPut, v2session.ContainerVerbPut) - }) - - t.Run("DELETE", func(t *testing.T) { - assert(c.ForDelete, c.IsForDelete, v2session.ContainerVerbDelete) - }) - - t.Run("SETEACL", func(t *testing.T) { - assert(c.ForSetEACL, c.IsForSetEACL, v2session.ContainerVerbSetEACL) - }) -} - -func TestContainerContext_ApplyTo(t *testing.T) { - c := session.NewContainerContext() - id := cidtest.Generate() - - t.Run("method", func(t *testing.T) { - c.ApplyTo(id) - - require.Equal(t, id, c.Container()) - - c.ApplyTo(nil) - - require.Nil(t, c.Container()) - }) - - t.Run("helper functions", func(t *testing.T) { - c.ApplyTo(id) - - session.ApplyToAllContainers(c) - - require.Nil(t, c.Container()) - }) -} - -func TestFilter_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *session.ContainerContext - - require.Nil(t, x.ToV2()) - }) - - t.Run("default values", func(t *testing.T) { - c := session.NewContainerContext() - - // check initial values - require.Nil(t, c.Container()) - - for _, op := range []func() bool{ - c.IsForPut, - c.IsForDelete, - c.IsForSetEACL, - } { - require.False(t, op()) - } - - // convert to v2 message - cV2 := c.ToV2() - - require.Equal(t, v2session.ContainerVerbUnknown, cV2.Verb()) - require.True(t, cV2.Wildcard()) - require.Nil(t, cV2.ContainerID()) - }) -} - -func TestContainerContextEncoding(t *testing.T) { - c := sessiontest.ContainerContext() - - t.Run("binary", func(t *testing.T) { - data, err := c.Marshal() - require.NoError(t, err) - - c2 := session.NewContainerContext() - require.NoError(t, c2.Unmarshal(data)) - - require.Equal(t, c, c2) - }) - - t.Run("json", func(t *testing.T) { - data, err := c.MarshalJSON() - require.NoError(t, err) - - c2 := session.NewContainerContext() - require.NoError(t, c2.UnmarshalJSON(data)) - - require.Equal(t, c, c2) - }) -} diff --git a/pkg/session/session.go b/pkg/session/session.go deleted file mode 100644 index 6235636..0000000 --- a/pkg/session/session.go +++ /dev/null @@ -1,282 +0,0 @@ -package session - -import ( - "crypto/ecdsa" - - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/util/signature" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/nspcc-dev/neofs-api-go/v2/session" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" -) - -// Token represents NeoFS API v2-compatible -// session token. -type Token session.SessionToken - -// NewTokenFromV2 wraps session.SessionToken message structure -// into Token. -// -// Nil session.SessionToken converts to nil. -func NewTokenFromV2(tV2 *session.SessionToken) *Token { - return (*Token)(tV2) -} - -// NewToken creates and returns blank Token. -// -// Defaults: -// - body: nil; -// - id: nil; -// - ownerId: nil; -// - sessionKey: nil; -// - exp: 0; -// - iat: 0; -// - nbf: 0; -func NewToken() *Token { - return NewTokenFromV2(new(session.SessionToken)) -} - -// ToV2 converts Token to session.SessionToken message structure. -// -// Nil Token converts to nil. -func (t *Token) ToV2() *session.SessionToken { - return (*session.SessionToken)(t) -} - -func (t *Token) setBodyField(setter func(*session.SessionTokenBody)) { - token := (*session.SessionToken)(t) - body := token.GetBody() - - if body == nil { - body = new(session.SessionTokenBody) - token.SetBody(body) - } - - setter(body) -} - -// ID returns Token identifier. -func (t *Token) ID() []byte { - return (*session.SessionToken)(t). - GetBody(). - GetID() -} - -// SetID sets Token identifier. -func (t *Token) SetID(v []byte) { - t.setBodyField(func(body *session.SessionTokenBody) { - body.SetID(v) - }) -} - -// OwnerID returns Token's owner identifier. -func (t *Token) OwnerID() *owner.ID { - return owner.NewIDFromV2( - (*session.SessionToken)(t). - GetBody(). - GetOwnerID(), - ) -} - -// SetOwnerID sets Token's owner identifier. -func (t *Token) SetOwnerID(v *owner.ID) { - t.setBodyField(func(body *session.SessionTokenBody) { - body.SetOwnerID(v.ToV2()) - }) -} - -// SessionKey returns public key of the session -// in a binary format. -func (t *Token) SessionKey() []byte { - return (*session.SessionToken)(t). - GetBody(). - GetSessionKey() -} - -// SetSessionKey sets public key of the session -// in a binary format. -func (t *Token) SetSessionKey(v []byte) { - t.setBodyField(func(body *session.SessionTokenBody) { - body.SetSessionKey(v) - }) -} - -func (t *Token) setLifetimeField(f func(*session.TokenLifetime)) { - t.setBodyField(func(body *session.SessionTokenBody) { - lt := body.GetLifetime() - if lt == nil { - lt = new(session.TokenLifetime) - body.SetLifetime(lt) - } - - f(lt) - }) -} - -// Exp returns epoch number of the token expiration. -func (t *Token) Exp() uint64 { - return (*session.SessionToken)(t). - GetBody(). - GetLifetime(). - GetExp() -} - -// SetExp sets epoch number of the token expiration. -func (t *Token) SetExp(exp uint64) { - t.setLifetimeField(func(lt *session.TokenLifetime) { - lt.SetExp(exp) - }) -} - -// Nbf returns starting epoch number of the token. -func (t *Token) Nbf() uint64 { - return (*session.SessionToken)(t). - GetBody(). - GetLifetime(). - GetNbf() -} - -// SetNbf sets starting epoch number of the token. -func (t *Token) SetNbf(nbf uint64) { - t.setLifetimeField(func(lt *session.TokenLifetime) { - lt.SetNbf(nbf) - }) -} - -// Iat returns starting epoch number of the token. -func (t *Token) Iat() uint64 { - return (*session.SessionToken)(t). - GetBody(). - GetLifetime(). - GetIat() -} - -// SetIat sets the number of the epoch in which the token was issued. -func (t *Token) SetIat(iat uint64) { - t.setLifetimeField(func(lt *session.TokenLifetime) { - lt.SetIat(iat) - }) -} - -// Sign calculates and writes signature of the Token data. -// -// Returns signature calculation errors. -func (t *Token) Sign(key *ecdsa.PrivateKey) error { - tV2 := (*session.SessionToken)(t) - - signedData := v2signature.StableMarshalerWrapper{ - SM: tV2.GetBody(), - } - - return signature.SignDataWithHandler(key, signedData, func(key, sig []byte) { - tSig := tV2.GetSignature() - if tSig == nil { - tSig = new(refs.Signature) - } - - tSig.SetKey(key) - tSig.SetSign(sig) - - tV2.SetSignature(tSig) - }) -} - -// VerifySignature checks if token signature is -// presented and valid. -func (t *Token) VerifySignature() bool { - tV2 := (*session.SessionToken)(t) - - signedData := v2signature.StableMarshalerWrapper{ - SM: tV2.GetBody(), - } - - return signature.VerifyDataWithSource(signedData, func() (key, sig []byte) { - tSig := tV2.GetSignature() - return tSig.GetKey(), tSig.GetSign() - }) == nil -} - -// Signature returns Token signature. -func (t *Token) Signature() *pkg.Signature { - return pkg.NewSignatureFromV2( - (*session.SessionToken)(t). - GetSignature(), - ) -} - -// SetContext sets context of the Token. -// -// Supported contexts: -// - *ContainerContext. -// -// Resets context if it is not supported. -func (t *Token) SetContext(v interface{}) { - var cV2 session.SessionTokenContext - - switch c := v.(type) { - case *ContainerContext: - cV2 = c.ToV2() - } - - t.setBodyField(func(body *session.SessionTokenBody) { - body.SetContext(cV2) - }) -} - -// Context returns context of the Token. -// -// Supports same contexts as SetContext. -// -// Returns nil if context is not supported. -func (t *Token) Context() interface{} { - switch v := (*session.SessionToken)(t). - GetBody(). - GetContext(); c := v.(type) { - default: - return nil - case *session.ContainerSessionContext: - return ContainerContextFromV2(c) - } -} - -// GetContainerContext is a helper function that casts -// Token context to ContainerContext. -// -// Returns nil if context is not a ContainerContext. -func GetContainerContext(t *Token) *ContainerContext { - c, _ := t.Context().(*ContainerContext) - return c -} - -// Marshal marshals Token into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (t *Token) Marshal(bs ...[]byte) ([]byte, error) { - var buf []byte - if len(bs) > 0 { - buf = bs[0] - } - - return (*session.SessionToken)(t). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Token. -func (t *Token) Unmarshal(data []byte) error { - return (*session.SessionToken)(t). - Unmarshal(data) -} - -// MarshalJSON encodes Token to protobuf JSON format. -func (t *Token) MarshalJSON() ([]byte, error) { - return (*session.SessionToken)(t). - MarshalJSON() -} - -// UnmarshalJSON decodes Token from protobuf JSON format. -func (t *Token) UnmarshalJSON(data []byte) error { - return (*session.SessionToken)(t). - UnmarshalJSON(data) -} diff --git a/pkg/session/session_test.go b/pkg/session/session_test.go deleted file mode 100644 index 3835f38..0000000 --- a/pkg/session/session_test.go +++ /dev/null @@ -1,202 +0,0 @@ -package session_test - -import ( - "testing" - - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test" - sessionv2 "github.com/nspcc-dev/neofs-api-go/v2/session" - "github.com/stretchr/testify/require" -) - -func TestSessionToken_SetID(t *testing.T) { - token := session.NewToken() - - id := []byte{1, 2, 3} - token.SetID(id) - - require.Equal(t, id, token.ID()) -} - -func TestSessionToken_SetOwnerID(t *testing.T) { - token := session.NewToken() - - ownerID := ownertest.Generate() - - token.SetOwnerID(ownerID) - - require.Equal(t, ownerID, token.OwnerID()) -} - -func TestSessionToken_SetSessionKey(t *testing.T) { - token := session.NewToken() - - key := []byte{1, 2, 3} - token.SetSessionKey(key) - - require.Equal(t, key, token.SessionKey()) -} - -func TestSessionTokenEncoding(t *testing.T) { - tok := sessiontest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := tok.Marshal() - require.NoError(t, err) - - tok2 := session.NewToken() - require.NoError(t, tok2.Unmarshal(data)) - - require.Equal(t, tok, tok2) - }) - - t.Run("json", func(t *testing.T) { - data, err := tok.MarshalJSON() - require.NoError(t, err) - - tok2 := session.NewToken() - require.NoError(t, tok2.UnmarshalJSON(data)) - - require.Equal(t, tok, tok2) - }) -} - -func TestToken_VerifySignature(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var tok *session.Token - - require.False(t, tok.VerifySignature()) - }) - - t.Run("unsigned", func(t *testing.T) { - tok := sessiontest.Generate() - - require.False(t, tok.VerifySignature()) - }) - - t.Run("signed", func(t *testing.T) { - tok := sessiontest.GenerateSigned() - - require.True(t, tok.VerifySignature()) - }) -} - -var unsupportedContexts = []interface{}{ - 123, - true, - session.NewToken(), -} - -var nonContainerContexts = unsupportedContexts - -func TestToken_Context(t *testing.T) { - tok := session.NewToken() - - for _, item := range []struct { - ctx interface{} - v2assert func(interface{}) - }{ - { - ctx: sessiontest.ContainerContext(), - v2assert: func(c interface{}) { - require.Equal(t, c.(*session.ContainerContext).ToV2(), tok.ToV2().GetBody().GetContext()) - }, - }, - } { - tok.SetContext(item.ctx) - - require.Equal(t, item.ctx, tok.Context()) - - item.v2assert(item.ctx) - } - - for _, c := range unsupportedContexts { - tok.SetContext(c) - - require.Nil(t, tok.Context()) - } -} - -func TestGetContainerContext(t *testing.T) { - tok := session.NewToken() - - c := sessiontest.ContainerContext() - - tok.SetContext(c) - - require.Equal(t, c, session.GetContainerContext(tok)) - - for _, c := range nonContainerContexts { - tok.SetContext(c) - - require.Nil(t, session.GetContainerContext(tok)) - } -} - -func TestToken_Exp(t *testing.T) { - tok := session.NewToken() - - const exp = 11 - - tok.SetExp(exp) - - require.EqualValues(t, exp, tok.Exp()) -} - -func TestToken_Nbf(t *testing.T) { - tok := session.NewToken() - - const nbf = 22 - - tok.SetNbf(nbf) - - require.EqualValues(t, nbf, tok.Nbf()) -} - -func TestToken_Iat(t *testing.T) { - tok := session.NewToken() - - const iat = 33 - - tok.SetIat(iat) - - require.EqualValues(t, iat, tok.Iat()) -} - -func TestNewTokenFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *sessionv2.SessionToken - - require.Nil(t, session.NewTokenFromV2(x)) - }) -} - -func TestToken_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *session.Token - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewToken(t *testing.T) { - t.Run("default values", func(t *testing.T) { - token := session.NewToken() - - // check initial values - require.Nil(t, token.Signature()) - require.Nil(t, token.OwnerID()) - require.Nil(t, token.SessionKey()) - require.Nil(t, token.ID()) - require.Zero(t, token.Exp()) - require.Zero(t, token.Iat()) - require.Zero(t, token.Nbf()) - - // convert to v2 message - tokenV2 := token.ToV2() - - require.Nil(t, tokenV2.GetSignature()) - require.Nil(t, tokenV2.GetBody()) - }) -} diff --git a/pkg/session/test/container.go b/pkg/session/test/container.go deleted file mode 100644 index 070bd1b..0000000 --- a/pkg/session/test/container.go +++ /dev/null @@ -1,26 +0,0 @@ -package sessiontest - -import ( - "math/rand" - - cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test" - "github.com/nspcc-dev/neofs-api-go/pkg/session" -) - -// ContainerContext returns session.ContainerContext -// which applies to random operation on a random container. -func ContainerContext() *session.ContainerContext { - c := session.NewContainerContext() - - setters := []func(){ - c.ForPut, - c.ForDelete, - c.ForSetEACL, - } - - setters[rand.Uint32()%uint32(len(setters))]() - - c.ApplyTo(cidtest.Generate()) - - return c -} diff --git a/pkg/session/test/token.go b/pkg/session/test/token.go deleted file mode 100644 index 82c405b..0000000 --- a/pkg/session/test/token.go +++ /dev/null @@ -1,54 +0,0 @@ -package sessiontest - -import ( - "math/rand" - - "github.com/google/uuid" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/session" - crypto "github.com/nspcc-dev/neofs-crypto" - "github.com/nspcc-dev/neofs-crypto/test" -) - -// Generate returns random session.Token. -// -// Resulting token is unsigned. -func Generate() *session.Token { - tok := session.NewToken() - - uid, err := uuid.New().MarshalBinary() - if err != nil { - panic(err) - } - - w := new(owner.NEO3Wallet) - rand.Read(w.Bytes()) - - ownerID := owner.NewID() - ownerID.SetNeo3Wallet(w) - - keyBin := crypto.MarshalPublicKey(&test.DecodeKey(0).PublicKey) - - tok.SetID(uid) - tok.SetOwnerID(ownerID) - tok.SetSessionKey(keyBin) - tok.SetExp(11) - tok.SetNbf(22) - tok.SetIat(33) - - return tok -} - -// GenerateSigned returns signed random session.Token. -// -// Panics if token could not be signed (actually unexpected). -func GenerateSigned() *session.Token { - tok := Generate() - - err := tok.Sign(test.DecodeKey(0)) - if err != nil { - panic(err) - } - - return tok -} diff --git a/pkg/signature.go b/pkg/signature.go deleted file mode 100644 index 0976946..0000000 --- a/pkg/signature.go +++ /dev/null @@ -1,85 +0,0 @@ -package pkg - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// Signature represents v2-compatible signature. -type Signature refs.Signature - -// NewSignatureFromV2 wraps v2 Signature message to Signature. -// -// Nil refs.Signature converts to nil. -func NewSignatureFromV2(sV2 *refs.Signature) *Signature { - return (*Signature)(sV2) -} - -// NewSignature creates and initializes blank Signature. -// -// Works similar as NewSignatureFromV2(new(Signature)). -// -// Defaults: -// - key: nil; -// - signature: nil. -func NewSignature() *Signature { - return NewSignatureFromV2(new(refs.Signature)) -} - -// Key sets binary public key. -func (s *Signature) Key() []byte { - return (*refs.Signature)(s).GetKey() -} - -// SetKey returns binary public key. -func (s *Signature) SetKey(v []byte) { - (*refs.Signature)(s).SetKey(v) -} - -// Sign return signature value. -func (s *Signature) Sign() []byte { - return (*refs.Signature)(s).GetSign() -} - -// SetSign sets signature value. -func (s *Signature) SetSign(v []byte) { - (*refs.Signature)(s).SetSign(v) -} - -// ToV2 converts Signature to v2 Signature message. -// -// Nil Signature converts to nil. -func (s *Signature) ToV2() *refs.Signature { - return (*refs.Signature)(s) -} - -// Marshal marshals Signature into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (s *Signature) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.Signature)(s). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Signature. -func (s *Signature) Unmarshal(data []byte) error { - return (*refs.Signature)(s). - Unmarshal(data) -} - -// MarshalJSON encodes Signature to protobuf JSON format. -func (s *Signature) MarshalJSON() ([]byte, error) { - return (*refs.Signature)(s). - MarshalJSON() -} - -// UnmarshalJSON decodes Signature from protobuf JSON format. -func (s *Signature) UnmarshalJSON(data []byte) error { - return (*refs.Signature)(s). - UnmarshalJSON(data) -} diff --git a/pkg/signature_test.go b/pkg/signature_test.go deleted file mode 100644 index 45a5f14..0000000 --- a/pkg/signature_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package pkg - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func TestSignatureEncoding(t *testing.T) { - s := NewSignature() - s.SetKey([]byte("key")) - s.SetSign([]byte("sign")) - - t.Run("binary", func(t *testing.T) { - data, err := s.Marshal() - require.NoError(t, err) - - s2 := NewSignature() - 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 := NewSignature() - require.NoError(t, s2.UnmarshalJSON(data)) - - require.Equal(t, s, s2) - }) -} - -func TestNewSignatureFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.Signature - - require.Nil(t, NewSignatureFromV2(x)) - }) -} - -func TestSignature_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Signature - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewSignature(t *testing.T) { - t.Run("default values", func(t *testing.T) { - sg := NewSignature() - - // check initial values - require.Nil(t, sg.Key()) - require.Nil(t, sg.Sign()) - - // convert to v2 message - sgV2 := sg.ToV2() - - require.Nil(t, sgV2.GetKey()) - require.Nil(t, sgV2.GetSign()) - }) -} diff --git a/pkg/storagegroup/storagegroup.go b/pkg/storagegroup/storagegroup.go deleted file mode 100644 index 1a73a5a..0000000 --- a/pkg/storagegroup/storagegroup.go +++ /dev/null @@ -1,157 +0,0 @@ -package storagegroup - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg" - "github.com/nspcc-dev/neofs-api-go/pkg/object" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/nspcc-dev/neofs-api-go/v2/storagegroup" -) - -// StorageGroup represents v2-compatible storage group. -type StorageGroup storagegroup.StorageGroup - -// NewFromV2 wraps v2 StorageGroup message to StorageGroup. -// -// Nil storagegroup.StorageGroup converts to nil. -func NewFromV2(aV2 *storagegroup.StorageGroup) *StorageGroup { - return (*StorageGroup)(aV2) -} - -// New creates and initializes blank StorageGroup. -// -// Defaults: -// - size: 0; -// - exp: 0; -// - members: nil; -// - hash: nil. -func New() *StorageGroup { - return NewFromV2(new(storagegroup.StorageGroup)) -} - -// ValidationDataSize returns total size of the payloads -// of objects in the storage group -func (sg *StorageGroup) ValidationDataSize() uint64 { - return (*storagegroup.StorageGroup)(sg). - GetValidationDataSize() -} - -// SetValidationDataSize sets total size of the payloads -// of objects in the storage group. -func (sg *StorageGroup) SetValidationDataSize(epoch uint64) { - (*storagegroup.StorageGroup)(sg). - SetValidationDataSize(epoch) -} - -// ValidationDataHash returns homomorphic hash from the -// concatenation of the payloads of the storage group members. -func (sg *StorageGroup) ValidationDataHash() *pkg.Checksum { - return pkg.NewChecksumFromV2( - (*storagegroup.StorageGroup)(sg). - GetValidationHash(), - ) -} - -// SetValidationDataHash sets homomorphic hash from the -// concatenation of the payloads of the storage group members. -func (sg *StorageGroup) SetValidationDataHash(hash *pkg.Checksum) { - (*storagegroup.StorageGroup)(sg). - SetValidationHash(hash.ToV2()) -} - -// ExpirationEpoch returns last NeoFS epoch number -// of the storage group lifetime. -func (sg *StorageGroup) ExpirationEpoch() uint64 { - return (*storagegroup.StorageGroup)(sg). - GetExpirationEpoch() -} - -// SetExpirationEpoch sets last NeoFS epoch number -// of the storage group lifetime. -func (sg *StorageGroup) SetExpirationEpoch(epoch uint64) { - (*storagegroup.StorageGroup)(sg). - SetExpirationEpoch(epoch) -} - -// Members returns strictly ordered list of -// storage group member objects. -func (sg *StorageGroup) Members() []*object.ID { - mV2 := (*storagegroup.StorageGroup)(sg). - GetMembers() - - if mV2 == nil { - return nil - } - - m := make([]*object.ID, len(mV2)) - - for i := range mV2 { - m[i] = object.NewIDFromV2(mV2[i]) - } - - return m -} - -// SetMembers sets strictly ordered list of -// storage group member objects. -func (sg *StorageGroup) SetMembers(members []*object.ID) { - mV2 := (*storagegroup.StorageGroup)(sg). - GetMembers() - - if members == nil { - mV2 = nil - } else { - ln := len(members) - - if cap(mV2) >= ln { - mV2 = mV2[:0] - } else { - mV2 = make([]*refs.ObjectID, 0, ln) - } - - for i := 0; i < ln; i++ { - mV2 = append(mV2, members[i].ToV2()) - } - } - - (*storagegroup.StorageGroup)(sg). - SetMembers(mV2) -} - -// ToV2 converts StorageGroup to v2 StorageGroup message. -// -// Nil StorageGroup converts to nil. -func (sg *StorageGroup) ToV2() *storagegroup.StorageGroup { - return (*storagegroup.StorageGroup)(sg) -} - -// Marshal marshals StorageGroup into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (sg *StorageGroup) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*storagegroup.StorageGroup)(sg). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of StorageGroup. -func (sg *StorageGroup) Unmarshal(data []byte) error { - return (*storagegroup.StorageGroup)(sg). - Unmarshal(data) -} - -// MarshalJSON encodes StorageGroup to protobuf JSON format. -func (sg *StorageGroup) MarshalJSON() ([]byte, error) { - return (*storagegroup.StorageGroup)(sg). - MarshalJSON() -} - -// UnmarshalJSON decodes StorageGroup from protobuf JSON format. -func (sg *StorageGroup) UnmarshalJSON(data []byte) error { - return (*storagegroup.StorageGroup)(sg). - UnmarshalJSON(data) -} diff --git a/pkg/storagegroup/storagegroup_test.go b/pkg/storagegroup/storagegroup_test.go deleted file mode 100644 index ee6c6a6..0000000 --- a/pkg/storagegroup/storagegroup_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package storagegroup_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/object" - objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test" - "github.com/nspcc-dev/neofs-api-go/pkg/storagegroup" - storagegrouptest "github.com/nspcc-dev/neofs-api-go/pkg/storagegroup/test" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" - storagegroupV2 "github.com/nspcc-dev/neofs-api-go/v2/storagegroup" - "github.com/stretchr/testify/require" -) - -func TestStorageGroup(t *testing.T) { - sg := storagegroup.New() - - sz := uint64(13) - sg.SetValidationDataSize(sz) - require.Equal(t, sz, sg.ValidationDataSize()) - - cs := refstest.Checksum() - sg.SetValidationDataHash(cs) - require.Equal(t, cs, sg.ValidationDataHash()) - - exp := uint64(33) - sg.SetExpirationEpoch(exp) - require.Equal(t, exp, sg.ExpirationEpoch()) - - members := []*object.ID{objecttest.ID(), objecttest.ID()} - sg.SetMembers(members) - require.Equal(t, members, sg.Members()) -} - -func TestStorageGroupEncoding(t *testing.T) { - sg := storagegrouptest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := sg.Marshal() - require.NoError(t, err) - - sg2 := storagegroup.New() - require.NoError(t, sg2.Unmarshal(data)) - - require.Equal(t, sg, sg2) - }) - - t.Run("json", func(t *testing.T) { - data, err := sg.MarshalJSON() - require.NoError(t, err) - - sg2 := storagegroup.New() - require.NoError(t, sg2.UnmarshalJSON(data)) - - require.Equal(t, sg, sg2) - }) -} - -func TestNewFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *storagegroupV2.StorageGroup - - require.Nil(t, storagegroup.NewFromV2(x)) - }) -} - -func TestStorageGroup_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *storagegroup.StorageGroup - - require.Nil(t, x.ToV2()) - }) -} - -func TestNew(t *testing.T) { - t.Run("default values", func(t *testing.T) { - sg := storagegroup.New() - - // check initial values - require.Nil(t, sg.Members()) - require.Nil(t, sg.ValidationDataHash()) - require.Zero(t, sg.ExpirationEpoch()) - require.Zero(t, sg.ValidationDataSize()) - - // convert to v2 message - sgV2 := sg.ToV2() - - require.Nil(t, sgV2.GetMembers()) - require.Nil(t, sgV2.GetValidationHash()) - require.Zero(t, sgV2.GetExpirationEpoch()) - require.Zero(t, sgV2.GetValidationDataSize()) - }) -} diff --git a/pkg/storagegroup/test/generate.go b/pkg/storagegroup/test/generate.go deleted file mode 100644 index 4efe1b2..0000000 --- a/pkg/storagegroup/test/generate.go +++ /dev/null @@ -1,20 +0,0 @@ -package storagegrouptest - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/object" - objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test" - "github.com/nspcc-dev/neofs-api-go/pkg/storagegroup" - refstest "github.com/nspcc-dev/neofs-api-go/pkg/test" -) - -// Generate returns random storagegroup.StorageGroup. -func Generate() *storagegroup.StorageGroup { - x := storagegroup.New() - - x.SetExpirationEpoch(66) - x.SetValidationDataSize(322) - x.SetValidationDataHash(refstest.Checksum()) - x.SetMembers([]*object.ID{objecttest.ID(), objecttest.ID()}) - - return x -} diff --git a/pkg/test/generate.go b/pkg/test/generate.go deleted file mode 100644 index 5bd0933..0000000 --- a/pkg/test/generate.go +++ /dev/null @@ -1,51 +0,0 @@ -package refstest - -import ( - "crypto/sha256" - "math/rand" - - "github.com/nspcc-dev/neofs-api-go/pkg" -) - -// Checksum returns random pkg.Checksum. -func Checksum() *pkg.Checksum { - var cs [sha256.Size]byte - - rand.Read(cs[:]) - - x := pkg.NewChecksum() - - x.SetSHA256(cs) - - return x -} - -// Signature returns random pkg.Signature. -func Signature() *pkg.Signature { - x := pkg.NewSignature() - - x.SetKey([]byte("key")) - x.SetSign([]byte("sign")) - - return x -} - -// Version returns random pkg.Version. -func Version() *pkg.Version { - x := pkg.NewVersion() - - x.SetMajor(2) - x.SetMinor(1) - - return x -} - -// XHeader returns random pkg.XHeader. -func XHeader() *pkg.XHeader { - x := pkg.NewXHeader() - - x.SetKey("key") - x.SetValue("value") - - return x -} diff --git a/pkg/token/bearer.go b/pkg/token/bearer.go deleted file mode 100644 index 621052c..0000000 --- a/pkg/token/bearer.go +++ /dev/null @@ -1,188 +0,0 @@ -package token - -import ( - "crypto/ecdsa" - "errors" - - "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/util/signature" - "github.com/nspcc-dev/neofs-api-go/v2/acl" - "github.com/nspcc-dev/neofs-api-go/v2/refs" - v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" - crypto "github.com/nspcc-dev/neofs-crypto" -) - -var ( - errNilBearerToken = errors.New("bearer token is not set") - errNilBearerTokenBody = errors.New("bearer token body is not set") - errNilBearerTokenEACL = errors.New("bearer token EACL table is not set") -) - -type BearerToken struct { - token acl.BearerToken -} - -// ToV2 converts BearerToken to v2 BearerToken message. -// -// Nil BearerToken converts to nil. -func (b *BearerToken) ToV2() *acl.BearerToken { - if b == nil { - return nil - } - - return &b.token -} - -func (b *BearerToken) SetLifetime(exp, nbf, iat uint64) { - body := b.token.GetBody() - if body == nil { - body = new(acl.BearerTokenBody) - } - - lt := new(acl.TokenLifetime) - lt.SetExp(exp) - lt.SetNbf(nbf) - lt.SetIat(iat) - - body.SetLifetime(lt) - b.token.SetBody(body) -} - -func (b *BearerToken) SetEACLTable(table *eacl.Table) { - body := b.token.GetBody() - if body == nil { - body = new(acl.BearerTokenBody) - } - - body.SetEACL(table.ToV2()) - b.token.SetBody(body) -} - -func (b *BearerToken) SetOwner(id *owner.ID) { - body := b.token.GetBody() - if body == nil { - body = new(acl.BearerTokenBody) - } - - body.SetOwnerID(id.ToV2()) - b.token.SetBody(body) -} - -func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error { - err := sanityCheck(b) - if err != nil { - return err - } - - signWrapper := v2signature.StableMarshalerWrapper{SM: b.token.GetBody()} - - return signature.SignDataWithHandler(key, signWrapper, func(key []byte, sig []byte) { - bearerSignature := new(refs.Signature) - bearerSignature.SetKey(key) - bearerSignature.SetSign(sig) - b.token.SetSignature(bearerSignature) - }) -} - -// Issuer returns owner.ID associated with the key that signed bearer token. -// To pass node validation it should be owner of requested container. Returns -// nil if token is not signed. -func (b *BearerToken) Issuer() *owner.ID { - pubKey := crypto.UnmarshalPublicKey(b.token.GetSignature().GetKey()) - - wallet, err := owner.NEO3WalletFromPublicKey(pubKey) - if err != nil { - return nil - } - - return owner.NewIDFromNeo3Wallet(wallet) -} - -// NewBearerToken creates and initializes blank BearerToken. -// -// Defaults: -// - signature: nil; -// - eacl: nil; -// - ownerID: nil; -// - exp: 0; -// - nbf: 0; -// - iat: 0. -func NewBearerToken() *BearerToken { - b := new(BearerToken) - b.token = acl.BearerToken{} - b.token.SetBody(new(acl.BearerTokenBody)) - - return b -} - -// ToV2 converts BearerToken to v2 BearerToken message. -func NewBearerTokenFromV2(v2 *acl.BearerToken) *BearerToken { - if v2 == nil { - v2 = new(acl.BearerToken) - } - - return &BearerToken{ - token: *v2, - } -} - -// sanityCheck if bearer token is ready to be issued. -func sanityCheck(b *BearerToken) error { - switch { - case b == nil: - return errNilBearerToken - case b.token.GetBody() == nil: - return errNilBearerTokenBody - case b.token.GetBody().GetEACL() == nil: - return errNilBearerTokenEACL - } - - // consider checking EACL sanity there, lifetime correctness, etc. - - return nil -} - -// Marshal marshals BearerToken into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (b *BearerToken) Marshal(bs ...[]byte) ([]byte, error) { - var buf []byte - if len(bs) > 0 { - buf = bs[0] - } - - return b.ToV2(). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of BearerToken. -func (b *BearerToken) Unmarshal(data []byte) error { - fV2 := new(acl.BearerToken) - if err := fV2.Unmarshal(data); err != nil { - return err - } - - *b = *NewBearerTokenFromV2(fV2) - - return nil -} - -// MarshalJSON encodes BearerToken to protobuf JSON format. -func (b *BearerToken) MarshalJSON() ([]byte, error) { - return b.ToV2(). - MarshalJSON() -} - -// UnmarshalJSON decodes BearerToken from protobuf JSON format. -func (b *BearerToken) UnmarshalJSON(data []byte) error { - fV2 := new(acl.BearerToken) - if err := fV2.UnmarshalJSON(data); err != nil { - return err - } - - *b = *NewBearerTokenFromV2(fV2) - - return nil -} diff --git a/pkg/token/bearer_test.go b/pkg/token/bearer_test.go deleted file mode 100644 index 191398b..0000000 --- a/pkg/token/bearer_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package token_test - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/token" - tokentest "github.com/nspcc-dev/neofs-api-go/pkg/token/test" - "github.com/nspcc-dev/neofs-crypto/test" - "github.com/stretchr/testify/require" -) - -func TestBearerToken_Issuer(t *testing.T) { - bearerToken := token.NewBearerToken() - - t.Run("non signed token", func(t *testing.T) { - require.Nil(t, bearerToken.Issuer()) - }) - - t.Run("signed token", func(t *testing.T) { - key := test.DecodeKey(1) - - wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey) - require.NoError(t, err) - - ownerID := owner.NewIDFromNeo3Wallet(wallet) - - bearerToken.SetEACLTable(eacl.NewTable()) - require.NoError(t, bearerToken.SignToken(key)) - require.True(t, ownerID.Equal(bearerToken.Issuer())) - }) -} - -func TestFilterEncoding(t *testing.T) { - f := tokentest.Generate() - - t.Run("binary", func(t *testing.T) { - data, err := f.Marshal() - require.NoError(t, err) - - f2 := token.NewBearerToken() - 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) - - d2 := token.NewBearerToken() - require.NoError(t, d2.UnmarshalJSON(data)) - - require.Equal(t, f, d2) - }) -} - -func TestBearerToken_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *token.BearerToken - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewBearerToken(t *testing.T) { - t.Run("default values", func(t *testing.T) { - tkn := token.NewBearerToken() - - // convert to v2 message - tknV2 := tkn.ToV2() - - require.NotNil(t, tknV2.GetBody()) - require.Zero(t, tknV2.GetBody().GetLifetime().GetExp()) - require.Zero(t, tknV2.GetBody().GetLifetime().GetNbf()) - require.Zero(t, tknV2.GetBody().GetLifetime().GetIat()) - require.Nil(t, tknV2.GetBody().GetEACL()) - require.Nil(t, tknV2.GetBody().GetOwnerID()) - require.Nil(t, tknV2.GetSignature()) - }) -} diff --git a/pkg/token/session.go b/pkg/token/session.go deleted file mode 100644 index 5c8e8a7..0000000 --- a/pkg/token/session.go +++ /dev/null @@ -1,22 +0,0 @@ -package token - -import ( - "github.com/nspcc-dev/neofs-api-go/pkg/session" -) - -// SessionToken represents NeoFS API v2-compatible -// session token. -// -// Deprecated: use session.Token instead -type SessionToken = session.Token - -// NewSessionTokenFromV2 wraps session.SessionToken message structure -// into Token. -// -// Deprecated: use session.NewTokenFromV2 instead. -var NewSessionTokenFromV2 = session.NewTokenFromV2 - -// NewSessionToken creates and returns blank session token. -// -// Deprecated: use session.NewToken instead. -var NewSessionToken = session.NewToken diff --git a/pkg/token/test/generate.go b/pkg/token/test/generate.go deleted file mode 100644 index f7ae59d..0000000 --- a/pkg/token/test/generate.go +++ /dev/null @@ -1,35 +0,0 @@ -package tokentest - -import ( - eacltest "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl/test" - ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test" - "github.com/nspcc-dev/neofs-api-go/pkg/token" - "github.com/nspcc-dev/neofs-crypto/test" -) - -// Generate returns random token.BearerToken. -// -// Resulting token is unsigned. -func Generate() *token.BearerToken { - x := token.NewBearerToken() - - x.SetLifetime(3, 2, 1) - x.SetOwner(ownertest.Generate()) - x.SetEACLTable(eacltest.Table()) - - return x -} - -// GenerateSigned returns signed random token.BearerToken. -// -// Panics if token could not be signed (actually unexpected). -func GenerateSigned() *token.BearerToken { - tok := Generate() - - err := tok.SignToken(test.DecodeKey(0)) - if err != nil { - panic(err) - } - - return tok -} diff --git a/pkg/version.go b/pkg/version.go deleted file mode 100644 index c720af5..0000000 --- a/pkg/version.go +++ /dev/null @@ -1,107 +0,0 @@ -package pkg - -import ( - "fmt" - - "github.com/nspcc-dev/neofs-api-go/v2/refs" -) - -// Version represents v2-compatible version. -type Version refs.Version - -const sdkMjr, sdkMnr = 2, 10 - -// NewVersionFromV2 wraps v2 Version message to Version. -// -// Nil refs.Version converts to nil. -func NewVersionFromV2(v *refs.Version) *Version { - return (*Version)(v) -} - -// NewVersion creates and initializes blank Version. -// -// Works similar as NewVersionFromV2(new(Version)). -// -// Defaults: -// - major: 0; -// - minor: 0. -func NewVersion() *Version { - return NewVersionFromV2(new(refs.Version)) -} - -// SDKVersion returns Version instance that -// initialized to current SDK revision number. -func SDKVersion() *Version { - v := NewVersion() - v.SetMajor(sdkMjr) - v.SetMinor(sdkMnr) - - return v -} - -// Major returns major number of the revision. -func (v *Version) Major() uint32 { - return (*refs.Version)(v). - GetMajor() -} - -// SetMajor sets major number of the revision. -func (v *Version) SetMajor(val uint32) { - (*refs.Version)(v). - SetMajor(val) -} - -// Minor returns minor number of the revision. -func (v *Version) Minor() uint32 { - return (*refs.Version)(v). - GetMinor() -} - -// SetMinor sets minor number of the revision. -func (v *Version) SetMinor(val uint32) { - (*refs.Version)(v). - SetMinor(val) -} - -// ToV2 converts Version to v2 Version message. -// -// Nil Version converts to nil. -func (v *Version) ToV2() *refs.Version { - return (*refs.Version)(v) -} - -func (v *Version) String() string { - return fmt.Sprintf("v%d.%d", v.Major(), v.Minor()) -} - -// Marshal marshals Version into a protobuf binary form. -// -// Buffer is allocated when the argument is empty. -// Otherwise, the first buffer is used. -func (v *Version) Marshal(b ...[]byte) ([]byte, error) { - var buf []byte - if len(b) > 0 { - buf = b[0] - } - - return (*refs.Version)(v). - StableMarshal(buf) -} - -// Unmarshal unmarshals protobuf binary representation of Version. -func (v *Version) Unmarshal(data []byte) error { - return (*refs.Version)(v). - Unmarshal(data) -} - -// MarshalJSON encodes Version to protobuf JSON format. -func (v *Version) MarshalJSON() ([]byte, error) { - return (*refs.Version)(v). - MarshalJSON() -} - -// UnmarshalJSON decodes Version from protobuf JSON format. -func (v *Version) UnmarshalJSON(data []byte) error { - return (*refs.Version)(v). - UnmarshalJSON(data) -} diff --git a/pkg/version_test.go b/pkg/version_test.go deleted file mode 100644 index 622e4b7..0000000 --- a/pkg/version_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package pkg - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/refs" - "github.com/stretchr/testify/require" -) - -func TestNewVersion(t *testing.T) { - t.Run("default values", func(t *testing.T) { - v := NewVersion() - - // check initial values - require.Zero(t, v.Major()) - require.Zero(t, v.Minor()) - - // convert to v2 message - vV2 := v.ToV2() - - require.Empty(t, vV2.GetMajor()) - require.Empty(t, vV2.GetMinor()) - }) - - t.Run("setting values", func(t *testing.T) { - v := NewVersion() - - var mjr, mnr uint32 = 1, 2 - - v.SetMajor(mjr) - v.SetMinor(mnr) - - require.Equal(t, mjr, v.Major()) - require.Equal(t, mnr, v.Minor()) - - ver := v.ToV2() - - require.Equal(t, mjr, ver.GetMajor()) - require.Equal(t, mnr, ver.GetMinor()) - }) -} - -func TestSDKVersion(t *testing.T) { - v := SDKVersion() - - require.Equal(t, uint32(sdkMjr), v.Major()) - require.Equal(t, uint32(sdkMnr), v.Minor()) -} - -func TestVersionEncoding(t *testing.T) { - v := NewVersion() - v.SetMajor(1) - v.SetMinor(2) - - t.Run("binary", func(t *testing.T) { - data, err := v.Marshal() - require.NoError(t, err) - - v2 := NewVersion() - require.NoError(t, v2.Unmarshal(data)) - - require.Equal(t, v, v2) - }) - - t.Run("json", func(t *testing.T) { - data, err := v.MarshalJSON() - require.NoError(t, err) - - v2 := NewVersion() - require.NoError(t, v2.UnmarshalJSON(data)) - - require.Equal(t, v, v2) - }) -} - -func TestNewVersionFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *refs.Version - - require.Nil(t, NewVersionFromV2(x)) - }) -} - -func TestVersion_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *Version - - require.Nil(t, x.ToV2()) - }) -} diff --git a/pkg/xheader.go b/pkg/xheader.go deleted file mode 100644 index b36f1f0..0000000 --- a/pkg/xheader.go +++ /dev/null @@ -1,55 +0,0 @@ -package pkg - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/session" -) - -// XHeader represents v2-compatible XHeader. -type XHeader session.XHeader - -// NewXHeaderFromV2 wraps v2 XHeader message to XHeader. -// -// Nil session.XHeader converts to nil. -func NewXHeaderFromV2(v *session.XHeader) *XHeader { - return (*XHeader)(v) -} - -// NewXHeader creates, initializes and returns blank XHeader instance. -// -// Defaults: -// - key: ""; -// - value: "". -func NewXHeader() *XHeader { - return NewXHeaderFromV2(new(session.XHeader)) -} - -// ToV2 converts XHeader to v2 XHeader message. -// -// Nil XHeader converts to nil. -func (x *XHeader) ToV2() *session.XHeader { - return (*session.XHeader)(x) -} - -// Key returns key to X-Header. -func (x *XHeader) Key() string { - return (*session.XHeader)(x). - GetKey() -} - -// SetKey sets key to X-Header. -func (x *XHeader) SetKey(k string) { - (*session.XHeader)(x). - SetKey(k) -} - -// Value returns value of X-Header. -func (x *XHeader) Value() string { - return (*session.XHeader)(x). - GetValue() -} - -// SetValue sets value of X-Header. -func (x *XHeader) SetValue(k string) { - (*session.XHeader)(x). - SetValue(k) -} diff --git a/pkg/xheader_test.go b/pkg/xheader_test.go deleted file mode 100644 index 22cbe87..0000000 --- a/pkg/xheader_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package pkg - -import ( - "testing" - - "github.com/nspcc-dev/neofs-api-go/v2/session" - "github.com/stretchr/testify/require" -) - -func TestXHeader(t *testing.T) { - x := NewXHeader() - - key := "some key" - val := "some value" - - x.SetKey(key) - x.SetValue(val) - - require.Equal(t, key, x.Key()) - require.Equal(t, val, x.Value()) - - xV2 := x.ToV2() - - require.Equal(t, key, xV2.GetKey()) - require.Equal(t, val, xV2.GetValue()) -} - -func TestNewXHeaderFromV2(t *testing.T) { - t.Run("from nil", func(t *testing.T) { - var x *session.XHeader - - require.Nil(t, NewXHeaderFromV2(x)) - }) -} - -func TestXHeader_ToV2(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var x *XHeader - - require.Nil(t, x.ToV2()) - }) -} - -func TestNewXHeader(t *testing.T) { - t.Run("default values", func(t *testing.T) { - xh := NewXHeader() - - // check initial values - require.Empty(t, xh.Value()) - require.Empty(t, xh.Key()) - - // convert to v2 message - xhV2 := xh.ToV2() - - require.Empty(t, xhV2.GetValue()) - require.Empty(t, xhV2.GetKey()) - }) -} diff --git a/v2/refs/convert.go b/refs/convert.go similarity index 97% rename from v2/refs/convert.go rename to refs/convert.go index 3cd87d2..8b89b71 100644 --- a/v2/refs/convert.go +++ b/refs/convert.go @@ -1,9 +1,9 @@ package refs import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (o *OwnerID) ToGRPCMessage() grpc.Message { diff --git a/v2/refs/grpc/types.go b/refs/grpc/types.go similarity index 100% rename from v2/refs/grpc/types.go rename to refs/grpc/types.go diff --git a/v2/refs/grpc/types.pb.go b/refs/grpc/types.pb.go similarity index 100% rename from v2/refs/grpc/types.pb.go rename to refs/grpc/types.pb.go diff --git a/v2/refs/json.go b/refs/json.go similarity index 96% rename from v2/refs/json.go rename to refs/json.go index 4197e2f..5a48cdb 100644 --- a/v2/refs/json.go +++ b/refs/json.go @@ -1,8 +1,8 @@ package refs import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (a *Address) MarshalJSON() ([]byte, error) { diff --git a/v2/refs/marshal.go b/refs/marshal.go similarity index 98% rename from v2/refs/marshal.go rename to refs/marshal.go index 806d8e4..e8d2565 100644 --- a/v2/refs/marshal.go +++ b/refs/marshal.go @@ -1,9 +1,9 @@ package refs import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - "github.com/nspcc-dev/neofs-api-go/util/proto" refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/refs/message_test.go b/refs/message_test.go similarity index 85% rename from v2/refs/message_test.go rename to refs/message_test.go index 92eb6df..d5e591f 100644 --- a/v2/refs/message_test.go +++ b/refs/message_test.go @@ -3,9 +3,9 @@ package refs_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/refs/string.go b/refs/string.go similarity index 100% rename from v2/refs/string.go rename to refs/string.go diff --git a/v2/refs/test/generate.go b/refs/test/generate.go similarity index 100% rename from v2/refs/test/generate.go rename to refs/test/generate.go diff --git a/v2/refs/types.go b/refs/types.go similarity index 100% rename from v2/refs/types.go rename to refs/types.go diff --git a/v2/reputation/convert.go b/reputation/convert.go similarity index 99% rename from v2/reputation/convert.go rename to reputation/convert.go index 0c49508..67f3aaf 100644 --- a/v2/reputation/convert.go +++ b/reputation/convert.go @@ -1,11 +1,11 @@ package reputation import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) // ToGRPCMessage converts PeerID to gRPC-generated diff --git a/v2/reputation/grpc/service.go b/reputation/grpc/service.go similarity index 100% rename from v2/reputation/grpc/service.go rename to reputation/grpc/service.go diff --git a/v2/reputation/grpc/service.pb.go b/reputation/grpc/service.pb.go similarity index 100% rename from v2/reputation/grpc/service.pb.go rename to reputation/grpc/service.pb.go diff --git a/v2/reputation/grpc/service_grpc.pb.go b/reputation/grpc/service_grpc.pb.go similarity index 100% rename from v2/reputation/grpc/service_grpc.pb.go rename to reputation/grpc/service_grpc.pb.go diff --git a/v2/reputation/grpc/types.go b/reputation/grpc/types.go similarity index 100% rename from v2/reputation/grpc/types.go rename to reputation/grpc/types.go diff --git a/v2/reputation/grpc/types.pb.go b/reputation/grpc/types.pb.go similarity index 100% rename from v2/reputation/grpc/types.pb.go rename to reputation/grpc/types.pb.go diff --git a/v2/reputation/json.go b/reputation/json.go similarity index 94% rename from v2/reputation/json.go rename to reputation/json.go index 5ee1cc2..17f559f 100644 --- a/v2/reputation/json.go +++ b/reputation/json.go @@ -1,8 +1,8 @@ package reputation import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) func (x *PeerID) MarshalJSON() ([]byte, error) { diff --git a/v2/reputation/marshal.go b/reputation/marshal.go similarity index 98% rename from v2/reputation/marshal.go rename to reputation/marshal.go index 6c15062..1af68c9 100644 --- a/v2/reputation/marshal.go +++ b/reputation/marshal.go @@ -1,9 +1,9 @@ package reputation import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/reputation/message_test.go b/reputation/message_test.go similarity index 92% rename from v2/reputation/message_test.go rename to reputation/message_test.go index f09c636..0f948c9 100644 --- a/v2/reputation/message_test.go +++ b/reputation/message_test.go @@ -3,9 +3,9 @@ package reputation_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" reputationtest "github.com/nspcc-dev/neofs-api-go/v2/reputation/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" ) func TestMessageConvert(t *testing.T) { diff --git a/v2/reputation/test/generate.go b/reputation/test/generate.go similarity index 100% rename from v2/reputation/test/generate.go rename to reputation/test/generate.go diff --git a/v2/reputation/types.go b/reputation/types.go similarity index 100% rename from v2/reputation/types.go rename to reputation/types.go diff --git a/v2/rpc/accounting.go b/rpc/accounting.go similarity index 85% rename from v2/rpc/accounting.go rename to rpc/accounting.go index 0e031da..0c0bd7b 100644 --- a/v2/rpc/accounting.go +++ b/rpc/accounting.go @@ -1,9 +1,9 @@ package rpc import ( - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/rpc/common" "github.com/nspcc-dev/neofs-api-go/v2/accounting" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" ) const serviceAccounting = serviceNamePrefix + "accounting.AccountingService" diff --git a/rpc/client/call_options.go b/rpc/client/call_options.go index ef849f3..e443a89 100644 --- a/rpc/client/call_options.go +++ b/rpc/client/call_options.go @@ -3,7 +3,7 @@ package client import ( "context" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" ) // CallOption is a messaging session option within Protobuf RPC. diff --git a/rpc/client/client.go b/rpc/client/client.go index e51cdcf..16b3496 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -3,7 +3,7 @@ package client import ( "sync" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" ) // Client represents client for exchanging messages diff --git a/rpc/client/connect.go b/rpc/client/connect.go index 9df1ddf..e80e422 100644 --- a/rpc/client/connect.go +++ b/rpc/client/connect.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" grpcstd "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) diff --git a/rpc/client/flows.go b/rpc/client/flows.go index c106e0a..4f4a04a 100644 --- a/rpc/client/flows.go +++ b/rpc/client/flows.go @@ -5,8 +5,8 @@ import ( "io" "sync" - "github.com/nspcc-dev/neofs-api-go/rpc/common" - "github.com/nspcc-dev/neofs-api-go/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) // SendUnary initializes communication session by RPC info, performs unary RPC diff --git a/rpc/client/init.go b/rpc/client/init.go index aa0d420..27c6199 100644 --- a/rpc/client/init.go +++ b/rpc/client/init.go @@ -3,9 +3,9 @@ package client import ( "io" - "github.com/nspcc-dev/neofs-api-go/rpc/common" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) // MessageReader is an interface of the Message reader. diff --git a/v2/rpc/common.go b/rpc/common.go similarity index 100% rename from v2/rpc/common.go rename to rpc/common.go diff --git a/rpc/common/call_test.go b/rpc/common/call_test.go index e1414e3..aa4898f 100644 --- a/rpc/common/call_test.go +++ b/rpc/common/call_test.go @@ -3,7 +3,7 @@ package common_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" "github.com/stretchr/testify/require" ) diff --git a/v2/rpc/container.go b/rpc/container.go similarity index 96% rename from v2/rpc/container.go rename to rpc/container.go index 82dbe8a..219e919 100644 --- a/v2/rpc/container.go +++ b/rpc/container.go @@ -1,9 +1,9 @@ package rpc import ( - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/rpc/common" "github.com/nspcc-dev/neofs-api-go/v2/container" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" ) const serviceContainer = serviceNamePrefix + "container.ContainerService" diff --git a/rpc/grpc/init.go b/rpc/grpc/init.go index ec3bc5a..aeb4fb4 100644 --- a/rpc/grpc/init.go +++ b/rpc/grpc/init.go @@ -3,7 +3,7 @@ package grpc import ( "io" - "github.com/nspcc-dev/neofs-api-go/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" "google.golang.org/grpc" ) diff --git a/rpc/grpc/util.go b/rpc/grpc/util.go index 150d57d..c7c65e2 100644 --- a/rpc/grpc/util.go +++ b/rpc/grpc/util.go @@ -3,7 +3,7 @@ package grpc import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" ) const methodNameFmt = "/%s/%s" diff --git a/rpc/message/encoding.go b/rpc/message/encoding.go index 7d9f7e9..4a53b68 100644 --- a/rpc/message/encoding.go +++ b/rpc/message/encoding.go @@ -1,7 +1,7 @@ package message import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) diff --git a/rpc/message/message.go b/rpc/message/message.go index 5cc3702..576559d 100644 --- a/rpc/message/message.go +++ b/rpc/message/message.go @@ -3,7 +3,7 @@ package message import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" ) // Message represents raw Protobuf message diff --git a/rpc/message/test/message.go b/rpc/message/test/message.go index 1afa796..e3ce9cd 100644 --- a/rpc/message/test/message.go +++ b/rpc/message/test/message.go @@ -6,7 +6,7 @@ import ( "fmt" "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" "github.com/stretchr/testify/require" ) diff --git a/v2/rpc/netmap.go b/rpc/netmap.go similarity index 91% rename from v2/rpc/netmap.go rename to rpc/netmap.go index 6e68456..b28abef 100644 --- a/v2/rpc/netmap.go +++ b/rpc/netmap.go @@ -1,9 +1,9 @@ package rpc import ( - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/rpc/common" "github.com/nspcc-dev/neofs-api-go/v2/netmap" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" ) const serviceNetmap = serviceNamePrefix + "netmap.NetmapService" diff --git a/v2/rpc/object.go b/rpc/object.go similarity index 96% rename from v2/rpc/object.go rename to rpc/object.go index 7e64a61..58faa9f 100644 --- a/v2/rpc/object.go +++ b/rpc/object.go @@ -1,10 +1,10 @@ package rpc import ( - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/rpc/common" - "github.com/nspcc-dev/neofs-api-go/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/object" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" ) const serviceObject = serviceNamePrefix + "object.ObjectService" diff --git a/v2/rpc/reputation.go b/rpc/reputation.go similarity index 92% rename from v2/rpc/reputation.go rename to rpc/reputation.go index ad9d2d9..9332f10 100644 --- a/v2/rpc/reputation.go +++ b/rpc/reputation.go @@ -1,9 +1,9 @@ package rpc import ( - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/rpc/common" "github.com/nspcc-dev/neofs-api-go/v2/reputation" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" ) const serviceReputation = serviceNamePrefix + "reputation.ReputationService" diff --git a/v2/rpc/session.go b/rpc/session.go similarity index 83% rename from v2/rpc/session.go rename to rpc/session.go index 89b5f1c..cdd43c2 100644 --- a/v2/rpc/session.go +++ b/rpc/session.go @@ -1,8 +1,8 @@ package rpc import ( - "github.com/nspcc-dev/neofs-api-go/rpc/client" - "github.com/nspcc-dev/neofs-api-go/rpc/common" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" "github.com/nspcc-dev/neofs-api-go/v2/session" ) diff --git a/v2/session/convert.go b/session/convert.go similarity index 99% rename from v2/session/convert.go rename to session/convert.go index 8015832..df78c9e 100644 --- a/v2/session/convert.go +++ b/session/convert.go @@ -3,12 +3,12 @@ package session import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/acl" aclGRPC "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" "github.com/nspcc-dev/neofs-api-go/v2/status" statusGRPC "github.com/nspcc-dev/neofs-api-go/v2/status/grpc" diff --git a/v2/session/grpc/client.go b/session/grpc/client.go similarity index 100% rename from v2/session/grpc/client.go rename to session/grpc/client.go diff --git a/v2/session/grpc/service.go b/session/grpc/service.go similarity index 100% rename from v2/session/grpc/service.go rename to session/grpc/service.go diff --git a/v2/session/grpc/service.pb.go b/session/grpc/service.pb.go similarity index 100% rename from v2/session/grpc/service.pb.go rename to session/grpc/service.pb.go diff --git a/v2/session/grpc/service_grpc.pb.go b/session/grpc/service_grpc.pb.go similarity index 100% rename from v2/session/grpc/service_grpc.pb.go rename to session/grpc/service_grpc.pb.go diff --git a/v2/session/grpc/types.go b/session/grpc/types.go similarity index 100% rename from v2/session/grpc/types.go rename to session/grpc/types.go diff --git a/v2/session/grpc/types.pb.go b/session/grpc/types.pb.go similarity index 100% rename from v2/session/grpc/types.pb.go rename to session/grpc/types.pb.go diff --git a/v2/session/json.go b/session/json.go similarity index 98% rename from v2/session/json.go rename to session/json.go index be7b9ac..d8056ee 100644 --- a/v2/session/json.go +++ b/session/json.go @@ -1,7 +1,7 @@ package session import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" "google.golang.org/protobuf/encoding/protojson" ) diff --git a/v2/session/marshal.go b/session/marshal.go similarity index 99% rename from v2/session/marshal.go rename to session/marshal.go index 7ffe5e0..9513d4c 100644 --- a/v2/session/marshal.go +++ b/session/marshal.go @@ -1,9 +1,9 @@ package session import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - "github.com/nspcc-dev/neofs-api-go/util/proto" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" goproto "google.golang.org/protobuf/proto" ) diff --git a/v2/session/message_test.go b/session/message_test.go similarity index 92% rename from v2/session/message_test.go rename to session/message_test.go index 17c428e..d9294c9 100644 --- a/v2/session/message_test.go +++ b/session/message_test.go @@ -3,8 +3,8 @@ package session_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - rpctest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + rpctest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" sessiontest "github.com/nspcc-dev/neofs-api-go/v2/session/test" ) diff --git a/v2/session/string.go b/session/string.go similarity index 100% rename from v2/session/string.go rename to session/string.go diff --git a/v2/session/test/generate.go b/session/test/generate.go similarity index 100% rename from v2/session/test/generate.go rename to session/test/generate.go diff --git a/v2/session/types.go b/session/types.go similarity index 100% rename from v2/session/types.go rename to session/types.go diff --git a/v2/session/util.go b/session/util.go similarity index 100% rename from v2/session/util.go rename to session/util.go diff --git a/v2/session/xheaders.go b/session/xheaders.go similarity index 100% rename from v2/session/xheaders.go rename to session/xheaders.go diff --git a/v2/signature/sign.go b/signature/sign.go similarity index 99% rename from v2/signature/sign.go rename to signature/sign.go index 04abab6..7054416 100644 --- a/v2/signature/sign.go +++ b/signature/sign.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" - "github.com/nspcc-dev/neofs-api-go/util/signature" "github.com/nspcc-dev/neofs-api-go/v2/accounting" "github.com/nspcc-dev/neofs-api-go/v2/container" "github.com/nspcc-dev/neofs-api-go/v2/netmap" @@ -13,6 +12,7 @@ import ( "github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/reputation" "github.com/nspcc-dev/neofs-api-go/v2/session" + "github.com/nspcc-dev/neofs-api-go/v2/util/signature" ) type serviceRequest interface { diff --git a/v2/signature/sign_test.go b/signature/sign_test.go similarity index 100% rename from v2/signature/sign_test.go rename to signature/sign_test.go diff --git a/v2/storagegroup/convert.go b/storagegroup/convert.go similarity index 91% rename from v2/storagegroup/convert.go rename to storagegroup/convert.go index 61e49d0..489dad3 100644 --- a/v2/storagegroup/convert.go +++ b/storagegroup/convert.go @@ -1,10 +1,10 @@ package storagegroup import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/refs" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" sg "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc" ) diff --git a/v2/storagegroup/grpc/types.go b/storagegroup/grpc/types.go similarity index 100% rename from v2/storagegroup/grpc/types.go rename to storagegroup/grpc/types.go diff --git a/v2/storagegroup/grpc/types.pb.go b/storagegroup/grpc/types.pb.go similarity index 100% rename from v2/storagegroup/grpc/types.pb.go rename to storagegroup/grpc/types.pb.go diff --git a/v2/storagegroup/json.go b/storagegroup/json.go similarity index 86% rename from v2/storagegroup/json.go rename to storagegroup/json.go index 82e97e9..3224835 100644 --- a/v2/storagegroup/json.go +++ b/storagegroup/json.go @@ -1,7 +1,7 @@ package storagegroup import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" storagegroup "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc" ) diff --git a/v2/storagegroup/marshal.go b/storagegroup/marshal.go similarity index 93% rename from v2/storagegroup/marshal.go rename to storagegroup/marshal.go index 75b3360..534f6f7 100644 --- a/v2/storagegroup/marshal.go +++ b/storagegroup/marshal.go @@ -1,10 +1,10 @@ package storagegroup import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - "github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/v2/refs" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" storagegroup "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/storagegroup/message_test.go b/storagegroup/message_test.go similarity index 70% rename from v2/storagegroup/message_test.go rename to storagegroup/message_test.go index 3a787d2..0eb65ef 100644 --- a/v2/storagegroup/message_test.go +++ b/storagegroup/message_test.go @@ -3,8 +3,8 @@ package storagegroup_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" storagegrouptest "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/test" ) diff --git a/v2/storagegroup/test/generate.go b/storagegroup/test/generate.go similarity index 100% rename from v2/storagegroup/test/generate.go rename to storagegroup/test/generate.go diff --git a/v2/storagegroup/types.go b/storagegroup/types.go similarity index 100% rename from v2/storagegroup/types.go rename to storagegroup/types.go diff --git a/v2/tombstone/convert.go b/tombstone/convert.go similarity index 88% rename from v2/tombstone/convert.go rename to tombstone/convert.go index 204c0a3..beb92a7 100644 --- a/v2/tombstone/convert.go +++ b/tombstone/convert.go @@ -1,9 +1,9 @@ package tombstone import ( - "github.com/nspcc-dev/neofs-api-go/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/rpc/message" "github.com/nspcc-dev/neofs-api-go/v2/refs" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc" ) diff --git a/v2/tombstone/grpc/types.go b/tombstone/grpc/types.go similarity index 100% rename from v2/tombstone/grpc/types.go rename to tombstone/grpc/types.go diff --git a/v2/tombstone/grpc/types.pb.go b/tombstone/grpc/types.pb.go similarity index 100% rename from v2/tombstone/grpc/types.pb.go rename to tombstone/grpc/types.pb.go diff --git a/v2/tombstone/json.go b/tombstone/json.go similarity index 85% rename from v2/tombstone/json.go rename to tombstone/json.go index be89a1c..28ffc1b 100644 --- a/v2/tombstone/json.go +++ b/tombstone/json.go @@ -1,7 +1,7 @@ package tombstone import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc" ) diff --git a/v2/tombstone/marshal.go b/tombstone/marshal.go similarity index 93% rename from v2/tombstone/marshal.go rename to tombstone/marshal.go index eb5bb38..f39d5d9 100644 --- a/v2/tombstone/marshal.go +++ b/tombstone/marshal.go @@ -1,9 +1,9 @@ package tombstone import ( - "github.com/nspcc-dev/neofs-api-go/rpc/message" - "github.com/nspcc-dev/neofs-api-go/util/proto" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" ) const ( diff --git a/v2/tombstone/message_test.go b/tombstone/message_test.go similarity index 69% rename from v2/tombstone/message_test.go rename to tombstone/message_test.go index 4609cdd..858cb01 100644 --- a/v2/tombstone/message_test.go +++ b/tombstone/message_test.go @@ -3,8 +3,8 @@ package tombstone_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/rpc/message" - messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" + messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test" tombstonetest "github.com/nspcc-dev/neofs-api-go/v2/tombstone/test" ) diff --git a/v2/tombstone/test/generate.go b/tombstone/test/generate.go similarity index 100% rename from v2/tombstone/test/generate.go rename to tombstone/test/generate.go diff --git a/v2/tombstone/types.go b/tombstone/types.go similarity index 100% rename from v2/tombstone/types.go rename to tombstone/types.go diff --git a/util/proto/marshal_test.go b/util/proto/marshal_test.go index 5095964..ba78c00 100644 --- a/util/proto/marshal_test.go +++ b/util/proto/marshal_test.go @@ -5,8 +5,8 @@ import ( "math" "testing" - "github.com/nspcc-dev/neofs-api-go/util/proto" - "github.com/nspcc-dev/neofs-api-go/util/proto/test" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto" + "github.com/nspcc-dev/neofs-api-go/v2/util/proto/test" "github.com/stretchr/testify/require" goproto "google.golang.org/protobuf/proto" )