Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 package buildbucket | |
| 2 | |
| 3 import ( | |
| 4 "encoding/json" | |
| 5 "net/http" | |
| 6 "strings" | |
| 7 | |
| 8 "golang.org/x/net/context" | |
| 9 | |
| 10 bucketApi "github.com/luci/luci-go/common/api/buildbucket/buildbucket/v1 " | |
| 11 "github.com/luci/luci-go/common/logging" | |
| 12 "github.com/luci/luci-go/common/tsmon/field" | |
| 13 "github.com/luci/luci-go/common/tsmon/metric" | |
| 14 "github.com/luci/luci-go/milo/common" | |
| 15 "github.com/luci/luci-go/server/router" | |
| 16 ) | |
| 17 | |
| 18 var ( | |
| 19 buildCounter = metric.NewCounter( | |
| 20 "luci/milo/buildbucket_pubsub/builds", | |
| 21 "The number of buildbucket builds received by Milo from PubSub", | |
| 22 nil, | |
| 23 field.String("bucket"), | |
| 24 // True for luci build, False for non-luci (ie buildbot) build. | |
| 25 field.Bool("luci"), | |
| 26 // Status can be "COMPLETED", "SCHEDULED", or "STARTED" | |
| 27 field.String("status"), | |
| 28 // Action can be one of 3 options. "New", "Replaced", "Rejected ". | |
| 29 field.String("action")) | |
| 30 ) | |
| 31 | |
| 32 type transientError error | |
|
iannucci
2017/07/08 00:05:25
use transient.Tag instead, and ditch these error t
Ryan Tseng
2017/07/08 01:47:33
Done.
| |
| 33 type permanenterror error | |
| 34 | |
| 35 func isLUCI(build *bucketApi.ApiCommonBuildMessage) bool { | |
| 36 // All luci buckets are assumed to be prefixed with luci. | |
| 37 return strings.HasPrefix(build.Bucket, "luci.") | |
|
iannucci
2017/07/08 00:05:25
this seems hard-codey? what is this for?
Ryan Tseng
2017/07/08 01:47:33
To filter out buildbot builds. the luci-migration
| |
| 38 } | |
| 39 | |
| 40 // PubSubHandler is a webhook that stores the builds coming in from pubsub. | |
| 41 func PubSubHandler(ctx *router.Context) { | |
| 42 statusCode := pubSubHandlerImpl(ctx.Context, ctx.Request) | |
| 43 ctx.Writer.WriteHeader(statusCode) | |
| 44 } | |
| 45 | |
| 46 func handlePubSubBuild(c context.Context, build *bucketApi.ApiCommonBuildMessage ) error { | |
| 47 if err := buildCounter.Add( | |
| 48 c, 1, build.Bucket, isLUCI(build), build.Status, "New"); err != nil { | |
| 49 logging.WithError(err).Warningf(c, "Failed to send metric") | |
| 50 } | |
| 51 logging.Debugf(c, "Received build %#v", build) | |
| 52 // TODO(hinoka): Save this into datastore. | |
|
iannucci
2017/07/08 00:05:25
:)
Ryan Tseng
2017/07/08 01:47:33
Sooooon™
| |
| 53 return nil | |
| 54 } | |
| 55 | |
| 56 func pubSubHandlerImpl(c context.Context, r *http.Request) int { | |
|
iannucci
2017/07/08 00:05:25
lets have this return an error and sort out the st
Ryan Tseng
2017/07/08 01:47:33
There's basically just two failure modes that need
iannucci
2017/07/08 02:08:40
I was meaning that we could just tag the error and
| |
| 57 var data struct { | |
| 58 Build bucketApi.ApiCommonBuildMessage | |
| 59 Hostname string | |
| 60 } | |
| 61 | |
| 62 msg := common.PubSubSubscription{} | |
| 63 defer r.Body.Close() | |
| 64 dec := json.NewDecoder(r.Body) | |
| 65 if err := dec.Decode(&msg); err != nil { | |
| 66 logging.WithError(err).Errorf( | |
| 67 c, "could not decode message. %s", err) | |
| 68 return http.StatusOK // This is a hard failure, we don't want Pu bSub to retry. | |
|
iannucci
2017/07/08 00:05:25
i.e. we should return an error tagged as 'badPaylo
Ryan Tseng
2017/07/08 01:47:33
Done.
| |
| 69 } | |
| 70 bData, err := msg.GetData() | |
| 71 if err != nil { | |
| 72 logging.WithError(err).Errorf(c, "could not parse pubsub message string") | |
| 73 return http.StatusOK // This is a hard failure, we don't want Pu bSub to retry. | |
| 74 } | |
| 75 if err := json.Unmarshal(bData, &data); err != nil { | |
| 76 logging.WithError(err).Errorf(c, "could not parse pubsub message data") | |
| 77 return http.StatusOK // This is a hard failure, we don't want Pu bSub to retry. | |
| 78 } | |
| 79 | |
| 80 if err := handlePubSubBuild(c, &data.Build); err != nil { | |
| 81 switch err.(type) { | |
| 82 case transientError: | |
| 83 return http.StatusInternalServerError | |
| 84 case permanenterror: | |
| 85 return http.StatusOK | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 return http.StatusOK | |
| 90 } | |
| OLD | NEW |