Skip to content

Commit

Permalink
Implement GetProject endpoint in FlyteAdmin (#4825)
Browse files Browse the repository at this point in the history
  • Loading branch information
RRap0so authored Mar 20, 2024
1 parent eb24107 commit 3fe4533
Show file tree
Hide file tree
Showing 31 changed files with 1,421 additions and 584 deletions.
2 changes: 1 addition & 1 deletion cmd/single/console_dist.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var consoleHandlers = map[string]handlerFunc{
consoleHandler.ServeHTTP(writer, request)
},
consoleRoot + "/": func(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Cache-Control", "max-age=604800") // 7 days
writer.Header().Set("Cache-Control", "max-age=604800") // 7 days
consoleHandler.ServeHTTP(writer, request)
},
}
13 changes: 13 additions & 0 deletions flyteadmin/pkg/manager/impl/project_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ func (m *ProjectManager) UpdateProject(ctx context.Context, projectUpdate admin.
return &response, nil
}

func (m *ProjectManager) GetProject(ctx context.Context, request admin.ProjectGetRequest) (*admin.Project, error) {
if err := validation.ValidateProjectGetRequest(request); err != nil {
return nil, err
}
projectModel, err := m.db.ProjectRepo().Get(ctx, request.Id)
if err != nil {
return nil, err
}
projectResponse := transformers.FromProjectModel(projectModel, m.getDomains())

return &projectResponse, nil
}

func NewProjectManager(db repoInterfaces.Repository, config runtimeInterfaces.Configuration) interfaces.ProjectInterface {
return &ProjectManager{
db: db,
Expand Down
56 changes: 56 additions & 0 deletions flyteadmin/pkg/manager/impl/project_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,59 @@ func TestProjectManager_UpdateProject_ErrorDueToInvalidProjectName(t *testing.T)
})
assert.EqualError(t, err, "project_name cannot exceed 64 characters")
}

func TestProjectManager_TestGetProject(t *testing.T) {
mockRepository := repositoryMocks.NewMockRepository()
mockedProject := &admin.ProjectGetRequest{Id: project}
activeState := int32(admin.Project_ACTIVE)
mockRepository.ProjectRepo().(*repositoryMocks.MockProjectRepo).GetFunction = func(ctx context.Context, projectID string) (models.Project, error) {

return models.Project{
BaseModel: models.BaseModel{},
Identifier: projectID,
Name: "a-mocked-project",
Description: "A mocked project",
State: &activeState,
}, nil
}

projectManager := NewProjectManager(mockRepository, runtimeMocks.NewMockConfigurationProvider(
getMockApplicationConfigForProjectManagerTest(), nil, nil, nil, nil, nil))

resp, _ := projectManager.GetProject(context.Background(),
*mockedProject)

assert.Equal(t, mockedProject.Id, resp.Id)
assert.Equal(t, "a-mocked-project", resp.Name)
assert.Equal(t, "A mocked project", resp.Description)
assert.Equal(t, admin.Project_ProjectState(0), resp.State)
}

func TestProjectManager_TestGetProject_ErrorDueToProjectNotFound(t *testing.T) {
mockRepository := repositoryMocks.NewMockRepository()
mockedProject := &admin.ProjectGetRequest{Id: project}
mockRepository.ProjectRepo().(*repositoryMocks.MockProjectRepo).GetFunction = func(ctx context.Context, projectID string) (models.Project, error) {
return models.Project{}, errors.New("project " + projectID + " not found")
}

projectManager := NewProjectManager(mockRepository, runtimeMocks.NewMockConfigurationProvider(
getMockApplicationConfigForProjectManagerTest(), nil, nil, nil, nil, nil))

_, err := projectManager.GetProject(context.Background(),
*mockedProject)

assert.EqualError(t, err, "project "+project+" not found")
}

func TestProjectManager_TestGetProject_ErrorDueToEmptyProjectGetRequest(t *testing.T) {
mockRepository := repositoryMocks.NewMockRepository()
mockedProject := &admin.ProjectGetRequest{Id: ""}

projectManager := NewProjectManager(mockRepository, runtimeMocks.NewMockConfigurationProvider(
getMockApplicationConfigForProjectManagerTest(), nil, nil, nil, nil, nil))

_, err := projectManager.GetProject(context.Background(),
*mockedProject)

assert.EqualError(t, err, "missing project_id")
}
7 changes: 7 additions & 0 deletions flyteadmin/pkg/manager/impl/validation/project_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ func ValidateProjectRegisterRequest(request admin.ProjectRegisterRequest) error
return ValidateProject(project)
}

func ValidateProjectGetRequest(request admin.ProjectGetRequest) error {
if err := ValidateEmptyStringField(request.Id, projectID); err != nil {
return err
}
return nil
}

func ValidateProject(project admin.Project) error {
if err := ValidateEmptyStringField(project.Id, projectID); err != nil {
return err
Expand Down
12 changes: 12 additions & 0 deletions flyteadmin/pkg/manager/impl/validation/project_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,15 @@ func TestValidateProjectExistsDb(t *testing.T) {
assert.Error(t, err)
})
}

func TestValidateProjectGetRequest(t *testing.T) {
t.Run("base case", func(t *testing.T) {
assert.Nil(t, ValidateProjectGetRequest(admin.ProjectGetRequest{
Id: "project-id",
}))
})

t.Run("missing project id", func(t *testing.T) {
assert.EqualError(t, ValidateProjectGetRequest(admin.ProjectGetRequest{}), "missing project_id")
})
}
1 change: 1 addition & 0 deletions flyteadmin/pkg/manager/interfaces/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ type ProjectInterface interface {
CreateProject(ctx context.Context, request admin.ProjectRegisterRequest) (*admin.ProjectRegisterResponse, error)
ListProjects(ctx context.Context, request admin.ProjectListRequest) (*admin.Projects, error)
UpdateProject(ctx context.Context, request admin.Project) (*admin.ProjectUpdateResponse, error)
GetProject(ctx context.Context, request admin.ProjectGetRequest) (*admin.Project, error)
}
13 changes: 13 additions & 0 deletions flyteadmin/pkg/manager/mocks/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
type CreateProjectFunc func(ctx context.Context, request admin.ProjectRegisterRequest) (*admin.ProjectRegisterResponse, error)
type ListProjectFunc func(ctx context.Context, request admin.ProjectListRequest) (*admin.Projects, error)
type UpdateProjectFunc func(ctx context.Context, request admin.Project) (*admin.ProjectUpdateResponse, error)
type GetProjectFunc func(ctx context.Context, request admin.ProjectGetRequest) (*admin.Project, error)

type MockProjectManager struct {
listProjectFunc ListProjectFunc
createProjectFunc CreateProjectFunc
updateProjectFunc UpdateProjectFunc
getProjectFunc GetProjectFunc
}

func (m *MockProjectManager) SetCreateProject(createProjectFunc CreateProjectFunc) {
Expand Down Expand Up @@ -45,3 +47,14 @@ func (m *MockProjectManager) ListProjects(
}
return nil, nil
}

func (m *MockProjectManager) SetGetCallBack(getProjectFunc GetProjectFunc) {
m.getProjectFunc = getProjectFunc
}

func (m *MockProjectManager) GetProject(ctx context.Context, request admin.ProjectGetRequest) (*admin.Project, error) {
if m.getProjectFunc != nil {
return m.getProjectFunc(ctx, request)
}
return nil, nil
}
2 changes: 2 additions & 0 deletions flyteadmin/pkg/rpc/adminservice/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type projectEndpointMetrics struct {
register util.RequestMetrics
list util.RequestMetrics
update util.RequestMetrics
get util.RequestMetrics
}

type attributeEndpointMetrics struct {
Expand Down Expand Up @@ -176,6 +177,7 @@ func InitMetrics(adminScope promutils.Scope) AdminMetrics {
register: util.NewRequestMetrics(adminScope, "register_project"),
list: util.NewRequestMetrics(adminScope, "list_projects"),
update: util.NewRequestMetrics(adminScope, "update_project"),
get: util.NewRequestMetrics(adminScope, "get_project"),
},
projectAttributesEndpointMetrics: attributeEndpointMetrics{
scope: adminScope,
Expand Down
18 changes: 18 additions & 0 deletions flyteadmin/pkg/rpc/adminservice/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,21 @@ func (m *AdminService) UpdateProject(ctx context.Context, request *admin.Project

return response, nil
}

func (m *AdminService) GetProject(ctx context.Context, request *admin.ProjectGetRequest) (*admin.Project, error) {
defer m.interceptPanic(ctx, request)
if request == nil {
return nil, status.Errorf(codes.InvalidArgument, "Incorrect request, nil requests not allowed")
}
var response *admin.Project
var err error
m.Metrics.projectEndpointMetrics.get.Time(func() {
response, err = m.ProjectManager.GetProject(ctx, *request)
})
if err != nil {
return nil, util.TransformAndRecordError(err, &m.Metrics.projectEndpointMetrics.get)
}

m.Metrics.projectEndpointMetrics.get.Success()
return response, nil
}
12 changes: 12 additions & 0 deletions flyteadmin/pkg/rpc/adminservice/tests/project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,15 @@ func TestListProjects(t *testing.T) {
assert.Nil(t, err)
assert.True(t, proto.Equal(projects, resp))
}

func TestGetProject(t *testing.T) {
mockProjectManager := mocks.MockProjectManager{}
project := &admin.Project{Id: "project id", Name: "project"}
mockProjectManager.SetGetCallBack(func(ctx context.Context, request admin.ProjectGetRequest) (*admin.Project, error) {
assert.NotNil(t, request)
return project, nil
})
resp, err := mockProjectManager.GetProject(context.Background(), admin.ProjectGetRequest{})
assert.Nil(t, err)
assert.True(t, proto.Equal(project, resp))
}
4 changes: 2 additions & 2 deletions flyteadmin/pkg/server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ func newHTTPServer(ctx context.Context, pluginRegistry *plugins.Registry, cfg *c
// the application/json content type.
gwmuxOptions = append(gwmuxOptions, runtime.WithMarshalerOption("application/json", &runtime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
UseProtoNames: true,
EmitUnpopulated: true,
EmitDefaultValues: true,
},
}))
Expand Down
48 changes: 48 additions & 0 deletions flyteidl/clients/go/admin/mocks/AdminServiceClient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions flyteidl/clients/go/admin/mocks/AdminServiceServer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions flyteidl/clients/go/assets/admin.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3fe4533

Please sign in to comment.