-
Notifications
You must be signed in to change notification settings - Fork 4
/
client.go
145 lines (116 loc) · 3.73 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package mesos
import (
"fmt"
"time"
"net/http"
"errors"
"log"
"io"
"io/ioutil"
"encoding/json"
"strings"
)
const (
HTTP_GET = "GET"
)
type Client struct {
config Config
logger *log.Logger
http *http.Client
}
type MesosClient interface {
setMasterURL(leader string)
masterURL() string
buildDiscoveryURL(uri string) string
slaveStateURL(hostname string) string
slaveStatsURL(hostname string) string
doApiRequest(url string, result interface{}) (int, string, error)
unMarshallDataToJson(stream io.Reader, result interface{}) error
doRequst(method, url string)(int, string, *http.Response, error)
}
func NewClient(config Config) (*Client) {
service := &Client{}
service.config = config
if config.LogOutput == nil {
config.LogOutput = ioutil.Discard
}
service.logger = log.New(config.LogOutput, "[debug]: ", 0)
service.http = &http.Client{
Timeout: (time.Duration(config.RequestTimeout) * time.Second),
}
return service
}
func (c *Client) doApiRequest(url string, result interface{}) (int, string, error) {
if status, content, _, err := c.doRequst(HTTP_GET, url); err != nil {
return 0, "", err
} else {
if status >= 200 && status <= 299 {
if result != nil {
if err := c.unMarshallDataToJson(strings.NewReader(content), &result); err != nil {
c.logger.Printf("doApiRequest(): failed to decode JSON, error: %s", err)
return status, content, ErrInvalidResponse
}
}
c.logger.Printf("apiCall() result: %V", result)
return status, content, nil
}
switch status {
case 500:
return status, "", ErrInternalServerError
case 404:
return status, "", ErrDoesNotExist
}
return status, content, errors.New("Unknown error.")
}
}
func (c *Client) unMarshallDataToJson(stream io.Reader, result interface{}) error {
decoder := json.NewDecoder(stream)
if err := decoder.Decode(result); err != nil {
return err
}
return nil
}
func (c *Client) doRequst(method, url string)(int, string, *http.Response, error) {
client := &http.Client{}
if request, err := http.NewRequest(method, url, nil); err != nil {
c.logger.Printf("Unable to make call to Mesos: %s", err)
return 0, "", nil, err
} else {
request.Header.Add("Content-Type", "application/json")
var content string
if response, err := client.Do(request); err != nil {
log.Printf("Unable to make call to Mesos: %s", err)
c.logger.Printf("Unable to make call to Mesos: %s", err)
return 0, "", nil, errors.New("Unable to make call to Mesos")
} else {
c.logger.Printf("doRequst: %s, url: %s\n", method, url)
if response.ContentLength != 0 {
if response_content, err := ioutil.ReadAll(response.Body); err != nil {
return response.StatusCode, "", response, err
} else {
content = string(response_content)
}
}
return response.StatusCode, content, response, nil
}
}
return 0, "", nil, errors.New("Unable to make call to marathon")
}
func (c *Client) buildDiscoveryURL(uri string) string {
return fmt.Sprintf("%s/%s", c.config.DiscoveryURL, uri)
}
func (c *Client) setMasterURL(leader string) {
c.config.MasterURL = fmt.Sprintf("%s//%s:%d", c.config.getScheme(), leader, c.config.MasterPort)
}
func (c *Client) masterURL() string {
return c.config.MasterURL
}
func (c *Client) slaveStateURL(hostname string) string {
return c.slaveURL(hostname, "slave(1)/state.json")
}
func (c *Client) slaveStatsURL(hostname string) string {
return c.slaveURL(hostname, "metrics/snapshot")
}
func (c *Client) slaveURL(hostname, uri string) string {
return fmt.Sprintf("%s//%s:%d/%s", c.config.getScheme(), hostname, c.config.SlavePort, uri)
}