diff --git a/README.md b/README.md index febbc260..dd538cb1 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ For a detailed understanding of Heureka's architecture and design, refer to the - [High-Level Architecture Diagram](https://github.com/cloudoperators/heureka/blob/main/docs/product_design_documentation.md#high-level-features): This provides a visual representation of the overall system architecture. - [High-Level Features](https://github.com/cloudoperators/heureka/blob/main/docs/product_design_documentation.md#high-level-features): A high-level overview of Heureka's functionalities. - ## Requirements and Setup The application can be configured using environment variables. These variables are stored in a `.env` file at the root of the project. diff --git a/go.mod b/go.mod index 3dd6a656..03f36829 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/samber/lo v1.47.0 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 + github.com/vektah/gqlparser/v2 v2.5.19 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 ) @@ -85,7 +86,6 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect github.com/urfave/cli/v2 v2.27.5 // indirect - github.com/vektah/gqlparser/v2 v2.5.19 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect diff --git a/internal/api/graphql/graph/baseResolver/common.go b/internal/api/graphql/graph/baseResolver/common.go index dcb162b5..1e83a5fd 100644 --- a/internal/api/graphql/graph/baseResolver/common.go +++ b/internal/api/graphql/graph/baseResolver/common.go @@ -102,6 +102,6 @@ func GetListOptions(requestedFields []string) *entity.ListOptions { return &entity.ListOptions{ ShowTotalCount: lo.Contains(requestedFields, "totalCount"), ShowPageInfo: lo.Contains(requestedFields, "pageInfo"), - IncludeAggregations: lo.Contains(requestedFields, "edges.node.metadata"), + IncludeAggregations: lo.Contains(requestedFields, "edges.node.objectMetadata"), } } diff --git a/internal/api/graphql/graph/model/models.go b/internal/api/graphql/graph/model/models.go index 4fe2052a..7089bd5f 100644 --- a/internal/api/graphql/graph/model/models.go +++ b/internal/api/graphql/graph/model/models.go @@ -15,6 +15,18 @@ import ( ) // add custom models here +func getModelMetadata(em entity.Metadata) *Metadata { + createdAt := em.CreatedAt.String() + deletedAt := em.DeletedAt.String() + updatedAt := em.UpdatedAt.String() + return &Metadata{ + CreatedAt: util.Ptr(createdAt), + CreatedBy: util.Ptr(fmt.Sprintf("%d", em.CreatedBy)), + DeletedAt: util.Ptr(deletedAt), + UpdatedAt: util.Ptr(updatedAt), + UpdatedBy: util.Ptr(fmt.Sprintf("%d", em.UpdatedBy)), + } +} var AllSeverityValuesOrdered = []SeverityValues{ SeverityValuesCritical, @@ -160,6 +172,7 @@ func NewIssue(issue *entity.Issue) Issue { Type: &issueType, Description: &issue.Description, LastModified: &lastModified, + Metadata: getModelMetadata(issue.Metadata), } } @@ -167,10 +180,10 @@ func NewIssueWithAggregations(issue *entity.IssueResult) Issue { lastModified := issue.Issue.UpdatedAt.String() issueType := IssueTypes(issue.Type.String()) - var metadata IssueMetadata + var objectMetadata IssueMetadata if issue.IssueAggregations != nil { - metadata = IssueMetadata{ + objectMetadata = IssueMetadata{ ServiceCount: int(issue.IssueAggregations.AffectedServices), ActivityCount: int(issue.IssueAggregations.Activities), IssueMatchCount: int(issue.IssueAggregations.IssueMatches), @@ -182,11 +195,13 @@ func NewIssueWithAggregations(issue *entity.IssueResult) Issue { } return Issue{ - ID: fmt.Sprintf("%d", issue.Issue.Id), - PrimaryName: &issue.Issue.PrimaryName, - Type: &issueType, - LastModified: &lastModified, - Metadata: &metadata, + ID: fmt.Sprintf("%d", issue.Issue.Id), + PrimaryName: &issue.Issue.PrimaryName, + Type: &issueType, + Description: &issue.Issue.Description, + LastModified: &lastModified, + ObjectMetadata: &objectMetadata, + Metadata: getModelMetadata(issue.Issue.Metadata), } } @@ -218,6 +233,7 @@ func NewIssueMatch(im *entity.IssueMatch) IssueMatch { IssueID: util.Ptr(fmt.Sprintf("%d", im.IssueId)), ComponentInstanceID: util.Ptr(fmt.Sprintf("%d", im.ComponentInstanceId)), UserID: util.Ptr(fmt.Sprintf("%d", im.UserId)), + Metadata: getModelMetadata(im.Metadata), } } @@ -240,7 +256,7 @@ func NewIssueMatchEntity(im *IssueMatchInput) entity.IssueMatch { IssueId: issueId, ComponentInstanceId: ciId, UserId: userId, - CreatedAt: createdAt, + Metadata: entity.Metadata{CreatedAt: createdAt}, } } @@ -253,6 +269,7 @@ func NewIssueMatchChange(imc *entity.IssueMatchChange) IssueMatchChange { IssueMatch: nil, ActivityID: util.Ptr(fmt.Sprintf("%d", imc.ActivityId)), Activity: nil, + Metadata: getModelMetadata(imc.Metadata), } } @@ -268,16 +285,13 @@ func NewIssueMatchChangeEntity(imc *IssueMatchChangeInput) entity.IssueMatchChan } func NewIssueRepository(repo *entity.IssueRepository) IssueRepository { - createdAt := repo.BaseIssueRepository.CreatedAt.String() - updatedAt := repo.BaseIssueRepository.UpdatedAt.String() return IssueRepository{ ID: fmt.Sprintf("%d", repo.Id), Name: &repo.Name, URL: &repo.Url, Services: nil, IssueVariants: nil, - CreatedAt: &createdAt, - UpdatedAt: &updatedAt, + Metadata: getModelMetadata(repo.BaseIssueRepository.Metadata), } } @@ -295,8 +309,6 @@ func NewIssueVariant(issueVariant *entity.IssueVariant) IssueVariant { if issueVariant.IssueRepository != nil { repo = NewIssueRepository(issueVariant.IssueRepository) } - createdAt := issueVariant.CreatedAt.String() - updatedAt := issueVariant.UpdatedAt.String() return IssueVariant{ ID: fmt.Sprintf("%d", issueVariant.Id), SecondaryName: &issueVariant.SecondaryName, @@ -305,20 +317,16 @@ func NewIssueVariant(issueVariant *entity.IssueVariant) IssueVariant { IssueID: util.Ptr(fmt.Sprintf("%d", issueVariant.IssueId)), IssueRepositoryID: util.Ptr(fmt.Sprintf("%d", issueVariant.IssueRepositoryId)), IssueRepository: &repo, - CreatedAt: &createdAt, - UpdatedAt: &updatedAt, + Metadata: getModelMetadata(issueVariant.Metadata), } } func NewIssueVariantEdge(issueVariant *entity.IssueVariant) IssueVariantEdge { iv := NewIssueVariant(issueVariant) - edgeCreationDate := issueVariant.CreatedAt.String() - edgeUpdateDate := issueVariant.UpdatedAt.String() issueVariantEdge := IssueVariantEdge{ - Node: &iv, - Cursor: &iv.ID, - CreatedAt: &edgeCreationDate, - UpdatedAt: &edgeUpdateDate, + Node: &iv, + Cursor: &iv.ID, + Metadata: getModelMetadata(issueVariant.Metadata), } return issueVariantEdge } @@ -341,6 +349,7 @@ func NewUser(user *entity.User) User { UniqueUserID: &user.UniqueUserID, Name: &user.Name, Type: int(user.Type), + Metadata: getModelMetadata(user.Metadata), } } @@ -354,25 +363,27 @@ func NewUserEntity(user *UserInput) entity.User { func NewService(s *entity.Service) Service { return Service{ - ID: fmt.Sprintf("%d", s.Id), - Ccrn: &s.CCRN, + ID: fmt.Sprintf("%d", s.Id), + Ccrn: &s.CCRN, + Metadata: getModelMetadata(s.BaseService.Metadata), } } func NewServiceWithAggregations(service *entity.ServiceResult) Service { - var metadata ServiceMetadata + var objectMetadata ServiceMetadata if service.ServiceAggregations != nil { - metadata = ServiceMetadata{ + objectMetadata = ServiceMetadata{ IssueMatchCount: int(service.ServiceAggregations.IssueMatches), ComponentInstanceCount: int(service.ServiceAggregations.ComponentInstances), } } return Service{ - ID: fmt.Sprintf("%d", service.Id), - Ccrn: &service.CCRN, - Metadata: &metadata, + ID: fmt.Sprintf("%d", service.Id), + Ccrn: &service.CCRN, + ObjectMetadata: &objectMetadata, + Metadata: getModelMetadata(service.BaseService.Metadata), } } @@ -386,8 +397,9 @@ func NewServiceEntity(service *ServiceInput) entity.Service { func NewSupportGroup(supportGroup *entity.SupportGroup) SupportGroup { return SupportGroup{ - ID: fmt.Sprintf("%d", supportGroup.Id), - Ccrn: &supportGroup.CCRN, + ID: fmt.Sprintf("%d", supportGroup.Id), + Ccrn: &supportGroup.CCRN, + Metadata: getModelMetadata(supportGroup.Metadata), } } @@ -400,8 +412,9 @@ func NewSupportGroupEntity(supportGroup *SupportGroupInput) entity.SupportGroup func NewActivity(activity *entity.Activity) Activity { status := ActivityStatusValues(activity.Status.String()) return Activity{ - ID: fmt.Sprintf("%d", activity.Id), - Status: &status, + ID: fmt.Sprintf("%d", activity.Id), + Status: &status, + Metadata: getModelMetadata(activity.Metadata), } } @@ -429,6 +442,7 @@ func NewEvidence(evidence *entity.Evidence) Evidence { Vector: severity.Cvss.Vector, Type: &t, RaaEnd: &raaEnd, + Metadata: getModelMetadata(evidence.Metadata), } } @@ -451,9 +465,10 @@ func NewEvidenceEntity(evidence *EvidenceInput) entity.Evidence { func NewComponent(component *entity.Component) Component { componentType, _ := ComponentTypeValue(component.Type) return Component{ - ID: fmt.Sprintf("%d", component.Id), - Ccrn: &component.CCRN, - Type: &componentType, + ID: fmt.Sprintf("%d", component.Id), + Ccrn: &component.CCRN, + Type: &componentType, + Metadata: getModelMetadata(component.Metadata), } } @@ -473,6 +488,7 @@ func NewComponentVersion(componentVersion *entity.ComponentVersion) ComponentVer ID: fmt.Sprintf("%d", componentVersion.Id), Version: &componentVersion.Version, ComponentID: util.Ptr(fmt.Sprintf("%d", componentVersion.ComponentId)), + Metadata: getModelMetadata(componentVersion.Metadata), } } @@ -495,6 +511,7 @@ func NewComponentInstance(componentInstance *entity.ComponentInstance) Component Count: &count, ComponentVersionID: util.Ptr(fmt.Sprintf("%d", componentInstance.ComponentVersionId)), ServiceID: util.Ptr(fmt.Sprintf("%d", componentInstance.ServiceId)), + Metadata: getModelMetadata(componentInstance.Metadata), } } diff --git a/internal/api/graphql/graph/queryCollection/componentInstance/directRelations.graphql b/internal/api/graphql/graph/queryCollection/componentInstance/directRelations.graphql index 1ef71306..62194d34 100644 --- a/internal/api/graphql/graph/queryCollection/componentInstance/directRelations.graphql +++ b/internal/api/graphql/graph/queryCollection/componentInstance/directRelations.graphql @@ -25,8 +25,10 @@ query ($filter: ComponentInstanceFilter, $first: Int, $after: String) { id ccrn } - createdAt - updatedAt + metadata { + created_at + updated_at + } issueMatches { totalCount edges { @@ -57,4 +59,4 @@ query ($filter: ComponentInstanceFilter, $first: Int, $after: String) { } } } -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/queryCollection/issue/create.graphql b/internal/api/graphql/graph/queryCollection/issue/create.graphql index 33383af3..7e1ebf78 100644 --- a/internal/api/graphql/graph/queryCollection/issue/create.graphql +++ b/internal/api/graphql/graph/queryCollection/issue/create.graphql @@ -10,4 +10,4 @@ mutation ($input: IssueInput!) { description type } -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/queryCollection/issue/directRelations.graphql b/internal/api/graphql/graph/queryCollection/issue/directRelations.graphql index 31c599d7..8dc0c8a7 100644 --- a/internal/api/graphql/graph/queryCollection/issue/directRelations.graphql +++ b/internal/api/graphql/graph/queryCollection/issue/directRelations.graphql @@ -33,16 +33,22 @@ query ($filter: IssueFilter, $first: Int, $after: String) { id name url + metadata { + created_at + updated_at + } + } + issueId + metadata { created_at updated_at } - issueId + } + cursor + metadata { created_at updated_at } - cursor - created_at - updated_at } pageInfo { hasNextPage @@ -61,8 +67,10 @@ query ($filter: IssueFilter, $first: Int, $after: String) { componentInstance { id count - createdAt - updatedAt + metadata { + created_at + updated_at + } ccrn } } @@ -73,7 +81,7 @@ query ($filter: IssueFilter, $first: Int, $after: String) { nextPageAfter } } - metadata { + objectMetadata { serviceCount activityCount issueMatchCount @@ -98,4 +106,4 @@ query ($filter: IssueFilter, $first: Int, $after: String) { } } } -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/queryCollection/issue/listIssues.graphql b/internal/api/graphql/graph/queryCollection/issue/listIssues.graphql new file mode 100644 index 00000000..318e8b22 --- /dev/null +++ b/internal/api/graphql/graph/queryCollection/issue/listIssues.graphql @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +query ($filter: IssueFilter, $first: Int, $after: String) { + Issues ( + filter: $filter, + first: $first, + after: $after + ) { + totalCount + edges { + node { + id + primaryName + type + description + metadata { + created_at + created_by + deleted_at + updated_at + updated_by + } + } + cursor + } + } +} diff --git a/internal/api/graphql/graph/queryCollection/issue/withMetadata.graphql b/internal/api/graphql/graph/queryCollection/issue/withObjectMetadata.graphql similarity index 97% rename from internal/api/graphql/graph/queryCollection/issue/withMetadata.graphql rename to internal/api/graphql/graph/queryCollection/issue/withObjectMetadata.graphql index 669a1022..0cfce82d 100644 --- a/internal/api/graphql/graph/queryCollection/issue/withMetadata.graphql +++ b/internal/api/graphql/graph/queryCollection/issue/withObjectMetadata.graphql @@ -12,7 +12,7 @@ query ($filter: IssueFilter, $first: Int, $after: String) { node { id lastModified - metadata { + objectMetadata { serviceCount activityCount issueMatchCount diff --git a/internal/api/graphql/graph/queryCollection/issueRepository/directRelations.graphql b/internal/api/graphql/graph/queryCollection/issueRepository/directRelations.graphql index db574c98..411f5ca4 100644 --- a/internal/api/graphql/graph/queryCollection/issueRepository/directRelations.graphql +++ b/internal/api/graphql/graph/queryCollection/issueRepository/directRelations.graphql @@ -23,12 +23,16 @@ query ($filter: IssueRepositoryFilter, $first: Int, $after: String) { description issueRepositoryId issueId + metadata { + created_at + updated_at + } + } + cursor + metadata { created_at updated_at } - cursor - created_at - updated_at } pageInfo { hasNextPage @@ -50,12 +54,16 @@ query ($filter: IssueRepositoryFilter, $first: Int, $after: String) { nextPageAfter } } + metadata { + created_at + updated_at + } + } + cursor + metadata { created_at updated_at } - cursor - created_at - updated_at } pageInfo { hasNextPage @@ -71,4 +79,4 @@ query ($filter: IssueRepositoryFilter, $first: Int, $after: String) { } } } -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/queryCollection/issueVariant/directRelations.graphql b/internal/api/graphql/graph/queryCollection/issueVariant/directRelations.graphql index f2402acd..a9c1bae3 100644 --- a/internal/api/graphql/graph/queryCollection/issueVariant/directRelations.graphql +++ b/internal/api/graphql/graph/queryCollection/issueVariant/directRelations.graphql @@ -23,20 +23,26 @@ query ($filter: IssueVariantFilter, $first: Int, $after: String) { id name url - created_at - updated_at + metadata { + created_at + updated_at + } } issueId issue { id lastModified } + metadata { + created_at + updated_at + } + } + cursor + metadata { created_at updated_at } - cursor - created_at - updated_at } pageInfo { hasNextPage @@ -52,4 +58,4 @@ query ($filter: IssueVariantFilter, $first: Int, $after: String) { } } } -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/queryCollection/service/directRelations.graphql b/internal/api/graphql/graph/queryCollection/service/directRelations.graphql index 3b1f6b75..eecf91c9 100644 --- a/internal/api/graphql/graph/queryCollection/service/directRelations.graphql +++ b/internal/api/graphql/graph/queryCollection/service/directRelations.graphql @@ -63,13 +63,17 @@ query ($filter: ServiceFilter, $first: Int, $after: String) { id name url - created_at - updated_at + metadata { + created_at + updated_at + } } cursor priority - created_at - updated_at + metadata { + created_at + updated_at + } } pageInfo { hasNextPage diff --git a/internal/api/graphql/graph/queryCollection/service/withMetadata.graphql b/internal/api/graphql/graph/queryCollection/service/withObjectMetadata.graphql similarity index 96% rename from internal/api/graphql/graph/queryCollection/service/withMetadata.graphql rename to internal/api/graphql/graph/queryCollection/service/withObjectMetadata.graphql index ae54a716..aaa17253 100644 --- a/internal/api/graphql/graph/queryCollection/service/withMetadata.graphql +++ b/internal/api/graphql/graph/queryCollection/service/withObjectMetadata.graphql @@ -22,7 +22,7 @@ query ($filter: ServiceFilter, $first: Int, $after: String) { } } } - metadata { + objectMetadata { issueMatchCount componentInstanceCount } @@ -30,4 +30,4 @@ query ($filter: ServiceFilter, $first: Int, $after: String) { cursor } } -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/queryCollection/user/listUsers.graphql b/internal/api/graphql/graph/queryCollection/user/listUsers.graphql new file mode 100644 index 00000000..9fd813a3 --- /dev/null +++ b/internal/api/graphql/graph/queryCollection/user/listUsers.graphql @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +query ($filter: UserFilter, $first: Int, $after: String) { + Users ( + filter: $filter, + first: $first, + after: $after + ) { + totalCount + edges { + node { + id + name + type + metadata { + created_at + created_by + deleted_at + updated_at + updated_by + } + } + cursor + } + } +} diff --git a/internal/api/graphql/graph/schema/activity.graphqls b/internal/api/graphql/graph/schema/activity.graphqls index 0b4dd782..c7029148 100644 --- a/internal/api/graphql/graph/schema/activity.graphqls +++ b/internal/api/graphql/graph/schema/activity.graphqls @@ -8,6 +8,7 @@ type Activity implements Node { issues(filter: IssueFilter, first: Int, after: String): IssueConnection evidences(filter: EvidenceFilter, first: Int, after: String): EvidenceConnection issueMatchChanges(filter: IssueMatchChangeFilter, first: Int, after: String): IssueMatchChangeConnection + metadata: Metadata } input ActivityInput { @@ -23,6 +24,7 @@ type ActivityConnection implements Connection { type ActivityEdge implements Edge { node: Activity! cursor: String + metadata: Metadata } input ActivityFilter { @@ -34,4 +36,4 @@ enum ActivityStatusValues { open, closed, in_progress -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/common.graphqls b/internal/api/graphql/graph/schema/common.graphqls index 9a97275c..ee15d2b7 100644 --- a/internal/api/graphql/graph/schema/common.graphqls +++ b/internal/api/graphql/graph/schema/common.graphqls @@ -104,4 +104,12 @@ type FilterItem { displayName: String filterName: String values: [String] -} \ No newline at end of file +} + +type Metadata { + created_at: DateTime + created_by: String + deleted_at: DateTime + updated_at: DateTime + updated_by: String +} diff --git a/internal/api/graphql/graph/schema/component.graphqls b/internal/api/graphql/graph/schema/component.graphqls index 025601e1..302322da 100644 --- a/internal/api/graphql/graph/schema/component.graphqls +++ b/internal/api/graphql/graph/schema/component.graphqls @@ -6,6 +6,7 @@ type Component implements Node { ccrn: String type: ComponentTypeValues componentVersions(filter: ComponentVersionFilter, first: Int, after: String): ComponentVersionConnection + metadata: Metadata } input ComponentInput { @@ -32,4 +33,4 @@ type ComponentConnection implements Connection { type ComponentEdge implements Edge { node: Component! cursor: String -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/component_instance.graphqls b/internal/api/graphql/graph/schema/component_instance.graphqls index 66d25d28..3d909907 100644 --- a/internal/api/graphql/graph/schema/component_instance.graphqls +++ b/internal/api/graphql/graph/schema/component_instance.graphqls @@ -10,8 +10,7 @@ type ComponentInstance implements Node { issueMatches(filter: IssueMatchFilter, first: Int, after: String): IssueMatchConnection serviceId: String service: Service - createdAt: DateTime - updatedAt: DateTime + metadata: Metadata } input ComponentInstanceInput { @@ -37,4 +36,4 @@ input ComponentInstanceFilter { ccrn: [String], supportGroup: [String], search:[String], -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/component_version.graphqls b/internal/api/graphql/graph/schema/component_version.graphqls index 597292a5..36fe0026 100644 --- a/internal/api/graphql/graph/schema/component_version.graphqls +++ b/internal/api/graphql/graph/schema/component_version.graphqls @@ -8,6 +8,7 @@ type ComponentVersion implements Node { component: Component issues(first: Int, after: String): IssueConnection componentInstances(first: Int, after: String): ComponentInstanceConnection + metadata: Metadata } input ComponentVersionInput { @@ -31,4 +32,4 @@ input ComponentVersionFilter { componentCcrn: [String] issueId: [String] version: [String] -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/evidence.graphqls b/internal/api/graphql/graph/schema/evidence.graphqls index 9f76a0ed..faee3485 100644 --- a/internal/api/graphql/graph/schema/evidence.graphqls +++ b/internal/api/graphql/graph/schema/evidence.graphqls @@ -13,6 +13,7 @@ type Evidence implements Node { activityId: String activity: Activity issueMatches(filter: IssueMatchFilter, first: Int, after: String): IssueMatchConnection + metadata: Metadata } input EvidenceInput { @@ -37,4 +38,4 @@ type EvidenceEdge implements Edge { input EvidenceFilter { placeholder: [Boolean] -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/issue.graphqls b/internal/api/graphql/graph/schema/issue.graphqls index 5236b9f8..370f5a80 100644 --- a/internal/api/graphql/graph/schema/issue.graphqls +++ b/internal/api/graphql/graph/schema/issue.graphqls @@ -13,7 +13,8 @@ type Issue implements Node { activities(filter: ActivityFilter, first: Int, after: String): ActivityConnection issueMatches(filter: IssueMatchFilter, first: Int, after: String): IssueMatchConnection componentVersions(filter: ComponentVersionFilter, first: Int, after: String): ComponentVersionConnection - metadata: IssueMetadata + objectMetadata: IssueMetadata + metadata: Metadata } type IssueMetadata { diff --git a/internal/api/graphql/graph/schema/issue_match.graphqls b/internal/api/graphql/graph/schema/issue_match.graphqls index 5ca68780..70108ed7 100644 --- a/internal/api/graphql/graph/schema/issue_match.graphqls +++ b/internal/api/graphql/graph/schema/issue_match.graphqls @@ -17,6 +17,7 @@ type IssueMatch implements Node { componentInstanceId: String componentInstance: ComponentInstance! issueMatchChanges(filter: IssueMatchChangeFilter, first: Int, after: String): IssueMatchChangeConnection + metadata: Metadata } input IssueMatchInput { diff --git a/internal/api/graphql/graph/schema/issue_match_change.graphqls b/internal/api/graphql/graph/schema/issue_match_change.graphqls index 84724ac0..65385d01 100644 --- a/internal/api/graphql/graph/schema/issue_match_change.graphqls +++ b/internal/api/graphql/graph/schema/issue_match_change.graphqls @@ -9,6 +9,7 @@ type IssueMatchChange implements Node { issueMatch: IssueMatch! activityId: String activity: Activity! + metadata: Metadata } input IssueMatchChangeInput { diff --git a/internal/api/graphql/graph/schema/issue_repository.graphqls b/internal/api/graphql/graph/schema/issue_repository.graphqls index f34eef63..eb4cae34 100644 --- a/internal/api/graphql/graph/schema/issue_repository.graphqls +++ b/internal/api/graphql/graph/schema/issue_repository.graphqls @@ -7,8 +7,7 @@ type IssueRepository implements Node { url: String issueVariants(filter: IssueVariantFilter, first: Int, after: String): IssueVariantConnection services(filter: ServiceFilter, first: Int, after: String): ServiceConnection - created_at: DateTime - updated_at: DateTime + metadata: Metadata } input IssueRepositoryInput { @@ -26,12 +25,11 @@ type IssueRepositoryEdge implements Edge { node: IssueRepository! cursor: String priority: Int - created_at: DateTime - updated_at: DateTime + metadata: Metadata } input IssueRepositoryFilter { serviceCcrn: [String] serviceId: [String] name: [String] -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/issue_variant.graphqls b/internal/api/graphql/graph/schema/issue_variant.graphqls index f6ffc280..8f688f65 100644 --- a/internal/api/graphql/graph/schema/issue_variant.graphqls +++ b/internal/api/graphql/graph/schema/issue_variant.graphqls @@ -10,8 +10,7 @@ type IssueVariant implements Node { issueRepository: IssueRepository issueId: String issue: Issue - created_at: DateTime - updated_at: DateTime + metadata: Metadata } input IssueVariantInput { @@ -31,10 +30,9 @@ type IssueVariantConnection implements Connection { type IssueVariantEdge implements Edge { node: IssueVariant! cursor: String - created_at: DateTime - updated_at: DateTime + metadata: Metadata } input IssueVariantFilter { secondaryName: [String] -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/service.graphqls b/internal/api/graphql/graph/schema/service.graphqls index 219596da..2a36af8c 100644 --- a/internal/api/graphql/graph/schema/service.graphqls +++ b/internal/api/graphql/graph/schema/service.graphqls @@ -9,7 +9,9 @@ type Service implements Node { activities(filter: ActivityFilter, first: Int, after: String): ActivityConnection issueRepositories(filter: IssueRepositoryFilter, first: Int, after: String): IssueRepositoryConnection componentInstances(filter: ComponentInstanceFilter, first: Int, after: String): ComponentInstanceConnection - metadata: ServiceMetadata + objectMetadata: ServiceMetadata + metadata: Metadata + } type ServiceMetadata { diff --git a/internal/api/graphql/graph/schema/support_group.graphqls b/internal/api/graphql/graph/schema/support_group.graphqls index 90060247..b66d4e0f 100644 --- a/internal/api/graphql/graph/schema/support_group.graphqls +++ b/internal/api/graphql/graph/schema/support_group.graphqls @@ -6,6 +6,7 @@ type SupportGroup implements Node { ccrn: String users(filter: UserFilter, first: Int, after: String): UserConnection services(filter: ServiceFilter, first: Int, after: String): ServiceConnection + metadata: Metadata } input SupportGroupInput { @@ -26,4 +27,4 @@ type SupportGroupEdge implements Edge { input SupportGroupFilter { supportGroupCcrn: [String], userIds: [String], -} \ No newline at end of file +} diff --git a/internal/api/graphql/graph/schema/user.graphqls b/internal/api/graphql/graph/schema/user.graphqls index 91b7d12a..2cd19c19 100644 --- a/internal/api/graphql/graph/schema/user.graphqls +++ b/internal/api/graphql/graph/schema/user.graphqls @@ -8,6 +8,7 @@ type User implements Node { name: String supportGroups(filter: SupportGroupFilter, first: Int, after: String): SupportGroupConnection services(filter: ServiceFilter, first: Int, after: String): ServiceConnection + metadata: Metadata } input UserInput { diff --git a/internal/app/activity/activity_handler.go b/internal/app/activity/activity_handler.go index b85dd821..00b3d0bb 100644 --- a/internal/app/activity/activity_handler.go +++ b/internal/app/activity/activity_handler.go @@ -137,6 +137,13 @@ func (a *activityHandler) CreateActivity(activity *entity.Activity) (*entity.Act "object": activity, }) + var err error + activity.CreatedBy, err = common.GetCurrentUserId(a.database) + if err != nil { + l.Error(err) + return nil, NewActivityHandlerError("Internal error while creating activity (GetUserId).") + } + newActivity, err := a.database.CreateActivity(activity) if err != nil { @@ -157,7 +164,14 @@ func (a *activityHandler) UpdateActivity(activity *entity.Activity) (*entity.Act "object": activity, }) - err := a.database.UpdateActivity(activity) + var err error + activity.UpdatedBy, err = common.GetCurrentUserId(a.database) + if err != nil { + l.Error(err) + return nil, NewActivityHandlerError("Internal error while updating activity (GetUserId).") + } + + err = a.database.UpdateActivity(activity) if err != nil { l.Error(err) diff --git a/internal/app/activity/activity_handler_test.go b/internal/app/activity/activity_handler_test.go index 208970c7..f768d6fe 100644 --- a/internal/app/activity/activity_handler_test.go +++ b/internal/app/activity/activity_handler_test.go @@ -17,6 +17,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestActivityHandler(t *testing.T) { @@ -114,6 +115,7 @@ var _ = Describe("When creating Activity", Label("app", "CreateActivity"), func( }) It("creates activity", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateActivity", &activity).Return(&activity, nil) activityHandler = a.NewActivityHandler(db, er) newActivity, err := activityHandler.CreateActivity(&activity) @@ -147,6 +149,7 @@ var _ = Describe("When updating Activity", Label("app", "UpdateService"), func() }) It("updates activity", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateActivity", &activity).Return(nil) activityHandler = a.NewActivityHandler(db, er) if activity.Status.String() == entity.ActivityStatusValuesOpen.String() { diff --git a/internal/app/common/user_id.go b/internal/app/common/user_id.go new file mode 100644 index 00000000..173dd0ba --- /dev/null +++ b/internal/app/common/user_id.go @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "fmt" + + "github.com/cloudoperators/heureka/internal/database" + "github.com/cloudoperators/heureka/internal/entity" +) + +func GetCurrentUserId(db database.Database) (int64, error) { + return getUserIdFromDb(db, "S0000000") +} + +func getUserIdFromDb(db database.Database, uniqueUserId string) (int64, error) { + filter := &entity.UserFilter{UniqueUserID: []*string{&uniqueUserId}} + ids, err := db.GetAllUserIds(filter) + if err != nil { + return 0, fmt.Errorf("Unable to get user ids %w", err) + } else if len(ids) < 1 { + return 0, nil + } + return ids[0], nil +} diff --git a/internal/app/component/component_handler.go b/internal/app/component/component_handler.go index 6afae4e8..975635c6 100644 --- a/internal/app/component/component_handler.go +++ b/internal/app/component/component_handler.go @@ -115,6 +115,13 @@ func (cs *componentHandler) CreateComponent(component *entity.Component) (*entit "filter": f, }) + var err error + component.CreatedBy, err = common.GetCurrentUserId(cs.database) + if err != nil { + l.Error(err) + return nil, NewUserHandlerError("Internal error while creating component (GetUserId).") + } + components, err := cs.ListComponents(f, &entity.ListOptions{}) if err != nil { @@ -144,7 +151,14 @@ func (cs *componentHandler) UpdateComponent(component *entity.Component) (*entit "object": component, }) - err := cs.database.UpdateComponent(component) + var err error + component.UpdatedBy, err = common.GetCurrentUserId(cs.database) + if err != nil { + l.Error(err) + return nil, NewUserHandlerError("Internal error while updating component (GetUserId).") + } + + err = cs.database.UpdateComponent(component) if err != nil { l.Error(err) diff --git a/internal/app/component/component_handler_test.go b/internal/app/component/component_handler_test.go index 335337d1..4dee1a12 100644 --- a/internal/app/component/component_handler_test.go +++ b/internal/app/component/component_handler_test.go @@ -16,6 +16,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestComponentHandler(t *testing.T) { @@ -125,6 +126,7 @@ var _ = Describe("When creating Component", Label("app", "CreateComponent"), fun It("creates component", func() { filter.CCRN = []*string{&component.CCRN} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateComponent", &component).Return(&component, nil) db.On("GetComponents", filter).Return([]entity.Component{}, nil) componentHandler = c.NewComponentHandler(db, er) @@ -161,6 +163,7 @@ var _ = Describe("When updating Component", Label("app", "UpdateComponent"), fun }) It("updates component", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateComponent", &component).Return(nil) componentHandler = c.NewComponentHandler(db, er) component.CCRN = "NewComponent" diff --git a/internal/app/component_instance/component_instance_handler.go b/internal/app/component_instance/component_instance_handler.go index 446a157b..129c361d 100644 --- a/internal/app/component_instance/component_instance_handler.go +++ b/internal/app/component_instance/component_instance_handler.go @@ -116,6 +116,13 @@ func (ci *componentInstanceHandler) CreateComponentInstance(componentInstance *e "object": componentInstance, }) + var err error + componentInstance.CreatedBy, err = common.GetCurrentUserId(ci.database) + if err != nil { + l.Error(err) + return nil, NewComponentInstanceHandlerError("Internal error while creating componentInstance (GetUserId).") + } + newComponentInstance, err := ci.database.CreateComponentInstance(componentInstance) if err != nil { @@ -136,7 +143,14 @@ func (ci *componentInstanceHandler) UpdateComponentInstance(componentInstance *e "object": componentInstance, }) - err := ci.database.UpdateComponentInstance(componentInstance) + var err error + componentInstance.UpdatedBy, err = common.GetCurrentUserId(ci.database) + if err != nil { + l.Error(err) + return nil, NewComponentInstanceHandlerError("Internal error while updating componentInstance (GetUserId).") + } + + err = ci.database.UpdateComponentInstance(componentInstance) if err != nil { l.Error(err) diff --git a/internal/app/component_instance/component_instance_handler_test.go b/internal/app/component_instance/component_instance_handler_test.go index e87dccd5..a5a1d470 100644 --- a/internal/app/component_instance/component_instance_handler_test.go +++ b/internal/app/component_instance/component_instance_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestComponentInstanceHandler(t *testing.T) { @@ -121,6 +122,7 @@ var _ = Describe("When creating ComponentInstance", Label("app", "CreateComponen }) It("creates componentInstance", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateComponentInstance", &componentInstance).Return(&componentInstance, nil) componentInstanceHandler = ci.NewComponentInstanceHandler(db, er) newComponentInstance, err := componentInstanceHandler.CreateComponentInstance(&componentInstance) @@ -158,6 +160,7 @@ var _ = Describe("When updating ComponentInstance", Label("app", "UpdateComponen }) It("updates componentInstance", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateComponentInstance", &componentInstance).Return(nil) componentInstanceHandler = ci.NewComponentInstanceHandler(db, er) componentInstance.CCRN = "NewCCRN" diff --git a/internal/app/component_version/component_version_handler.go b/internal/app/component_version/component_version_handler.go index 47cadc33..1ae6b932 100644 --- a/internal/app/component_version/component_version_handler.go +++ b/internal/app/component_version/component_version_handler.go @@ -114,6 +114,13 @@ func (cv *componentVersionHandler) CreateComponentVersion(componentVersion *enti "object": componentVersion, }) + var err error + componentVersion.CreatedBy, err = common.GetCurrentUserId(cv.database) + if err != nil { + l.Error(err) + return nil, NewComponentVersionHandlerError("Internal error while creating componentVersion (GetUserId).") + } + newComponent, err := cv.database.CreateComponentVersion(componentVersion) if err != nil { @@ -138,7 +145,14 @@ func (cv *componentVersionHandler) UpdateComponentVersion(componentVersion *enti "object": componentVersion, }) - err := cv.database.UpdateComponentVersion(componentVersion) + var err error + componentVersion.UpdatedBy, err = common.GetCurrentUserId(cv.database) + if err != nil { + l.Error(err) + return nil, NewComponentVersionHandlerError("Internal error while updating componentVersion (GetUserId).") + } + + err = cv.database.UpdateComponentVersion(componentVersion) if err != nil { l.Error(err) diff --git a/internal/app/component_version/component_version_handler_test.go b/internal/app/component_version/component_version_handler_test.go index 88d31e00..71c948b3 100644 --- a/internal/app/component_version/component_version_handler_test.go +++ b/internal/app/component_version/component_version_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestComponentVersionHandler(t *testing.T) { @@ -111,6 +112,7 @@ var _ = Describe("When creating ComponentVersion", Label("app", "CreateComponent }) It("creates componentVersion", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateComponentVersion", &componentVersion).Return(&componentVersion, nil) componenVersionService = cv.NewComponentVersionHandler(db, er) newComponentVersion, err := componenVersionService.CreateComponentVersion(&componentVersion) @@ -146,6 +148,7 @@ var _ = Describe("When updating ComponentVersion", Label("app", "UpdateComponent }) It("updates componentVersion", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateComponentVersion", &componentVersion).Return(nil) componenVersionService = cv.NewComponentVersionHandler(db, er) componentVersion.Version = "7.3.3.1" diff --git a/internal/app/evidence/evidence_handler.go b/internal/app/evidence/evidence_handler.go index f3a8eb21..6363d608 100644 --- a/internal/app/evidence/evidence_handler.go +++ b/internal/app/evidence/evidence_handler.go @@ -109,6 +109,13 @@ func (e *evidenceHandler) CreateEvidence(evidence *entity.Evidence) (*entity.Evi "object": evidence, }) + var err error + evidence.CreatedBy, err = common.GetCurrentUserId(e.database) + if err != nil { + l.Error(err) + return nil, NewEvidenceHandlerError("Internal error while creating evidence (GetUserId).") + } + newEvidence, err := e.database.CreateEvidence(evidence) if err != nil { @@ -127,7 +134,14 @@ func (e *evidenceHandler) UpdateEvidence(evidence *entity.Evidence) (*entity.Evi "object": evidence, }) - err := e.database.UpdateEvidence(evidence) + var err error + evidence.UpdatedBy, err = common.GetCurrentUserId(e.database) + if err != nil { + l.Error(err) + return nil, NewEvidenceHandlerError("Internal error while updating evidence (GetUserId).") + } + + err = e.database.UpdateEvidence(evidence) if err != nil { l.Error(err) diff --git a/internal/app/evidence/evidence_handler_test.go b/internal/app/evidence/evidence_handler_test.go index abad38df..1c2c5dbd 100644 --- a/internal/app/evidence/evidence_handler_test.go +++ b/internal/app/evidence/evidence_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestEvidenceHandler(t *testing.T) { @@ -119,6 +120,7 @@ var _ = Describe("When creating Evidence", Label("app", "CreateEvidence"), func( }) It("creates evidence", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateEvidence", &evidence).Return(&evidence, nil) evidenceHandler = es.NewEvidenceHandler(db, er) newEvidence, err := evidenceHandler.CreateEvidence(&evidence) @@ -158,6 +160,7 @@ var _ = Describe("When updating Evidence", Label("app", "UpdateEvidence"), func( }) It("updates evidence", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateEvidence", &evidence).Return(nil) evidenceHandler = es.NewEvidenceHandler(db, er) evidence.Description = "New Description" diff --git a/internal/app/issue/issue_handler.go b/internal/app/issue/issue_handler.go index 2c5aae5f..be19aff1 100644 --- a/internal/app/issue/issue_handler.go +++ b/internal/app/issue/issue_handler.go @@ -170,6 +170,13 @@ func (is *issueHandler) CreateIssue(issue *entity.Issue) (*entity.Issue, error) "filter": f, }) + var err error + issue.CreatedBy, err = common.GetCurrentUserId(is.database) + if err != nil { + l.Error(err) + return nil, NewIssueHandlerError("Internal error while creating issue (GetUserId).") + } + issues, err := is.ListIssues(f, &entity.IssueListOptions{}) if err != nil { @@ -198,7 +205,14 @@ func (is *issueHandler) UpdateIssue(issue *entity.Issue) (*entity.Issue, error) "object": issue, }) - err := is.database.UpdateIssue(issue) + var err error + issue.UpdatedBy, err = common.GetCurrentUserId(is.database) + if err != nil { + l.Error(err) + return nil, NewIssueHandlerError("Internal error while updating issue (GetUserId).") + } + + err = is.database.UpdateIssue(issue) if err != nil { l.Error(err) diff --git a/internal/app/issue/issue_handler_test.go b/internal/app/issue/issue_handler_test.go index 3ea773da..76100094 100644 --- a/internal/app/issue/issue_handler_test.go +++ b/internal/app/issue/issue_handler_test.go @@ -16,6 +16,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestIssueHandler(t *testing.T) { @@ -238,6 +239,7 @@ var _ = Describe("When creating Issue", Label("app", "CreateIssue"), func() { It("creates issue", func() { filter.PrimaryName = []*string{&issueEntity.PrimaryName} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateIssue", &issueEntity).Return(&issueEntity, nil) db.On("GetIssues", filter).Return([]entity.Issue{}, nil) issueHandler = issue.NewIssueHandler(db, er) @@ -275,6 +277,7 @@ var _ = Describe("When updating Issue", Label("app", "UpdateIssue"), func() { }) It("updates issueEntity", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateIssue", &issueEntity).Return(nil) issueHandler = issue.NewIssueHandler(db, er) issueEntity.Description = "New Description" diff --git a/internal/app/issue_match/issue_match_handler.go b/internal/app/issue_match/issue_match_handler.go index 49f4de05..834a0fb8 100644 --- a/internal/app/issue_match/issue_match_handler.go +++ b/internal/app/issue_match/issue_match_handler.go @@ -141,6 +141,13 @@ func (im *issueMatchHandler) CreateIssueMatch(issueMatch *entity.IssueMatch) (*e "object": issueMatch, }) + var err error + issueMatch.CreatedBy, err = common.GetCurrentUserId(im.database) + if err != nil { + l.Error(err) + return nil, NewIssueMatchHandlerError("Internal error while retrieving effective severity (GetUserId).") + } + severityFilter := &entity.SeverityFilter{ IssueId: []*int64{&issueMatch.IssueId}, } @@ -175,7 +182,14 @@ func (im *issueMatchHandler) UpdateIssueMatch(issueMatch *entity.IssueMatch) (*e "object": issueMatch, }) - err := im.database.UpdateIssueMatch(issueMatch) + var err error + issueMatch.UpdatedBy, err = common.GetCurrentUserId(im.database) + if err != nil { + l.Error(err) + return nil, NewIssueMatchHandlerError("Internal error while retrieving effective severity (GetUserId).") + } + + err = im.database.UpdateIssueMatch(issueMatch) if err != nil { l.Error(err) diff --git a/internal/app/issue_match/issue_match_handler_test.go b/internal/app/issue_match/issue_match_handler_test.go index 9f10e321..5155e289 100644 --- a/internal/app/issue_match/issue_match_handler_test.go +++ b/internal/app/issue_match/issue_match_handler_test.go @@ -196,6 +196,7 @@ var _ = Describe("When creating IssueMatch", Label("app", "CreateIssueMatch"), f irFilter.Id = []*int64{&repositories[0].Id} ivFilter.IssueId = []*int64{&issueMatch.IssueId} issueMatch.Severity = issueVariants[0].Severity + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateIssueMatch", &issueMatch).Return(&issueMatch, nil) db.On("GetIssueVariants", ivFilter).Return(issueVariants, nil) db.On("GetIssueRepositories", irFilter).Return(repositories, nil) @@ -240,6 +241,7 @@ var _ = Describe("When updating IssueMatch", Label("app", "UpdateIssueMatch"), f }) It("updates issueMatch", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateIssueMatch", &issueMatch).Return(nil) issueMatchHandler = im.NewIssueMatchHandler(db, er, nil) if issueMatch.Status == entity.NewIssueMatchStatusValue("new") { diff --git a/internal/app/issue_match_change/issue_match_change_handler.go b/internal/app/issue_match_change/issue_match_change_handler.go index 876a235c..e2b32ef0 100644 --- a/internal/app/issue_match_change/issue_match_change_handler.go +++ b/internal/app/issue_match_change/issue_match_change_handler.go @@ -113,6 +113,13 @@ func (imc *issueMatchChangeHandler) CreateIssueMatchChange(issueMatchChange *ent "object": issueMatchChange, }) + var err error + issueMatchChange.CreatedBy, err = common.GetCurrentUserId(imc.database) + if err != nil { + l.Error(err) + return nil, NewIssueMatchChangeHandlerError("Internal error while creating issueMatchChange (GetUserId).") + } + newIssueMatchChange, err := imc.database.CreateIssueMatchChange(issueMatchChange) if err != nil { @@ -133,7 +140,14 @@ func (imc *issueMatchChangeHandler) UpdateIssueMatchChange(issueMatchChange *ent "object": issueMatchChange, }) - err := imc.database.UpdateIssueMatchChange(issueMatchChange) + var err error + issueMatchChange.UpdatedBy, err = common.GetCurrentUserId(imc.database) + if err != nil { + l.Error(err) + return nil, NewIssueMatchChangeHandlerError("Internal error while updating issueMatchChange (GetUserId).") + } + + err = imc.database.UpdateIssueMatchChange(issueMatchChange) if err != nil { l.Error(err) diff --git a/internal/app/issue_match_change/issue_match_change_handler_test.go b/internal/app/issue_match_change/issue_match_change_handler_test.go index 6d1e7705..48ffc9a7 100644 --- a/internal/app/issue_match_change/issue_match_change_handler_test.go +++ b/internal/app/issue_match_change/issue_match_change_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestIssueHandler(t *testing.T) { @@ -115,6 +116,7 @@ var _ = Describe("When creating IssueMatchChange", Label("app", "CreateIssueMatc }) It("creates issueMatchChange", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateIssueMatchChange", &issueMatchChange).Return(&issueMatchChange, nil) issueMatchChangeHandler = imc.NewIssueMatchChangeHandler(db, er) newIssueMatchChange, err := issueMatchChangeHandler.CreateIssueMatchChange(&issueMatchChange) @@ -149,6 +151,7 @@ var _ = Describe("When updating IssueMatchChange", Label("app", "UpdateIssueMatc }) It("updates issueMatchChange", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateIssueMatchChange", &issueMatchChange).Return(nil) issueMatchChangeHandler = imc.NewIssueMatchChangeHandler(db, er) if issueMatchChange.Action == entity.IssueMatchChangeActionAdd.String() { diff --git a/internal/app/issue_repository/issue_repository_handler.go b/internal/app/issue_repository/issue_repository_handler.go index bc38f1b7..f6e4fded 100644 --- a/internal/app/issue_repository/issue_repository_handler.go +++ b/internal/app/issue_repository/issue_repository_handler.go @@ -112,6 +112,13 @@ func (ir *issueRepositoryHandler) CreateIssueRepository(issueRepository *entity. "filter": f, }) + var err error + issueRepository.BaseIssueRepository.CreatedBy, err = common.GetCurrentUserId(ir.database) + if err != nil { + l.Error(err) + return nil, NewIssueRepositoryHandlerError("Internal error while creating issueRepository (GetUserId).") + } + issueRepositories, err := ir.ListIssueRepositories(f, &entity.ListOptions{}) if err != nil { @@ -142,7 +149,14 @@ func (ir *issueRepositoryHandler) UpdateIssueRepository(issueRepository *entity. "object": issueRepository, }) - err := ir.database.UpdateIssueRepository(issueRepository) + var err error + issueRepository.BaseIssueRepository.UpdatedBy, err = common.GetCurrentUserId(ir.database) + if err != nil { + l.Error(err) + return nil, NewIssueRepositoryHandlerError("Internal error while updating issueRepository (GetUserId).") + } + + err = ir.database.UpdateIssueRepository(issueRepository) if err != nil { l.Error(err) diff --git a/internal/app/issue_repository/issue_repository_handler_events.go b/internal/app/issue_repository/issue_repository_handler_events.go index ccc0e3f0..a64b8203 100644 --- a/internal/app/issue_repository/issue_repository_handler_events.go +++ b/internal/app/issue_repository/issue_repository_handler_events.go @@ -4,10 +4,10 @@ package issue_repository import ( - "github.com/sirupsen/logrus" "github.com/cloudoperators/heureka/internal/app/event" "github.com/cloudoperators/heureka/internal/database" "github.com/cloudoperators/heureka/internal/entity" + "github.com/sirupsen/logrus" ) const ( diff --git a/internal/app/issue_repository/issue_repository_handler_test.go b/internal/app/issue_repository/issue_repository_handler_test.go index 2a22fb57..70e1cb60 100644 --- a/internal/app/issue_repository/issue_repository_handler_test.go +++ b/internal/app/issue_repository/issue_repository_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestIssueRepositoryHandler(t *testing.T) { @@ -132,6 +133,7 @@ var _ = Describe("When creating IssueRepository", Label("app", "CreateIssueRepos It("creates issueRepository", func() { filter.Name = []*string{&issueRepository.Name} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateIssueRepository", &issueRepository).Return(&issueRepository, nil) db.On("GetIssueRepositories", filter).Return([]entity.IssueRepository{}, nil) issueRepositoryHandler = ir.NewIssueRepositoryHandler(db, er) @@ -192,6 +194,7 @@ var _ = Describe("When updating IssueRepository", Label("app", "UpdateIssueRepos }) It("updates issueRepository", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateIssueRepository", &issueRepository).Return(nil) issueRepositoryHandler = ir.NewIssueRepositoryHandler(db, er) issueRepository.Name = "SecretRepository" diff --git a/internal/app/issue_variant/issue_variant_handler.go b/internal/app/issue_variant/issue_variant_handler.go index 6ac751e8..7f8bfd1f 100644 --- a/internal/app/issue_variant/issue_variant_handler.go +++ b/internal/app/issue_variant/issue_variant_handler.go @@ -178,6 +178,13 @@ func (iv *issueVariantHandler) CreateIssueVariant(issueVariant *entity.IssueVari "filter": f, }) + var err error + issueVariant.CreatedBy, err = common.GetCurrentUserId(iv.database) + if err != nil { + l.Error(err) + return nil, NewIssueVariantHandlerError("Internal error while creating issueVariant (GetUserId).") + } + issueVariants, err := iv.ListIssueVariants(f, &entity.ListOptions{}) if err != nil { @@ -208,7 +215,14 @@ func (iv *issueVariantHandler) UpdateIssueVariant(issueVariant *entity.IssueVari "object": issueVariant, }) - err := iv.database.UpdateIssueVariant(issueVariant) + var err error + issueVariant.UpdatedBy, err = common.GetCurrentUserId(iv.database) + if err != nil { + l.Error(err) + return nil, NewIssueVariantHandlerError("Internal error while updating issueVariant (GetUserId).") + } + + err = iv.database.UpdateIssueVariant(issueVariant) if err != nil { l.Error(err) diff --git a/internal/app/issue_variant/issue_variant_handler_test.go b/internal/app/issue_variant/issue_variant_handler_test.go index 8c2b620a..12190e1f 100644 --- a/internal/app/issue_variant/issue_variant_handler_test.go +++ b/internal/app/issue_variant/issue_variant_handler_test.go @@ -16,6 +16,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestIssueVariantHandler(t *testing.T) { @@ -230,6 +231,7 @@ var _ = Describe("When creating IssueVariant", Label("app", "CreateIssueVariant" It("creates issueVariant", func() { filter.SecondaryName = []*string{&issueVariant.SecondaryName} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateIssueVariant", &issueVariant).Return(&issueVariant, nil) db.On("GetIssueVariants", filter).Return([]entity.IssueVariant{}, nil) issueVariantHandler = iv.NewIssueVariantHandler(db, er, rs) @@ -273,6 +275,7 @@ var _ = Describe("When updating IssueVariant", Label("app", "UpdateIssueVariant" }) It("updates issueVariant", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateIssueVariant", &issueVariant).Return(nil) issueVariantHandler = iv.NewIssueVariantHandler(db, er, rs) issueVariant.SecondaryName = "SecretAdvisory" diff --git a/internal/app/service/service_handler.go b/internal/app/service/service_handler.go index 8429cbf1..72a31f72 100644 --- a/internal/app/service/service_handler.go +++ b/internal/app/service/service_handler.go @@ -164,6 +164,13 @@ func (s *serviceHandler) CreateService(service *entity.Service) (*entity.Service "filter": f, }) + var err error + service.BaseService.CreatedBy, err = common.GetCurrentUserId(s.database) + if err != nil { + l.Error(err) + return nil, NewServiceHandlerError("Internal error while creating service (GetUserId).") + } + services, err := s.ListServices(f, &entity.ListOptions{}) if err != nil { @@ -193,7 +200,14 @@ func (s *serviceHandler) UpdateService(service *entity.Service) (*entity.Service "object": service, }) - err := s.database.UpdateService(service) + var err error + service.BaseService.UpdatedBy, err = common.GetCurrentUserId(s.database) + if err != nil { + l.Error(err) + return nil, NewServiceHandlerError("Internal error while updating service (GetUserId).") + } + + err = s.database.UpdateService(service) if err != nil { l.Error(err) diff --git a/internal/app/service/service_handler_test.go b/internal/app/service/service_handler_test.go index a3690bca..74de1554 100644 --- a/internal/app/service/service_handler_test.go +++ b/internal/app/service/service_handler_test.go @@ -18,6 +18,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestServiceHandler(t *testing.T) { @@ -225,6 +226,7 @@ var _ = Describe("When creating Service", Label("app", "CreateService"), func() It("creates service", func() { filter.CCRN = []*string{&service.CCRN} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateService", &service).Return(&service, nil) db.On("GetServices", filter).Return([]entity.Service{}, nil) @@ -335,6 +337,7 @@ var _ = Describe("When updating Service", Label("app", "UpdateService"), func() }) It("updates service", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateService", &service).Return(nil) serviceHandler = s.NewServiceHandler(db, er) service.CCRN = "SecretService" diff --git a/internal/app/support_group/support_group_handler.go b/internal/app/support_group/support_group_handler.go index 47b6e316..7c3e68c6 100644 --- a/internal/app/support_group/support_group_handler.go +++ b/internal/app/support_group/support_group_handler.go @@ -142,6 +142,13 @@ func (sg *supportGroupHandler) CreateSupportGroup(supportGroup *entity.SupportGr CCRN: []*string{&supportGroup.CCRN}, } + var err error + supportGroup.CreatedBy, err = common.GetCurrentUserId(sg.database) + if err != nil { + l.Error(err) + return nil, NewSupportGroupHandlerError("Internal error while creating supportGroup (GetUserId).") + } + supportGroups, err := sg.ListSupportGroups(f, &entity.ListOptions{}) if err != nil { @@ -173,7 +180,14 @@ func (sg *supportGroupHandler) UpdateSupportGroup(supportGroup *entity.SupportGr "object": supportGroup, }) - err := sg.database.UpdateSupportGroup(supportGroup) + var err error + supportGroup.UpdatedBy, err = common.GetCurrentUserId(sg.database) + if err != nil { + l.Error(err) + return nil, NewSupportGroupHandlerError("Internal error while updating supportGroup (GetUserId).") + } + + err = sg.database.UpdateSupportGroup(supportGroup) if err != nil { l.Error(err) diff --git a/internal/app/support_group/support_group_handler_test.go b/internal/app/support_group/support_group_handler_test.go index 859ddacd..9c622bcc 100644 --- a/internal/app/support_group/support_group_handler_test.go +++ b/internal/app/support_group/support_group_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestSupportGroupHandler(t *testing.T) { @@ -122,6 +123,7 @@ var _ = Describe("When creating SupportGroup", Label("app", "CreateSupportGroup" It("creates supportGroup", func() { filter.CCRN = []*string{&supportGroup.CCRN} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateSupportGroup", &supportGroup).Return(&supportGroup, nil) db.On("GetSupportGroups", filter).Return([]entity.SupportGroup{}, nil) supportGroupHandler = sg.NewSupportGroupHandler(db, er) @@ -157,6 +159,7 @@ var _ = Describe("When updating SupportGroup", Label("app", "UpdateSupportGroup" }) It("updates supportGroup", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateSupportGroup", &supportGroup).Return(nil) supportGroupHandler = sg.NewSupportGroupHandler(db, er) supportGroup.CCRN = "Team Alone" diff --git a/internal/app/user/user_handler.go b/internal/app/user/user_handler.go index 19abd432..e8ad6461 100644 --- a/internal/app/user/user_handler.go +++ b/internal/app/user/user_handler.go @@ -112,6 +112,13 @@ func (u *userHandler) CreateUser(user *entity.User) (*entity.User, error) { "object": user, }) + var err error + user.CreatedBy, err = common.GetCurrentUserId(u.database) + if err != nil { + l.Error(err) + return nil, NewUserHandlerError("Internal error while creating user (GetUserId).") + } + users, err := u.ListUsers(f, &entity.ListOptions{}) if err != nil { @@ -141,7 +148,14 @@ func (u *userHandler) UpdateUser(user *entity.User) (*entity.User, error) { "object": user, }) - err := u.database.UpdateUser(user) + var err error + user.UpdatedBy, err = common.GetCurrentUserId(u.database) + if err != nil { + l.Error(err) + return nil, NewUserHandlerError("Internal error while updating user (GetUserId).") + } + + err = u.database.UpdateUser(user) if err != nil { l.Error(err) diff --git a/internal/app/user/user_handler_test.go b/internal/app/user/user_handler_test.go index 582c47e6..106ff4cd 100644 --- a/internal/app/user/user_handler_test.go +++ b/internal/app/user/user_handler_test.go @@ -15,6 +15,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/samber/lo" + mock "github.com/stretchr/testify/mock" ) func TestUserHandler(t *testing.T) { @@ -125,6 +126,7 @@ var _ = Describe("When creating User", Label("app", "CreateUser"), func() { It("creates user", func() { filter.UniqueUserID = []*string{&user.UniqueUserID} + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("CreateUser", &user).Return(&user, nil) db.On("GetUsers", filter).Return([]entity.User{}, nil) userHandler = u.NewUserHandler(db, er) @@ -161,6 +163,7 @@ var _ = Describe("When updating User", Label("app", "UpdateUser"), func() { }) It("updates user", func() { + db.On("GetAllUserIds", mock.Anything).Return([]int64{}, nil) db.On("UpdateUser", &user).Return(nil) userHandler = u.NewUserHandler(db, er) user.Name = "Sauron" diff --git a/internal/database/mariadb/activity.go b/internal/database/mariadb/activity.go index 4f6e1c5f..2dd69c64 100644 --- a/internal/database/mariadb/activity.go +++ b/internal/database/mariadb/activity.go @@ -68,6 +68,9 @@ func (s *SqlDatabase) getActivityUpdateFields(activity *entity.Activity) string if activity.Status != "" { fl = append(fl, "activity_status = :activity_status") } + if activity.UpdatedBy != 0 { + fl = append(fl, "activity_updated_by = :activity_updated_by") + } return strings.Join(fl, ", ") } @@ -208,9 +211,11 @@ func (s *SqlDatabase) CreateActivity(activity *entity.Activity) (*entity.Activit query := ` INSERT INTO Activity ( - activity_status + activity_status, + activity_created_by ) VALUES ( - :activity_status + :activity_status, + :activity_created_by ) ` diff --git a/internal/database/mariadb/component.go b/internal/database/mariadb/component.go index cffb0c87..ddfc1601 100644 --- a/internal/database/mariadb/component.go +++ b/internal/database/mariadb/component.go @@ -64,6 +64,9 @@ func (s *SqlDatabase) getComponentUpdateFields(component *entity.Component) stri if component.Type != "" { fl = append(fl, "component_type = :component_type") } + if component.UpdatedBy != 0 { + fl = append(fl, "component_updated_by = :component_updated_by") + } return strings.Join(fl, ", ") } @@ -202,10 +205,12 @@ func (s *SqlDatabase) CreateComponent(component *entity.Component) (*entity.Comp query := ` INSERT INTO Component ( component_ccrn, - component_type + component_type, + component_created_by ) VALUES ( :component_ccrn, - :component_type + :component_type, + :component_created_by ) ` diff --git a/internal/database/mariadb/component_instance.go b/internal/database/mariadb/component_instance.go index 3b965aa1..a2e66202 100644 --- a/internal/database/mariadb/component_instance.go +++ b/internal/database/mariadb/component_instance.go @@ -80,6 +80,10 @@ func (s *SqlDatabase) getComponentInstanceUpdateFields(componentInstance *entity if componentInstance.ServiceId != 0 { fl = append(fl, "componentinstance_service_id = :componentinstance_service_id") } + if componentInstance.UpdatedBy != 0 { + fl = append(fl, "componentinstance_updated_by = :componentinstance_updated_by") + } + return strings.Join(fl, ", ") } @@ -223,12 +227,14 @@ func (s *SqlDatabase) CreateComponentInstance(componentInstance *entity.Componen componentinstance_ccrn, componentinstance_count, componentinstance_component_version_id, - componentinstance_service_id + componentinstance_service_id, + componentinstance_created_by ) VALUES ( :componentinstance_ccrn, :componentinstance_count, :componentinstance_component_version_id, - :componentinstance_service_id + :componentinstance_service_id, + :componentinstance_created_by ) ` diff --git a/internal/database/mariadb/component_version.go b/internal/database/mariadb/component_version.go index 8f4ec7b5..4fc5e661 100644 --- a/internal/database/mariadb/component_version.go +++ b/internal/database/mariadb/component_version.go @@ -57,6 +57,9 @@ func (s *SqlDatabase) getComponentVersionUpdateFields(componentVersion *entity.C if componentVersion.ComponentId != 0 { fl = append(fl, "componentversion_component_id = :componentversion_component_id") } + if componentVersion.UpdatedBy != 0 { + fl = append(fl, "componentversion_updated_by = :componentversion_updated_by") + } return strings.Join(fl, ", ") } @@ -209,10 +212,12 @@ func (s *SqlDatabase) CreateComponentVersion(componentVersion *entity.ComponentV query := ` INSERT INTO ComponentVersion ( componentversion_component_id, - componentversion_version + componentversion_version, + componentversion_created_by ) VALUES ( :componentversion_component_id, - :componentversion_version + :componentversion_version, + :componentversion_created_by ) ` diff --git a/internal/database/mariadb/entity.go b/internal/database/mariadb/entity.go index c03c5577..0f9f78e8 100644 --- a/internal/database/mariadb/entity.go +++ b/internal/database/mariadb/entity.go @@ -87,8 +87,10 @@ type IssueRow struct { PrimaryName sql.NullString `db:"issue_primary_name" json:"primary_name"` Description sql.NullString `db:"issue_description" json:"description"` CreatedAt sql.NullTime `db:"issue_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"issue_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"issue_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"issue_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"issue_updated_by" json:"updated_by"` } func (ir *IssueRow) AsIssue() entity.Issue { @@ -100,9 +102,13 @@ func (ir *IssueRow) AsIssue() entity.Issue { IssueVariants: []entity.IssueVariant{}, IssueMatches: []entity.IssueMatch{}, Activity: []entity.Activity{}, - CreatedAt: GetTimeValue(ir.CreatedAt), - DeletedAt: GetTimeValue(ir.DeletedAt), - UpdatedAt: GetTimeValue(ir.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ir.CreatedAt), + CreatedBy: GetInt64Value(ir.CreatedBy), + DeletedAt: GetTimeValue(ir.DeletedAt), + UpdatedAt: GetTimeValue(ir.UpdatedAt), + UpdatedBy: GetInt64Value(ir.UpdatedBy), + }, } } @@ -140,9 +146,13 @@ func (ibr *GetIssuesByRow) AsIssueWithAggregations() entity.IssueWithAggregation IssueVariants: []entity.IssueVariant{}, IssueMatches: []entity.IssueMatch{}, Activity: []entity.Activity{}, - CreatedAt: GetTimeValue(ibr.IssueRow.CreatedAt), - DeletedAt: GetTimeValue(ibr.IssueRow.DeletedAt), - UpdatedAt: GetTimeValue(ibr.IssueRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ibr.IssueRow.CreatedAt), + CreatedBy: GetInt64Value(ibr.IssueRow.CreatedBy), + DeletedAt: GetTimeValue(ibr.IssueRow.DeletedAt), + UpdatedAt: GetTimeValue(ibr.IssueRow.UpdatedAt), + UpdatedBy: GetInt64Value(ibr.IssueRow.UpdatedBy), + }, }, } } @@ -156,9 +166,13 @@ func (ibr *GetIssuesByRow) AsIssue() entity.Issue { IssueVariants: []entity.IssueVariant{}, IssueMatches: []entity.IssueMatch{}, Activity: []entity.Activity{}, - CreatedAt: GetTimeValue(ibr.IssueRow.CreatedAt), - DeletedAt: GetTimeValue(ibr.IssueRow.DeletedAt), - UpdatedAt: GetTimeValue(ibr.IssueRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ibr.IssueRow.CreatedAt), + CreatedBy: GetInt64Value(ibr.IssueRow.CreatedBy), + DeletedAt: GetTimeValue(ibr.IssueRow.DeletedAt), + UpdatedAt: GetTimeValue(ibr.IssueRow.UpdatedAt), + UpdatedBy: GetInt64Value(ibr.IssueRow.UpdatedBy), + }, } } @@ -180,8 +194,10 @@ func (ir *IssueRow) FromIssue(i *entity.Issue) { ir.Type = sql.NullString{String: i.Type.String(), Valid: true} ir.Description = sql.NullString{String: i.Description, Valid: true} ir.CreatedAt = sql.NullTime{Time: i.CreatedAt, Valid: true} + ir.CreatedBy = sql.NullInt64{Int64: i.CreatedBy, Valid: true} ir.DeletedAt = sql.NullTime{Time: i.DeletedAt, Valid: true} ir.UpdatedAt = sql.NullTime{Time: i.UpdatedAt, Valid: true} + ir.UpdatedBy = sql.NullInt64{Int64: i.UpdatedBy, Valid: true} } type IssueMatchRow struct { @@ -195,8 +211,10 @@ type IssueMatchRow struct { RemediationDate sql.NullTime `db:"issuematch_remediation_date" json:"remediation_date"` TargetRemediationDate sql.NullTime `db:"issuematch_target_remediation_date" json:"target_remediation_date"` CreatedAt sql.NullTime `db:"issuematch_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"issuematch_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"issuematch_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"issuematch_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"issuematch_updated_by" json:"updated_by"` } func (imr IssueMatchRow) AsIssueMatch() entity.IssueMatch { @@ -212,9 +230,13 @@ func (imr IssueMatchRow) AsIssueMatch() entity.IssueMatch { RemediationDate: GetTimeValue(imr.RemediationDate), TargetRemediationDate: GetTimeValue(imr.TargetRemediationDate), Severity: entity.NewSeverity(GetStringValue(imr.Vector)), - CreatedAt: GetTimeValue(imr.CreatedAt), - DeletedAt: GetTimeValue(imr.DeletedAt), - UpdatedAt: GetTimeValue(imr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(imr.CreatedAt), + CreatedBy: GetInt64Value(imr.CreatedBy), + DeletedAt: GetTimeValue(imr.DeletedAt), + UpdatedAt: GetTimeValue(imr.UpdatedAt), + UpdatedBy: GetInt64Value(imr.UpdatedBy), + }, } } @@ -229,8 +251,10 @@ func (imr *IssueMatchRow) FromIssueMatch(im *entity.IssueMatch) { imr.RemediationDate = sql.NullTime{Time: im.RemediationDate, Valid: true} imr.TargetRemediationDate = sql.NullTime{Time: im.TargetRemediationDate, Valid: true} imr.CreatedAt = sql.NullTime{Time: im.CreatedAt, Valid: true} + imr.CreatedBy = sql.NullInt64{Int64: im.CreatedBy, Valid: true} imr.DeletedAt = sql.NullTime{Time: im.DeletedAt, Valid: true} imr.UpdatedAt = sql.NullTime{Time: im.UpdatedAt, Valid: true} + imr.UpdatedBy = sql.NullInt64{Int64: im.UpdatedBy, Valid: true} } type IssueRepositoryRow struct { @@ -243,8 +267,10 @@ type BaseIssueRepositoryRow struct { Name sql.NullString `db:"issuerepository_name"` Url sql.NullString `db:"issuerepository_url"` CreatedAt sql.NullTime `db:"issuerepository_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"issuerepository_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"issuerepository_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"issuerepository_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"issuerepository_updated_by" json:"updated_by"` } func (irr *IssueRepositoryRow) FromIssueRepository(ir *entity.IssueRepository) { @@ -254,6 +280,11 @@ func (irr *IssueRepositoryRow) FromIssueRepository(ir *entity.IssueRepository) { irr.Priority = sql.NullInt64{Int64: ir.Priority, Valid: true} irr.ServiceId = sql.NullInt64{Int64: ir.ServiceId, Valid: true} irr.IssueRepositoryId = sql.NullInt64{Int64: ir.IssueRepositoryId, Valid: true} + irr.BaseIssueRepositoryRow.CreatedAt = sql.NullTime{Time: ir.BaseIssueRepository.CreatedAt, Valid: true} + irr.BaseIssueRepositoryRow.CreatedBy = sql.NullInt64{Int64: ir.BaseIssueRepository.CreatedBy, Valid: true} + irr.BaseIssueRepositoryRow.DeletedAt = sql.NullTime{Time: ir.BaseIssueRepository.DeletedAt, Valid: true} + irr.BaseIssueRepositoryRow.UpdatedAt = sql.NullTime{Time: ir.BaseIssueRepository.UpdatedAt, Valid: true} + irr.BaseIssueRepositoryRow.UpdatedBy = sql.NullInt64{Int64: ir.BaseIssueRepository.UpdatedBy, Valid: true} } func (birr *BaseIssueRepositoryRow) AsBaseIssueRepository() entity.BaseIssueRepository { @@ -263,9 +294,13 @@ func (birr *BaseIssueRepositoryRow) AsBaseIssueRepository() entity.BaseIssueRepo Url: GetStringValue(birr.Url), IssueVariants: nil, Services: nil, - CreatedAt: GetTimeValue(birr.CreatedAt), - DeletedAt: GetTimeValue(birr.DeletedAt), - UpdatedAt: GetTimeValue(birr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(birr.CreatedAt), + CreatedBy: GetInt64Value(birr.CreatedBy), + DeletedAt: GetTimeValue(birr.DeletedAt), + UpdatedAt: GetTimeValue(birr.UpdatedAt), + UpdatedBy: GetInt64Value(birr.UpdatedBy), + }, } } @@ -277,9 +312,13 @@ func (barr *BaseIssueRepositoryRow) AsIssueRepository() entity.IssueRepository { Url: GetStringValue(barr.Url), IssueVariants: nil, Services: nil, - CreatedAt: GetTimeValue(barr.CreatedAt), - DeletedAt: GetTimeValue(barr.DeletedAt), - UpdatedAt: GetTimeValue(barr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(barr.CreatedAt), + CreatedBy: GetInt64Value(barr.CreatedBy), + DeletedAt: GetTimeValue(barr.DeletedAt), + UpdatedAt: GetTimeValue(barr.UpdatedAt), + UpdatedBy: GetInt64Value(barr.UpdatedBy), + }, }, } } @@ -292,9 +331,13 @@ func (irr *IssueRepositoryRow) AsIssueRepository() entity.IssueRepository { Url: GetStringValue(irr.Url), IssueVariants: nil, Services: nil, - CreatedAt: GetTimeValue(irr.BaseIssueRepositoryRow.CreatedAt), - DeletedAt: GetTimeValue(irr.BaseIssueRepositoryRow.DeletedAt), - UpdatedAt: GetTimeValue(irr.BaseIssueRepositoryRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(irr.BaseIssueRepositoryRow.CreatedAt), + CreatedBy: GetInt64Value(irr.BaseIssueRepositoryRow.CreatedBy), + DeletedAt: GetTimeValue(irr.BaseIssueRepositoryRow.DeletedAt), + UpdatedAt: GetTimeValue(irr.BaseIssueRepositoryRow.UpdatedAt), + UpdatedBy: GetInt64Value(irr.BaseIssueRepositoryRow.UpdatedBy), + }, }, IssueRepositoryService: entity.IssueRepositoryService{ ServiceId: GetInt64Value(irr.ServiceId), @@ -312,8 +355,10 @@ type IssueVariantRow struct { Rating sql.NullString `db:"issuevariant_rating" json:"rating"` Description sql.NullString `db:"issuevariant_description" json:"description"` CreatedAt sql.NullTime `db:"issuevariant_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"issuevariant_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"issuevariant_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"issuevariant_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"issuevariant_updated_by" json:"updated_by"` } func (ivr *IssueVariantRow) AsIssueVariant(repository *entity.IssueRepository) entity.IssueVariant { @@ -326,9 +371,13 @@ func (ivr *IssueVariantRow) AsIssueVariant(repository *entity.IssueRepository) e Issue: nil, Severity: entity.NewSeverity(GetStringValue(ivr.Vector)), Description: GetStringValue(ivr.Description), - CreatedAt: GetTimeValue(ivr.CreatedAt), - DeletedAt: GetTimeValue(ivr.DeletedAt), - UpdatedAt: GetTimeValue(ivr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ivr.CreatedAt), + CreatedBy: GetInt64Value(ivr.CreatedBy), + DeletedAt: GetTimeValue(ivr.DeletedAt), + UpdatedAt: GetTimeValue(ivr.UpdatedAt), + UpdatedBy: GetInt64Value(ivr.UpdatedBy), + }, } } @@ -341,8 +390,10 @@ func (ivr *IssueVariantRow) FromIssueVariant(iv *entity.IssueVariant) { ivr.Rating = sql.NullString{String: iv.Severity.Value, Valid: true} ivr.Description = sql.NullString{String: iv.Description, Valid: true} ivr.CreatedAt = sql.NullTime{Time: iv.CreatedAt, Valid: true} + ivr.CreatedBy = sql.NullInt64{Int64: iv.CreatedBy, Valid: true} ivr.DeletedAt = sql.NullTime{Time: iv.DeletedAt, Valid: true} ivr.UpdatedAt = sql.NullTime{Time: iv.UpdatedAt, Valid: true} + ivr.UpdatedBy = sql.NullInt64{Int64: iv.UpdatedBy, Valid: true} } type IssueVariantWithRepository struct { @@ -361,9 +412,13 @@ func (ivwr *IssueVariantWithRepository) AsIssueVariantEntry() entity.IssueVarian Issue: nil, Severity: entity.NewSeverity(GetStringValue(ivwr.Vector)), Description: GetStringValue(ivwr.Description), - CreatedAt: GetTimeValue(ivwr.IssueVariantRow.CreatedAt), - DeletedAt: GetTimeValue(ivwr.IssueVariantRow.DeletedAt), - UpdatedAt: GetTimeValue(ivwr.IssueVariantRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ivwr.IssueVariantRow.CreatedAt), + CreatedBy: GetInt64Value(ivwr.CreatedBy), + DeletedAt: GetTimeValue(ivwr.IssueVariantRow.DeletedAt), + UpdatedAt: GetTimeValue(ivwr.IssueVariantRow.UpdatedAt), + UpdatedBy: GetInt64Value(ivwr.UpdatedBy), + }, } } @@ -384,9 +439,13 @@ func (siv *ServiceIssueVariantRow) AsServiceIssueVariantEntry() entity.ServiceIs Issue: nil, Severity: entity.NewSeverity(GetStringValue(siv.Vector)), Description: GetStringValue(siv.Description), - CreatedAt: GetTimeValue(siv.IssueVariantRow.CreatedAt), - DeletedAt: GetTimeValue(siv.IssueVariantRow.DeletedAt), - UpdatedAt: GetTimeValue(siv.IssueVariantRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(siv.IssueVariantRow.CreatedAt), + CreatedBy: GetInt64Value(siv.CreatedBy), + DeletedAt: GetTimeValue(siv.IssueVariantRow.DeletedAt), + UpdatedAt: GetTimeValue(siv.IssueVariantRow.UpdatedAt), + UpdatedBy: GetInt64Value(siv.UpdatedBy), + }, }, ServiceId: GetInt64Value(siv.IssueRepositoryServiceRow.ServiceId), Priority: GetInt64Value(siv.Priority), @@ -398,18 +457,24 @@ type ComponentRow struct { CCRN sql.NullString `db:"component_ccrn" json:"ccrn"` Type sql.NullString `db:"component_type" json:"type"` CreatedAt sql.NullTime `db:"component_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"component_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"component_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"component_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"component_updated_by" json:"updated_by"` } func (cr *ComponentRow) AsComponent() entity.Component { return entity.Component{ - Id: GetInt64Value(cr.Id), - CCRN: GetStringValue(cr.CCRN), - Type: GetStringValue(cr.Type), - CreatedAt: GetTimeValue(cr.CreatedAt), - DeletedAt: GetTimeValue(cr.DeletedAt), - UpdatedAt: GetTimeValue(cr.UpdatedAt), + Id: GetInt64Value(cr.Id), + CCRN: GetStringValue(cr.CCRN), + Type: GetStringValue(cr.Type), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(cr.CreatedAt), + CreatedBy: GetInt64Value(cr.CreatedBy), + DeletedAt: GetTimeValue(cr.DeletedAt), + UpdatedAt: GetTimeValue(cr.UpdatedAt), + UpdatedBy: GetInt64Value(cr.UpdatedBy), + }, } } @@ -418,8 +483,10 @@ func (cr *ComponentRow) FromComponent(c *entity.Component) { cr.CCRN = sql.NullString{String: c.CCRN, Valid: true} cr.Type = sql.NullString{String: c.Type, Valid: true} cr.CreatedAt = sql.NullTime{Time: c.CreatedAt, Valid: true} + cr.CreatedBy = sql.NullInt64{Int64: c.CreatedBy, Valid: true} cr.DeletedAt = sql.NullTime{Time: c.DeletedAt, Valid: true} cr.UpdatedAt = sql.NullTime{Time: c.UpdatedAt, Valid: true} + cr.UpdatedBy = sql.NullInt64{Int64: c.UpdatedBy, Valid: true} } type ComponentVersionRow struct { @@ -427,8 +494,10 @@ type ComponentVersionRow struct { Version sql.NullString `db:"componentversion_version" json:"version"` ComponentId sql.NullInt64 `db:"componentversion_component_id"` CreatedAt sql.NullTime `db:"componentversion_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"componentversion_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"componentversion_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"componentversion_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"componentversion_updated_by" json:"updated_by"` } func (cvr *ComponentVersionRow) AsComponentVersion() entity.ComponentVersion { @@ -436,9 +505,13 @@ func (cvr *ComponentVersionRow) AsComponentVersion() entity.ComponentVersion { Id: GetInt64Value(cvr.Id), Version: GetStringValue(cvr.Version), ComponentId: GetInt64Value(cvr.ComponentId), - CreatedAt: GetTimeValue(cvr.CreatedAt), - DeletedAt: GetTimeValue(cvr.DeletedAt), - UpdatedAt: GetTimeValue(cvr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(cvr.CreatedAt), + CreatedBy: GetInt64Value(cvr.CreatedBy), + DeletedAt: GetTimeValue(cvr.DeletedAt), + UpdatedAt: GetTimeValue(cvr.UpdatedAt), + UpdatedBy: GetInt64Value(cvr.UpdatedBy), + }, } } @@ -447,25 +520,33 @@ func (cvr *ComponentVersionRow) FromComponentVersion(cv *entity.ComponentVersion cvr.Version = sql.NullString{String: cv.Version, Valid: true} cvr.ComponentId = sql.NullInt64{Int64: cv.ComponentId, Valid: true} cvr.CreatedAt = sql.NullTime{Time: cv.CreatedAt, Valid: true} + cvr.CreatedBy = sql.NullInt64{Int64: cv.CreatedBy, Valid: true} cvr.DeletedAt = sql.NullTime{Time: cv.DeletedAt, Valid: true} cvr.UpdatedAt = sql.NullTime{Time: cv.UpdatedAt, Valid: true} + cvr.UpdatedBy = sql.NullInt64{Int64: cv.UpdatedBy, Valid: true} } type SupportGroupRow struct { Id sql.NullInt64 `db:"supportgroup_id" json:"id"` CCRN sql.NullString `db:"supportgroup_ccrn" json:"ccrn"` CreatedAt sql.NullTime `db:"supportgroup_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"supportgroup_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"supportgroup_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"supportgroup_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"supportgroup_updated_by" json:"updated_by"` } func (sgr *SupportGroupRow) AsSupportGroup() entity.SupportGroup { return entity.SupportGroup{ - Id: GetInt64Value(sgr.Id), - CCRN: GetStringValue(sgr.CCRN), - CreatedAt: GetTimeValue(sgr.CreatedAt), - DeletedAt: GetTimeValue(sgr.DeletedAt), - UpdatedAt: GetTimeValue(sgr.UpdatedAt), + Id: GetInt64Value(sgr.Id), + CCRN: GetStringValue(sgr.CCRN), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(sgr.CreatedAt), + CreatedBy: GetInt64Value(sgr.CreatedBy), + DeletedAt: GetTimeValue(sgr.DeletedAt), + UpdatedAt: GetTimeValue(sgr.UpdatedAt), + UpdatedBy: GetInt64Value(sgr.UpdatedBy), + }, } } @@ -473,8 +554,10 @@ func (sgr *SupportGroupRow) FromSupportGroup(sg *entity.SupportGroup) { sgr.Id = sql.NullInt64{Int64: sg.Id, Valid: true} sgr.CCRN = sql.NullString{String: sg.CCRN, Valid: true} sgr.CreatedAt = sql.NullTime{Time: sg.CreatedAt, Valid: true} + sgr.CreatedBy = sql.NullInt64{Int64: sg.CreatedBy, Valid: true} sgr.DeletedAt = sql.NullTime{Time: sg.DeletedAt, Valid: true} sgr.UpdatedAt = sql.NullTime{Time: sg.UpdatedAt, Valid: true} + sgr.UpdatedBy = sql.NullInt64{Int64: sg.UpdatedBy, Valid: true} } type ServiceRow struct { @@ -486,8 +569,10 @@ type BaseServiceRow struct { Id sql.NullInt64 `db:"service_id" json:"id"` CCRN sql.NullString `db:"service_ccrn" json:"ccrn"` CreatedAt sql.NullTime `db:"service_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"service_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"service_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"service_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"service_updated_by" json:"updated_by"` } func (bsr *BaseServiceRow) AsBaseService() entity.BaseService { @@ -496,9 +581,13 @@ func (bsr *BaseServiceRow) AsBaseService() entity.BaseService { CCRN: GetStringValue(bsr.CCRN), Owners: []entity.User{}, Activities: []entity.Activity{}, - CreatedAt: GetTimeValue(bsr.CreatedAt), - DeletedAt: GetTimeValue(bsr.DeletedAt), - UpdatedAt: GetTimeValue(bsr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(bsr.CreatedAt), + CreatedBy: GetInt64Value(bsr.CreatedBy), + DeletedAt: GetTimeValue(bsr.DeletedAt), + UpdatedAt: GetTimeValue(bsr.UpdatedAt), + UpdatedBy: GetInt64Value(bsr.UpdatedBy), + }, } } @@ -516,9 +605,13 @@ func (sr *ServiceRow) AsService() entity.Service { CCRN: GetStringValue(sr.CCRN), Owners: []entity.User{}, Activities: []entity.Activity{}, - CreatedAt: GetTimeValue(sr.BaseServiceRow.CreatedAt), - DeletedAt: GetTimeValue(sr.BaseServiceRow.DeletedAt), - UpdatedAt: GetTimeValue(sr.BaseServiceRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(sr.BaseServiceRow.CreatedAt), + CreatedBy: GetInt64Value(sr.BaseServiceRow.CreatedBy), + DeletedAt: GetTimeValue(sr.BaseServiceRow.DeletedAt), + UpdatedAt: GetTimeValue(sr.BaseServiceRow.UpdatedAt), + UpdatedBy: GetInt64Value(sr.BaseServiceRow.UpdatedBy), + }, }, IssueRepositoryService: entity.IssueRepositoryService{ ServiceId: GetInt64Value(sr.ServiceId), @@ -531,8 +624,10 @@ func (sr *ServiceRow) FromService(s *entity.Service) { sr.Id = sql.NullInt64{Int64: s.Id, Valid: true} sr.CCRN = sql.NullString{String: s.CCRN, Valid: true} sr.BaseServiceRow.CreatedAt = sql.NullTime{Time: s.BaseService.CreatedAt, Valid: true} + sr.BaseServiceRow.CreatedBy = sql.NullInt64{Int64: s.BaseService.CreatedBy, Valid: true} sr.BaseServiceRow.DeletedAt = sql.NullTime{Time: s.BaseService.DeletedAt, Valid: true} sr.BaseServiceRow.UpdatedAt = sql.NullTime{Time: s.BaseService.UpdatedAt, Valid: true} + sr.BaseServiceRow.UpdatedBy = sql.NullInt64{Int64: s.BaseService.UpdatedBy, Valid: true} } type GetServicesByRow struct { @@ -557,9 +652,13 @@ func (sbr *GetServicesByRow) AsServiceWithAggregations() entity.ServiceWithAggre CCRN: GetStringValue(sbr.BaseServiceRow.CCRN), Owners: []entity.User{}, Activities: []entity.Activity{}, - CreatedAt: GetTimeValue(sbr.BaseServiceRow.CreatedAt), - DeletedAt: GetTimeValue(sbr.BaseServiceRow.DeletedAt), - UpdatedAt: GetTimeValue(sbr.BaseServiceRow.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(sbr.BaseServiceRow.CreatedAt), + CreatedBy: GetInt64Value(sbr.BaseServiceRow.CreatedBy), + DeletedAt: GetTimeValue(sbr.BaseServiceRow.DeletedAt), + UpdatedAt: GetTimeValue(sbr.BaseServiceRow.UpdatedAt), + UpdatedBy: GetInt64Value(sbr.BaseServiceRow.UpdatedBy), + }, }, IssueRepositoryService: entity.IssueRepositoryService{ ServiceId: GetInt64Value(sbr.IssueRepositoryServiceRow.ServiceId), @@ -574,8 +673,10 @@ type ActivityRow struct { Id sql.NullInt64 `db:"activity_id" json:"id"` Status sql.NullString `db:"activity_status" json:"status"` CreatedAt sql.NullTime `db:"activity_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"activity_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"activity_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"activity_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"activity_updated_by" json:"updated_by"` } func (ar *ActivityRow) AsActivity() entity.Activity { @@ -584,9 +685,13 @@ func (ar *ActivityRow) AsActivity() entity.Activity { Status: entity.ActivityStatusValue(GetStringValue(ar.Status)), Issues: []entity.Issue{}, Evidences: []entity.Evidence{}, - CreatedAt: GetTimeValue(ar.CreatedAt), - DeletedAt: GetTimeValue(ar.DeletedAt), - UpdatedAt: GetTimeValue(ar.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ar.CreatedAt), + CreatedBy: GetInt64Value(ar.CreatedBy), + DeletedAt: GetTimeValue(ar.DeletedAt), + UpdatedAt: GetTimeValue(ar.UpdatedAt), + UpdatedBy: GetInt64Value(ar.UpdatedBy), + }, } } @@ -594,8 +699,10 @@ func (ar *ActivityRow) FromActivity(a *entity.Activity) { ar.Id = sql.NullInt64{Int64: a.Id, Valid: true} ar.Status = sql.NullString{String: a.Status.String(), Valid: true} ar.CreatedAt = sql.NullTime{Time: a.CreatedAt, Valid: true} + ar.CreatedBy = sql.NullInt64{Int64: a.CreatedBy, Valid: true} ar.DeletedAt = sql.NullTime{Time: a.DeletedAt, Valid: true} ar.UpdatedAt = sql.NullTime{Time: a.UpdatedAt, Valid: true} + ar.UpdatedBy = sql.NullInt64{Int64: a.UpdatedBy, Valid: true} } type ComponentInstanceRow struct { @@ -605,8 +712,10 @@ type ComponentInstanceRow struct { ComponentVersionId sql.NullInt64 `db:"componentinstance_component_version_id"` ServiceId sql.NullInt64 `db:"componentinstance_service_id"` CreatedAt sql.NullTime `db:"componentinstance_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"componentinstance_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"componentinstance_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"componentinstance_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"componentinstance_updated_by" json:"udpated_by"` } func (cir *ComponentInstanceRow) AsComponentInstance() entity.ComponentInstance { @@ -618,9 +727,13 @@ func (cir *ComponentInstanceRow) AsComponentInstance() entity.ComponentInstance ComponentVersionId: GetInt64Value(cir.ComponentVersionId), Service: nil, ServiceId: GetInt64Value(cir.ServiceId), - CreatedAt: GetTimeValue(cir.CreatedAt), - DeletedAt: GetTimeValue(cir.DeletedAt), - UpdatedAt: GetTimeValue(cir.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(cir.CreatedAt), + CreatedBy: GetInt64Value(cir.CreatedBy), + DeletedAt: GetTimeValue(cir.DeletedAt), + UpdatedAt: GetTimeValue(cir.UpdatedAt), + UpdatedBy: GetInt64Value(cir.UpdatedBy), + }, } } @@ -631,8 +744,10 @@ func (cir *ComponentInstanceRow) FromComponentInstance(ci *entity.ComponentInsta cir.ComponentVersionId = sql.NullInt64{Int64: ci.ComponentVersionId, Valid: true} cir.ServiceId = sql.NullInt64{Int64: ci.ServiceId, Valid: true} cir.CreatedAt = sql.NullTime{Time: ci.CreatedAt, Valid: true} + cir.CreatedBy = sql.NullInt64{Int64: ci.CreatedBy, Valid: true} cir.DeletedAt = sql.NullTime{Time: ci.DeletedAt, Valid: true} cir.UpdatedAt = sql.NullTime{Time: ci.UpdatedAt, Valid: true} + cir.UpdatedBy = sql.NullInt64{Int64: ci.UpdatedBy, Valid: true} } type UserRow struct { @@ -641,8 +756,10 @@ type UserRow struct { UniqueUserID sql.NullString `db:"user_unique_user_id" json:"unique_user_id"` Type sql.NullInt64 `db:"user_type" json:"type"` CreatedAt sql.NullTime `db:"user_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"user_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"user_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"user_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"user_updated_by" json:"Updated_by"` } func (ur *UserRow) AsUser() entity.User { @@ -651,9 +768,13 @@ func (ur *UserRow) AsUser() entity.User { Name: GetStringValue(ur.Name), UniqueUserID: GetStringValue(ur.UniqueUserID), Type: GetUserTypeValue(ur.Type), - CreatedAt: GetTimeValue(ur.CreatedAt), - DeletedAt: GetTimeValue(ur.DeletedAt), - UpdatedAt: GetTimeValue(ur.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(ur.CreatedAt), + CreatedBy: GetInt64Value(ur.CreatedBy), + DeletedAt: GetTimeValue(ur.DeletedAt), + UpdatedAt: GetTimeValue(ur.UpdatedAt), + UpdatedBy: GetInt64Value(ur.UpdatedBy), + }, } } @@ -663,8 +784,10 @@ func (ur *UserRow) FromUser(u *entity.User) { ur.UniqueUserID = sql.NullString{String: u.UniqueUserID, Valid: true} ur.Type = sql.NullInt64{Int64: int64(u.Type), Valid: true} ur.CreatedAt = sql.NullTime{Time: u.CreatedAt, Valid: true} + ur.CreatedBy = sql.NullInt64{Int64: u.CreatedBy, Valid: true} ur.DeletedAt = sql.NullTime{Time: u.DeletedAt, Valid: true} ur.UpdatedAt = sql.NullTime{Time: u.UpdatedAt, Valid: true} + ur.UpdatedBy = sql.NullInt64{Int64: u.UpdatedBy, Valid: true} } type EvidenceRow struct { @@ -679,8 +802,10 @@ type EvidenceRow struct { Activity *ActivityRow `json:"activity,omitempty"` ActivityId sql.NullInt64 `db:"evidence_activity_id"` CreatedAt sql.NullTime `db:"evidence_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"evidence_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"evidence_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"evidence_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"evidence_updated_by" json:"updated_by"` } func (er *EvidenceRow) AsEvidence() entity.Evidence { @@ -694,9 +819,13 @@ func (er *EvidenceRow) AsEvidence() entity.Evidence { UserId: GetInt64Value(er.UserId), Activity: nil, ActivityId: GetInt64Value(er.ActivityId), - CreatedAt: GetTimeValue(er.CreatedAt), - DeletedAt: GetTimeValue(er.DeletedAt), - UpdatedAt: GetTimeValue(er.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(er.CreatedAt), + CreatedBy: GetInt64Value(er.CreatedBy), + DeletedAt: GetTimeValue(er.DeletedAt), + UpdatedAt: GetTimeValue(er.UpdatedAt), + UpdatedBy: GetInt64Value(er.UpdatedBy), + }, } } @@ -710,8 +839,10 @@ func (er *EvidenceRow) FromEvidence(e *entity.Evidence) { er.UserId = sql.NullInt64{Int64: e.UserId, Valid: true} er.ActivityId = sql.NullInt64{Int64: e.ActivityId, Valid: true} er.CreatedAt = sql.NullTime{Time: e.CreatedAt, Valid: true} + er.CreatedBy = sql.NullInt64{Int64: e.CreatedBy, Valid: true} er.DeletedAt = sql.NullTime{Time: e.DeletedAt, Valid: true} er.UpdatedAt = sql.NullTime{Time: e.UpdatedAt, Valid: true} + er.UpdatedBy = sql.NullInt64{Int64: e.UpdatedBy, Valid: true} } type IssueMatchChangeRow struct { @@ -720,8 +851,10 @@ type IssueMatchChangeRow struct { ActivityId sql.NullInt64 `db:"issuematchchange_activity_id" json:"activity_id"` Action sql.NullString `db:"issuematchchange_action" json:"action"` CreatedAt sql.NullTime `db:"issuematchchange_created_at" json:"created_at"` + CreatedBy sql.NullInt64 `db:"issuematchchange_created_by" json:"created_by"` DeletedAt sql.NullTime `db:"issuematchchange_deleted_at" json:"deleted_at,omitempty"` UpdatedAt sql.NullTime `db:"issuematchchange_updated_at" json:"updated_at"` + UpdatedBy sql.NullInt64 `db:"issuematchchange_updated_by" json:"updated_by"` } func (imcr *IssueMatchChangeRow) AsIssueMatchChange() entity.IssueMatchChange { @@ -730,9 +863,13 @@ func (imcr *IssueMatchChangeRow) AsIssueMatchChange() entity.IssueMatchChange { IssueMatchId: GetInt64Value(imcr.IssueMatchId), ActivityId: GetInt64Value(imcr.ActivityId), Action: GetStringValue(imcr.Action), - CreatedAt: GetTimeValue(imcr.CreatedAt), - DeletedAt: GetTimeValue(imcr.DeletedAt), - UpdatedAt: GetTimeValue(imcr.UpdatedAt), + Metadata: entity.Metadata{ + CreatedAt: GetTimeValue(imcr.CreatedAt), + CreatedBy: GetInt64Value(imcr.CreatedBy), + DeletedAt: GetTimeValue(imcr.DeletedAt), + UpdatedAt: GetTimeValue(imcr.UpdatedAt), + UpdatedBy: GetInt64Value(imcr.UpdatedBy), + }, } } @@ -742,8 +879,10 @@ func (imcr *IssueMatchChangeRow) FromIssueMatchChange(imc *entity.IssueMatchChan imcr.ActivityId = sql.NullInt64{Int64: imc.ActivityId, Valid: true} imcr.Action = sql.NullString{String: imc.Action, Valid: true} imcr.CreatedAt = sql.NullTime{Time: imc.CreatedAt, Valid: true} + imcr.CreatedBy = sql.NullInt64{Int64: imc.CreatedBy, Valid: true} imcr.DeletedAt = sql.NullTime{Time: imc.DeletedAt, Valid: true} imcr.UpdatedAt = sql.NullTime{Time: imc.UpdatedAt, Valid: true} + imcr.UpdatedBy = sql.NullInt64{Int64: imc.UpdatedBy, Valid: true} } type OwnerRow struct { diff --git a/internal/database/mariadb/evidence.go b/internal/database/mariadb/evidence.go index 73d7c693..8838826c 100644 --- a/internal/database/mariadb/evidence.go +++ b/internal/database/mariadb/evidence.go @@ -76,6 +76,9 @@ func (s *SqlDatabase) getEvidenceUpdateFields(evidence *entity.Evidence) string if !evidence.RaaEnd.IsZero() { fl = append(fl, "evidence_raa_end = :evidence_raa_end") } + if evidence.UpdatedBy != 0 { + fl = append(fl, "evidence_updated_by = :evidence_updated_by") + } return strings.Join(fl, ", ") } @@ -220,7 +223,8 @@ func (s *SqlDatabase) CreateEvidence(evidence *entity.Evidence) (*entity.Evidenc evidence_description, evidence_vector, evidence_rating, - evidence_raa_end + evidence_raa_end, + evidence_created_by ) VALUES ( :evidence_author_id, :evidence_activity_id, @@ -228,7 +232,8 @@ func (s *SqlDatabase) CreateEvidence(evidence *entity.Evidence) (*entity.Evidenc :evidence_description, :evidence_vector, :evidence_rating, - :evidence_raa_end + :evidence_raa_end, + :evidence_created_by ) ` diff --git a/internal/database/mariadb/init/schema.sql b/internal/database/mariadb/init/schema.sql index c8b59885..995d1fbe 100644 --- a/internal/database/mariadb/init/schema.sql +++ b/internal/database/mariadb/init/schema.sql @@ -5,6 +5,36 @@ create schema if not exists heureka; use heureka; +create table if not exists User +( + user_id int unsigned auto_increment + primary key, + user_name varchar(256) not null, + user_unique_user_id varchar(64) not null, + user_type int unsigned, + user_created_at timestamp default current_timestamp() not null, + user_created_by int unsigned null, + user_deleted_at timestamp null, + user_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + user_updated_by int unsigned null, + constraint user_id_UNIQUE + unique (user_id), + constraint unique_user_id_UNIQUE + unique (user_unique_user_id), + constraint fk_user_created_by + foreign key (user_created_by) references User (user_id), + constraint fk_user_updated_by + foreign key (user_updated_by) references User (user_id) +); + +set @TechnicalUserType = 2; +set @SystemUserId = 1; +set @SystemUserName = 'systemuser'; +set @SystemUserUniqueUserId = 'S0000000'; +insert ignore into User (user_id, user_name, user_unique_user_id, user_type, user_created_at, user_created_by) + values + (@SystemUserId, @SystemUserName, @SystemUserUniqueUserId, @TechnicalUserType, current_timestamp(), @SystemUserId); + create table if not exists Component ( component_id int unsigned auto_increment @@ -12,12 +42,18 @@ create table if not exists Component component_ccrn varchar(256) not null, component_type varchar(256) not null, component_created_at timestamp default current_timestamp() not null, + component_created_by int unsigned null, component_deleted_at timestamp null, component_updated_at timestamp default current_timestamp() not null on update current_timestamp(), - constraint component_id_UNIQUE + component_updated_by int unsigned null, + constraint id_UNIQUE unique (component_id), constraint component_ccrn_UNIQUE - unique (component_ccrn) + unique (component_ccrn), + constraint fk_component_created_by + foreign key (component_created_by) references User (user_id), + constraint fk_component_updated_by + foreign key (component_updated_by) references User (user_id) ); create table if not exists ComponentVersion @@ -27,15 +63,21 @@ create table if not exists ComponentVersion componentversion_version varchar(256) not null, componentversion_component_id int unsigned not null, componentversion_created_at timestamp default current_timestamp() not null, + componentversion_created_by int unsigned null, componentversion_deleted_at timestamp null, componentversion_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + componentversion_updated_by int unsigned null, constraint componentversion_id_UNIQUE unique (componentversion_id), constraint version_component_UNIQUE unique (componentversion_version, componentversion_component_id), constraint fk_component_version_component foreign key (componentversion_component_id) references Component (component_id) - on update cascade + on update cascade, + constraint fk_componentversion_created_by + foreign key (componentversion_created_by) references User (user_id), + constraint fk_componentversion_updated_by + foreign key (componentversion_updated_by) references User (user_id) ); create table if not exists SupportGroup @@ -44,12 +86,18 @@ create table if not exists SupportGroup primary key, supportgroup_ccrn varchar(256) not null, supportgroup_created_at timestamp default current_timestamp() not null, + supportgroup_created_by int unsigned null, supportgroup_deleted_at timestamp null, supportgroup_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + supportgroup_updated_by int unsigned null, constraint supportgroup_id_UNIQUE unique (supportgroup_id), constraint supportgroup_ccrn_UNIQUE - unique (supportgroup_ccrn) + unique (supportgroup_ccrn), + constraint fk_supportgroup_created_by + foreign key (supportgroup_created_by) references User (user_id), + constraint fk_supportgroup_updated_by + foreign key (supportgroup_updated_by) references User (user_id) ); create table if not exists Service @@ -58,12 +106,18 @@ create table if not exists Service primary key, service_ccrn varchar(256) not null, service_created_at timestamp default current_timestamp() not null, + service_created_by int unsigned null, service_deleted_at timestamp null, service_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + service_updated_by int unsigned null, constraint service_id_UNIQUE unique (service_id), constraint service_ccrn_UNIQUE - unique (service_ccrn) + unique (service_ccrn), + constraint fk_service_created_by + foreign key (service_created_by) references User (user_id), + constraint fk_service_updated_by + foreign key (service_updated_by) references User (user_id) ); create table if not exists SupportGroupService @@ -88,10 +142,16 @@ create table if not exists Activity primary key, activity_status enum ('open','closed','in_progress') not null, activity_created_at timestamp default current_timestamp() not null, + activity_created_by int unsigned null, activity_deleted_at timestamp null, activity_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + activity_updated_by int unsigned null, constraint activity_id_UNIQUE - unique (activity_id) + unique (activity_id), + constraint fk_activity_created_by + foreign key (activity_created_by) references User (user_id), + constraint fk_activity_updated_by + foreign key (activity_updated_by) references User (user_id) ); create table if not exists ComponentInstance @@ -103,8 +163,10 @@ create table if not exists ComponentInstance componentinstance_component_version_id int unsigned not null, componentinstance_service_id int unsigned not null, componentinstance_created_at timestamp default current_timestamp() not null, + componentinstance_created_by int unsigned null, componentinstance_deleted_at timestamp null, componentinstance_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + componentinstance_updated_by int unsigned null, constraint componentinstance_id_UNIQUE unique (componentinstance_id), constraint componentinstance_ccrn_service_id_unique @@ -114,25 +176,11 @@ create table if not exists ComponentInstance on update cascade, constraint fk_component_instance_service foreign key (componentinstance_service_id) references Service (service_id) - on update cascade -); - - - -create table if not exists User -( - user_id int unsigned auto_increment - primary key, - user_name varchar(256) not null, - user_unique_user_id varchar(64) not null, - user_type int unsigned, - user_created_at timestamp default current_timestamp() not null, - user_deleted_at timestamp null, - user_updated_at timestamp default current_timestamp() not null on update current_timestamp(), - constraint user_id_UNIQUE - unique (user_id), - constraint unique_user_id_UNIQUE - unique (user_unique_user_id) + on update cascade, + constraint fk_componentinstance_created_by + foreign key (componentinstance_created_by) references User (user_id), + constraint fk_componentinstance_updated_by + foreign key (componentinstance_updated_by) references User (user_id) ); create table if not exists Evidence @@ -147,8 +195,10 @@ create table if not exists Evidence evidence_rating enum ('None','Low','Medium','High','Critical') null, evidence_raa_end datetime null, evidence_created_at timestamp default current_timestamp() not null, + evidence_created_by int unsigned null, evidence_deleted_at timestamp null, evidence_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + evidence_updated_by int unsigned null, constraint evidence_id_UNIQUE unique (evidence_id), constraint fk_evidence_user @@ -156,7 +206,11 @@ create table if not exists Evidence on update cascade, constraint fk_evidience_activity foreign key (evidence_activity_id) references Activity (activity_id) - on update cascade + on update cascade, + constraint fk_evidence_created_by + foreign key (evidence_created_by) references User (user_id), + constraint fk_evidence_updated_by + foreign key (evidence_updated_by) references User (user_id) ); @@ -201,12 +255,18 @@ create table if not exists IssueRepository issuerepository_name varchar(2048) not null, issuerepository_url varchar(2048) not null, issuerepository_created_at timestamp default current_timestamp() not null, + issuerepository_created_by int unsigned null, issuerepository_deleted_at timestamp null, issuerepository_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + issuerepository_updated_by int unsigned null, constraint issuerepository_id_UNIQUE unique (issuerepository_id), constraint issuerepository_name_UNIQUE - unique (issuerepository_name) + unique (issuerepository_name), + constraint fk_issuerepository_created_by + foreign key (issuerepository_created_by) references User (user_id), + constraint fk_issuerepository_updated_by + foreign key (issuerepository_updated_by) references User (user_id) ); create table if not exists Issue @@ -217,12 +277,18 @@ create table if not exists Issue issue_primary_name varchar(256) not null, issue_description longtext not null, issue_created_at timestamp default current_timestamp() not null, + issue_created_by int unsigned null, issue_deleted_at timestamp null, issue_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + issue_updated_by int unsigned null, constraint issue_id_UNIQUE unique (issue_id), constraint issue_primary_name_UNIQUE - unique (issue_primary_name) + unique (issue_primary_name), + constraint fk_issue_created_by + foreign key (issue_created_by) references User (user_id), + constraint fk_issue_updated_by + foreign key (issue_updated_by) references User (user_id) ); create table if not exists IssueVariant @@ -236,8 +302,10 @@ create table if not exists IssueVariant issuevariant_secondary_name varchar(256) not null, issuevariant_description longtext not null, issuevariant_created_at timestamp default current_timestamp() not null, + issuevariant_created_by int unsigned null, issuevariant_deleted_at timestamp null, issuevariant_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + issuevariant_updated_by int unsigned null, constraint issuevariant_id_UNIQUE unique (issuevariant_id), constraint issuevariant_secondary_name_UNIQUE @@ -246,7 +314,11 @@ create table if not exists IssueVariant foreign key (issuevariant_issue_id) references Issue (issue_id), constraint fk_issuevariant_issuerepository foreign key (issuevariant_repository_id) references IssueRepository (issuerepository_id) - on update cascade + on update cascade, + constraint fk_issuevariant_created_by + foreign key (issuevariant_created_by) references User (user_id), + constraint fk_issuevariant_updated_by + foreign key (issuevariant_updated_by) references User (user_id) ); create table if not exists ActivityHasIssue @@ -293,8 +365,10 @@ create table if not exists IssueMatch issuematch_component_instance_id int unsigned not null, issuematch_created_at timestamp default current_timestamp() not null, + issuematch_created_by int unsigned null, issuematch_deleted_at timestamp null, issuematch_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + issuematch_updated_by int unsigned null, constraint issuematch_id_UNIQUE unique (issuematch_id), constraint fk_issue_match_user_id @@ -305,7 +379,11 @@ create table if not exists IssueMatch on update cascade, constraint fk_issue_match_issue foreign key (issuematch_issue_id) references Issue (issue_id) - on update cascade + on update cascade, + constraint fk_issuematch_created_by + foreign key (issuematch_created_by) references User (user_id), + constraint fk_issuematch_updated_by + foreign key (issuematch_updated_by) references User (user_id) ); create table if not exists IssueMatchChange @@ -316,12 +394,18 @@ create table if not exists IssueMatchChange issuematchchange_issue_match_id int unsigned not null, issuematchchange_action enum ('add','remove') not null, issuematchchange_created_at timestamp default current_timestamp() not null, + issuematchchange_created_by int unsigned null, issuematchchange_deleted_at timestamp null, issuematchchange_updated_at timestamp default current_timestamp() not null on update current_timestamp(), + issuematchchange_updated_by int unsigned null, constraint fk_issuematchchange_activity foreign key (issuematchchange_activity_id) references Activity (activity_id), constraint fk_issuematchchange_issue_match - foreign key (issuematchchange_issue_match_id) references IssueMatch (issuematch_id) + foreign key (issuematchchange_issue_match_id) references IssueMatch (issuematch_id), + constraint fk_issuematchchange_created_by + foreign key (issuematchchange_created_by) references User (user_id), + constraint fk_issuematchchange_updated_by + foreign key (issuematchchange_updated_by) references User (user_id) ); create table if not exists ComponentVersionIssue @@ -358,9 +442,6 @@ create table if not exists IssueRepositoryService issuerepositoryservice_service_id int unsigned not null, issuerepositoryservice_issue_repository_id int unsigned not null, issuerepositoryservice_priority int unsigned not null, - issuerepositoryservice_created_at timestamp default current_timestamp() not null, - issuerepositoryservice_deleted_at timestamp null, - issuerepositoryservice_updated_at timestamp default current_timestamp() not null on update current_timestamp(), primary key (issuerepositoryservice_service_id, issuerepositoryservice_issue_repository_id), constraint fk_issue_repository_service foreign key (issuerepositoryservice_issue_repository_id) references IssueRepository (issuerepository_id) diff --git a/internal/database/mariadb/issue.go b/internal/database/mariadb/issue.go index ebfb98c7..88e995ac 100644 --- a/internal/database/mariadb/issue.go +++ b/internal/database/mariadb/issue.go @@ -134,6 +134,9 @@ func (s *SqlDatabase) getIssueUpdateFields(issue *entity.Issue) string { if issue.Description != "" { fl = append(fl, "issue_description = :issue_description") } + if issue.UpdatedBy != 0 { + fl = append(fl, "issue_updated_by = :issue_updated_by") + } return strings.Join(fl, ", ") } @@ -404,11 +407,13 @@ func (s *SqlDatabase) CreateIssue(issue *entity.Issue) (*entity.Issue, error) { INSERT INTO Issue ( issue_primary_name, issue_type, - issue_description + issue_description, + issue_created_by ) VALUES ( :issue_primary_name, :issue_type, - :issue_description + :issue_description, + :issue_created_by ) ` diff --git a/internal/database/mariadb/issue_match.go b/internal/database/mariadb/issue_match.go index 015845d6..9e5d1c6b 100644 --- a/internal/database/mariadb/issue_match.go +++ b/internal/database/mariadb/issue_match.go @@ -122,6 +122,9 @@ func (s *SqlDatabase) getIssueMatchUpdateFields(issueMatch *entity.IssueMatch) s if !issueMatch.TargetRemediationDate.IsZero() { fl = append(fl, "issuematch_target_remediation_date = :issuematch_target_remediation_date") } + if issueMatch.UpdatedBy != 0 { + fl = append(fl, "issuematch_updated_by = :issuematch_updated_by") + } return strings.Join(fl, ", ") } @@ -270,7 +273,8 @@ func (s *SqlDatabase) CreateIssueMatch(issueMatch *entity.IssueMatch) (*entity.I issuematch_rating, issuematch_user_id, issuematch_component_instance_id, - issuematch_issue_id + issuematch_issue_id, + issuematch_created_by ) VALUES ( :issuematch_status, :issuematch_remediation_date, @@ -279,7 +283,8 @@ func (s *SqlDatabase) CreateIssueMatch(issueMatch *entity.IssueMatch) (*entity.I :issuematch_rating, :issuematch_user_id, :issuematch_component_instance_id, - :issuematch_issue_id + :issuematch_issue_id, + :issuematch_created_by ) ` diff --git a/internal/database/mariadb/issue_match_change.go b/internal/database/mariadb/issue_match_change.go index 264d295b..f2273254 100644 --- a/internal/database/mariadb/issue_match_change.go +++ b/internal/database/mariadb/issue_match_change.go @@ -46,6 +46,9 @@ func (s *SqlDatabase) getIssueMatchChangeUpdateFields(imc *entity.IssueMatchChan if imc.Action != "" { fl = append(fl, "issuematchchange_action = :issuematchchange_action") } + if imc.UpdatedBy != 0 { + fl = append(fl, "issuematchchange_updated_by = :issuematchchange_updated_by") + } return strings.Join(fl, ", ") } @@ -181,11 +184,13 @@ func (s *SqlDatabase) CreateIssueMatchChange(imc *entity.IssueMatchChange) (*ent INSERT INTO IssueMatchChange ( issuematchchange_action, issuematchchange_activity_id, - issuematchchange_issue_match_id + issuematchchange_issue_match_id, + issuematchchange_created_by ) VALUES ( :issuematchchange_action, :issuematchchange_activity_id, - :issuematchchange_issue_match_id + :issuematchchange_issue_match_id, + :issuematchchange_created_by ) ` diff --git a/internal/database/mariadb/issue_repository.go b/internal/database/mariadb/issue_repository.go index e9f8eef5..74117308 100644 --- a/internal/database/mariadb/issue_repository.go +++ b/internal/database/mariadb/issue_repository.go @@ -46,6 +46,9 @@ func (s *SqlDatabase) getIssueRepositoryUpdateFields(issueRepository *entity.Iss if issueRepository.Url != "" { fl = append(fl, "issuerepository_url = :issuerepository_url") } + if issueRepository.BaseIssueRepository.UpdatedBy != 0 { + fl = append(fl, "issuerepository_updated_by = :issuerepository_updated_by") + } return strings.Join(fl, ", ") } @@ -218,10 +221,12 @@ func (s *SqlDatabase) CreateIssueRepository(issueRepository *entity.IssueReposit query := ` INSERT INTO IssueRepository ( issuerepository_name, - issuerepository_url + issuerepository_url, + issuerepository_created_by ) VALUES ( :issuerepository_name, - :issuerepository_url + :issuerepository_url, + :issuerepository_created_by ) ` diff --git a/internal/database/mariadb/issue_variant.go b/internal/database/mariadb/issue_variant.go index 651a28e7..1cac98b3 100644 --- a/internal/database/mariadb/issue_variant.go +++ b/internal/database/mariadb/issue_variant.go @@ -96,6 +96,9 @@ func (s *SqlDatabase) getIssueVariantUpdateFields(issueVariant *entity.IssueVari if issueVariant.IssueRepositoryId != 0 { fl = append(fl, "issuevariant_repository_id = :issuevariant_repository_id") } + if issueVariant.UpdatedBy != 0 { + fl = append(fl, "issuevariant_updated_by = :issuevariant_updated_by") + } return strings.Join(fl, ", ") } @@ -242,14 +245,16 @@ func (s *SqlDatabase) CreateIssueVariant(issueVariant *entity.IssueVariant) (*en issuevariant_vector, issuevariant_rating, issuevariant_secondary_name, - issuevariant_description + issuevariant_description, + issuevariant_created_by ) VALUES ( :issuevariant_issue_id, :issuevariant_repository_id, :issuevariant_vector, :issuevariant_rating, :issuevariant_secondary_name, - :issuevariant_description + :issuevariant_description, + :issuevariant_created_by ) ` diff --git a/internal/database/mariadb/service.go b/internal/database/mariadb/service.go index 21ff8495..9064115b 100644 --- a/internal/database/mariadb/service.go +++ b/internal/database/mariadb/service.go @@ -134,6 +134,9 @@ func (s *SqlDatabase) getServiceUpdateFields(service *entity.Service) string { if service.CCRN != "" { fl = append(fl, "service_ccrn = :service_ccrn") } + if service.BaseService.UpdatedBy != 0 { + fl = append(fl, "service_updated_by = :service_updated_by") + } return strings.Join(fl, ", ") } @@ -341,9 +344,11 @@ func (s *SqlDatabase) CreateService(service *entity.Service) (*entity.Service, e query := ` INSERT INTO Service ( - service_ccrn + service_ccrn, + service_created_by ) VALUES ( - :service_ccrn + :service_ccrn, + :service_created_by ) ` diff --git a/internal/database/mariadb/service_issue_variant_test.go b/internal/database/mariadb/service_issue_variant_test.go index e10f6d1a..403a3eed 100644 --- a/internal/database/mariadb/service_issue_variant_test.go +++ b/internal/database/mariadb/service_issue_variant_test.go @@ -206,7 +206,7 @@ var _ = Describe("ServiceIssueVariant - ", Label("database", "IssueVariant"), fu BeforeEach(func() { // Create service services = seeder.SeedServices(1) - + // Create issue issues := seeder.SeedIssues(1) issue = issues[0] @@ -228,7 +228,7 @@ var _ = Describe("ServiceIssueVariant - ", Label("database", "IssueVariant"), fu } _, err := seeder.InsertFakeComponentVersionIssue(cvi) Expect(err).To(BeNil()) - + // Create component instance componentInstances = seeder.SeedComponentInstances(1, componentVersions, services) @@ -263,13 +263,13 @@ var _ = Describe("ServiceIssueVariant - ", Label("database", "IssueVariant"), fu It("returns all variants when filtering for the issue", func() { filter := &entity.ServiceIssueVariantFilter{ ComponentInstanceId: []*int64{lo.ToPtr(componentInstances[0].Id.Int64)}, - IssueId: []*int64{lo.ToPtr(issue.Id.Int64)}, + IssueId: []*int64{lo.ToPtr(issue.Id.Int64)}, } res, err := db.GetServiceIssueVariants(filter) Expect(err).To(BeNil()) Expect(res).To(HaveLen(5)) // One variant per repository - + // All variants should be for our issue for _, variant := range res { Expect(variant.IssueId).To(Equal(issue.Id.Int64)) diff --git a/internal/database/mariadb/service_test.go b/internal/database/mariadb/service_test.go index e160fa90..4479f3a9 100644 --- a/internal/database/mariadb/service_test.go +++ b/internal/database/mariadb/service_test.go @@ -775,7 +775,9 @@ var _ = Describe("Service", Label("database", "Service"), func() { seedCollection = seeder.SeedDbWithNFakeData(10) newIssueRepositoryRow = test.NewFakeIssueRepository() newIssueRepository = newIssueRepositoryRow.AsIssueRepository() - issueRepository, _ = db.CreateIssueRepository(&newIssueRepository) + var err error + issueRepository, err = db.CreateIssueRepository(&newIssueRepository) + Expect(err).To(BeNil()) }) It("can add issue repository correctly", func() { service := seedCollection.ServiceRows[0].AsService() diff --git a/internal/database/mariadb/support_group.go b/internal/database/mariadb/support_group.go index f407af2e..024fc031 100644 --- a/internal/database/mariadb/support_group.go +++ b/internal/database/mariadb/support_group.go @@ -28,6 +28,9 @@ func (s *SqlDatabase) getSupportGroupUpdateFields(supportGroup *entity.SupportGr if supportGroup.CCRN != "" { fl = append(fl, "supportgroup_ccrn = :supportgroup_ccrn") } + if supportGroup.UpdatedBy != 0 { + fl = append(fl, "supportgroup_updated_by = :supportgroup_updated_by") + } return strings.Join(fl, ", ") } @@ -206,9 +209,11 @@ func (s *SqlDatabase) CreateSupportGroup(supportGroup *entity.SupportGroup) (*en query := ` INSERT INTO SupportGroup ( - supportgroup_ccrn + supportgroup_ccrn, + supportgroup_created_by ) VALUES ( - :supportgroup_ccrn + :supportgroup_ccrn, + :supportgroup_created_by ) ` diff --git a/internal/database/mariadb/test/database_manager.go b/internal/database/mariadb/test/database_manager.go index d1e30765..8006d2e9 100644 --- a/internal/database/mariadb/test/database_manager.go +++ b/internal/database/mariadb/test/database_manager.go @@ -149,6 +149,7 @@ func (dbm *LocalTestDataBaseManager) NewTestSchema() *mariadb.SqlDatabase { dbm.Schemas = append(dbm.Schemas, schemaName) dbm.CurrentSchema = schemaName dbm.Config.DBName = schemaName + dbm.Config.AuthType = "none" err := dbm.dbClient.SetupSchema(dbm.Config.Config) if err != nil { diff --git a/internal/database/mariadb/test/fixture.go b/internal/database/mariadb/test/fixture.go index e4e36ef3..a62921fe 100644 --- a/internal/database/mariadb/test/fixture.go +++ b/internal/database/mariadb/test/fixture.go @@ -9,6 +9,7 @@ import ( "math/rand" "strings" + "github.com/cloudoperators/heureka/internal/e2e/common" "github.com/cloudoperators/heureka/internal/entity" "github.com/goark/go-cvss/v3/metric" "github.com/onsi/ginkgo/v2/dsl/core" @@ -269,6 +270,7 @@ func GenerateRandomCVSS31Vector() string { } func (s *DatabaseSeeder) SeedDbForServer(n int) *SeedCollection { + users := s.SeedUsers(n) supportGroupsMap := s.SeedRealSupportGroups() supportGroups := lo.Values[string, mariadb.SupportGroupRow](supportGroupsMap) servicesMap := s.SeedRealServices() @@ -279,7 +281,6 @@ func (s *DatabaseSeeder) SeedDbForServer(n int) *SeedCollection { repos := s.SeedIssueRepositories() issues := s.SeedIssues(n) issueVariants := s.SeedIssueVariants(n, repos, issues) - users := s.SeedUsers(n) owners := s.SeedOwners(n, services, users) supportGroupServices := s.SeedRealSupportGroupService(servicesMap, supportGroupsMap) supportGroupUsers := s.SeedSupportGroupUsers(n, users, supportGroups) @@ -319,6 +320,7 @@ func (s *DatabaseSeeder) SeedDbForServer(n int) *SeedCollection { } func (s *DatabaseSeeder) SeedDbWithNFakeData(n int) *SeedCollection { + users := s.SeedUsers(n) supportGroups := s.SeedSupportGroups(n) services := s.SeedServices(n) components := s.SeedComponents(n) @@ -327,7 +329,6 @@ func (s *DatabaseSeeder) SeedDbWithNFakeData(n int) *SeedCollection { repos := s.SeedIssueRepositories() issues := s.SeedIssues(n) issueVariants := s.SeedIssueVariants(n, repos, issues) - users := s.SeedUsers(n) owners := s.SeedOwners(n, services, users) supportGroupServices := s.SeedSupportGroupServices(n/2, services, supportGroups) supportGroupUsers := s.SeedSupportGroupUsers(n/2, users, supportGroups) @@ -371,6 +372,7 @@ func (s *DatabaseSeeder) SeedDbWithFakeData() { } func (s *DatabaseSeeder) SeedDbForNestedIssueVariantTest() *SeedCollection { + users := s.SeedUsers(1) services := s.SeedServices(1) components := s.SeedComponents(1) componentVersions := s.SeedComponentVersions(1, components) @@ -378,7 +380,6 @@ func (s *DatabaseSeeder) SeedDbForNestedIssueVariantTest() *SeedCollection { repos := s.SeedIssueRepositories() issues := s.SeedIssues(1) issueVariants := s.SeedIssueVariants(100, repos, issues) - users := s.SeedUsers(1) issueMatches := s.SeedIssueMatches(1, issues, componentInstances, users) issueRepositoryServices := s.SeedIssueRepositoryServices(len(repos), services, repos) return &SeedCollection{ @@ -417,8 +418,10 @@ func (s *DatabaseSeeder) SeedIssueRepositories() []mariadb.BaseIssueRepositoryRo i := 0 for _, name := range variants { row := mariadb.BaseIssueRepositoryRow{ - Name: sql.NullString{String: fmt.Sprintf("%s-%s", name, gofakeit.UUID()), Valid: true}, - Url: sql.NullString{String: gofakeit.URL(), Valid: true}, + Name: sql.NullString{String: fmt.Sprintf("%s-%s", name, gofakeit.UUID()), Valid: true}, + Url: sql.NullString{String: gofakeit.URL(), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } id, err := s.InsertFakeBaseIssueRepository(row) if err != nil { @@ -1123,6 +1126,8 @@ func NewFakeIssueMatch() mariadb.IssueMatchRow { Rating: sql.NullString{String: rating, Valid: true}, RemediationDate: sql.NullTime{Time: gofakeit.Date(), Valid: true}, TargetRemediationDate: sql.NullTime{Time: gofakeit.Date(), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1131,6 +1136,8 @@ func NewFakeIssue() mariadb.IssueRow { PrimaryName: sql.NullString{String: fmt.Sprintf("CVE-%d-%d", gofakeit.Year(), gofakeit.Number(100, 9999999)), Valid: true}, Description: sql.NullString{String: gofakeit.HackerPhrase(), Valid: true}, Type: sql.NullString{String: gofakeit.RandomString(entity.AllIssueTypes), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1152,21 +1159,27 @@ func NewFakeIssueVariant(repos []mariadb.BaseIssueRepositoryRow, disc []mariadb. Int64: disc[rand.Intn(len(disc))].Id.Int64, Valid: true, }, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } func NewFakeIssueRepository() mariadb.IssueRepositoryRow { return mariadb.IssueRepositoryRow{ BaseIssueRepositoryRow: mariadb.BaseIssueRepositoryRow{ - Name: sql.NullString{String: fmt.Sprintf("%s-%s", gofakeit.AppName(), gofakeit.UUID()), Valid: true}, - Url: sql.NullString{String: gofakeit.URL(), Valid: true}, + Name: sql.NullString{String: fmt.Sprintf("%s-%s", gofakeit.AppName(), gofakeit.UUID()), Valid: true}, + Url: sql.NullString{String: gofakeit.URL(), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, }, } } func NewFakeBaseService() mariadb.BaseServiceRow { return mariadb.BaseServiceRow{ - CCRN: sql.NullString{String: fmt.Sprintf("%s-%s", gofakeit.AppName(), gofakeit.UUID()), Valid: true}, + CCRN: sql.NullString{String: fmt.Sprintf("%s-%s", gofakeit.AppName(), gofakeit.UUID()), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1181,7 +1194,9 @@ func NewFakeService() mariadb.ServiceRow { func NewFakeSupportGroup() mariadb.SupportGroupRow { return mariadb.SupportGroupRow{ - CCRN: sql.NullString{String: fmt.Sprintf("%s-%s", gofakeit.AppName(), gofakeit.UUID()), Valid: true}, + CCRN: sql.NullString{String: fmt.Sprintf("%s-%s", gofakeit.AppName(), gofakeit.UUID()), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1189,14 +1204,18 @@ func NewFakeComponent() mariadb.ComponentRow { types := []string{"containerImage", "virtualMachineImage", "repository"} ccrn := fmt.Sprintf("%s-%d", gofakeit.AppName(), gofakeit.UUID()) return mariadb.ComponentRow{ - CCRN: sql.NullString{String: ccrn, Valid: true}, - Type: sql.NullString{String: gofakeit.RandomString(types), Valid: true}, + CCRN: sql.NullString{String: ccrn, Valid: true}, + Type: sql.NullString{String: gofakeit.RandomString(types), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } func NewFakeComponentVersion() mariadb.ComponentVersionRow { return mariadb.ComponentVersionRow{ - Version: sql.NullString{String: gofakeit.AppVersion(), Valid: true}, + Version: sql.NullString{String: gofakeit.AppVersion(), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1206,8 +1225,10 @@ func NewFakeComponentInstance() mariadb.ComponentInstanceRow { n = n * -1 } return mariadb.ComponentInstanceRow{ - CCRN: sql.NullString{String: gofakeit.UUID(), Valid: true}, - Count: sql.NullInt16{Int16: n, Valid: true}, + CCRN: sql.NullString{String: gofakeit.UUID(), Valid: true}, + Count: sql.NullInt16{Int16: n, Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1229,6 +1250,8 @@ func NewFakeUser() mariadb.UserRow { Name: sql.NullString{String: gofakeit.Name(), Valid: true}, UniqueUserID: sql.NullString{String: uniqueUserId, Valid: true}, Type: sql.NullInt64{Int64: getNextUserType(), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1247,7 +1270,9 @@ func NewFakeSupportGroupUser() mariadb.SupportGroupUserRow { func NewFakeActivity() mariadb.ActivityRow { status := []string{"open", "closed", "in_progress"} return mariadb.ActivityRow{ - Status: sql.NullString{String: gofakeit.RandomString(status), Valid: true}, + Status: sql.NullString{String: gofakeit.RandomString(status), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1274,9 +1299,11 @@ func NewFakeEvidence() mariadb.EvidenceRow { String: gofakeit.RandomString(types), Valid: true, }, - Vector: sql.NullString{String: v, Valid: true}, - Rating: sql.NullString{String: rating, Valid: true}, - RAAEnd: sql.NullTime{Time: gofakeit.Date(), Valid: true}, + Vector: sql.NullString{String: v, Valid: true}, + Rating: sql.NullString{String: rating, Valid: true}, + RAAEnd: sql.NullTime{Time: gofakeit.Date(), Valid: true}, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } @@ -1294,6 +1321,8 @@ func NewFakeIssueMatchChange() mariadb.IssueMatchChangeRow { String: gofakeit.RandomString(entity.AllIssueMatchChangeActions), Valid: true, }, + CreatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, + UpdatedBy: sql.NullInt64{Int64: e2e_common.SystemUserId, Valid: true}, } } diff --git a/internal/database/mariadb/user.go b/internal/database/mariadb/user.go index dea44f59..59078262 100644 --- a/internal/database/mariadb/user.go +++ b/internal/database/mariadb/user.go @@ -62,6 +62,9 @@ func (s *SqlDatabase) getUserUpdateFields(user *entity.User) string { if user.Type != entity.InvalidUserType { fl = append(fl, "user_type = :user_type") } + if user.UpdatedBy != 0 { + fl = append(fl, "user_updated_by = :user_updated_by") + } return strings.Join(fl, ", ") } @@ -178,7 +181,6 @@ func (s *SqlDatabase) GetUsers(filter *entity.UserFilter) ([]entity.User, error) } defer stmt.Close() - return performListScan( stmt, filterParameters, @@ -220,11 +222,13 @@ func (s *SqlDatabase) CreateUser(user *entity.User) (*entity.User, error) { INSERT INTO User ( user_name, user_unique_user_id, - user_type + user_type, + user_created_by ) VALUES ( :user_name, :user_unique_user_id, - :user_type + :user_type, + :user_created_by ) ` diff --git a/internal/database/mariadb/user_test.go b/internal/database/mariadb/user_test.go index 75a86d6f..9e80c14f 100644 --- a/internal/database/mariadb/user_test.go +++ b/internal/database/mariadb/user_test.go @@ -8,6 +8,7 @@ import ( "github.com/cloudoperators/heureka/internal/database/mariadb" "github.com/cloudoperators/heureka/internal/database/mariadb/test" + "github.com/cloudoperators/heureka/internal/e2e/common" "github.com/cloudoperators/heureka/internal/entity" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -28,11 +29,12 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and the database is empty", func() { It("can perform the query", func() { res, err := db.GetAllUserIds(nil) + res = e2e_common.SubtractSystemUserId(res) By("throwing no error", func() { Expect(err).To(BeNil()) }) - By("returning an empty list", func() { + By("returning an empty list of non-system users", func() { Expect(res).To(BeEmpty()) }) }) @@ -50,6 +52,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and using no filter", func() { It("can fetch the items correctly", func() { res, err := db.GetAllUserIds(nil) + res = e2e_common.SubtractSystemUserId(res) By("throwing no error", func() { Expect(err).Should(BeNil()) @@ -105,6 +108,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and the database is empty", func() { It("can perform the query", func() { res, err := db.GetUsers(nil) + res = e2e_common.SubtractSystemUsersEntity(res) By("throwing no error", func() { Expect(err).To(BeNil()) @@ -123,7 +127,7 @@ var _ = Describe("User", Label("database", "User"), func() { It("can fetch the items correctly", func() { res, err := db.GetUsers(nil) - + res = e2e_common.SubtractSystemUsersEntity(res) By("throwing no error", func() { Expect(err).Should(BeNil()) }) @@ -304,7 +308,7 @@ var _ = Describe("User", Label("database", "User"), func() { }) By("number of human and technical user types should match number of all users", func() { - Expect(len(humanUserEntries) + len(technicalUserEntries)).To(BeEquivalentTo(len(seedCollection.UserRows))) + Expect(e2e_common.SubtractSystemUsers(len(humanUserEntries) + len(technicalUserEntries))).To(BeEquivalentTo(len(seedCollection.UserRows))) }) }) }) @@ -314,6 +318,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and the database is empty", func() { It("can count correctly", func() { c, err := db.CountUsers(nil) + c = e2e_common.SubtractSystemUsers(c) By("throwing no error", func() { Expect(err).To(BeNil()) @@ -336,6 +341,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and using no filter", func() { It("can count", func() { c, err := db.CountUsers(nil) + c = e2e_common.SubtractSystemUsers(c) By("throwing no error", func() { Expect(err).To(BeNil()) @@ -355,6 +361,7 @@ var _ = Describe("User", Label("database", "User"), func() { }, } c, err := db.CountUsers(filter) + c = e2e_common.SubtractSystemUsers(c) By("throwing no error", func() { Expect(err).To(BeNil()) @@ -545,6 +552,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and the database is empty", func() { It("can perform the list query", func() { res, err := db.GetUserNames(nil) + res = e2e_common.SubtractSystemUserNameVL(res) By("throwing no error", func() { Expect(err).To(BeNil()) }) @@ -562,6 +570,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and using no filter", func() { It("can fetch the items correctly", func() { res, err := db.GetUserNames(nil) + res = e2e_common.SubtractSystemUserNameVL(res) By("throwing no error", func() { Expect(err).Should(BeNil()) @@ -649,6 +658,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and the database is empty", func() { It("can perform the list query", func() { res, err := db.GetUniqueUserIDs(nil) + res = e2e_common.SubtractSystemUserUniqueUserIdVL(res) By("throwing no error", func() { Expect(err).To(BeNil()) }) @@ -666,6 +676,7 @@ var _ = Describe("User", Label("database", "User"), func() { Context("and using no filter", func() { It("can fetch the items correctly", func() { res, err := db.GetUniqueUserIDs(nil) + res = e2e_common.SubtractSystemUserUniqueUserIdVL(res) By("throwing no error", func() { Expect(err).Should(BeNil()) diff --git a/internal/e2e/common/issue.go b/internal/e2e/common/issue.go new file mode 100644 index 00000000..8fc26276 --- /dev/null +++ b/internal/e2e/common/issue.go @@ -0,0 +1,104 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + +package e2e_common + +import ( + "context" + "fmt" + "os" + + "github.com/cloudoperators/heureka/internal/api/graphql/graph/model" + util2 "github.com/cloudoperators/heureka/pkg/util" + + "github.com/machinebox/graphql" + . "github.com/onsi/gomega" + "github.com/sirupsen/logrus" +) + +type Issue struct { + PrimaryName string + Description string + Type string +} + +func QueryCreateIssue(port string, issue Issue) *model.Issue { + client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", port)) + + //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? + b, err := os.ReadFile("../api/graphql/graph/queryCollection/issue/create.graphql") + Expect(err).To(BeNil()) + str := string(b) + req := graphql.NewRequest(str) + + req.Var("input", map[string]string{ + "primaryName": issue.PrimaryName, + "description": issue.Description, + "type": issue.Type, + }) + + req.Header.Set("Cache-Control", "no-cache") + ctx := context.Background() + + var respData struct { + Issue model.Issue `json:"createIssue"` + } + if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { + logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") + } + return &respData.Issue +} + +func QueryUpdateIssue(port string, issue Issue, iid string) *model.Issue { + // create a queryCollection (safe to share across requests) + client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", port)) + + //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? + b, err := os.ReadFile("../api/graphql/graph/queryCollection/issue/update.graphql") + Expect(err).To(BeNil()) + str := string(b) + req := graphql.NewRequest(str) + + req.Var("id", iid) + req.Var("input", map[string]string{ + "description": issue.Description, + "type": issue.Type, + }) + + req.Header.Set("Cache-Control", "no-cache") + ctx := context.Background() + + var respData struct { + Issue model.Issue `json:"updateIssue"` + } + if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { + logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") + } + return &respData.Issue +} + +func QueryGetIssue(port string, issuePrimaryName string) *model.IssueConnection { + // create a queryCollection (safe to share across requests) + client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", port)) + + //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? + b, err := os.ReadFile("../api/graphql/graph/queryCollection/issue/listIssues.graphql") + Expect(err).To(BeNil()) + str := string(b) + req := graphql.NewRequest(str) + + req.Var("filter", map[string]string{"primaryName": issuePrimaryName}) + req.Var("first", 1) + req.Var("after", "0") + + req.Header.Set("Cache-Control", "no-cache") + ctx := context.Background() + + var respData struct { + Issues model.IssueConnection `json:"Issues"` + } + if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { + logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") + } + return &respData.Issues +} diff --git a/internal/e2e/common/user.go b/internal/e2e/common/user.go new file mode 100644 index 00000000..9c697476 --- /dev/null +++ b/internal/e2e/common/user.go @@ -0,0 +1,169 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + +package e2e_common + +import ( + "context" + "fmt" + "os" + + "github.com/cloudoperators/heureka/internal/api/graphql/graph/model" + "github.com/cloudoperators/heureka/internal/entity" + util2 "github.com/cloudoperators/heureka/pkg/util" + + "github.com/machinebox/graphql" + . "github.com/onsi/gomega" + "github.com/samber/lo" + "github.com/sirupsen/logrus" +) + +const NumberOfSystemUsers = 1 +const SystemUserId = 1 +const EmptyUserId = -1 + +var SystemUserName = "systemuser" +var SystemUserUniqueUserId = "S0000000" + +type Number interface { + int | int64 +} + +func SubtractSystemUsers[T Number](n T) T { + return n - NumberOfSystemUsers +} + +func SubtractSystemUserName(v []*string) []*string { + return lo.Filter(v, func(val *string, _ int) bool { + return val == nil || *val != SystemUserName + }) +} + +func SubtractSystemUserUniqueUserId(v []*string) []*string { + return lo.Filter(v, func(val *string, _ int) bool { + return val == nil || *val != SystemUserUniqueUserId + }) +} + +func SubtractSystemUserUniqueUserIdVL(v []string) []string { + return lo.Filter(v, func(val string, _ int) bool { + return val != SystemUserUniqueUserId + }) +} + +func SubtractSystemUserNameVL(v []string) []string { + return lo.Filter(v, func(val string, _ int) bool { + return val != SystemUserName + }) +} + +func SubtractSystemUsersEntity(v []entity.User) []entity.User { + return lo.Filter(v, func(val entity.User, _ int) bool { + return val.UniqueUserID != SystemUserUniqueUserId + }) +} + +func SubtractSystemUserId(v []int64) []int64 { + return lo.Filter(v, func(val int64, _ int) bool { + return val != SystemUserId + }) +} + +func ExpectNonSystemUserCount(n, expectedN int) { + Expect(SubtractSystemUsers(n)).To(Equal(expectedN)) +} + +func ExpectNonSystemUserNames(v, expectedV []*string) { + Expect(SubtractSystemUserName(v)).To(Equal(expectedV)) +} + +func ExpectNonSystemUserUniqueUserIds(v, expectedV []*string) { + Expect(SubtractSystemUserUniqueUserId(v)).To(Equal(expectedV)) +} + +type User struct { + UniqueUserID string + Type entity.UserType + Name string +} + +func QueryCreateUser(port string, user User) *model.User { + client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", port)) + + //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? + b, err := os.ReadFile("../api/graphql/graph/queryCollection/user/create.graphql") + Expect(err).To(BeNil()) + str := string(b) + req := graphql.NewRequest(str) + + req.Var("input", map[string]string{ + "uniqueUserId": user.UniqueUserID, + "type": entity.GetUserTypeString(user.Type), + "name": user.Name, + }) + + req.Header.Set("Cache-Control", "no-cache") + ctx := context.Background() + + var respData struct { + User model.User `json:"createUser"` + } + if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { + logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") + } + return &respData.User +} + +func QueryUpdateUser(port string, user User, uid string) *model.User { + // create a queryCollection (safe to share across requests) + client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", port)) + + //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? + b, err := os.ReadFile("../api/graphql/graph/queryCollection/user/update.graphql") + Expect(err).To(BeNil()) + str := string(b) + req := graphql.NewRequest(str) + + req.Var("id", uid) + req.Var("input", map[string]string{ + "name": user.Name, + "type": entity.GetUserTypeString(user.Type), + }) + + req.Header.Set("Cache-Control", "no-cache") + ctx := context.Background() + + var respData struct { + User model.User `json:"updateUser"` + } + if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { + logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") + } + return &respData.User +} + +func QueryGetUser(port string, uniqueUserId string) *model.UserConnection { + // create a queryCollection (safe to share across requests) + client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", port)) + + //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? + b, err := os.ReadFile("../api/graphql/graph/queryCollection/user/listUsers.graphql") + Expect(err).To(BeNil()) + str := string(b) + req := graphql.NewRequest(str) + + req.Var("filter", map[string]string{"uniqueUserId": uniqueUserId}) + req.Var("first", 1) + req.Var("after", "0") + + req.Header.Set("Cache-Control", "no-cache") + ctx := context.Background() + + var respData struct { + Users model.UserConnection `json:"Users"` + } + if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { + logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") + } + return &respData.Users +} diff --git a/internal/e2e/issue_query_test.go b/internal/e2e/issue_query_test.go index f4846d7b..e4bacbec 100644 --- a/internal/e2e/issue_query_test.go +++ b/internal/e2e/issue_query_test.go @@ -199,13 +199,13 @@ var _ = Describe("Getting Issues via API", Label("e2e", "Issues"), func() { Expect(*respData.Issues.PageInfo.PageNumber).To(Equal(1), "Correct page number") }) }) - Context("and we request metadata", Label("withMetadata.graphql"), func() { + Context("and we request metadata", Label("withObjectMetadata.graphql"), func() { It("returns correct metadata counts", func() { // create a queryCollection (safe to share across requests) client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", cfg.Port)) //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? - b, err := os.ReadFile("../api/graphql/graph/queryCollection/issue/withMetadata.graphql") + b, err := os.ReadFile("../api/graphql/graph/queryCollection/issue/withObjectMetadata.graphql") Expect(err).To(BeNil()) str := string(b) @@ -232,10 +232,10 @@ var _ = Describe("Getting Issues via API", Label("e2e", "Issues"), func() { ciCount += *imEdge.Node.ComponentInstance.Count serviceIdSet[imEdge.Node.ComponentInstance.Service.ID] = true } - Expect(issueEdge.Node.Metadata.IssueMatchCount).To(Equal(issueEdge.Node.IssueMatches.TotalCount), "IssueMatchCount is correct") - Expect(issueEdge.Node.Metadata.ComponentInstanceCount).To(Equal(ciCount), "ComponentInstanceCount is correct") - Expect(issueEdge.Node.Metadata.ActivityCount).To(Equal(issueEdge.Node.Activities.TotalCount), "ActivityCount is correct") - Expect(issueEdge.Node.Metadata.ServiceCount).To(Equal(len(serviceIdSet)), "ServiceCount is correct") + Expect(issueEdge.Node.ObjectMetadata.IssueMatchCount).To(Equal(issueEdge.Node.IssueMatches.TotalCount), "IssueMatchCount is correct") + Expect(issueEdge.Node.ObjectMetadata.ComponentInstanceCount).To(Equal(ciCount), "ComponentInstanceCount is correct") + Expect(issueEdge.Node.ObjectMetadata.ActivityCount).To(Equal(issueEdge.Node.Activities.TotalCount), "ActivityCount is correct") + Expect(issueEdge.Node.ObjectMetadata.ServiceCount).To(Equal(len(serviceIdSet)), "ServiceCount is correct") } }) }) @@ -286,7 +286,7 @@ var _ = Describe("Creating Issue via API", Label("e2e", "Issues"), func() { str := string(b) req := graphql.NewRequest(str) - req.Var("input", map[string]string{ + req.Var("input", map[string]interface{}{ "primaryName": issue.PrimaryName, "description": issue.Description, "type": issue.Type.String(), diff --git a/internal/e2e/metadata_test.go b/internal/e2e/metadata_test.go new file mode 100644 index 00000000..bb0d82a9 --- /dev/null +++ b/internal/e2e/metadata_test.go @@ -0,0 +1,123 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + +package e2e_test + +import ( + "fmt" + "time" + + "github.com/cloudoperators/heureka/internal/api/graphql/graph/model" + "github.com/cloudoperators/heureka/internal/e2e/common" + "github.com/cloudoperators/heureka/internal/entity" + "github.com/cloudoperators/heureka/internal/server" + "github.com/cloudoperators/heureka/internal/util" + util2 "github.com/cloudoperators/heureka/pkg/util" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + testIssuePrimaryName = "PN-001" + testCreatedIssueDescription = "Created Issue" + testUpdatedIssueDescription = "Updated Issue" + dbDateLayout = "2006-01-02 15:04:05 -0700 MST" +) + +var ( + testCreatedIssueType = entity.IssueTypeVulnerability.String() + testUpdatedIssueType = entity.IssueTypePolicyViolation.String() +) + +func createTestIssue(port string) string { + issue := e2e_common.QueryCreateIssue(port, e2e_common.Issue{PrimaryName: testIssuePrimaryName, Description: testCreatedIssueDescription, Type: testCreatedIssueType}) + Expect(*issue.PrimaryName).To(Equal(testIssuePrimaryName)) + Expect(*issue.Description).To(Equal(testCreatedIssueDescription)) + Expect(issue.Type.String()).To(Equal(testCreatedIssueType)) + return issue.ID +} +func updateTestIssue(port string, iid string) { + issue := e2e_common.QueryUpdateIssue(port, e2e_common.Issue{PrimaryName: testIssuePrimaryName, Description: testUpdatedIssueDescription, Type: testUpdatedIssueType}, iid) + Expect(*issue.PrimaryName).To(Equal(testIssuePrimaryName)) + Expect(*issue.Description).To(Equal(testUpdatedIssueDescription)) + Expect(issue.Type.String()).To(Equal(testUpdatedIssueType)) +} + +func getTestIssue(port string) model.Issue { + issues := e2e_common.QueryGetIssue(port, testIssuePrimaryName) + Expect(issues.TotalCount).To(Equal(1)) + return *issues.Edges[0].Node +} + +var _ = Describe("Creating and updating entity via API", Label("e2e", "Entities"), func() { + var s *server.Server + var cfg util.Config + + BeforeEach(func() { + _ = dbm.NewTestSchema() + + cfg = dbm.DbConfig() + cfg.Port = util2.GetRandomFreePort() + s = server.NewServer(cfg) + + s.NonBlockingStart() + }) + + AfterEach(func() { + s.BlockingStop() + }) + + When("New issue is created via API", func() { + var issue model.Issue + BeforeEach(func() { + createTestIssue(cfg.Port) + issue = getTestIssue(cfg.Port) + }) + It("shall assign CreatedBy and CreatedAt metadata fields and shall keep nil in UpdatedBy, UpdatedAt and DeltedAt metadata fields", func() { + Expect(*issue.Description).To(Equal(testCreatedIssueDescription)) + Expect(issue.Type.String()).To(Equal(testCreatedIssueType)) + + Expect(issue.Metadata).To(Not(BeNil())) + Expect(*issue.Metadata.CreatedBy).To(Equal(fmt.Sprintf("%d", e2e_common.SystemUserId))) + + createdAt, err := time.Parse(dbDateLayout, *issue.Metadata.CreatedAt) + Expect(err).Should(BeNil()) + Expect(createdAt).Should(BeTemporally("~", time.Now().UTC(), 3*time.Second)) + + Expect(*issue.Metadata.UpdatedBy).To(Equal(fmt.Sprintf("%d", e2e_common.EmptyUserId))) + + updatedAt, err := time.Parse(dbDateLayout, *issue.Metadata.UpdatedAt) + Expect(err).Should(BeNil()) + Expect(updatedAt).To(Equal(createdAt)) + }) + }) + When("Issue is updated via API", func() { + var issue model.Issue + BeforeEach(func() { + iid := createTestIssue(cfg.Port) + time.Sleep(1100 * time.Millisecond) + updateTestIssue(cfg.Port, iid) + issue = getTestIssue(cfg.Port) + }) + It("shall assign UpdatedBy and UpdatedAt metadata fields and shall keep nil in DeletedAt metadata field", func() { + Expect(*issue.Description).To(Equal(testUpdatedIssueDescription)) + Expect(issue.Type.String()).To(Equal(testUpdatedIssueType)) + + Expect(issue.Metadata).To(Not(BeNil())) + Expect(*issue.Metadata.CreatedBy).To(Equal(fmt.Sprintf("%d", e2e_common.SystemUserId))) + + createdAt, err := time.Parse(dbDateLayout, *issue.Metadata.CreatedAt) + Expect(err).Should(BeNil()) + Expect(createdAt).Should(BeTemporally("~", time.Now().UTC(), 3*time.Second)) + + Expect(*issue.Metadata.UpdatedBy).To(Equal(fmt.Sprintf("%d", e2e_common.SystemUserId))) + + updatedAt, err := time.Parse(dbDateLayout, *issue.Metadata.UpdatedAt) + Expect(err).Should(BeNil()) + Expect(updatedAt).Should(BeTemporally("~", time.Now().UTC(), 2*time.Second)) + Expect(updatedAt).Should(BeTemporally(">", createdAt)) + }) + }) + +}) diff --git a/internal/e2e/service_filter_query_test.go b/internal/e2e/service_filter_query_test.go index 73ca78a9..3f758965 100644 --- a/internal/e2e/service_filter_query_test.go +++ b/internal/e2e/service_filter_query_test.go @@ -16,6 +16,7 @@ import ( "github.com/cloudoperators/heureka/internal/api/graphql/graph/model" "github.com/cloudoperators/heureka/internal/database/mariadb" "github.com/cloudoperators/heureka/internal/database/mariadb/test" + "github.com/cloudoperators/heureka/internal/e2e/common" "github.com/machinebox/graphql" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -109,7 +110,7 @@ var _ = Describe("Getting ServiceFilterValues via API", Label("e2e", "ServiceFil logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") } - Expect(respData.ServiceFilterValues.UserName.Values).To(BeEmpty()) + e2e_common.ExpectNonSystemUserNames(respData.ServiceFilterValues.UserName.Values, []*string{}) }) It("returns empty for uniqueUserID", func() { client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", cfg.Port)) @@ -130,7 +131,7 @@ var _ = Describe("Getting ServiceFilterValues via API", Label("e2e", "ServiceFil logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") } - Expect(respData.ServiceFilterValues.UniqueUserID.Values).To(BeEmpty()) + e2e_common.ExpectNonSystemUserUniqueUserIds(respData.ServiceFilterValues.UniqueUserID.Values, []*string{}) }) }) @@ -218,13 +219,13 @@ var _ = Describe("Getting ServiceFilterValues via API", Label("e2e", "ServiceFil logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") } - Expect(len(respData.ServiceFilterValues.UserName.Values)).To(Equal(len(seedCollection.UserRows))) + e2e_common.ExpectNonSystemUserCount(len(respData.ServiceFilterValues.UserName.Values), len(seedCollection.UserRows)) existingUserNames := lo.Map(seedCollection.UserRows, func(s mariadb.UserRow, index int) string { return s.Name.String }) - for _, name := range respData.ServiceFilterValues.UserName.Values { + for _, name := range e2e_common.SubtractSystemUserName(respData.ServiceFilterValues.UserName.Values) { Expect(lo.Contains(existingUserNames, *name)).To(BeTrue()) } }) @@ -247,13 +248,13 @@ var _ = Describe("Getting ServiceFilterValues via API", Label("e2e", "ServiceFil logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") } - Expect(len(respData.ServiceFilterValues.UniqueUserID.Values)).To(Equal(len(seedCollection.UserRows))) + e2e_common.ExpectNonSystemUserCount(len(respData.ServiceFilterValues.UniqueUserID.Values), len(seedCollection.UserRows)) existingUniqueUserIds := lo.Map(seedCollection.UserRows, func(s mariadb.UserRow, index int) string { return s.UniqueUserID.String }) - for _, name := range respData.ServiceFilterValues.UniqueUserID.Values { + for _, name := range e2e_common.SubtractSystemUserUniqueUserId(respData.ServiceFilterValues.UniqueUserID.Values) { Expect(lo.Contains(existingUniqueUserIds, *name)).To(BeTrue()) } }) diff --git a/internal/e2e/service_query_test.go b/internal/e2e/service_query_test.go index b7b46656..1742c868 100644 --- a/internal/e2e/service_query_test.go +++ b/internal/e2e/service_query_test.go @@ -119,7 +119,7 @@ var _ = Describe("Getting Services via API", Label("e2e", "Services"), func() { client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", cfg.Port)) //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? - b, err := os.ReadFile("../api/graphql/graph/queryCollection/service/withMetadata.graphql") + b, err := os.ReadFile("../api/graphql/graph/queryCollection/service/withObjectMetadata.graphql") Expect(err).To(BeNil()) str := string(b) @@ -146,8 +146,8 @@ var _ = Describe("Getting Services via API", Label("e2e", "Services"), func() { imCount += ciEdge.Node.IssueMatches.TotalCount ciCount += *ciEdge.Node.Count } - Expect(serviceEdge.Node.Metadata.IssueMatchCount).To(Equal(imCount)) - Expect(serviceEdge.Node.Metadata.ComponentInstanceCount).To(Equal(ciCount)) + Expect(serviceEdge.Node.ObjectMetadata.IssueMatchCount).To(Equal(imCount)) + Expect(serviceEdge.Node.ObjectMetadata.ComponentInstanceCount).To(Equal(ciCount)) } }) diff --git a/internal/e2e/user_query_test.go b/internal/e2e/user_query_test.go index f32fe6c5..7ca75dd7 100644 --- a/internal/e2e/user_query_test.go +++ b/internal/e2e/user_query_test.go @@ -21,6 +21,7 @@ import ( "github.com/sirupsen/logrus" "github.com/cloudoperators/heureka/internal/database/mariadb/test" + "github.com/cloudoperators/heureka/internal/e2e/common" testentity "github.com/cloudoperators/heureka/internal/entity/test" "github.com/cloudoperators/heureka/internal/server" ) @@ -73,8 +74,7 @@ var _ = Describe("Getting Users via API", Label("e2e", "Users"), func() { if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") } - - Expect(respData.Users.TotalCount).To(Equal(0)) + e2e_common.ExpectNonSystemUserCount(respData.Users.TotalCount, 0) }) }) @@ -112,7 +112,7 @@ var _ = Describe("Getting Users via API", Label("e2e", "Users"), func() { logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") } - Expect(respData.Users.TotalCount).To(Equal(len(seedCollection.UserRows))) + e2e_common.ExpectNonSystemUserCount(respData.Users.TotalCount, len(seedCollection.UserRows)) Expect(len(respData.Users.Edges)).To(Equal(5)) }) }) @@ -145,7 +145,7 @@ var _ = Describe("Getting Users via API", Label("e2e", "Users"), func() { }) It("- returns the correct result count", func() { - Expect(respData.Users.TotalCount).To(Equal(len(seedCollection.UserRows))) + e2e_common.ExpectNonSystemUserCount(respData.Users.TotalCount, len(seedCollection.UserRows)) Expect(len(respData.Users.Edges)).To(Equal(5)) }) @@ -188,7 +188,7 @@ var _ = Describe("Getting Users via API", Label("e2e", "Users"), func() { Expect(*respData.Users.PageInfo.HasNextPage).To(BeTrue(), "hasNextPage is set") Expect(*respData.Users.PageInfo.HasPreviousPage).To(BeFalse(), "hasPreviousPage is set") Expect(respData.Users.PageInfo.NextPageAfter).ToNot(BeNil(), "nextPageAfter is set") - Expect(len(respData.Users.PageInfo.Pages)).To(Equal(2), "Correct amount of pages") + Expect(len(respData.Users.PageInfo.Pages)).To(Equal(3), "Correct amount of pages") Expect(*respData.Users.PageInfo.PageNumber).To(Equal(1), "Correct page number") }) }) @@ -229,35 +229,10 @@ var _ = Describe("Creating User via API", Label("e2e", "Users"), func() { Context("and a mutation query is performed", Label("create.graphql"), func() { It("creates new user", func() { - // create a queryCollection (safe to share across requests) - client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", cfg.Port)) - - //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? - b, err := os.ReadFile("../api/graphql/graph/queryCollection/user/create.graphql") - - Expect(err).To(BeNil()) - str := string(b) - req := graphql.NewRequest(str) - - req.Var("input", map[string]string{ - "uniqueUserId": user.UniqueUserID, - "type": entity.GetUserTypeString(user.Type), - "name": user.Name, - }) - - req.Header.Set("Cache-Control", "no-cache") - ctx := context.Background() - - var respData struct { - User model.User `json:"createUser"` - } - if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { - logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") - } - - Expect(*respData.User.Name).To(Equal(user.Name)) - Expect(*respData.User.UniqueUserID).To(Equal(user.UniqueUserID)) - Expect(entity.UserType(respData.User.Type)).To(Equal(user.Type)) + respUser := e2e_common.QueryCreateUser(cfg.Port, e2e_common.User{UniqueUserID: user.UniqueUserID, Type: user.Type, Name: user.Name}) + Expect(*respUser.Name).To(Equal(user.Name)) + Expect(*respUser.UniqueUserID).To(Equal(user.UniqueUserID)) + Expect(entity.UserType(respUser.Type)).To(Equal(user.Type)) }) }) }) @@ -295,37 +270,12 @@ var _ = Describe("Updating User via API", Label("e2e", "Users"), func() { Context("and a mutation query is performed", Label("update.graphql"), func() { It("updates user", func() { - // create a queryCollection (safe to share across requests) - client := graphql.NewClient(fmt.Sprintf("http://localhost:%s/query", cfg.Port)) - - //@todo may need to make this more fault proof?! What if the test is executed from the root dir? does it still work? - b, err := os.ReadFile("../api/graphql/graph/queryCollection/user/update.graphql") - - Expect(err).To(BeNil()) - str := string(b) - req := graphql.NewRequest(str) - user := seedCollection.UserRows[0].AsUser() user.Name = "Sauron" - - req.Var("id", fmt.Sprintf("%d", user.Id)) - req.Var("input", map[string]string{ - "name": user.Name, - }) - - req.Header.Set("Cache-Control", "no-cache") - ctx := context.Background() - - var respData struct { - User model.User `json:"updateUser"` - } - if err := util2.RequestWithBackoff(func() error { return client.Run(ctx, req, &respData) }); err != nil { - logrus.WithError(err).WithField("request", req).Fatalln("Error while unmarshaling") - } - - Expect(*respData.User.Name).To(Equal(user.Name)) - Expect(*respData.User.UniqueUserID).To(Equal(user.UniqueUserID)) - Expect(entity.UserType(respData.User.Type)).To(Equal(user.Type)) + respUser := e2e_common.QueryUpdateUser(cfg.Port, e2e_common.User{UniqueUserID: user.UniqueUserID, Name: user.Name, Type: user.Type}, fmt.Sprintf("%d", user.Id)) + Expect(*respUser.Name).To(Equal(user.Name)) + Expect(*respUser.UniqueUserID).To(Equal(user.UniqueUserID)) + Expect(entity.UserType(respUser.Type)).To(Equal(user.Type)) }) }) }) diff --git a/internal/entity/activity.go b/internal/entity/activity.go index 4769e363..2bb0ffa5 100644 --- a/internal/entity/activity.go +++ b/internal/entity/activity.go @@ -3,8 +3,6 @@ package entity -import "time" - type ActivityStatusValue string const ( @@ -36,14 +34,12 @@ var AllActivityStatusValues = []string{ } type Activity struct { + Metadata Id int64 `json:"id"` Status ActivityStatusValue `json:"status"` Service *Service `json:"service,omitempty"` Issues []Issue `json:"issues,omitempty"` Evidences []Evidence `json:"evidences,omitempty"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } func (a *Activity) GetId() int64 { @@ -51,11 +47,9 @@ func (a *Activity) GetId() int64 { } type ActivityHasIssue struct { - ActivityId int64 `json:"activity_id"` - IssueId int64 `json:"issue_id"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + ActivityId int64 `json:"activity_id"` + IssueId int64 `json:"issue_id"` } type ActivityAggregations struct { diff --git a/internal/entity/common.go b/internal/entity/common.go index 1a11dac2..f0d26d0f 100644 --- a/internal/entity/common.go +++ b/internal/entity/common.go @@ -17,10 +17,13 @@ import ( type HeurekaEntity interface { Activity | + ActivityAggregations | ActivityHasIssue | IssueVariant | + IssueVariantAggregations | BaseIssueRepository | IssueRepository | + IssueRepositoryAggregations | ResultList | ListOptions | PageInfo | @@ -28,18 +31,23 @@ type HeurekaEntity interface { Severity | Cvss | Component | - ComponentInstanceAggregations | + ComponentAggregations | ComponentInstance | + ComponentInstanceAggregations | ComponentVersion | + ComponentVersionAggregations | Evidence | + EvidenceAggregations | BaseService | Service | ServiceAggregations | ServiceWithAggregations | SupportGroup | + SupportGroupAggregations | SupportGroupService | SupportGroupUser | User | + UserAggregations | IssueWithAggregations | IssueAggregations | Issue | @@ -47,6 +55,7 @@ type HeurekaEntity interface { IssueMatchChange | HeurekaFilter | IssueCount | + IssueTypeCounts | ServiceIssueVariant } @@ -64,7 +73,8 @@ type HeurekaFilter interface { EvidenceFilter | ComponentFilter | ComponentVersionFilter | - IssueRepositoryFilter + IssueRepositoryFilter | + SeverityFilter } type HasCursor interface { @@ -185,3 +195,11 @@ type Cvss struct { Temporal *metric.Temporal Environmental *metric.Environmental } + +type Metadata struct { + CreatedAt time.Time `json:"created_at"` + CreatedBy int64 `json:"created_by"` + UpdatedAt time.Time `json:"updated_at"` + UpdatedBy int64 `json:"updated_by"` + DeletedAt time.Time `json:"deleted_at,omitempty"` +} diff --git a/internal/entity/component.go b/internal/entity/component.go index 45eff250..82d5d959 100644 --- a/internal/entity/component.go +++ b/internal/entity/component.go @@ -3,15 +3,11 @@ package entity -import "time" - type Component struct { - Id int64 `json:"id"` - CCRN string `json:"ccrn"` - Type string `json:"type"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + Id int64 `json:"id"` + CCRN string `json:"ccrn"` + Type string `json:"type"` } type ComponentResult struct { diff --git a/internal/entity/component_instance.go b/internal/entity/component_instance.go index d20ad7de..a9249a47 100644 --- a/internal/entity/component_instance.go +++ b/internal/entity/component_instance.go @@ -3,8 +3,6 @@ package entity -import "time" - type ComponentInstanceFilter struct { Paginated IssueMatchId []*int64 `json:"issue_match_id"` @@ -16,7 +14,8 @@ type ComponentInstanceFilter struct { Search []*string `json:"search"` } -type ComponentInstanceAggregations struct{} +type ComponentInstanceAggregations struct { +} type ComponentInstanceResult struct { WithCursor @@ -25,6 +24,7 @@ type ComponentInstanceResult struct { } type ComponentInstance struct { + Metadata Id int64 `json:"id"` CCRN string `json:"ccrn"` Count int16 `json:"count"` @@ -32,7 +32,4 @@ type ComponentInstance struct { ComponentVersionId int64 `db:"componentinstance_component_version_id"` Service *Service `json:"service,omitempty"` ServiceId int64 `db:"componentinstance_service_id"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } diff --git a/internal/entity/component_version.go b/internal/entity/component_version.go index 6ea5d88b..1d76d1f4 100644 --- a/internal/entity/component_version.go +++ b/internal/entity/component_version.go @@ -3,8 +3,6 @@ package entity -import "time" - type ComponentVersionFilter struct { Paginated Id []*int64 `json:"id"` @@ -14,7 +12,8 @@ type ComponentVersionFilter struct { Version []*string `json:"version"` } -type ComponentVersionAggregations struct{} +type ComponentVersionAggregations struct { +} type ComponentVersionResult struct { WithCursor @@ -23,13 +22,11 @@ type ComponentVersionResult struct { } type ComponentVersion struct { + Metadata Id int64 `json:"id"` Version string `json:"version"` Component *Component `json:"component,omitempty"` ComponentId int64 `db:"componentversion_component_id"` ComponentInstances []ComponentInstance `json:"component_instances,omitempty"` Issues []Issue `json:"issues,omitempty"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } diff --git a/internal/entity/evidence.go b/internal/entity/evidence.go index a4e0a0e0..ae6becf5 100644 --- a/internal/entity/evidence.go +++ b/internal/entity/evidence.go @@ -42,6 +42,7 @@ var AllEvidenceTypeValues = []string{ } type Evidence struct { + Metadata Id int64 `json:"id"` Description string `json:"description"` Type EvidenceType `json:"type"` @@ -51,9 +52,6 @@ type Evidence struct { UserId int64 `db:"evidence_author_id"` Activity *Activity `json:"activity,omitempty"` ActivityId int64 `db:"evidence_activity_id"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } type EvidenceFilter struct { @@ -63,7 +61,8 @@ type EvidenceFilter struct { IssueMatchId []*int64 `json:"issue_match_id"` UserId []*int64 `json:"user_id"` } -type EvidenceAggregations struct{} +type EvidenceAggregations struct { +} type EvidenceResult struct { WithCursor diff --git a/internal/entity/issue.go b/internal/entity/issue.go index 95ecb1ef..44e52129 100644 --- a/internal/entity/issue.go +++ b/internal/entity/issue.go @@ -76,6 +76,7 @@ type IssueAggregations struct { } type Issue struct { + Metadata Id int64 `json:"id"` Type IssueType `json:"type"` PrimaryName string `json:"primary_name"` @@ -84,9 +85,6 @@ type Issue struct { IssueMatches []IssueMatch `json:"issue_matches,omitempty"` ComponentVersions []ComponentVersion `json:"component_versions,omitempty"` Activity []Activity `json:"activity,omitempty"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_lsat"` } type IssueCount struct { diff --git a/internal/entity/issue_match.go b/internal/entity/issue_match.go index fbd0ea7e..8e020893 100644 --- a/internal/entity/issue_match.go +++ b/internal/entity/issue_match.go @@ -39,6 +39,7 @@ var AllIssueMatchStatusValues = []string{ } type IssueMatch struct { + Metadata Id int64 `json:"id"` Status IssueMatchStatusValue `json:"status"` User *User `json:"user,omitempty"` @@ -51,9 +52,6 @@ type IssueMatch struct { IssueId int64 `json:"issue_id"` RemediationDate time.Time `json:"remediation_date"` TargetRemediationDate time.Time `json:"target_remediation_date"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } type IssueMatchFilter struct { diff --git a/internal/entity/issue_match_change.go b/internal/entity/issue_match_change.go index 416b029a..bbcd54a5 100644 --- a/internal/entity/issue_match_change.go +++ b/internal/entity/issue_match_change.go @@ -3,8 +3,6 @@ package entity -import "time" - type IssueMatchChangeAction string const ( @@ -32,15 +30,13 @@ var AllIssueMatchChangeActions = []string{ } type IssueMatchChange struct { + Metadata Id int64 `json:"id"` ActivityId int64 `json:"activity_id"` Activity *Activity IssueMatchId int64 `json:"issue_match_id"` IssueMatch *IssueMatch - Action string `json:"action"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at"` - UpdatedAt time.Time `json:"updated_at"` + Action string `json:"action"` } type IssueMatchChangeFilter struct { diff --git a/internal/entity/issue_repository.go b/internal/entity/issue_repository.go index 75013371..4456a549 100644 --- a/internal/entity/issue_repository.go +++ b/internal/entity/issue_repository.go @@ -3,17 +3,13 @@ package entity -import "time" - type BaseIssueRepository struct { + Metadata Id int64 `json:"id"` Name string `json:"name"` Url string `json:"url"` IssueVariants []IssueVariant `json:"issue_variants,omitempty"` Services []Service `json:"services,omitempty"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } type IssueRepositoryFilter struct { diff --git a/internal/entity/issue_repository_service.go b/internal/entity/issue_repository_service.go index fddbc449..5005b841 100644 --- a/internal/entity/issue_repository_service.go +++ b/internal/entity/issue_repository_service.go @@ -3,13 +3,9 @@ package entity -import "time" - type IssueRepositoryService struct { - ServiceId int64 `json:"service_id"` - IssueRepositoryId int64 `json:"issue_repository_id"` - Priority int64 `json:"priority"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + ServiceId int64 `json:"service_id"` + IssueRepositoryId int64 `json:"issue_repository_id"` + Priority int64 `json:"priority"` } diff --git a/internal/entity/issue_variant.go b/internal/entity/issue_variant.go index 2c4f5b25..3b891740 100644 --- a/internal/entity/issue_variant.go +++ b/internal/entity/issue_variant.go @@ -3,9 +3,8 @@ package entity -import "time" - type IssueVariant struct { + Metadata Id int64 `json:"id"` IssueRepositoryId int64 `json:"issue_repository_id"` IssueRepository *IssueRepository `json:"issue_repository"` @@ -14,9 +13,6 @@ type IssueVariant struct { Issue *Issue `json:"issue"` Severity Severity `json:"severity"` Description string `json:"description"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } type IssueVariantFilter struct { diff --git a/internal/entity/service.go b/internal/entity/service.go index bd034086..2c96629e 100644 --- a/internal/entity/service.go +++ b/internal/entity/service.go @@ -3,9 +3,8 @@ package entity -import "time" - type BaseService struct { + Metadata Id int64 `json:"id"` CCRN string `json:"ccrn"` SupportGroup *SupportGroup `json:"support_group,omitempty"` @@ -13,9 +12,6 @@ type BaseService struct { Owners []User `json:"owners,omitempty"` Activities []Activity `json:"activities,omitempty"` Priority int64 `json:"priority"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` } type ServiceAggregations struct { diff --git a/internal/entity/support_group.go b/internal/entity/support_group.go index 75259174..f9d48b6b 100644 --- a/internal/entity/support_group.go +++ b/internal/entity/support_group.go @@ -3,14 +3,10 @@ package entity -import "time" - type SupportGroup struct { - Id int64 `json:"id"` - CCRN string `json:"ccrn"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + Id int64 `json:"id"` + CCRN string `json:"ccrn"` } type SupportGroupFilter struct { diff --git a/internal/entity/support_group_service.go b/internal/entity/support_group_service.go index 1e0e42c4..b098a564 100644 --- a/internal/entity/support_group_service.go +++ b/internal/entity/support_group_service.go @@ -3,12 +3,8 @@ package entity -import "time" - type SupportGroupService struct { - SupportGroupId int64 `json:"support_group_id"` - ServiceId int64 `json:"service_id"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + SupportGroupId int64 `json:"support_group_id"` + ServiceId int64 `json:"service_id"` } diff --git a/internal/entity/support_group_user.go b/internal/entity/support_group_user.go index e35ad945..d811acff 100644 --- a/internal/entity/support_group_user.go +++ b/internal/entity/support_group_user.go @@ -3,12 +3,8 @@ package entity -import "time" - type SupportGroupUser struct { - SupportGroupId int64 `json:"support_group_id"` - UserId int64 `json:"user_id"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + SupportGroupId int64 `json:"support_group_id"` + UserId int64 `json:"user_id"` } diff --git a/internal/entity/test/activity.go b/internal/entity/test/activity.go index a182335b..da70be19 100644 --- a/internal/entity/test/activity.go +++ b/internal/entity/test/activity.go @@ -15,9 +15,11 @@ func NewFakeActivityEntity() entity.Activity { Issues: nil, Evidences: nil, Service: nil, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/component.go b/internal/entity/test/component.go index 867fae84..425c2d3a 100644 --- a/internal/entity/test/component.go +++ b/internal/entity/test/component.go @@ -10,12 +10,14 @@ import ( func NewFakeComponentEntity() entity.Component { return entity.Component{ - Id: int64(gofakeit.Number(1, 10000000)), - CCRN: gofakeit.Name(), - Type: gofakeit.Word(), - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Id: int64(gofakeit.Number(1, 10000000)), + CCRN: gofakeit.Name(), + Type: gofakeit.Word(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/component_instance.go b/internal/entity/test/component_instance.go index 217f25cc..d34fc3c4 100644 --- a/internal/entity/test/component_instance.go +++ b/internal/entity/test/component_instance.go @@ -17,9 +17,11 @@ func NewFakeComponentInstanceEntity() entity.ComponentInstance { ComponentVersionId: int64(gofakeit.Number(1, 10000000)), Service: nil, ServiceId: int64(gofakeit.Number(1, 10000000)), - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/component_version.go b/internal/entity/test/component_version.go index a44b32a3..07fff6d2 100644 --- a/internal/entity/test/component_version.go +++ b/internal/entity/test/component_version.go @@ -15,9 +15,11 @@ func NewFakeComponentVersionEntity() entity.ComponentVersion { ComponentId: 0, ComponentInstances: nil, Issues: nil, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/evidence.go b/internal/entity/test/evidence.go index d0c561b8..ea837675 100644 --- a/internal/entity/test/evidence.go +++ b/internal/entity/test/evidence.go @@ -19,9 +19,11 @@ func NewFakeEvidenceEntity() entity.Evidence { RaaEnd: gofakeit.Date(), Type: entity.NewEvidenceTypeValue(t), Severity: severity, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/issue.go b/internal/entity/test/issue.go index d233e39a..927f4487 100644 --- a/internal/entity/test/issue.go +++ b/internal/entity/test/issue.go @@ -22,9 +22,11 @@ func NewFakeIssueEntity() entity.Issue { IssueMatches: nil, ComponentVersions: nil, Activity: nil, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/issue_match.go b/internal/entity/test/issue_match.go index e0b839d0..45ecfc62 100644 --- a/internal/entity/test/issue_match.go +++ b/internal/entity/test/issue_match.go @@ -25,9 +25,11 @@ func NewFakeIssueMatch() entity.IssueMatch { Issue: nil, RemediationDate: gofakeit.Date(), TargetRemediationDate: gofakeit.Date(), - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/issue_match_change.go b/internal/entity/test/issue_match_change.go index ea11442a..b706a086 100644 --- a/internal/entity/test/issue_match_change.go +++ b/internal/entity/test/issue_match_change.go @@ -15,9 +15,11 @@ func NewFakeIssueMatchChange() entity.IssueMatchChange { Action: gofakeit.RandomString(actions), IssueMatch: nil, Activity: nil, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/issue_repository.go b/internal/entity/test/issue_repository.go index f61af12b..f0c6ecf4 100644 --- a/internal/entity/test/issue_repository.go +++ b/internal/entity/test/issue_repository.go @@ -11,12 +11,14 @@ import ( func NewFakeIssueRepositoryEntity() entity.IssueRepository { return entity.IssueRepository{ BaseIssueRepository: entity.BaseIssueRepository{ - Id: int64(gofakeit.Number(1, 10000000)), - Name: gofakeit.Noun(), - Url: gofakeit.URL(), - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Id: int64(gofakeit.Number(1, 10000000)), + Name: gofakeit.Noun(), + Url: gofakeit.URL(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, }, IssueRepositoryService: entity.IssueRepositoryService{ Priority: int64(gofakeit.Number(1, 10)), diff --git a/internal/entity/test/issue_variant.go b/internal/entity/test/issue_variant.go index 72437b67..7724da6d 100644 --- a/internal/entity/test/issue_variant.go +++ b/internal/entity/test/issue_variant.go @@ -29,9 +29,11 @@ func NewFakeIssueVariantEntity(issue *int64) entity.IssueVariant { Issue: nil, IssueRepositoryId: 0, IssueRepository: nil, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/service.go b/internal/entity/test/service.go index 50cb5fae..1c8be266 100644 --- a/internal/entity/test/service.go +++ b/internal/entity/test/service.go @@ -16,9 +16,11 @@ func NewFakeServiceEntity() entity.Service { SupportGroup: nil, Activities: nil, Owners: nil, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, }, } } diff --git a/internal/entity/test/support_group.go b/internal/entity/test/support_group.go index 17719720..ac6bcd52 100644 --- a/internal/entity/test/support_group.go +++ b/internal/entity/test/support_group.go @@ -10,11 +10,13 @@ import ( func NewFakeSupportGroupEntity() entity.SupportGroup { return entity.SupportGroup{ - Id: int64(gofakeit.Number(1, 10000000)), - CCRN: gofakeit.AppName(), - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Id: int64(gofakeit.Number(1, 10000000)), + CCRN: gofakeit.AppName(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/test/user.go b/internal/entity/test/user.go index c06d95af..0cf39c0e 100644 --- a/internal/entity/test/user.go +++ b/internal/entity/test/user.go @@ -17,9 +17,11 @@ func NewFakeUserEntity() entity.User { Name: gofakeit.Name(), UniqueUserID: uniqueUserId, Type: entity.HumanUserType, - CreatedAt: gofakeit.Date(), - DeletedAt: gofakeit.Date(), - UpdatedAt: gofakeit.Date(), + Metadata: entity.Metadata{ + CreatedAt: gofakeit.Date(), + DeletedAt: gofakeit.Date(), + UpdatedAt: gofakeit.Date(), + }, } } diff --git a/internal/entity/user.go b/internal/entity/user.go index 324a7782..4f373bcd 100644 --- a/internal/entity/user.go +++ b/internal/entity/user.go @@ -3,8 +3,6 @@ package entity -import "time" - type UserType int const ( @@ -14,13 +12,11 @@ const ( ) type User struct { - Id int64 `json:"id"` - Name string `json:"name"` - UniqueUserID string `json:"uniqueUserId"` - Type UserType `json:"type"` - CreatedAt time.Time `json:"created_at"` - DeletedAt time.Time `json:"deleted_at,omitempty"` - UpdatedAt time.Time `json:"updated_at"` + Metadata + Id int64 `json:"id"` + Name string `json:"name"` + UniqueUserID string `json:"uniqueUserId"` + Type UserType `json:"type"` } type UserFilter struct {