From 41761398ff7b8684581045a2eab792dcc158105b Mon Sep 17 00:00:00 2001 From: kevin Date: Thu, 10 Nov 2022 20:58:16 +0800 Subject: [PATCH 1/2] fix: inherit issue when parent after inherits --- core/mapping/unmarshaler_test.go | 42 ++++++++++++++++++++++++++++++++ core/mapping/valuer.go | 36 ++++++++++++++++++--------- 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go index e4fd78fd2091..3c58bb2b6481 100644 --- a/core/mapping/unmarshaler_test.go +++ b/core/mapping/unmarshaler_test.go @@ -2991,6 +2991,48 @@ func TestUnmarshaler_InheritFromGrandparent(t *testing.T) { assert.Equal(t, "localhost:8080", s.Middle.Value.Discovery) } +func TestUnmarshaler_InheritSequence(t *testing.T) { + var testConf = []byte(` +Nacos: + NamespaceId: "123" +RpcConf: + Nacos: + NamespaceId: "456" + Name: hello +`) + + type ( + NacosConf struct { + NamespaceId string + } + + RpcConf struct { + Nacos NacosConf `json:",inherit"` + Name string + } + + Config1 struct { + RpcConf RpcConf + Nacos NacosConf + } + + Config2 struct { + RpcConf RpcConf + Nacos NacosConf + } + ) + + var c1 Config1 + assert.NoError(t, UnmarshalYamlBytes(testConf, &c1)) + assert.Equal(t, "123", c1.Nacos.NamespaceId) + assert.Equal(t, "456", c1.RpcConf.Nacos.NamespaceId) + + var c2 Config2 + assert.NoError(t, UnmarshalYamlBytes(testConf, &c2)) + assert.Equal(t, "123", c1.Nacos.NamespaceId) + assert.Equal(t, "456", c1.RpcConf.Nacos.NamespaceId) +} + func TestUnmarshalValuer(t *testing.T) { unmarshaler := NewUnmarshaler(jsonTagKey) var foo string diff --git a/core/mapping/valuer.go b/core/mapping/valuer.go index e22c877fc8ee..5421b4dabd55 100644 --- a/core/mapping/valuer.go +++ b/core/mapping/valuer.go @@ -70,21 +70,33 @@ func (rv recursiveValuer) Value(key string) (interface{}, bool) { return nil, false } - if vm, ok := val.(map[string]interface{}); ok { - if parent := rv.Parent(); parent != nil { - pv, pok := parent.Value(key) - if pok { - if pm, ok := pv.(map[string]interface{}); ok { - for k, v := range vm { - pm[k] = v - } - return pm, true - } - } + vm, ok := val.(map[string]interface{}) + if !ok { + return val, true + } + + parent := rv.Parent() + if parent == nil { + return val, true + } + + pv, pok := parent.Value(key) + if !pok { + return val, true + } + + pm, ok := pv.(map[string]interface{}) + if !ok { + return val, true + } + + for k, v := range pm { + if _, ok := vm[k]; !ok { + vm[k] = v } } - return val, true + return vm, true } // Parent get the parent valuer from rv. From a479cef447e89bdcba7e8e055c488efd585d8610 Mon Sep 17 00:00:00 2001 From: kevin Date: Thu, 10 Nov 2022 21:49:20 +0800 Subject: [PATCH 2/2] chore: add more tests --- core/mapping/unmarshaler_test.go | 49 ++++++++++++++++++++++++++++++++ core/mapping/valuer.go | 4 +-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go index 3c58bb2b6481..9619d5da3bdf 100644 --- a/core/mapping/unmarshaler_test.go +++ b/core/mapping/unmarshaler_test.go @@ -3033,6 +3033,55 @@ RpcConf: assert.Equal(t, "456", c1.RpcConf.Nacos.NamespaceId) } +func TestUnmarshaler_InheritNested(t *testing.T) { + var testConf = []byte(` +Nacos: + Value1: "123" +Server: + Nacos: + Value2: "456" + Rpc: + Nacos: + Value3: "789" + Name: hello +`) + + type ( + NacosConf struct { + Value1 string `json:",optional"` + Value2 string `json:",optional"` + Value3 string `json:",optional"` + } + + RpcConf struct { + Nacos NacosConf `json:",inherit"` + Name string + } + + ServerConf struct { + Nacos NacosConf `json:",inherit"` + Rpc RpcConf + } + + Config struct { + Server ServerConf + Nacos NacosConf + } + ) + + var c Config + assert.NoError(t, UnmarshalYamlBytes(testConf, &c)) + assert.Equal(t, "123", c.Nacos.Value1) + assert.Empty(t, c.Nacos.Value2) + assert.Empty(t, c.Nacos.Value3) + assert.Equal(t, "123", c.Server.Nacos.Value1) + assert.Equal(t, "456", c.Server.Nacos.Value2) + assert.Empty(t, c.Nacos.Value3) + assert.Equal(t, "123", c.Server.Rpc.Nacos.Value1) + assert.Equal(t, "456", c.Server.Rpc.Nacos.Value2) + assert.Equal(t, "789", c.Server.Rpc.Nacos.Value3) +} + func TestUnmarshalValuer(t *testing.T) { unmarshaler := NewUnmarshaler(jsonTagKey) var foo string diff --git a/core/mapping/valuer.go b/core/mapping/valuer.go index 5421b4dabd55..8df2cc0995f3 100644 --- a/core/mapping/valuer.go +++ b/core/mapping/valuer.go @@ -80,8 +80,8 @@ func (rv recursiveValuer) Value(key string) (interface{}, bool) { return val, true } - pv, pok := parent.Value(key) - if !pok { + pv, ok := parent.Value(key) + if !ok { return val, true }