github.com/Axway/agent-sdk@v1.1.101/pkg/config/validator.go (about) 1 package config 2 3 import ( 4 "reflect" 5 6 "github.com/Axway/agent-sdk/pkg/util" 7 ) 8 9 // ValidateConfig - Validates the agent config 10 // Uses reflection to get the IConfigValidator interface on the config struct or 11 // struct variable. 12 // Makes call to ValidateCfg method except if the struct variable is of CentralConfig type 13 // as the validation for CentralConfig is already done during parseCentralConfig 14 func ValidateConfig(cfg interface{}) error { 15 // This defer func is to catch a possible panic that WILL occur if the cfg object that is passed in embeds the IConfigValidator interface 16 // within its struct, but does NOT implement the ValidateCfg method. While it might be that this method really isn't necessary, we will 17 // log an error alerting the user in case it wasn't intentional. 18 defer util.HandleInterfaceFuncNotImplemented(cfg, "ValidateCfg", "IConfigValidator") 19 20 // Check if top level struct has Validate. If it does then call Validate 21 // only at top level 22 if cfg == nil { 23 return nil 24 } 25 26 if objInterface, ok := cfg.(IConfigValidator); ok { 27 err := objInterface.ValidateCfg() 28 if err != nil { 29 return err 30 } 31 } 32 33 // If the parameter is of struct pointer, use indirection to get the 34 // real value object 35 v := reflect.ValueOf(cfg) 36 if v.Kind() == reflect.Ptr { 37 v = reflect.Indirect(v) 38 } 39 40 return validateFields(cfg, v) 41 } 42 43 func validateFields(cfg interface{}, v reflect.Value) error { 44 // Look for Validate method on struct properties and invoke it 45 for i := 0; i < v.NumField(); i++ { 46 if v.Field(i).CanInterface() { 47 fieldInterface := v.Field(i).Interface() 48 // Skip the property it is CentralConfig type as its already Validated 49 // during parseCentralConfig 50 51 if shouldValidateField(cfg, fieldInterface) { 52 if objInterface, ok := fieldInterface.(IConfigValidator); ok { 53 err := ValidateConfig(objInterface) 54 if err != nil { 55 return err 56 } 57 } 58 } 59 } 60 } 61 62 return nil 63 } 64 65 func shouldValidateField(cfg interface{}, fieldInterface interface{}) bool { 66 _, isTopLevelCentralCfg := cfg.(CentralConfig) 67 if isTopLevelCentralCfg { 68 return true 69 } 70 71 _, isFieldCentralCfg := fieldInterface.(CentralConfig) 72 return !isFieldCentralCfg 73 }