// GET: /job/{id} func (cr *JobController) Read(id string, cx *goweb.Context) { LogRequest(cx.Request) // Try to authenticate user. u, err := request.Authenticate(cx.Request) if err != nil && err.Error() != e.NoAuth { cx.RespondWithErrorMessage(err.Error(), http.StatusUnauthorized) return } // If no auth was provided, and anonymous read is allowed, use the public user if u == nil { if conf.ANON_READ == true { u = &user.User{Uuid: "public"} } else { cx.RespondWithErrorMessage(e.NoAuth, http.StatusUnauthorized) return } } // Load job by id job, err := core.LoadJob(id) if err != nil { cx.RespondWithErrorMessage("job not found:"+id, http.StatusBadRequest) return } // User must have read permissions on job or be job owner or be an admin rights := job.Acl.Check(u.Uuid) prights := job.Acl.Check("public") if job.Acl.Owner != u.Uuid && rights["read"] == false && u.Admin == false && prights["read"] == false { cx.RespondWithErrorMessage(e.UnAuth, http.StatusUnauthorized) return } // Gather query params query := &Query{Li: cx.Request.URL.Query()} if query.Has("perf") { //Load job perf by id perf, err := core.LoadJobPerf(id) if err != nil { if err == mgo.ErrNotFound { cx.RespondWithNotFound() } else { // In theory the db connection could be lost between // checking user and load but seems unlikely. logger.Error("Err@LoadJobPerf: " + id + ":" + err.Error()) cx.RespondWithErrorMessage("job perf stats not found:"+id, http.StatusBadRequest) } return } cx.RespondWithData(perf) return //done with returning perf, no need to load job further. } if query.Has("position") { if job.State != "queued" && job.State != "in-progress" { cx.RespondWithErrorMessage("job is not queued or in-progress, job state:"+job.State, http.StatusBadRequest) return } // Retrieve the job's approximate position in the queue (this is a rough estimate since jobs are not actually in a queue) q := bson.M{} qState := bson.M{} // query job state qPriority := bson.M{} // query job priority qCgroup := bson.M{} // query job clietgroup qState["$or"] = []bson.M{bson.M{"state": core.JOB_STAT_INIT}, bson.M{"state": core.JOB_STAT_QUEUED}, bson.M{"state": core.JOB_STAT_INPROGRESS}} qPriority["$or"] = []bson.M{bson.M{"info.priority": bson.M{"$gt": job.Info.Priority}}, bson.M{"$and": []bson.M{bson.M{"info.priority": job.Info.Priority}, bson.M{"info.submittime": bson.M{"$lt": job.Info.SubmitTime}}}}} var cgroups []bson.M for _, value := range strings.Split(job.Info.ClientGroups, ",") { cgroups = append(cgroups, bson.M{"info.clientgroups": bson.M{"$regex": value}}) } qCgroup["$or"] = cgroups q["$and"] = []bson.M{qState, qPriority, qCgroup} if count, err := core.GetJobCount(q); err != nil { cx.RespondWithErrorMessage("error retrieving job position in queue", http.StatusInternalServerError) } else { m := make(map[string]int) m["position"] = count + 1 cx.RespondWithData(m) } return } if core.QMgr.IsJobRegistered(id) { job.Registered = true } else { job.Registered = false } if query.Has("export") { target := query.Value("export") if target == "" { cx.RespondWithErrorMessage("lacking stage id from which the recompute starts", http.StatusBadRequest) return } else if target == "taverna" { wfrun, err := taverna.ExportWorkflowRun(job) if err != nil { cx.RespondWithErrorMessage("failed to export job to taverna workflowrun:"+id, http.StatusBadRequest) return } cx.RespondWithData(wfrun) return } } // Base case respond with job in json cx.RespondWithData(job) return }
// GET: /job/{id} func (cr *JobController) Read(id string, cx *goweb.Context) { LogRequest(cx.Request) // Try to authenticate user. u, err := request.Authenticate(cx.Request) if err != nil && err.Error() != e.NoAuth { cx.RespondWithErrorMessage(err.Error(), http.StatusUnauthorized) return } // If no auth was provided, and anonymous read is allowed, use the public user if u == nil { if conf.ANON_READ == true { u = &user.User{Uuid: "public"} } else { cx.RespondWithErrorMessage(e.NoAuth, http.StatusUnauthorized) return } } // Load job by id job, err := core.LoadJob(id) if err != nil { if err == mgo.ErrNotFound { cx.RespondWithNotFound() } else { // In theory the db connection could be lost between // checking user and load but seems unlikely. // logger.Error("Err@job_Read:LoadJob: " + id + ":" + err.Error()) cx.RespondWithErrorMessage("job not found:"+id, http.StatusBadRequest) } return } // User must have read permissions on job or be job owner or be an admin rights := job.Acl.Check(u.Uuid) if job.Acl.Owner != u.Uuid && rights["read"] == false && u.Admin == false { cx.RespondWithErrorMessage(e.UnAuth, http.StatusUnauthorized) return } // Gather query params query := &Query{Li: cx.Request.URL.Query()} if query.Has("perf") { //Load job perf by id perf, err := core.LoadJobPerf(id) if err != nil { if err == mgo.ErrNotFound { cx.RespondWithNotFound() } else { // In theory the db connection could be lost between // checking user and load but seems unlikely. logger.Error("Err@LoadJobPerf: " + id + ":" + err.Error()) cx.RespondWithErrorMessage("job perf stats not found:"+id, http.StatusBadRequest) } return } cx.RespondWithData(perf) return //done with returning perf, no need to load job further. } if core.QMgr.IsJobRegistered(id) { job.Registered = true } else { job.Registered = false } if query.Has("export") { target := query.Value("export") if target == "" { cx.RespondWithErrorMessage("lacking stage id from which the recompute starts", http.StatusBadRequest) return } else if target == "taverna" { wfrun, err := taverna.ExportWorkflowRun(job) if err != nil { cx.RespondWithErrorMessage("failed to export job to taverna workflowrun:"+id, http.StatusBadRequest) return } cx.RespondWithData(wfrun) return } } // Base case respond with job in json cx.RespondWithData(job) return }