Skip to content

Commit

Permalink
feat: adds support for deployment type #521
Browse files Browse the repository at this point in the history
  • Loading branch information
srinandan committed Aug 16, 2024
1 parent 5ecb2db commit eb18587
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 50 deletions.
120 changes: 101 additions & 19 deletions internal/client/env/reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ import (
)

const (
proxy_dimension = "apiproxy"
selection = "sum(message_count)"
proxy_dimension = "apiproxy"
proxy_deployment_type = "proxy_deployment_type"
selection = "sum(message_count)"
)

type report struct {
Expand All @@ -55,7 +56,9 @@ type metric struct {
}

type apiCalls struct {
count int
count int
standardCount int
extensibleCount int
sync.Mutex
}

Expand All @@ -79,8 +82,72 @@ func TotalAPICallsInMonthAsync(environment string, month int, year int, envDetai
}
}

func TotalAPICallsByTypeInMonthAsync(environment string, month int, year int, envDetails bool, wg *sync.WaitGroup) {
defer wg.Done()
var totalExtensible, totalStandard int
var err error

if totalExtensible, totalStandard, err = TotalAPICallsByTypeInMonth(environment, month, year); err != nil {
clilog.Error.Println(err)
return
}
ApiCalls.incrementExtensibleCount(totalExtensible)
ApiCalls.incrementStandardCount(totalStandard)
if envDetails {
w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0)
fmt.Fprintf(w, "%s\t%d/%d\t%d\t%d", environment, month, year, totalExtensible, totalStandard)
fmt.Fprintln(w)
w.Flush()
}
}

func TotalAPICallsInMonth(environment string, month int, year int) (total int, err error) {
var apiCalls int

environmentReport, err := getReport(proxy_dimension, environment, month, year)
if err != nil {
return -1, err
}

for _, e := range environmentReport.Environments {
for _, d := range e.Dimensions {
for _, m := range d.Metrics {
calls, _ := strconv.Atoi(m.Values[0])
apiCalls = apiCalls + calls
}
}
}

return apiCalls, nil
}

func TotalAPICallsByTypeInMonth(environment string, month int, year int) (totalExtensible int, totalStandard int, err error) {
var extensibleApiCalls, standardApiCalls int

environmentReport, err := getReport(proxy_deployment_type, environment, month, year)
if err != nil {
return -1, -1, err
}

for _, e := range environmentReport.Environments {
for _, d := range e.Dimensions {
if d.Name == "EXTENSIBLE" {
for _, m := range d.Metrics {
calls, _ := strconv.Atoi(m.Values[0])
extensibleApiCalls = extensibleApiCalls + calls
}
} else if d.Name == "STANDARD" {
for _, m := range d.Metrics {
calls, _ := strconv.Atoi(m.Values[0])
standardApiCalls = standardApiCalls + calls
}
}
}
}
return extensibleApiCalls, standardApiCalls, nil
}

func getReport(dimension string, environment string, month int, year int) (r report, err error) {
var respBody []byte

// throttle API Calls
Expand All @@ -97,40 +164,41 @@ func TotalAPICallsInMonth(environment string, month int, year int) (total int, e
q.Set("timeRange", timeRange)

u.RawQuery = q.Encode()
u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "environments", environment, "stats", proxy_dimension)
u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "environments", environment, "stats", dimension)

if respBody, err = apiclient.HttpClient(u.String()); err != nil {
return -1, err
return r, err
}

environmentReport := report{}

if err = json.Unmarshal(respBody, &environmentReport); err != nil {
return -1, err
}

for _, e := range environmentReport.Environments {
for _, d := range e.Dimensions {
for _, m := range d.Metrics {
calls, _ := strconv.Atoi(m.Values[0])
apiCalls = apiCalls + calls
}
}
if err = json.Unmarshal(respBody, &r); err != nil {
return r, err
}

return apiCalls, nil
return r, nil
}

// GetCount
func (c *apiCalls) GetCount() int {
return c.count
}

// GetExtensibleCount
func (c *apiCalls) GetExtensibleCount() int {
return c.extensibleCount
}

// GetStandardCount
func (c *apiCalls) GetStandardCount() int {
return c.standardCount
}

// ResetCount
func (c *apiCalls) ResetCount() {
c.Lock()
defer c.Unlock()
c.count = 0
c.extensibleCount = 0
c.standardCount = 0
}

// daysIn returns the number of days in a month for a given year.
Expand All @@ -146,3 +214,17 @@ func (c *apiCalls) incrementCount(total int) {
defer c.Unlock()
c.count = c.count + total
}

// incrementStandardCount synchronizes counting
func (c *apiCalls) incrementStandardCount(total int) {
c.Lock()
defer c.Unlock()
c.standardCount = c.standardCount + total
}

// incrementExtensibleCount synchronizes counting
func (c *apiCalls) incrementExtensibleCount(total int) {
c.Lock()
defer c.Unlock()
c.extensibleCount = c.extensibleCount + total
}
52 changes: 33 additions & 19 deletions internal/client/orgs/reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import (
"internal/client/env"
)

func TotalAPICallsInMonth(month int, year int, envDetails bool, conn int) (total int, err error) {
func TotalAPICallsInMonth(month int, year int, envDetails bool,
proxyType bool, conn int) (apiCalls int, extensibleApiCalls int, standardApiCalls int, err error) {
var pwg sync.WaitGroup
var envListBytes []byte
var envList []string
Expand All @@ -39,11 +40,11 @@ func TotalAPICallsInMonth(month int, year int, envDetails bool, conn int) (total
defer apiclient.ClientPrintHttpResponse.Set(apiclient.GetCmdPrintHttpResponseSetting())

if envListBytes, err = env.List(); err != nil {
return -1, err
return -1, -1, -1, err
}

if err = json.Unmarshal(envListBytes, &envList); err != nil {
return -1, err
return -1, -1, -1, err
}

numEntities := len(envList)
Expand All @@ -63,61 +64,74 @@ func TotalAPICallsInMonth(month int, year int, envDetails bool, conn int) (total
pwg.Add(1)
end = (i * conn) + conn
clilog.Debug.Printf("Creating reports for a batch %d of environments\n", (i + 1))
go batchReport(envList[start:end], month, year, envDetails, &pwg)
go batchReport(envList[start:end], month, year, envDetails, proxyType, &pwg)
start = end
pwg.Wait()
}

if remaining > 0 {
pwg.Add(1)
clilog.Debug.Printf("Creating reports for remaining %d environments\n", remaining)
go batchReport(envList[start:numEntities], month, year, envDetails, &pwg)
go batchReport(envList[start:numEntities], month, year, envDetails, proxyType, &pwg)
pwg.Wait()
}

return env.ApiCalls.GetCount(), nil
return env.ApiCalls.GetCount(), env.ApiCalls.GetExtensibleCount(), env.ApiCalls.GetStandardCount(), nil
}

func batchReport(envList []string, month int, year int, envDetails bool, pwg *sync.WaitGroup) {
func batchReport(envList []string, month int, year int, envDetails bool, proxyType bool, pwg *sync.WaitGroup) {
defer pwg.Done()
// batch workgroup
var bwg sync.WaitGroup

bwg.Add(len(envList))

for _, environment := range envList {
go env.TotalAPICallsInMonthAsync(environment, month, year, envDetails, &bwg)
if proxyType {
for _, environment := range envList {
go env.TotalAPICallsByTypeInMonthAsync(environment, month, year, envDetails, &bwg)
}
} else {
for _, environment := range envList {
go env.TotalAPICallsInMonthAsync(environment, month, year, envDetails, &bwg)
}
}

bwg.Wait()
}

func TotalAPICallsInYear(year int, envDetails bool, conn int) (total int, err error) {
var monthlyTotal int
func TotalAPICallsInYear(year int, envDetails bool,
proxyType bool, conn int) (apiCalls int, extensibleApiCalls int, standardApiCalls int, err error) {
var monthlyApiTotal, monthlyExtensibleTotal, monthlyStandardTotal int

t := time.Now()
currentYear := t.Year()

if year > currentYear {
return -1, fmt.Errorf("Invalid year. Year cannot be greater than current year")
return -1, -1, -1, fmt.Errorf("Invalid year. Year cannot be greater than current year")
}

if currentYear == year {
currentMonth := t.Month()
for i := 1; i <= int(currentMonth); i++ { // run the loop only till the current month
if monthlyTotal, err = TotalAPICallsInMonth(i, year, envDetails, conn); err != nil {
return -1, err
if monthlyApiTotal, monthlyExtensibleTotal, monthlyStandardTotal, err =
TotalAPICallsInMonth(i, year, envDetails, proxyType, conn); err != nil {
return -1, -1, -1, err
}
total = total + monthlyTotal
apiCalls = apiCalls + monthlyApiTotal
extensibleApiCalls = extensibleApiCalls + monthlyExtensibleTotal
standardApiCalls = standardApiCalls + monthlyStandardTotal
}
} else {
for i := 1; i <= 12; i++ { // run the loop for each month
if monthlyTotal, err = TotalAPICallsInMonth(i, year, envDetails, conn); err != nil {
return -1, err
if monthlyApiTotal, monthlyExtensibleTotal, monthlyStandardTotal, err =
TotalAPICallsInMonth(i, year, envDetails, proxyType, conn); err != nil {
return -1, -1, -1, err
}
total = total + monthlyTotal
apiCalls = apiCalls + monthlyApiTotal
extensibleApiCalls = extensibleApiCalls + monthlyExtensibleTotal
standardApiCalls = standardApiCalls + monthlyStandardTotal
}
}

return total, nil
return apiCalls, extensibleApiCalls, standardApiCalls, nil
}
29 changes: 22 additions & 7 deletions internal/cmd/org/reportmonthly.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,15 @@ var MonthlyCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) (err error) {
cmd.SilenceUsage = true

var apiCalls int
var apiCalls, extensibleApiCalls, standardApiCalls int
var apiHeader string

if proxyType {
apiHeader = proxyTypeHeader
} else {
apiHeader = apiCallsHeader
}

w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0)

clilog.Warning.Println("This API is rate limited to 1 API Call per second")
Expand All @@ -50,20 +58,25 @@ var MonthlyCmd = &cobra.Command{
}

if envDetails {
fmt.Fprintln(w, "ENVIRONMENT\tMONTH\tAPI CALLS")
fmt.Fprintln(w, "ENVIRONMENT\tMONTH"+apiHeader)
w.Flush()
}

if apiCalls, err = orgs.TotalAPICallsInMonth(month, year, envDetails, conn); err != nil {
if apiCalls, extensibleApiCalls, standardApiCalls, err = orgs.TotalAPICallsInMonth(month,
year, envDetails, proxyType, conn); err != nil {
return err
}

if envDetails {
fmt.Printf("\nSummary\n\n")
}

fmt.Fprintln(w, "ORGANIATION\tMONTH\tAPI CALLS")
fmt.Fprintf(w, "%s\t%d/%d\t%d\n", apiclient.GetApigeeOrg(), month, year, apiCalls)
fmt.Fprintln(w, "ORGANIATION\tMONTH"+apiHeader)
if proxyType {
fmt.Fprintf(w, "%s\t%d/%d\t%d\t%d\n", apiclient.GetApigeeOrg(), month, year, extensibleApiCalls, standardApiCalls)
} else {
fmt.Fprintf(w, "%s\t%d/%d\t%d\n", apiclient.GetApigeeOrg(), month, year, apiCalls)
}
fmt.Fprintln(w)
w.Flush()

Expand All @@ -72,8 +85,8 @@ var MonthlyCmd = &cobra.Command{
}

var (
month, year int
envDetails bool
month, year int
envDetails, proxyType bool
)

func init() {
Expand All @@ -83,6 +96,8 @@ func init() {
-1, "Year")
MonthlyCmd.Flags().BoolVarP(&envDetails, "env-details", "",
false, "Print details of each environment")
MonthlyCmd.Flags().BoolVarP(&proxyType, "proxy-type", "",
false, "Split the API Calls by proxy type, standard vs extensible proxy")
MonthlyCmd.Flags().IntVarP(&conn, "conn", "c",
4, "Number of connections")
MonthlyCmd.Flags().StringVarP(&org, "org", "o",
Expand Down
3 changes: 3 additions & 0 deletions internal/cmd/org/reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ var ReportCmd = &cobra.Command{
Long: "Report Apigee Org Usage",
}

const apiCallsHeader = "\tAPI CALLS"
const proxyTypeHeader = "\tEXTENSIBLE PROXY\tSTANDARD PROXY"

func init() {
ReportCmd.AddCommand(MonthlyCmd)
ReportCmd.AddCommand(YearlyCmd)
Expand Down
Loading

0 comments on commit eb18587

Please sign in to comment.