From 80c52b84eac582cfa1df93d4f049357c55ce1d6a Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Tue, 26 Sep 2023 14:45:12 -0700 Subject: [PATCH 1/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 74 ++++++++++++++++++++++++++++++- migration/pkg.go | 2 + migration/v10/model/analysis.go | 77 +++++++++++++++++++++++++++++++++ model/pkg.go | 3 +- 4 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 migration/v10/model/analysis.go diff --git a/api/analysis.go b/api/analysis.go index 7abd79e99..9f77831d9 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -228,12 +228,17 @@ func (h AnalysisHandler) AppCreate(ctx *gin.Context) { _ = ctx.Error(result.Error) return } + err := h.archive(ctx) + if err != nil { + _ = ctx.Error(err) + return + } analysis := &model.Analysis{} analysis.ApplicationID = id analysis.CreateUser = h.BaseHandler.CurrentUser(ctx) db := h.DB(ctx) db.Logger = db.Logger.LogMode(logger.Error) - err := db.Create(analysis).Error + err = db.Create(analysis).Error if err != nil { _ = ctx.Error(err) return @@ -1728,6 +1733,61 @@ func (h *AnalysisHandler) depIDs(ctx *gin.Context, f qf.Filter) (q *gorm.DB) { return } +// +// archive +// - Set the 'archived' field with archived issues. +// - Delete issues. +// - Delete dependencies. +func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { + appId := h.pk(ctx) + var unarchived []model.Analysis + db := h.DB(ctx) + db = db.Where("ApplicationID", appId) + db = db.Where("Archived IS NULL") + err = db.Find(&unarchived).Error + if err != nil { + return + } + for _, m := range unarchived { + db := h.DB(ctx) + db = db.Select( + "i.RuleSet", + "i.Rule", + "i.Name", + "i.Description", + "COUNT(n.ID)") + db = db.Table("Issue i,") + db = db.Joins("Incident n") + db = db.Where("n.IssueID = i.ID") + db = db.Where("i.AnalysisID", m.ID) + db = db.Group("i.ID") + archived := []ArchivedIssue{} + err = db.Scan(&archived).Error + if err != nil { + return + } + m.Archived, _ = json.Marshal(archived) + err = db.Update("Archived", archived).Error + if err != nil { + return + } + db = h.DB(ctx) + db = db.Model(&model.Issue{}) + err = db.Delete("AnalysisID", m.ID).Error + if err != nil { + return + } + db = h.DB(ctx) + db = db.Model(&model.TechDependency{}) + err = db.Delete("AnalysisID", m.ID).Error + if err != nil { + return + } + } + + return +} + // // Analysis REST resource. type Analysis struct { @@ -1932,6 +1992,18 @@ type Link struct { Title string `json:"title,omitempty" yaml:",omitempty"` } +// +// ArchivedIssue created when issues are archived. +type ArchivedIssue model.ArchivedIssue + +// +// ArchivedAnalysis resource created when issues are archived. +type ArchivedAnalysis struct { + Resource `yaml:",inline"` + Effort int `json:"effort"` + Issues []ArchivedIssue +} + // // RuleReport REST resource. type RuleReport struct { diff --git a/migration/pkg.go b/migration/pkg.go index c82490c0e..bf242d6e7 100644 --- a/migration/pkg.go +++ b/migration/pkg.go @@ -2,6 +2,7 @@ package migration import ( "github.com/jortel/go-utils/logr" + v10 "github.com/konveyor/tackle2-hub/migration/v10" "github.com/konveyor/tackle2-hub/migration/v2" v3 "github.com/konveyor/tackle2-hub/migration/v3" v4 "github.com/konveyor/tackle2-hub/migration/v4" @@ -51,5 +52,6 @@ func All() []Migration { v7.Migration{}, v8.Migration{}, v9.Migration{}, + v10.Migration{}, } } diff --git a/migration/v10/model/analysis.go b/migration/v10/model/analysis.go new file mode 100644 index 000000000..6941d128f --- /dev/null +++ b/migration/v10/model/analysis.go @@ -0,0 +1,77 @@ +package model + +// +// Analysis report. +type Analysis struct { + Model + Effort int + Archived JSON `gorm:"type:json"` + Issues []Issue `gorm:"constraint:OnDelete:CASCADE"` + Dependencies []TechDependency `gorm:"constraint:OnDelete:CASCADE"` + ApplicationID uint `gorm:"index;not null"` + Application *Application +} + +// +// TechDependency report dependency. +type TechDependency struct { + Model + Provider string `gorm:"uniqueIndex:depA"` + Name string `gorm:"uniqueIndex:depA"` + Version string `gorm:"uniqueIndex:depA"` + SHA string `gorm:"uniqueIndex:depA"` + Indirect bool + Labels JSON `gorm:"type:json"` + AnalysisID uint `gorm:"index;uniqueIndex:depA;not null"` + Analysis *Analysis +} + +// +// Issue report issue (violation). +type Issue struct { + Model + RuleSet string `gorm:"uniqueIndex:issueA;not null"` + Rule string `gorm:"uniqueIndex:issueA;not null"` + Name string `gorm:"index"` + Description string + Category string `gorm:"index;not null"` + Incidents []Incident `gorm:"foreignKey:IssueID;constraint:OnDelete:CASCADE"` + Links JSON `gorm:"type:json"` + Facts JSON `gorm:"type:json"` + Labels JSON `gorm:"type:json"` + Effort int `gorm:"index;not null"` + AnalysisID uint `gorm:"index;uniqueIndex:issueA;not null"` + Analysis *Analysis +} + +// +// Incident report an issue incident. +type Incident struct { + Model + File string `gorm:"index;not null"` + Line int + Message string + CodeSnip string + Facts JSON `gorm:"type:json"` + IssueID uint `gorm:"index;not null"` + Issue *Issue +} + +// +// Link URL link. +type Link struct { + URL string `json:"url"` + Title string `json:"title,omitempty"` +} + +// +// ArchivedAIssue resource created when issues are archived. +type ArchivedAIssue struct { + RuleSet string `json:"ruleSet"` + Rule string `json:"rule"` + Name string `json:"name,omitempty" yaml:",omitempty"` + Description string `json:"description,omitempty" yaml:",omitempty"` + Category string `json:"category"` + Effort int `json:"effort"` + Incidents int `json:"incidents"` +} diff --git a/model/pkg.go b/model/pkg.go index 60361f4fb..9e6a2e148 100644 --- a/model/pkg.go +++ b/model/pkg.go @@ -1,7 +1,7 @@ package model import ( - "github.com/konveyor/tackle2-hub/migration/v9/model" + "github.com/konveyor/tackle2-hub/migration/v10/model" "gorm.io/datatypes" ) @@ -18,6 +18,7 @@ type Assessment = model.Assessment type TechDependency = model.TechDependency type Incident = model.Incident type Analysis = model.Analysis +type ArchivedIssue = model.ArchivedAIssue type Issue = model.Issue type Bucket = model.Bucket type BucketOwner = model.BucketOwner From b5621dfc77b2ba68c05c21211041016f0a80db36 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Tue, 26 Sep 2023 15:00:57 -0700 Subject: [PATCH 2/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/api/analysis.go b/api/analysis.go index 9f77831d9..6fd875fb8 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -1755,7 +1755,9 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { "i.Rule", "i.Name", "i.Description", - "COUNT(n.ID)") + "i.Category", + "i.Effort", + "COUNT(n.ID) Incidents") db = db.Table("Issue i,") db = db.Joins("Incident n") db = db.Where("n.IssueID = i.ID") @@ -1766,8 +1768,10 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { if err != nil { return } - m.Archived, _ = json.Marshal(archived) - err = db.Update("Archived", archived).Error + db = h.DB(ctx) + db = db.Model(m) + b, _ := json.Marshal(archived) + err = db.Update("Archived", &b).Error if err != nil { return } From f1260f8872547446eb75784762cbf31c6fceb5d5 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Tue, 26 Sep 2023 15:26:15 -0700 Subject: [PATCH 3/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/analysis.go b/api/analysis.go index 6fd875fb8..5899ff8ad 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -1770,20 +1770,20 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { } db = h.DB(ctx) db = db.Model(m) - b, _ := json.Marshal(archived) - err = db.Update("Archived", &b).Error + m.Archived, _ = json.Marshal(archived) + err = db.Update("Archived", &m.Archived).Error if err != nil { return } db = h.DB(ctx) - db = db.Model(&model.Issue{}) - err = db.Delete("AnalysisID", m.ID).Error + db = db.Where("AnalysisID", m.ID) + err = db.Delete(&model.Issue{}).Error if err != nil { return } db = h.DB(ctx) - db = db.Model(&model.TechDependency{}) - err = db.Delete("AnalysisID", m.ID).Error + db = db.Where("AnalysisID", m.ID) + err = db.Delete(&model.TechDependency{}).Error if err != nil { return } From 7dcfe767f03833eb601ce2e5abef297b8275ee0f Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Tue, 26 Sep 2023 15:27:39 -0700 Subject: [PATCH 4/9] checkpoint Signed-off-by: Jeff Ortel --- migration/v10/migrate.go | 20 +++++++++ migration/v10/model/pkg.go | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 migration/v10/migrate.go create mode 100644 migration/v10/model/pkg.go diff --git a/migration/v10/migrate.go b/migration/v10/migrate.go new file mode 100644 index 000000000..14dbc8a3f --- /dev/null +++ b/migration/v10/migrate.go @@ -0,0 +1,20 @@ +package v10 + +import ( + "github.com/jortel/go-utils/logr" + "github.com/konveyor/tackle2-hub/migration/v10/model" + "gorm.io/gorm" +) + +var log = logr.WithName("migration|v9") + +type Migration struct{} + +func (r Migration) Apply(db *gorm.DB) (err error) { + err = db.AutoMigrate(r.Models()...) + return +} + +func (r Migration) Models() []interface{} { + return model.All() +} diff --git a/migration/v10/model/pkg.go b/migration/v10/model/pkg.go new file mode 100644 index 000000000..4d66fc80b --- /dev/null +++ b/migration/v10/model/pkg.go @@ -0,0 +1,87 @@ +package model + +import "github.com/konveyor/tackle2-hub/migration/v9/model" + +// +// JSON field (data) type. +type JSON = []byte + +type Model = model.Model +type Application = model.Application +type Archetype = model.Archetype +type Assessment = model.Assessment +type Bucket = model.Bucket +type BucketOwner = model.BucketOwner +type BusinessService = model.BusinessService +type Dependency = model.Dependency +type File = model.File +type Fact = model.Fact +type Identity = model.Identity +type Import = model.Import +type ImportSummary = model.ImportSummary +type ImportTag = model.ImportTag +type JobFunction = model.JobFunction +type MigrationWave = model.MigrationWave +type Proxy = model.Proxy +type Questionnaire = model.Questionnaire +type Review = model.Review +type Setting = model.Setting +type RuleSet = model.RuleSet +type Rule = model.Rule +type Stakeholder = model.Stakeholder +type StakeholderGroup = model.StakeholderGroup +type Tag = model.Tag +type TagCategory = model.TagCategory +type Target = model.Target +type Task = model.Task +type TaskGroup = model.TaskGroup +type TaskReport = model.TaskReport +type Ticket = model.Ticket +type Tracker = model.Tracker +type TTL = model.TTL +type ApplicationTag = model.ApplicationTag +type DependencyCyclicError = model.DependencyCyclicError + +// +// All builds all models. +// Models are enumerated such that each are listed after +// all the other models on which they may depend. +func All() []interface{} { + return []interface{}{ + Application{}, + TechDependency{}, + Incident{}, + Analysis{}, + Issue{}, + Bucket{}, + BusinessService{}, + Dependency{}, + File{}, + Fact{}, + Identity{}, + Import{}, + ImportSummary{}, + ImportTag{}, + JobFunction{}, + MigrationWave{}, + Proxy{}, + Review{}, + Setting{}, + RuleSet{}, + Rule{}, + Stakeholder{}, + StakeholderGroup{}, + Tag{}, + TagCategory{}, + Target{}, + Task{}, + TaskGroup{}, + TaskReport{}, + Ticket{}, + Tracker{}, + ApplicationTag{}, + Questionnaire{}, + Assessment{}, + Archetype{}, + } +} From 139ab4a966e405b59ac33010dbfb49b07c387eff Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Tue, 26 Sep 2023 15:51:53 -0700 Subject: [PATCH 5/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/api/analysis.go b/api/analysis.go index 5899ff8ad..7e09b67f9 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -1799,6 +1799,7 @@ type Analysis struct { Effort int `json:"effort"` Issues []Issue `json:"issues,omitempty" yaml:",omitempty"` Dependencies []TechDependency `json:"dependencies,omitempty" yaml:",omitempty"` + Archived []ArchivedIssue `json:"archived,omitempty" yaml:",omitempty"` } // @@ -1822,6 +1823,9 @@ func (r *Analysis) With(m *model.Analysis) { r.Dependencies, n) } + if m.Archived != nil { + _ = json.Unmarshal(m.Archived, &r.Archived) + } } // @@ -2000,14 +2004,6 @@ type Link struct { // ArchivedIssue created when issues are archived. type ArchivedIssue model.ArchivedIssue -// -// ArchivedAnalysis resource created when issues are archived. -type ArchivedAnalysis struct { - Resource `yaml:",inline"` - Effort int `json:"effort"` - Issues []ArchivedIssue -} - // // RuleReport REST resource. type RuleReport struct { From 0ac974b3d947234b176339654f6e4ca20b79d6d8 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Wed, 27 Sep 2023 07:39:58 -0700 Subject: [PATCH 6/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 18 ++++++++++-------- migration/v10/model/analysis.go | 3 ++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/api/analysis.go b/api/analysis.go index 7e09b67f9..edcbb0039 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -1743,7 +1743,7 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { var unarchived []model.Analysis db := h.DB(ctx) db = db.Where("ApplicationID", appId) - db = db.Where("Archived IS NULL") + db = db.Where("Archived", false) err = db.Find(&unarchived).Error if err != nil { return @@ -1763,15 +1763,16 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { db = db.Where("n.IssueID = i.ID") db = db.Where("i.AnalysisID", m.ID) db = db.Group("i.ID") - archived := []ArchivedIssue{} - err = db.Scan(&archived).Error + summary := []ArchivedIssue{} + err = db.Scan(&summary).Error if err != nil { return } db = h.DB(ctx) db = db.Model(m) - m.Archived, _ = json.Marshal(archived) - err = db.Update("Archived", &m.Archived).Error + m.Archived = true + m.Summary, _ = json.Marshal(summary) + err = db.Save(&m).Error if err != nil { return } @@ -1797,9 +1798,10 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { type Analysis struct { Resource `yaml:",inline"` Effort int `json:"effort"` + Archived bool `json:"archived,omitempty" yaml:",omitempty"` Issues []Issue `json:"issues,omitempty" yaml:",omitempty"` Dependencies []TechDependency `json:"dependencies,omitempty" yaml:",omitempty"` - Archived []ArchivedIssue `json:"archived,omitempty" yaml:",omitempty"` + Summary []ArchivedIssue `json:"summary,omitempty" yaml:",omitempty"` } // @@ -1823,8 +1825,8 @@ func (r *Analysis) With(m *model.Analysis) { r.Dependencies, n) } - if m.Archived != nil { - _ = json.Unmarshal(m.Archived, &r.Archived) + if m.Summary != nil { + _ = json.Unmarshal(m.Summary, &r.Summary) } } diff --git a/migration/v10/model/analysis.go b/migration/v10/model/analysis.go index 6941d128f..29d05168e 100644 --- a/migration/v10/model/analysis.go +++ b/migration/v10/model/analysis.go @@ -5,7 +5,8 @@ package model type Analysis struct { Model Effort int - Archived JSON `gorm:"type:json"` + Archived bool `json:"archived"` + Summary JSON `gorm:"type:json"` Issues []Issue `gorm:"constraint:OnDelete:CASCADE"` Dependencies []TechDependency `gorm:"constraint:OnDelete:CASCADE"` ApplicationID uint `gorm:"index;not null"` From 4e15fcd1765f241f9c9d1d104c6c33cf348fd0ac Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Wed, 27 Sep 2023 08:03:39 -0700 Subject: [PATCH 7/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/analysis.go b/api/analysis.go index edcbb0039..3fae184d7 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -1770,9 +1770,10 @@ func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) { } db = h.DB(ctx) db = db.Model(m) + db = db.Omit(clause.Associations) m.Archived = true m.Summary, _ = json.Marshal(summary) - err = db.Save(&m).Error + err = db.Updates(h.fields(&m)).Error if err != nil { return } @@ -1809,6 +1810,7 @@ type Analysis struct { func (r *Analysis) With(m *model.Analysis) { r.Resource.With(&m.Model) r.Effort = m.Effort + r.Archived = m.Archived r.Issues = []Issue{} for i := range m.Issues { n := Issue{} From 72f4be89dc6813cdb6c4c5f1ef21362029c797df Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Wed, 27 Sep 2023 09:45:36 -0700 Subject: [PATCH 8/9] checkpoint Signed-off-by: Jeff Ortel --- migration/v10/model/analysis.go | 4 ++-- model/pkg.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/migration/v10/model/analysis.go b/migration/v10/model/analysis.go index 29d05168e..baa7781df 100644 --- a/migration/v10/model/analysis.go +++ b/migration/v10/model/analysis.go @@ -66,8 +66,8 @@ type Link struct { } // -// ArchivedAIssue resource created when issues are archived. -type ArchivedAIssue struct { +// ArchivedIssue resource created when issues are archived. +type ArchivedIssue struct { RuleSet string `json:"ruleSet"` Rule string `json:"rule"` Name string `json:"name,omitempty" yaml:",omitempty"` diff --git a/model/pkg.go b/model/pkg.go index 9e6a2e148..3277bf076 100644 --- a/model/pkg.go +++ b/model/pkg.go @@ -18,7 +18,7 @@ type Assessment = model.Assessment type TechDependency = model.TechDependency type Incident = model.Incident type Analysis = model.Analysis -type ArchivedIssue = model.ArchivedAIssue +type ArchivedIssue = model.ArchivedIssue type Issue = model.Issue type Bucket = model.Bucket type BucketOwner = model.BucketOwner From aedbfbea7e6b8f3b8258cc6bf96cffa2476cd53c Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Wed, 27 Sep 2023 11:11:50 -0700 Subject: [PATCH 9/9] checkpoint Signed-off-by: Jeff Ortel --- api/analysis.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/analysis.go b/api/analysis.go index 3fae184d7..251fafefb 100644 --- a/api/analysis.go +++ b/api/analysis.go @@ -1735,7 +1735,8 @@ func (h *AnalysisHandler) depIDs(ctx *gin.Context, f qf.Filter) (q *gorm.DB) { // // archive -// - Set the 'archived' field with archived issues. +// - Set the 'archived' flag. +// - Set the 'summary' field with archived issues. // - Delete issues. // - Delete dependencies. func (h *AnalysisHandler) archive(ctx *gin.Context) (err error) {