From d87b8ff4ba4608368f848b175ab5424915aa2455 Mon Sep 17 00:00:00 2001 From: Steven Polley Date: Fri, 6 Jul 2018 18:26:11 -0600 Subject: [PATCH] -Added to documentation -Moved logic of http request to the Do() method in request.go - --- 3.0/connectwise/company.go | 27 ++++++++++++++++----------- 3.0/connectwise/requests.go | 21 +++++++++++++++++---- 3.0/connectwise/service.go | 5 ++++- 3.0/connectwise/system.go | 9 +++++++-- 3.0/connectwise/time.go | 2 ++ 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/3.0/connectwise/company.go b/3.0/connectwise/company.go index ca4d660..6c055ac 100644 --- a/3.0/connectwise/company.go +++ b/3.0/connectwise/company.go @@ -146,6 +146,16 @@ type Company struct { } `json:"customFields"` } +//Unmarshal is a method which exists for each struct for data returned by or posted to the ConnectWise API +//It is responsible for Unmarshaling the JSON data into the struct +func (co *Company) Unmarshal(data *[]byte) error { + err := json.Unmarshal(*data, co) + if err != nil { + return fmt.Errorf("failed to unmarshal data into company struct: %s", err) + } + return nil +} + //GetCompanyByName expects an exact match, perhaps an improvement could be made to support wildcard characters. //Will return a pointer to a slice of Company's. func (cw *ConnectwiseSite) GetCompanyByName(companyName string) (*[]Company, error) { @@ -175,22 +185,17 @@ func (cw *ConnectwiseSite) GetCompanyByName(companyName string) (*[]Company, err //GetCompanyByID expects the Connectwise Company ID and returns a pointer to a Company //Does not return a slice like GetCompanyByName as the ID will only ever have one match func (cw *ConnectwiseSite) GetCompanyByID(companyID int) (*Company, error) { - restAction := fmt.Sprintf("/company/companies/%d", companyID) - cwurl, err := cw.BuildURL(restAction) + req := NewRequest(cw, fmt.Sprintf("/company/companies/%d", companyID), "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) - } - - company := Company{} - err = json.Unmarshal(body, &company) + co := &Company{} + err = co.Unmarshal(&req.Body) if err != nil { return nil, fmt.Errorf("failed to unmarshal body into struct: %s", err) } - return &company, nil + return co, nil } diff --git a/3.0/connectwise/requests.go b/3.0/connectwise/requests.go index cd3f051..f231f65 100644 --- a/3.0/connectwise/requests.go +++ b/3.0/connectwise/requests.go @@ -1,6 +1,7 @@ package connectwise import ( + "bytes" "fmt" "io" "io/ioutil" @@ -17,11 +18,13 @@ type Request struct { Body []byte //In a GET request, this is an instance of the struct that the expected json data is to be unmarshaled into } +//NewRequest is a function which takes the mandatory fields to perform a request to the CW API and returns a pointer to a Request struct func NewRequest(cw *ConnectwiseSite, restAction, method string, body []byte) *Request { req := Request{CW: cw, RestAction: restAction, Method: method, Body: body} return &req } +//Do is a method of the Request struct which uses the data contained within the Request instance to perform an HTTP request to ConnectWise func (req *Request) Do() error { cwurl, err := req.CW.BuildURL(req.RestAction) if err != nil { @@ -36,14 +39,24 @@ func (req *Request) Do() error { cwurl.RawQuery = parameters.Encode() } - /////// - req.Body, err = req.CW.GetRequest(cwurl) + client := &http.Client{} + jsonBuffer := bytes.NewReader(req.Body) + httpreq, err := http.NewRequest(req.Method, cwurl.String(), jsonBuffer) if err != nil { - return fmt.Errorf("get request failed: %s", err) + return fmt.Errorf("could not construct http request: %s", err) + } + httpreq.Header.Set("Authorization", req.CW.Auth) + httpreq.Header.Set("Content-Type", "application/json") + resp, err := client.Do(httpreq) + if err != nil { + return fmt.Errorf("could not perform http %s request: %s", req.Method, err) + } + req.Body, err = getHTTPResponseBody(resp) + if err != nil { + return fmt.Errorf("failed to get http response body: %s", err) } return nil - } //BuildURL will take a REST action such as "/companies/company/5" and then append the CW site to it and return a pointer to a url.URL diff --git a/3.0/connectwise/service.go b/3.0/connectwise/service.go index e6d1419..8cde4cb 100644 --- a/3.0/connectwise/service.go +++ b/3.0/connectwise/service.go @@ -6,7 +6,7 @@ import ( "time" ) -//Company is a struct to hold the unmarshaled JSON data when making a call to the Service API +//Ticket is a struct to hold the unmarshaled JSON data when making a call to the Service API type Ticket struct { ID int `json:"id"` Summary string `json:"summary"` @@ -182,6 +182,8 @@ type TimeEntryReference struct { } `json:"_info"` } +//ConfigurationReference is a struct to hold a reference to Configuration data in the Connectwise API +//TBD: Do these "reference" types really need to be exported??? type ConfigurationReference struct { ID int `json:"id"` DeviceIdentifier string `json:"deviceIdentifier"` @@ -233,6 +235,7 @@ func (cw *ConnectwiseSite) GetTicketTimeEntriesByID(ticketID int) (*[]TimeEntryR return &timeEntryReference, nil } +//GetTicketConfigurationsByID expects a ticket ID and returns a pointer to a slice of the configurations attached to the ticket func (cw *ConnectwiseSite) GetTicketConfigurationsByID(ticketID int) (*[]ConfigurationReference, error) { restAction := fmt.Sprintf("/service/tickets/%d/configurations", ticketID) cwurl, err := cw.BuildURL(restAction) diff --git a/3.0/connectwise/system.go b/3.0/connectwise/system.go index 69397b4..5413ce3 100644 --- a/3.0/connectwise/system.go +++ b/3.0/connectwise/system.go @@ -6,17 +6,20 @@ import ( "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 + ObjectID int Type string Level string - MemberId int + MemberID int InactiveFlag bool } +//GetCallbacks returns a slice of Callback structs containing all the callbacks currently registered with ConnectWise func (cw *ConnectwiseSite) GetCallbacks() (*[]Callback, error) { restAction := "/system/callbacks" cwurl, err := cw.BuildURL(restAction) @@ -38,6 +41,7 @@ func (cw *ConnectwiseSite) GetCallbacks() (*[]Callback, error) { } +//NewCallback expects a Callback struct and will register a new callback with Connectwise //TBD: This should return something useful, response body?? func (cw *ConnectwiseSite) NewCallback(callback Callback) error { restAction := "/system/callbacks" @@ -61,6 +65,7 @@ func (cw *ConnectwiseSite) NewCallback(callback Callback) error { return nil } +//DeleteCallback expects the ID of an existing callback and will unregister it with ConnectWise //TBD: This should return something useful, response body?? func (cw *ConnectwiseSite) DeleteCallback(callback int) error { restAction := fmt.Sprintf("/system/callbacks/%d", callback) diff --git a/3.0/connectwise/time.go b/3.0/connectwise/time.go index b2b11c3..1081ce1 100644 --- a/3.0/connectwise/time.go +++ b/3.0/connectwise/time.go @@ -5,6 +5,7 @@ import ( "fmt" ) +//TimeEntry is a struct to hold the unmarshaled JSON data when making a call to the Time API type TimeEntry struct { ID int `json:"id"` Company struct { @@ -83,6 +84,7 @@ type TimeEntry struct { } } +//GetTimeEntryByID expects a time entry ID and will return a pointer to a TimeEntry struct func (cw *ConnectwiseSite) GetTimeEntryByID(timeEntryID int) (*TimeEntry, error) { restAction := fmt.Sprintf("/time/entries/%d", timeEntryID) cwurl, err := cw.BuildURL(restAction)