Skip to content

Commit

Permalink
feat(list): add more pagination limits to list funcs
Browse files Browse the repository at this point in the history
Signed-off-by: Boris Glimcher <[email protected]>
  • Loading branch information
glimchb committed Sep 7, 2023
1 parent 71379e5 commit 6b042bb
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 43 deletions.
19 changes: 11 additions & 8 deletions pkg/evpn/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net"
"sort"

"github.com/google/uuid"
"github.com/vishvananda/netlink"

pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go"
Expand Down Expand Up @@ -253,25 +254,27 @@ func (s *Server) ListLogicalBridges(_ context.Context, in *pb.ListLogicalBridges
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
// fetch pagination from the database, calculate size and offset
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
// }
// fetch object from the database
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)
}
// sort is needed, since MAP is unsorted in golang, and we might get different results
sortLogicalBridges(Blobarray)
log.Printf("Limiting result len(%d) to [%d:%d]", len(Blobarray), offset, size)
Blobarray, hasMoreElements := limitPagination(Blobarray, offset, size)
token := ""
if hasMoreElements {
token = uuid.New().String()
s.Pagination[token] = offset + size
}
return &pb.ListLogicalBridgesResponse{LogicalBridges: Blobarray, NextPageToken: token}, nil
}
25 changes: 25 additions & 0 deletions pkg/evpn/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,30 @@ func Test_ListLogicalBridges(t *testing.T) {
size: 0,
token: "unknown-pagination-token",
},
"pagination overflow": {
in: "",
out: []*pb.LogicalBridge{&testLogicalBridgeWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1000,
token: "",
},
"pagination normal": {
in: "",
out: []*pb.LogicalBridge{&testLogicalBridgeWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "",
},
"pagination offset": {
in: "",
out: []*pb.LogicalBridge{},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "existing-pagination-token",
},
}

// run tests
Expand All @@ -693,6 +717,7 @@ func Test_ListLogicalBridges(t *testing.T) {

opi.Bridges[testLogicalBridgeName] = protoClone(&testLogicalBridge)
opi.Bridges[testLogicalBridgeName].Name = testLogicalBridgeName
opi.Pagination["existing-pagination-token"] = 1

request := &pb.ListLogicalBridgesRequest{PageSize: tt.size, PageToken: tt.token}
response, err := client.ListLogicalBridges(ctx, request)
Expand Down
20 changes: 10 additions & 10 deletions pkg/evpn/evpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ func extractPagination(pageSize int32, pageToken string, pagination map[string]i
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
// }
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
}
21 changes: 13 additions & 8 deletions pkg/evpn/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"path"
"sort"

"github.com/google/uuid"
// "github.com/vishvananda/netlink"

pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go"
Expand Down Expand Up @@ -73,6 +74,8 @@ func (s *Server) CreateBridgePort(_ context.Context, in *pb.CreateBridgePortRequ
}
// get base interface (e.g.: eth2)
iface, err := s.nLink.LinkByName(resourceID)
// TODO: maybe we need to create a new iface here and not rely on existing one ?
// iface := &netlink.Dummy{LinkAttrs: netlink.LinkAttrs{Name: resourceID}}
if err != nil {
err := status.Errorf(codes.NotFound, "unable to find key %s", resourceID)
log.Printf("error: %v", err)
Expand Down Expand Up @@ -278,25 +281,27 @@ func (s *Server) ListBridgePorts(_ context.Context, in *pb.ListBridgePortsReques
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
// fetch pagination from the database, calculate size and offset
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
// }
// fetch object from the database
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)
}
// sort is needed, since MAP is unsorted in golang, and we might get different results
sortBridgePorts(Blobarray)
log.Printf("Limiting result len(%d) to [%d:%d]", len(Blobarray), offset, size)
Blobarray, hasMoreElements := limitPagination(Blobarray, offset, size)
token := ""
if hasMoreElements {
token = uuid.New().String()
s.Pagination[token] = offset + size
}
return &pb.ListBridgePortsResponse{BridgePorts: Blobarray, NextPageToken: token}, nil
}
25 changes: 25 additions & 0 deletions pkg/evpn/port_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,30 @@ func Test_ListBridgePorts(t *testing.T) {
size: 0,
token: "unknown-pagination-token",
},
"pagination overflow": {
in: "",
out: []*pb.BridgePort{&testBridgePortWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1000,
token: "",
},
"pagination normal": {
in: "",
out: []*pb.BridgePort{&testBridgePortWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "",
},
"pagination offset": {
in: "",
out: []*pb.BridgePort{},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "existing-pagination-token",
},
}

// run tests
Expand All @@ -726,6 +750,7 @@ func Test_ListBridgePorts(t *testing.T) {

opi.Ports[testBridgePortName] = protoClone(&testBridgePort)
opi.Ports[testBridgePortName].Name = testBridgePortName
opi.Pagination["existing-pagination-token"] = 1

request := &pb.ListBridgePortsRequest{PageSize: tt.size, PageToken: tt.token}
response, err := client.ListBridgePorts(ctx, request)
Expand Down
19 changes: 11 additions & 8 deletions pkg/evpn/svi.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"path"
"sort"

"github.com/google/uuid"
"github.com/vishvananda/netlink"

pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go"
Expand Down Expand Up @@ -311,25 +312,27 @@ func (s *Server) ListSvis(_ context.Context, in *pb.ListSvisRequest) (*pb.ListSv
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
// fetch pagination from the database, calculate size and offset
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
// }
// fetch object from the database
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)
}
// sort is needed, since MAP is unsorted in golang, and we might get different results
sortSvis(Blobarray)
log.Printf("Limiting result len(%d) to [%d:%d]", len(Blobarray), offset, size)
Blobarray, hasMoreElements := limitPagination(Blobarray, offset, size)
token := ""
if hasMoreElements {
token = uuid.New().String()
s.Pagination[token] = offset + size
}
return &pb.ListSvisResponse{Svis: Blobarray, NextPageToken: token}, nil
}
25 changes: 25 additions & 0 deletions pkg/evpn/svi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,30 @@ func Test_ListSvis(t *testing.T) {
size: 0,
token: "unknown-pagination-token",
},
"pagination overflow": {
in: "",
out: []*pb.Svi{&testSviWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1000,
token: "",
},
"pagination normal": {
in: "",
out: []*pb.Svi{&testSviWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "",
},
"pagination offset": {
in: "",
out: []*pb.Svi{},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "existing-pagination-token",
},
}

// run tests
Expand All @@ -852,6 +876,7 @@ func Test_ListSvis(t *testing.T) {

opi.Svis[testSviName] = protoClone(&testSvi)
opi.Svis[testSviName].Name = testSviName
opi.Pagination["existing-pagination-token"] = 1

request := &pb.ListSvisRequest{PageSize: tt.size, PageToken: tt.token}
response, err := client.ListSvis(ctx, request)
Expand Down
20 changes: 11 additions & 9 deletions pkg/evpn/vrf.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"path"
"sort"

"github.com/google/uuid"
"github.com/vishvananda/netlink"

pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go"
Expand Down Expand Up @@ -326,26 +327,27 @@ func (s *Server) ListVrfs(_ context.Context, in *pb.ListVrfsRequest) (*pb.ListVr
log.Printf("error: %v", err)
return nil, err
}
// fetch object from the database
// fetch pagination from the database, calculate size and offset
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
// }
// fetch object from the database
Blobarray := []*pb.Vrf{}
for _, vrf := range s.Vrfs {
r := protoClone(vrf)
r.Status = &pb.VrfStatus{LocalAs: 4}
Blobarray = append(Blobarray, r)
}
// TODO: fetch object from the database
// sort is needed, since MAP is unsorted in golang, and we might get different results
sortVrfs(Blobarray)
log.Printf("Limiting result len(%d) to [%d:%d]", len(Blobarray), offset, size)
Blobarray, hasMoreElements := limitPagination(Blobarray, offset, size)
token := ""
if hasMoreElements {
token = uuid.New().String()
s.Pagination[token] = offset + size
}
return &pb.ListVrfsResponse{Vrfs: Blobarray, NextPageToken: token}, nil
}
25 changes: 25 additions & 0 deletions pkg/evpn/vrf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,30 @@ func Test_ListVrfs(t *testing.T) {
size: 0,
token: "unknown-pagination-token",
},
"pagination overflow": {
in: "",
out: []*pb.Vrf{&testVrfWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1000,
token: "",
},
"pagination normal": {
in: "",
out: []*pb.Vrf{&testVrfWithStatus},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "",
},
"pagination offset": {
in: "",
out: []*pb.Vrf{},
errCode: codes.OK,
errMsg: "",
size: 1,
token: "existing-pagination-token",
},
}

// run tests
Expand All @@ -884,6 +908,7 @@ func Test_ListVrfs(t *testing.T) {

opi.Vrfs[testVrfName] = protoClone(&testVrf)
opi.Vrfs[testVrfName].Name = testVrfName
opi.Pagination["existing-pagination-token"] = 1

request := &pb.ListVrfsRequest{PageSize: tt.size, PageToken: tt.token}
response, err := client.ListVrfs(ctx, request)
Expand Down

0 comments on commit 6b042bb

Please sign in to comment.