Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mr2011/issue 310/im ordering #438

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/api/graphql/graph/baseResolver/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,6 @@ func GetListOptions(requestedFields []string) *entity.ListOptions {
ShowTotalCount: lo.Contains(requestedFields, "totalCount"),
ShowPageInfo: lo.Contains(requestedFields, "pageInfo"),
IncludeAggregations: lo.Contains(requestedFields, "edges.node.objectMetadata"),
Order: []entity.Order{},
}
}
5 changes: 4 additions & 1 deletion internal/api/graphql/graph/baseResolver/issue_match.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func SingleIssueMatchBaseResolver(app app.Heureka, ctx context.Context, parent *
return &issueMatch, nil
}

func IssueMatchBaseResolver(app app.Heureka, ctx context.Context, filter *model.IssueMatchFilter, first *int, after *string, parent *model.NodeParent) (*model.IssueMatchConnection, error) {
func IssueMatchBaseResolver(app app.Heureka, ctx context.Context, filter *model.IssueMatchFilter, first *int, after *string, orderBy []*model.IssueMatchOrderBy, parent *model.NodeParent) (*model.IssueMatchConnection, error) {
requestedFields := GetPreloads(ctx)
logrus.WithFields(logrus.Fields{
"requestedFields": requestedFields,
Expand Down Expand Up @@ -119,6 +119,9 @@ func IssueMatchBaseResolver(app app.Heureka, ctx context.Context, filter *model.
}

opt := GetListOptions(requestedFields)
for _, o := range orderBy {
opt.Order = append(opt.Order, o.ToOrderEntity())
}

issueMatches, err := app.ListIssueMatches(f, opt)

Expand Down
26 changes: 26 additions & 0 deletions internal/api/graphql/graph/model/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ var AllIssueMatchStatusValuesOrdered = []IssueMatchStatusValues{
IssueMatchStatusValuesMitigated,
}

type HasToEntity interface {
ToOrderEntity() entity.Order
}

func (od *OrderDirection) ToOrderDirectionEntity() entity.OrderDirection {
direction := entity.OrderDirectionAsc
if *od == OrderDirectionDesc {
direction = entity.OrderDirectionDesc
}
return direction
}

func (imo *IssueMatchOrderBy) ToOrderEntity() entity.Order {
var order entity.Order
switch *imo.By {
case IssueMatchOrderByFieldPrimaryName:
order.By = entity.IssuePrimaryName
case IssueMatchOrderByFieldComponentInstanceCcrn:
order.By = entity.ComponentInstanceCcrn
case IssueMatchOrderByFieldTargetRemediationDate:
order.By = entity.IssueMatchTargetRemediationDate
}
order.Direction = imo.Direction.ToOrderDirectionEntity()
return order
}

func NewPageInfo(p *entity.PageInfo) *PageInfo {
if p == nil {
return nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
# SPDX-License-Identifier: Apache-2.0

query ($filter: IssueMatchFilter, $first: Int, $after: String, $orderBy: [IssueMatchOrderBy]) {
IssueMatches (
filter: $filter,
first: $first,
after: $after
orderBy: $orderBy
) {
totalCount
edges {
node {
id
targetRemediationDate
severity {
value
score
}
issueId
issue {
id
primaryName
}
componentInstanceId
componentInstance {
id
ccrn
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
isValidPage
pageNumber
nextPageAfter
pages {
after
isCurrent
pageNumber
pageCount
}
}
}
}

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

2 changes: 1 addition & 1 deletion internal/api/graphql/graph/resolver/evidence.go

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

2 changes: 1 addition & 1 deletion internal/api/graphql/graph/resolver/issue.go

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

4 changes: 2 additions & 2 deletions internal/api/graphql/graph/resolver/query.go

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

5 changes: 5 additions & 0 deletions internal/api/graphql/graph/schema/common.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,8 @@ type Metadata {
updated_at: DateTime
updated_by: String
}

enum OrderDirection {
asc
desc
}
11 changes: 11 additions & 0 deletions internal/api/graphql/graph/schema/issue_match.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,14 @@ enum IssueMatchStatusValues {
false_positive
mitigated
}

input IssueMatchOrderBy {
by: IssueMatchOrderByField
direction: OrderDirection
}

enum IssueMatchOrderByField {
primaryName
targetRemediationDate
componentInstanceCcrn
}
2 changes: 1 addition & 1 deletion internal/api/graphql/graph/schema/query.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

type Query {
Issues(filter: IssueFilter, first: Int, after: String): IssueConnection
IssueMatches(filter: IssueMatchFilter, first: Int, after: String): IssueMatchConnection
IssueMatches(filter: IssueMatchFilter, first: Int, after: String, orderBy: [IssueMatchOrderBy]): IssueMatchConnection
IssueMatchChanges(filter: IssueMatchChangeFilter, first: Int, after: String): IssueMatchChangeConnection
Services(filter: ServiceFilter, first: Int, after: String): ServiceConnection
Components(filter: ComponentFilter, first: Int, after: String): ComponentConnection
Expand Down
2 changes: 1 addition & 1 deletion internal/app/issue/issue_handler_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func createIssueMatches(
issue_matches, err := db.GetIssueMatches(&entity.IssueMatchFilter{
IssueId: []*int64{&issueId},
ComponentInstanceId: []*int64{&componentInstanceId},
})
}, []entity.Order{})

if err != nil {
l.WithField("event-step", "FetchIssueMatches").WithError(err).Error("Error while fetching issue matches related to assigned Component Instance")
Expand Down
4 changes: 2 additions & 2 deletions internal/app/issue/issue_handler_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ var _ = Describe("OnComponentVersionAttachmentToIssue", Label("app", "ComponentV
db.On("GetIssueMatches", &entity.IssueMatchFilter{
ComponentInstanceId: []*int64{&componentInstance.Id},
IssueId: []*int64{&issueEntity.Id},
}).Return([]entity.IssueMatch{}, nil)
}, []entity.Order{}).Return([]entity.IssueMatch{}, nil)

db.On("GetServiceIssueVariants", &entity.ServiceIssueVariantFilter{
ComponentInstanceId: []*int64{&componentInstance.Id},
Expand Down Expand Up @@ -123,7 +123,7 @@ var _ = Describe("OnComponentVersionAttachmentToIssue", Label("app", "ComponentV
db.On("GetIssueMatches", &entity.IssueMatchFilter{
ComponentInstanceId: []*int64{&componentInstance.Id},
IssueId: []*int64{&issueEntity.Id},
}).Return([]entity.IssueMatch{existingMatch}, nil)
}, []entity.Order{}).Return([]entity.IssueMatch{existingMatch}, nil)

issue.OnComponentVersionAttachmentToIssue(db, event)
db.AssertNotCalled(GinkgoT(), "CreateIssueMatch", mock.Anything)
Expand Down
9 changes: 5 additions & 4 deletions internal/app/issue_match/issue_match_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ func (e *IssueMatchHandlerError) Error() string {
return e.message
}

func (h *issueMatchHandler) getIssueMatchResults(filter *entity.IssueMatchFilter) ([]entity.IssueMatchResult, error) {
func (h *issueMatchHandler) getIssueMatchResults(filter *entity.IssueMatchFilter, order []entity.Order) ([]entity.IssueMatchResult, error) {
var results []entity.IssueMatchResult
ims, err := h.database.GetIssueMatches(filter)
ims, err := h.database.GetIssueMatches(filter, order)
if err != nil {
return nil, err
}
Expand All @@ -65,7 +65,8 @@ func (im *issueMatchHandler) GetIssueMatch(issueMatchId int64) (*entity.IssueMat
"id": issueMatchId,
})
issueMatchFilter := entity.IssueMatchFilter{Id: []*int64{&issueMatchId}}
issueMatches, err := im.ListIssueMatches(&issueMatchFilter, &entity.ListOptions{})
options := entity.ListOptions{Order: []entity.Order{}}
issueMatches, err := im.ListIssueMatches(&issueMatchFilter, &options)

if err != nil {
l.Error(err)
Expand Down Expand Up @@ -95,7 +96,7 @@ func (im *issueMatchHandler) ListIssueMatches(filter *entity.IssueMatchFilter, o
"filter": filter,
})

res, err := im.getIssueMatchResults(filter)
res, err := im.getIssueMatchResults(filter, options.Order)

if err != nil {
l.Error(err)
Expand Down
2 changes: 1 addition & 1 deletion internal/app/issue_match/issue_match_handler_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func OnComponentVersionAssignmentToComponentInstance(db database.Database, compo
issue_matches, err := db.GetIssueMatches(&entity.IssueMatchFilter{
IssueId: []*int64{&issueId},
ComponentInstanceId: []*int64{&componentInstanceID},
})
}, nil)

if err != nil {
l.WithField("event-step", "FetchIssueMatches").WithError(err).Error("Error while fetching issue matches related to assigned Component Instance")
Expand Down
26 changes: 14 additions & 12 deletions internal/app/issue_match/issue_match_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ var _ = Describe("When listing IssueMatches", Label("app", "ListIssueMatches"),

BeforeEach(func() {
options.ShowTotalCount = true
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{}, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{}, nil)
db.On("CountIssueMatches", filter).Return(int64(1337), nil)
})

Expand All @@ -97,7 +97,7 @@ var _ = Describe("When listing IssueMatches", Label("app", "ListIssueMatches"),
i++
ids = append(ids, i)
}
db.On("GetIssueMatches", filter).Return(matches, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return(matches, nil)
db.On("GetAllIssueMatchIds", filter).Return(ids, nil)
issueMatchHandler = im.NewIssueMatchHandler(db, er, nil)
res, err := issueMatchHandler.ListIssueMatches(filter, options)
Expand All @@ -121,7 +121,7 @@ var _ = Describe("When listing IssueMatches", Label("app", "ListIssueMatches"),
Context("and the given filter does not have any matches in the database", func() {

BeforeEach(func() {
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{}, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{}, nil)
})
It("should return an empty result", func() {

Expand All @@ -134,7 +134,7 @@ var _ = Describe("When listing IssueMatches", Label("app", "ListIssueMatches"),
})
Context("and the filter does have results in the database", func() {
BeforeEach(func() {
db.On("GetIssueMatches", filter).Return(test.NNewFakeIssueMatches(15), nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return(test.NNewFakeIssueMatches(15), nil)
})
It("should return the expected matches in the result", func() {
issueMatchHandler = im.NewIssueMatchHandler(db, er, nil)
Expand All @@ -146,7 +146,7 @@ var _ = Describe("When listing IssueMatches", Label("app", "ListIssueMatches"),

Context("and the database operations throw an error", func() {
BeforeEach(func() {
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{}, errors.New("some error"))
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{}, errors.New("some error"))
})

It("should return the expected matches in the result", func() {
Expand Down Expand Up @@ -250,7 +250,7 @@ var _ = Describe("When updating IssueMatch", Label("app", "UpdateIssueMatch"), f
issueMatch.Status = entity.NewIssueMatchStatusValue("new")
}
filter.Id = []*int64{&issueMatch.Id}
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{issueMatch}, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{issueMatch}, nil)
updatedIssueMatch, err := issueMatchHandler.UpdateIssueMatch(&issueMatch)
Expect(err).To(BeNil(), "no error should be thrown")
By("setting fields", func() {
Expand All @@ -273,6 +273,7 @@ var _ = Describe("When deleting IssueMatch", Label("app", "DeleteIssueMatch"), f
issueMatchHandler im.IssueMatchHandler
id int64
filter *entity.IssueMatchFilter
options *entity.ListOptions
)

BeforeEach(func() {
Expand All @@ -287,17 +288,18 @@ var _ = Describe("When deleting IssueMatch", Label("app", "DeleteIssueMatch"), f
After: &after,
},
}
options = entity.NewListOptions()
})

It("deletes issueMatch", func() {
db.On("DeleteIssueMatch", id).Return(nil)
issueMatchHandler = im.NewIssueMatchHandler(db, er, nil)
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{}, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{}, nil)
err := issueMatchHandler.DeleteIssueMatch(id)
Expect(err).To(BeNil(), "no error should be thrown")

filter.Id = []*int64{&id}
issueMatches, err := issueMatchHandler.ListIssueMatches(filter, &entity.ListOptions{})
issueMatches, err := issueMatchHandler.ListIssueMatches(filter, options)
Expect(err).To(BeNil(), "no error should be thrown")
Expect(issueMatches.Elements).To(BeEmpty(), "no error should be thrown")
})
Expand Down Expand Up @@ -330,7 +332,7 @@ var _ = Describe("When modifying relationship of evidence and issueMatch", Label

It("adds evidence to issueMatch", func() {
db.On("AddEvidenceToIssueMatch", issueMatch.Id, evidence.Id).Return(nil)
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{issueMatch}, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{issueMatch}, nil)
issueMatchHandler = im.NewIssueMatchHandler(db, er, nil)
issueMatch, err := issueMatchHandler.AddEvidenceToIssueMatch(issueMatch.Id, evidence.Id)
Expect(err).To(BeNil(), "no error should be thrown")
Expand All @@ -339,7 +341,7 @@ var _ = Describe("When modifying relationship of evidence and issueMatch", Label

It("removes evidence from issueMatch", func() {
db.On("RemoveEvidenceFromIssueMatch", issueMatch.Id, evidence.Id).Return(nil)
db.On("GetIssueMatches", filter).Return([]entity.IssueMatch{issueMatch}, nil)
db.On("GetIssueMatches", filter, []entity.Order{}).Return([]entity.IssueMatch{issueMatch}, nil)
issueMatchHandler = im.NewIssueMatchHandler(db, er, nil)
issueMatch, err := issueMatchHandler.RemoveEvidenceFromIssueMatch(issueMatch.Id, evidence.Id)
Expect(err).To(BeNil(), "no error should be thrown")
Expand Down Expand Up @@ -467,7 +469,7 @@ var _ = Describe("OnComponentInstanceCreate", Label("app", "OnComponentInstanceC
})

It("should create issue matches for each issue", func() {
db.On("GetIssueMatches", mock.Anything).Return([]entity.IssueMatch{}, nil)
db.On("GetIssueMatches", mock.Anything, mock.Anything).Return([]entity.IssueMatch{}, nil)
// Mock CreateIssueMatch
db.On("CreateIssueMatch", mock.AnythingOfType("*entity.IssueMatch")).Return(&entity.IssueMatch{}, nil).Twice()
im.OnComponentVersionAssignmentToComponentInstance(db, componentInstanceID, componentVersionID)
Expand All @@ -482,7 +484,7 @@ var _ = Describe("OnComponentInstanceCreate", Label("app", "OnComponentInstanceC
issueMatch := test.NewFakeIssueMatch()
issueMatch.IssueId = 2 // issue2.Id
//when issueid is 2 return a fake issue match
db.On("GetIssueMatches", mock.Anything).Return([]entity.IssueMatch{issueMatch}, nil).Once()
db.On("GetIssueMatches", mock.Anything, mock.Anything).Return([]entity.IssueMatch{issueMatch}, nil).Once()
})

It("should should not create new issues", func() {
Expand Down
2 changes: 1 addition & 1 deletion internal/database/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type Database interface {
GetDefaultIssuePriority() int64
GetDefaultRepositoryName() string

GetIssueMatches(*entity.IssueMatchFilter) ([]entity.IssueMatch, error)
GetIssueMatches(*entity.IssueMatchFilter, []entity.Order) ([]entity.IssueMatch, error)
GetAllIssueMatchIds(*entity.IssueMatchFilter) ([]int64, error)
CountIssueMatches(filter *entity.IssueMatchFilter) (int64, error)
CreateIssueMatch(*entity.IssueMatch) (*entity.IssueMatch, error)
Expand Down
8 changes: 8 additions & 0 deletions internal/database/mariadb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,11 @@ func getCursor(p entity.Paginated, filterStr string, stmt string) entity.Cursor
Limit: limit,
}
}

func GetDefaultOrder(order []entity.Order, by entity.DbColumnName, direction entity.OrderDirection) []entity.Order {
if len(order) == 0 {
order = append([]entity.Order{{By: by, Direction: direction}}, order...)
}

return order
}
Loading