Skip to content

Commit

Permalink
Project import generated by Copybara.
Browse files Browse the repository at this point in the history
FolderOrigin-RevId: /usr/local/google/home/gdennis/copybara/temp/folder-destination4569156230434808993/.
  • Loading branch information
GGN Engprod Team authored and greg-dennis committed Sep 28, 2022
1 parent cf83474 commit 3338c32
Show file tree
Hide file tree
Showing 86 changed files with 170,856 additions and 91,530 deletions.
6 changes: 3 additions & 3 deletions binding/ixweb/chassis.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *Chassis) absPath(relPath string) string {
}

// Get submits a GET request, at a relative path to the chassis API.
func (c *Chassis) Get(ctx context.Context, path string, out interface{}) error {
func (c *Chassis) Get(ctx context.Context, path string, out any) error {
return c.ixweb.jsonReq(ctx, get, c.absPath(path), nil, out)
}

Expand All @@ -39,11 +39,11 @@ func (c *Chassis) Delete(ctx context.Context, path string) error {
}

// Patch submits a PATCH request, at a relative path to the chassis API.
func (c *Chassis) Patch(ctx context.Context, path string, in interface{}) error {
func (c *Chassis) Patch(ctx context.Context, path string, in any) error {
return c.ixweb.jsonReq(ctx, patch, c.absPath(path), in, nil)
}

// Post submits a POST request, at a relative path to the chassis API.
func (c *Chassis) Post(ctx context.Context, path string, in, out interface{}) error {
func (c *Chassis) Post(ctx context.Context, path string, in, out any) error {
return c.ixweb.jsonReq(ctx, post, c.absPath(path), in, out)
}
26 changes: 13 additions & 13 deletions binding/ixweb/ixconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ func (c *Config) QueryIDs(ctx context.Context, xpaths ...string) (map[string]str
}

const selectOpPath = "operations/select?xpath=true"
selectReq := map[string][]interface{}{
"selects": []interface{}{
map[string]interface{}{
selectReq := map[string][]any{
"selects": []any{
map[string]any{
// Base path in IxNetwork REST hierarchy to query from.
// Since we can't assume we know any IDs we can't make this narrower.
"from": "/",
"properties": []string{""},
"children": []interface{}{
map[string]interface{}{
"children": []any{
map[string]any{
// Regex of field names of objects to return IDs for. This operation
// will not recurse on a field name in the hierarchy that is not
// included here, so the field names of all parent objects of a
Expand All @@ -112,16 +112,16 @@ func (c *Config) QueryIDs(ctx context.Context, xpaths ...string) (map[string]str
},
},
},
"inlines": []map[string]interface{}{
map[string]interface{}{
"inlines": []map[string]any{
map[string]any{
"child": "",
"properties": []string{""},
},
},
},
},
}
var resp []map[string]interface{}
var resp []map[string]any
if err := c.sess.Post(ctx, selectOpPath, selectReq, &resp); err != nil {
return nil, fmt.Errorf("error querying for node IDs: %w", err)
}
Expand All @@ -148,7 +148,7 @@ func (c *Config) QueryIDs(ctx context.Context, xpaths ...string) (map[string]str

// updateIDsFromMap recurses through a nested map response from the IxNetwork
// 'select' operation, updating the IDs for xpaths in the given xpathToID map.
func updateIDsFromMap(m map[string]interface{}, xpathToID map[string]string) {
func updateIDsFromMap(m map[string]any, xpathToID map[string]string) {
xp, hasXPath := m["xpath"].(string)
id, hasID := m["href"].(string)
if hasXPath && hasID {
Expand All @@ -158,14 +158,14 @@ func updateIDsFromMap(m map[string]interface{}, xpathToID map[string]string) {
}

// Update on an sublists/maps.
var updateIDs func(interface{})
updateIDs = func(mapOrList interface{}) {
var updateIDs func(any)
updateIDs = func(mapOrList any) {
switch val := mapOrList.(type) {
case []interface{}:
case []any:
for _, v := range val {
updateIDs(v)
}
case map[string]interface{}:
case map[string]any:
updateIDsFromMap(val, xpathToID)
}
}
Expand Down
12 changes: 6 additions & 6 deletions binding/ixweb/ixnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (s *Session) AbsPath(relPath string) string {
}

// Get submits a JSON GET request, at a path relative to the IxNetwork session.
func (s *Session) Get(ctx context.Context, path string, out interface{}) error {
func (s *Session) Get(ctx context.Context, path string, out any) error {
return s.jsonReq(ctx, get, path, nil, out)
}

Expand All @@ -176,12 +176,12 @@ func (s *Session) Delete(ctx context.Context, path string) error {
}

// Patch submits a JSON PATCH request, at a path relative to the IxNetwork session.
func (s *Session) Patch(ctx context.Context, path string, in interface{}) error {
func (s *Session) Patch(ctx context.Context, path string, in any) error {
return s.jsonReq(ctx, patch, path, in, nil)
}

// Post submits a JSON POST request, at a path relative to the IxNetwork session.
func (s *Session) Post(ctx context.Context, path string, in, out interface{}) error {
func (s *Session) Post(ctx context.Context, path string, in, out any) error {
return s.jsonReq(ctx, post, path, in, out)
}

Expand Down Expand Up @@ -241,7 +241,7 @@ func (s *Session) Errors(ctx context.Context) ([]*Error, error) {
return errors, nil
}

func (s *Session) jsonReq(ctx context.Context, method httpMethod, path string, in, out interface{}) error {
func (s *Session) jsonReq(ctx context.Context, method httpMethod, path string, in, out any) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.ixweb.jsonReq(ctx, method, s.AbsPath(path), in, out)
Expand All @@ -254,11 +254,11 @@ func (s *Session) binaryReq(ctx context.Context, method httpMethod, path string,
}

// OpArgs is a list of arguments for an operation to use as input to a POST request.
type OpArgs []interface{}
type OpArgs []any

// MarshalJSON marshals the operation arguments to JSON.
func (a OpArgs) MarshalJSON() ([]byte, error) {
m := make(map[string]interface{})
m := make(map[string]any)
for i, v := range a {
m["arg"+strconv.Itoa(i+1)] = v
}
Expand Down
54 changes: 27 additions & 27 deletions binding/ixweb/ixstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ func (s *Stats) Views(ctx context.Context) (map[string]*StatView, error) {
// ConfigEgressView will create a statistics views for the specified traffic
// item names, broken down by their egress-tracked values. If an egress stat
// view already exists, it will be deleted first before the new one is created.
func (s *Stats) ConfigEgressView(ctx context.Context, trafficItems []string) (*StatView, error) {
// The egressPageSize is the number of unique values that will be tracked.
func (s *Stats) ConfigEgressView(ctx context.Context, trafficItems []string, egressPageSize int) (*StatView, error) {
const minEgressPageSize, maxEgressPageSize = 1, 79
if egressPageSize < minEgressPageSize || egressPageSize > maxEgressPageSize {
return nil, fmt.Errorf("egress page size %v not in allowed range [%v, %v]", egressPageSize, minEgressPageSize, maxEgressPageSize)
}
views, err := s.Views(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -113,6 +118,26 @@ func (s *Stats) ConfigEgressView(ctx context.Context, trafficItems []string) (*S
if err := egressView.configEgressFilters(ctx, trafficItems); err != nil {
return nil, err
}

// IxNetwork has a maximum number of rows per page of 2000, so the following
// condition must be true: pageSize * (egressPageSize + 1) <= 2000.
// In addition, IxNetwork requires the pageSize to be a multiple of 25.
const (
maxPageSize = 2000
pageSizeMultiple = 25
)
pageSize := ((maxPageSize / (egressPageSize + 1)) / pageSizeMultiple) * pageSizeMultiple
pageSizes := struct {
PageSize int `json:"pageSize"`
EgressPageSize int `json:"egressPageSize"`
}{
PageSize: pageSize,
EgressPageSize: egressPageSize,
}
dataPath := path.Join(egressView.path(), "data")
if err := egressView.sess.Patch(ctx, dataPath, pageSizes); err != nil {
return nil, fmt.Errorf("error setting page sizes: %w", err)
}
return egressView, nil
}

Expand Down Expand Up @@ -292,35 +317,10 @@ func (v *StatView) fetchTableFromCSV(ctx context.Context) (StatTable, error) {
}

func (v *StatView) fetchEgressTableFromPages(ctx context.Context) (StatTable, error) {
// IxNetwork has a maximum number of rows per page of 2000, so the following
// condition must be true: pageSize * (egressPageSize + 1) <= 2000.
// In addition, IxNetwork requires the pageSize to be a multiple of 25.
// The egressPageSize should be a power of 2, so that it can store all values
// represented by the egress-tracked bits, but IxNetwork doesn't enforce this.
// To allow users to fully track 3 bits, the egressPageSize is set to 8 and
// the pageSize to 200. Note: retrieving all pages may be a slow operation.
// TODO: Choose egressPageSize dynamically based on the number of bits
// actually being tracked?
const (
maxPageSize = 2000
pageSizeMultiple = 25
egressPageSize = 8
)
pageSizes := struct {
EgressPageSize int `json:"egressPageSize"`
PageSize int `json:"pageSize"`
}{
PageSize: (maxPageSize / (egressPageSize + 1) / pageSizeMultiple) * pageSizeMultiple,
EgressPageSize: egressPageSize,
}
dataPath := path.Join(v.path(), "data")
if err := v.sess.Patch(ctx, dataPath, pageSizes); err != nil {
return nil, fmt.Errorf("error setting page sizes: %w", err)
}
if err := v.waitForReady(ctx); err != nil {
return nil, err
}

dataPath := path.Join(v.path(), "data")
pageNum := struct {
PageNum int `json:"currentPage"`
}{}
Expand Down
32 changes: 22 additions & 10 deletions binding/ixweb/ixstats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,13 @@ func TestConfigEgressStatView(t *testing.T) {
}}}

tests := []struct {
name string
doResps []*http.Response
name string
egPageSize int
doResps []*http.Response
wantErr string
}{{
name: "no existing",
name: "no existing",
egPageSize: 1,
doResps: []*http.Response{
fakeResponse(200, "[]"),
fakeResponse(200, `{"links": [{"href": "/api/v1/sessions/1/ixnetwork/statistics/view/11"}]}`),
Expand All @@ -74,9 +77,11 @@ func TestConfigEgressStatView(t *testing.T) {
fakeResponse(200, `[{"name": "statisticFilter1", "links": [{"href": "sf1"}]}]`),
fakeResponse(200, "enabled statisticFilter"),
fakeResponse(200, "enabled EgressStatView"),
fakeResponse(200, "set page sizes"),
},
}, {
name: "delete existing",
name: "delete existing",
egPageSize: 1,
doResps: []*http.Response{
fakeResponse(200, `[{"id": 11, "caption": "EgressStatView"}]`),
fakeResponse(200, "deleted EgressStatView"),
Expand All @@ -89,20 +94,28 @@ func TestConfigEgressStatView(t *testing.T) {
fakeResponse(200, `[{"name": "statisticFilter1", "links": [{"href": "sf1"}]}]`),
fakeResponse(200, "enabled statisticFilter"),
fakeResponse(200, "enabled EgressStatView"),
fakeResponse(200, "set page sizes"),
},
}, {
name: "bad egress page size",
egPageSize: 100,
wantErr: "not in allowed range",
}}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeClient.doResps = test.doResps
view, err := stats.ConfigEgressView(context.Background(), []string{"item1"})
if err != nil {
t.Fatalf("ConfigEgressStatView unexpected err: %v", err)
view, err := stats.ConfigEgressView(context.Background(), []string{"item1"}, test.egPageSize)
if (err == nil) != (test.wantErr == "") || (err != nil && !strings.Contains(err.Error(), test.wantErr)) {
t.Fatalf("ConfigEgressStatView unexpected err: got %v, want %v", err, test.wantErr)
}
if test.wantErr != "" {
return
}
if view.id != 11 {
t.Fatalf("ConfigEgressStatView unexpected id, got %v, want %v", view.id, 11)
t.Errorf("ConfigEgressStatView unexpected id, got %v, want %v", view.id, 11)
}
if view.caption != EgressStatsCaption {
t.Fatalf("ConfigEgressStatView unexpected caption, got %v, want %v", view.caption, EgressStatsCaption)
t.Errorf("ConfigEgressStatView unexpected caption, got %v, want %v", view.caption, EgressStatsCaption)
}
})
}
Expand Down Expand Up @@ -132,7 +145,6 @@ func TestFetchEgressStatsTable(t *testing.T) {
view := &StatView{
caption: EgressStatsCaption,
sess: &Session{ixweb: &IxWeb{client: &fakeHTTPClient{doResps: []*http.Response{
fakeResponse(200, "set pages sizes"),
fakeResponse(200, `{"isReady": true}`),
fakeResponse(200, "set current page"),
fakeResponse(200, `{
Expand Down
14 changes: 7 additions & 7 deletions binding/ixweb/ixweb.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (ix *IxWeb) setAPIKey(ctx context.Context, username, password string) error

// jsonReq issues a JSON HTTP request. The "in" JSON object is marshalled to
// the request body, and the response is unmarshalled to "out" JSON object.
func (ix *IxWeb) jsonReq(ctx context.Context, method httpMethod, path string, in, out interface{}) error {
func (ix *IxWeb) jsonReq(ctx context.Context, method httpMethod, path string, in, out any) error {
var body []byte
if in != nil {
var err error
Expand Down Expand Up @@ -184,7 +184,7 @@ func (ix *IxWeb) request(ctx context.Context, method httpMethod, path, contentTy
}
req, err := http.NewRequestWithContext(ctx, string(method), url, body)
if err != nil {
return 0, nil, err
return 0, nil, fmt.Errorf("error creating HTTP request: %w", err)
}
if len(content) > 0 {
req.Header.Set("Content-Type", contentType)
Expand Down Expand Up @@ -214,7 +214,7 @@ func (ix *IxWeb) request(ctx context.Context, method httpMethod, path, contentTy
}
// If out of retries or if the original context is no longer active (there would be error from the 'Do' in the latter case.).
if i == RetryLimit || ctx.Err() != nil {
return 0, nil, err
return 0, nil, fmt.Errorf("error on HTTP request %v: %w", req, err)
}

if ctx.Err() != nil {
Expand All @@ -241,7 +241,7 @@ func (ix *IxWeb) request(ctx context.Context, method httpMethod, path, contentTy
return status, data, nil
}

func (ix *IxWeb) waitForAsync(ctx context.Context, data []byte, out interface{}) error {
func (ix *IxWeb) waitForAsync(ctx context.Context, data []byte, out any) error {
const pollDelay = 5 * time.Second
status := struct {
State string `json:"state"`
Expand All @@ -256,9 +256,9 @@ func (ix *IxWeb) waitForAsync(ctx context.Context, data []byte, out interface{})
for i := 0; i < pollLimit; i++ {
switch status.State {
case "EXCEPTION":
return errors.New(status.Message)
return fmt.Errorf("operation exception: %q", status.Message)
case "ERROR":
return errors.New(string(status.Result))
return fmt.Errorf("operation error: %q", string(status.Result))
case "IN_PROGRESS":
pollURL, err := url.Parse(status.URL)
if err != nil {
Expand All @@ -278,7 +278,7 @@ func (ix *IxWeb) waitForAsync(ctx context.Context, data []byte, out interface{})
return fmt.Errorf("operation timeout; last status: %v", status)
}

func unmarshal(data []byte, out interface{}) error {
func unmarshal(data []byte, out any) error {
// Unmarshal will fail if data is empty or out is nil; make it a noop instead.
if out != nil && len(data) > 0 {
if err := json.Unmarshal(data, out); err != nil {
Expand Down
Loading

0 comments on commit 3338c32

Please sign in to comment.