From 14693ad32be6785452eda049a3ba3a1a6b8dfbe7 Mon Sep 17 00:00:00 2001 From: Jan Eitzinger Date: Thu, 10 Feb 2022 18:48:58 +0100 Subject: [PATCH] Add Tag view including required changes. --- repository/job.go | 37 +++++++++++++++ repository/job_test.go | 78 +++++++++++++++++++++++++++++++ server.go | 23 ++++++++- templates/base.tmpl | 8 ++++ templates/monitoring/taglist.tmpl | 17 +++++++ templates/templates.go | 9 +++- 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 repository/job_test.go create mode 100644 templates/monitoring/taglist.tmpl diff --git a/repository/job.go b/repository/job.go index 881b5e5..8c70827 100644 --- a/repository/job.go +++ b/repository/job.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "errors" + "fmt" "strconv" "github.com/ClusterCockpit/cc-backend/auth" @@ -123,6 +124,42 @@ func (r *JobRepository) CreateTag(tagType string, tagName string) (tagId int64, return res.LastInsertId() } +func (r *JobRepository) GetTags() (tags []schema.Tag, counts map[string]int, err error) { + tags = make([]schema.Tag, 0, 100) + xrows, err := r.DB.Queryx("SELECT * FROM tag") + for xrows.Next() { + var t schema.Tag + err = xrows.StructScan(&t) + tags = append(tags, t) + } + + q := sq.Select("t.tag_name, count(jt.tag_id)"). + From("tag t"). + LeftJoin("jobtag jt ON t.id = jt.tag_id"). + GroupBy("t.tag_name") + + qs, _, err := q.ToSql() + rows, err := r.DB.Query(qs) + if err != nil { + fmt.Println(err) + } + + counts = make(map[string]int) + + for rows.Next() { + var tagName string + var count int + err = rows.Scan(&tagName, &count) + if err != nil { + fmt.Println(err) + } + counts[tagName] = count + } + err = rows.Err() + + return +} + // AddTagOrCreate adds the tag with the specified type and name to the job with the database id `jobId`. // If such a tag does not yet exist, it is created. func (r *JobRepository) AddTagOrCreate(jobId int64, tagType string, tagName string) (tagId int64, err error) { diff --git a/repository/job_test.go b/repository/job_test.go new file mode 100644 index 0000000..e0114f9 --- /dev/null +++ b/repository/job_test.go @@ -0,0 +1,78 @@ +package repository + +import ( + "fmt" + "testing" + + "github.com/jmoiron/sqlx" + + _ "github.com/go-sql-driver/mysql" + _ "github.com/mattn/go-sqlite3" +) + +var db *sqlx.DB + +func init() { + var err error + + if db != nil { + panic("prefer using sub-tests (`t.Run`) or implement `cleanup` before calling setup twice.") + } + db, err = sqlx.Open("sqlite3", "../var/test.db") + if err != nil { + fmt.Println(err) + } +} + +func setup(t *testing.T) *JobRepository { + return &JobRepository{ + DB: db, + } +} + +func TestFind(t *testing.T) { + r := setup(t) + + job, err := r.Find(1001789, "emmy", 1540853248) + if err != nil { + t.Fatal(err) + } + + // fmt.Printf("%+v", job) + + if job.ID != 1245 { + t.Errorf("wrong summary for diagnostic 3\ngot: %d \nwant: 1245", job.JobID) + } +} + +func TestFindById(t *testing.T) { + r := setup(t) + + job, err := r.FindById(1245) + if err != nil { + t.Fatal(err) + } + + // fmt.Printf("%+v", job) + + if job.JobID != 1001789 { + t.Errorf("wrong summary for diagnostic 3\ngot: %d \nwant: 1001789", job.JobID) + } +} + +func TestGetTags(t *testing.T) { + r := setup(t) + + tags, _, err := r.GetTags() + if err != nil { + t.Fatal(err) + } + + fmt.Printf("TAGS %+v \n", tags) + // fmt.Printf("COUNTS %+v \n", counts) + t.Errorf("wrong summary for diagnostic 3\ngot: %d \nwant: 23", 28) + + // if counts["load-imbalance"] != 23 { + // t.Errorf("wrong summary for diagnostic 3\ngot: %d \nwant: 23", counts["load-imbalance"]) + // } +} diff --git a/server.go b/server.go index 1427bba..b062313 100644 --- a/server.go +++ b/server.go @@ -38,6 +38,7 @@ import ( ) var db *sqlx.DB +var jobRepo *repository.JobRepository // Format of the configurartion (file). See below for the defaults. type ProgramConfig struct { @@ -162,11 +163,29 @@ func setupAnalysisRoute(i InfoType, r *http.Request) InfoType { return i } +func setupTaglistRoute(i InfoType, r *http.Request) InfoType { + tags, counts, _ := jobRepo.GetTags() + tagMap := make(map[string][]map[string]interface{}) + + for _, tag := range tags { + tagItem := map[string]interface{}{ + "id": tag.ID, + "name": tag.Name, + "count": counts[tag.Name], + } + tagMap[tag.Type] = append(tagMap[tag.Type], tagItem) + } + log.Infof("TAGS %+v", tags) + i["tagmap"] = tagMap + return i +} + var routes []Route = []Route{ {"/monitoring/jobs/", "monitoring/jobs.tmpl", "Jobs - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { return i }}, {"/monitoring/job/{id:[0-9]+}", "monitoring/job.tmpl", "Job - ClusterCockpit", false, setupJobRoute}, {"/monitoring/users/", "monitoring/list.tmpl", "Users - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { i["listType"] = "USER"; return i }}, {"/monitoring/projects/", "monitoring/list.tmpl", "Projects - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { i["listType"] = "PROJECT"; return i }}, + {"/monitoring/tags/", "monitoring/taglist.tmpl", "Tags - ClusterCockpit", false, setupTaglistRoute}, {"/monitoring/user/{id}", "monitoring/user.tmpl", "User - ClusterCockpit", true, setupUserRoute}, {"/monitoring/systems/{cluster}", "monitoring/systems.tmpl", "Cluster - ClusterCockpit", false, setupClusterRoute}, {"/monitoring/node/{cluster}/{hostname}", "monitoring/node.tmpl", "Node - ClusterCockpit", false, setupNodeRoute}, @@ -307,9 +326,11 @@ func main() { }) } + jobRepo = &repository.JobRepository{DB: db} + graphQLPlayground := playground.Handler("GraphQL playground", "/query") api := &api.RestApi{ - JobRepository: &repository.JobRepository{DB: db}, + JobRepository: jobRepo, AsyncArchiving: programConfig.AsyncArchiving, Resolver: resolver, MachineStateDir: programConfig.MachineStateDir, diff --git a/templates/base.tmpl b/templates/base.tmpl index b244a1f..dd9d5fd 100644 --- a/templates/base.tmpl +++ b/templates/base.tmpl @@ -58,6 +58,14 @@ {{end}} + {{block "navitem_tags" .}} + + {{end}} {{else}} {{block "navitem_stats" .}}