diff --git a/sourceapi/client.go b/sourceapi/client.go new file mode 100644 index 0000000..152a542 --- /dev/null +++ b/sourceapi/client.go @@ -0,0 +1,74 @@ +package sourceapi + +import ( + "errors" + "io/ioutil" + "net/http" +) + +const ( + // EndpointProduction is the push production endpoint + EndpointProduction = "https://platform.cloud.coveo.com/rest/organizations/" +) + +// Client is the pushapi client to send documents or identities +type Client interface { + CreateSource(d Source) (string, error) + UpdateSource(sourceID string, d Source) (string, error) + DeleteSource(sourceID string) error + ReadSource(sourceID string) (string, error) +} + +type client struct { + httpClient *http.Client + apikey string + endpoint string + organizationid string +} + +// Config is used to configure a new client +type Config struct { + // Endpoint is used if you want to use custom endpoints (dev,staging,testing) + Endpoint string + // The Coveo organization ID + OrganizationID string + // APIKey is the key used to push content to Coveo + APIKey string +} + +// NewClient initializes a new pushapi client with the config param +func NewClient(c Config) (Client, error) { + if len(c.Endpoint) == 0 { + c.Endpoint = EndpointProduction + } + + return &client{ + apikey: c.APIKey, + endpoint: c.Endpoint, + organizationid: c.OrganizationID, + httpClient: http.DefaultClient, + }, nil +} + +func (c *client) sendRequest(req *http.Request) (string, string, error) { + req.Header.Add("Authorization", "Bearer "+c.apikey) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + + resp, err := c.httpClient.Do(req) + if err != nil { + return "", "", err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", "", err + } + + if resp.StatusCode >= 300 { + return "", resp.Status, errors.New(string(body)) + } + + return string(body), resp.Status, nil +} diff --git a/sourceapi/client_test.go b/sourceapi/client_test.go new file mode 100644 index 0000000..c94b3fc --- /dev/null +++ b/sourceapi/client_test.go @@ -0,0 +1,32 @@ +package sourceapi + +import ( + "testing" +) + +func TestClient(t *testing.T) { + config := Config{} + _, err := NewClient(config) + if err != nil { + t.Fatalf("unexpected error. expected %v, actual %v", nil, err) + } +} + +func TestCreateSourceReturnError(t *testing.T){ + config := Config{ + OrganizationID : "", + APIKey : "", + } + c, err := NewClient(config) + source := Source{ + Name: "test-qa-enviroment-source", + Type: "PUSH", + Visibility: "SHARED", + Enabled: true, + } + _, err = c.CreateSource(source) + if err == nil { + t.Fatalf("Error shouldn't be empty") + } +} + diff --git a/sourceapi/source.go b/sourceapi/source.go new file mode 100644 index 0000000..fb3d0c5 --- /dev/null +++ b/sourceapi/source.go @@ -0,0 +1,106 @@ +package sourceapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "log" + "net/http" +) + +type Source struct { + Id string `json:"id"` + Name string `json:"name"` + Type string `json:"sourceType"` + Visibility string `json:"sourceVisibility"` + Enabled bool `json:"pushEnabled"` +} + + +// PushSource will send a document to the pushapi to create a source +func (c *client) CreateSource(d Source) (string, error) { + log.Printf("[INFO] Creating a resource") + if len(d.Name) == 0 { + return "", errors.New("you need a name for the source") + } + + marshalledDocument, err := json.Marshal(d) + log.Printf("[INFO] Document to create %s", string(marshalledDocument)) + if err != nil { + return "", err + } + buf := bytes.NewReader(marshalledDocument) + + endpoint := fmt.Sprintf("%s%s/sources", + c.endpoint, c.organizationid) + log.Printf("[INFO] Contacting endpoint %s", endpoint) + + req, err := http.NewRequest("POST", endpoint, buf) + resp, status, err := c.sendRequest(req) + if err != nil { + return "", errors.New("received status:" + status) + } + + return resp, nil +} + +// ReadSource will send a GET request for the specified sourceID to read +func (c *client) ReadSource(sourceID string) (string, error) { + if len(sourceID) == 0 { + return "", errors.New("you need a sourceID") + } + + endpoint := fmt.Sprintf("%s%s/sources/%s", + c.endpoint, c.organizationid, sourceID) + + req, err := http.NewRequest("GET", endpoint, nil) + resp, status, err := c.sendRequest(req) + if err != nil { + return "", errors.New("received status:" + status) + } + + return resp, nil +} + + +// UpdateSource will send a PUT request for the specified sourceID to modify +func (c *client) UpdateSource(sourceID string, d Source) (string, error) { + if len(sourceID) == 0 { + return "", errors.New("you need a sourceID") + } + marshalledDocument, err := json.Marshal(d) + if err != nil { + return "", err + } + buf := bytes.NewReader(marshalledDocument) + + endpoint := fmt.Sprintf("%s%s/sources/%s", + c.endpoint, c.organizationid, sourceID) + + req, err := http.NewRequest("PUT", endpoint, buf) + resp, status, err := c.sendRequest(req) + if err != nil { + return "", errors.New("received status:" + status) + } + + return resp, nil +} + +// DeleteSource will send a delete request for the specified sourceID +func (c *client) DeleteSource(sourceID string) error { + if len(sourceID) == 0 { + return errors.New("You need a sourceID") + } + + endpoint := fmt.Sprintf("%s%s/sources/%s", + c.endpoint, c.organizationid, sourceID) + + req, err := http.NewRequest("DELETE", endpoint, nil) + _, status, err := c.sendRequest(req) + if err != nil { + return errors.New("received status:" + status) + } + + return nil +}