Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Commit

Permalink
Refactor show and Implement List API
Browse files Browse the repository at this point in the history
This patch will refactor the show api to return the
pip-env map of the id provided inspite of assuming
one in a space and always return the first

Also implement list api to return all the pip-env maps
in a space.

Implement tests for list api

Fixes #142
Fixes openshiftio/openshift.io#4638
  • Loading branch information
piyush-garg authored and chmouel committed Dec 13, 2018
1 parent 0387db0 commit 36b9c82
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 35 deletions.
38 changes: 29 additions & 9 deletions build/pipelineenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ type Environment struct {

type Repository interface {
Create(ctx context.Context, pipl *Pipeline) (*Pipeline, error)
Load(ctx context.Context, spaceID uuid.UUID) (*Pipeline, error)
Load(ctx context.Context, ID uuid.UUID) (*Pipeline, error)
List(ctx context.Context, spaceID uuid.UUID) ([]*Pipeline, error)
}

type GormRepository struct {
Expand All @@ -50,31 +51,50 @@ func (r *GormRepository) Create(ctx context.Context, pipl *Pipeline) (*Pipeline,
err := r.db.Create(pipl).Error
if err != nil {
if gormsupport.IsUniqueViolation(err, "pipelines_name_space_id_key") {
return nil, errors.NewDataConflictError(fmt.Sprintf("pipeline_name %s with spaceID %s already exists", *pipl.Name, pipl.SpaceID))
return nil, errors.NewDataConflictError(fmt.Sprintf("pipeline_environment_map_name %s with spaceID %s already exists", *pipl.Name, pipl.SpaceID))
}

log.Error(ctx, map[string]interface{}{"err": err},
"unable to create pipeline")
"unable to create pipeline-environment map")
return nil, errs.WithStack(err)
}

return pipl, nil
}

func (r *GormRepository) Load(ctx context.Context, spaceID uuid.UUID) (*Pipeline, error) {
defer goa.MeasureSince([]string{"goa", "db", "pipeline", "load"}, time.Now())
ppl := Pipeline{}
tx := r.db.Model(&Pipeline{}).Where("space_id = ?", spaceID).Preload("Environment").First(&ppl)
func (r *GormRepository) List(ctx context.Context, spaceID uuid.UUID) ([]*Pipeline, error) {
defer goa.MeasureSince([]string{"goa", "db", "pipeline", "list"}, time.Now())
var rows []*Pipeline
tx := r.db.Model(&Pipeline{}).Where("space_id = ?", spaceID).Preload("Environment").Find(&rows)
if tx.RecordNotFound() {
log.Error(ctx, map[string]interface{}{"space_id": spaceID.String()},
"state or known referer was empty")
return nil, errors.NewNotFoundError("pipeline", spaceID.String())
return nil, errors.NewNotFoundError("pipeline-environment", spaceID.String())
}
// This should not happen as I don't see what kind of other error (as long
// schemas are created) than RecordNotFound can we have
if tx.Error != nil {
log.Error(ctx, map[string]interface{}{"err": tx.Error, "space_id": spaceID.String()},
"unable to load the pipeline by spaceID")
"unable to list the pipeline-environment by spaceID")
return nil, errors.NewInternalError(ctx, tx.Error)
}
return rows, nil
}

func (r *GormRepository) Load(ctx context.Context, ID uuid.UUID) (*Pipeline, error) {
defer goa.MeasureSince([]string{"goa", "db", "pipeline", "load"}, time.Now())
ppl := Pipeline{}
tx := r.db.Model(&Pipeline{}).Where("id = ?", ID).Preload("Environment").First(&ppl)
if tx.RecordNotFound() {
log.Error(ctx, map[string]interface{}{"id": ID.String()},
"state or known referer was empty")
return nil, errors.NewNotFoundError("pipeline-environment", ID.String())
}
// This should not happen as I don't see what kind of other error (as long
// schemas are created) than RecordNotFound can we have
if tx.Error != nil {
log.Error(ctx, map[string]interface{}{"err": tx.Error, "id": ID.String()},
"unable to load the pipeline-environment by ID")
return nil, errors.NewInternalError(ctx, tx.Error)
}
return &ppl, nil
Expand Down
17 changes: 16 additions & 1 deletion build/pipelineenv_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,27 @@ func (s *BuildRepositorySuite) TestShow() {
require.NoError(s.T(), err)
require.NotNil(s.T(), newEnv)

env, err := s.buildRepo.Load(context.Background(), spaceID)
env, err := s.buildRepo.Load(context.Background(), newEnv.ID)
require.NoError(s.T(), err)
assert.NotNil(s.T(), env)
assert.Equal(s.T(), newEnv.ID, env.ID)
}

func (s *BuildRepositorySuite) TestList() {
spaceID, envUUID, envUUID2 := uuid.NewV4(), uuid.NewV4(), uuid.NewV4()
newEnv, err := s.buildRepo.Create(context.Background(), newPipeline("pipelineShow", spaceID, envUUID))
newEnv2, err2 := s.buildRepo.Create(context.Background(), newPipeline("pipelineShow2", spaceID, envUUID2))
require.NoError(s.T(), err)
require.NoError(s.T(), err2)
require.NotNil(s.T(), newEnv)
require.NotNil(s.T(), newEnv2)

env, err := s.buildRepo.List(context.Background(), spaceID)
require.NoError(s.T(), err)
assert.NotNil(s.T(), env)
assert.Equal(s.T(), 2, len(env))
}

func newPipeline(name string, spaceID, envUUID uuid.UUID) *build.Pipeline {
ppl := &build.Pipeline{
Name: &name,
Expand Down
59 changes: 44 additions & 15 deletions controller/pipeline_environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,31 +103,42 @@ func (c *PipelineEnvironmentController) Create(ctx *app.CreatePipelineEnvironmen
return ctx.Created(res)
}

// Show runs the show action.
func (c *PipelineEnvironmentController) Show(ctx *app.ShowPipelineEnvironmentsContext) error {
// List runs the list action.
func (c *PipelineEnvironmentController) List(ctx *app.ListPipelineEnvironmentsContext) error {
spaceID := ctx.SpaceID
err := c.checkSpaceExist(ctx, spaceID.String())
if err != nil {
return app.JSONErrorResponse(ctx, err)
}

ppl, err := c.db.Pipeline().Load(ctx, spaceID)
pplenv, err := c.db.Pipeline().List(ctx, spaceID)
if err != nil {
return app.JSONErrorResponse(ctx, err)
}

newEnvAttributes := []*app.EnvironmentAttributes{}
for _, pipeline := range ppl.Environment {
newEnvAttributes = append(newEnvAttributes, &app.EnvironmentAttributes{
EnvUUID: pipeline.EnvironmentID,
})
newPipelineList := []*app.PipelineEnvironments{}
for _, ppl := range pplenv {
newPipelineList = append(newPipelineList, convertToPipelineEnvironmentStruct(ppl))
}

res := &app.PipelineEnvironmentSingle{
Data: &app.PipelineEnvironments{
ID: &ppl.ID,
Name: *ppl.Name,
Environments: newEnvAttributes,
SpaceID: ppl.SpaceID,
},
res := &app.PipelineEnvironmentsList{
Data: newPipelineList,
}
return ctx.OK(res)
}

// Show runs the load action.
func (c *PipelineEnvironmentController) Show(ctx *app.ShowPipelineEnvironmentsContext) error {
envID := ctx.ID
ppl, err := c.db.Pipeline().Load(ctx, envID)
if err != nil {
return app.JSONErrorResponse(ctx, err)
}

data := convertToPipelineEnvironmentStruct(ppl)
res := &app.PipelineEnvironmentSingle{
Data: data,
}
return ctx.OK(res)
}

Expand Down Expand Up @@ -172,3 +183,21 @@ func convertToEnvUidList(envList []env.Environment) map[guuid.UUID]string {
}
return envMap
}

//this will convert the pipeline struct from database to pipeline-environment struct
func convertToPipelineEnvironmentStruct(ppl *build.Pipeline) *app.PipelineEnvironments {
newEnvAttributes := []*app.EnvironmentAttributes{}
for _, pipeline := range ppl.Environment {
newEnvAttributes = append(newEnvAttributes, &app.EnvironmentAttributes{
EnvUUID: pipeline.EnvironmentID,
})
}

pe := &app.PipelineEnvironments{
ID: &ppl.ID,
Name: *ppl.Name,
Environments: newEnvAttributes,
SpaceID: ppl.SpaceID,
}
return pe
}
28 changes: 27 additions & 1 deletion controller/pipeline_environments_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func (s *PipelineEnvironmentControllerSuite) TestShow() {
_, newEnv := test.CreatePipelineEnvironmentsCreated(t, s.ctx2, s.svc2, s.ctrl2, spaceID, payload)
require.NotNil(t, newEnv)

_, env := test.ShowPipelineEnvironmentsOK(t, s.ctx2, s.svc2, s.ctrl2, spaceID)
_, env := test.ShowPipelineEnvironmentsOK(t, s.ctx2, s.svc2, s.ctrl2, *newEnv.Data.ID)
assert.NotNil(t, env)
assert.Equal(t, newEnv.Data.ID, env.Data.ID)
})
Expand All @@ -291,6 +291,32 @@ func (s *PipelineEnvironmentControllerSuite) TestShow() {
})
}

func (s *PipelineEnvironmentControllerSuite) TestList() {
s.T().Run("ok", func(t *testing.T) {
spaceID := uuid.NewV4()
env1ID := uuid.NewV4()
env2ID := uuid.NewV4()
s.createGockONSpace(spaceID, "space1")
s.createGockONEnvList(spaceID, env1ID, env2ID)
payload := newPipelineEnvironmentPayload("osio-stage-show", env1ID)
_, newEnv := test.CreatePipelineEnvironmentsCreated(t, s.ctx2, s.svc2, s.ctrl2, spaceID, payload)
require.NotNil(t, newEnv)
payload2 := newPipelineEnvironmentPayload("osio-stage-show", env2ID)
_, newEnv2 := test.CreatePipelineEnvironmentsCreated(t, s.ctx2, s.svc2, s.ctrl2, spaceID, payload2)
require.NotNil(t, newEnv2)

_, env := test.ListPipelineEnvironmentsOK(t, s.ctx2, s.svc2, s.ctrl2, spaceID)
assert.NotNil(t, env)
assert.Equal(t, 2, len(env.Data))
})

s.T().Run("space_not_found", func(t *testing.T) {
spaceID := uuid.NewV4()
_, err := test.ListPipelineEnvironmentsInternalServerError(t, s.ctx2, s.svc2, s.ctrl2, spaceID)
assert.NotNil(t, err)
})
}

func newPipelineEnvironmentPayload(name string, envUUID uuid.UUID) *app.CreatePipelineEnvironmentsPayload {
payload := &app.CreatePipelineEnvironmentsPayload{
Data: &app.PipelineEnvironments{
Expand Down
14 changes: 14 additions & 0 deletions design/media_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package design

import (
d "github.com/goadesign/goa/design"
a "github.com/goadesign/goa/design/apidsl"
)

var pagingLinks = a.Type("pagingLinks", func() {
a.Attribute("prev", d.String)
a.Attribute("next", d.String)
a.Attribute("first", d.String)
a.Attribute("last", d.String)
a.Attribute("filters", d.String)
})
41 changes: 32 additions & 9 deletions design/pipelineenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,70 @@ var pipelineEnv = a.Type("PipelineEnvironments", func() {
a.Required("name", "environments")
})

var pipelineEnvListMeta = a.Type("PipelineEnvironmentListMeta", func() {
a.Attribute("totalCount", d.Integer)
a.Required("totalCount")
})

var pipelineEnvSingle = JSONSingle(
"PipelineEnvironment", "Holds a single pipeline environment map",
pipelineEnv,
nil)

var pipelineEnvList = JSONList(
"PipelineEnvironments", "Holds the list of pipeline environment map",
pipelineEnv,
pagingLinks,
pipelineEnvListMeta)

var _ = a.Resource("PipelineEnvironments", func() {
a.Action("create", func() {
a.Description("Create pipeline environment map")
a.Params(func() {
a.Param("spaceID", d.UUID, "Space ID for the pipeline environment map")
})
a.Routing(
a.POST("/spaces/:spaceID/pipeline-environments"),
)
a.Description("Create environment")
a.Params(func() {
a.Param("spaceID", d.UUID, "UUID of the space")
})
a.Payload(pipelineEnvSingle)
a.Response(d.Created, pipelineEnvSingle)
a.Response(d.BadRequest, JSONAPIErrors)
a.Response(d.InternalServerError, JSONAPIErrors)
a.Response(d.Unauthorized, JSONAPIErrors)
a.Response(d.MethodNotAllowed, JSONAPIErrors)
a.Response(d.Forbidden, JSONAPIErrors)
a.Response(d.Conflict, JSONAPIErrors)
a.Response(d.NotFound, JSONAPIErrors)
})

a.Action("show", func() {
a.Description("Retrieve pipeline environment map (as JSONAPI) for the given space ID.")
a.Action("list", func() {
a.Description("Retrieve list of pipeline environment maps (as JSONAPI) for the given space ID.")
a.Params(func() {
a.Param("spaceID", d.UUID, "Space ID for the pipeline environment map")
})

a.Routing(
a.GET("/spaces/:spaceID/pipeline-environments"),
)
a.Response(d.OK, pipelineEnvList)
a.Response(d.InternalServerError, JSONAPIErrors)
a.Response(d.NotFound, JSONAPIErrors)
a.Response(d.Unauthorized, JSONAPIErrors)
a.Response(d.Forbidden, JSONAPIErrors)
})

a.Action("show", func() {
a.Description("Retrieve pipeline environment map (as JSONAPI) for the given ID.")
a.Params(func() {
a.Param("spaceID", d.UUID, "UUID of the space")
a.Param("ID", d.UUID, "ID of the pipeline environment map")
})

a.Routing(
a.GET("/pipeline-environments/:ID"),
)
a.Response(d.OK, pipelineEnvSingle)
a.Response(d.InternalServerError, JSONAPIErrors)
a.Response(d.NotFound, JSONAPIErrors)
a.Response(d.Unauthorized, JSONAPIErrors)
a.Response(d.Forbidden, JSONAPIErrors)
})

})

0 comments on commit 36b9c82

Please sign in to comment.