blob: 76800294ef008ba49cedee8b7bf2420a66bc5003 [file] [log] [blame] [edit]
package apiGatewayConfDeploy
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
const (
configBearerToken = "apigeesync_bearer_token"
trackerConfigStatusEndpoint = "/configurations/status"
trackerHeartbeatEndpoint = "/serviceheartbeat/{uuid}"
trackerRegisterEndpoint = "/serviceregister/{uuid}"
)
type trackerClientInterface interface {
putConfigStatus(body *configStatusBody) *trackerResponse
putRegister(uuid string, body *registerBody) *trackerResponse
putHeartbeat(uuid, reportedTime string) *trackerResponse
}
type trackerResponse struct {
code int
contentType string
body []byte
}
type trackerClient struct {
trackerBaseUrl string
clusterId string
httpclient *http.Client
}
func (t *trackerClient) putConfigStatus(reqBody *configStatusBody) *trackerResponse {
uri, err := url.Parse(t.trackerBaseUrl + trackerConfigStatusEndpoint)
if err != nil {
log.Errorf("putConfigStatus failed to parse tracker uri: %v", err)
return (internalError(err))
}
bodyBytes, err := json.Marshal(*reqBody)
req, err := http.NewRequest("PUT", uri.String(), bytes.NewReader(bodyBytes))
req.Header.Add("Authorization", getBearerToken())
r, err := t.httpclient.Do(req)
if err != nil {
log.Errorf("trackerClient communication error: %v", err)
return (internalError(err))
}
defer r.Body.Close()
return parseTrackerResponse(r)
}
func (t *trackerClient) putRegister(uuid string, reqBody *registerBody) *trackerResponse {
uri, err := url.Parse(t.trackerBaseUrl + strings.Replace(trackerRegisterEndpoint, "{uuid}", uuid, 1))
if err != nil {
log.Errorf("postRegister failed to parse tracker uri: %v", err)
return (internalError(err))
}
body := serviceRegisterBody{
ClusterId: t.clusterId,
Pod: reqBody.Pod,
PodType: reqBody.Type,
ReportedTime: reqBody.ReportedTime,
Name: reqBody.Name,
Type: reqBody.Type,
}
bodyBytes, err := json.Marshal(body)
if err != nil {
return (internalError(err))
}
req, err := http.NewRequest("PUT", uri.String(), bytes.NewReader(bodyBytes))
req.Header.Add("Authorization", getBearerToken())
r, err := t.httpclient.Do(req)
if err != nil {
log.Errorf("trackerClient communication error: %v", err)
return (internalError(err))
}
defer r.Body.Close()
return parseTrackerResponse(r)
}
func (t *trackerClient) putHeartbeat(uuid, reported string) *trackerResponse {
uri, err := url.Parse(t.trackerBaseUrl + strings.Replace(trackerHeartbeatEndpoint, "{uuid}", uuid, 1))
if err != nil {
log.Errorf("putHeartbeat failed to parse tracker uri: %v", err)
return internalError(err)
}
req, err := http.NewRequest("PUT", uri.String(), nil)
req.Header.Add("Authorization", getBearerToken())
req.Header.Add("reportedTime", reported)
r, err := t.httpclient.Do(req)
if err != nil {
log.Errorf("trackerClient communication error: %v", err)
return internalError(err)
}
defer r.Body.Close()
return parseTrackerResponse(r)
}
func internalError(err error) *trackerResponse {
res := &trackerResponse{}
res.code = http.StatusInternalServerError
res.body = []byte(err.Error())
return res
}
func getBearerToken() string {
return "Bearer " + config.GetString(configBearerToken)
}
func parseTrackerResponse(r *http.Response) *trackerResponse {
trackerBody, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Errorf("apid failed to read response body: %v", err)
return (internalError(err))
}
res := &trackerResponse{}
res.contentType = r.Header.Get("Content-type")
switch r.StatusCode {
case http.StatusOK:
res.code = r.StatusCode
res.body = trackerBody
case http.StatusUnauthorized, http.StatusForbidden:
res.code = http.StatusInternalServerError
res.body = []byte("apid token rejected by tracker")
log.Errorf("%v: %v, %v", res.body, r.StatusCode, trackerBody)
case http.StatusNotFound:
res.code = http.StatusInternalServerError
res.body = []byte("apid cannot connect to tracker")
log.Errorf("%v: %v, %v", res.body, r.StatusCode, trackerBody)
default:
log.Infof("Abnormal Response from Tracker: %v, %v", r.StatusCode, trackerBody)
res.code = r.StatusCode
res.body = trackerBody
}
return res
}
type serviceRegisterBody struct {
ClusterId string `json:"clusterId"`
Pod string `json:"pod"`
PodType string `json:"podType"`
ReportedTime string `json:"reportedTime"`
Name string `json:"name"`
Type string `json:"type"`
}