2015-04-22 08:00:15 +00:00
|
|
|
package plugin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
|
2015-05-17 18:42:56 +00:00
|
|
|
"github.com/drone/drone/pkg/queue"
|
2015-04-22 08:00:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Client struct {
|
|
|
|
url string
|
|
|
|
token string
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(url, token string) *Client {
|
|
|
|
return &Client{url, token}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Publish makes an http request to the remote queue
|
|
|
|
// to insert work at the tail.
|
|
|
|
func (c *Client) Publish(work *queue.Work) error {
|
|
|
|
return c.send("POST", "/queue", work, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove makes an http request to the remote queue to
|
|
|
|
// remove the specified work item.
|
|
|
|
func (c *Client) Remove(work *queue.Work) error {
|
|
|
|
return c.send("DELETE", "/queue", work, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pull makes an http request to the remote queue to
|
|
|
|
// retrieve work. This initiates a long poll and will
|
|
|
|
// block until complete.
|
|
|
|
func (c *Client) Pull() *queue.Work {
|
|
|
|
out := &queue.Work{}
|
|
|
|
err := c.send("POST", "/queue/pull", nil, out)
|
|
|
|
if err != nil {
|
|
|
|
// TODO handle error
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pull makes an http request to the remote queue to
|
2015-05-05 08:04:20 +00:00
|
|
|
// retrieve work. This initiates a long poll and will
|
|
|
|
// block until complete.
|
|
|
|
func (c *Client) PullClose(cn queue.CloseNotifier) *queue.Work {
|
2015-04-22 08:00:15 +00:00
|
|
|
out := &queue.Work{}
|
2015-05-05 08:04:20 +00:00
|
|
|
err := c.send("POST", "/queue/pull", nil, out)
|
2015-04-22 08:00:15 +00:00
|
|
|
if err != nil {
|
|
|
|
// TODO handle error
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ack makes an http request to the remote queue
|
|
|
|
// to acknowledge an item in the queue was processed.
|
|
|
|
func (c *Client) Ack(work *queue.Work) error {
|
|
|
|
return c.send("POST", "/queue/ack", nil, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Items makes an http request to the remote queue
|
|
|
|
// to fetch a list of all work.
|
|
|
|
func (c *Client) Items() []*queue.Work {
|
|
|
|
out := []*queue.Work{}
|
|
|
|
err := c.send("GET", "/queue/items", nil, &out)
|
|
|
|
if err != nil {
|
|
|
|
// TODO handle error
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
// send is a helper function that makes an authenticated
|
|
|
|
// request to the remote http plugin.
|
|
|
|
func (c *Client) send(method, path string, in interface{}, out interface{}) error {
|
|
|
|
url_, err := url.Parse(c.url + path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var buf io.ReadWriter
|
|
|
|
if in != nil {
|
|
|
|
buf = new(bytes.Buffer)
|
|
|
|
err := json.NewEncoder(buf).Encode(in)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
req, err := http.NewRequest(method, url_.String(), buf)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
req.Header.Add("Authorization", "Bearer "+c.token)
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if out == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return json.NewDecoder(resp.Body).Decode(out)
|
|
|
|
}
|
2015-05-05 08:04:20 +00:00
|
|
|
|
|
|
|
// In order to implement PullClose() we'll need to use a custom transport:
|
|
|
|
//
|
|
|
|
// tr := &http.Transport{}
|
|
|
|
// client := &http.Client{Transport: tr}
|
|
|
|
// c := make(chan error, 1)
|
|
|
|
// go func() { c <- f(client.Do(req)) }()
|
|
|
|
// select {
|
|
|
|
// case <-ctx.Done():
|
|
|
|
// tr.CancelRequest(req)
|
|
|
|
// <-c // Wait for f to return.
|
|
|
|
// return ctx.Err()
|
|
|
|
// case err := <-c:
|
|
|
|
// return err
|
|
|
|
// }
|