Skip to content

Commit

Permalink
Merge pull request #32 from goreflect/issue_4
Browse files Browse the repository at this point in the history
Issue 4: Support json source for configuring
  • Loading branch information
kubitre authored Nov 15, 2020
2 parents 717c0e3 + ac94e30 commit c5cb775
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 14 deletions.
3 changes: 1 addition & 2 deletions converters/base_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
49 changes: 45 additions & 4 deletions pipeline/json_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, &notValue
}
config.configureFileParsed = lzjson.Decode(fileBuffer)
return true, nil
}
return true, nil
}
207 changes: 207 additions & 0 deletions pipeline/json_func_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}
6 changes: 2 additions & 4 deletions pipeline/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
11 changes: 7 additions & 4 deletions pipeline/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
11 changes: 11 additions & 0 deletions test_configs/config1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"field1": "test1Field",
"myTestField2": 23,
"field3": true,
"field4": 12.4,
"field5": [
23,
12,
45
]
}
3 changes: 3 additions & 0 deletions test_configs/config_err.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"test": ""
}
16 changes: 16 additions & 0 deletions tools/reader_file.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit c5cb775

Please sign in to comment.