// :WEBAPI: // { // "url": "{schema}://{host}/api/v1/tasks", // "method": "GET", // "description": "Returns list of tasks", // "parameters": [ // {"name": "state", "type": "string", "description": "shows tasks with specified state", "default": "NaN"}, // {"name": "owner", "type": "string", "description": "shows tasks with specified owner", "default": "NaN"}, // {"name": "limit", "type": "number", "description": "shows only specified number of retults", "default": "1000"} // ] // } func TaskListHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) { p, ok := ctx.Value("http.request.query.params").(*url.Values) if !ok { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to obtain params from context") return } q := db.QueryDoc{} if p.Get("owner") != "" { q["owner"] = p.Get("owner") } if p.Get("repo") != "" { q["repo"] = p.Get("repo") } if p.Get("state") != "" { q["state"] = p.Get("state") } apiSearch(ctx, w, r, []Query{ Query{ CollName: task.CollName, Sort: []string{"taskid"}, Pattern: q, Iterator: func(iter db.Iter) interface{} { t := task.New() if !iter.Next(t) { return nil } return t }, }, }) }
// :WEBAPI: // { // "url": "{schema}://{host}/api/v1/search", // "method": "GET", // "parameters": [ // {"name": "prefix", "type": "string", "description": "filter objects by prefix", "default": "NaN"}, // {"name": "limit", "type": "number", "description": "shows only specified number of retults", "default": "1000"} // ], // "description": "Returns list of tasks and subtasks" // } func SearchHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) { p, ok := ctx.Value("http.request.query.params").(*url.Values) if !ok { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to obtain params from context") return } apiSearch(ctx, w, r, []Query{ Query{ CollName: task.CollName, Pattern: db.QueryDoc{"search.key": db.QueryDoc{"$regex": "^" + p.Get("prefix")}}, Sort: []string{"-taskid"}, Iterator: func(iter db.Iter) interface{} { t := task.New() if !iter.Next(t) { return nil } return t }, }, Query{ CollName: subtask.CollName, Pattern: db.QueryDoc{"search.key": db.QueryDoc{"$regex": "^" + p.Get("prefix")}}, Sort: []string{"-taskid"}, Iterator: func(iter db.Iter) interface{} { t := subtask.New() if !iter.Next(t) { return nil } return t }, }, }) }
// :WEBAPI: // { // "url": "{schema}://{host}/api/v1/tasks", // "method": "POST", // "description": "Creates new task" // } func TaskCreateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) { cfg, ok := ctx.Value("app.config").(*config.Config) if !ok { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to obtain config from context") return } msg, err := ioutil.ReadAll(r.Body) if err != nil { ahttp.HTTPResponse(w, http.StatusBadRequest, "Unable to read body: %s", err) return } logger.GetHTTPEntry(ctx).WithFields(nil).Infof("TaskCreateHandler: Request body: %s", string(msg)) ev := task.NewTaskEvent() if err = json.Unmarshal(msg, ev); err != nil { ahttp.HTTPResponse(w, http.StatusBadRequest, "Invalid JSON: %s", err) return } t := task.New() fillTask(t, ev) t.TimeCreate.Set(time.Now().Unix()) logger.GetHTTPEntry(ctx).WithFields(nil).Infof("TaskCreateHandler: Task: %+v", t) if v, ok := t.Repo.Get(); ok { if !util.InSliceString(v, cfg.Builder.Repos) { ahttp.HTTPResponse(w, http.StatusBadRequest, "Unknown repo") return } } else { ahttp.HTTPResponse(w, http.StatusBadRequest, "repo: mandatory field is not specified") return } if !t.Owner.IsDefined() { ahttp.HTTPResponse(w, http.StatusBadRequest, "owner: mandatory field is not specified") return } if !writeTask(ctx, w, t) { return } ahttp.HTTPResponse(w, http.StatusOK, "OK") }
// :WEBAPI: // { // "url": "{schema}://{host}/api/v1/tasks/{taskid}", // "method": "GET", // "arguments": [ // {"name": "taskid", "type": "integer", "description": "task number"} // ], // "description": "Returns information about specified task" // } func TaskGetHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) { p, ok := ctx.Value("http.request.query.params").(*url.Values) if !ok { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to obtain params from context") return } apiGet(ctx, w, r, Query{ CollName: task.CollName, Pattern: task.MakeID(util.ToInt64(p.Get("task"))), One: func(query db.Query) (interface{}, error) { t := task.New() err := query.One(t) return t, err }, }) }
func StatisticQueueHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) { st, ok := ctx.Value("app.database").(db.Session) if !ok { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to obtain database from context") return } cfg, ok := ctx.Value("app.config").(*config.Config) if !ok { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to obtain config from context") return } ans := make(map[string]map[string]int64) for _, repo := range cfg.Builder.Repos { ans[repo] = make(map[string]int64) for _, state := range taskStates { ans[repo][state] = 0 } } q := db.QueryDoc{ "state": db.QueryDoc{"$in": []string{"new", "awaiting", "postponed", "building", "pending", "committing"}}, } col, err := st.Coll(task.CollName) if err != nil { ahttp.HTTPResponse(w, http.StatusInternalServerError, "%v", err) return } iter := col.Find(q).Iter() for { if !ahttp.IsAlive(w) { return } t := task.New() if !iter.Next(t) { break } state, ok := t.State.Get() if !ok { continue } repo, ok := t.Repo.Get() if !ok { continue } ans[repo][state] += int64(1) } if err := iter.Close(); err != nil { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Error iterating: %+v", err) return } msg, err := json.Marshal(ans) if err != nil { ahttp.HTTPResponse(w, http.StatusInternalServerError, "Unable to marshal json: %v", err) return } w.Write([]byte(`{"result":`)) w.Write(msg) w.Write([]byte(`}`)) }