Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: appengine/cmd/cron/ui/job.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Update tests Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package ui 5 package ui
6 6
7 import ( 7 import (
8 "crypto/sha1" 8 "crypto/sha1"
9 "encoding/base64" 9 "encoding/base64"
10 "fmt" 10 "fmt"
11 "net/http" 11 "net/http"
12 "time" 12 "time"
13 13
14 "github.com/julienschmidt/httprouter" 14 "github.com/julienschmidt/httprouter"
15 "golang.org/x/net/context" 15 "golang.org/x/net/context"
16 16
17 "github.com/luci/gae/service/memcache" 17 "github.com/luci/gae/service/memcache"
18 "github.com/luci/luci-go/common/clock" 18 "github.com/luci/luci-go/common/clock"
19 "github.com/luci/luci-go/server/auth" 19 "github.com/luci/luci-go/server/auth"
20 "github.com/luci/luci-go/server/router"
20 "github.com/luci/luci-go/server/templates" 21 "github.com/luci/luci-go/server/templates"
21 ) 22 )
22 23
23 func jobPage(c context.Context, w http.ResponseWriter, r *http.Request, p httpro uter.Params) { 24 func jobPage(ctx *router.Context) {
25 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
26
24 projectID := p.ByName("ProjectID") 27 projectID := p.ByName("ProjectID")
25 jobID := p.ByName("JobID") 28 jobID := p.ByName("JobID")
26 cursor := r.URL.Query().Get("c") 29 cursor := r.URL.Query().Get("c")
27 30
28 // Grab the job from the datastore. 31 // Grab the job from the datastore.
29 job, err := config(c).Engine.GetCronJob(c, projectID+"/"+jobID) 32 job, err := config(c).Engine.GetCronJob(c, projectID+"/"+jobID)
30 if err != nil { 33 if err != nil {
31 panic(err) 34 panic(err)
32 } 35 }
33 if job == nil { 36 if job == nil {
34 http.Error(w, "No such job", http.StatusNotFound) 37 http.Error(w, "No such job", http.StatusNotFound)
38 ctx.Abort()
35 return 39 return
36 } 40 }
37 41
38 // Grab latest invocations from the datastore. 42 // Grab latest invocations from the datastore.
39 invs, nextCursor, err := config(c).Engine.ListInvocations(c, job.JobID, 50, cursor) 43 invs, nextCursor, err := config(c).Engine.ListInvocations(c, job.JobID, 50, cursor)
40 if err != nil { 44 if err != nil {
41 panic(err) 45 panic(err)
42 } 46 }
43 47
44 // memcacheKey hashes cursor to reduce its length, since full cursor doe sn't 48 // memcacheKey hashes cursor to reduce its length, since full cursor doe sn't
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 "Job": makeCronJob(job, now), 80 "Job": makeCronJob(job, now),
77 "Invocations": convertToInvocations(job.ProjectID, job.JobID, in vs, now), 81 "Invocations": convertToInvocations(job.ProjectID, job.JobID, in vs, now),
78 "PrevCursor": prevCursor, 82 "PrevCursor": prevCursor,
79 "NextCursor": nextCursor, 83 "NextCursor": nextCursor,
80 }) 84 })
81 } 85 }
82 86
83 //////////////////////////////////////////////////////////////////////////////// 87 ////////////////////////////////////////////////////////////////////////////////
84 // Actions. 88 // Actions.
85 89
86 func runJobAction(c context.Context, w http.ResponseWriter, r *http.Request, p h ttprouter.Params) { 90 func runJobAction(ctx *router.Context) {
91 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
92
87 projectID := p.ByName("ProjectID") 93 projectID := p.ByName("ProjectID")
88 jobID := p.ByName("JobID") 94 jobID := p.ByName("JobID")
89 if !isJobOwner(c, projectID, jobID) { 95 if !isJobOwner(c, projectID, jobID) {
90 http.Error(w, "Forbidden", 403) 96 http.Error(w, "Forbidden", 403)
97 ctx.Abort()
91 return 98 return
92 } 99 }
93 100
94 // genericReply renders "we did something (or we failed to do something) " 101 // genericReply renders "we did something (or we failed to do something) "
95 // page, shown on error or if invocation is starting for too long. 102 // page, shown on error or if invocation is starting for too long.
96 genericReply := func(err error) { 103 genericReply := func(err error) {
97 templates.MustRender(c, w, "pages/run_job_result.html", map[stri ng]interface{}{ 104 templates.MustRender(c, w, "pages/run_job_result.html", map[stri ng]interface{}{
98 "ProjectID": projectID, 105 "ProjectID": projectID,
99 "JobID": jobID, 106 "JobID": jobID,
100 "Error": err, 107 "Error": err,
101 }) 108 })
102 } 109 }
103 110
104 // Enqueue new invocation request, and wait for corresponding invocation to 111 // Enqueue new invocation request, and wait for corresponding invocation to
105 // appear. Give up if task queue or datastore indexes are lagging too mu ch. 112 // appear. Give up if task queue or datastore indexes are lagging too mu ch.
106 e := config(c).Engine 113 e := config(c).Engine
107 fullJobID := projectID + "/" + jobID 114 fullJobID := projectID + "/" + jobID
108 invNonce, err := e.TriggerInvocation(c, fullJobID, auth.CurrentIdentity( c)) 115 invNonce, err := e.TriggerInvocation(c, fullJobID, auth.CurrentIdentity( c))
109 if err != nil { 116 if err != nil {
110 genericReply(err) 117 genericReply(err)
118 ctx.Abort()
111 return 119 return
112 } 120 }
113 121
114 invID := int64(0) 122 invID := int64(0)
115 deadline := clock.Now(c).Add(10 * time.Second) 123 deadline := clock.Now(c).Add(10 * time.Second)
116 for invID == 0 && deadline.Sub(clock.Now(c)) > 0 { 124 for invID == 0 && deadline.Sub(clock.Now(c)) > 0 {
117 // Asking for invocation immediately after triggering it never w orks, 125 // Asking for invocation immediately after triggering it never w orks,
118 // so sleep a bit first. 126 // so sleep a bit first.
119 if tr := clock.Sleep(c, 600*time.Millisecond); tr.Incomplete() { 127 if tr := clock.Sleep(c, 600*time.Millisecond); tr.Incomplete() {
120 // The Context was canceled before the Sleep completed. Terminate the 128 // The Context was canceled before the Sleep completed. Terminate the
(...skipping 12 matching lines...) Expand all
133 } 141 }
134 } 142 }
135 143
136 if invID != 0 { 144 if invID != 0 {
137 http.Redirect(w, r, fmt.Sprintf("/jobs/%s/%s/%d", projectID, job ID, invID), http.StatusFound) 145 http.Redirect(w, r, fmt.Sprintf("/jobs/%s/%s/%d", projectID, job ID, invID), http.StatusFound)
138 } else { 146 } else {
139 genericReply(nil) // deadline 147 genericReply(nil) // deadline
140 } 148 }
141 } 149 }
142 150
143 func pauseJobAction(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { 151 func pauseJobAction(c *router.Context) {
144 » handleJobAction(c, w, r, p, func(jobID string) error { 152 » handleJobAction(c.Context, c.Writer, c.Request, c.Params, func(jobID str ing) error {
145 » » who := auth.CurrentIdentity(c) 153 » » who := auth.CurrentIdentity(c.Context)
146 » » return config(c).Engine.PauseJob(c, jobID, who) 154 » » return config(c.Context).Engine.PauseJob(c.Context, jobID, who)
147 }) 155 })
148 } 156 }
149 157
150 func resumeJobAction(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { 158 func resumeJobAction(c *router.Context) {
151 » handleJobAction(c, w, r, p, func(jobID string) error { 159 » handleJobAction(c.Context, c.Writer, c.Request, c.Params, func(jobID str ing) error {
152 » » who := auth.CurrentIdentity(c) 160 » » who := auth.CurrentIdentity(c.Context)
153 » » return config(c).Engine.ResumeJob(c, jobID, who) 161 » » return config(c.Context).Engine.ResumeJob(c.Context, jobID, who)
154 }) 162 })
155 } 163 }
156 164
157 func handleJobAction(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params, cb func(string) error) { 165 func handleJobAction(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params, cb func(string) error) {
158 projectID := p.ByName("ProjectID") 166 projectID := p.ByName("ProjectID")
159 jobID := p.ByName("JobID") 167 jobID := p.ByName("JobID")
160 if !isJobOwner(c, projectID, jobID) { 168 if !isJobOwner(c, projectID, jobID) {
161 http.Error(w, "Forbidden", 403) 169 http.Error(w, "Forbidden", 403)
162 return 170 return
163 } 171 }
164 if err := cb(projectID + "/" + jobID); err != nil { 172 if err := cb(projectID + "/" + jobID); err != nil {
165 panic(err) 173 panic(err)
166 } 174 }
167 http.Redirect(w, r, fmt.Sprintf("/jobs/%s/%s", projectID, jobID), http.S tatusFound) 175 http.Redirect(w, r, fmt.Sprintf("/jobs/%s/%s", projectID, jobID), http.S tatusFound)
168 } 176 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698