From 0c7791e2672590eacd428331fb10099f5514ad7f Mon Sep 17 00:00:00 2001 From: Steven Polley Date: Sat, 7 Jul 2018 17:18:59 -0600 Subject: [PATCH] Complete refactor of request system... much more flexible requests. --- 3.0/connectwise/finance.go | 39 +++++++------------ 3.0/connectwise/requests.go | 67 -------------------------------- 3.0/connectwise/service.go | 49 ++++++++++-------------- 3.0/connectwise/system.go | 76 +++++++++++++++++-------------------- 3.0/connectwise/time.go | 17 +++------ 5 files changed, 72 insertions(+), 176 deletions(-) diff --git a/3.0/connectwise/finance.go b/3.0/connectwise/finance.go index c770ba5..3f2c67d 100644 --- a/3.0/connectwise/finance.go +++ b/3.0/connectwise/finance.go @@ -3,7 +3,6 @@ package connectwise import ( "encoding/json" "fmt" - "net/url" ) //Agreement is a struct to hold the unmarshaled JSON data when making a call to the Finance API @@ -118,50 +117,38 @@ type Agreement struct { //GetAgreements returns a list of agreements, not paginated and currently not that useful //TBD: Pagination and filtering options still need to be considered func (cw *Site) GetAgreements() (*[]Agreement, error) { - restAction := "/finance/agreements" - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, "/finance/agreements", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - agreements := []Agreement{} - err = json.Unmarshal(body, &agreements) + agreements := &[]Agreement{} + err = json.Unmarshal(req.Body, agreements) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &agreements, nil - + return agreements, nil } //GetAgreementsByCompanyName returns a list of agreements that belong to an exact matching company name //TBD: Pagination and filtering options still need to be considered func (cw *Site) GetAgreementsByCompanyName(companyName string) (*[]Agreement, error) { - restAction := "/finance/agreements" - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, "/finance/agreements", "GET", nil) + req.Parameters["conditions"] = "company/name=\"" + companyName + "\"" + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - parameters := url.Values{} - parameters.Add("conditions", "company/name=\""+companyName+"\"") - cwurl.RawQuery = parameters.Encode() - - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - agreements := []Agreement{} - err = json.Unmarshal(body, &agreements) + agreements := &[]Agreement{} + err = json.Unmarshal(req.Body, agreements) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &agreements, nil + return agreements, nil } //GetBillingCycles is not complete diff --git a/3.0/connectwise/requests.go b/3.0/connectwise/requests.go index e3cb840..09a406c 100644 --- a/3.0/connectwise/requests.go +++ b/3.0/connectwise/requests.go @@ -3,7 +3,6 @@ package connectwise import ( "bytes" "fmt" - "io" "io/ioutil" "net/http" "net/url" @@ -87,69 +86,3 @@ func getHTTPResponseBody(resp *http.Response) ([]byte, error) { return body, nil } - -//GetRequest takes a Site and request URL, and returns the body of the response -func (cw *Site) GetRequest(cwurl *url.URL) ([]byte, error) { - client := &http.Client{} - req, err := http.NewRequest("GET", cwurl.String(), nil) - if err != nil { - return nil, fmt.Errorf("could not construct http request: %s", err) - } - req.Header.Set("Authorization", cw.Auth) - req.Header.Set("Content-Type", "application/json") - response, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("could not perform http get request: %s", err) - } - - body, err := getHTTPResponseBody(response) - if err != nil { - return nil, fmt.Errorf("could not get http response body: %s", err) - } - - return body, nil -} - -//PostRequest takes a Site and request URL, and returns the body of the response -func (cw *Site) PostRequest(cwurl *url.URL, reqBody io.Reader) ([]byte, error) { - client := &http.Client{} - req, err := http.NewRequest("POST", cwurl.String(), reqBody) - if err != nil { - return nil, fmt.Errorf("could not construct http request: %s", err) - } - req.Header.Set("Authorization", cw.Auth) - req.Header.Set("Content-Type", "application/json") - response, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("could not perform http post request: %s", err) - } - - body, err := getHTTPResponseBody(response) - if err != nil { - return nil, fmt.Errorf("could not get http response body: %s", err) - } - - return body, nil -} - -//DeleteRequest takes a Site and request URL, and returns the body of the response -func (cw *Site) DeleteRequest(cwurl *url.URL) ([]byte, error) { - client := &http.Client{} - req, err := http.NewRequest("DELETE", cwurl.String(), nil) - if err != nil { - return nil, fmt.Errorf("could not construct http request: %s", err) - } - req.Header.Set("Authorization", cw.Auth) - req.Header.Set("Content-Type", "application/json") - response, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("could not perform http delete request: %s", err) - } - - body, err := getHTTPResponseBody(response) - if err != nil { - return nil, fmt.Errorf("could not get http response body: %s", err) - } - - return body, nil -} diff --git a/3.0/connectwise/service.go b/3.0/connectwise/service.go index 21d444d..c0155a5 100644 --- a/3.0/connectwise/service.go +++ b/3.0/connectwise/service.go @@ -195,63 +195,52 @@ type ConfigurationReference struct { //GetTicketByID expects a ticket ID and returns a pointer to a Ticket struct func (cw *Site) GetTicketByID(ticketID int) (*Ticket, error) { - restAction := fmt.Sprintf("/service/tickets/%d", ticketID) - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, fmt.Sprintf("/service/tickets/%d", ticketID), "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - ticket := Ticket{} - err = json.Unmarshal(body, &ticket) + ticket := &Ticket{} + err = json.Unmarshal(req.Body, ticket) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &ticket, nil + return ticket, nil } //GetTicketTimeEntriesByID expects a ticket ID and returns a pointer a to a slice of TimeEntryReference's, all the time entries attached to that ticket func (cw *Site) GetTicketTimeEntriesByID(ticketID int) (*[]TimeEntryReference, error) { - restAction := fmt.Sprintf("/service/tickets/%d/timeentries", ticketID) - cwurl, err := cw.BuildURL(restAction) + + req := NewRequest(cw, fmt.Sprintf("/service/tickets/%d/timeentries", ticketID), "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - timeEntryReference := []TimeEntryReference{} - err = json.Unmarshal(body, &timeEntryReference) + timeEntryReference := &[]TimeEntryReference{} + err = json.Unmarshal(req.Body, timeEntryReference) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &timeEntryReference, nil + return timeEntryReference, nil } //GetTicketConfigurationsByID expects a ticket ID and returns a pointer to a slice of the configurations attached to the ticket func (cw *Site) GetTicketConfigurationsByID(ticketID int) (*[]ConfigurationReference, error) { - restAction := fmt.Sprintf("/service/tickets/%d/configurations", ticketID) - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, fmt.Sprintf("/service/tickets/%d/configurations", ticketID), "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - configurationReference := []ConfigurationReference{} - err = json.Unmarshal(body, &configurationReference) + configurationReference := &[]ConfigurationReference{} + err = json.Unmarshal(req.Body, configurationReference) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &configurationReference, nil + return configurationReference, nil } diff --git a/3.0/connectwise/system.go b/3.0/connectwise/system.go index 81366f3..fa05039 100644 --- a/3.0/connectwise/system.go +++ b/3.0/connectwise/system.go @@ -1,81 +1,73 @@ package connectwise import ( - "bytes" "encoding/json" "fmt" ) //Callback is a struct to hold the unmarshaled JSON data when making a call to the System API -//TBD: struct tags type Callback struct { - ID int - Description string - URL string - ObjectID int - Type string - Level string - MemberID int - InactiveFlag bool + ID int `json:"id"` + Description string `json:"description"` + URL string `json:"url"` + ObjectID int `json:"objectId"` + Type string `json:"type"` + Level string `json:"level"` + MemberID int `json:"memberId"` + InactiveFlag bool `json:"inactiveFlag"` + Info struct { + LastUpdated string `json:"lastUpdated"` + UpdatedBy string `json:"updatedBy"` + } `json:"_info"` } //GetCallbacks returns a slice of Callback structs containing all the callbacks currently registered with ConnectWise func (cw *Site) GetCallbacks() (*[]Callback, error) { - restAction := "/system/callbacks" - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, "/system/callbacks", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - callbacks := []Callback{} - err = json.Unmarshal(body, &callbacks) + callbacks := &[]Callback{} + err = json.Unmarshal(req.Body, callbacks) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &callbacks, nil - + return callbacks, nil } //NewCallback expects a Callback struct and will register a new callback with Connectwise //TBD: This should return something useful, response body?? -func (cw *Site) NewCallback(callback Callback) error { - restAction := "/system/callbacks" - cwurl, err := cw.BuildURL(restAction) - if err != nil { - return fmt.Errorf("could not build url %s: %s", restAction, err) - } - +func (cw *Site) NewCallback(callback *Callback) (*Callback, error) { jsonCallback, err := json.Marshal(callback) if err != nil { - return fmt.Errorf("could not marshal json data: %s", err) + return nil, fmt.Errorf("could not marshal json data: %s", err) } - jsonBuffer := bytes.NewReader(jsonCallback) - - _, err = cw.PostRequest(cwurl, jsonBuffer) + req := NewRequest(cw, "/system/callbacks", "POST", jsonCallback) + err = req.Do() if err != nil { - return fmt.Errorf("could not post request %s: %s", cwurl, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - return nil + callback = &Callback{} + err = json.Unmarshal(req.Body, callback) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) + } + + return callback, nil } //DeleteCallback expects the ID of an existing callback and will unregister it with ConnectWise -//TBD: This should return something useful, response body?? +//Does not return anything - CW gives an empty response body func (cw *Site) DeleteCallback(callback int) error { - restAction := fmt.Sprintf("/system/callbacks/%d", callback) - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, fmt.Sprintf("/system/callbacks/%d", callback), "DELETE", nil) + err := req.Do() if err != nil { - return fmt.Errorf("could not build url %s: %s", restAction, err) - } - _, err = cw.DeleteRequest(cwurl) - if err != nil { - return fmt.Errorf("could not delete request %s: %s", cwurl, err) + return fmt.Errorf("request failed for %s: %s", req.RestAction, err) } return nil diff --git a/3.0/connectwise/time.go b/3.0/connectwise/time.go index c387600..aab9eb8 100644 --- a/3.0/connectwise/time.go +++ b/3.0/connectwise/time.go @@ -86,22 +86,17 @@ type TimeEntry struct { //GetTimeEntryByID expects a time entry ID and will return a pointer to a TimeEntry struct func (cw *Site) GetTimeEntryByID(timeEntryID int) (*TimeEntry, error) { - restAction := fmt.Sprintf("/time/entries/%d", timeEntryID) - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, fmt.Sprintf("/time/entries/%d", timeEntryID), "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build url %s: %s", restAction, err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := cw.GetRequest(cwurl) - if err != nil { - return nil, fmt.Errorf("could not get request %s: %s", cwurl, err) - } - - timeEntry := TimeEntry{} - err = json.Unmarshal(body, &timeEntry) + timeEntry := &TimeEntry{} + err = json.Unmarshal(req.Body, timeEntry) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &timeEntry, nil + return timeEntry, nil }