storj/pkg/overlay/client.go
Cameron f5c115596e filter out excluded nodes when repairing (#426)
* add filter field into OverlayOptions message

* chooseFiltered method, add excluded parameter in populate method

* change excluded type to []dht.NodeID in ChooseFiltered, change comment

* change name filter to excluded_nodes in proto

* implement helper function contains

* delete ChooseFiltered and add its functionality into Choose method to keep original author's history, add excluded argument into Choose calls

* regenerate mock_client.go

* regenerate protobuf

* update test case to use new IDFromString function

* remove old kademlia test code
2018-10-15 13:42:36 -04:00

114 lines
3.0 KiB
Go

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package overlay
import (
"context"
"github.com/zeebo/errs"
"storj.io/storj/pkg/dht"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/provider"
)
// Client is the interface that defines an overlay client.
//
// Choose returns a list of storage NodeID's that fit the provided criteria.
// limit is the maximum number of nodes to be returned.
// space is the storage and bandwidth requested consumption in bytes.
//
// Lookup finds a Node with the provided identifier.
// ClientError creates class of errors for stack traces
var ClientError = errs.Class("Client Error")
//Client implements the Overlay Client interface
type Client interface {
Choose(ctx context.Context, op Options) ([]*pb.Node, error)
Lookup(ctx context.Context, nodeID dht.NodeID) (*pb.Node, error)
BulkLookup(ctx context.Context, nodeIDs []dht.NodeID) ([]*pb.Node, error)
}
// Overlay is the overlay concrete implementation of the client interface
type Overlay struct {
client pb.OverlayClient
}
// Options contains parameters for selecting nodes
type Options struct {
Amount int
Space int64
Excluded []dht.NodeID
}
// NewOverlayClient returns a new intialized Overlay Client
func NewOverlayClient(identity *provider.FullIdentity, address string) (*Overlay, error) {
dialOpt, err := identity.DialOption()
if err != nil {
return nil, err
}
c, err := NewClient(address, dialOpt)
if err != nil {
return nil, err
}
return &Overlay{
client: c,
}, nil
}
// a compiler trick to make sure *Overlay implements Client
var _ Client = (*Overlay)(nil)
// Choose implements the client.Choose interface
func (o *Overlay) Choose(ctx context.Context, op Options) ([]*pb.Node, error) {
var exIDs []string
for _, id := range op.Excluded {
exIDs = append(exIDs, id.String())
}
// TODO(coyle): We will also need to communicate with the reputation service here
resp, err := o.client.FindStorageNodes(ctx, &pb.FindStorageNodesRequest{
Opts: &pb.OverlayOptions{
Amount: int64(op.Amount),
Restrictions: &pb.NodeRestrictions{FreeDisk: op.Space},
ExcludedNodes: exIDs,
},
})
if err != nil {
return nil, Error.Wrap(err)
}
return resp.GetNodes(), nil
}
// Lookup provides a Node with the given ID
func (o *Overlay) Lookup(ctx context.Context, nodeID dht.NodeID) (*pb.Node, error) {
resp, err := o.client.Lookup(ctx, &pb.LookupRequest{NodeID: nodeID.String()})
if err != nil {
return nil, err
}
return resp.GetNode(), nil
}
//BulkLookup provides a list of Nodes with the given IDs
func (o *Overlay) BulkLookup(ctx context.Context, nodeIDs []dht.NodeID) ([]*pb.Node, error) {
var reqs pb.LookupRequests
for _, v := range nodeIDs {
reqs.Lookuprequest = append(reqs.Lookuprequest, &pb.LookupRequest{NodeID: v.String()})
}
resp, err := o.client.BulkLookup(ctx, &reqs)
if err != nil {
return nil, ClientError.Wrap(err)
}
var nodes []*pb.Node
for _, v := range resp.Lookupresponse {
nodes = append(nodes, v.Node)
}
return nodes, nil
}