Skip to content

Commit 22a3a8d

Browse files
committed
[public-api] Refactor to use conenct handlers
1 parent d7b5c50 commit 22a3a8d

File tree

8 files changed

+193
-277
lines changed

8 files changed

+193
-277
lines changed

components/public-api-server/pkg/apiv1/prebuild.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,24 @@ package apiv1
66

77
import (
88
"context"
9+
10+
"github.com/bufbuild/connect-go"
911
v1 "github.com/gitpod-io/gitpod/public-api/v1"
12+
"github.com/gitpod-io/gitpod/public-api/v1/v1connect"
1013
)
1114

1215
func NewPrebuildService() *PrebuildService {
13-
return &PrebuildService{
14-
UnimplementedPrebuildsServiceServer: &v1.UnimplementedPrebuildsServiceServer{},
15-
}
16+
return &PrebuildService{}
1617
}
1718

1819
type PrebuildService struct {
19-
*v1.UnimplementedPrebuildsServiceServer
20+
v1connect.UnimplementedPrebuildsServiceHandler
2021
}
2122

22-
func (p *PrebuildService) GetPrebuild(ctx context.Context, req *v1.GetPrebuildRequest) (*v1.GetPrebuildResponse, error) {
23-
return &v1.GetPrebuildResponse{
23+
func (p *PrebuildService) GetPrebuild(ctx context.Context, req *connect.Request[v1.GetPrebuildRequest]) (*connect.Response[v1.GetPrebuildResponse], error) {
24+
return connect.NewResponse(&v1.GetPrebuildResponse{
2425
Prebuild: &v1.Prebuild{
25-
PrebuildId: req.GetPrebuildId(),
26+
PrebuildId: req.Msg.GetPrebuildId(),
2627
Spec: &v1.PrebuildSpec{
2728
Context: &v1.WorkspaceContext{
2829
ContextUrl: "https://github.com/gitpod-io/gitpod",
@@ -32,5 +33,5 @@ func (p *PrebuildService) GetPrebuild(ctx context.Context, req *v1.GetPrebuildRe
3233
},
3334
Status: nil,
3435
},
35-
}, nil
36+
}), nil
3637
}

components/public-api-server/pkg/apiv1/prebuild_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ package apiv1
66

77
import (
88
"context"
9+
"testing"
10+
11+
"github.com/bufbuild/connect-go"
912
v1 "github.com/gitpod-io/gitpod/public-api/v1"
1013
"github.com/stretchr/testify/require"
11-
"testing"
1214
)
1315

1416
func TestPrebuildService_GetPrebuild(t *testing.T) {
1517
svc := NewPrebuildService()
1618

1719
prebuildID := "some-prebuild-id"
18-
resp, err := svc.GetPrebuild(context.Background(), &v1.GetPrebuildRequest{
20+
resp, err := svc.GetPrebuild(context.Background(), connect.NewRequest(&v1.GetPrebuildRequest{
1921
PrebuildId: prebuildID,
20-
})
22+
}))
2123
require.NoError(t, err)
2224
require.Equal(t, &v1.GetPrebuildResponse{
2325
Prebuild: &v1.Prebuild{
@@ -31,6 +33,6 @@ func TestPrebuildService_GetPrebuild(t *testing.T) {
3133
},
3234
Status: nil,
3335
},
34-
}, resp)
36+
}, resp.Msg)
3537

3638
}

components/public-api-server/pkg/apiv1/workspace.go

Lines changed: 32 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -6,60 +6,50 @@ package apiv1
66

77
import (
88
"context"
9+
"fmt"
910

11+
connect "github.com/bufbuild/connect-go"
1012
protocol "github.com/gitpod-io/gitpod/gitpod-protocol"
13+
"github.com/gitpod-io/gitpod/public-api-server/pkg/auth"
1114
"github.com/gitpod-io/gitpod/public-api-server/pkg/proxy"
1215
v1 "github.com/gitpod-io/gitpod/public-api/v1"
16+
"github.com/gitpod-io/gitpod/public-api/v1/v1connect"
1317
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
1418
"github.com/relvacode/iso8601"
15-
"google.golang.org/grpc"
1619
"google.golang.org/grpc/codes"
17-
"google.golang.org/grpc/metadata"
1820
"google.golang.org/grpc/status"
1921
"google.golang.org/protobuf/types/known/timestamppb"
2022
)
2123

2224
func NewWorkspaceService(serverConnPool proxy.ServerConnectionPool) *WorkspaceService {
2325
return &WorkspaceService{
24-
connectionPool: serverConnPool,
25-
UnimplementedWorkspacesServiceServer: &v1.UnimplementedWorkspacesServiceServer{},
26+
connectionPool: serverConnPool,
2627
}
2728
}
2829

2930
type WorkspaceService struct {
3031
connectionPool proxy.ServerConnectionPool
3132

32-
*v1.UnimplementedWorkspacesServiceServer
33+
v1connect.UnimplementedWorkspacesServiceHandler
3334
}
3435

35-
func (w *WorkspaceService) GetWorkspace(ctx context.Context, r *v1.GetWorkspaceRequest) (*v1.GetWorkspaceResponse, error) {
36+
func (s *WorkspaceService) GetWorkspace(ctx context.Context, req *connect.Request[v1.GetWorkspaceRequest]) (*connect.Response[v1.GetWorkspaceResponse], error) {
37+
token := auth.TokenFromContext(ctx)
3638
logger := ctxlogrus.Extract(ctx)
37-
token, err := bearerTokenFromContext(ctx)
38-
if err != nil {
39-
return nil, err
40-
}
4139

42-
server, err := w.connectionPool.Get(ctx, token)
40+
server, err := s.connectionPool.Get(ctx, token)
4341
if err != nil {
4442
logger.WithError(err).Error("Failed to get connection to server.")
45-
return nil, status.Error(codes.Internal, "failed to establish connection to downstream services")
43+
return nil, connect.NewError(connect.CodeInternal, err)
4644
}
4745

48-
workspace, err := server.GetWorkspace(ctx, r.GetWorkspaceId())
46+
workspace, err := server.GetWorkspace(ctx, req.Msg.GetWorkspaceId())
4947
if err != nil {
5048
logger.WithError(err).Error("Failed to get workspace.")
51-
converted := proxy.ConvertError(err)
52-
switch status.Code(converted) {
53-
case codes.PermissionDenied:
54-
return nil, status.Error(codes.PermissionDenied, "insufficient permission to access workspace")
55-
case codes.NotFound:
56-
return nil, status.Error(codes.NotFound, "workspace does not exist")
57-
default:
58-
return nil, status.Error(codes.Internal, "unable to retrieve workspace")
59-
}
49+
return nil, proxy.ConvertError(err)
6050
}
6151

62-
return &v1.GetWorkspaceResponse{
52+
return connect.NewResponse(&v1.GetWorkspaceResponse{
6353
Result: &v1.Workspace{
6454
WorkspaceId: workspace.Workspace.ID,
6555
OwnerId: workspace.Workspace.OwnerID,
@@ -73,72 +63,40 @@ func (w *WorkspaceService) GetWorkspace(ctx context.Context, r *v1.GetWorkspaceR
7363
},
7464
Description: workspace.Workspace.Description,
7565
},
76-
}, nil
66+
}), nil
7767
}
7868

79-
func (w *WorkspaceService) GetOwnerToken(ctx context.Context, r *v1.GetOwnerTokenRequest) (*v1.GetOwnerTokenResponse, error) {
69+
func (s *WorkspaceService) GetOwnerToken(ctx context.Context, req *connect.Request[v1.GetOwnerTokenRequest]) (*connect.Response[v1.GetOwnerTokenResponse], error) {
8070
logger := ctxlogrus.Extract(ctx)
81-
token, err := bearerTokenFromContext(ctx)
82-
if err != nil {
83-
return nil, err
84-
}
71+
token := auth.TokenFromContext(ctx)
8572

86-
server, err := w.connectionPool.Get(ctx, token)
73+
server, err := s.connectionPool.Get(ctx, token)
8774
if err != nil {
8875
logger.WithError(err).Error("Failed to get connection to server.")
8976
return nil, status.Error(codes.Internal, "failed to establish connection to downstream services")
9077
}
9178

92-
ownerToken, err := server.GetOwnerToken(ctx, r.GetWorkspaceId())
79+
ownerToken, err := server.GetOwnerToken(ctx, req.Msg.GetWorkspaceId())
9380

9481
if err != nil {
9582
logger.WithError(err).Error("Failed to get owner token.")
96-
converted := proxy.ConvertError(err)
97-
switch status.Code(converted) {
98-
case codes.PermissionDenied:
99-
return nil, status.Error(codes.PermissionDenied, "insufficient permission to retrieve ownertoken")
100-
case codes.NotFound:
101-
return nil, status.Error(codes.NotFound, "workspace does not exist")
102-
default:
103-
return nil, status.Error(codes.Internal, "unable to retrieve owner token")
104-
}
105-
}
106-
107-
return &v1.GetOwnerTokenResponse{Token: ownerToken}, nil
108-
}
109-
110-
func bearerTokenFromContext(ctx context.Context) (string, error) {
111-
md, ok := metadata.FromIncomingContext(ctx)
112-
if !ok {
113-
return "", status.Error(codes.Unauthenticated, "no credentials provided")
114-
}
115-
116-
values := md.Get("authorization")
117-
if len(values) == 0 {
118-
return "", status.Error(codes.Unauthenticated, "no authorization header specified")
119-
}
120-
if len(values) > 1 {
121-
return "", status.Error(codes.Unauthenticated, "more than one authorization header specified, exactly one is required")
83+
return nil, proxy.ConvertError(err)
12284
}
12385

124-
token := values[0]
125-
return token, nil
86+
return connect.NewResponse(&v1.GetOwnerTokenResponse{Token: ownerToken}), nil
12687
}
12788

128-
func (w *WorkspaceService) ListWorkspaces(ctx context.Context, req *v1.ListWorkspacesRequest) (*v1.ListWorkspacesResponse, error) {
89+
func (s *WorkspaceService) ListWorkspaces(ctx context.Context, req *connect.Request[v1.ListWorkspacesRequest]) (*connect.Response[v1.ListWorkspacesResponse], error) {
12990
logger := ctxlogrus.Extract(ctx)
130-
token, err := bearerTokenFromContext(ctx)
131-
if err != nil {
132-
return nil, err
133-
}
91+
token := auth.TokenFromContext(ctx)
13492

135-
server, err := w.connectionPool.Get(ctx, token)
93+
server, err := s.connectionPool.Get(ctx, token)
13694
if err != nil {
13795
logger.WithError(err).Error("Failed to get connection to server.")
13896
return nil, status.Error(codes.Internal, "failed to establish connection to downstream services")
13997
}
14098

141-
limit, err := getLimitFromPagination(req.Pagination)
99+
limit, err := getLimitFromPagination(req.Msg.GetPagination())
142100
if err != nil {
143101
// getLimitFromPagination returns gRPC errors
144102
return nil, err
@@ -161,9 +119,11 @@ func (w *WorkspaceService) ListWorkspaces(ctx context.Context, req *v1.ListWorks
161119
res = append(res, workspaceAndInstance)
162120
}
163121

164-
return &v1.ListWorkspacesResponse{
165-
Result: res,
166-
}, nil
122+
return connect.NewResponse(
123+
&v1.ListWorkspacesResponse{
124+
Result: res,
125+
},
126+
), nil
167127
}
168128

169129
func getLimitFromPagination(pagination *v1.Pagination) (int, error) {
@@ -179,7 +139,7 @@ func getLimitFromPagination(pagination *v1.Pagination) (int, error) {
179139
return defaultLimit, nil
180140
}
181141
if pagination.PageSize < 0 || maxLimit < pagination.PageSize {
182-
return 0, grpc.Errorf(codes.InvalidArgument, "invalid pagination page size (must be 0 < x < %d)", maxLimit)
142+
return 0, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid pagination page size (must be 0 < x < %d)", maxLimit))
183143
}
184144

185145
return int(pagination.PageSize), nil
@@ -192,7 +152,7 @@ func convertWorkspaceInfo(input *protocol.WorkspaceInfo) (*v1.ListWorkspacesResp
192152
creationTime, err := parseGitpodTimestamp(wsi.CreationTime)
193153
if err != nil {
194154
// TODO(cw): should this really return an error and possibly fail the entire operation?
195-
return nil, grpc.Errorf(codes.FailedPrecondition, "cannot parse creation time: %v", err)
155+
return nil, connect.NewError(connect.CodeFailedPrecondition, fmt.Errorf("cannot parse creation time: %v", err))
196156
}
197157

198158
var phase v1.WorkspaceInstanceStatus_Phase
@@ -219,7 +179,7 @@ func convertWorkspaceInfo(input *protocol.WorkspaceInfo) (*v1.ListWorkspacesResp
219179
phase = v1.WorkspaceInstanceStatus_PHASE_STOPPED
220180
default:
221181
// TODO(cw): should this really return an error and possibly fail the entire operation?
222-
return nil, grpc.Errorf(codes.FailedPrecondition, "cannot convert instance phase: %s", wsi.Status.Phase)
182+
return nil, connect.NewError(connect.CodeFailedPrecondition, fmt.Errorf("cannot convert instance phase: %s", wsi.Status.Phase))
223183
}
224184

225185
var admissionLevel v1.AdmissionLevel

0 commit comments

Comments
 (0)