Chromium Code Reviews| Index: go/src/infra/monorail/endpoints.go |
| diff --git a/go/src/infra/monorail/endpoints.go b/go/src/infra/monorail/endpoints.go |
| index fffac476a774b97aacd7a92689db71aea2a3ed1f..c9c31129a3f727aa23f6a7610e62dbe3aab55916 100644 |
| --- a/go/src/infra/monorail/endpoints.go |
| +++ b/go/src/infra/monorail/endpoints.go |
| @@ -46,6 +46,53 @@ func NewEndpointsClient(client *http.Client, url string) MonorailClient { |
| return &epClient{HTTP: client, url: strings.TrimSuffix(url, "/")} |
| } |
| +func (c *epClient) get(ctx context.Context, urlSuffix string, response interface{}) error { |
| + client := c.HTTP |
| + if client == nil { |
| + client = http.DefaultClient |
| + } |
| + |
| + // Limit ctx deadline to timeout set in client. |
| + if client.Timeout > 0 { |
| + clientDeadline := clock.Now(ctx).Add(client.Timeout) |
| + if deadline, ok := ctx.Deadline(); !ok || deadline.After(clientDeadline) { |
| + ctx, _ = context.WithDeadline(ctx, clientDeadline) |
| + } |
| + } |
| + |
| + // Make an HTTP request. |
| + req, err := http.NewRequest("GET", c.url+urlSuffix, nil) |
| + if err != nil { |
| + return fmt.Errorf("could not make a request to %s: %s", req.URL, err) |
| + } |
| + req.Header.Set("Accept", "application/json") |
| + |
| + // Send the request. |
| + logging.Debugf(ctx, "GET %s %s", req.URL) |
| + res, err := ctxhttp.Do(ctx, client, req) |
| + if err != nil { |
| + return errors.WrapTransient(err) |
| + } |
| + defer res.Body.Close() |
| + |
| + // Check HTTP status code. |
| + if res.StatusCode != http.StatusOK { |
| + text, _ := ioutil.ReadAll(io.LimitReader(res.Body, 1024)) |
| + err := fmt.Errorf("unexpected status %q. Response: %s", res.Status, text) |
| + if res.StatusCode == http.StatusNotFound || res.StatusCode > 500 { |
| + // Cloud Endpoints often flake with HTTP 404. |
| + // Treat such responses transient errors. |
| + err = errors.WrapTransient(err) |
| + } |
| + return err |
| + } |
| + |
| + if response == nil { |
| + return nil |
| + } |
| + return json.NewDecoder(res.Body).Decode(response) |
| +} |
| + |
|
nodir
2016/06/09 04:09:28
Please don't copy paste code such big chunks of co
seanmccullough1
2016/06/09 15:01:32
Done.
|
| func (c *epClient) call(ctx context.Context, urlSuffix string, request, response interface{}) error { |
| client := c.HTTP |
| if client == nil { |
| @@ -69,7 +116,7 @@ func (c *epClient) call(ctx context.Context, urlSuffix string, request, response |
| } |
| // Make an HTTP request. |
| - req, err := http.NewRequest("POST", c.url + urlSuffix, reqBuf) |
| + req, err := http.NewRequest("POST", c.url+urlSuffix, reqBuf) |
| if err != nil { |
| return fmt.Errorf("could not make a request to %s: %s", req.URL, err) |
| } |
| @@ -122,6 +169,19 @@ func (c *epClient) InsertComment(ctx context.Context, req *InsertCommentRequest, |
| return &InsertCommentResponse{}, c.call(ctx, url, req.Comment, nil) |
| } |
| +func (c *epClient) IssuesList(ctx context.Context, req *IssuesListRequest, options ...grpc.CallOption) (*IssuesListResponse, error) { |
| + if err := checkOptions(options); err != nil { |
| + return nil, err |
| + } |
| + url := fmt.Sprintf("/projects/%s/issues?can=open&q=%s", req.ProjectId, req.Q) |
|
nodir
2016/06/09 04:09:28
What about all the other fields? Either don't decl
nodir
2016/06/09 04:09:28
req.Can should be used instead of hardcoded open
seanmccullough1
2016/06/09 15:01:32
Done.
seanmccullough1
2016/06/09 15:01:32
Done.
|
| + res := &IssuesListResponse{} |
| + err := c.get(ctx, url, res) |
| + if err != nil { |
| + return nil, err |
| + } |
| + return res, nil |
| +} |
| + |
| func checkOptions(options []grpc.CallOption) error { |
| if len(options) > 0 { |
| return errGrpcOptions |