Skip to content

Commit 14962fe

Browse files
authored
CVL database access layer changes (sonic-net#100)
* cvl database access layer changes * cvl database access layer changes to fix test code * cvl database access layer changes to fix benchmark test code * cvl database access layer changes to fix CvlEditConfigData test cases * cvl database access layer - removed the cvl_db_test.go, will be added it after integerating the changes
1 parent ee3029d commit 14962fe

5 files changed

Lines changed: 760 additions & 62 deletions

File tree

cvl/common/cvl_types.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
// //
3+
// Copyright 2022 Broadcom. The term Broadcom refers to Broadcom Inc. and/or //
4+
// its subsidiaries. //
5+
// //
6+
// Licensed under the Apache License, Version 2.0 (the "License"); //
7+
// you may not use this file except in compliance with the License. //
8+
// You may obtain a copy of the License at //
9+
// //
10+
// http://www.apache.org/licenses/LICENSE-2.0 //
11+
// //
12+
// Unless required by applicable law or agreed to in writing, software //
13+
// distributed under the License is distributed on an "AS IS" BASIS, //
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
15+
// See the License for the specific language governing permissions and //
16+
// limitations under the License. //
17+
// //
18+
////////////////////////////////////////////////////////////////////////////////
19+
20+
package common
21+
22+
import (
23+
"github.com/antchfx/xmlquery"
24+
)
25+
26+
// CVLEditConfigData Strcture for key and data in API
27+
type CVLEditConfigData struct {
28+
VType CVLValidateType //Validation type
29+
VOp CVLOperation //Operation type
30+
Key string //Key format : "PORT|Ethernet4"
31+
Data map[string]string //Value : {"alias": "40GE0/28", "mtu" : 9100, "admin_status": down}
32+
ReplaceOp bool
33+
}
34+
35+
type CVLValidateType uint
36+
37+
const (
38+
VALIDATE_NONE CVLValidateType = iota //Data is used as dependent data
39+
VALIDATE_SYNTAX //Syntax is checked and data is used as dependent data
40+
VALIDATE_SEMANTICS //Semantics is checked
41+
VALIDATE_ALL //Syntax and Semantics are checked
42+
)
43+
44+
type CVLOperation uint
45+
46+
const (
47+
OP_NONE CVLOperation = 0 //Used to just validate the config without any operation
48+
OP_CREATE = 1 << 0 //For Create operation
49+
OP_UPDATE = 1 << 1 //For Update operation
50+
OP_DELETE = 1 << 2 //For Delete operation
51+
)
52+
53+
// RequestCacheType Struct for request data and YANG data
54+
type RequestCacheType struct {
55+
ReqData CVLEditConfigData
56+
YangData *xmlquery.Node
57+
}

cvl/common/db_access.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
// //
3+
// Copyright 2023 Broadcom. The term Broadcom refers to Broadcom Inc. and/or //
4+
// its subsidiaries. //
5+
// //
6+
// Licensed under the Apache License, Version 2.0 (the "License"); //
7+
// you may not use this file except in compliance with the License. //
8+
// You may obtain a copy of the License at //
9+
// //
10+
// http://www.apache.org/licenses/LICENSE-2.0 //
11+
// //
12+
// Unless required by applicable law or agreed to in writing, software //
13+
// distributed under the License is distributed on an "AS IS" BASIS, //
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
15+
// See the License for the specific language governing permissions and //
16+
// limitations under the License. //
17+
// //
18+
////////////////////////////////////////////////////////////////////////////////
19+
20+
package common
21+
22+
// DBAccess is used by cvl and custom validation functions to access the ConfigDB.
23+
// This allows cvl clients to plugin additional data source, like transaction cache,
24+
// into cvl. Most of the interface methods mimic the go-redis APIs. It also defines
25+
// Lookup and Count methods to perform advanced search by matching hash field values.
26+
type DBAccess interface {
27+
Exists(key string) IntResult
28+
Keys(pattern string) StrSliceResult
29+
HGet(key, field string) StrResult
30+
HMGet(key string, fields ...string) SliceResult
31+
HGetAll(key string) StrMapResult
32+
Pipeline() PipeResult
33+
34+
// Lookup entries using a Search criteria and return them in sonic db json format.
35+
// E.g, {"INTERFACE": {"Ethernet0": {"vrf", "Vrf1"}, "Ethernet0|1.2.3.4": {"NULL": "NULL"}}}
36+
// TODO fix the return value for not found case
37+
Lookup(s Search) JsonResult
38+
// Count entries using a Search criteria. Returns 0 if there are no matches.
39+
Count(s Search) IntResult
40+
}
41+
42+
type IntResult interface {
43+
Result() (int64, error)
44+
}
45+
46+
type StrResult interface {
47+
Result() (string, error)
48+
}
49+
50+
type StrSliceResult interface {
51+
Result() ([]string, error)
52+
}
53+
54+
type SliceResult interface {
55+
Result() ([]interface{}, error)
56+
}
57+
58+
type StrMapResult interface {
59+
Result() (map[string]string, error)
60+
}
61+
62+
type JsonResult interface {
63+
Result() (string, error) //TODO have it as map instead of string
64+
}
65+
66+
type PipeResult interface {
67+
Keys(pattern string) StrSliceResult
68+
HGet(key, field string) StrResult
69+
HMGet(key string, fields ...string) SliceResult
70+
HGetAll(key string) StrMapResult
71+
Exec() error
72+
Close()
73+
}
74+
75+
// Search criteria for advanced lookup. Initial filtering is done by matching the key Pattern.
76+
// Results are further refined by applying Predicate, WithField and Limit constraints (optional)
77+
type Search struct {
78+
// Pattern to match the keys from a redis table. Must contain a table name prefix.
79+
// E.g, `INTERFACE|Ethernet0` `INTERFACE|*` "INTERFACE|*|*"
80+
Pattern string
81+
// Predicate is a lua condition statement to inspect an entry's key and hash attributes.
82+
// It can use map variables 'k' and 'h' to access key & hash attributes.
83+
// E.g, `k['type'] == 'L3' and h['enabled'] == true`
84+
Predicate string
85+
// KeyNames must contain the key component names in order. Required only if Predicate uses 'k'.
86+
// E.g, if ["name","type"], a key "ACL|TEST|L3" will expand to lua map {name="TEST", type="L3"}
87+
KeyNames []string
88+
// WithField selects a entry only if it contains this hash field
89+
WithField string
90+
// Limit the results to maximum these number of entries
91+
Limit int
92+
}

cvl/custom_validation/common.go

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,98 +21,106 @@ package custom_validation
2121

2222
import (
2323
"reflect"
24-
"github.com/antchfx/xmlquery"
25-
"github.com/go-redis/redis/v7"
24+
25+
"github.com/Azure/sonic-mgmt-common/cvl/common"
2626
"github.com/Azure/sonic-mgmt-common/cvl/internal/util"
2727
"github.com/Azure/sonic-mgmt-common/cvl/internal/yparser"
28-
)
28+
"github.com/antchfx/xmlquery"
29+
"github.com/go-redis/redis/v7"
30+
)
2931

30-
type CustomValidation struct {}
32+
type CustomValidation struct{}
3133

3234
type CVLValidateType uint
35+
3336
const (
34-
VALIDATE_NONE CVLValidateType = iota //Data is used as dependent data
35-
VALIDATE_SYNTAX //Syntax is checked and data is used as dependent data
36-
VALIDATE_SEMANTICS //Semantics is checked
37-
VALIDATE_ALL //Syntax and Semantics are checked
37+
VALIDATE_NONE CVLValidateType = iota //Data is used as dependent data
38+
VALIDATE_SYNTAX //Syntax is checked and data is used as dependent data
39+
VALIDATE_SEMANTICS //Semantics is checked
40+
VALIDATE_ALL //Syntax and Semantics are checked
3841
)
3942

4043
type CVLOperation uint
44+
4145
const (
42-
OP_NONE CVLOperation = 0 //Used to just validate the config without any operation
43-
OP_CREATE = 1 << 0//For Create operation
44-
OP_UPDATE = 1 << 1//For Update operation
45-
OP_DELETE = 1 << 2//For Delete operation
46+
OP_NONE CVLOperation = 0 //Used to just validate the config without any operation
47+
OP_CREATE = 1 << 0 //For Create operation
48+
OP_UPDATE = 1 << 1 //For Update operation
49+
OP_DELETE = 1 << 2 //For Delete operation
4650
)
4751

48-
//CVLRetCode CVL Error codes
52+
// CVLRetCode CVL Error codes
4953
type CVLRetCode int
54+
5055
const (
5156
CVL_SUCCESS CVLRetCode = iota
5257
CVL_ERROR
5358
CVL_NOT_IMPLEMENTED
5459
CVL_INTERNAL_UNKNOWN
5560
CVL_FAILURE
56-
CVL_SYNTAX_ERROR = CVLRetCode(yparser.YP_SYNTAX_ERROR)
57-
CVL_SEMANTIC_ERROR = CVLRetCode(yparser.YP_SEMANTIC_ERROR)
58-
CVL_SYNTAX_MISSING_FIELD = CVLRetCode(yparser.YP_SYNTAX_MISSING_FIELD)
59-
CVL_SYNTAX_INVALID_FIELD = CVLRetCode(yparser.YP_SYNTAX_INVALID_FIELD) /* Invalid Field */
60-
CVL_SYNTAX_INVALID_INPUT_DATA = CVLRetCode(yparser.YP_SYNTAX_INVALID_INPUT_DATA) /*Invalid Input Data */
61-
CVL_SYNTAX_MULTIPLE_INSTANCE = CVLRetCode(yparser.YP_SYNTAX_MULTIPLE_INSTANCE) /* Multiple Field Instances */
62-
CVL_SYNTAX_DUPLICATE = CVLRetCode(yparser.YP_SYNTAX_DUPLICATE) /* Duplicate Fields */
63-
CVL_SYNTAX_ENUM_INVALID = CVLRetCode(yparser.YP_SYNTAX_ENUM_INVALID) /* Invalid enum value */
64-
CVL_SYNTAX_ENUM_INVALID_NAME = CVLRetCode(yparser.YP_SYNTAX_ENUM_INVALID_NAME) /* Invalid enum name */
65-
CVL_SYNTAX_ENUM_WHITESPACE = CVLRetCode(yparser.YP_SYNTAX_ENUM_WHITESPACE) /* Enum name with leading/trailing whitespaces */
66-
CVL_SYNTAX_OUT_OF_RANGE = CVLRetCode(yparser.YP_SYNTAX_OUT_OF_RANGE) /* Value out of range/length/pattern (data) */
67-
CVL_SYNTAX_MINIMUM_INVALID = CVLRetCode(yparser.YP_SYNTAX_MINIMUM_INVALID) /* min-elements constraint not honored */
68-
CVL_SYNTAX_MAXIMUM_INVALID = CVLRetCode(yparser.YP_SYNTAX_MAXIMUM_INVALID) /* max-elements constraint not honored */
69-
CVL_SEMANTIC_DEPENDENT_DATA_MISSING = CVLRetCode(yparser.YP_SEMANTIC_DEPENDENT_DATA_MISSING) /* Dependent Data is missing */
61+
CVL_SYNTAX_ERROR = CVLRetCode(yparser.YP_SYNTAX_ERROR)
62+
CVL_SEMANTIC_ERROR = CVLRetCode(yparser.YP_SEMANTIC_ERROR)
63+
CVL_SYNTAX_MISSING_FIELD = CVLRetCode(yparser.YP_SYNTAX_MISSING_FIELD)
64+
CVL_SYNTAX_INVALID_FIELD = CVLRetCode(yparser.YP_SYNTAX_INVALID_FIELD) /* Invalid Field */
65+
CVL_SYNTAX_INVALID_INPUT_DATA = CVLRetCode(yparser.YP_SYNTAX_INVALID_INPUT_DATA) /*Invalid Input Data */
66+
CVL_SYNTAX_MULTIPLE_INSTANCE = CVLRetCode(yparser.YP_SYNTAX_MULTIPLE_INSTANCE) /* Multiple Field Instances */
67+
CVL_SYNTAX_DUPLICATE = CVLRetCode(yparser.YP_SYNTAX_DUPLICATE) /* Duplicate Fields */
68+
CVL_SYNTAX_ENUM_INVALID = CVLRetCode(yparser.YP_SYNTAX_ENUM_INVALID) /* Invalid enum value */
69+
CVL_SYNTAX_ENUM_INVALID_NAME = CVLRetCode(yparser.YP_SYNTAX_ENUM_INVALID_NAME) /* Invalid enum name */
70+
CVL_SYNTAX_ENUM_WHITESPACE = CVLRetCode(yparser.YP_SYNTAX_ENUM_WHITESPACE) /* Enum name with leading/trailing whitespaces */
71+
CVL_SYNTAX_OUT_OF_RANGE = CVLRetCode(yparser.YP_SYNTAX_OUT_OF_RANGE) /* Value out of range/length/pattern (data) */
72+
CVL_SYNTAX_MINIMUM_INVALID = CVLRetCode(yparser.YP_SYNTAX_MINIMUM_INVALID) /* min-elements constraint not honored */
73+
CVL_SYNTAX_MAXIMUM_INVALID = CVLRetCode(yparser.YP_SYNTAX_MAXIMUM_INVALID) /* max-elements constraint not honored */
74+
CVL_SEMANTIC_DEPENDENT_DATA_MISSING = CVLRetCode(yparser.YP_SEMANTIC_DEPENDENT_DATA_MISSING) /* Dependent Data is missing */
7075
CVL_SEMANTIC_MANDATORY_DATA_MISSING = CVLRetCode(yparser.YP_SEMANTIC_MANDATORY_DATA_MISSING) /* Mandatory Data is missing */
71-
CVL_SEMANTIC_KEY_ALREADY_EXIST = CVLRetCode(yparser.YP_SEMANTIC_KEY_ALREADY_EXIST) /* Key already existing. */
72-
CVL_SEMANTIC_KEY_NOT_EXIST = CVLRetCode(yparser.YP_SEMANTIC_KEY_NOT_EXIST) /* Key is missing. */
73-
CVL_SEMANTIC_KEY_DUPLICATE = CVLRetCode(yparser.YP_SEMANTIC_KEY_DUPLICATE) /* Duplicate key. */
74-
CVL_SEMANTIC_KEY_INVALID = CVLRetCode(yparser.YP_SEMANTIC_KEY_INVALID)
76+
CVL_SEMANTIC_KEY_ALREADY_EXIST = CVLRetCode(yparser.YP_SEMANTIC_KEY_ALREADY_EXIST) /* Key already existing. */
77+
CVL_SEMANTIC_KEY_NOT_EXIST = CVLRetCode(yparser.YP_SEMANTIC_KEY_NOT_EXIST) /* Key is missing. */
78+
CVL_SEMANTIC_KEY_DUPLICATE = CVLRetCode(yparser.YP_SEMANTIC_KEY_DUPLICATE) /* Duplicate key. */
79+
CVL_SEMANTIC_KEY_INVALID = CVLRetCode(yparser.YP_SEMANTIC_KEY_INVALID)
7580
)
7681

77-
//CVLEditConfigData Strcture for key and data in API
82+
// CVLEditConfigData Strcture for key and data in API
7883
type CVLEditConfigData struct {
79-
VType CVLValidateType //Validation type
80-
VOp CVLOperation //Operation type
81-
Key string //Key format : "PORT|Ethernet4"
82-
Data map[string]string //Value : {"alias": "40GE0/28", "mtu" : 9100, "admin_status": down}
84+
VType CVLValidateType //Validation type
85+
VOp CVLOperation //Operation type
86+
Key string //Key format : "PORT|Ethernet4"
87+
Data map[string]string //Value : {"alias": "40GE0/28", "mtu" : 9100, "admin_status": down}
8388
}
8489

85-
//CVLErrorInfo CVL Error Structure
90+
// CVLErrorInfo CVL Error Structure
8691
type CVLErrorInfo struct {
87-
TableName string /* Table having error */
88-
ErrCode CVLRetCode /* CVL Error return Code. */
89-
CVLErrDetails string /* CVL Error Message details. */
90-
Keys []string /* Keys of the Table having error. */
91-
Value string /* Field Value throwing error */
92-
Field string /* Field Name throwing error . */
93-
Msg string /* Detailed error message. */
94-
ConstraintErrMsg string /* Constraint error message. */
95-
ErrAppTag string
92+
TableName string /* Table having error */
93+
ErrCode CVLRetCode /* CVL Error return Code. */
94+
CVLErrDetails string /* CVL Error Message details. */
95+
Keys []string /* Keys of the Table having error. */
96+
Value string /* Field Value throwing error */
97+
Field string /* Field Name throwing error . */
98+
Msg string /* Detailed error message. */
99+
ConstraintErrMsg string /* Constraint error message. */
100+
ErrAppTag string
96101
}
97102

98103
type CustValidationCache struct {
99104
Data interface{}
100105
}
101106

102-
//CustValidationCtxt Custom validation context passed to custom validation function
107+
// CustValidationCtxt Custom validation context passed to custom validation function
103108
type CustValidationCtxt struct {
104-
ReqData []CVLEditConfigData //All request data
105-
CurCfg *CVLEditConfigData //Current request data for which validation should be done
106-
YNodeName string //YANG node name
107-
YNodeVal string //YANG node value, leaf-list will have "," separated value
108-
YCur *xmlquery.Node //YANG data tree
109+
ReqData []CVLEditConfigData //All request data
110+
CurCfg *CVLEditConfigData //Current request data for which validation should be done
111+
YNodeName string //YANG node name
112+
YNodeVal string //YANG node value, leaf-list will have "," separated value
113+
YCur *xmlquery.Node //YANG data tree
109114
SessCache *CustValidationCache //Session cache, can be used for storing data, persistent in session
110-
RClient *redis.Client //Redis client
115+
RClient *redis.Client //Redis client
111116
}
112117

113-
//InvokeCustomValidation Common function to invoke custom validation
114-
//TBD should we do this using GO plugin feature ?
115-
func InvokeCustomValidation(cv *CustomValidation, name string, args... interface{}) CVLErrorInfo {
118+
// Search criteria for advanced lookup through DBAccess APIs
119+
type Search = common.Search
120+
121+
// InvokeCustomValidation Common function to invoke custom validation
122+
// TBD should we do this using GO plugin feature ?
123+
func InvokeCustomValidation(cv *CustomValidation, name string, args ...interface{}) CVLErrorInfo {
116124
inputs := make([]reflect.Value, len(args))
117125
for i := range args {
118126
inputs[i] = reflect.ValueOf(args[i])
@@ -129,4 +137,3 @@ func InvokeCustomValidation(cv *CustomValidation, name string, args... interface
129137

130138
return CVLErrorInfo{ErrCode: CVL_SUCCESS}
131139
}
132-

0 commit comments

Comments
 (0)