Skip to content

Commit

Permalink
feat(list): add pagination to list funcs
Browse files Browse the repository at this point in the history
Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
  • Loading branch information
glimchb committed Sep 7, 2023
1 parent 91f7ae7 commit 71379e5
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 13 deletions.
13 changes: 12 additions & 1 deletion pkg/evpn/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,25 @@ func (s *Server) ListLogicalBridges(_ context.Context, in *pb.ListLogicalBridges
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
size, offset, perr := extractPagination(in.PageSize, in.PageToken, s.Pagination)
if perr != nil {
log.Printf("error: %v", perr)
return nil, perr
}
token := ""
log.Printf("Limiting result len(%d) to [%d:%d]", len(s.Bridges), offset, size)
// result, hasMoreElements := limitPagination(s.Bridges, offset, size)
// if hasMoreElements {
// token = uuid.New().String()
// s.Pagination[token] = offset + size
// }
Blobarray := []*pb.LogicalBridge{}
for _, bridge := range s.Bridges {
r := protoClone(bridge)
r.Status = &pb.LogicalBridgeStatus{OperStatus: pb.LBOperStatus_LB_OPER_STATUS_UP}
Blobarray = append(Blobarray, r)
}
// TODO: Limit results to offset and size and rememeber pagination
sortLogicalBridges(Blobarray)
return &pb.ListLogicalBridgesResponse{LogicalBridges: Blobarray, NextPageToken: token}, nil
}
16 changes: 16 additions & 0 deletions pkg/evpn/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,22 @@ func Test_ListLogicalBridges(t *testing.T) {
size: 0,
token: "",
},
"pagination negative": {
in: "",
out: nil,
errCode: codes.InvalidArgument,
errMsg: "negative PageSize is not allowed",
size: -10,
token: "",
},
"pagination error": {
in: "",
out: nil,
errCode: codes.NotFound,
errMsg: fmt.Sprintf("unable to find pagination token %s", "unknown-pagination-token"),
size: 0,
token: "unknown-pagination-token",
},
}

// run tests
Expand Down
63 changes: 53 additions & 10 deletions pkg/evpn/evpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"fmt"
"log"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"

pe "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go"
Expand All @@ -27,11 +29,12 @@ type Server struct {
pe.UnimplementedSviServiceServer
pe.UnimplementedLogicalBridgeServiceServer
pe.UnimplementedBridgePortServiceServer
Bridges map[string]*pe.LogicalBridge
Ports map[string]*pe.BridgePort
Svis map[string]*pe.Svi
Vrfs map[string]*pe.Vrf
nLink utils.Netlink
Bridges map[string]*pe.LogicalBridge
Ports map[string]*pe.BridgePort
Svis map[string]*pe.Svi
Vrfs map[string]*pe.Vrf
Pagination map[string]int
nLink utils.Netlink
}

// NewServer creates initialized instance of EVPN server
Expand All @@ -47,11 +50,12 @@ func NewServerWithArgs(nLink utils.Netlink) *Server {
log.Panic("nil for Netlink is not allowed")
}
return &Server{
Bridges: make(map[string]*pe.LogicalBridge),
Ports: make(map[string]*pe.BridgePort),
Svis: make(map[string]*pe.Svi),
Vrfs: make(map[string]*pe.Vrf),
nLink: nLink,
Bridges: make(map[string]*pe.LogicalBridge),
Ports: make(map[string]*pe.BridgePort),
Svis: make(map[string]*pe.Svi),
Vrfs: make(map[string]*pe.Vrf),
Pagination: make(map[string]int),
nLink: nLink,
}
}

Expand All @@ -74,3 +78,42 @@ func generateRandMAC() ([]byte, error) {

return buf, nil
}

func extractPagination(pageSize int32, pageToken string, pagination map[string]int) (size int, offset int, err error) {
const (
maxPageSize = 250
defaultPageSize = 50
)
switch {
case pageSize < 0:
return -1, -1, status.Error(codes.InvalidArgument, "negative PageSize is not allowed")
case pageSize == 0:
size = defaultPageSize
case pageSize > maxPageSize:
size = maxPageSize
default:
size = int(pageSize)
}
// fetch offset from the database using opaque token
offset = 0
if pageToken != "" {
var ok bool
offset, ok = pagination[pageToken]
if !ok {
return -1, -1, status.Errorf(codes.NotFound, "unable to find pagination token %s", pageToken)
}
log.Printf("Found offset %d from pagination token: %s", offset, pageToken)
}
return size, offset, nil
}

// func limitPagination[T any](result []T, offset int, size int) ([]T, bool) {
// end := offset + size
// hasMoreElements := false
// if end < len(result) {
// hasMoreElements = true
// } else {
// end = len(result)
// }
// return result[offset:end], hasMoreElements
// }
13 changes: 12 additions & 1 deletion pkg/evpn/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,25 @@ func (s *Server) ListBridgePorts(_ context.Context, in *pb.ListBridgePortsReques
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
size, offset, perr := extractPagination(in.PageSize, in.PageToken, s.Pagination)
if perr != nil {
log.Printf("error: %v", perr)
return nil, perr
}
token := ""
log.Printf("Limiting result len(%d) to [%d:%d]", len(s.Ports), offset, size)
// result, hasMoreElements := limitPagination(s.Ports, offset, size)
// if hasMoreElements {
// token = uuid.New().String()
// s.Pagination[token] = offset + size
// }
Blobarray := []*pb.BridgePort{}
for _, port := range s.Ports {
r := protoClone(port)
r.Status = &pb.BridgePortStatus{OperStatus: pb.BPOperStatus_BP_OPER_STATUS_UP}
Blobarray = append(Blobarray, r)
}
// TODO: Limit results to offset and size and rememeber pagination
sortBridgePorts(Blobarray)
return &pb.ListBridgePortsResponse{BridgePorts: Blobarray, NextPageToken: token}, nil
}
16 changes: 16 additions & 0 deletions pkg/evpn/port_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,22 @@ func Test_ListBridgePorts(t *testing.T) {
size: 0,
token: "",
},
"pagination negative": {
in: "",
out: nil,
errCode: codes.InvalidArgument,
errMsg: "negative PageSize is not allowed",
size: -10,
token: "",
},
"pagination error": {
in: "",
out: nil,
errCode: codes.NotFound,
errMsg: fmt.Sprintf("unable to find pagination token %s", "unknown-pagination-token"),
size: 0,
token: "unknown-pagination-token",
},
}

// run tests
Expand Down
13 changes: 12 additions & 1 deletion pkg/evpn/svi.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,25 @@ func (s *Server) ListSvis(_ context.Context, in *pb.ListSvisRequest) (*pb.ListSv
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
size, offset, perr := extractPagination(in.PageSize, in.PageToken, s.Pagination)
if perr != nil {
log.Printf("error: %v", perr)
return nil, perr
}
token := ""
log.Printf("Limiting result len(%d) to [%d:%d]", len(s.Svis), offset, size)
// result, hasMoreElements := limitPagination(s.Svis, offset, size)
// if hasMoreElements {
// token = uuid.New().String()
// s.Pagination[token] = offset + size
// }
Blobarray := []*pb.Svi{}
for _, svi := range s.Svis {
r := protoClone(svi)
r.Status = &pb.SviStatus{OperStatus: pb.SVIOperStatus_SVI_OPER_STATUS_UP}
Blobarray = append(Blobarray, r)
}
// TODO: Limit results to offset and size and rememeber pagination
sortSvis(Blobarray)
return &pb.ListSvisResponse{Svis: Blobarray, NextPageToken: token}, nil
}
16 changes: 16 additions & 0 deletions pkg/evpn/svi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,22 @@ func Test_ListSvis(t *testing.T) {
size: 0,
token: "",
},
"pagination negative": {
in: "",
out: nil,
errCode: codes.InvalidArgument,
errMsg: "negative PageSize is not allowed",
size: -10,
token: "",
},
"pagination error": {
in: "",
out: nil,
errCode: codes.NotFound,
errMsg: fmt.Sprintf("unable to find pagination token %s", "unknown-pagination-token"),
size: 0,
token: "unknown-pagination-token",
},
}

// run tests
Expand Down
12 changes: 12 additions & 0 deletions pkg/evpn/vrf.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,19 @@ func (s *Server) ListVrfs(_ context.Context, in *pb.ListVrfsRequest) (*pb.ListVr
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
size, offset, perr := extractPagination(in.PageSize, in.PageToken, s.Pagination)
if perr != nil {
log.Printf("error: %v", perr)
return nil, perr
}
token := ""
log.Printf("Limiting result len(%d) to [%d:%d]", len(s.Vrfs), offset, size)
// result, hasMoreElements := limitPagination(s.Vrfs, offset, size)
// if hasMoreElements {
// token = uuid.New().String()
// s.Pagination[token] = offset + size
// }
Blobarray := []*pb.Vrf{}
for _, vrf := range s.Vrfs {
r := protoClone(vrf)
Expand Down
16 changes: 16 additions & 0 deletions pkg/evpn/vrf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,22 @@ func Test_ListVrfs(t *testing.T) {
size: 0,
token: "",
},
"pagination negative": {
in: "",
out: nil,
errCode: codes.InvalidArgument,
errMsg: "negative PageSize is not allowed",
size: -10,
token: "",
},
"pagination error": {
in: "",
out: nil,
errCode: codes.NotFound,
errMsg: fmt.Sprintf("unable to find pagination token %s", "unknown-pagination-token"),
size: 0,
token: "unknown-pagination-token",
},
}

// run tests
Expand Down

0 comments on commit 71379e5

Please sign in to comment.