-
Notifications
You must be signed in to change notification settings - Fork 3
/
report.go
113 lines (88 loc) · 2.79 KB
/
report.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package omtr
import (
"encoding/json"
"fmt"
"time"
)
// takes a query object and returns a reportId which can be used to fetch the report in the future
func (omcl *OmnitureClient) QueueReport(query *ReportQuery) (int64, error) {
bytes, err := json.Marshal(query)
if err != nil {
return -1, err
}
return omcl.QueueReportRaw(string(bytes))
}
func format_error_response(resp []byte) error {
var ge getError
err := json.Unmarshal(resp, &ge)
if err != nil {
return fmt.Errorf("Report.Get returned '%s'; error attempting to unmarshal to error structure: %v", string(resp), err)
}
return ge
}
// takes a query string (json) and returns a reportId which can be used to fetch the report in the future
func (omcl *OmnitureClient) QueueReportRaw(query string) (int64, error) {
fmt.Printf("DEBUG: query: %s\n", query)
status, b, err := omcl.om_request("Report.Queue", query)
if err != nil {
return -1, err
}
if status == 400 {
return -1, format_error_response(b)
}
response := queueReport_response{}
err = json.Unmarshal(b, &response)
if err != nil {
return -1, err
}
return int64(response.ReportID), nil
}
// takes a reportId and returns a raw byteslice of json data, or error, including the Report Not Ready error.
func (omcl *OmnitureClient) GetReportRaw(reportId int64) ([]byte, error) {
status, response, err := omcl.om_request("Report.Get", fmt.Sprintf("{ \"reportID\":%d }", reportId))
if err != nil {
return nil, err
}
// the api returns 400 if the report is not yet ready; in this case I'll parse the response as an error and return it
if status == 400 {
return nil, format_error_response(response)
}
return response, err
}
func (omcl *OmnitureClient) GetReport(reportId int64) (*ReportResponse, error) {
bytes, err := omcl.GetReportRaw(reportId)
if err != nil {
return nil, err
}
resp := &ReportResponse{}
err = json.Unmarshal(bytes, resp)
resp.TimeRetrieved = time.Now()
return resp, err
}
/*
Takes a report definition and a callback which will be called once the report has successfully been retrieved.
Returns the reportId of the queued report or error
*/
func (omcl *OmnitureClient) Report(query *ReportQuery, success_callback func(*ReportResponse, error)) (int64, error) {
rid, err := omcl.QueueReport(query)
if err != nil {
return -1, err
}
go omcl.wait_for_report_then_call(rid, success_callback)
return rid, nil
}
func (omcl *OmnitureClient) wait_for_report_then_call(rid int64, callback func(*ReportResponse, error)) {
for {
response, err := omcl.GetReport(rid)
if err == nil {
callback(response, nil)
return
}
if _, ok := err.(getError); !ok { // type assert that err is a getError, and execute following block if it's not
// getError is a "good" error; anything else isn't.
callback(nil, err)
return
}
time.Sleep(1 * time.Second)
}
}