Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 frontend implements GAE web server for luci-cron service. | 5 // Package frontend implements GAE web server for luci-cron service. |
| 6 // | 6 // |
| 7 // Due to the way classic GAE imports work, this package can not have | 7 // Due to the way classic GAE imports work, this package can not have |
| 8 // subpackages (or at least subpackages referenced via absolute import path). | 8 // subpackages (or at least subpackages referenced via absolute import path). |
| 9 // We can't use relative imports because luci-go will then become unbuildable | 9 // We can't use relative imports because luci-go will then become unbuildable |
| 10 // by regular (non GAE) toolset. | 10 // by regular (non GAE) toolset. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 "time" | 25 "time" |
| 26 | 26 |
| 27 "github.com/julienschmidt/httprouter" | 27 "github.com/julienschmidt/httprouter" |
| 28 "golang.org/x/net/context" | 28 "golang.org/x/net/context" |
| 29 "google.golang.org/appengine" | 29 "google.golang.org/appengine" |
| 30 | 30 |
| 31 "github.com/luci/gae/service/info" | 31 "github.com/luci/gae/service/info" |
| 32 "github.com/luci/gae/service/taskqueue" | 32 "github.com/luci/gae/service/taskqueue" |
| 33 | 33 |
| 34 "github.com/luci/luci-go/server/auth" | 34 "github.com/luci/luci-go/server/auth" |
| 35 » "github.com/luci/luci-go/server/middleware" | 35 » "github.com/luci/luci-go/server/router" |
| 36 | 36 |
| 37 "github.com/luci/luci-go/appengine/gaeauth/server" | 37 "github.com/luci/luci-go/appengine/gaeauth/server" |
| 38 "github.com/luci/luci-go/appengine/gaeconfig" | 38 "github.com/luci/luci-go/appengine/gaeconfig" |
| 39 "github.com/luci/luci-go/appengine/gaemiddleware" | 39 "github.com/luci/luci-go/appengine/gaemiddleware" |
| 40 | 40 |
| 41 "github.com/luci/luci-go/common/config" | 41 "github.com/luci/luci-go/common/config" |
| 42 "github.com/luci/luci-go/common/config/impl/memory" | 42 "github.com/luci/luci-go/common/config/impl/memory" |
| 43 "github.com/luci/luci-go/common/errors" | 43 "github.com/luci/luci-go/common/errors" |
| 44 "github.com/luci/luci-go/common/logging" | 44 "github.com/luci/luci-go/common/logging" |
| 45 | 45 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 // getConfigImpl returns config.Interface implementation to use from the | 125 // getConfigImpl returns config.Interface implementation to use from the |
| 126 // catalog. | 126 // catalog. |
| 127 func getConfigImpl(c context.Context) (config.Interface, error) { | 127 func getConfigImpl(c context.Context) (config.Interface, error) { |
| 128 // Use fake config data on dev server for simplicity. | 128 // Use fake config data on dev server for simplicity. |
| 129 if info.Get(c).IsDevAppServer() { | 129 if info.Get(c).IsDevAppServer() { |
| 130 return memory.New(devServerConfigs()), nil | 130 return memory.New(devServerConfigs()), nil |
| 131 } | 131 } |
| 132 return gaeconfig.New(c) | 132 return gaeconfig.New(c) |
| 133 } | 133 } |
| 134 | 134 |
| 135 // wrap converts the handler to format accepted by middleware lib. It also adds | 135 // wrap converts the handler to handler format accepted by router lib. |
| 136 // context initialization code. | 136 func wrap(h handler) router.Handler { |
| 137 func wrap(h handler) middleware.Handler { | 137 » return func(c *router.Context) { |
| 138 » return func(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { | 138 » » h(&requestContext{c.Context, c.Writer, c.Request, c.Params}) |
|
iannucci
2016/06/13 19:23:28
hm... at this point, can't we just use router.Hand
| |
| 139 » » h(&requestContext{c, w, r, p}) | |
| 140 } | 139 } |
| 141 } | 140 } |
| 142 | 141 |
| 143 // base starts middleware chain. It initializes prod context and sets up | 142 // base starts middleware chain. It initializes prod context and sets up |
| 144 // authentication config. | 143 // authentication config. |
| 145 func base(h middleware.Handler) httprouter.Handle { | 144 func base() []router.Handler { |
| 146 methods := auth.Authenticator{ | 145 methods := auth.Authenticator{ |
| 147 &server.OAuth2Method{Scopes: []string{server.EmailScope}}, | 146 &server.OAuth2Method{Scopes: []string{server.EmailScope}}, |
| 148 server.CookieAuth, | 147 server.CookieAuth, |
| 149 &server.InboundAppIDAuthMethod{}, | 148 &server.InboundAppIDAuthMethod{}, |
| 150 } | 149 } |
| 151 » wrapper := func(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) { | 150 » return append( |
| 152 » » globalInit.Do(func() { initializeGlobalState(c) }) | 151 » » gaemiddleware.BaseProd(), |
| 153 » » c = auth.SetAuthenticator(c, methods) | 152 » » func(c *router.Context) { |
| 154 » » h(c, w, r, p) | 153 » » » globalInit.Do(func() { initializeGlobalState(c.Context) }) |
| 155 » } | 154 » » » c.Context = auth.SetAuthenticator(c.Context, methods) |
| 156 » return gaemiddleware.BaseProd(wrapper) | 155 » » }, |
| 156 » ) | |
| 157 } | 157 } |
| 158 | 158 |
| 159 // cronHandler returns handler intended for cron jobs. | 159 // cronHandler returns handler intended for cron jobs. |
| 160 func cronHandler(h handler) httprouter.Handle { | 160 func cronHandler(h handler) []router.Handler { |
| 161 » return base(gaemiddleware.RequireCron(wrap(h))) | 161 » return append( |
| 162 » » base(), | |
| 163 » » gaemiddleware.RequireCron(), | |
| 164 » » wrap(h), | |
| 165 » ) | |
| 162 } | 166 } |
| 163 | 167 |
| 164 // taskQueueHandler returns handler intended for task queue calls. | 168 // taskQueueHandler returns handler intended for task queue calls. |
| 165 func taskQueueHandler(name string, h handler) httprouter.Handle { | 169 func taskQueueHandler(name string, h handler) []router.Handler { |
| 166 » return base(gaemiddleware.RequireTaskQueue(name, wrap(h))) | 170 » return append( |
| 171 » » base(), | |
| 172 » » gaemiddleware.RequireTaskQueue(name), | |
| 173 » » wrap(h), | |
| 174 » ) | |
| 167 } | 175 } |
| 168 | 176 |
| 169 //// Routes. | 177 //// Routes. |
| 170 | 178 |
| 171 func init() { | 179 func init() { |
| 172 // Dev server likes to restart a lot, and upon a restart math/rand seed is | 180 // Dev server likes to restart a lot, and upon a restart math/rand seed is |
| 173 // always set to 1, resulting in lots of presumably "random" IDs not bei ng | 181 // always set to 1, resulting in lots of presumably "random" IDs not bei ng |
| 174 // very random. Seed it with real randomness. | 182 // very random. Seed it with real randomness. |
| 175 var seed int64 | 183 var seed int64 |
| 176 if err := binary.Read(cryptorand.Reader, binary.LittleEndian, &seed); er r != nil { | 184 if err := binary.Read(cryptorand.Reader, binary.LittleEndian, &seed); er r != nil { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 188 globalEngine = engine.NewEngine(engine.Config{ | 196 globalEngine = engine.NewEngine(engine.Config{ |
| 189 Catalog: globalCatalog, | 197 Catalog: globalCatalog, |
| 190 TimersQueuePath: "/internal/tasks/timers", | 198 TimersQueuePath: "/internal/tasks/timers", |
| 191 TimersQueueName: "timers", | 199 TimersQueueName: "timers", |
| 192 InvocationsQueuePath: "/internal/tasks/invocations", | 200 InvocationsQueuePath: "/internal/tasks/invocations", |
| 193 InvocationsQueueName: "invocations", | 201 InvocationsQueueName: "invocations", |
| 194 PubSubPushPath: "/pubsub", | 202 PubSubPushPath: "/pubsub", |
| 195 }) | 203 }) |
| 196 | 204 |
| 197 // Setup HTTP routes. | 205 // Setup HTTP routes. |
| 198 » router := httprouter.New() | 206 » router := router.New() |
| 199 | 207 |
| 200 » gaemiddleware.InstallHandlers(router, base) | 208 » gaemiddleware.InstallHandlers(router, base()) |
| 201 » ui.InstallHandlers(router, base, ui.Config{ | 209 » ui.InstallHandlers(router, base(), ui.Config{ |
| 202 Engine: globalEngine, | 210 Engine: globalEngine, |
| 203 TemplatesPath: "templates", | 211 TemplatesPath: "templates", |
| 204 }) | 212 }) |
| 205 | 213 |
| 206 » router.GET("/_ah/warmup", base(wrap(warmupHandler))) | 214 » router.GET("/_ah/warmup", append(base(), wrap(warmupHandler))...) |
|
iannucci
2016/06/13 19:23:28
er... can't this be
router.GET("/_ah/warmup", b
| |
| 207 » router.GET("/_ah/start", base(wrap(warmupHandler))) | 215 » router.GET("/_ah/start", append(base(), wrap(warmupHandler))...) |
| 208 » router.POST("/pubsub", base(wrap(pubsubPushHandler))) | 216 » router.POST("/pubsub", append(base(), wrap(pubsubPushHandler))...) |
| 209 » router.GET("/internal/cron/read-config", cronHandler(readConfigCron)) | 217 » router.GET("/internal/cron/read-config", cronHandler(readConfigCron)...) |
| 210 » router.POST("/internal/tasks/read-project-config", taskQueueHandler("rea d-project-config", readProjectConfigTask)) | 218 » router.POST("/internal/tasks/read-project-config", taskQueueHandler("rea d-project-config", readProjectConfigTask)...) |
| 211 » router.POST("/internal/tasks/timers", taskQueueHandler("timers", actionT ask)) | 219 » router.POST("/internal/tasks/timers", taskQueueHandler("timers", actionT ask)...) |
| 212 » router.POST("/internal/tasks/invocations", taskQueueHandler("invocations ", actionTask)) | 220 » router.POST("/internal/tasks/invocations", taskQueueHandler("invocations ", actionTask)...) |
| 213 | 221 |
| 214 // Devserver can't accept PubSub pushes, so allow manual pulls instead t o | 222 // Devserver can't accept PubSub pushes, so allow manual pulls instead t o |
| 215 // simplify local development. | 223 // simplify local development. |
| 216 if appengine.IsDevAppServer() { | 224 if appengine.IsDevAppServer() { |
| 217 » » router.GET("/pubsub/pull/:ManagerName/:Publisher", base(wrap(pub subPullHandler))) | 225 » » router.GET("/pubsub/pull/:ManagerName/:Publisher", append(base() , wrap(pubsubPullHandler))...) |
| 218 } | 226 } |
| 219 | 227 |
| 220 http.DefaultServeMux.Handle("/", router) | 228 http.DefaultServeMux.Handle("/", router) |
| 221 } | 229 } |
| 222 | 230 |
| 223 // warmupHandler warms in-memory caches. | 231 // warmupHandler warms in-memory caches. |
| 224 func warmupHandler(rc *requestContext) { | 232 func warmupHandler(rc *requestContext) { |
| 225 if err := server.Warmup(rc); err != nil { | 233 if err := server.Warmup(rc); err != nil { |
| 226 rc.fail(500, "Failed to warmup OpenID: %s", err) | 234 rc.fail(500, "Failed to warmup OpenID: %s", err) |
| 227 return | 235 return |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 return | 341 return |
| 334 } | 342 } |
| 335 count, _ := strconv.Atoi(c.r.Header.Get("X-AppEngine-TaskExecutionCount" )) | 343 count, _ := strconv.Atoi(c.r.Header.Get("X-AppEngine-TaskExecutionCount" )) |
| 336 err = globalEngine.ExecuteSerializedAction(c.Context, body, count) | 344 err = globalEngine.ExecuteSerializedAction(c.Context, body, count) |
| 337 if err != nil { | 345 if err != nil { |
| 338 c.err(err, "Error when executing the action") | 346 c.err(err, "Error when executing the action") |
| 339 return | 347 return |
| 340 } | 348 } |
| 341 c.ok() | 349 c.ok() |
| 342 } | 350 } |
| OLD | NEW |