diff --git a/converters/base_types.go b/converters/base_types.go index 591117a..2e73213 100644 --- a/converters/base_types.go +++ b/converters/base_types.go @@ -5,9 +5,8 @@ import ( "reflect" "strconv" - logrus "github.com/sirupsen/logrus" - "github.com/goreflect/gostructor/infra" + logrus "github.com/sirupsen/logrus" ) func convertToInt(source reflect.Value, destination reflect.Value) infra.GoStructorValue { diff --git a/go.mod b/go.mod index 0e61cc6..f488d90 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/goreflect/gostructor go 1.13 require ( + github.com/go-restit/lzjson v0.0.0-20161206095556-efe3c53acc68 github.com/google/go-cmp v0.5.2 // indirect github.com/goreflect/go_hocon v0.0.2 github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index 95073a4..6e84d55 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/go-akka/configuration v0.0.0-20190919102339-a31c845c4b1b h1:3tSuByOnO github.com/go-akka/configuration v0.0.0-20190919102339-a31c845c4b1b/go.mod h1:19bUnum2ZAeftfwwLZ/wRe7idyfoW2MfmXO464Hrfbw= github.com/go-akka/configuration v0.0.0-20200115015912-550403a6bd87 h1:qsA6HPoRXYJ1a2fsHVUmieRTg+otMAM4wEJgSWzumL8= github.com/go-akka/configuration v0.0.0-20200115015912-550403a6bd87/go.mod h1:19bUnum2ZAeftfwwLZ/wRe7idyfoW2MfmXO464Hrfbw= +github.com/go-restit/lzjson v0.0.0-20161206095556-efe3c53acc68 h1:QR2R74UbwMtnEVGVvNfcx6mQmWGgN8abQeXOy92pQIo= +github.com/go-restit/lzjson v0.0.0-20161206095556-efe3c53acc68/go.mod h1:7vXSKQt83WmbPeyVjCfNT9YDJ5BUFmcwFsEjI9SCvYM= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/goreflect/go_hocon v0.0.1 h1:n05o2/7F4S2Q6ZOnn02Sm3kEj/zmkvThk2m7uQQ1Ong= diff --git a/pipeline/json_func.go b/pipeline/json_func.go index 36439aa..e2de959 100644 --- a/pipeline/json_func.go +++ b/pipeline/json_func.go @@ -3,22 +3,63 @@ package pipeline import ( "errors" + "github.com/go-restit/lzjson" "github.com/goreflect/gostructor/infra" + "github.com/goreflect/gostructor/tags" + "github.com/goreflect/gostructor/tools" "github.com/sirupsen/logrus" ) /*JSONConfig - source json configuring*/ type JSONConfig struct { + FileName string + configureFileParsed lzjson.Node } /*GetComplexType - get complex types like arrays, slices, maps from json source*/ -func (json JSONConfig) GetComplexType(context *structContext) infra.GoStructorValue { - logrus.Debug("json configurator source start.") +func (config JSONConfig) GetComplexType(context *structContext) infra.GoStructorValue { + logrus.Debug("Level: Debug. Json configurator source start.") return infra.NewGoStructorNoValue(context.Value.Interface(), errors.New("getcomplext type from json not implemented")) } /*GetBaseType - gettin base type like string, int, float32...*/ -func (json JSONConfig) GetBaseType(context *structContext) infra.GoStructorValue { - logrus.Debug("json configurator source start.") +func (config JSONConfig) GetBaseType(context *structContext) infra.GoStructorValue { + logrus.Debug("Level: Debug. Json configurator source start.") + parsed, notAValue := config.typeSafeLoadConfigFile(context) + if !parsed { + return *notAValue + } + nameField := context.StructField.Tag.Get(tags.TagJSON) + if config.validation(nameField) { + nameField = context.Prefix + context.StructField.Name + } + logrus.Debug("Level: Debug. Key for getting values from source: ", nameField) + + parsedValue := config.configureFileParsed.Get(nameField) + logrus.Error("Node: ", config.configureFileParsed.Type(), "values: ", string(config.configureFileParsed.Raw())) + if parsedValue.ParseError() != nil { + logrus.Error("Can not parsed value from json decoder: ", parsedValue.ParseError()) + return infra.NewGoStructorNoValue(context.Value, parsedValue.ParseError()) + } + logrus.Debug("Level: Debug. Get from json source: ", parsedValue.String()) return infra.NewGoStructorNoValue(context.Value.Interface(), errors.New("getbase type from json not implemented")) } + +// validation - true if everting ok +func (config JSONConfig) validation(value string) bool { + return value == "" +} + +// return true - if loaded config or successfully load config by filename +func (config *JSONConfig) typeSafeLoadConfigFile(context *structContext) (bool, *infra.GoStructorValue) { + if config.configureFileParsed == nil { + fileBuffer, err := tools.ReadFromFile(config.FileName) + if err != nil { + notValue := infra.NewGoStructorNoValue(context.Value, err) + return false, ¬Value + } + config.configureFileParsed = lzjson.Decode(fileBuffer) + return true, nil + } + return true, nil +} diff --git a/pipeline/json_func_test.go b/pipeline/json_func_test.go new file mode 100644 index 0000000..1e622a9 --- /dev/null +++ b/pipeline/json_func_test.go @@ -0,0 +1,207 @@ +package pipeline + +import ( + "reflect" + "strings" + "testing" + + "github.com/go-restit/lzjson" + "github.com/goreflect/gostructor/infra" +) + +type ContextVl struct { + Value []int `cf_json:"complextArray"` + String string `cf_json:"string"` +} + +func TestJSONConfig_GetComplexType(t *testing.T) { + reader := strings.NewReader(` + { + "string": "test", + "complextArray": [1,2,3] + } + `) + valueSimple := ContextVl{} + + fieldStruct1Type := reflect.ValueOf(valueSimple).Type().Field(0) + fieldStruct1Value := reflect.ValueOf(valueSimple).Field(0) + + type fields struct { + FileName string + configureFileParsed lzjson.Node + } + type args struct { + context *structContext + } + tests := []struct { + name string + fields fields + args args + want infra.GoStructorValue + }{ + { + name: "getting complex type error", + fields: fields{ + FileName: "test", + configureFileParsed: lzjson.Decode(reader), + }, + args: args{ + context: &structContext{ + Value: fieldStruct1Value, + StructField: fieldStruct1Type, + Prefix: "", + }, + }, + want: infra.NewGoStructorNoValue(fieldStruct1Value.Interface(), nil), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := JSONConfig{ + FileName: tt.fields.FileName, + configureFileParsed: tt.fields.configureFileParsed, + } + got := config.GetComplexType(tt.args.context) + + if !reflect.DeepEqual(got.GetNotAValue().ValueAddress, fieldStruct1Value.Interface()) { + t.Errorf("JSONConfig.GetComplexType() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestJSONConfig_typeSafeLoadConfigFile(t *testing.T) { + type fields struct { + FileName string + configureFileParsed lzjson.Node + } + type args struct { + context *structContext + } + valueSimple := ContextVl{} + fieldStruct1Value := reflect.ValueOf(valueSimple).Field(0) + + lastWant := infra.NewGoStructorNoValue(fieldStruct1Value, nil) + tests := []struct { + name string + fields fields + args args + want bool + want1 *infra.GoStructorValue + }{ + { + name: "check error while loading parsing node from file", + fields: fields{ + FileName: "", + configureFileParsed: nil, + }, + args: args{ + context: &structContext{ + Value: fieldStruct1Value, + }, + }, + want: false, + want1: &lastWant, + }, + { + name: "check can not loading config from file. File Not Exist", + fields: fields{ + FileName: "../test_configs/config_err1231.json", + configureFileParsed: nil, + }, + args: args{ + context: &structContext{ + Value: fieldStruct1Value, + }, + }, + want: false, + want1: &lastWant, + }, + { + name: "check success loading config", + fields: fields{ + FileName: "../test_configs/config_err.json", + configureFileParsed: nil, + }, + args: args{ + context: &structContext{ + Value: fieldStruct1Value, + }, + }, + want: true, + want1: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := &JSONConfig{ + FileName: tt.fields.FileName, + configureFileParsed: tt.fields.configureFileParsed, + } + got, got1 := config.typeSafeLoadConfigFile(tt.args.context) + if got != tt.want { + t.Errorf("JSONConfig.typeSafeLoadConfigFile() got = %v, want %v", got, tt.want) + } + if got1 != nil && !reflect.DeepEqual(got1.Value, tt.want1.Value) { + t.Errorf("JSONConfig.typeSafeLoadConfigFile() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + +func TestJSONConfig_GetBaseType(t *testing.T) { + type fields struct { + FileName string + configureFileParsed lzjson.Node + } + type args struct { + context *structContext + } + reader := strings.NewReader(` + { + "string": "test", + "complextArray": [1,2,3] + } + `) + test := lzjson.Decode(reader) + if test.Get("string").IsNull() { + t.Error("can not reading inside packet with json: ") + } + t.Log(test.Get("string").Len()) + valueSimple := ContextVl{} + fieldStruct2Value := reflect.ValueOf(valueSimple).Field(1) + + lastWant := infra.NewGoStructorNoValue(fieldStruct2Value, nil) + + tests := []struct { + name string + fields fields + args args + want infra.GoStructorValue + }{ + { + name: "check type parsed. Error", + fields: fields{ + FileName: "unknownFile", + }, + args: args{ + context: &structContext{ + Value: fieldStruct2Value, + }, + }, + want: lastWant, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := JSONConfig{ + FileName: tt.fields.FileName, + configureFileParsed: tt.fields.configureFileParsed, + } + got := config.GetBaseType(tt.args.context) + if !reflect.DeepEqual(got.GetNotAValue().ValueAddress, tt.want.GetNotAValue().ValueAddress) { + t.Errorf("JSONConfig.GetBaseType() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pipeline/pipeline.go b/pipeline/pipeline.go index 48f3c2f..b122de5 100644 --- a/pipeline/pipeline.go +++ b/pipeline/pipeline.go @@ -128,11 +128,9 @@ func getChainByIdentifier( case infra.FunctionSetupHocon: return &HoconConfig{fileName: fileName}, sourceFileInDisk, nil case infra.FunctionSetupJSON: - - return &JSONConfig{}, sourceFileInDisk, errors.New(notSupportedTypeError + - "json configurator source. Not implemented yet") + return &JSONConfig{FileName: fileName}, sourceFileInDisk, nil case infra.FunctionSetupYaml: - return &YamlConfig{}, sourceFileInDisk, errors.New(notSupportedTypeError + + return nil, sourceFileInDisk, errors.New(notSupportedTypeError + "yaml configurator source. Not implemented yet") case infra.FunctionSetupVault: return nil, sourceFielInServer, errors.New(notSupportedTypeError + "vault configurator source. Not implemented yet") diff --git a/pipeline/pipeline_test.go b/pipeline/pipeline_test.go index c042f48..a7570c4 100644 --- a/pipeline/pipeline_test.go +++ b/pipeline/pipeline_test.go @@ -104,18 +104,21 @@ func Test_getChainByIdentifier(t *testing.T) { { name: "check function setup json", args: args{ - idFunc: infra.FunctionSetupJSON, + idFunc: infra.FunctionSetupJSON, + fileName: "test", + }, + want: &JSONConfig{ + FileName: "test", }, - want: &JSONConfig{}, want1: sourceFileInDisk, - wantErr: true, + wantErr: false, }, { name: "check function setup yaml", args: args{ idFunc: infra.FunctionSetupYaml, }, - want: &YamlConfig{}, + want: nil, want1: sourceFileInDisk, wantErr: true, }, diff --git a/test_configs/config1.json b/test_configs/config1.json new file mode 100644 index 0000000..bed43fc --- /dev/null +++ b/test_configs/config1.json @@ -0,0 +1,11 @@ +{ + "field1": "test1Field", + "myTestField2": 23, + "field3": true, + "field4": 12.4, + "field5": [ + 23, + 12, + 45 + ] +} \ No newline at end of file diff --git a/test_configs/config_err.json b/test_configs/config_err.json new file mode 100644 index 0000000..c1ec0ef --- /dev/null +++ b/test_configs/config_err.json @@ -0,0 +1,3 @@ +{ + "test": "" +} diff --git a/tools/reader_file.go b/tools/reader_file.go new file mode 100644 index 0000000..08164a9 --- /dev/null +++ b/tools/reader_file.go @@ -0,0 +1,16 @@ +package tools + +import ( + "bytes" + "io/ioutil" +) + +//ReadFromFile - read from file to byte buffer +func ReadFromFile(fileName string) (*bytes.Buffer, error) { + bts, err := ioutil.ReadFile(fileName) + if err != nil { + return nil, err + } + byteBuffer := bytes.NewBuffer(bts) + return byteBuffer, nil +}