Skip to content

Commit

Permalink
Pagination followups (#1189)
Browse files Browse the repository at this point in the history
* backend: validate page size

* backend: remove pagination on ListACLs

* backend: set default page size
  • Loading branch information
weeco authored Mar 22, 2024
1 parent 0ffd99c commit 2de65c5
Show file tree
Hide file tree
Showing 23 changed files with 1,984 additions and 1,893 deletions.
21 changes: 21 additions & 0 deletions backend/pkg/api/connect/service/kafkaconnect/defaulter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Redpanda Data, Inc.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.md
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0

package kafkaconnect

import v1alpha1 "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/dataplane/v1alpha1"

// Defaulter updates a given kafkaconnect request with defaults.
type defaulter struct{}

func (*defaulter) applyListConnectorsRequest(req *v1alpha1.ListConnectorsRequest) {
if req.GetPageSize() == 0 {
req.PageSize = 100
}
}
4 changes: 4 additions & 0 deletions backend/pkg/api/connect/service/kafkaconnect/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Service struct {
logger *zap.Logger
connectSvc *kafkaconnect.Service
mapper *mapper
defaulter defaulter
}

// NewService creates a new user service handler.
Expand All @@ -51,11 +52,14 @@ func NewService(cfg *config.Config,
logger: logger,
connectSvc: kafkaConnectSrv,
mapper: &mapper{},
defaulter: defaulter{},
}
}

// ListConnectors implements the handler for the list connectors operation.
func (s *Service) ListConnectors(ctx context.Context, req *connect.Request[v1alpha1.ListConnectorsRequest]) (*connect.Response[v1alpha1.ListConnectorsResponse], error) {
s.defaulter.applyListConnectorsRequest(req.Msg)

response, err := s.connectSvc.GetClusterConnectors(ctx, req.Msg.ClusterName)
if err != nil {
return nil, s.matchError(err)
Expand Down
21 changes: 21 additions & 0 deletions backend/pkg/api/connect/service/topic/defaulter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Redpanda Data, Inc.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.md
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0

package topic

import v1alpha1 "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/dataplane/v1alpha1"

// Defaulter updates a given Topic input request with defaults.
type defaulter struct{}

func (*defaulter) applyListTopicsRequest(req *v1alpha1.ListTopicsRequest) {
if req.GetPageSize() == 0 {
req.PageSize = 100
}
}
37 changes: 21 additions & 16 deletions backend/pkg/api/connect/service/topic/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ type Service struct {
logger *zap.Logger
consoleSvc console.Servicer
mapper kafkaClientMapper
defaulter defaulter
}

// ListTopics lists all Kafka topics with their most important metadata.
func (s *Service) ListTopics(ctx context.Context, req *connect.Request[v1alpha1.ListTopicsRequest]) (*connect.Response[v1alpha1.ListTopicsResponse], error) {
s.defaulter.applyListTopicsRequest(req.Msg)
kafkaReq := kmsg.NewMetadataRequest()
kafkaRes, err := s.consoleSvc.GetMetadata(ctx, &kafkaReq)
if err != nil {
Expand All @@ -66,26 +68,28 @@ func (s *Service) ListTopics(ctx context.Context, req *connect.Request[v1alpha1.
}

topics := s.mapper.kafkaMetadataToProto(kafkaRes)
if req.Msg.GetPageSize() == 0 {
return connect.NewResponse(&v1alpha1.ListTopicsResponse{Topics: topics, NextPageToken: ""}), nil
}

// Add pagination
sort.SliceStable(topics, func(i, j int) bool {
return topics[i].Name < topics[j].Name
})
page, nextPageToken, err := pagination.SliceToPaginatedWithToken(topics, int(req.Msg.PageSize), req.Msg.GetPageToken(), "name", func(x *v1alpha1.ListTopicsResponse_Topic) string {
return x.GetName()
})
if err != nil {
return nil, apierrors.NewConnectError(
connect.CodeInternal,
fmt.Errorf("failed to apply pagination: %w", err),
apierrors.NewErrorInfo(v1alpha1.Reason_REASON_CONSOLE_ERROR.String()),
)
var nextPageToken string
if req.Msg.GetPageSize() > 0 {
sort.SliceStable(topics, func(i, j int) bool {
return topics[i].Name < topics[j].Name
})
page, token, err := pagination.SliceToPaginatedWithToken(topics, int(req.Msg.PageSize), req.Msg.GetPageToken(), "name", func(x *v1alpha1.ListTopicsResponse_Topic) string {
return x.GetName()
})
if err != nil {
return nil, apierrors.NewConnectError(
connect.CodeInternal,
fmt.Errorf("failed to apply pagination: %w", err),
apierrors.NewErrorInfo(v1alpha1.Reason_REASON_CONSOLE_ERROR.String()),
)
}
topics = page
nextPageToken = token
}

return connect.NewResponse(&v1alpha1.ListTopicsResponse{Topics: page, NextPageToken: nextPageToken}), nil
return connect.NewResponse(&v1alpha1.ListTopicsResponse{Topics: topics, NextPageToken: nextPageToken}), nil
}

// DeleteTopic deletes a Kafka topic.
Expand Down Expand Up @@ -337,6 +341,7 @@ func NewService(cfg *config.Config,
logger: logger,
consoleSvc: consoleSvc,
mapper: kafkaClientMapper{},
defaulter: defaulter{},
}
}

Expand Down
21 changes: 21 additions & 0 deletions backend/pkg/api/connect/service/transform/defaulter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Redpanda Data, Inc.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.md
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0

package transform

import v1alpha1 "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/dataplane/v1alpha1"

// Defaulter updates a given transforms request with defaults.
type defaulter struct{}

func (*defaulter) applyListTransformsRequest(req *v1alpha1.ListTransformsRequest) {
if req.GetPageSize() == 0 {
req.PageSize = 100
}
}
4 changes: 4 additions & 0 deletions backend/pkg/api/connect/service/transform/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Service struct {
validator *protovalidate.Validator
mapper mapper
errorWriter *connect.ErrorWriter
defaulter defaulter
}

// NewService creates a new transform service handler.
Expand All @@ -55,6 +56,7 @@ func NewService(cfg *config.Config,
validator: protoValidator,
mapper: mapper{},
errorWriter: connect.NewErrorWriter(),
defaulter: defaulter{},
}
}

Expand All @@ -75,6 +77,8 @@ func (s *Service) ListTransforms(ctx context.Context, c *connect.Request[v1alpha
return nil, apierrors.NewRedpandaAdminAPINotConfiguredError()
}

s.defaulter.applyListTransformsRequest(c.Msg)

transforms, err := s.redpandaSvc.ListWasmTransforms(ctx)
if err != nil {
return nil, apierrors.NewConnectErrorFromRedpandaAdminAPIError(err, "")
Expand Down
21 changes: 21 additions & 0 deletions backend/pkg/api/connect/service/user/defaulter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Redpanda Data, Inc.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.md
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0

package user

import v1alpha1 "github.com/redpanda-data/console/backend/pkg/protogen/redpanda/api/dataplane/v1alpha1"

// Defaulter updates a given user request with defaults.
type defaulter struct{}

func (*defaulter) applyListUsersRequest(req *v1alpha1.ListUsersRequest) {
if req.GetPageSize() == 0 {
req.PageSize = 100
}
}
3 changes: 3 additions & 0 deletions backend/pkg/api/connect/service/user/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Service struct {
logger *zap.Logger
consoleSvc console.Servicer
redpandaSvc *redpanda.Service
defaulter defaulter

isProtectedUserFn func(userName string) bool
}
Expand All @@ -56,6 +57,7 @@ func NewService(cfg *config.Config,
logger: logger,
consoleSvc: consoleSvc,
redpandaSvc: redpandaSvc,
defaulter: defaulter{},
isProtectedUserFn: isProtectedUserFn,
}
}
Expand All @@ -71,6 +73,7 @@ func (s *Service) ListUsers(ctx context.Context, req *connect.Request[v1alpha1.L
apierrors.NewHelp(apierrors.NewHelpLinkConsoleReferenceConfig()),
)
}
s.defaulter.applyListUsersRequest(req.Msg)

// 2. List users
users, err := s.redpandaSvc.ListUsers(ctx)
Expand Down
Loading

0 comments on commit 2de65c5

Please sign in to comment.