Skip to content

Commit

Permalink
Trying out adding some Iter() style functions to make this SDK faster #…
Browse files Browse the repository at this point in the history
  • Loading branch information
allmightyspiff committed Feb 7, 2024
1 parent 967fb9b commit 88ce3a9
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 3 deletions.
61 changes: 61 additions & 0 deletions examples/cmd/virtual_iter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"

"github.com/softlayer/softlayer-go/filter"
"github.com/softlayer/softlayer-go/services"
"github.com/softlayer/softlayer-go/session"
)

func init() {
rootCmd.AddCommand(listVirtCmd)
}

var listVirtCmd = &cobra.Command{
Use: "virt-list",
Short: "Lists all VSI on the account",
Long: `Lists all VSI on the account using an iterative aproach.`,
RunE: func(cmd *cobra.Command, args []string) error {
return RunListVirtCmd(cmd, args)
},
}

func RunListVirtCmd(cmd *cobra.Command, args []string) error {

objectMask := "mask[id,hostname,domain,primaryIpAddress,primaryBackendIpAddress]"
// When using a result Limit to break up your API request, its important to include an orderBy objectFilter
// to enforce an order on the query, as the database might not always return results in the same order between
// queries otherwise
filters := filter.New()
filters = append(filters, filter.Path("virtualGuests.id").OrderBy("ASC"))
objectFilter := filters.Build()
// Sets up the session with authentication headers.
sess := session.New()
// uncomment to output API calls as they are made.
sess.Debug = true

// creates a reference to the service object (SoftLayer_Account)
service := services.GetAccountService(sess)

// Sets the mask, filter, result limit, and then makes the API call SoftLayer_Account::getHardware()
servers, err := service.Mask(objectMask).Filter(objectFilter).GetVirtualGuestsIter()
if err != nil {
return err
}
fmt.Printf("Id, Hostname, Domain, IP Address\n")

for _, server := range servers {
ipAddress := "-"
// Servers with a private only connection will not have a primary IP
if server.PrimaryIpAddress != nil {
ipAddress = *server.PrimaryIpAddress
}
fmt.Printf("%v, %v, %v, %v\n", *server.Id, *server.Hostname, *server.Domain, ipAddress)
}


return nil
}
41 changes: 41 additions & 0 deletions services/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package services
import (
"fmt"
"strings"
"sync"

"github.com/softlayer/softlayer-go/datatypes"
"github.com/softlayer/softlayer-go/session"
Expand Down Expand Up @@ -1897,6 +1898,46 @@ func (r Account) GetVirtualGuests() (resp []datatypes.Virtual_Guest, err error)
return
}

// Retrieve An account's associated virtual guest objects in pages
func (r Account) GetVirtualGuestsIter() (resp []datatypes.Virtual_Guest, err error) {

limit := 2
// r.Session.Debug = true
if r.Options.Limit == nil {
r = r.Limit(limit)
}
// Get the first result set to find out how many total results we have to get through.
err = r.Session.DoRequest("SoftLayer_Account", "getVirtualGuests", nil, &r.Options, &resp)
if err != nil {
return
}
// how many api calls we have to make still.
apicalls := r.Options.GetRemainingAPICalls()
fmt.Printf(" (%v -%v) / %v = %v \n", r.Options.TotalItems, limit, limit, apicalls)
// First call returned all items (or none) and we are done.
if apicalls < 1 {
return
}
var wg sync.WaitGroup
for x := 1; x <= apicalls; x++ {
wg.Add(1)

go func(i int) {
defer wg.Done()
offset := i * limit
this_resp := []datatypes.Virtual_Guest{}
// Makes a copy of the options, because doing a go routine will have &r.Optoins all be the same.
options := r.Options
options.Offset = &offset
err = r.Session.DoRequest("SoftLayer_Account", "getVirtualGuests", nil, &options, &this_resp)
resp = append(resp, this_resp...)
}(x)
}
wg.Wait()
return

}

// Retrieve An account's associated virtual guest objects currently over bandwidth allocation.
func (r Account) GetVirtualGuestsOverBandwidthAllocation() (resp []datatypes.Virtual_Guest, err error) {
err = r.Session.DoRequest("SoftLayer_Account", "getVirtualGuestsOverBandwidthAllocation", nil, &r.Options, &resp)
Expand Down
8 changes: 8 additions & 0 deletions session/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,17 @@ func makeHTTPRequest(
defer resp.Body.Close()

responseBody, err := ioutil.ReadAll(resp.Body)

if err != nil {
return nil, resp.StatusCode, err
}
if resp.Header["Softlayer-Total-Items"] != nil && len(resp.Header["Softlayer-Total-Items"]) == 1 {
var str_err error
options.TotalItems, str_err = strconv.Atoi(resp.Header["Softlayer-Total-Items"][0])
if str_err != nil {
log.Println("[Error] Unable to convert Softlayer-Total-Items to int: ", str_err)
}
}

if session.Debug {
log.Println("[DEBUG] Status Code: ", resp.StatusCode)
Expand Down
6 changes: 5 additions & 1 deletion session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,11 @@ func (r *Session) DoRequest(service string, method string, args []interface{}, o
r.TransportHandler = getDefaultTransport(r.Endpoint)
}

return r.TransportHandler.DoRequest(r, service, method, args, options, pResult)
err := r.TransportHandler.DoRequest(r, service, method, args, options, pResult)
if err != nil {
return err
}
return err
}

// SetTimeout creates a copy of the session and sets the passed timeout into it
Expand Down
15 changes: 13 additions & 2 deletions sl/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,23 @@

package sl

// Options contains the individual query parameters that can be applied to
// a request.
import (
"math"
)

// Options contains the individual query parameters that can be applied to a request.
type Options struct {
Id *int
Mask string
Filter string
Limit *int
Offset *int
TotalItems int
}

// returns Math.Ciel((TotalItems - Limit) / Limit)
func (opt Options) GetRemainingAPICalls() int {
Total := float64(opt.TotalItems)
Limit := float64(*opt.Limit)
return int(math.Ceil((Total - Limit) / Limit ))
}

0 comments on commit 88ce3a9

Please sign in to comment.