-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #227 from cpontes-ns1/PENG-3689
PENG-3689 - Introducing support for datasets functionality
- Loading branch information
Showing
9 changed files
with
871 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package mockns1 | ||
|
||
import ( | ||
"net/http" | ||
|
||
"gopkg.in/ns1/ns1-go.v2/rest/model/dataset" | ||
) | ||
|
||
// AddDatasetListTestCase sets up a test case for the api.Client.Datasets.List() function | ||
func (s *Service) AddDatasetListTestCase( | ||
requestHeaders, responseHeaders http.Header, | ||
response []*dataset.Dataset, | ||
) error { | ||
return s.AddTestCase( | ||
http.MethodGet, "/datasets", http.StatusOK, requestHeaders, | ||
responseHeaders, "", response, | ||
) | ||
} | ||
|
||
// AddDatasetGetTestCase sets up a test case for the api.Client.Datasets.Get() function | ||
func (s *Service) AddDatasetGetTestCase( | ||
id string, | ||
requestHeaders, responseHeaders http.Header, | ||
response *dataset.Dataset, | ||
) error { | ||
return s.AddTestCase( | ||
http.MethodGet, "/datasets/"+id, http.StatusOK, requestHeaders, | ||
responseHeaders, "", response, | ||
) | ||
} | ||
|
||
// AddDatasetCreateTestCase sets up a test case for the api.Client.Datasets.Create() function | ||
func (s *Service) AddDatasetCreateTestCase( | ||
requestHeaders, responseHeaders http.Header, | ||
request, response *dataset.Dataset, | ||
) error { | ||
return s.AddTestCase( | ||
http.MethodPut, "/datasets", http.StatusCreated, requestHeaders, | ||
responseHeaders, request, response, | ||
) | ||
} | ||
|
||
// AddDatasetDeleteTestCase sets up a test case for the api.Client.Datasets.Delete() function | ||
func (s *Service) AddDatasetDeleteTestCase( | ||
id string, requestHeaders, responseHeaders http.Header, | ||
) error { | ||
return s.AddTestCase( | ||
http.MethodDelete, "/datasets/"+id, http.StatusNoContent, requestHeaders, | ||
responseHeaders, "", "", | ||
) | ||
} | ||
|
||
// AddDatasetGetReportTestCase sets up a test case for the api.Client.Datasets.GetReport() function | ||
func (s *Service) AddDatasetGetReportTestCase( | ||
id string, reportId string, requestHeaders, responseHeaders http.Header, fileContents []byte, | ||
) error { | ||
return s.AddTestCase( | ||
http.MethodGet, "/datasets/"+id+"/reports/"+reportId, http.StatusOK, requestHeaders, | ||
responseHeaders, "", fileContents, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"gopkg.in/ns1/ns1-go.v2/rest/model/dataset" | ||
"io" | ||
"log" | ||
"net/http" | ||
"os" | ||
"strings" | ||
"time" | ||
|
||
api "gopkg.in/ns1/ns1-go.v2/rest" | ||
) | ||
|
||
var client *api.Client | ||
|
||
// Helper that initializes rest api client from environment variable. | ||
func init() { | ||
k := os.Getenv("NS1_APIKEY") | ||
if k == "" { | ||
fmt.Println("NS1_APIKEY environment variable is not set, giving up") | ||
} | ||
|
||
httpClient := &http.Client{Timeout: time.Second * 10} | ||
// Adds logging to each http request. | ||
doer := api.Decorate(httpClient, api.Logging(log.New(os.Stdout, "", log.LstdFlags))) | ||
client = api.NewClient(doer, api.SetAPIKey(k)) | ||
} | ||
|
||
func main() { | ||
dt, _, err := client.Datasets.Create(&dataset.Dataset{ | ||
Name: "My dataset", | ||
Datatype: &dataset.Datatype{ | ||
Type: dataset.DatatypeTypeNumQueries, | ||
Scope: dataset.DatatypeScopeAccount, | ||
Data: nil, | ||
}, | ||
Repeat: nil, | ||
Timeframe: &dataset.Timeframe{ | ||
Aggregation: dataset.TimeframeAggregationMontly, | ||
Cycles: func() *int32 { i := int32(1); return &i }(), | ||
}, | ||
ExportType: dataset.ExportTypeCSV, | ||
RecipientEmails: nil, | ||
}) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
b, _ := json.MarshalIndent(dt, "", " ") | ||
fmt.Println(string(b)) | ||
|
||
for { | ||
fmt.Println("waiting for report to be generated...") | ||
|
||
dt, _, err = client.Datasets.Get(dt.ID) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
if len(dt.Reports) == 0 { | ||
time.Sleep(time.Second * 5) | ||
continue | ||
} | ||
|
||
dtStatus := dt.Reports[0].Status | ||
|
||
if dtStatus == dataset.ReportStatusGenerating || dtStatus == dataset.ReportStatusQueued { | ||
time.Sleep(time.Second * 5) | ||
continue | ||
} | ||
|
||
if dtStatus == dataset.ReportStatusFailed { | ||
log.Fatal(fmt.Errorf("dataset[%s] report[%s] failed to generate", dt.ID, dt.Reports[0].ID)) | ||
} | ||
|
||
// report generated | ||
break | ||
} | ||
|
||
reportBuf, reportResp, err := client.Datasets.GetReport(dt.ID, dt.Reports[0].ID) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
var fileName string | ||
contentDisposition := reportResp.Header.Get("Content-Disposition") | ||
params := strings.Split(contentDisposition, ";") | ||
for _, param := range params { | ||
param = strings.TrimSpace(param) | ||
if strings.HasPrefix(param, "filename=") { | ||
fileName = strings.TrimPrefix(param, "filename=") | ||
fileName = strings.TrimSpace(fileName) | ||
fileName = strings.Trim(fileName, "\"") | ||
break | ||
} | ||
} | ||
|
||
cwd, err := os.Getwd() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
file, err := os.Create(fmt.Sprintf("%s/%s", cwd, fileName)) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer file.Close() | ||
|
||
_, err = io.Copy(file, reportBuf) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Println("dataset report saved to", fileName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package rest | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
|
||
"gopkg.in/ns1/ns1-go.v2/rest/model/dataset" | ||
) | ||
|
||
var ( | ||
// ErrDatasetNotFound bundles GET/POST/DELETE not found errors. | ||
ErrDatasetNotFound = errors.New("dataset not found") | ||
) | ||
|
||
// DatasetsService handles 'datasets' endpoint. | ||
type DatasetsService service | ||
|
||
// List returns the configured datasets. | ||
// | ||
// NS1 API docs: https://developer.ibm.com/apis/catalog/ns1--ibm-ns1-connect-api/api/API--ns1--ibm-ns1-connect-api#listDataset | ||
func (s *DatasetsService) List() ([]*dataset.Dataset, *http.Response, error) { | ||
req, err := s.client.NewRequest("GET", "datasets", nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
dts := make([]*dataset.Dataset, 0) | ||
resp, err := s.client.Do(req, &dts) | ||
|
||
return dts, resp, err | ||
} | ||
|
||
// Get takes a dataset id and returns all its data. | ||
// | ||
// NS1 API docs: https://developer.ibm.com/apis/catalog/ns1--ibm-ns1-connect-api/api/API--ns1--ibm-ns1-connect-api#getDataset | ||
func (s *DatasetsService) Get(dtID string) (*dataset.Dataset, *http.Response, error) { | ||
path := fmt.Sprintf("datasets/%s", dtID) | ||
|
||
req, err := s.client.NewRequest("GET", path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var dt dataset.Dataset | ||
resp, err := s.client.Do(req, &dt) | ||
if err != nil { | ||
var clientErr *Error | ||
switch { | ||
case errors.As(err, &clientErr): | ||
if strings.HasSuffix(clientErr.Message, " not found") { | ||
return nil, resp, ErrDatasetNotFound | ||
} | ||
} | ||
return nil, resp, err | ||
} | ||
|
||
return &dt, resp, nil | ||
} | ||
|
||
// Create takes a *Dataset and creates a new dataset. | ||
// | ||
// NS1 API docs: https://developer.ibm.com/apis/catalog/ns1--ibm-ns1-connect-api/api/API--ns1--ibm-ns1-connect-api#createDataset | ||
func (s *DatasetsService) Create(dt *dataset.Dataset) (*dataset.Dataset, *http.Response, error) { | ||
req, err := s.client.NewRequest("PUT", "datasets", dt) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
resp, err := s.client.Do(req, dt) | ||
return dt, resp, err | ||
} | ||
|
||
// Delete takes a dataset id and deletes it. | ||
// | ||
// NS1 API docs: https://developer.ibm.com/apis/catalog/ns1--ibm-ns1-connect-api/api/API--ns1--ibm-ns1-connect-api#deleteDataset | ||
func (s *DatasetsService) Delete(dtID string) (*http.Response, error) { | ||
path := fmt.Sprintf("datasets/%s", dtID) | ||
|
||
req, err := s.client.NewRequest("DELETE", path, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp, err := s.client.Do(req, nil) | ||
if err != nil { | ||
var clientErr *Error | ||
switch { | ||
case errors.As(err, &clientErr): | ||
if strings.HasSuffix(clientErr.Message, " not found") { | ||
return resp, ErrDatasetNotFound | ||
} | ||
} | ||
return resp, err | ||
} | ||
|
||
return resp, nil | ||
} | ||
|
||
// GetReport takes a dataset id and a report id and returns bytes.Buffer which contains the file contents | ||
// Additionally, file name can be grabbed from the 'Content-Disposition' header in the http.Response | ||
// | ||
// NS1 API docs: https://developer.ibm.com/apis/catalog/ns1--ibm-ns1-connect-api/api/API--ns1--ibm-ns1-connect-api#getDatasetReport | ||
func (s *DatasetsService) GetReport(dtID string, reportID string) (*bytes.Buffer, *http.Response, error) { | ||
path := fmt.Sprintf("datasets/%s/reports/%s", dtID, reportID) | ||
|
||
req, err := s.client.NewRequest("GET", path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var buf bytes.Buffer | ||
|
||
resp, err := s.client.Do(req, &buf) | ||
if err != nil { | ||
var clientErr *Error | ||
switch { | ||
case errors.As(err, &clientErr): | ||
if strings.HasSuffix(clientErr.Message, " not found") { | ||
return nil, resp, ErrDatasetNotFound | ||
} | ||
} | ||
return nil, resp, err | ||
} | ||
|
||
return &buf, resp, nil | ||
} |
Oops, something went wrong.