Compare commits
1 commit
master
...
test_build
Author | SHA1 | Date | |
---|---|---|---|
d50b7a906f |
|
@ -25,7 +25,7 @@ linters-settings:
|
|||
# report about shadowed variables
|
||||
check-shadowing: false
|
||||
staticcheck:
|
||||
checks: ["all"]
|
||||
checks: ["all", "-SA1019"] # TODO Enable SA1019 after deprecated warning are fixed.
|
||||
funlen:
|
||||
lines: 80 # default 60
|
||||
statements: 60 # default 40
|
||||
|
|
|
@ -102,8 +102,8 @@ outdated in some details.
|
|||
|
||||
```go
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
)
|
||||
|
||||
func placementNodes(addr *object.Address, p *netmap.PlacementPolicy, frostfsNodes []netmap.NodeInfo) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
v2accounting "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/accounting"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package accountingtest
|
|||
import (
|
||||
"math/rand"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/accounting"
|
||||
)
|
||||
|
||||
// Decimal returns random accounting.Decimal.
|
||||
|
|
|
@ -5,7 +5,7 @@ Note that importing the package into source files is highly discouraged.
|
|||
|
||||
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||
|
||||
import accountingtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting/test"
|
||||
import accountingtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/accounting/test"
|
||||
|
||||
dec := accountingtest.Decimal()
|
||||
// test the value
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
)
|
||||
|
||||
// Token represents bearer token for object service operations.
|
||||
|
|
|
@ -7,15 +7,15 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
bearertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
eacltest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
bearertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer/test"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
eacltest "git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
usertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/user/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -22,7 +22,7 @@ Bearer token must be signed by owner of the container.
|
|||
Provide signed token in JSON or binary format to the request sender. Request
|
||||
sender can attach this bearer token to the object service requests:
|
||||
|
||||
import sdkClient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
import sdkClient "git.frostfs.info/mbiryukova/frostfs-sdk-go/client"
|
||||
|
||||
var headParams sdkClient.PrmObjectHead
|
||||
headParams.WithBearerToken(bearerToken)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package bearertest
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
eacltest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl/test"
|
||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
eacltest "git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl/test"
|
||||
usertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/user/test"
|
||||
)
|
||||
|
||||
// Token returns random bearer.Token.
|
||||
|
|
|
@ -2,9 +2,9 @@ package checksum
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ Note that importing the package into source files is highly discouraged.
|
|||
|
||||
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||
|
||||
import checksumtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum/test"
|
||||
import checksumtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/checksum/test"
|
||||
|
||||
cs := checksumtest.Checksum()
|
||||
// test the value
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package checksumtest
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"math/rand"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/checksum"
|
||||
)
|
||||
|
||||
// Checksum returns random checksum.Checksum.
|
||||
func Checksum() checksum.Checksum {
|
||||
var cs [sha256.Size]byte
|
||||
|
||||
_, _ = rand.Read(cs[:])
|
||||
rand.Read(cs[:])
|
||||
|
||||
var x checksum.Checksum
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/accounting"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
)
|
||||
|
||||
// PrmBalanceGet groups parameters of BalanceGet operation.
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
)
|
||||
|
||||
// structure is embedded to all resulting types in order to inherit status-related methods.
|
||||
|
@ -47,8 +47,6 @@ func writeXHeadersToMeta(xHeaders []string, h *v2session.RequestMetaHeader) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO (aarifullin): remove the panic when all client parameters will check XHeaders
|
||||
// within buildRequest invocation.
|
||||
if len(xHeaders)%2 != 0 {
|
||||
panic("slice of X-Headers with odd length")
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
)
|
||||
|
||||
// SyncContainerWithNetwork requests network configuration using passed client
|
||||
|
|
|
@ -10,10 +10,10 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmContainerDelete groups parameters of ContainerDelete operation.
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
)
|
||||
|
||||
// PrmContainerEACL groups parameters of ContainerEACL operation.
|
||||
|
|
|
@ -11,9 +11,9 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// PrmContainerGet groups parameters of ContainerGet operation.
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
)
|
||||
|
||||
// PrmContainerList groups parameters of ContainerList operation.
|
||||
|
|
|
@ -10,11 +10,11 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmContainerPut groups parameters of ContainerPut operation.
|
||||
|
|
|
@ -10,10 +10,10 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmContainerSetEACL groups parameters of ContainerSetEACL operation.
|
||||
|
|
|
@ -9,34 +9,32 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
)
|
||||
|
||||
// PrmAnnounceSpace groups parameters of ContainerAnnounceUsedSpace operation.
|
||||
type PrmAnnounceSpace struct {
|
||||
XHeaders []string
|
||||
prmCommonMeta
|
||||
|
||||
Announcements []container.SizeEstimation
|
||||
announcements []container.SizeEstimation
|
||||
}
|
||||
|
||||
// SetValues sets values describing volume of space that is used for the container objects.
|
||||
// Required parameter. Must not be empty.
|
||||
//
|
||||
// Must not be mutated before the end of the operation.
|
||||
//
|
||||
// Deprecated: Use PrmAnnounceSpace.Announcements instead.
|
||||
func (x *PrmAnnounceSpace) SetValues(vs []container.SizeEstimation) {
|
||||
x.Announcements = vs
|
||||
x.announcements = vs
|
||||
}
|
||||
|
||||
func (x *PrmAnnounceSpace) buildRequest(c *Client) (*v2container.AnnounceUsedSpaceRequest, error) {
|
||||
if len(x.Announcements) == 0 {
|
||||
if len(x.announcements) == 0 {
|
||||
return nil, errorMissingAnnouncements
|
||||
}
|
||||
|
||||
v2announce := make([]v2container.UsedSpaceAnnouncement, len(x.Announcements))
|
||||
for i := range x.Announcements {
|
||||
x.Announcements[i].WriteToV2(&v2announce[i])
|
||||
v2announce := make([]v2container.UsedSpaceAnnouncement, len(x.announcements))
|
||||
for i := range x.announcements {
|
||||
x.announcements[i].WriteToV2(&v2announce[i])
|
||||
}
|
||||
|
||||
reqBody := new(v2container.AnnounceUsedSpaceRequestBody)
|
||||
|
|
|
@ -72,7 +72,7 @@ for the all operations are write-only and the results of the all operations are
|
|||
read-only. To be able to override client behavior (e.g. for tests), abstract it
|
||||
with an interface:
|
||||
|
||||
import "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
import "git.frostfs.info/mbiryukova/frostfs-sdk-go/client"
|
||||
|
||||
type FrostFSClient interface {
|
||||
// Operations according to the application needs
|
||||
|
|
|
@ -3,7 +3,7 @@ package client
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
)
|
||||
|
||||
// wrapsErrType returns true if any error in the error tree of err is of type E.
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/client"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,19 +9,19 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
)
|
||||
|
||||
// PrmEndpointInfo groups parameters of EndpointInfo operation.
|
||||
type PrmEndpointInfo struct {
|
||||
XHeaders []string
|
||||
prmCommonMeta
|
||||
}
|
||||
|
||||
func (x *PrmEndpointInfo) buildRequest(c *Client) (*v2netmap.LocalNodeInfoRequest, error) {
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(x.XHeaders, meta)
|
||||
writeXHeadersToMeta(x.xHeaders, meta)
|
||||
|
||||
req := new(v2netmap.LocalNodeInfoRequest)
|
||||
req.SetBody(new(v2netmap.LocalNodeInfoRequestBody))
|
||||
|
@ -112,12 +112,12 @@ func (c *Client) EndpointInfo(ctx context.Context, prm PrmEndpointInfo) (*ResEnd
|
|||
|
||||
// PrmNetworkInfo groups parameters of NetworkInfo operation.
|
||||
type PrmNetworkInfo struct {
|
||||
XHeaders []string
|
||||
prmCommonMeta
|
||||
}
|
||||
|
||||
func (x PrmNetworkInfo) buildRequest(c *Client) (*v2netmap.NetworkInfoRequest, error) {
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(x.XHeaders, meta)
|
||||
writeXHeadersToMeta(x.xHeaders, meta)
|
||||
|
||||
var req v2netmap.NetworkInfoRequest
|
||||
req.SetBody(new(v2netmap.NetworkInfoRequestBody))
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -12,34 +12,80 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmObjectDelete groups parameters of ObjectDelete operation.
|
||||
type PrmObjectDelete struct {
|
||||
XHeaders []string
|
||||
meta v2session.RequestMetaHeader
|
||||
|
||||
BearerToken *bearer.Token
|
||||
body v2object.DeleteRequestBody
|
||||
|
||||
Session *session.Object
|
||||
addr v2refs.Address
|
||||
|
||||
ContainerID *cid.ID
|
||||
keySet bool
|
||||
key ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
ObjectID *oid.ID
|
||||
// WithinSession specifies session within which object should be read.
|
||||
//
|
||||
// Creator of the session acquires the authorship of the request.
|
||||
// This may affect the execution of an operation (e.g. access control).
|
||||
//
|
||||
// Must be signed.
|
||||
func (x *PrmObjectDelete) WithinSession(t session.Object) {
|
||||
var tv2 v2session.Token
|
||||
t.WriteToV2(&tv2)
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
x.meta.SetSessionToken(&tv2)
|
||||
}
|
||||
|
||||
// WithBearerToken attaches bearer token to be used for the operation.
|
||||
//
|
||||
// If set, underlying eACL rules will be used in access control.
|
||||
//
|
||||
// Must be signed.
|
||||
func (x *PrmObjectDelete) WithBearerToken(t bearer.Token) {
|
||||
var v2token acl.BearerToken
|
||||
t.WriteToV2(&v2token)
|
||||
x.meta.SetBearerToken(&v2token)
|
||||
}
|
||||
|
||||
// FromContainer specifies FrostFS container of the object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectDelete) FromContainer(id cid.ID) {
|
||||
var cidV2 v2refs.ContainerID
|
||||
id.WriteToV2(&cidV2)
|
||||
|
||||
x.addr.SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// ByID specifies identifier of the requested object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectDelete) ByID(id oid.ID) {
|
||||
var idV2 v2refs.ObjectID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
x.addr.SetObjectID(&idV2)
|
||||
}
|
||||
|
||||
// UseKey specifies private key to sign the requests.
|
||||
// If key is not provided, then Client default key is used.
|
||||
func (x *PrmObjectDelete) UseKey(key ecdsa.PrivateKey) {
|
||||
x.keySet = true
|
||||
x.key = key
|
||||
}
|
||||
|
||||
// WithXHeaders specifies list of extended headers (string key-value pairs)
|
||||
// to be attached to the request. Must have an even length.
|
||||
//
|
||||
// Deprecated: Use PrmObjectDelete.Key instead.
|
||||
func (prm *PrmObjectDelete) UseKey(key ecdsa.PrivateKey) {
|
||||
prm.Key = &key
|
||||
// Slice must not be mutated until the operation completes.
|
||||
func (x *PrmObjectDelete) WithXHeaders(hs ...string) {
|
||||
writeXHeadersToMeta(hs, &x.meta)
|
||||
}
|
||||
|
||||
// ResObjectDelete groups resulting values of ObjectDelete operation.
|
||||
|
@ -54,54 +100,6 @@ func (x ResObjectDelete) Tombstone() oid.ID {
|
|||
return x.tomb
|
||||
}
|
||||
|
||||
func (prm *PrmObjectDelete) buildRequest(c *Client) (*v2object.DeleteRequest, error) {
|
||||
if prm.ContainerID == nil {
|
||||
return nil, errorMissingContainer
|
||||
}
|
||||
|
||||
if prm.ObjectID == nil {
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
if len(prm.XHeaders)%2 != 0 {
|
||||
return nil, errorInvalidXHeaders
|
||||
}
|
||||
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(prm.XHeaders, meta)
|
||||
|
||||
if prm.BearerToken != nil {
|
||||
v2BearerToken := new(acl.BearerToken)
|
||||
prm.BearerToken.WriteToV2(v2BearerToken)
|
||||
meta.SetBearerToken(v2BearerToken)
|
||||
}
|
||||
|
||||
if prm.Session != nil {
|
||||
v2SessionToken := new(v2session.Token)
|
||||
prm.Session.WriteToV2(v2SessionToken)
|
||||
meta.SetSessionToken(v2SessionToken)
|
||||
}
|
||||
|
||||
addr := new(v2refs.Address)
|
||||
|
||||
cnrV2 := new(v2refs.ContainerID)
|
||||
prm.ContainerID.WriteToV2(cnrV2)
|
||||
addr.SetContainerID(cnrV2)
|
||||
|
||||
objV2 := new(v2refs.ObjectID)
|
||||
prm.ObjectID.WriteToV2(objV2)
|
||||
addr.SetObjectID(objV2)
|
||||
|
||||
body := new(v2object.DeleteRequestBody)
|
||||
body.SetAddress(addr)
|
||||
|
||||
req := new(v2object.DeleteRequest)
|
||||
req.SetBody(body)
|
||||
c.prepareRequest(req, meta)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// ObjectDelete marks an object for deletion from the container using FrostFS API protocol.
|
||||
// As a marker, a special unit called a tombstone is placed in the container.
|
||||
// It confirms the user's intent to delete the object, and is itself a container object.
|
||||
|
@ -126,22 +124,32 @@ func (prm *PrmObjectDelete) buildRequest(c *Client) (*v2object.DeleteRequest, er
|
|||
// - *apistatus.ObjectLocked;
|
||||
// - *apistatus.SessionTokenExpired.
|
||||
func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObjectDelete, error) {
|
||||
req, err := prm.buildRequest(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
return nil, errorMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
// form request body
|
||||
prm.body.SetAddress(&prm.addr)
|
||||
|
||||
// form request
|
||||
var req v2object.DeleteRequest
|
||||
req.SetBody(&prm.body)
|
||||
c.prepareRequest(&req, &prm.meta)
|
||||
|
||||
key := c.prm.key
|
||||
if prm.Key != nil {
|
||||
key = *prm.Key
|
||||
if prm.keySet {
|
||||
key = prm.key
|
||||
}
|
||||
|
||||
err = signature.SignServiceMessage(&key, req)
|
||||
err := signature.SignServiceMessage(&key, &req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := rpcapi.DeleteObject(&c.c, req, client.WithContext(ctx))
|
||||
resp, err := rpcapi.DeleteObject(&c.c, &req, client.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -14,84 +14,85 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// shared parameters of GET/HEAD/RANGE.
|
||||
type prmObjectRead struct {
|
||||
meta v2session.RequestMetaHeader
|
||||
|
||||
raw bool
|
||||
|
||||
addr v2refs.Address
|
||||
}
|
||||
|
||||
// WithXHeaders specifies list of extended headers (string key-value pairs)
|
||||
// to be attached to the request. Must have an even length.
|
||||
//
|
||||
// Slice must not be mutated until the operation completes.
|
||||
func (x *prmObjectRead) WithXHeaders(hs ...string) {
|
||||
writeXHeadersToMeta(hs, &x.meta)
|
||||
}
|
||||
|
||||
// MarkRaw marks an intent to read physically stored object.
|
||||
func (x *prmObjectRead) MarkRaw() {
|
||||
x.raw = true
|
||||
}
|
||||
|
||||
// MarkLocal tells the server to execute the operation locally.
|
||||
func (x *prmObjectRead) MarkLocal() {
|
||||
x.meta.SetTTL(1)
|
||||
}
|
||||
|
||||
// WithinSession specifies session within which object should be read.
|
||||
//
|
||||
// Creator of the session acquires the authorship of the request.
|
||||
// This may affect the execution of an operation (e.g. access control).
|
||||
//
|
||||
// Must be signed.
|
||||
func (x *prmObjectRead) WithinSession(t session.Object) {
|
||||
var tokv2 v2session.Token
|
||||
t.WriteToV2(&tokv2)
|
||||
x.meta.SetSessionToken(&tokv2)
|
||||
}
|
||||
|
||||
// WithBearerToken attaches bearer token to be used for the operation.
|
||||
//
|
||||
// If set, underlying eACL rules will be used in access control.
|
||||
//
|
||||
// Must be signed.
|
||||
func (x *prmObjectRead) WithBearerToken(t bearer.Token) {
|
||||
var v2token acl.BearerToken
|
||||
t.WriteToV2(&v2token)
|
||||
x.meta.SetBearerToken(&v2token)
|
||||
}
|
||||
|
||||
// FromContainer specifies FrostFS container of the object.
|
||||
// Required parameter.
|
||||
func (x *prmObjectRead) FromContainer(id cid.ID) {
|
||||
var cnrV2 v2refs.ContainerID
|
||||
id.WriteToV2(&cnrV2)
|
||||
x.addr.SetContainerID(&cnrV2)
|
||||
}
|
||||
|
||||
// ByID specifies identifier of the requested object.
|
||||
// Required parameter.
|
||||
func (x *prmObjectRead) ByID(id oid.ID) {
|
||||
var objV2 v2refs.ObjectID
|
||||
id.WriteToV2(&objV2)
|
||||
x.addr.SetObjectID(&objV2)
|
||||
}
|
||||
|
||||
// PrmObjectGet groups parameters of ObjectGetInit operation.
|
||||
type PrmObjectGet struct {
|
||||
XHeaders []string
|
||||
prmObjectRead
|
||||
|
||||
BearerToken *bearer.Token
|
||||
|
||||
Session *session.Object
|
||||
|
||||
Raw bool
|
||||
|
||||
Local bool
|
||||
|
||||
ContainerID *cid.ID
|
||||
|
||||
ObjectID *oid.ID
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
func (prm *PrmObjectGet) buildRequest(c *Client) (*v2object.GetRequest, error) {
|
||||
if prm.ContainerID == nil {
|
||||
return nil, errorMissingContainer
|
||||
}
|
||||
|
||||
if prm.ObjectID == nil {
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
if len(prm.XHeaders)%2 != 0 {
|
||||
return nil, errorInvalidXHeaders
|
||||
}
|
||||
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(prm.XHeaders, meta)
|
||||
|
||||
if prm.BearerToken != nil {
|
||||
v2BearerToken := new(acl.BearerToken)
|
||||
prm.BearerToken.WriteToV2(v2BearerToken)
|
||||
meta.SetBearerToken(v2BearerToken)
|
||||
}
|
||||
|
||||
if prm.Session != nil {
|
||||
v2SessionToken := new(v2session.Token)
|
||||
prm.Session.WriteToV2(v2SessionToken)
|
||||
meta.SetSessionToken(v2SessionToken)
|
||||
}
|
||||
|
||||
if prm.Local {
|
||||
meta.SetTTL(1)
|
||||
}
|
||||
|
||||
addr := new(v2refs.Address)
|
||||
|
||||
cnrV2 := new(v2refs.ContainerID)
|
||||
prm.ContainerID.WriteToV2(cnrV2)
|
||||
addr.SetContainerID(cnrV2)
|
||||
|
||||
objV2 := new(v2refs.ObjectID)
|
||||
prm.ObjectID.WriteToV2(objV2)
|
||||
addr.SetObjectID(objV2)
|
||||
|
||||
body := new(v2object.GetRequestBody)
|
||||
body.SetRaw(prm.Raw)
|
||||
body.SetAddress(addr)
|
||||
|
||||
req := new(v2object.GetRequest)
|
||||
req.SetBody(body)
|
||||
c.prepareRequest(req, meta)
|
||||
|
||||
return req, nil
|
||||
key *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// ResObjectGet groups the final result values of ObjectGetInit operation.
|
||||
|
@ -121,10 +122,8 @@ type ObjectReader struct {
|
|||
|
||||
// UseKey specifies private key to sign the requests.
|
||||
// If key is not provided, then Client default key is used.
|
||||
//
|
||||
// Deprecated: Use PrmObjectGet.Key instead.
|
||||
func (prm *PrmObjectGet) UseKey(key ecdsa.PrivateKey) {
|
||||
prm.Key = &key
|
||||
func (x *PrmObjectGet) UseKey(key ecdsa.PrivateKey) {
|
||||
x.key = &key
|
||||
}
|
||||
|
||||
// ReadHeader reads header of the object. Result means success.
|
||||
|
@ -300,24 +299,39 @@ func (x *ObjectReader) Read(p []byte) (int, error) {
|
|||
// Returns an error if parameters are set incorrectly (see PrmObjectGet docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
func (c *Client) ObjectGetInit(ctx context.Context, prm PrmObjectGet) (*ObjectReader, error) {
|
||||
req, err := prm.buildRequest(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// check parameters
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
return nil, errorMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
key := prm.Key
|
||||
// form request body
|
||||
var body v2object.GetRequestBody
|
||||
|
||||
body.SetRaw(prm.raw)
|
||||
body.SetAddress(&prm.addr)
|
||||
|
||||
// form request
|
||||
var req v2object.GetRequest
|
||||
|
||||
req.SetBody(&body)
|
||||
c.prepareRequest(&req, &prm.meta)
|
||||
|
||||
key := prm.key
|
||||
if key == nil {
|
||||
key = &c.prm.key
|
||||
}
|
||||
|
||||
err = signature.SignServiceMessage(key, req)
|
||||
err := signature.SignServiceMessage(key, &req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
stream, err := rpcapi.GetObject(&c.c, req, client.WithContext(ctx))
|
||||
stream, err := rpcapi.GetObject(&c.c, &req, client.WithContext(ctx))
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("open stream: %w", err)
|
||||
|
@ -333,29 +347,17 @@ func (c *Client) ObjectGetInit(ctx context.Context, prm PrmObjectGet) (*ObjectRe
|
|||
|
||||
// PrmObjectHead groups parameters of ObjectHead operation.
|
||||
type PrmObjectHead struct {
|
||||
XHeaders []string
|
||||
prmObjectRead
|
||||
|
||||
BearerToken *bearer.Token
|
||||
|
||||
Session *session.Object
|
||||
|
||||
Raw bool
|
||||
|
||||
Local bool
|
||||
|
||||
ContainerID *cid.ID
|
||||
|
||||
ObjectID *oid.ID
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
keySet bool
|
||||
key ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// UseKey specifies private key to sign the requests.
|
||||
// If key is not provided, then Client default key is used.
|
||||
//
|
||||
// Deprecated: Use PrmObjectHead.Key instead.
|
||||
func (prm *PrmObjectHead) UseKey(key ecdsa.PrivateKey) {
|
||||
prm.Key = &key
|
||||
func (x *PrmObjectHead) UseKey(key ecdsa.PrivateKey) {
|
||||
x.keySet = true
|
||||
x.key = key
|
||||
}
|
||||
|
||||
// ResObjectHead groups resulting values of ObjectHead operation.
|
||||
|
@ -388,58 +390,6 @@ func (x *ResObjectHead) ReadHeader(dst *object.Object) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (prm *PrmObjectHead) buildRequest(c *Client) (*v2object.HeadRequest, error) {
|
||||
if prm.ContainerID == nil {
|
||||
return nil, errorMissingContainer
|
||||
}
|
||||
|
||||
if prm.ObjectID == nil {
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
if len(prm.XHeaders)%2 != 0 {
|
||||
return nil, errorInvalidXHeaders
|
||||
}
|
||||
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(prm.XHeaders, meta)
|
||||
|
||||
if prm.BearerToken != nil {
|
||||
v2BearerToken := new(acl.BearerToken)
|
||||
prm.BearerToken.WriteToV2(v2BearerToken)
|
||||
meta.SetBearerToken(v2BearerToken)
|
||||
}
|
||||
|
||||
if prm.Session != nil {
|
||||
v2SessionToken := new(v2session.Token)
|
||||
prm.Session.WriteToV2(v2SessionToken)
|
||||
meta.SetSessionToken(v2SessionToken)
|
||||
}
|
||||
|
||||
if prm.Local {
|
||||
meta.SetTTL(1)
|
||||
}
|
||||
|
||||
addr := new(v2refs.Address)
|
||||
|
||||
cnrV2 := new(v2refs.ContainerID)
|
||||
prm.ContainerID.WriteToV2(cnrV2)
|
||||
addr.SetContainerID(cnrV2)
|
||||
|
||||
objV2 := new(v2refs.ObjectID)
|
||||
prm.ObjectID.WriteToV2(objV2)
|
||||
addr.SetObjectID(objV2)
|
||||
body := new(v2object.HeadRequestBody)
|
||||
body.SetRaw(prm.Raw)
|
||||
body.SetAddress(addr)
|
||||
|
||||
req := new(v2object.HeadRequest)
|
||||
req.SetBody(body)
|
||||
c.prepareRequest(req, meta)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// ObjectHead reads object header through a remote server using FrostFS API protocol.
|
||||
//
|
||||
// Exactly one return value is non-nil. By default, server status is returned in res structure.
|
||||
|
@ -463,24 +413,33 @@ func (prm *PrmObjectHead) buildRequest(c *Client) (*v2object.HeadRequest, error)
|
|||
// - *apistatus.ObjectAlreadyRemoved;
|
||||
// - *apistatus.SessionTokenExpired.
|
||||
func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectHead, error) {
|
||||
req, err := prm.buildRequest(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
return nil, errorMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
var body v2object.HeadRequestBody
|
||||
body.SetRaw(prm.raw)
|
||||
body.SetAddress(&prm.addr)
|
||||
|
||||
var req v2object.HeadRequest
|
||||
req.SetBody(&body)
|
||||
c.prepareRequest(&req, &prm.meta)
|
||||
|
||||
key := c.prm.key
|
||||
if prm.Key != nil {
|
||||
key = *prm.Key
|
||||
if prm.keySet {
|
||||
key = prm.key
|
||||
}
|
||||
|
||||
// sign the request
|
||||
|
||||
err = signature.SignServiceMessage(&key, req)
|
||||
err := signature.SignServiceMessage(&key, &req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := rpcapi.HeadObject(&c.c, req, client.WithContext(ctx))
|
||||
resp, err := rpcapi.HeadObject(&c.c, &req, client.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("write request: %w", err)
|
||||
}
|
||||
|
@ -495,7 +454,7 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
|
|||
return &res, nil
|
||||
}
|
||||
|
||||
res.idObj = *prm.ObjectID
|
||||
_ = res.idObj.ReadFromV2(*prm.addr.GetObjectID())
|
||||
|
||||
switch v := resp.GetBody().GetHeaderPart().(type) {
|
||||
default:
|
||||
|
@ -511,95 +470,29 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
|
|||
|
||||
// PrmObjectRange groups parameters of ObjectRange operation.
|
||||
type PrmObjectRange struct {
|
||||
XHeaders []string
|
||||
prmObjectRead
|
||||
|
||||
BearerToken *bearer.Token
|
||||
key *ecdsa.PrivateKey
|
||||
|
||||
Session *session.Object
|
||||
|
||||
Raw bool
|
||||
|
||||
Local bool
|
||||
|
||||
ContainerID *cid.ID
|
||||
|
||||
ObjectID *oid.ID
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
|
||||
Offset uint64
|
||||
|
||||
Length uint64
|
||||
rng v2object.Range
|
||||
}
|
||||
|
||||
func (prm *PrmObjectRange) buildRequest(c *Client) (*v2object.GetRangeRequest, error) {
|
||||
if prm.Length == 0 {
|
||||
return nil, errorZeroRangeLength
|
||||
}
|
||||
// SetOffset sets offset of the payload range to be read.
|
||||
// Zero by default.
|
||||
func (x *PrmObjectRange) SetOffset(off uint64) {
|
||||
x.rng.SetOffset(off)
|
||||
}
|
||||
|
||||
if prm.ContainerID == nil {
|
||||
return nil, errorMissingContainer
|
||||
}
|
||||
|
||||
if prm.ObjectID == nil {
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
if len(prm.XHeaders)%2 != 0 {
|
||||
return nil, errorInvalidXHeaders
|
||||
}
|
||||
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(prm.XHeaders, meta)
|
||||
|
||||
if prm.BearerToken != nil {
|
||||
v2BearerToken := new(acl.BearerToken)
|
||||
prm.BearerToken.WriteToV2(v2BearerToken)
|
||||
meta.SetBearerToken(v2BearerToken)
|
||||
}
|
||||
|
||||
if prm.Session != nil {
|
||||
v2SessionToken := new(v2session.Token)
|
||||
prm.Session.WriteToV2(v2SessionToken)
|
||||
meta.SetSessionToken(v2SessionToken)
|
||||
}
|
||||
|
||||
if prm.Local {
|
||||
meta.SetTTL(1)
|
||||
}
|
||||
|
||||
addr := new(v2refs.Address)
|
||||
|
||||
cnrV2 := new(v2refs.ContainerID)
|
||||
prm.ContainerID.WriteToV2(cnrV2)
|
||||
addr.SetContainerID(cnrV2)
|
||||
|
||||
objV2 := new(v2refs.ObjectID)
|
||||
prm.ObjectID.WriteToV2(objV2)
|
||||
addr.SetObjectID(objV2)
|
||||
|
||||
rng := new(v2object.Range)
|
||||
rng.SetLength(prm.Length)
|
||||
rng.SetOffset(prm.Offset)
|
||||
|
||||
body := new(v2object.GetRangeRequestBody)
|
||||
body.SetRaw(prm.Raw)
|
||||
body.SetAddress(addr)
|
||||
body.SetRange(rng)
|
||||
|
||||
req := new(v2object.GetRangeRequest)
|
||||
req.SetBody(body)
|
||||
c.prepareRequest(req, meta)
|
||||
|
||||
return req, nil
|
||||
// SetLength sets length of the payload range to be read.
|
||||
// Must be positive.
|
||||
func (x *PrmObjectRange) SetLength(ln uint64) {
|
||||
x.rng.SetLength(ln)
|
||||
}
|
||||
|
||||
// UseKey specifies private key to sign the requests.
|
||||
// If key is not provided, then Client default key is used.
|
||||
//
|
||||
// Deprecated: Use PrmObjectRange.Key instead.
|
||||
func (prm *PrmObjectRange) UseKey(key ecdsa.PrivateKey) {
|
||||
prm.Key = &key
|
||||
func (x *PrmObjectRange) UseKey(key ecdsa.PrivateKey) {
|
||||
x.key = &key
|
||||
}
|
||||
|
||||
// ResObjectRange groups the final result values of ObjectRange operation.
|
||||
|
@ -769,31 +662,49 @@ func (x *ObjectRangeReader) Read(p []byte) (int, error) {
|
|||
// Returns an error if parameters are set incorrectly (see PrmObjectRange docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
func (c *Client) ObjectRangeInit(ctx context.Context, prm PrmObjectRange) (*ObjectRangeReader, error) {
|
||||
req, err := prm.buildRequest(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// check parameters
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
return nil, errorMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
return nil, errorMissingObject
|
||||
case prm.rng.GetLength() == 0:
|
||||
return nil, errorZeroRangeLength
|
||||
}
|
||||
|
||||
key := prm.Key
|
||||
// form request body
|
||||
var body v2object.GetRangeRequestBody
|
||||
|
||||
body.SetRaw(prm.raw)
|
||||
body.SetAddress(&prm.addr)
|
||||
body.SetRange(&prm.rng)
|
||||
|
||||
// form request
|
||||
var req v2object.GetRangeRequest
|
||||
|
||||
req.SetBody(&body)
|
||||
c.prepareRequest(&req, &prm.meta)
|
||||
|
||||
key := prm.key
|
||||
if key == nil {
|
||||
key = &c.prm.key
|
||||
}
|
||||
|
||||
err = signature.SignServiceMessage(key, req)
|
||||
err := signature.SignServiceMessage(key, &req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
stream, err := rpcapi.GetObjectRange(&c.c, req, client.WithContext(ctx))
|
||||
stream, err := rpcapi.GetObjectRange(&c.c, &req, client.WithContext(ctx))
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("open stream: %w", err)
|
||||
}
|
||||
|
||||
var r ObjectRangeReader
|
||||
r.remainingPayloadLen = int(prm.Length)
|
||||
r.remainingPayloadLen = int(prm.rng.GetLength())
|
||||
r.cancelCtxStream = cancel
|
||||
r.stream = stream
|
||||
r.client = c
|
||||
|
|
|
@ -12,54 +12,122 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmObjectHash groups parameters of ObjectHash operation.
|
||||
type PrmObjectHash struct {
|
||||
XHeaders []string
|
||||
meta v2session.RequestMetaHeader
|
||||
|
||||
BearerToken *bearer.Token
|
||||
body v2object.GetRangeHashRequestBody
|
||||
|
||||
Session *session.Object
|
||||
csAlgo v2refs.ChecksumType
|
||||
|
||||
Local bool
|
||||
addr v2refs.Address
|
||||
|
||||
Ranges []object.Range
|
||||
|
||||
Salt []byte
|
||||
|
||||
ChecksumType checksum.Type
|
||||
|
||||
ContainerID *cid.ID
|
||||
|
||||
ObjectID *oid.ID
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
keySet bool
|
||||
key ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// UseKey specifies private key to sign the requests.
|
||||
// If key is not provided, then Client default key is used.
|
||||
func (x *PrmObjectHash) UseKey(key ecdsa.PrivateKey) {
|
||||
x.keySet = true
|
||||
x.key = key
|
||||
}
|
||||
|
||||
// MarkLocal tells the server to execute the operation locally.
|
||||
func (x *PrmObjectHash) MarkLocal() {
|
||||
x.meta.SetTTL(1)
|
||||
}
|
||||
|
||||
// WithinSession specifies session within which object should be read.
|
||||
//
|
||||
// Deprecated: Use PrmObjectHash.Key instead.
|
||||
func (prm *PrmObjectHash) UseKey(key ecdsa.PrivateKey) {
|
||||
prm.Key = &key
|
||||
// Creator of the session acquires the authorship of the request.
|
||||
// This may affect the execution of an operation (e.g. access control).
|
||||
//
|
||||
// Must be signed.
|
||||
func (x *PrmObjectHash) WithinSession(t session.Object) {
|
||||
var tv2 v2session.Token
|
||||
t.WriteToV2(&tv2)
|
||||
|
||||
x.meta.SetSessionToken(&tv2)
|
||||
}
|
||||
|
||||
// WithBearerToken attaches bearer token to be used for the operation.
|
||||
//
|
||||
// If set, underlying eACL rules will be used in access control.
|
||||
//
|
||||
// Must be signed.
|
||||
func (x *PrmObjectHash) WithBearerToken(t bearer.Token) {
|
||||
var v2token acl.BearerToken
|
||||
t.WriteToV2(&v2token)
|
||||
x.meta.SetBearerToken(&v2token)
|
||||
}
|
||||
|
||||
// FromContainer specifies FrostFS container of the object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectHash) FromContainer(id cid.ID) {
|
||||
var cidV2 v2refs.ContainerID
|
||||
id.WriteToV2(&cidV2)
|
||||
|
||||
x.addr.SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// ByID specifies identifier of the requested object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectHash) ByID(id oid.ID) {
|
||||
var idV2 v2refs.ObjectID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
x.addr.SetObjectID(&idV2)
|
||||
}
|
||||
|
||||
// SetRangeList sets list of ranges in (offset, length) pair format.
|
||||
// Required parameter.
|
||||
//
|
||||
// If passed as slice, then it must not be mutated before the operation completes.
|
||||
func (x *PrmObjectHash) SetRangeList(r ...uint64) {
|
||||
ln := len(r)
|
||||
if ln%2 != 0 {
|
||||
panic("odd number of range parameters")
|
||||
}
|
||||
|
||||
rs := make([]v2object.Range, ln/2)
|
||||
|
||||
for i := 0; i < ln/2; i++ {
|
||||
rs[i].SetOffset(r[2*i])
|
||||
rs[i].SetLength(r[2*i+1])
|
||||
}
|
||||
|
||||
x.body.SetRanges(rs)
|
||||
}
|
||||
|
||||
// TillichZemorAlgo changes the hash function to Tillich-Zemor
|
||||
// (https://link.springer.com/content/pdf/10.1007/3-540-48658-5_5.pdf).
|
||||
//
|
||||
// By default, SHA256 hash function is used/.
|
||||
// By default, SHA256 hash function is used.
|
||||
func (x *PrmObjectHash) TillichZemorAlgo() {
|
||||
x.csAlgo = v2refs.TillichZemor
|
||||
}
|
||||
|
||||
// UseSalt sets the salt to XOR the data range before hashing.
|
||||
//
|
||||
// Deprecated: Use PrmObjectHash.ChecksumType instead.
|
||||
func (prm *PrmObjectHash) TillichZemorAlgo() {
|
||||
prm.ChecksumType = checksum.TZ
|
||||
// Must not be mutated before the operation completes.
|
||||
func (x *PrmObjectHash) UseSalt(salt []byte) {
|
||||
x.body.SetSalt(salt)
|
||||
}
|
||||
|
||||
// WithXHeaders specifies list of extended headers (string key-value pairs)
|
||||
// to be attached to the request. Must have an even length.
|
||||
//
|
||||
// Slice must not be mutated until the operation completes.
|
||||
func (x *PrmObjectHash) WithXHeaders(hs ...string) {
|
||||
writeXHeadersToMeta(hs, &x.meta)
|
||||
}
|
||||
|
||||
// ResObjectHash groups resulting values of ObjectHash operation.
|
||||
|
@ -74,76 +142,6 @@ func (x ResObjectHash) Checksums() [][]byte {
|
|||
return x.checksums
|
||||
}
|
||||
|
||||
func (prm *PrmObjectHash) buildRequest(c *Client) (*v2object.GetRangeHashRequest, error) {
|
||||
if prm.ContainerID == nil {
|
||||
return nil, errorMissingContainer
|
||||
}
|
||||
|
||||
if prm.ObjectID == nil {
|
||||
return nil, errorMissingObject
|
||||
}
|
||||
|
||||
if len(prm.XHeaders)%2 != 0 {
|
||||
return nil, errorInvalidXHeaders
|
||||
}
|
||||
|
||||
if len(prm.Ranges) == 0 {
|
||||
return nil, errorMissingRanges
|
||||
}
|
||||
|
||||
meta := new(v2session.RequestMetaHeader)
|
||||
writeXHeadersToMeta(prm.XHeaders, meta)
|
||||
|
||||
if prm.BearerToken != nil {
|
||||
v2BearerToken := new(acl.BearerToken)
|
||||
prm.BearerToken.WriteToV2(v2BearerToken)
|
||||
meta.SetBearerToken(v2BearerToken)
|
||||
}
|
||||
|
||||
if prm.Session != nil {
|
||||
v2SessionToken := new(v2session.Token)
|
||||
prm.Session.WriteToV2(v2SessionToken)
|
||||
meta.SetSessionToken(v2SessionToken)
|
||||
}
|
||||
|
||||
if prm.Local {
|
||||
meta.SetTTL(1)
|
||||
}
|
||||
|
||||
addr := new(v2refs.Address)
|
||||
|
||||
cnrV2 := new(v2refs.ContainerID)
|
||||
prm.ContainerID.WriteToV2(cnrV2)
|
||||
addr.SetContainerID(cnrV2)
|
||||
|
||||
objV2 := new(v2refs.ObjectID)
|
||||
prm.ObjectID.WriteToV2(objV2)
|
||||
addr.SetObjectID(objV2)
|
||||
|
||||
rs := make([]v2object.Range, len(prm.Ranges))
|
||||
for i := range prm.Ranges {
|
||||
rs[i].SetOffset(prm.Ranges[i].GetOffset())
|
||||
rs[i].SetLength(prm.Ranges[i].GetLength())
|
||||
}
|
||||
|
||||
body := new(v2object.GetRangeHashRequestBody)
|
||||
body.SetAddress(addr)
|
||||
body.SetRanges(rs)
|
||||
body.SetSalt(prm.Salt)
|
||||
|
||||
if prm.ChecksumType == checksum.Unknown {
|
||||
body.SetType(v2refs.SHA256)
|
||||
} else {
|
||||
body.SetType(v2refs.ChecksumType(prm.ChecksumType))
|
||||
}
|
||||
|
||||
req := new(v2object.GetRangeHashRequest)
|
||||
req.SetBody(body)
|
||||
c.prepareRequest(req, meta)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// ObjectHash requests checksum of the range list of the object payload using
|
||||
// FrostFS API protocol.
|
||||
//
|
||||
|
@ -167,22 +165,37 @@ func (prm *PrmObjectHash) buildRequest(c *Client) (*v2object.GetRangeHashRequest
|
|||
// - *apistatus.ObjectOutOfRange;
|
||||
// - *apistatus.SessionTokenExpired.
|
||||
func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectHash, error) {
|
||||
req, err := prm.buildRequest(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
return nil, errorMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
return nil, errorMissingObject
|
||||
case len(prm.body.GetRanges()) == 0:
|
||||
return nil, errorMissingRanges
|
||||
}
|
||||
|
||||
prm.body.SetAddress(&prm.addr)
|
||||
if prm.csAlgo == v2refs.UnknownChecksum {
|
||||
prm.body.SetType(v2refs.SHA256)
|
||||
} else {
|
||||
prm.body.SetType(prm.csAlgo)
|
||||
}
|
||||
|
||||
var req v2object.GetRangeHashRequest
|
||||
c.prepareRequest(&req, &prm.meta)
|
||||
req.SetBody(&prm.body)
|
||||
|
||||
key := c.prm.key
|
||||
if prm.Key != nil {
|
||||
key = *prm.Key
|
||||
if prm.keySet {
|
||||
key = prm.key
|
||||
}
|
||||
|
||||
err = signature.SignServiceMessage(&key, req)
|
||||
err := signature.SignServiceMessage(&key, &req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := rpcapi.HashObjectRange(&c.c, req, client.WithContext(ctx))
|
||||
resp, err := rpcapi.HashObjectRange(&c.c, &req, client.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("write request: %w", err)
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/transformer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object/transformer"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// defaultGRPCPayloadChunkLen default value for maxChunkLen.
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
)
|
||||
|
||||
func (c *Client) objectPutInitRaw(ctx context.Context, prm PrmObjectPutInit) (*objectWriterRaw, error) {
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmObjectPutSingle groups parameters of PutSingle operation.
|
||||
|
|
|
@ -3,9 +3,9 @@ package client
|
|||
import (
|
||||
"context"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/transformer"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object/transformer"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
|
|
@ -14,12 +14,12 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/bearer"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// PrmObjectSearch groups parameters of ObjectSearch operation.
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
signatureV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
oidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -10,38 +10,36 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
)
|
||||
|
||||
// PrmSessionCreate groups parameters of SessionCreate operation.
|
||||
type PrmSessionCreate struct {
|
||||
XHeaders []string
|
||||
prmCommonMeta
|
||||
|
||||
Expiration uint64
|
||||
exp uint64
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
keySet bool
|
||||
key ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// SetExp sets number of the last NepFS epoch in the lifetime of the session after which it will be expired.
|
||||
//
|
||||
// Deprecated: Use PrmSessionCreate.Expiration instead.
|
||||
func (x *PrmSessionCreate) SetExp(exp uint64) {
|
||||
x.Expiration = exp
|
||||
x.exp = exp
|
||||
}
|
||||
|
||||
// UseKey specifies private key to sign the requests and compute token owner.
|
||||
// If key is not provided, then Client default key is used.
|
||||
//
|
||||
// Deprecated: Use PrmSessionCreate.Key instead.
|
||||
func (x *PrmSessionCreate) UseKey(key ecdsa.PrivateKey) {
|
||||
x.Key = &key
|
||||
x.keySet = true
|
||||
x.key = key
|
||||
}
|
||||
|
||||
func (x *PrmSessionCreate) buildRequest(c *Client) (*v2session.CreateRequest, error) {
|
||||
ownerKey := c.prm.key.PublicKey
|
||||
if x.Key != nil {
|
||||
ownerKey = x.Key.PublicKey
|
||||
if x.keySet {
|
||||
ownerKey = x.key.PublicKey
|
||||
}
|
||||
var ownerID user.ID
|
||||
user.IDFromKey(&ownerID, ownerKey)
|
||||
|
@ -51,10 +49,10 @@ func (x *PrmSessionCreate) buildRequest(c *Client) (*v2session.CreateRequest, er
|
|||
|
||||
reqBody := new(v2session.CreateRequestBody)
|
||||
reqBody.SetOwnerID(&ownerIDV2)
|
||||
reqBody.SetExpiration(x.Expiration)
|
||||
reqBody.SetExpiration(x.exp)
|
||||
|
||||
var meta v2session.RequestMetaHeader
|
||||
writeXHeadersToMeta(x.XHeaders, &meta)
|
||||
writeXHeadersToMeta(x.xHeaders, &meta)
|
||||
|
||||
var req v2session.CreateRequest
|
||||
req.SetBody(reqBody)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package apistatus_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
apistatus "git.frostfs.info/mbiryukova/frostfs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -12,13 +12,13 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container/acl"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@ import (
|
|||
v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
containertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/test"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
|
||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
containertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/test"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
netmaptest "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap/test"
|
||||
usertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/user/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package cid_test
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ Note that importing the package into source files is highly discouraged.
|
|||
|
||||
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||
|
||||
import cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
import cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
|
||||
cid := cidtest.ID()
|
||||
// test the value
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package cidtest
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"math/rand"
|
||||
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// ID returns random cid.ID.
|
||||
func ID() cid.ID {
|
||||
checksum := [sha256.Size]byte{}
|
||||
|
||||
_, _ = rand.Read(checksum[:])
|
||||
rand.Read(checksum[:])
|
||||
|
||||
return IDWithChecksum(checksum)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// ApplyNetworkConfig applies network configuration to the
|
||||
|
|
|
@ -3,9 +3,9 @@ package container_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
containertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/test"
|
||||
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
containertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/test"
|
||||
netmaptest "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// SizeEstimation groups information about estimation of the size of the data
|
||||
|
|
|
@ -6,9 +6,9 @@ import (
|
|||
|
||||
v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ package containertest
|
|||
import (
|
||||
"math/rand"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
|
||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container/acl"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
netmaptest "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap/test"
|
||||
usertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/user/test"
|
||||
)
|
||||
|
||||
// Container returns random container.Container.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package frostfscrypto_test
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package frostfsecdsa
|
||||
|
||||
import frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
import frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
|
||||
func init() {
|
||||
frostfscrypto.RegisterScheme(frostfscrypto.ECDSA_SHA512, func() frostfscrypto.PublicKey {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/signature/walletconnect"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -101,16 +101,16 @@ In a nutshell, a `SELECT` takes a filter result as input and outputs a specific
|
|||
Let's see some examples
|
||||
```sql
|
||||
-- Selects exactly one node from the entire netmap
|
||||
SELECT 1 FROM *
|
||||
SELECT 1 FROM *
|
||||
|
||||
-- Same as above, but with an identifier for the selection
|
||||
SELECT 1 FROM * AS ONE
|
||||
SELECT 1 FROM * AS ONE
|
||||
|
||||
-- Selects two nodes from the RedOrBlueNodes filter, such that both selected nodes
|
||||
-- Selects two nodes from the RedOrBlueNodes filter, such that both selected nodes
|
||||
-- share the same value for the Color attribute, i.e. both red or both blue.
|
||||
SELECT 2 IN SAME Color FROM RedOrBlueNodes
|
||||
SELECT 2 IN SAME Color FROM RedOrBlueNodes
|
||||
|
||||
-- Selects two nodes from the RedOrBlueNodes filter, such that the selected nodes
|
||||
-- Selects two nodes from the RedOrBlueNodes filter, such that the selected nodes
|
||||
-- have distinct values for the Color attribute, i.e. one red and one blue.
|
||||
-- The selection is also given an identifier.
|
||||
SELECT 2 IN DISTINCT Color FROM RedOrBlueNodes AS MyNodes
|
||||
|
@ -131,8 +131,7 @@ Its basic syntax is as follows:
|
|||
REP <count> {IN <select>}
|
||||
```
|
||||
|
||||
If a select is not specified, then the entire netmap is used as input. The only exception to this rule is when exactly 1 replica and 1 selector are being present: in this case the only selector is being used instead of the whole netmap.
|
||||
The resulting nodes will be used to actually store objects and they constitute a replica group (or simply, "a replica").
|
||||
If a select is not specified, then the entire netmap is used as input. The resulting nodes will be used to actually store objects and they constitute a replica group (or simply, "a replica").
|
||||
|
||||
Examples
|
||||
```sql
|
||||
|
@ -174,18 +173,18 @@ In additional to this basic syntax, there are a couple of additional useful opti
|
|||
|
||||
### The policy playground
|
||||
|
||||
> ℹ️ This section assumes you have an up-to-date version of the `frostfs-cli`.
|
||||
> ℹ️ This section assumes you have an up-to-date version of the `frostfs-cli`.
|
||||
|
||||
While simple placement policies have predictable results that can be understood at a glance, more complex ones need careful consideration before deployment. In order to simplify understanding a policy's outcome and experimenting while learning, a builtin tool is provided as part of the `frostfs-cli` for this purpose: the policy playground.
|
||||
|
||||
For the remainder of this guide, we will use the policy playground to setup a virtual netmap (that is, one that doesn't require any networking or deployment) and test various policies. In order to visualize this netmap easily, each node will have three attributes: a character, a shape and a color
|
||||
For the remainder of this guide, we will use the policy playground to setup a virtual netmap (that is, one that doesn't require any networking or deployment) and test various policies. In order to visualize this netmap easily, each node will have three attributes: a character, a shape and a color
|
||||
|
||||
![Sample Netmap](./image/sample_netmap.svg)
|
||||
|
||||
We can start the policy playground as follows:
|
||||
```sh
|
||||
$ frostfs-cli container policy-playground
|
||||
>
|
||||
>
|
||||
```
|
||||
|
||||
Since we didn't pass any endpoint, the initial netmap is empty, which we can verify with the `ls` command (to list the nodes in the netmap):
|
||||
|
@ -401,7 +400,7 @@ FILTER Color EQ 'Green' AS GreenNodes
|
|||
#### Example #6
|
||||
```sql
|
||||
REP 1 IN MyNodes
|
||||
REP 2
|
||||
REP 2
|
||||
CBF 2
|
||||
SELECT 1 FROM CuteNodes AS MyNodes
|
||||
FILTER (Color EQ 'Blue') AND NOT (Shape EQ 'Circle' OR Shape EQ 'Square') AS CuteNodes
|
||||
|
@ -443,4 +442,4 @@ Others:
|
|||
- `ls`: list nodes in the current netmap and their attributes
|
||||
- `add`: add a node to the current netmap. If it already exists, it will be overwritten.
|
||||
- `remove`: remove a node from the current netmap.
|
||||
- `eval`: evaluate a placement policy on the current netmap.
|
||||
- `eval`: evaluate a placement policy on the current netmap.
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
v2acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ import (
|
|||
"crypto/ecdsa"
|
||||
|
||||
v2acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/checksum"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
)
|
||||
|
||||
// Record of the ContainerEACL rule, that defines ContainerEACL action, targets for this action,
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"testing"
|
||||
|
||||
v2acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
checksumtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum/test"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||
versiontest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version/test"
|
||||
checksumtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/checksum/test"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
oidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id/test"
|
||||
usertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/user/test"
|
||||
versiontest "git.frostfs.info/mbiryukova/frostfs-sdk-go/version/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
|
||||
v2acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
)
|
||||
|
||||
// Table is a group of ContainerEACL records for single container.
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
eacltest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
eacltest "git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/version"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@ package eacltest
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
versiontest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version/test"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
versiontest "git.frostfs.info/mbiryukova/frostfs-sdk-go/version/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package eacltest
|
||||
|
||||
import (
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||
versiontest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version/test"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/eacl"
|
||||
usertest "git.frostfs.info/mbiryukova/frostfs-sdk-go/user/test"
|
||||
versiontest "git.frostfs.info/mbiryukova/frostfs-sdk-go/version/test"
|
||||
)
|
||||
|
||||
// Target returns random eacl.Target.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eacl
|
||||
|
||||
import (
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// Header is an interface of string key-value header.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eacl
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
2
go.mod
|
@ -1,4 +1,4 @@
|
|||
module git.frostfs.info/TrueCloudLab/frostfs-sdk-go
|
||||
module git.frostfs.info/mbiryukova/frostfs-sdk-go
|
||||
|
||||
go 1.20
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package netmap
|
|||
import (
|
||||
"testing"
|
||||
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -40,10 +40,6 @@ type context struct {
|
|||
// policy uses the UNIQUE flag. Nodes marked as used are not used in subsequent
|
||||
// base selections.
|
||||
usedNodes map[uint64]bool
|
||||
|
||||
// If true, returns an error when netmap does not contain enough nodes for selection.
|
||||
// By default best effort is taken.
|
||||
strict bool
|
||||
}
|
||||
|
||||
// Various validation errors.
|
||||
|
|
|
@ -2,7 +2,6 @@ package netmap
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -48,8 +47,7 @@ func TestPlacementPolicy_Interopability(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
for i := range ds {
|
||||
filename := filepath.Join(testsDir, ds[i].Name())
|
||||
bs, err := os.ReadFile(filename)
|
||||
bs, err := os.ReadFile(filepath.Join(testsDir, ds[i].Name()))
|
||||
require.NoError(t, err)
|
||||
|
||||
var tc TestCase
|
||||
|
@ -58,7 +56,7 @@ func TestPlacementPolicy_Interopability(t *testing.T) {
|
|||
srcNodes := make([]NodeInfo, len(tc.Nodes))
|
||||
copy(srcNodes, tc.Nodes)
|
||||
|
||||
t.Run(fmt.Sprintf("%s:%s", filename, tc.Name), func(t *testing.T) {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
var nm NetMap
|
||||
nm.SetNodes(tc.Nodes)
|
||||
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
{
|
||||
"name": "non-strict selections",
|
||||
"comment": "These test specify loose selection behaviour, to allow fetching already PUT objects even when there is not enough nodes to select from.",
|
||||
"nodes": [
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"key": "Country",
|
||||
"value": "Russia"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"key": "Country",
|
||||
"value": "Germany"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"attributes": [ ]
|
||||
}
|
||||
],
|
||||
"tests": {
|
||||
"not enough nodes (backup factor)": {
|
||||
"policy": {
|
||||
"replicas": [
|
||||
{
|
||||
"count": 1,
|
||||
"selector": "MyStore"
|
||||
}
|
||||
],
|
||||
"containerBackupFactor": 2,
|
||||
"selectors": [
|
||||
{
|
||||
"name": "MyStore",
|
||||
"count": 2,
|
||||
"clause": "DISTINCT",
|
||||
"attribute": "Country",
|
||||
"filter": "FromRU"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "FromRU",
|
||||
"key": "Country",
|
||||
"op": "EQ",
|
||||
"value": "Russia",
|
||||
"filters": [ ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": [
|
||||
[
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"not enough nodes (buckets)": {
|
||||
"policy": {
|
||||
"replicas": [
|
||||
{
|
||||
"count": 1,
|
||||
"selector": "MyStore"
|
||||
}
|
||||
],
|
||||
"containerBackupFactor": 1,
|
||||
"selectors": [
|
||||
{
|
||||
"name": "MyStore",
|
||||
"count": 2,
|
||||
"clause": "DISTINCT",
|
||||
"attribute": "Country",
|
||||
"filter": "FromRU"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "FromRU",
|
||||
"key": "Country",
|
||||
"op": "EQ",
|
||||
"value": "Russia",
|
||||
"filters": [ ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": [
|
||||
[
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -104,14 +104,7 @@
|
|||
"selectors": [],
|
||||
"filters": []
|
||||
},
|
||||
"result": [
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
]
|
||||
"error": "not enough nodes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,7 @@
|
|||
"tests": {
|
||||
"missing filter": {
|
||||
"policy": {
|
||||
"replicas": [
|
||||
{
|
||||
"count": 1,
|
||||
"selector": "MyStore"
|
||||
}
|
||||
],
|
||||
"replicas": [],
|
||||
"containerBackupFactor": 1,
|
||||
"selectors": [
|
||||
{
|
||||
|
@ -52,14 +47,9 @@
|
|||
},
|
||||
"error": "filter not found"
|
||||
},
|
||||
"not enough nodes (filter results in empty set)": {
|
||||
"not enough nodes (backup factor)": {
|
||||
"policy": {
|
||||
"replicas": [
|
||||
{
|
||||
"count": 1,
|
||||
"selector": "MyStore"
|
||||
}
|
||||
],
|
||||
"replicas": [],
|
||||
"containerBackupFactor": 2,
|
||||
"selectors": [
|
||||
{
|
||||
|
@ -67,15 +57,40 @@
|
|||
"count": 2,
|
||||
"clause": "DISTINCT",
|
||||
"attribute": "Country",
|
||||
"filter": "FromMoon"
|
||||
"filter": "FromRU"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "FromMoon",
|
||||
"name": "FromRU",
|
||||
"key": "Country",
|
||||
"op": "EQ",
|
||||
"value": "Moon",
|
||||
"value": "Russia",
|
||||
"filters": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"error": "not enough nodes"
|
||||
},
|
||||
"not enough nodes (buckets)": {
|
||||
"policy": {
|
||||
"replicas": [],
|
||||
"containerBackupFactor": 1,
|
||||
"selectors": [
|
||||
{
|
||||
"name": "MyStore",
|
||||
"count": 2,
|
||||
"clause": "DISTINCT",
|
||||
"attribute": "Country",
|
||||
"filter": "FromRU"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "FromRU",
|
||||
"key": "Country",
|
||||
"op": "EQ",
|
||||
"value": "Russia",
|
||||
"filters": []
|
||||
}
|
||||
]
|
||||
|
|
|
@ -238,7 +238,7 @@ func (m NetMap) ContainerNodes(p PlacementPolicy, pivot []byte) ([][]NodeInfo, e
|
|||
// marked as used by earlier replicas.
|
||||
for i := range p.replicas {
|
||||
sName := p.replicas[i].GetSelector()
|
||||
if sName == "" && !(len(p.replicas) == 1 && len(p.selectors) == 1) {
|
||||
if sName == "" {
|
||||
var s netmap.Selector
|
||||
s.SetCount(p.replicas[i].GetCount())
|
||||
s.SetFilter(mainFilterName)
|
||||
|
@ -258,9 +258,6 @@ func (m NetMap) ContainerNodes(p PlacementPolicy, pivot []byte) ([][]NodeInfo, e
|
|||
}
|
||||
|
||||
if p.unique {
|
||||
if c.processedSelectors[sName] == nil {
|
||||
return nil, fmt.Errorf("selector not found: '%s'", sName)
|
||||
}
|
||||
nodes, err := c.getSelection(*c.processedSelectors[sName])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
netmaptest "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
. "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
. "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
"git.frostfs.info/TrueCloudLab/hrw"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
)
|
||||
|
||||
// NodeInfo groups information about FrostFS storage node which is reflected
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/parser"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap/parser"
|
||||
"github.com/antlr4-go/antlr/v4"
|
||||
)
|
||||
|
||||
|
@ -551,7 +551,7 @@ func (p *PlacementPolicy) DecodeString(s string) error {
|
|||
return errors.New("parsed nil value")
|
||||
}
|
||||
|
||||
if err := validatePolicy(*parsed); err != nil {
|
||||
if err := validatePolicy(*p); err != nil {
|
||||
return fmt.Errorf("invalid policy: %w", err)
|
||||
}
|
||||
|
||||
|
@ -605,13 +605,6 @@ var (
|
|||
errUnknownSelector = errors.New("policy: selector not found")
|
||||
// errSyntaxError is returned for errors found by ANTLR parser.
|
||||
errSyntaxError = errors.New("policy: syntax error")
|
||||
// errRedundantSelector is returned for errors found by selectors policy validator.
|
||||
errRedundantSelector = errors.New("policy: found redundant selector")
|
||||
// errUnnamedSelector is returned for errors found by selectors policy validator.
|
||||
errUnnamedSelector = errors.New("policy: unnamed selectors are useless, " +
|
||||
"make sure to pair REP and SELECT clauses: \"REP .. IN X\" + \"SELECT ... AS X\"")
|
||||
// errRedundantSelector is returned for errors found by filters policy validator.
|
||||
errRedundantFilter = errors.New("policy: found redundant filter")
|
||||
)
|
||||
|
||||
type policyVisitor struct {
|
||||
|
@ -852,52 +845,25 @@ func (p *policyVisitor) VisitExpr(ctx *parser.ExprContext) any {
|
|||
// validatePolicy checks high-level constraints such as filter link in SELECT
|
||||
// being actually defined in FILTER section.
|
||||
func validatePolicy(p PlacementPolicy) error {
|
||||
canOmitNames := len(p.selectors) == 1 && len(p.replicas) == 1
|
||||
seenFilters := map[string]bool{}
|
||||
expectedFilters := map[string]struct{}{}
|
||||
|
||||
for i := range p.filters {
|
||||
seenFilters[p.filters[i].GetName()] = true
|
||||
for _, f := range p.filters[i].GetFilters() {
|
||||
if f.GetName() != "" {
|
||||
expectedFilters[f.GetName()] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
seenSelectors := map[string]*netmap.Selector{}
|
||||
seenSelectors := map[string]bool{}
|
||||
|
||||
for i := range p.selectors {
|
||||
if p.selectors[i].GetName() == "" && !canOmitNames {
|
||||
return errUnnamedSelector
|
||||
if flt := p.selectors[i].GetFilter(); flt != mainFilterName && !seenFilters[flt] {
|
||||
return fmt.Errorf("%w: '%s'", errUnknownFilter, flt)
|
||||
}
|
||||
if flt := p.selectors[i].GetFilter(); flt != mainFilterName {
|
||||
expectedFilters[flt] = struct{}{}
|
||||
if !seenFilters[flt] {
|
||||
return fmt.Errorf("%w: '%s'", errUnknownFilter, flt)
|
||||
}
|
||||
}
|
||||
seenSelectors[p.selectors[i].GetName()] = &p.selectors[i]
|
||||
|
||||
seenSelectors[p.selectors[i].GetName()] = true
|
||||
}
|
||||
|
||||
for _, f := range p.filters {
|
||||
if _, ok := expectedFilters[f.GetName()]; !ok {
|
||||
return fmt.Errorf("%w: '%s'", errRedundantFilter, f.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
expectedSelectors := map[string]struct{}{}
|
||||
for i := range p.replicas {
|
||||
selName := p.replicas[i].GetSelector()
|
||||
if selName != "" || canOmitNames {
|
||||
expectedSelectors[selName] = struct{}{}
|
||||
if seenSelectors[selName] == nil {
|
||||
return fmt.Errorf("%w: '%s'", errUnknownSelector, selName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range p.selectors {
|
||||
if _, ok := expectedSelectors[s.GetName()]; !ok {
|
||||
return fmt.Errorf("%w: to use selector '%s' use keyword IN", errRedundantSelector, s.GetName())
|
||||
if sel := p.replicas[i].GetSelector(); sel != "" && !seenSelectors[sel] {
|
||||
return fmt.Errorf("%w: '%s'", errUnknownSelector, sel)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDecodeString(t *testing.T) {
|
||||
testCases := []string{
|
||||
`REP 2
|
||||
CBF 2
|
||||
SELECT 2 FROM *`,
|
||||
`REP 1 IN X
|
||||
CBF 1
|
||||
SELECT 2 IN SAME Location FROM * AS X`,
|
||||
|
||||
`REP 1 IN X
|
||||
REP 2 IN Y
|
||||
CBF 1
|
||||
SELECT 2 FROM * AS X
|
||||
SELECT 3 FROM * AS Y`,
|
||||
|
||||
`REP 1 IN X
|
||||
SELECT 2 IN City FROM Good AS X
|
||||
FILTER Country EQ RU AS FromRU
|
||||
FILTER Country EQ EN AS FromEN
|
||||
FILTER @FromRU AND @FromEN AND Rating GT 7 AS Good`,
|
||||
|
||||
`REP 7 IN SPB
|
||||
SELECT 1 IN City FROM SPBSSD AS SPB
|
||||
FILTER City EQ SPB AND SSD EQ true OR City EQ SPB AND Rating GE 5 AS SPBSSD`,
|
||||
|
||||
`REP 7 IN SPB
|
||||
SELECT 1 IN City FROM SPBSSD AS SPB
|
||||
FILTER NOT (NOT (City EQ SPB) AND SSD EQ true OR City EQ SPB AND Rating GE 5) AS SPBSSD`,
|
||||
|
||||
`UNIQUE
|
||||
REP 1
|
||||
REP 1`,
|
||||
}
|
||||
|
||||
var p PlacementPolicy
|
||||
|
||||
for _, testCase := range testCases {
|
||||
require.NoError(t, p.DecodeString(testCase), "unable parse %s", testCase)
|
||||
var b strings.Builder
|
||||
require.NoError(t, p.WriteStringTo(&b))
|
||||
require.Equal(t, testCase, b.String())
|
||||
}
|
||||
|
||||
invalidTestCases := map[string]error{
|
||||
`?REP 1`: errSyntaxError,
|
||||
`REP 1 trailing garbage`: errSyntaxError,
|
||||
`REP 1 REP 1 SELECT 4 FROM *`: errUnnamedSelector,
|
||||
`REP 1 SELECT 4 FROM * SELECT 1 FROM *`: errUnnamedSelector,
|
||||
`REP 1 IN X SELECT 4 FROM *`: errUnknownSelector,
|
||||
`REP 1 IN X REP 2 SELECT 4 FROM * AS X FILTER 'UN-LOCODE' EQ 'RU LED' AS F`: errRedundantFilter,
|
||||
}
|
||||
|
||||
for i := range invalidTestCases {
|
||||
require.ErrorIs(t, p.DecodeString(i), invalidTestCases[i], "#%s", i)
|
||||
}
|
||||
}
|
|
@ -1,13 +1,63 @@
|
|||
package netmap_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
|
||||
. "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
netmaptest "git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
testCases := []string{
|
||||
`REP 1 IN X
|
||||
CBF 1
|
||||
SELECT 2 IN SAME Location FROM * AS X`,
|
||||
|
||||
`REP 1
|
||||
SELECT 2 IN City FROM Good
|
||||
FILTER Country EQ RU AS FromRU
|
||||
FILTER @FromRU AND Rating GT 7 AS Good`,
|
||||
|
||||
`REP 7 IN SPB
|
||||
SELECT 1 IN City FROM SPBSSD AS SPB
|
||||
FILTER City EQ SPB AND SSD EQ true OR City EQ SPB AND Rating GE 5 AS SPBSSD`,
|
||||
|
||||
`REP 7 IN SPB
|
||||
SELECT 1 IN City FROM SPBSSD AS SPB
|
||||
FILTER NOT (NOT (City EQ SPB) AND SSD EQ true OR City EQ SPB AND Rating GE 5) AS SPBSSD`,
|
||||
|
||||
`UNIQUE
|
||||
REP 1
|
||||
REP 1`,
|
||||
|
||||
`REP 1 IN X
|
||||
SELECT 1 FROM F AS X
|
||||
FILTER 'UN-LOCODE' EQ 'RU LED' AS F`,
|
||||
}
|
||||
|
||||
var p PlacementPolicy
|
||||
|
||||
for _, testCase := range testCases {
|
||||
require.NoError(t, p.DecodeString(testCase))
|
||||
|
||||
var b strings.Builder
|
||||
require.NoError(t, p.WriteStringTo(&b))
|
||||
|
||||
require.Equal(t, testCase, b.String())
|
||||
}
|
||||
|
||||
invalidTestCases := []string{
|
||||
`?REP 1`,
|
||||
`REP 1 trailing garbage`,
|
||||
}
|
||||
|
||||
for i := range invalidTestCases {
|
||||
require.Error(t, p.DecodeString(invalidTestCases[i]), "#%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlacementPolicyEncoding(t *testing.T) {
|
||||
v := netmaptest.PlacementPolicy()
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ func (c *context) getSelection(s netmap.Selector) ([]nodes, error) {
|
|||
bucketCount, nodesInBucket := calcNodesCount(s)
|
||||
buckets := c.getSelectionBase(s)
|
||||
|
||||
if c.strict && len(buckets) < bucketCount {
|
||||
if len(buckets) < bucketCount {
|
||||
return nil, fmt.Errorf("%w: '%s'", errNotEnoughNodes, s.GetName())
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ func (c *context) getSelection(s netmap.Selector) ([]nodes, error) {
|
|||
if len(res) < bucketCount {
|
||||
// Fallback to using minimum allowed backup factor (1).
|
||||
res = append(res, fallback...)
|
||||
if c.strict && len(res) < bucketCount {
|
||||
if len(res) < bucketCount {
|
||||
return nil, fmt.Errorf("%w: '%s'", errNotEnoughNodes, s.GetName())
|
||||
}
|
||||
}
|
||||
|
@ -110,13 +110,6 @@ func (c *context) getSelection(s netmap.Selector) ([]nodes, error) {
|
|||
hrw.SortHasherSliceByWeightValue(res, weights, c.hrwSeedHash)
|
||||
}
|
||||
|
||||
if len(res) < bucketCount {
|
||||
if len(res) == 0 {
|
||||
return nil, errNotEnoughNodes
|
||||
}
|
||||
bucketCount = len(res)
|
||||
}
|
||||
|
||||
if s.GetAttribute() == "" {
|
||||
res, fallback = res[:bucketCount], res[bucketCount:]
|
||||
for i := range fallback {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
mrand "math/rand"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
@ -29,10 +28,10 @@ func BenchmarkHRWSort(b *testing.B) {
|
|||
node.SetPublicKey(key)
|
||||
|
||||
vectors[i] = nodes{node}
|
||||
weights[i] = float64(mrand.Uint32()%10) / 10.0
|
||||
weights[i] = float64(rand.Uint32()%10) / 10.0
|
||||
}
|
||||
|
||||
pivot := mrand.Uint64()
|
||||
pivot := rand.Uint64()
|
||||
b.Run("sort by index, no weight", func(b *testing.B) {
|
||||
realNodes := make([]nodes, netmapSize)
|
||||
b.ResetTimer()
|
||||
|
@ -283,55 +282,6 @@ func TestPlacementPolicy_Unique(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPlacementPolicy_SingleOmitNames(t *testing.T) {
|
||||
nodes := []NodeInfo{
|
||||
nodeInfoFromAttributes("ID", "1", "Country", "Russia", "City", "SPB"),
|
||||
nodeInfoFromAttributes("ID", "2", "Country", "Germany", "City", "Berlin"),
|
||||
nodeInfoFromAttributes("ID", "3", "Country", "Russia", "City", "Moscow"),
|
||||
nodeInfoFromAttributes("ID", "4", "Country", "France", "City", "Paris"),
|
||||
nodeInfoFromAttributes("ID", "5", "Country", "France", "City", "Lyon"),
|
||||
nodeInfoFromAttributes("ID", "6", "Country", "Russia", "City", "SPB"),
|
||||
nodeInfoFromAttributes("ID", "7", "Country", "Russia", "City", "Moscow"),
|
||||
nodeInfoFromAttributes("ID", "8", "Country", "Germany", "City", "Darmstadt"),
|
||||
nodeInfoFromAttributes("ID", "9", "Country", "Germany", "City", "Frankfurt"),
|
||||
nodeInfoFromAttributes("ID", "10", "Country", "Russia", "City", "SPB"),
|
||||
nodeInfoFromAttributes("ID", "11", "Country", "Russia", "City", "Moscow"),
|
||||
nodeInfoFromAttributes("ID", "12", "Country", "Germany", "City", "London"),
|
||||
}
|
||||
for i := range nodes {
|
||||
pub := make([]byte, 33)
|
||||
rand.Read(pub)
|
||||
nodes[i].SetPublicKey(pub)
|
||||
}
|
||||
|
||||
var nm NetMap
|
||||
nm.SetNodes(nodes)
|
||||
|
||||
for _, unique := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("unique=%t", unique), func(t *testing.T) {
|
||||
ssNamed := []Selector{newSelector("X", "City", 2, "FromRU", (*Selector).SelectDistinct)}
|
||||
fsNamed := []Filter{newFilter("FromRU", "Country", "Russia", netmap.EQ)}
|
||||
rsNamed := []ReplicaDescriptor{newReplica(1, "X")}
|
||||
pNamed := newPlacementPolicy(3, rsNamed, ssNamed, fsNamed)
|
||||
pNamed.unique = unique
|
||||
|
||||
vNamed, err := nm.ContainerNodes(pNamed, []byte{1})
|
||||
require.NoError(t, err)
|
||||
|
||||
ssUnnamed := []Selector{newSelector("", "City", 2, "FromRU", (*Selector).SelectDistinct)}
|
||||
fsUnnamed := []Filter{newFilter("FromRU", "Country", "Russia", netmap.EQ)}
|
||||
rsUnnamed := []ReplicaDescriptor{newReplica(1, "")}
|
||||
pUnnamed := newPlacementPolicy(3, rsUnnamed, ssUnnamed, fsUnnamed)
|
||||
pUnnamed.unique = unique
|
||||
|
||||
vUnnamed, err := nm.ContainerNodes(pUnnamed, []byte{1})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, vNamed, vUnnamed)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlacementPolicy_MultiREP(t *testing.T) {
|
||||
nodes := []NodeInfo{
|
||||
nodeInfoFromAttributes("ID", "1", "Country", "Russia", "City", "SPB"),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package netmaptest
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/rand"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
func filter(withInner bool) (x netmap.Filter) {
|
||||
|
@ -70,7 +70,7 @@ func NetworkInfo() (x netmap.NetworkInfo) {
|
|||
// NodeInfo returns random netmap.NodeInfo.
|
||||
func NodeInfo() (x netmap.NodeInfo) {
|
||||
key := make([]byte, 33)
|
||||
_, _ = rand.Read(key)
|
||||
rand.Read(key)
|
||||
|
||||
x.SetPublicKey(key)
|
||||
x.SetNetworkEndpoints("1", "2", "3")
|
||||
|
|
|
@ -3,7 +3,7 @@ package ns
|
|||
import (
|
||||
"net"
|
||||
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// DNS looks up FrostFS names using system DNS.
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"net/url"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package ns
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/container"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ import (
|
|||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/checksum"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cid "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// Address represents global object identifier in FrostFS network. Each object
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
oidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
frostfscrypto "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/mbiryukova/frostfs-sdk-go/crypto/ecdsa"
|
||||
"github.com/mr-tron/base58"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ Note that importing the package into source files is highly discouraged.
|
|||
|
||||
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||
|
||||
import oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||
import oidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id/test"
|
||||
|
||||
value := oidtest.ID()
|
||||
// test the value
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package oidtest
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"math/rand"
|
||||
|
||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
cidtest "git.frostfs.info/mbiryukova/frostfs-sdk-go/container/id/test"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
// ID returns random oid.ID.
|
||||
func ID() oid.ID {
|
||||
checksum := [sha256.Size]byte{}
|
||||
|
||||
_, _ = rand.Read(checksum[:])
|
||||
rand.Read(checksum[:])
|
||||
|
||||
return idWithChecksum(checksum)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package object
|
|||
import (
|
||||
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
oid "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
// Lock represents record with locked objects. It is compatible with
|
||||
|
|
|
@ -3,8 +3,8 @@ package object_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
objecttest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/test"
|
||||
"git.frostfs.info/mbiryukova/frostfs-sdk-go/object"
|
||||
objecttest "git.frostfs.info/mbiryukova/frostfs-sdk-go/object/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|