// getTask finds a json document by using thex task that is in the plugin. func getTaskByName(w http.ResponseWriter, r *http.Request) { t := plugin.GetTask(r) if t == nil { http.Error(w, "task not found", http.StatusNotFound) return } name := mux.Vars(r)["name"] taskName := mux.Vars(r)["task_name"] var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{VersionIdKey: t.Version, BuildIdKey: t.BuildId, NameKey: name, TaskNameKey: taskName}), &jsonForTask) if err != nil { if err == mgo.ErrNotFound { plugin.WriteJSON(w, http.StatusNotFound, nil) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(r.FormValue("full")) != 0 { // if specified, include the json data's container as well plugin.WriteJSON(w, http.StatusOK, jsonForTask) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask.Data) }
// getTasksForLatestVersion sends back the TaskJSON data associated with the latest version. func getTasksForLatestVersion(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] var jsonTask TaskJSON projects := []string{} err := util.ReadJSONInto(r.Body, &projects) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } versionData := []VersionData{} for _, project := range projects { err := db.FindOneQ(collection, db.Query(bson.M{NameKey: name, ProjectIdKey: project}).Sort([]string{"-" + RevisionOrderNumberKey}).WithFields(VersionIdKey), &jsonTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } if jsonTask.VersionId == "" { http.Error(w, "{}", http.StatusNotFound) } jsonTasks, err := findTasksForVersion(jsonTask.VersionId, name) if jsonTasks == nil { http.Error(w, "{}", http.StatusNotFound) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // get the version commit info v, err := version.FindOne(version.ById(jsonTask.VersionId)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if v == nil { http.Error(w, "{}", http.StatusNotFound) return } commitInfo := CommitInfo{ Author: v.Author, Message: v.Message, CreateTime: v.CreateTime, Revision: v.Revision, VersionId: jsonTask.VersionId, } versionData = append(versionData, VersionData{jsonTasks, commitInfo}) } plugin.WriteJSON(w, http.StatusOK, versionData) }
func fixPatchInHistory(taskId string, base *task.Task, history []TaskJSON) ([]TaskJSON, error) { var jsonForTask *TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{"task_id": taskId}), &jsonForTask) if err != nil { return nil, err } if base != nil { jsonForTask.RevisionOrderNumber = base.RevisionOrderNumber } if jsonForTask == nil { return history, nil } found := false for i, item := range history { if item.Revision == base.Revision { history[i] = *jsonForTask found = true } } // if found is false, it means we don't have json on the base commit, so it was // not replaced and we must add it explicitly if !found { history = append(history, *jsonForTask) } return history, nil }
// FindOne gets one Host for the given query. func FindOne(query db.Q) (*Host, error) { host := &Host{} err := db.FindOneQ(Collection, query, host) if err == mgo.ErrNotFound { return nil, nil } return host, err }
// FindOne returns one build that satisfies the query. func FindOne(query db.Q) (*Build, error) { build := &Build{} err := db.FindOneQ(Collection, query, build) if err == mgo.ErrNotFound { return nil, nil } return build, err }
// FindOne runs a patch query, returning one patch. func FindOne(query db.Q) (*Patch, error) { patch := &Patch{} err := db.FindOneQ(Collection, query, patch) if err == mgo.ErrNotFound { return nil, nil } return patch, err }
// FindOneOld returns one task from the old tasks collection that satisfies the query. func FindOneOld(query db.Q) (*Task, error) { task := &Task{} err := db.FindOneQ(OldCollection, query, task) if err == mgo.ErrNotFound { return nil, nil } return task, err }
// FindOne ets one Entry for the given query func FindOne(query db.Q) (*Entry, error) { entry := &Entry{} err := db.FindOneQ(Collection, query, entry) if err == mgo.ErrNotFound { return nil, nil } return entry, err }
// FindOne gets one DBUser for the given query. func FindOne(query db.Q) (*DBUser, error) { u := &DBUser{} err := db.FindOneQ(Collection, query, u) if err == mgo.ErrNotFound { return nil, nil } return u, err }
// FindOne gets one AlertRecord for the given query. func FindOne(query db.Q) (*AlertRecord, error) { alertRec := &AlertRecord{} err := db.FindOneQ(Collection, query, alertRec) if err == mgo.ErrNotFound { return nil, nil } return alertRec, err }
// FindOne gets one Manifest for the given query. func FindOne(query db.Q) (*Manifest, error) { m := &Manifest{} err := db.FindOneQ(Collection, query, m) if err == mgo.ErrNotFound { return nil, nil } return m, err }
func FindOne(query db.Q) (*Version, error) { version := &Version{} err := db.FindOneQ(Collection, query, version) if err == mgo.ErrNotFound { return nil, nil } return version, err }
// NoteForTask returns the note for the given task Id, if it exists. func NoteForTask(taskId string) (*Note, error) { n := &Note{} err := db.FindOneQ( NotesCollection, db.Query(bson.D{{TaskIdKey, taskId}}), n, ) if err == mgo.ErrNotFound { return nil, nil } return n, err }
// getTaskById sends back a JSONTask with the corresponding task id. func getTaskById(w http.ResponseWriter, r *http.Request) { var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{TaskIdKey: mux.Vars(r)["task_id"], NameKey: mux.Vars(r)["name"]}), &jsonForTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask) }
// getTaskForVariant finds a task by name and variant and finds // the document in the json collection associated with that task's id. func getTaskForVariant(w http.ResponseWriter, r *http.Request) { t := plugin.GetTask(r) if t == nil { http.Error(w, "task not found", http.StatusNotFound) return } name := mux.Vars(r)["name"] taskName := mux.Vars(r)["task_name"] variantId := mux.Vars(r)["variant"] // Find the task for the other variant, if it exists ts, err := task.Find(db.Query(bson.M{task.VersionKey: t.Version, task.BuildVariantKey: variantId, task.DisplayNameKey: taskName}).Limit(1)) if err != nil { if err == mgo.ErrNotFound { plugin.WriteJSON(w, http.StatusNotFound, nil) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(ts) == 0 { plugin.WriteJSON(w, http.StatusNotFound, nil) return } otherVariantTask := ts[0] var jsonForTask TaskJSON err = db.FindOneQ(collection, db.Query(bson.M{TaskIdKey: otherVariantTask.Id, NameKey: name}), &jsonForTask) if err != nil { if err == mgo.ErrNotFound { plugin.WriteJSON(w, http.StatusNotFound, nil) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(r.FormValue("full")) != 0 { // if specified, include the json data's container as well plugin.WriteJSON(w, http.StatusOK, jsonForTask) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask.Data) }
// getTaskJSONByTag finds a TaskJSON by a tag func getTaskJSONByTag(w http.ResponseWriter, r *http.Request) { var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{"project_id": mux.Vars(r)["project_id"], TagKey: mux.Vars(r)["tag"], VariantKey: mux.Vars(r)["variant"], TaskNameKey: mux.Vars(r)["task_name"], NameKey: mux.Vars(r)["name"], }), &jsonForTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } if len(r.FormValue("full")) != 0 { // if specified, include the json data's container as well plugin.WriteJSON(w, http.StatusOK, jsonForTask) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask) }
func getCommit(w http.ResponseWriter, r *http.Request) { var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{ProjectIdKey: mux.Vars(r)["project_id"], RevisionKey: bson.RegEx{"^" + regexp.QuoteMeta(mux.Vars(r)["revision"]), "i"}, VariantKey: mux.Vars(r)["variant"], TaskNameKey: mux.Vars(r)["task_name"], NameKey: mux.Vars(r)["name"], IsPatchKey: false, }), &jsonForTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } if len(r.FormValue("full")) != 0 { // if specified, include the json data's container as well plugin.WriteJSON(w, http.StatusOK, jsonForTask) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask) }
// FindOne gets one Distro for the given query. func FindOne(query db.Q) (*Distro, error) { d := &Distro{} return d, db.FindOneQ(Collection, query, d) }
func (hwp *JSONPlugin) GetUIHandler() http.Handler { r := mux.NewRouter() r.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { plugin.WriteJSON(w, http.StatusOK, "1") }) r.HandleFunc("/task/{task_id}/{name}/", func(w http.ResponseWriter, r *http.Request) { var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{"task_id": mux.Vars(r)["task_id"], "name": mux.Vars(r)["name"]}), &jsonForTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask) }) r.HandleFunc("/task/{task_id}/{name}/tags", func(w http.ResponseWriter, r *http.Request) { t, err := model.FindTask(mux.Vars(r)["task_id"]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } tags := []struct { Tag string `bson:"_id" json:"tag"` }{} err = db.Aggregate(collection, []bson.M{ {"$match": bson.M{"project_id": t.Project, "tag": bson.M{"$exists": true, "$ne": ""}}}, {"$project": bson.M{"tag": 1}}, bson.M{"$group": bson.M{"_id": "$tag"}}, }, &tags) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, tags) }) r.HandleFunc("/task/{task_id}/{name}/tag", func(w http.ResponseWriter, r *http.Request) { t, err := model.FindTask(mux.Vars(r)["task_id"]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if t == nil { http.Error(w, "{}", http.StatusNotFound) return } if r.Method == "DELETE" { if _, err = db.UpdateAll(collection, bson.M{"version_id": t.Version, "name": mux.Vars(r)["name"]}, bson.M{"$unset": bson.M{"tag": 1}}); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, "") } inTag := struct { Tag string `json:"tag"` }{} err = util.ReadJSONInto(r.Body, &inTag) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(inTag.Tag) == 0 { http.Error(w, "tag must not be blank", http.StatusBadRequest) return } _, err = db.UpdateAll(collection, bson.M{"version_id": t.Version, "name": mux.Vars(r)["name"]}, bson.M{"$set": bson.M{"tag": inTag.Tag}}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, "") }) r.HandleFunc("/tag/{project_id}/{tag}/{variant}/{task_name}/{name}", func(w http.ResponseWriter, r *http.Request) { var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{"project_id": mux.Vars(r)["project_id"], "tag": mux.Vars(r)["tag"], "variant": mux.Vars(r)["variant"], "task_name": mux.Vars(r)["task_name"], "name": mux.Vars(r)["name"], }), &jsonForTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask) }) r.HandleFunc("/commit/{project_id}/{revision}/{variant}/{task_name}/{name}", func(w http.ResponseWriter, r *http.Request) { var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{"project_id": mux.Vars(r)["project_id"], "revision": bson.RegEx{"^" + regexp.QuoteMeta(mux.Vars(r)["revision"]), "i"}, "variant": mux.Vars(r)["variant"], "task_name": mux.Vars(r)["task_name"], "name": mux.Vars(r)["name"], "is_patch": false, }), &jsonForTask) if err != nil { if err != mgo.ErrNotFound { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Error(w, "{}", http.StatusNotFound) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask) }) r.HandleFunc("/history/{task_id}/{name}", func(w http.ResponseWriter, r *http.Request) { t, err := model.FindTask(mux.Vars(r)["task_id"]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if t == nil { http.Error(w, "{}", http.StatusNotFound) return } before := []TaskJSON{} jsonQuery := db.Query(bson.M{ "project_id": t.Project, "variant": t.BuildVariant, "order": bson.M{"$lte": t.RevisionOrderNumber}, "task_name": t.DisplayName, "is_patch": false, "name": mux.Vars(r)["name"]}) jsonQuery = jsonQuery.Sort([]string{"-order"}).Limit(100) err = db.FindAllQ(collection, jsonQuery, &before) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } //reverse order of "before" because we had to sort it backwards to apply the limit correctly: for i, j := 0, len(before)-1; i < j; i, j = i+1, j-1 { before[i], before[j] = before[j], before[i] } after := []TaskJSON{} jsonAfterQuery := db.Query(bson.M{ "project_id": t.Project, "variant": t.BuildVariant, "order": bson.M{"$gt": t.RevisionOrderNumber}, "task_name": t.DisplayName, "is_patch": false, "name": mux.Vars(r)["name"]}).Sort([]string{"order"}).Limit(100) err = db.FindAllQ(collection, jsonAfterQuery, &after) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } //concatenate before + after before = append(before, after...) plugin.WriteJSON(w, http.StatusOK, before) }) return r }
// GetRoutes returns an API route for serving patch data. func (jsp *JSONPlugin) GetAPIHandler() http.Handler { r := mux.NewRouter() r.HandleFunc("/tags/{task_name}/{name}", func(w http.ResponseWriter, r *http.Request) { t := plugin.GetTask(r) if t == nil { http.Error(w, "task not found", http.StatusNotFound) return } tagged := []TaskJSON{} jsonQuery := db.Query(bson.M{ "project_id": t.Project, "variant": t.BuildVariant, "task_name": mux.Vars(r)["task_name"], "tag": bson.M{"$exists": true, "$ne": ""}, "name": mux.Vars(r)["name"]}) err := db.FindAllQ(collection, jsonQuery, &tagged) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, tagged) }) r.HandleFunc("/history/{task_name}/{name}", func(w http.ResponseWriter, r *http.Request) { t := plugin.GetTask(r) if t == nil { http.Error(w, "task not found", http.StatusNotFound) return } before := []TaskJSON{} jsonQuery := db.Query(bson.M{ "project_id": t.Project, "variant": t.BuildVariant, "order": bson.M{"$lte": t.RevisionOrderNumber}, "task_name": mux.Vars(r)["task_name"], "is_patch": false, "name": mux.Vars(r)["name"]}).Sort([]string{"-order"}).Limit(100) err := db.FindAllQ(collection, jsonQuery, &before) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } //reverse order of "before" because we had to sort it backwards to apply the limit correctly: for i, j := 0, len(before)-1; i < j; i, j = i+1, j-1 { before[i], before[j] = before[j], before[i] } after := []TaskJSON{} jsonAfterQuery := db.Query(bson.M{ "project_id": t.Project, "variant": t.BuildVariant, "order": bson.M{"$gt": t.RevisionOrderNumber}, "task_name": mux.Vars(r)["task_name"], "is_patch": false, "name": mux.Vars(r)["name"]}).Sort([]string{"order"}).Limit(100) err = db.FindAllQ(collection, jsonAfterQuery, &after) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } //concatenate before + after before = append(before, after...) plugin.WriteJSON(w, http.StatusOK, before) }) r.HandleFunc("/data/{name}", func(w http.ResponseWriter, r *http.Request) { task := plugin.GetTask(r) if task == nil { http.Error(w, "task not found", http.StatusNotFound) return } name := mux.Vars(r)["name"] rawData := map[string]interface{}{} err := util.ReadJSONInto(r.Body, &rawData) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } jsonBlob := TaskJSON{ TaskId: task.Id, TaskName: task.DisplayName, Name: name, BuildId: task.BuildId, Variant: task.BuildVariant, ProjectId: task.Project, VersionId: task.Version, Revision: task.Revision, RevisionOrderNumber: task.RevisionOrderNumber, Data: rawData, IsPatch: task.Requester == evergreen.PatchVersionRequester, } _, err = db.Upsert(collection, bson.M{"task_id": task.Id, "name": name}, jsonBlob) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, "ok") return }) r.HandleFunc("/data/{task_name}/{name}", func(w http.ResponseWriter, r *http.Request) { task := plugin.GetTask(r) if task == nil { http.Error(w, "task not found", http.StatusNotFound) return } name := mux.Vars(r)["name"] taskName := mux.Vars(r)["task_name"] var jsonForTask TaskJSON err := db.FindOneQ(collection, db.Query(bson.M{"version_id": task.Version, "build_id": task.BuildId, "name": name, "task_name": taskName}), &jsonForTask) if err != nil { if err == mgo.ErrNotFound { plugin.WriteJSON(w, http.StatusNotFound, nil) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask.Data) }) r.HandleFunc("/data/{task_name}/{name}/{variant}", func(w http.ResponseWriter, r *http.Request) { task := plugin.GetTask(r) if task == nil { http.Error(w, "task not found", http.StatusNotFound) return } name := mux.Vars(r)["name"] taskName := mux.Vars(r)["task_name"] variantId := mux.Vars(r)["variant"] // Find the task for the other variant, if it exists ts, err := model.FindTasks(db.Query(bson.M{model.TaskVersionKey: task.Version, model.TaskBuildVariantKey: variantId, model.TaskDisplayNameKey: taskName}).Limit(1)) if err != nil { if err == mgo.ErrNotFound { plugin.WriteJSON(w, http.StatusNotFound, nil) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(ts) == 0 { plugin.WriteJSON(w, http.StatusNotFound, nil) return } otherVariantTask := ts[0] var jsonForTask TaskJSON err = db.FindOneQ(collection, db.Query(bson.M{"task_id": otherVariantTask.Id, "name": name}), &jsonForTask) if err != nil { if err == mgo.ErrNotFound { plugin.WriteJSON(w, http.StatusNotFound, nil) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } plugin.WriteJSON(w, http.StatusOK, jsonForTask.Data) }) return r }